Bug 1521168
- Export Screenshots 37.1.0 to Firefox (code excluding translations); r=_6a68
MozReview-Commit-ID: 3lIF2XGAwlj Depends on D18102 Differential Revision: https://phabricator.services.mozilla.com/D18103 --HG-- extra : moz-landing-system : lando
|
@ -5,8 +5,17 @@
|
|||
this.analytics = (function() {
|
||||
const exports = {};
|
||||
|
||||
const GA_PORTION = 0.1; // 10% of users will send to the server/GA
|
||||
// This is set from storage, or randomly; if it is less that GA_PORTION then we send analytics:
|
||||
let myGaSegment = 1;
|
||||
let telemetryPrefKnown = false;
|
||||
let telemetryEnabled;
|
||||
// If we ever get a 410 Gone response (or 404) from the server, we'll stop trying to send events for the rest
|
||||
// of the session
|
||||
let hasReturnedGone = false;
|
||||
// If there's this many entirely failed responses (e.g., server can't be contacted), then stop sending events
|
||||
// for the rest of the session:
|
||||
let serverFailedResponses = 3;
|
||||
|
||||
const EVENT_BATCH_DURATION = 1000; // ms for setTimeout
|
||||
let pendingEvents = [];
|
||||
|
@ -19,6 +28,10 @@ this.analytics = (function() {
|
|||
credentials: "include",
|
||||
};
|
||||
|
||||
function shouldSendEvents() {
|
||||
return !hasReturnedGone && serverFailedResponses > 0 && myGaSegment < GA_PORTION;
|
||||
}
|
||||
|
||||
function flushEvents() {
|
||||
if (pendingEvents.length === 0) {
|
||||
return;
|
||||
|
@ -58,6 +71,9 @@ this.analytics = (function() {
|
|||
function sendTiming(timingLabel, timingVar, timingValue) {
|
||||
// sendTiming is only called in response to sendEvent, so no need to check
|
||||
// the telemetry pref again here.
|
||||
if (!shouldSendEvents()) {
|
||||
return;
|
||||
}
|
||||
const timingCategory = "addon";
|
||||
pendingTimings.push({
|
||||
timingCategory,
|
||||
|
@ -110,6 +126,10 @@ this.analytics = (function() {
|
|||
for (const [gaField, value] of Object.entries(abTests)) {
|
||||
options[gaField] = value;
|
||||
}
|
||||
if (!shouldSendEvents()) {
|
||||
// We don't want to save or send the events anymore
|
||||
return Promise.resolve();
|
||||
}
|
||||
pendingEvents.push({
|
||||
eventTime: Date.now(),
|
||||
event: eventCategory,
|
||||
|
@ -307,16 +327,37 @@ this.analytics = (function() {
|
|||
}
|
||||
|
||||
function fetchWatcher(request) {
|
||||
catcher.watchPromise(
|
||||
request.then(response => {
|
||||
if (!response.ok) {
|
||||
throw new Error(`Bad response from ${request.url}: ${response.status} ${response.statusText}`);
|
||||
}
|
||||
return response;
|
||||
}),
|
||||
true
|
||||
);
|
||||
request.then(response => {
|
||||
if (response.status === 410 || response.status === 404) { // Gone
|
||||
hasReturnedGone = true;
|
||||
pendingEvents = [];
|
||||
pendingTimings = [];
|
||||
}
|
||||
if (!response.ok) {
|
||||
log.debug(`Error code in event response: ${response.status} ${response.statusText}`);
|
||||
}
|
||||
}).catch(error => {
|
||||
serverFailedResponses--;
|
||||
if (serverFailedResponses <= 0) {
|
||||
log.info(`Server is not responding, no more events will be sent`);
|
||||
pendingEvents = [];
|
||||
pendingTimings = [];
|
||||
}
|
||||
log.debug(`Error event in response: ${error}`);
|
||||
});
|
||||
}
|
||||
|
||||
async function init() {
|
||||
const result = await browser.storage.local.get(["myGaSegment"]);
|
||||
if (!result.myGaSegment) {
|
||||
myGaSegment = Math.random();
|
||||
await browser.storage.local.set({myGaSegment});
|
||||
} else {
|
||||
myGaSegment = result.myGaSegment;
|
||||
}
|
||||
}
|
||||
|
||||
init();
|
||||
|
||||
return exports;
|
||||
})();
|
||||
|
|
|
@ -10,6 +10,17 @@ this.main = (function() {
|
|||
|
||||
const manifest = browser.runtime.getManifest();
|
||||
let backend;
|
||||
let _hasAnyShots = false;
|
||||
|
||||
startBackground.serverStatus.then((status) => {
|
||||
_hasAnyShots = status.hasAny;
|
||||
}).catch((e) => {
|
||||
log.warn("Cannot see server status", e);
|
||||
});
|
||||
|
||||
exports.hasAnyShots = function() {
|
||||
return _hasAnyShots;
|
||||
};
|
||||
|
||||
let hasSeenOnboarding = browser.storage.local.get(["hasSeenOnboarding"]).then((result) => {
|
||||
const onboarded = !!result.hasSeenOnboarding;
|
||||
|
@ -83,36 +94,7 @@ this.main = (function() {
|
|||
// This is called by startBackground.js, where is registered as a click
|
||||
// handler for the webextension page action.
|
||||
exports.onClicked = catcher.watchFunction((tab) => {
|
||||
catcher.watchPromise(hasSeenOnboarding.then(onboarded => {
|
||||
if (shouldOpenMyShots(tab.url)) {
|
||||
if (!onboarded) {
|
||||
catcher.watchPromise(analytics.refreshTelemetryPref().then(() => {
|
||||
sendEvent("goto-onboarding", "selection-button", {incognito: tab.incognito});
|
||||
return forceOnboarding();
|
||||
}));
|
||||
return;
|
||||
}
|
||||
catcher.watchPromise(analytics.refreshTelemetryPref().then(() => {
|
||||
sendEvent("goto-myshots", "about-newtab", {incognito: tab.incognito});
|
||||
}));
|
||||
catcher.watchPromise(
|
||||
auth.maybeLogin()
|
||||
.then(() => browser.tabs.update({url: backend + "/shots"})));
|
||||
} else {
|
||||
catcher.watchPromise(
|
||||
toggleSelector(tab)
|
||||
.then(active => {
|
||||
const event = active ? "start-shot" : "cancel-shot";
|
||||
sendEvent(event, "toolbar-button", {incognito: tab.incognito});
|
||||
}, (error) => {
|
||||
if ((!onboarded) && error.popupMessage === "UNSHOOTABLE_PAGE") {
|
||||
sendEvent("goto-onboarding", "selection-button", {incognito: tab.incognito});
|
||||
return forceOnboarding();
|
||||
}
|
||||
throw error;
|
||||
}));
|
||||
}
|
||||
}));
|
||||
_startShotFlow(tab, "toolbar-button");
|
||||
});
|
||||
|
||||
function forceOnboarding() {
|
||||
|
@ -120,6 +102,23 @@ this.main = (function() {
|
|||
}
|
||||
|
||||
exports.onClickedContextMenu = catcher.watchFunction((info, tab) => {
|
||||
_startShotFlow(tab, "context-menu");
|
||||
});
|
||||
|
||||
exports.onCommand = catcher.watchFunction((tab) => {
|
||||
_startShotFlow(tab, "keyboard-shortcut");
|
||||
});
|
||||
|
||||
const _openMyShots = (tab, inputType) => {
|
||||
catcher.watchPromise(analytics.refreshTelemetryPref().then(() => {
|
||||
sendEvent("goto-myshots", inputType, {incognito: tab.incognito});
|
||||
}));
|
||||
catcher.watchPromise(
|
||||
auth.maybeLogin()
|
||||
.then(() => browser.tabs.update({url: backend + "/shots"})));
|
||||
};
|
||||
|
||||
const _startShotFlow = (tab, inputType) => {
|
||||
catcher.watchPromise(hasSeenOnboarding.then(onboarded => {
|
||||
if (!tab) {
|
||||
// Not in a page/tab context, ignore
|
||||
|
@ -127,7 +126,8 @@ this.main = (function() {
|
|||
}
|
||||
if (!urlEnabled(tab.url)) {
|
||||
if (!onboarded) {
|
||||
sendEvent("goto-onboarding", "selection-button", {incognito: tab.incognito});
|
||||
// Updated generic "selection-button" event data to inputType
|
||||
sendEvent("goto-onboarding", inputType, {incognito: tab.incognito});
|
||||
forceOnboarding();
|
||||
return;
|
||||
}
|
||||
|
@ -135,13 +135,24 @@ this.main = (function() {
|
|||
popupMessage: "UNSHOOTABLE_PAGE",
|
||||
});
|
||||
return;
|
||||
} else if (shouldOpenMyShots(tab.url)) {
|
||||
_openMyShots(tab, inputType);
|
||||
return;
|
||||
}
|
||||
// No need to catch() here because of watchPromise().
|
||||
// eslint-disable-next-line promise/catch-or-return
|
||||
toggleSelector(tab)
|
||||
.then(() => sendEvent("start-shot", "context-menu", {incognito: tab.incognito}));
|
||||
.then(active => {
|
||||
let event = "start-shot";
|
||||
if (inputType !== "context-menu") {
|
||||
event = active ? "start-shot" : "cancel-shot";
|
||||
}
|
||||
sendEvent(event, inputType, {incognito: tab.incognito});
|
||||
}).catch((error) => {
|
||||
throw error;
|
||||
});
|
||||
}));
|
||||
});
|
||||
};
|
||||
|
||||
function urlEnabled(url) {
|
||||
if (shouldOpenMyShots(url)) {
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* globals catcher, communication, log */
|
||||
/* globals catcher, communication, log, main */
|
||||
|
||||
"use strict";
|
||||
|
||||
|
@ -69,7 +69,13 @@ this.selectorLoader = (function() {
|
|||
exports.loadModules = function(tabId, hasSeenOnboarding) {
|
||||
catcher.watchPromise(hasSeenOnboarding.then(onboarded => {
|
||||
loadingTabs.add(tabId);
|
||||
let promise = downloadOnlyCheck(tabId);
|
||||
let promise = Promise.resolve();
|
||||
promise = promise.then(() => {
|
||||
browser.tabs.executeScript(tabId, {
|
||||
code: `window.hasAnyShots = ${!!main.hasAnyShots()};`,
|
||||
runAt: "document_start",
|
||||
});
|
||||
});
|
||||
if (onboarded) {
|
||||
promise = promise.then(() => {
|
||||
return executeModules(tabId, standardScripts.concat(selectorScripts));
|
||||
|
@ -89,25 +95,6 @@ this.selectorLoader = (function() {
|
|||
}));
|
||||
};
|
||||
|
||||
function downloadOnlyCheck(tabId) {
|
||||
return browser.experiments.screenshots.isHistoryEnabled().then((historyEnabled) => {
|
||||
return browser.experiments.screenshots.isUploadDisabled().then((uploadDisabled) => {
|
||||
return browser.experiments.screenshots.getUpdateChannel().then((channel) => {
|
||||
return browser.tabs.get(tabId).then(tab => {
|
||||
const downloadOnly = !historyEnabled || uploadDisabled || channel === "esr" || tab.incognito;
|
||||
return browser.tabs.executeScript(tabId, {
|
||||
// Note: `window` here refers to a global accessible to content
|
||||
// scripts, but not the scripts in the underlying page. For more
|
||||
// details, see https://mdn.io/WebExtensions/Content_scripts#Content_script_environment
|
||||
code: `window.downloadOnly = ${downloadOnly}`,
|
||||
runAt: "document_start",
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
function executeModules(tabId, scripts) {
|
||||
let lastPromise = Promise.resolve(null);
|
||||
scripts.forEach((file) => {
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* globals browser, main, communication */
|
||||
/* globals browser, main, communication, manifest */
|
||||
/* This file handles:
|
||||
clicks on the WebExtension page action
|
||||
browser.contextMenus.onClicked
|
||||
|
@ -10,6 +10,16 @@ const startTime = Date.now();
|
|||
|
||||
this.startBackground = (function() {
|
||||
const exports = {startTime};
|
||||
// Wait until this many milliseconds to check the server for shots (for the purpose of migration warning):
|
||||
const CHECK_SERVER_TIME = 5000; // 5 seconds
|
||||
// If we want to pop open the tab showing the server status, wait this many milliseconds to open it:
|
||||
const OPEN_SERVER_TAB_TIME = 5000; // 5 seconds
|
||||
let hasSeenServerStatus = false;
|
||||
let _resolveServerStatus;
|
||||
exports.serverStatus = new Promise((resolve, reject) => {
|
||||
_resolveServerStatus = {resolve, reject};
|
||||
});
|
||||
let backend;
|
||||
|
||||
const backgroundScripts = [
|
||||
"log.js",
|
||||
|
@ -40,7 +50,7 @@ this.startBackground = (function() {
|
|||
browser.contextMenus.create({
|
||||
id: "create-screenshot",
|
||||
title: browser.i18n.getMessage("contextMenuLabel"),
|
||||
contexts: ["page"],
|
||||
contexts: ["page", "selection"],
|
||||
documentUrlPatterns: ["<all_urls>", "about:reader*"],
|
||||
});
|
||||
|
||||
|
@ -52,7 +62,21 @@ this.startBackground = (function() {
|
|||
});
|
||||
});
|
||||
|
||||
browser.experiments.screenshots.initLibraryButton();
|
||||
browser.commands.onCommand.addListener((cmd) => {
|
||||
if (cmd !== "take-screenshot") {
|
||||
return;
|
||||
}
|
||||
loadIfNecessary().then(() => {
|
||||
browser.tabs.query({currentWindow: true, active: true}).then((tabs) => {
|
||||
const activeTab = tabs[0];
|
||||
main.onCommand(activeTab);
|
||||
}).catch((error) => {
|
||||
throw error;
|
||||
});
|
||||
}).catch((error) => {
|
||||
console.error("Error toggling Screenshots via keyboard shortcut: ", error);
|
||||
});
|
||||
});
|
||||
|
||||
browser.runtime.onMessage.addListener((req, sender, sendResponse) => {
|
||||
loadIfNecessary().then(() => {
|
||||
|
@ -90,5 +114,84 @@ this.startBackground = (function() {
|
|||
return loadedPromise;
|
||||
}
|
||||
|
||||
async function checkExpiration() {
|
||||
const manifest = await browser.runtime.getManifest();
|
||||
for (const permission of manifest.permissions) {
|
||||
if (/^https?:\/\//.test(permission)) {
|
||||
backend = permission.replace(/\/*$/, "");
|
||||
break;
|
||||
}
|
||||
}
|
||||
const result = await browser.storage.local.get(["registrationInfo", "hasSeenServerStatus", "hasShotsResponse"]);
|
||||
hasSeenServerStatus = result.hasSeenServerStatus;
|
||||
const { registrationInfo } = result;
|
||||
if (!backend || !registrationInfo || !registrationInfo.registered) {
|
||||
// The add-on hasn't been used, or at least no upload has occurred
|
||||
_resolveServerStatus.resolve({hasIndefinite: false, hasAny: false});
|
||||
return;
|
||||
}
|
||||
if (result.hasShotsResponse) {
|
||||
// We've already retrieved information from the server
|
||||
_resolveServerStatus.resolve(result.hasShotsResponse);
|
||||
return;
|
||||
}
|
||||
const loginUrl = `${backend}/api/login`;
|
||||
const hasShotsUrl = `${backend}/api/has-shots`;
|
||||
try {
|
||||
let resp = await fetch(loginUrl, {
|
||||
method: "POST",
|
||||
headers: {
|
||||
"Content-Type": "application/json",
|
||||
},
|
||||
body: JSON.stringify({
|
||||
deviceId: registrationInfo.deviceId,
|
||||
secret: registrationInfo.secret,
|
||||
}),
|
||||
});
|
||||
if (!resp.ok) {
|
||||
throw new Error(`Bad login response: ${resp.status}`);
|
||||
}
|
||||
const { authHeader } = await resp.json();
|
||||
resp = await fetch(hasShotsUrl, {
|
||||
method: "GET",
|
||||
credentials: "include",
|
||||
headers: Object.assign({}, authHeader, {
|
||||
"Content-Type": "application/json",
|
||||
}),
|
||||
});
|
||||
if (!resp.ok) {
|
||||
throw new Error(`Bad response from server: ${resp.status}`);
|
||||
}
|
||||
const body = await resp.json();
|
||||
browser.storage.local.set({hasShotsResponse: body});
|
||||
_resolveServerStatus.resolve(body);
|
||||
} catch (e) {
|
||||
_resolveServerStatus.reject(e);
|
||||
}
|
||||
}
|
||||
|
||||
exports.serverStatus.then((status) => {
|
||||
if (status.hasAny) {
|
||||
browser.experiments.screenshots.initLibraryButton();
|
||||
}
|
||||
if (status.hasIndefinite && !hasSeenServerStatus) {
|
||||
setTimeout(async () => {
|
||||
await browser.tabs.create({
|
||||
url: `${backend}/hosting-shutdown`,
|
||||
});
|
||||
hasSeenServerStatus = true;
|
||||
await browser.storage.local.set({hasSeenServerStatus});
|
||||
}, OPEN_SERVER_TAB_TIME);
|
||||
}
|
||||
}).catch((e) => {
|
||||
console.error("Error finding Screenshots server status:", String(e), e.stack);
|
||||
});
|
||||
|
||||
setTimeout(() => {
|
||||
window.requestIdleCallback(() => {
|
||||
checkExpiration();
|
||||
});
|
||||
}, CHECK_SERVER_TIME);
|
||||
|
||||
return exports;
|
||||
})();
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/* Created from build/server/static/css/inline-selection.css */
|
||||
window.inlineSelectionCss = `
|
||||
.button, .highlight-button-cancel, .highlight-button-save, .highlight-button-download, .highlight-button-copy, .preview-button-save {
|
||||
.button, .highlight-button-cancel, .highlight-button-download, .highlight-button-copy {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
|
@ -19,31 +19,31 @@ window.inlineSelectionCss = `
|
|||
transition: background 150ms cubic-bezier(0.07, 0.95, 0, 1), border 150ms cubic-bezier(0.07, 0.95, 0, 1);
|
||||
user-select: none;
|
||||
white-space: nowrap; }
|
||||
.button.hidden, .hidden.highlight-button-cancel, .hidden.highlight-button-save, .hidden.highlight-button-download, .hidden.highlight-button-copy, .hidden.preview-button-save {
|
||||
.button.hidden, .hidden.highlight-button-cancel, .hidden.highlight-button-download, .hidden.highlight-button-copy {
|
||||
display: none; }
|
||||
.button.small, .small.highlight-button-cancel, .small.highlight-button-save, .small.highlight-button-download, .small.highlight-button-copy, .small.preview-button-save {
|
||||
.button.small, .small.highlight-button-cancel, .small.highlight-button-download, .small.highlight-button-copy {
|
||||
height: 32px;
|
||||
line-height: 32px;
|
||||
padding: 0 8px; }
|
||||
.button.active, .active.highlight-button-cancel, .active.highlight-button-save, .active.highlight-button-download, .active.highlight-button-copy, .active.preview-button-save {
|
||||
.button.active, .active.highlight-button-cancel, .active.highlight-button-download, .active.highlight-button-copy {
|
||||
background-color: #dedede; }
|
||||
.button.tiny, .tiny.highlight-button-cancel, .tiny.highlight-button-save, .tiny.highlight-button-download, .tiny.highlight-button-copy, .tiny.preview-button-save {
|
||||
.button.tiny, .tiny.highlight-button-cancel, .tiny.highlight-button-download, .tiny.highlight-button-copy {
|
||||
font-size: 14px;
|
||||
height: 26px;
|
||||
border: 1px solid #c7c7c7; }
|
||||
.button.tiny:hover, .tiny.highlight-button-cancel:hover, .tiny.highlight-button-save:hover, .tiny.highlight-button-download:hover, .tiny.highlight-button-copy:hover, .tiny.preview-button-save:hover, .button.tiny:focus, .tiny.highlight-button-cancel:focus, .tiny.highlight-button-save:focus, .tiny.highlight-button-download:focus, .tiny.highlight-button-copy:focus, .tiny.preview-button-save:focus {
|
||||
.button.tiny:hover, .tiny.highlight-button-cancel:hover, .tiny.highlight-button-download:hover, .tiny.highlight-button-copy:hover, .button.tiny:focus, .tiny.highlight-button-cancel:focus, .tiny.highlight-button-download:focus, .tiny.highlight-button-copy:focus {
|
||||
background: #ededf0;
|
||||
border-color: #989898; }
|
||||
.button.tiny:active, .tiny.highlight-button-cancel:active, .tiny.highlight-button-save:active, .tiny.highlight-button-download:active, .tiny.highlight-button-copy:active, .tiny.preview-button-save:active {
|
||||
.button.tiny:active, .tiny.highlight-button-cancel:active, .tiny.highlight-button-download:active, .tiny.highlight-button-copy:active {
|
||||
background: #dedede;
|
||||
border-color: #989898; }
|
||||
.button.block-button, .block-button.highlight-button-cancel, .block-button.highlight-button-save, .block-button.highlight-button-download, .block-button.highlight-button-copy, .block-button.preview-button-save {
|
||||
.button.block-button, .block-button.highlight-button-cancel, .block-button.highlight-button-download, .block-button.highlight-button-copy {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
box-sizing: border-box;
|
||||
border: 0;
|
||||
border-right: 1px solid #c7c7c7;
|
||||
border-inline-end: 1px solid #c7c7c7;
|
||||
box-shadow: 0;
|
||||
border-radius: 0;
|
||||
flex-shrink: 0;
|
||||
|
@ -52,47 +52,47 @@ window.inlineSelectionCss = `
|
|||
line-height: 100%;
|
||||
overflow: hidden; }
|
||||
@media (max-width: 719px) {
|
||||
.button.block-button, .block-button.highlight-button-cancel, .block-button.highlight-button-save, .block-button.highlight-button-download, .block-button.highlight-button-copy, .block-button.preview-button-save {
|
||||
.button.block-button, .block-button.highlight-button-cancel, .block-button.highlight-button-download, .block-button.highlight-button-copy {
|
||||
justify-content: flex-start;
|
||||
font-size: 16px;
|
||||
height: 72px;
|
||||
margin-right: 10px;
|
||||
margin-inline-end: 10px;
|
||||
padding: 0 5px; } }
|
||||
.button.block-button:hover, .block-button.highlight-button-cancel:hover, .block-button.highlight-button-save:hover, .block-button.highlight-button-download:hover, .block-button.highlight-button-copy:hover, .block-button.preview-button-save:hover {
|
||||
.button.block-button:hover, .block-button.highlight-button-cancel:hover, .block-button.highlight-button-download:hover, .block-button.highlight-button-copy:hover {
|
||||
background: #ededf0; }
|
||||
.button.block-button:active, .block-button.highlight-button-cancel:active, .block-button.highlight-button-save:active, .block-button.highlight-button-download:active, .block-button.highlight-button-copy:active, .block-button.preview-button-save:active {
|
||||
.button.block-button:active, .block-button.highlight-button-cancel:active, .block-button.highlight-button-download:active, .block-button.highlight-button-copy:active {
|
||||
background: #dedede; }
|
||||
.button.download, .download.highlight-button-cancel, .download.highlight-button-save, .download.highlight-button-download, .download.highlight-button-copy, .download.preview-button-save, .button.edit, .edit.highlight-button-cancel, .edit.highlight-button-save, .edit.highlight-button-download, .edit.highlight-button-copy, .edit.preview-button-save, .button.trash, .trash.highlight-button-cancel, .trash.highlight-button-save, .trash.highlight-button-download, .trash.highlight-button-copy, .trash.preview-button-save, .button.share, .share.highlight-button-cancel, .share.highlight-button-save, .share.highlight-button-download, .share.highlight-button-copy, .share.preview-button-save, .button.flag, .flag.highlight-button-cancel, .flag.highlight-button-save, .flag.highlight-button-download, .flag.highlight-button-copy, .flag.preview-button-save {
|
||||
.button.download, .download.highlight-button-cancel, .download.highlight-button-download, .download.highlight-button-copy, .button.edit, .edit.highlight-button-cancel, .edit.highlight-button-download, .edit.highlight-button-copy, .button.trash, .trash.highlight-button-cancel, .trash.highlight-button-download, .trash.highlight-button-copy, .button.share, .share.highlight-button-cancel, .share.highlight-button-download, .share.highlight-button-copy, .button.flag, .flag.highlight-button-cancel, .flag.highlight-button-download, .flag.highlight-button-copy {
|
||||
background-repeat: no-repeat;
|
||||
background-size: 50%;
|
||||
background-position: center;
|
||||
margin-right: 10px;
|
||||
margin-inline-end: 10px;
|
||||
transition: background-color 150ms cubic-bezier(0.07, 0.95, 0, 1); }
|
||||
.button.download, .download.highlight-button-cancel, .download.highlight-button-save, .download.highlight-button-download, .download.highlight-button-copy, .download.preview-button-save {
|
||||
.button.download, .download.highlight-button-cancel, .download.highlight-button-download, .download.highlight-button-copy {
|
||||
background-image: url("../img/icon-download.svg"); }
|
||||
.button.download:hover, .download.highlight-button-cancel:hover, .download.highlight-button-save:hover, .download.highlight-button-download:hover, .download.highlight-button-copy:hover, .download.preview-button-save:hover {
|
||||
.button.download:hover, .download.highlight-button-cancel:hover, .download.highlight-button-download:hover, .download.highlight-button-copy:hover {
|
||||
background-color: #ededf0; }
|
||||
.button.download:active, .download.highlight-button-cancel:active, .download.highlight-button-save:active, .download.highlight-button-download:active, .download.highlight-button-copy:active, .download.preview-button-save:active {
|
||||
.button.download:active, .download.highlight-button-cancel:active, .download.highlight-button-download:active, .download.highlight-button-copy:active {
|
||||
background-color: #dedede; }
|
||||
.button.share, .share.highlight-button-cancel, .share.highlight-button-save, .share.highlight-button-download, .share.highlight-button-copy, .share.preview-button-save {
|
||||
.button.share, .share.highlight-button-cancel, .share.highlight-button-download, .share.highlight-button-copy {
|
||||
background-image: url("../img/icon-share.svg"); }
|
||||
.button.share:hover, .share.highlight-button-cancel:hover, .share.highlight-button-save:hover, .share.highlight-button-download:hover, .share.highlight-button-copy:hover, .share.preview-button-save:hover {
|
||||
.button.share:hover, .share.highlight-button-cancel:hover, .share.highlight-button-download:hover, .share.highlight-button-copy:hover {
|
||||
background-color: #ededf0; }
|
||||
.button.share.active, .share.active.highlight-button-cancel, .share.active.highlight-button-save, .share.active.highlight-button-download, .share.active.highlight-button-copy, .share.active.preview-button-save, .button.share:active, .share.highlight-button-cancel:active, .share.highlight-button-save:active, .share.highlight-button-download:active, .share.highlight-button-copy:active, .share.preview-button-save:active {
|
||||
.button.share.active, .share.active.highlight-button-cancel, .share.active.highlight-button-download, .share.active.highlight-button-copy, .button.share:active, .share.highlight-button-cancel:active, .share.highlight-button-download:active, .share.highlight-button-copy:active {
|
||||
background-color: #dedede; }
|
||||
.button.share.newicon, .share.newicon.highlight-button-cancel, .share.newicon.highlight-button-save, .share.newicon.highlight-button-download, .share.newicon.highlight-button-copy, .share.newicon.preview-button-save {
|
||||
.button.share.newicon, .share.newicon.highlight-button-cancel, .share.newicon.highlight-button-download, .share.newicon.highlight-button-copy {
|
||||
background-image: url("../img/icon-share-alternate.svg"); }
|
||||
.button.trash, .trash.highlight-button-cancel, .trash.highlight-button-save, .trash.highlight-button-download, .trash.highlight-button-copy, .trash.preview-button-save {
|
||||
.button.trash, .trash.highlight-button-cancel, .trash.highlight-button-download, .trash.highlight-button-copy {
|
||||
background-image: url("../img/icon-trash.svg"); }
|
||||
.button.trash:hover, .trash.highlight-button-cancel:hover, .trash.highlight-button-save:hover, .trash.highlight-button-download:hover, .trash.highlight-button-copy:hover, .trash.preview-button-save:hover {
|
||||
.button.trash:hover, .trash.highlight-button-cancel:hover, .trash.highlight-button-download:hover, .trash.highlight-button-copy:hover {
|
||||
background-color: #ededf0; }
|
||||
.button.trash:active, .trash.highlight-button-cancel:active, .trash.highlight-button-save:active, .trash.highlight-button-download:active, .trash.highlight-button-copy:active, .trash.preview-button-save:active {
|
||||
.button.trash:active, .trash.highlight-button-cancel:active, .trash.highlight-button-download:active, .trash.highlight-button-copy:active {
|
||||
background-color: #dedede; }
|
||||
.button.edit, .edit.highlight-button-cancel, .edit.highlight-button-save, .edit.highlight-button-download, .edit.highlight-button-copy, .edit.preview-button-save {
|
||||
.button.edit, .edit.highlight-button-cancel, .edit.highlight-button-download, .edit.highlight-button-copy {
|
||||
background-image: url("../img/icon-edit.svg"); }
|
||||
.button.edit:hover, .edit.highlight-button-cancel:hover, .edit.highlight-button-save:hover, .edit.highlight-button-download:hover, .edit.highlight-button-copy:hover, .edit.preview-button-save:hover {
|
||||
.button.edit:hover, .edit.highlight-button-cancel:hover, .edit.highlight-button-download:hover, .edit.highlight-button-copy:hover {
|
||||
background-color: #ededf0; }
|
||||
.button.edit:active, .edit.highlight-button-cancel:active, .edit.highlight-button-save:active, .edit.highlight-button-download:active, .edit.highlight-button-copy:active, .edit.preview-button-save:active {
|
||||
.button.edit:active, .edit.highlight-button-cancel:active, .edit.highlight-button-download:active, .edit.highlight-button-copy:active {
|
||||
background-color: #dedede; }
|
||||
|
||||
.app-body {
|
||||
|
@ -117,36 +117,36 @@ window.inlineSelectionCss = `
|
|||
color: #e1e1e6;
|
||||
text-decoration: underline; }
|
||||
|
||||
.button.primary, .primary.highlight-button-cancel, .highlight-button-save, .primary.highlight-button-download, .primary.highlight-button-copy, .preview-button-save {
|
||||
.button.primary, .primary.highlight-button-cancel, .highlight-button-download, .primary.highlight-button-copy {
|
||||
background-color: #0a84ff;
|
||||
color: #fff; }
|
||||
.button.primary:hover, .primary.highlight-button-cancel:hover, .highlight-button-save:hover, .primary.highlight-button-download:hover, .primary.highlight-button-copy:hover, .preview-button-save:hover, .button.primary:focus, .primary.highlight-button-cancel:focus, .highlight-button-save:focus, .primary.highlight-button-download:focus, .primary.highlight-button-copy:focus, .preview-button-save:focus {
|
||||
.button.primary:hover, .primary.highlight-button-cancel:hover, .highlight-button-download:hover, .primary.highlight-button-copy:hover, .button.primary:focus, .primary.highlight-button-cancel:focus, .highlight-button-download:focus, .primary.highlight-button-copy:focus {
|
||||
background-color: #0072e5; }
|
||||
.button.primary:active, .primary.highlight-button-cancel:active, .highlight-button-save:active, .primary.highlight-button-download:active, .primary.highlight-button-copy:active, .preview-button-save:active {
|
||||
.button.primary:active, .primary.highlight-button-cancel:active, .highlight-button-download:active, .primary.highlight-button-copy:active {
|
||||
background-color: #0065cc; }
|
||||
|
||||
.button.secondary, .highlight-button-cancel, .secondary.highlight-button-save, .highlight-button-download, .highlight-button-copy, .secondary.preview-button-save {
|
||||
.button.secondary, .highlight-button-cancel, .secondary.highlight-button-download, .highlight-button-copy {
|
||||
background-color: #f9f9fa;
|
||||
color: #38383d; }
|
||||
.button.secondary:hover, .highlight-button-cancel:hover, .secondary.highlight-button-save:hover, .highlight-button-download:hover, .highlight-button-copy:hover, .secondary.preview-button-save:hover {
|
||||
.button.secondary:hover, .highlight-button-cancel:hover, .secondary.highlight-button-download:hover, .highlight-button-copy:hover {
|
||||
background-color: #ededf0; }
|
||||
.button.secondary:active, .highlight-button-cancel:active, .secondary.highlight-button-save:active, .highlight-button-download:active, .highlight-button-copy:active, .secondary.preview-button-save:active {
|
||||
.button.secondary:active, .highlight-button-cancel:active, .secondary.highlight-button-download:active, .highlight-button-copy:active {
|
||||
background-color: #dedede; }
|
||||
|
||||
.button.transparent, .transparent.highlight-button-cancel, .transparent.highlight-button-save, .transparent.highlight-button-download, .transparent.highlight-button-copy, .transparent.preview-button-save {
|
||||
.button.transparent, .transparent.highlight-button-cancel, .transparent.highlight-button-download, .transparent.highlight-button-copy {
|
||||
background-color: transparent;
|
||||
color: #38383d; }
|
||||
.button.transparent:hover, .transparent.highlight-button-cancel:hover, .transparent.highlight-button-save:hover, .transparent.highlight-button-download:hover, .transparent.highlight-button-copy:hover, .transparent.preview-button-save:hover {
|
||||
.button.transparent:hover, .transparent.highlight-button-cancel:hover, .transparent.highlight-button-download:hover, .transparent.highlight-button-copy:hover {
|
||||
background-color: #ededf0; }
|
||||
.button.transparent:focus, .transparent.highlight-button-cancel:focus, .transparent.highlight-button-save:focus, .transparent.highlight-button-download:focus, .transparent.highlight-button-copy:focus, .transparent.preview-button-save:focus, .button.transparent:active, .transparent.highlight-button-cancel:active, .transparent.highlight-button-save:active, .transparent.highlight-button-download:active, .transparent.highlight-button-copy:active, .transparent.preview-button-save:active {
|
||||
.button.transparent:focus, .transparent.highlight-button-cancel:focus, .transparent.highlight-button-download:focus, .transparent.highlight-button-copy:focus, .button.transparent:active, .transparent.highlight-button-cancel:active, .transparent.highlight-button-download:active, .transparent.highlight-button-copy:active {
|
||||
background-color: #dedede; }
|
||||
|
||||
.button.warning, .warning.highlight-button-cancel, .warning.highlight-button-save, .warning.highlight-button-download, .warning.highlight-button-copy, .warning.preview-button-save {
|
||||
.button.warning, .warning.highlight-button-cancel, .warning.highlight-button-download, .warning.highlight-button-copy {
|
||||
color: #fff;
|
||||
background: #d92215; }
|
||||
.button.warning:hover, .warning.highlight-button-cancel:hover, .warning.highlight-button-save:hover, .warning.highlight-button-download:hover, .warning.highlight-button-copy:hover, .warning.preview-button-save:hover, .button.warning:focus, .warning.highlight-button-cancel:focus, .warning.highlight-button-save:focus, .warning.highlight-button-download:focus, .warning.highlight-button-copy:focus, .warning.preview-button-save:focus {
|
||||
.button.warning:hover, .warning.highlight-button-cancel:hover, .warning.highlight-button-download:hover, .warning.highlight-button-copy:hover, .button.warning:focus, .warning.highlight-button-cancel:focus, .warning.highlight-button-download:focus, .warning.highlight-button-copy:focus {
|
||||
background: #b81d12; }
|
||||
.button.warning:active, .warning.highlight-button-cancel:active, .warning.highlight-button-save:active, .warning.highlight-button-download:active, .warning.highlight-button-copy:active, .warning.preview-button-save:active {
|
||||
.button.warning:active, .warning.highlight-button-cancel:active, .warning.highlight-button-download:active, .warning.highlight-button-copy:active {
|
||||
background: #a11910; }
|
||||
|
||||
.subtitle-link {
|
||||
|
@ -245,9 +245,9 @@ window.inlineSelectionCss = `
|
|||
border: 2px dashed rgba(255, 255, 255, 0.4);
|
||||
bottom: 0;
|
||||
content: "";
|
||||
left: 0;
|
||||
inset-inline-start: 0;
|
||||
position: absolute;
|
||||
right: 0;
|
||||
inset-inline-end: 0;
|
||||
top: 0; }
|
||||
body.hcm .hover-highlight {
|
||||
background-color: white;
|
||||
|
@ -256,14 +256,14 @@ window.inlineSelectionCss = `
|
|||
.mover-target.direction-topLeft {
|
||||
cursor: nwse-resize;
|
||||
height: 60px;
|
||||
left: -30px;
|
||||
inset-inline-start: -30px;
|
||||
top: -30px;
|
||||
width: 60px; }
|
||||
|
||||
.mover-target.direction-top {
|
||||
cursor: ns-resize;
|
||||
height: 60px;
|
||||
left: 0;
|
||||
inset-inline-start: 0;
|
||||
top: -30px;
|
||||
width: 100%;
|
||||
z-index: 4; }
|
||||
|
@ -271,14 +271,14 @@ window.inlineSelectionCss = `
|
|||
.mover-target.direction-topRight {
|
||||
cursor: nesw-resize;
|
||||
height: 60px;
|
||||
right: -30px;
|
||||
inset-inline-end: -30px;
|
||||
top: -30px;
|
||||
width: 60px; }
|
||||
|
||||
.mover-target.direction-left {
|
||||
cursor: ew-resize;
|
||||
height: 100%;
|
||||
left: -30px;
|
||||
inset-inline-start: -30px;
|
||||
top: 0;
|
||||
width: 60px;
|
||||
z-index: 4; }
|
||||
|
@ -286,7 +286,7 @@ window.inlineSelectionCss = `
|
|||
.mover-target.direction-right {
|
||||
cursor: ew-resize;
|
||||
height: 100%;
|
||||
right: -30px;
|
||||
inset-inline-end: -30px;
|
||||
top: 0;
|
||||
width: 60px;
|
||||
z-index: 4; }
|
||||
|
@ -295,14 +295,14 @@ window.inlineSelectionCss = `
|
|||
bottom: -30px;
|
||||
cursor: nesw-resize;
|
||||
height: 60px;
|
||||
left: -30px;
|
||||
inset-inline-start: -30px;
|
||||
width: 60px; }
|
||||
|
||||
.mover-target.direction-bottom {
|
||||
bottom: -30px;
|
||||
cursor: ns-resize;
|
||||
height: 60px;
|
||||
left: 0;
|
||||
inset-inline-start: 0;
|
||||
width: 100%;
|
||||
z-index: 4; }
|
||||
|
||||
|
@ -310,7 +310,7 @@ window.inlineSelectionCss = `
|
|||
bottom: -30px;
|
||||
cursor: nwse-resize;
|
||||
height: 60px;
|
||||
right: -30px;
|
||||
inset-inline-end: -30px;
|
||||
width: 60px; }
|
||||
|
||||
.mover-target:hover .mover {
|
||||
|
@ -332,7 +332,7 @@ window.inlineSelectionCss = `
|
|||
.direction-topLeft .mover,
|
||||
.direction-left .mover,
|
||||
.direction-bottomLeft .mover {
|
||||
left: -1px; }
|
||||
inset-inline-start: -1px; }
|
||||
|
||||
.direction-topLeft .mover,
|
||||
.direction-top .mover,
|
||||
|
@ -342,7 +342,7 @@ window.inlineSelectionCss = `
|
|||
.direction-topRight .mover,
|
||||
.direction-right .mover,
|
||||
.direction-bottomRight .mover {
|
||||
right: -1px; }
|
||||
inset-inline-end: -1px; }
|
||||
|
||||
.direction-bottomRight .mover,
|
||||
.direction-bottom .mover,
|
||||
|
@ -357,90 +357,13 @@ window.inlineSelectionCss = `
|
|||
background-color: black;
|
||||
opacity: 0.7; }
|
||||
|
||||
.notice {
|
||||
display: flex;
|
||||
height: 41px;
|
||||
left: 50%;
|
||||
position: fixed;
|
||||
transform: translate(-50%, 0);
|
||||
transition: top 125ms ease-out, translate 125ms ease-out;
|
||||
user-select: none;
|
||||
will-change: top, translate;
|
||||
z-index: 10000000000; }
|
||||
.notice .notice-wrapper {
|
||||
align-items: center;
|
||||
background: #737373;
|
||||
border-radius: 100px;
|
||||
display: flex;
|
||||
flex-wrap: nowrap;
|
||||
justify-content: space-between;
|
||||
padding: 10px 15px; }
|
||||
.notice .notice-content {
|
||||
color: #fff;
|
||||
flex: 1;
|
||||
font-family: -apple-system, BlinkMacSystemFont, "segoe ui", "helvetica neue", helvetica, ubuntu, roboto, noto, arial, sans-serif;
|
||||
font-size: 14px;
|
||||
font-weight: bold;
|
||||
white-space: nowrap; }
|
||||
.notice .notice-help {
|
||||
background-image: url("MOZ_EXTENSION/icons/help-16.svg");
|
||||
background-position: center center;
|
||||
background-repeat: no-repeat;
|
||||
height: 16px;
|
||||
width: 16px; }
|
||||
.notice.middle {
|
||||
display: none;
|
||||
top: calc(50% - 21px); }
|
||||
|
||||
.preview-button-save:active ~ .notice.middle,
|
||||
.preview-button-save:focus ~ .notice.middle,
|
||||
.preview-button-save:hover ~ .notice.middle {
|
||||
display: block; }
|
||||
|
||||
.notice-tooltip {
|
||||
background: #fff;
|
||||
border-radius: 3px;
|
||||
border: 1px solid #9d9d9e;
|
||||
bottom: 60px;
|
||||
color: #000;
|
||||
cursor: default;
|
||||
display: none;
|
||||
font-family: -apple-system, BlinkMacSystemFont, "segoe ui", "helvetica neue", helvetica, ubuntu, roboto, noto, arial, sans-serif;
|
||||
font-size: 14px;
|
||||
font-weight: normal;
|
||||
line-height: 22px;
|
||||
overflow-wrap: break-word;
|
||||
padding: 15px;
|
||||
position: absolute;
|
||||
right: -14px;
|
||||
white-space: normal;
|
||||
width: 300px;
|
||||
z-index: 10000000000;
|
||||
/* down-arrow for the tooltip */ }
|
||||
.notice:hover .notice-tooltip {
|
||||
display: block; }
|
||||
.notice-tooltip p {
|
||||
margin: 0; }
|
||||
.notice-tooltip ul {
|
||||
margin-bottom: 0; }
|
||||
.notice-tooltip::after {
|
||||
border-left: 10px solid transparent;
|
||||
border-right: 10px solid transparent;
|
||||
border-top: 10px solid #f9f9fa;
|
||||
content: "";
|
||||
height: 0;
|
||||
left: 86%;
|
||||
position: absolute;
|
||||
top: 100%;
|
||||
width: 0; }
|
||||
|
||||
.preview-overlay {
|
||||
align-items: center;
|
||||
background-color: rgba(0, 0, 0, 0.7);
|
||||
display: flex;
|
||||
height: 100%;
|
||||
justify-content: center;
|
||||
left: 0;
|
||||
inset-inline-start: 0;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
position: fixed;
|
||||
|
@ -455,7 +378,7 @@ window.inlineSelectionCss = `
|
|||
cursor: crosshair; }
|
||||
|
||||
.highlight {
|
||||
border-radius: 2px;
|
||||
border-radius: 1px;
|
||||
border: 2px dashed rgba(255, 255, 255, 0.8);
|
||||
box-sizing: border-box;
|
||||
cursor: move;
|
||||
|
@ -469,54 +392,38 @@ window.inlineSelectionCss = `
|
|||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
bottom: -55px;
|
||||
bottom: -58px;
|
||||
position: absolute;
|
||||
inset-inline-end: 5px;
|
||||
z-index: 6; }
|
||||
html[dir="rtl"] .highlight-buttons {
|
||||
left: 5px; }
|
||||
html[dir="ltr"] .highlight-buttons {
|
||||
right: 5px; }
|
||||
.bottom-selection .highlight-buttons {
|
||||
bottom: 5px; }
|
||||
.left-selection .highlight-buttons {
|
||||
right: auto;
|
||||
left: 5px; }
|
||||
inset-inline-end: auto;
|
||||
inset-inline-start: 5px; }
|
||||
.highlight-buttons > button {
|
||||
box-shadow: 0 0 0 1px rgba(12, 12, 13, 0.1), 0 2px 8px rgba(12, 12, 13, 0.1); }
|
||||
|
||||
.highlight-button-cancel {
|
||||
border: 1px solid #dedede;
|
||||
margin: 5px;
|
||||
width: 40px; }
|
||||
|
||||
.highlight-button-save {
|
||||
font-size: 18px;
|
||||
margin: 5px;
|
||||
min-width: 80px; }
|
||||
html[dir="ltr"] .highlight-button-save img {
|
||||
padding-right: 8px; }
|
||||
html[dir="rtl"] .highlight-button-save img {
|
||||
padding-left: 8px; }
|
||||
|
||||
.highlight-button-download {
|
||||
border: 1px solid #dedede;
|
||||
display: block;
|
||||
margin: 5px;
|
||||
width: 40px; }
|
||||
.highlight-button-download.download-only-button {
|
||||
font-size: 18px;
|
||||
width: auto; }
|
||||
.highlight-button-download.download-only-button img {
|
||||
height: 16px;
|
||||
width: 16px; }
|
||||
html[dir="ltr"] .highlight-button-download.download-only-button img {
|
||||
padding-right: 8px; }
|
||||
html[dir="rtl"] .highlight-button-download.download-only-button img {
|
||||
padding-left: 8px; }
|
||||
width: auto;
|
||||
font-size: 18px; }
|
||||
.highlight-button-download img {
|
||||
height: 16px;
|
||||
width: 16px;
|
||||
padding-inline-end: 8px; }
|
||||
|
||||
.highlight-button-copy {
|
||||
border: 1px solid #dedede;
|
||||
display: block;
|
||||
margin: 5px;
|
||||
width: 40px; }
|
||||
width: auto; }
|
||||
.highlight-button-copy img {
|
||||
height: 16px;
|
||||
width: 16px;
|
||||
padding-inline-end: 8px; }
|
||||
|
||||
.pixel-dimensions {
|
||||
position: absolute;
|
||||
|
@ -530,40 +437,51 @@ window.inlineSelectionCss = `
|
|||
.preview-buttons {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
justify-content: flex-end;
|
||||
padding-inline-end: 4px;
|
||||
inset-inline-end: 0;
|
||||
width: 100%;
|
||||
position: absolute;
|
||||
top: -2px; }
|
||||
html[dir="rtl"] .preview-buttons {
|
||||
left: 0; }
|
||||
html[dir="ltr"] .preview-buttons {
|
||||
right: 0; }
|
||||
height: 60px;
|
||||
border-radius: 4px 4px 0 0;
|
||||
background: rgba(249, 249, 250, 0.8);
|
||||
top: 0;
|
||||
border: 1px solid rgba(249, 249, 250, 0.2);
|
||||
border-bottom: 0;
|
||||
box-sizing: border-box; }
|
||||
|
||||
.preview-image {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
flex-direction: column;
|
||||
justify-content: center;
|
||||
margin: 24px auto;
|
||||
position: relative;
|
||||
height: 80%;
|
||||
max-width: 100%;
|
||||
margin: auto 2em;
|
||||
max-width: 80%;
|
||||
max-height: 95%;
|
||||
text-align: center;
|
||||
animation-delay: 50ms;
|
||||
animation: bounce-in 300ms forwards ease-in-out; }
|
||||
display: flex; }
|
||||
|
||||
.preview-image > img {
|
||||
.preview-image-wrapper {
|
||||
background: rgba(249, 249, 250, 0.8);
|
||||
border-radius: 0 0 4px 4px;
|
||||
display: block;
|
||||
width: auto;
|
||||
height: auto;
|
||||
max-width: 100%;
|
||||
max-height: 90%;
|
||||
margin: 50px auto;
|
||||
border: 1px solid rgba(255, 255, 255, 0.8); }
|
||||
min-width: 320px;
|
||||
overflow-y: scroll;
|
||||
padding: 0 60px;
|
||||
margin-top: 60px;
|
||||
border: 1px solid rgba(249, 249, 250, 0.2);
|
||||
border-top: 0; }
|
||||
|
||||
.preview-button-save {
|
||||
font-size: 18px;
|
||||
margin: 5px;
|
||||
min-width: 80px; }
|
||||
html[dir="ltr"] .preview-button-save img {
|
||||
padding-right: 8px; }
|
||||
html[dir="rtl"] .preview-button-save img {
|
||||
padding-left: 8px; }
|
||||
.preview-image-wrapper > img {
|
||||
box-shadow: 0 0 0 1px rgba(12, 12, 13, 0.1), 0 2px 8px rgba(12, 12, 13, 0.1);
|
||||
height: auto;
|
||||
margin-bottom: 60px;
|
||||
max-width: 100%;
|
||||
width: 100%; }
|
||||
|
||||
.fixed-container {
|
||||
align-items: center;
|
||||
|
@ -571,7 +489,7 @@ window.inlineSelectionCss = `
|
|||
flex-direction: column;
|
||||
height: 100vh;
|
||||
justify-content: center;
|
||||
left: 0;
|
||||
inset-inline-start: 0;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
pointer-events: none;
|
||||
|
@ -597,7 +515,7 @@ window.inlineSelectionCss = `
|
|||
position: absolute;
|
||||
border-radius: 100%;
|
||||
overflow: hidden;
|
||||
left: 16.4px;
|
||||
inset-inline-start: 16.4px;
|
||||
top: 19.8px; }
|
||||
|
||||
.eyeball {
|
||||
|
@ -606,15 +524,15 @@ window.inlineSelectionCss = `
|
|||
height: 6px;
|
||||
background-color: #000;
|
||||
border-radius: 50%;
|
||||
left: 2.4px;
|
||||
inset-inline-start: 2.4px;
|
||||
top: 4.3px;
|
||||
z-index: 10; }
|
||||
|
||||
.left {
|
||||
margin-left: 0; }
|
||||
margin-inline-start: 0; }
|
||||
|
||||
.right {
|
||||
margin-left: 20px; }
|
||||
margin-inline-start: 20px; }
|
||||
|
||||
.preview-instructions {
|
||||
display: flex;
|
||||
|
@ -653,11 +571,9 @@ window.inlineSelectionCss = `
|
|||
height: 80px;
|
||||
padding: 8px;
|
||||
position: absolute;
|
||||
right: 5px;
|
||||
top: 5px; }
|
||||
html[dir="rtl"] .myshots-all-buttons-container {
|
||||
left: 5px;
|
||||
right: inherit; }
|
||||
inset-inline-end: 8px;
|
||||
top: 8px;
|
||||
box-shadow: 0 0 0 1px rgba(12, 12, 13, 0.1), 0 2px 8px rgba(12, 12, 13, 0.1); }
|
||||
.myshots-all-buttons-container .spacer {
|
||||
background-color: #c9c9c9;
|
||||
flex: 0 0 1px;
|
||||
|
@ -670,6 +586,7 @@ window.inlineSelectionCss = `
|
|||
align-items: center;
|
||||
flex-direction: column;
|
||||
justify-content: flex-end;
|
||||
color: #3e3d40;
|
||||
background-color: #f5f5f5;
|
||||
background-position: center top;
|
||||
background-repeat: no-repeat;
|
||||
|
|
|
@ -122,7 +122,7 @@ body {
|
|||
border-radius: 2px;
|
||||
color: #fff;
|
||||
font-size: 16px;
|
||||
margin-left: 5px;
|
||||
margin-inline-start: 5px;
|
||||
padding: 2px; }
|
||||
.slide p {
|
||||
animation-duration: 350ms;
|
||||
|
@ -219,21 +219,15 @@ body {
|
|||
|
||||
#prev {
|
||||
background-image: url("MOZ_EXTENSION/icons/back.svg");
|
||||
left: 50%; }
|
||||
html[dir="ltr"] #prev {
|
||||
margin-left: -385px; }
|
||||
html[dir="rtl"] #prev {
|
||||
margin-left: 315px; }
|
||||
inset-inline-start: 50%;
|
||||
margin-inline-start: -385px; }
|
||||
[dir="rtl"] #prev {
|
||||
transform: rotate(180deg); }
|
||||
|
||||
#next,
|
||||
#done {
|
||||
left: 50%; }
|
||||
html[dir="ltr"] #next, html[dir="ltr"]
|
||||
#done {
|
||||
margin-left: 315px; }
|
||||
html[dir="rtl"] #next, html[dir="rtl"]
|
||||
#done {
|
||||
margin-left: -385px; }
|
||||
inset-inline-start: 50%;
|
||||
margin-inline-start: 315px; }
|
||||
|
||||
#prev,
|
||||
#next,
|
||||
|
@ -255,22 +249,18 @@ body {
|
|||
#next {
|
||||
background-image: url("MOZ_EXTENSION/icons/back.svg");
|
||||
transform: rotate(180deg); }
|
||||
[dir="rtl"] #next {
|
||||
transform: rotate(0deg); }
|
||||
.active-slide-1 #next {
|
||||
background-image: url("MOZ_EXTENSION/icons/back-highlight.svg"); }
|
||||
|
||||
[dir='rtl'] #next {
|
||||
transform: rotate(0deg); }
|
||||
|
||||
[dir='rtl'] #prev {
|
||||
transform: rotate(180deg); }
|
||||
|
||||
#skip {
|
||||
background: none;
|
||||
border: 0;
|
||||
color: #fff;
|
||||
font-size: 16px;
|
||||
left: 50%;
|
||||
margin-left: -330px;
|
||||
inset-inline-start: 50%;
|
||||
margin-inline-start: -330px;
|
||||
margin-top: 257px;
|
||||
opacity: 0.7;
|
||||
position: absolute;
|
||||
|
@ -289,7 +279,7 @@ body {
|
|||
background-image: url("MOZ_EXTENSION/icons/done.svg");
|
||||
display: none; }
|
||||
|
||||
.active-slide-6 #done {
|
||||
.active-slide-4 #done {
|
||||
display: inline-block; }
|
||||
|
||||
/* for smaller screen sizes */
|
||||
|
@ -314,13 +304,13 @@ body {
|
|||
font-size: 10px;
|
||||
line-height: 16px; }
|
||||
#skip {
|
||||
margin-left: -205px;
|
||||
margin-inline-start: -205px;
|
||||
margin-top: 177px; }
|
||||
#prev {
|
||||
margin-left: -260px; }
|
||||
margin-inline-start: -260px; }
|
||||
#next,
|
||||
#done {
|
||||
margin-left: 190px; } }
|
||||
margin-inline-start: 190px; } }
|
||||
|
||||
`;
|
||||
null;
|
||||
|
|
|
@ -10,14 +10,14 @@ window.onboardingHtml = `
|
|||
<body>
|
||||
<div id="slide-overlay">
|
||||
<!-- The current slide is set by having .active-slide-1, .active-slide-2, etc on #slide element: -->
|
||||
<div id="slide-container" data-number-of-slides="6" class="active-slide-1">
|
||||
<div id="slide-container" data-number-of-slides="4" class="active-slide-1">
|
||||
<div class="slide slide-1">
|
||||
<!-- Note: all images must be listed in manifest.json.template under web_accessible_resources -->
|
||||
<div class="slide-image" style="background-image: url('MOZ_EXTENSION/icons/onboarding-1.png');"></div>
|
||||
<div class="slide-content">
|
||||
<div class="slide-content-aligner">
|
||||
<h1><span><strong>Firefox</strong> Screenshots</span><sup>Beta</sup></h1>
|
||||
<p data-l10n-id="tourBodyIntro"></p>
|
||||
<h1><span><strong>Firefox</strong> Screenshots</span></h1>
|
||||
<p data-l10n-id="tourBodyIntroServerless"></p>
|
||||
</div>
|
||||
<p class="onboarding-legal-notice"><!-- Substituted with termsAndPrivacyNotice --></p>
|
||||
</div>
|
||||
|
@ -43,20 +43,6 @@ window.onboardingHtml = `
|
|||
<p data-l10n-id="tourBodyFullPage"></p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="slide slide-5">
|
||||
<div class="slide-image" style="background-image: url('MOZ_EXTENSION/icons/onboarding-5.png');"></div>
|
||||
<div class="slide-content">
|
||||
<h1 data-l10n-id="tourHeaderDownloadUpload"></h1>
|
||||
<p data-l10n-id="tourBodyDownloadUpload"></p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="slide slide-6">
|
||||
<div class="slide-image" style="background-image: url('MOZ_EXTENSION/icons/onboarding-6.png');"></div>
|
||||
<div class="slide-content">
|
||||
<h1 data-l10n-id="tourHeaderAccounts"></h1>
|
||||
<p data-l10n-id="tourBodyAccounts"></p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Clickable elements should be buttons for accessibility -->
|
||||
<button id="skip" data-l10n-id="tourSkip" tabindex=1>Skip</button>
|
||||
|
@ -68,8 +54,6 @@ window.onboardingHtml = `
|
|||
<button class="goto-slide goto-slide-2" data-number="2" tabindex=5></button>
|
||||
<button class="goto-slide goto-slide-3" data-number="3" tabindex=6></button>
|
||||
<button class="goto-slide goto-slide-4" data-number="4" tabindex=7></button>
|
||||
<button class="goto-slide goto-slide-5" data-number="5" tabindex=8></button>
|
||||
<button class="goto-slide goto-slide-6" data-number="6" tabindex=9></button>
|
||||
</div>
|
||||
<!-- FIXME: Need to put in privacy / etc links -->
|
||||
</div>
|
||||
|
|
|
@ -332,6 +332,14 @@ class AbstractShot {
|
|||
this._origin = val || undefined;
|
||||
}
|
||||
|
||||
get isOwner() {
|
||||
return this._isOwner;
|
||||
}
|
||||
|
||||
set isOwner(val) {
|
||||
this._isOwner = val || undefined;
|
||||
}
|
||||
|
||||
get filename() {
|
||||
let filenameTitle = this.title;
|
||||
const date = new Date(this.createdDate);
|
||||
|
|
|
@ -0,0 +1 @@
|
|||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20"><path d="M9.1 12L4.9 7.9c-.5-.5-1.3-.5-1.8 0s-.5 1.3 0 1.8l6.2 6.2c.5.5 1.3.5 1.8 0l6.2-6.2c.5-.5.5-1.3 0-1.8s-1.3-.5-1.8 0L11.6 12V1.2C11.6.6 11 0 10.3 0c-.7 0-1.2.6-1.2 1.2V12zM4 20c-.7 0-1.2-.6-1.2-1.2s.6-1.2 1.2-1.2h12.5c.7 0 1.2.6 1.2 1.2s-.5 1.2-1.2 1.2H4z" fill="#fff"/></svg>
|
После Ширина: | Высота: | Размер: 343 B |
Двоичные данные
browser/extensions/screenshots/icons/onboarding-3.png
До Ширина: | Высота: | Размер: 70 KiB После Ширина: | Высота: | Размер: 69 KiB |
Двоичные данные
browser/extensions/screenshots/icons/onboarding-4.png
До Ширина: | Высота: | Размер: 34 KiB После Ширина: | Высота: | Размер: 29 KiB |
Двоичные данные
browser/extensions/screenshots/icons/onboarding-5.png
До Ширина: | Высота: | Размер: 15 KiB |
Двоичные данные
browser/extensions/screenshots/icons/onboarding-6.png
До Ширина: | Высота: | Размер: 22 KiB |
|
@ -1,10 +1,11 @@
|
|||
{
|
||||
"manifest_version": 2,
|
||||
"name": "Firefox Screenshots",
|
||||
"version": "35.0.0",
|
||||
"version": "37.1.0",
|
||||
"description": "__MSG_addonDescription__",
|
||||
"author": "__MSG_addonAuthorsList__",
|
||||
"homepage_url": "https://github.com/mozilla-services/screenshots",
|
||||
"incognito": "spanning",
|
||||
"applications": {
|
||||
"gecko": {
|
||||
"id": "screenshots@mozilla.org",
|
||||
|
@ -18,6 +19,14 @@
|
|||
"background/startBackground.js"
|
||||
]
|
||||
},
|
||||
"commands": {
|
||||
"take-screenshot": {
|
||||
"suggested_key": {
|
||||
"default": "Ctrl+Shift+S"
|
||||
},
|
||||
"description": "Open the Firefox Screenshots UI"
|
||||
}
|
||||
},
|
||||
"content_scripts": [
|
||||
{
|
||||
"matches": ["https://screenshots.firefox.com/*"],
|
||||
|
|
|
@ -429,6 +429,7 @@ FINAL_TARGET_FILES.features['screenshots@mozilla.org']["icons"] += [
|
|||
'icons/copied-notification.svg',
|
||||
'icons/copy.svg',
|
||||
'icons/done.svg',
|
||||
'icons/download-white.svg',
|
||||
'icons/download.svg',
|
||||
'icons/help-16.svg',
|
||||
'icons/icon-highlight-32-v2.svg',
|
||||
|
@ -441,9 +442,7 @@ FINAL_TARGET_FILES.features['screenshots@mozilla.org']["icons"] += [
|
|||
'icons/onboarding-1.png',
|
||||
'icons/onboarding-2.png',
|
||||
'icons/onboarding-3.png',
|
||||
'icons/onboarding-4.png',
|
||||
'icons/onboarding-5.png',
|
||||
'icons/onboarding-6.png'
|
||||
'icons/onboarding-4.png'
|
||||
]
|
||||
|
||||
FINAL_TARGET_FILES.features['screenshots@mozilla.org']["onboarding"] += [
|
||||
|
@ -460,12 +459,6 @@ FINAL_TARGET_FILES.features['screenshots@mozilla.org']["selector"] += [
|
|||
'selector/util.js'
|
||||
]
|
||||
|
||||
FINAL_TARGET_FILES.features['screenshots@mozilla.org']["test"]["browser"] += [
|
||||
'test/browser/.eslintrc.yml',
|
||||
'test/browser/browser.ini',
|
||||
'test/browser/browser_screenshots_ui_check.js'
|
||||
]
|
||||
|
||||
# AUTOMATIC INSERTION END
|
||||
|
||||
BROWSER_CHROME_MANIFESTS += [
|
||||
|
|
|
@ -8,14 +8,14 @@
|
|||
<body>
|
||||
<div id="slide-overlay">
|
||||
<!-- The current slide is set by having .active-slide-1, .active-slide-2, etc on #slide element: -->
|
||||
<div id="slide-container" data-number-of-slides="6" class="active-slide-1">
|
||||
<div id="slide-container" data-number-of-slides="4" class="active-slide-1">
|
||||
<div class="slide slide-1">
|
||||
<!-- Note: all images must be listed in manifest.json.template under web_accessible_resources -->
|
||||
<div class="slide-image" style="background-image: url('MOZ_EXTENSION/icons/onboarding-1.png');"></div>
|
||||
<div class="slide-content">
|
||||
<div class="slide-content-aligner">
|
||||
<h1><span><strong>Firefox</strong> Screenshots</span><sup>Beta</sup></h1>
|
||||
<p data-l10n-id="tourBodyIntro"></p>
|
||||
<h1><span><strong>Firefox</strong> Screenshots</span></h1>
|
||||
<p data-l10n-id="tourBodyIntroServerless"></p>
|
||||
</div>
|
||||
<p class="onboarding-legal-notice"><!-- Substituted with termsAndPrivacyNotice --></p>
|
||||
</div>
|
||||
|
@ -41,20 +41,6 @@
|
|||
<p data-l10n-id="tourBodyFullPage"></p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="slide slide-5">
|
||||
<div class="slide-image" style="background-image: url('MOZ_EXTENSION/icons/onboarding-5.png');"></div>
|
||||
<div class="slide-content">
|
||||
<h1 data-l10n-id="tourHeaderDownloadUpload"></h1>
|
||||
<p data-l10n-id="tourBodyDownloadUpload"></p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="slide slide-6">
|
||||
<div class="slide-image" style="background-image: url('MOZ_EXTENSION/icons/onboarding-6.png');"></div>
|
||||
<div class="slide-content">
|
||||
<h1 data-l10n-id="tourHeaderAccounts"></h1>
|
||||
<p data-l10n-id="tourBodyAccounts"></p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Clickable elements should be buttons for accessibility -->
|
||||
<button id="skip" data-l10n-id="tourSkip" tabindex=1>Skip</button>
|
||||
|
@ -66,8 +52,6 @@
|
|||
<button class="goto-slide goto-slide-2" data-number="2" tabindex=5></button>
|
||||
<button class="goto-slide goto-slide-3" data-number="3" tabindex=6></button>
|
||||
<button class="goto-slide goto-slide-4" data-number="4" tabindex=7></button>
|
||||
<button class="goto-slide goto-slide-5" data-number="5" tabindex=8></button>
|
||||
<button class="goto-slide goto-slide-6" data-number="6" tabindex=9></button>
|
||||
</div>
|
||||
<!-- FIXME: Need to put in privacy / etc links -->
|
||||
</div>
|
||||
|
|
|
@ -53,10 +53,13 @@ this.slides = (function() {
|
|||
doc.documentElement.lang = browser.i18n.getMessage("@@ui_locale");
|
||||
localizeText(doc);
|
||||
activateSlide(doc);
|
||||
// Give the DOM a moment to settle before applying focus
|
||||
setTimeout(() => {
|
||||
iframe.contentWindow.focus();
|
||||
});
|
||||
resolve();
|
||||
}), {once: true});
|
||||
document.body.appendChild(iframe);
|
||||
iframe.focus();
|
||||
window.addEventListener("resize", onResize);
|
||||
});
|
||||
};
|
||||
|
|
|
@ -79,37 +79,10 @@ this.ui = (function() { // eslint-disable-line no-unused-vars
|
|||
return (computed && computed.backgroundImage === "none");
|
||||
}
|
||||
|
||||
const isDownloadOnly = exports.isDownloadOnly = function() {
|
||||
return window.downloadOnly;
|
||||
const showMyShots = exports.showMyShots = function() {
|
||||
return window.hasAnyShots;
|
||||
};
|
||||
|
||||
// the download notice is rendered in iframes that match the document height
|
||||
// or the window height. If parent iframe matches window height, pass in true
|
||||
function renderDownloadNotice(initAtBottom = false) {
|
||||
const notice = makeEl("table", "notice");
|
||||
notice.innerHTML = `
|
||||
<div class="notice-tooltip">
|
||||
<p data-l10n-id="downloadOnlyDetails"></p>
|
||||
<ul>
|
||||
<li data-l10n-id="downloadOnlyDetailsPrivate"></li>
|
||||
<li data-l10n-id="downloadOnlyDetailsNeverRemember"></li>
|
||||
<li data-l10n-id="downloadOnlyDetailsESR"></li>
|
||||
<li data-l10n-id="downloadOnlyDetailsNoUploadPref"></li>
|
||||
</ul>
|
||||
</div>
|
||||
<tbody>
|
||||
<tr class="notice-wrapper">
|
||||
<td class="notice-content" data-l10n-id="downloadOnlyNotice"></td>
|
||||
<td class="notice-help"></td>
|
||||
</tr>
|
||||
<tbody>`;
|
||||
localizeText(notice);
|
||||
if (initAtBottom) {
|
||||
notice.style.bottom = "10px";
|
||||
}
|
||||
return notice;
|
||||
}
|
||||
|
||||
function initializeIframe() {
|
||||
const el = document.createElement("iframe");
|
||||
el.src = browser.extension.getURL("blank.html");
|
||||
|
@ -300,10 +273,10 @@ this.ui = (function() { // eslint-disable-line no-unused-vars
|
|||
<div class="preview-instructions" data-l10n-id="screenshotInstructions"></div>
|
||||
<button class="cancel-shot">${browser.i18n.getMessage("cancelScreenshot")}</button>
|
||||
<div class="myshots-all-buttons-container">
|
||||
${isDownloadOnly() ? "" : `
|
||||
${showMyShots() ? `
|
||||
<button class="myshots-button" tabindex="3" data-l10n-id="myShotsLink"></button>
|
||||
<div class="spacer"></div>
|
||||
`}
|
||||
` : ""}
|
||||
<button class="visible" tabindex="2" data-l10n-id="saveScreenshotVisibleArea"></button>
|
||||
<button class="full-page" tabindex="1" data-l10n-id="saveScreenshotFullPage"></button>
|
||||
</div>
|
||||
|
@ -318,7 +291,7 @@ this.ui = (function() { // eslint-disable-line no-unused-vars
|
|||
this.document.documentElement.lang = browser.i18n.getMessage("@@ui_locale");
|
||||
const overlay = this.document.querySelector(".preview-overlay");
|
||||
localizeText(this.document);
|
||||
if (!(isDownloadOnly())) {
|
||||
if (showMyShots()) {
|
||||
overlay.querySelector(".myshots-button").addEventListener(
|
||||
"click", watchFunction(assertIsTrusted(standardOverlayCallbacks.onOpenMyShots)));
|
||||
}
|
||||
|
@ -409,22 +382,14 @@ this.ui = (function() { // eslint-disable-line no-unused-vars
|
|||
data-l10n-title="cancelScreenshot"><img
|
||||
src="${browser.extension.getURL("icons/cancel.svg")}" /></button>
|
||||
<button class="highlight-button-copy"
|
||||
data-l10n-title="copyScreenshot"><img
|
||||
src="${browser.extension.getURL("icons/copy.svg")}" /></button>
|
||||
${isDownloadOnly() ?
|
||||
`<button class="highlight-button-download download-only-button"
|
||||
data-l10n-title="downloadScreenshot"><img
|
||||
src="${browser.extension.getURL("icons/download.svg")}"
|
||||
/>${browser.i18n.getMessage("downloadScreenshot")}</button>` :
|
||||
`<button class="highlight-button-download"
|
||||
data-l10n-title="downloadScreenshot"><img
|
||||
src="${browser.extension.getURL("icons/download.svg")}" /></button>
|
||||
<button class="preview-button-save"
|
||||
data-l10n-title="saveScreenshotSelectedArea"><img
|
||||
src="${browser.extension.getURL("icons/cloud.svg")}"
|
||||
/>${browser.i18n.getMessage("saveScreenshotSelectedArea")}</button>`
|
||||
}
|
||||
data-l10n-title="copyScreenshotTitle"><img
|
||||
src="${browser.extension.getURL("icons/copy.svg")}" />${browser.i18n.getMessage("copyScreenshot")}</button>
|
||||
<button class="highlight-button-download"
|
||||
data-l10n-title="downloadScreenshotTitle"><img
|
||||
src="${browser.extension.getURL("icons/download-white.svg")}"
|
||||
/>${browser.i18n.getMessage("downloadScreenshot")}</button>
|
||||
</div>
|
||||
<div class="preview-image-wrapper"></div>
|
||||
</div>
|
||||
<div class="loader" style="display:none">
|
||||
<div class="loader-inner"></div>
|
||||
|
@ -436,12 +401,6 @@ this.ui = (function() { // eslint-disable-line no-unused-vars
|
|||
this.document.documentElement.lang = browser.i18n.getMessage("@@ui_locale");
|
||||
localizeText(this.document);
|
||||
const overlay = this.document.querySelector(".preview-overlay");
|
||||
if (isDownloadOnly()) {
|
||||
overlay.appendChild(renderDownloadNotice(true));
|
||||
} else {
|
||||
overlay.querySelector(".preview-button-save").addEventListener(
|
||||
"click", watchFunction(assertIsTrusted(standardOverlayCallbacks.onSavePreview)));
|
||||
}
|
||||
overlay.querySelector(".highlight-button-copy").addEventListener(
|
||||
"click", watchFunction(assertIsTrusted(standardOverlayCallbacks.onCopyPreview)));
|
||||
overlay.querySelector(".highlight-button-download").addEventListener(
|
||||
|
@ -471,7 +430,6 @@ this.ui = (function() { // eslint-disable-line no-unused-vars
|
|||
|
||||
showLoader() {
|
||||
this.document.body.querySelector(".preview-image").style.display = "none";
|
||||
this.document.body.querySelector(".notice").style.display = "none";
|
||||
this.document.body.querySelector(".loader").style.display = "";
|
||||
},
|
||||
|
||||
|
@ -642,24 +600,6 @@ this.ui = (function() { // eslint-disable-line no-unused-vars
|
|||
this.bgRight.style.height = `${pos.bottom - pos.top}px`;
|
||||
this.bgRight.style.left = `${pos.right}px`;
|
||||
this.bgRight.style.width = `calc(100% - ${pos.right}px)`;
|
||||
// the download notice is injected into an iframe that matches the document size
|
||||
// in order to reposition it on scroll we need to bind an updated positioning
|
||||
// function to some window events.
|
||||
this.repositionDownloadNotice = () => {
|
||||
if (this.downloadNotice) {
|
||||
const currentYOffset = window.pageYOffset;
|
||||
const currentWinBottom = window.innerHeight;
|
||||
this.downloadNotice.style.top = (currentYOffset + currentWinBottom - 60) + "px";
|
||||
}
|
||||
};
|
||||
|
||||
if (this.downloadNotice) {
|
||||
this.downloadNotice.style.top = (pageYOffset + winBottom - 60) + "px";
|
||||
// event callbacks are delayed 100ms each to keep from overloading things
|
||||
this.windowChangeStop = this.delayExecution(100, this.repositionDownloadNotice);
|
||||
window.addEventListener("scroll", watchFunction(assertIsTrusted(this.windowChangeStop)));
|
||||
window.addEventListener("resize", watchFunction(assertIsTrusted(this.windowChangeStop)));
|
||||
}
|
||||
},
|
||||
|
||||
// used to eventually move the download-only warning
|
||||
|
@ -675,11 +615,7 @@ this.ui = (function() { // eslint-disable-line no-unused-vars
|
|||
},
|
||||
|
||||
remove() {
|
||||
if (this.downloadNotice) {
|
||||
window.removeEventListener("scroll", this.windowChangeStop, true);
|
||||
window.removeEventListener("resize", this.windowChangeStop, true);
|
||||
}
|
||||
for (const name of ["el", "bgTop", "bgLeft", "bgRight", "bgBottom", "downloadNotice"]) {
|
||||
for (const name of ["el", "bgTop", "bgLeft", "bgRight", "bgBottom"]) {
|
||||
if (name in this) {
|
||||
util.removeNode(this[name]);
|
||||
this[name] = null;
|
||||
|
@ -702,42 +638,26 @@ this.ui = (function() { // eslint-disable-line no-unused-vars
|
|||
buttons.appendChild(cancel);
|
||||
|
||||
const copy = makeEl("button", "highlight-button-copy");
|
||||
copy.title = browser.i18n.getMessage("copyScreenshot");
|
||||
copy.title = browser.i18n.getMessage("copyScreenshotTitle");
|
||||
const copyImg = makeEl("img");
|
||||
const copyString = makeEl("span");
|
||||
copyString.textContent = browser.i18n.getMessage("copyScreenshot");
|
||||
copyImg.src = browser.extension.getURL("icons/copy.svg");
|
||||
copy.appendChild(copyImg);
|
||||
copy.appendChild(copyString);
|
||||
buttons.appendChild(copy);
|
||||
|
||||
let download, save;
|
||||
|
||||
if (isDownloadOnly()) {
|
||||
download = makeEl("button", "highlight-button-download download-only-button");
|
||||
const downloadImg = makeEl("img");
|
||||
downloadImg.src = browser.extension.getURL("icons/download.svg");
|
||||
download.appendChild(downloadImg);
|
||||
download.append(browser.i18n.getMessage("downloadScreenshot"));
|
||||
download.title = browser.i18n.getMessage("downloadScreenshot");
|
||||
} else {
|
||||
download = makeEl("button", "highlight-button-download");
|
||||
download.title = browser.i18n.getMessage("downloadScreenshot");
|
||||
const downloadImg = makeEl("img");
|
||||
downloadImg.src = browser.extension.getURL("icons/download.svg");
|
||||
download.appendChild(downloadImg);
|
||||
save = makeEl("button", "highlight-button-save");
|
||||
const saveImg = makeEl("img");
|
||||
saveImg.src = browser.extension.getURL("icons/cloud.svg");
|
||||
save.appendChild(saveImg);
|
||||
save.append(browser.i18n.getMessage("saveScreenshotSelectedArea"));
|
||||
save.title = browser.i18n.getMessage("saveScreenshotSelectedArea");
|
||||
}
|
||||
const download = makeEl("button", "highlight-button-download");
|
||||
const downloadImg = makeEl("img");
|
||||
downloadImg.src = browser.extension.getURL("icons/download-white.svg");
|
||||
download.appendChild(downloadImg);
|
||||
download.append(browser.i18n.getMessage("downloadScreenshot"));
|
||||
download.title = browser.i18n.getMessage("downloadScreenshotTitle");
|
||||
buttons.appendChild(download);
|
||||
if (save) {
|
||||
buttons.appendChild(save);
|
||||
}
|
||||
this.cancel = cancel;
|
||||
this.download = download;
|
||||
this.copy = copy;
|
||||
this.save = save;
|
||||
|
||||
boxEl.appendChild(buttons);
|
||||
for (const name of movements) {
|
||||
const elTarget = makeEl("div", "mover-target direction-" + name);
|
||||
|
@ -754,10 +674,6 @@ this.ui = (function() { // eslint-disable-line no-unused-vars
|
|||
this.bgBottom = makeEl("div", "bghighlight");
|
||||
iframe.document().body.appendChild(this.bgBottom);
|
||||
iframe.document().body.appendChild(boxEl);
|
||||
if (isDownloadOnly()) {
|
||||
this.downloadNotice = renderDownloadNotice();
|
||||
iframe.document().body.appendChild(this.downloadNotice);
|
||||
}
|
||||
this.el = boxEl;
|
||||
},
|
||||
|
||||
|
@ -838,9 +754,6 @@ this.ui = (function() { // eslint-disable-line no-unused-vars
|
|||
if (this.el) {
|
||||
this.el.style.display = "none";
|
||||
}
|
||||
if (this.downloadNotice) {
|
||||
this.downloadNotice.display = "none";
|
||||
}
|
||||
},
|
||||
|
||||
remove() {
|
||||
|
@ -874,22 +787,11 @@ this.ui = (function() { // eslint-disable-line no-unused-vars
|
|||
};
|
||||
|
||||
exports.Preview = {
|
||||
display(dataUrl, showCropWarning) {
|
||||
display(dataUrl) {
|
||||
const img = makeEl("IMG");
|
||||
const imgBlob = blobConverters.dataUrlToBlob(dataUrl);
|
||||
img.src = URL.createObjectURL(imgBlob);
|
||||
iframe.document().querySelector(".preview-image").appendChild(img);
|
||||
if (showCropWarning && !(isDownloadOnly())) {
|
||||
const imageCroppedEl = makeEl("table", "notice middle");
|
||||
imageCroppedEl.innerHTML = `<tbody>
|
||||
<tr class="notice-wrapper">
|
||||
<td class="notice-content"></td>
|
||||
</tr>
|
||||
</tbody>`;
|
||||
const contentCell = imageCroppedEl.getElementsByTagName("td");
|
||||
contentCell[0].textContent = browser.i18n.getMessage("imageCropPopupWarning", buildSettings.maxImageHeight);
|
||||
iframe.document().querySelector(".preview-buttons").appendChild(imageCroppedEl);
|
||||
}
|
||||
iframe.document().querySelector(".preview-image-wrapper").appendChild(img);
|
||||
},
|
||||
};
|
||||
|
||||
|
|
|
@ -911,13 +911,8 @@ this.uicontrol = (function() {
|
|||
if ((event.key || event.code) === "Enter"
|
||||
&& getState.state === "selected"
|
||||
&& ui.iframe.document().activeElement.tagName === "BODY") {
|
||||
if (ui.isDownloadOnly()) {
|
||||
sendEvent("download-shot", "keyboard-enter");
|
||||
downloadShot();
|
||||
} else {
|
||||
sendEvent("save-shot", "keyboard-enter");
|
||||
shooter.takeShot("selection", selectedPos);
|
||||
}
|
||||
sendEvent("download-shot", "keyboard-enter");
|
||||
downloadShot();
|
||||
}
|
||||
}
|
||||
|
||||
|
|