first commit
Some checks failed
Types tests / Test (lts/*) (push) Has been cancelled
Lint / Lint (lts/*) (push) Has been cancelled
CodeQL / Analyze (javascript) (push) Has been cancelled
CI / Test (20) (push) Has been cancelled
CI / Test (22) (push) Has been cancelled
CI / Test (24) (push) Has been cancelled
Some checks failed
Types tests / Test (lts/*) (push) Has been cancelled
Lint / Lint (lts/*) (push) Has been cancelled
CodeQL / Analyze (javascript) (push) Has been cancelled
CI / Test (20) (push) Has been cancelled
CI / Test (22) (push) Has been cancelled
CI / Test (24) (push) Has been cancelled
This commit is contained in:
153
extensions/chromium/options/migration.js
Normal file
153
extensions/chromium/options/migration.js
Normal file
@@ -0,0 +1,153 @@
|
||||
/*
|
||||
Copyright 2016 Mozilla Foundation
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
"use strict";
|
||||
|
||||
chrome.runtime.onInstalled.addListener(({ reason }) => {
|
||||
if (reason !== "update") {
|
||||
// We only need to run migration logic for extension updates, not for new
|
||||
// installs or browser updates.
|
||||
return;
|
||||
}
|
||||
var storageLocal = chrome.storage.local;
|
||||
var storageSync = chrome.storage.sync;
|
||||
|
||||
if (!storageSync) {
|
||||
// No sync storage area - nothing to migrate to.
|
||||
return;
|
||||
}
|
||||
|
||||
getStorageNames(function (storageKeys) {
|
||||
storageLocal.get(storageKeys, function (values) {
|
||||
if (!values || !Object.keys(values).length) {
|
||||
// No local storage - nothing to migrate.
|
||||
// ... except possibly for a renamed preference name.
|
||||
migrateRenamedStorage();
|
||||
return;
|
||||
}
|
||||
migrateToSyncStorage(values);
|
||||
});
|
||||
});
|
||||
|
||||
async function getStorageNames(callback) {
|
||||
var schema_location = chrome.runtime.getManifest().storage.managed_schema;
|
||||
var res = await fetch(chrome.runtime.getURL(schema_location));
|
||||
var storageManifest = await res.json();
|
||||
var storageKeys = Object.keys(storageManifest.properties);
|
||||
callback(storageKeys);
|
||||
}
|
||||
|
||||
// Save |values| to storage.sync and delete the values with that key from
|
||||
// storage.local.
|
||||
function migrateToSyncStorage(values) {
|
||||
storageSync.set(values, function () {
|
||||
if (chrome.runtime.lastError) {
|
||||
console.error(
|
||||
"Failed to migrate settings due to an error: " +
|
||||
chrome.runtime.lastError.message
|
||||
);
|
||||
return;
|
||||
}
|
||||
// Migration successful. Delete local settings.
|
||||
storageLocal.remove(Object.keys(values), function () {
|
||||
// In theory remove() could fail (e.g. if the browser's storage
|
||||
// backend is corrupt), but since storageSync.set succeeded, consider
|
||||
// the migration successful.
|
||||
console.log(
|
||||
"Successfully migrated preferences from local to sync storage."
|
||||
);
|
||||
migrateRenamedStorage();
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
// TODO: Remove this migration code somewhere in the future, when most users
|
||||
// have had their chance of migrating to the new preference format.
|
||||
// Note: We cannot modify managed preferences, so the migration logic is
|
||||
// duplicated in web/chromecom.js too.
|
||||
function migrateRenamedStorage() {
|
||||
storageSync.get(
|
||||
[
|
||||
"enableHandToolOnLoad",
|
||||
"cursorToolOnLoad",
|
||||
"disableTextLayer",
|
||||
"enhanceTextSelection",
|
||||
"textLayerMode",
|
||||
"showPreviousViewOnLoad",
|
||||
"disablePageMode",
|
||||
"viewOnLoad",
|
||||
],
|
||||
function (items) {
|
||||
// Migration code for https://github.com/mozilla/pdf.js/pull/7635.
|
||||
if (typeof items.enableHandToolOnLoad === "boolean") {
|
||||
if (items.enableHandToolOnLoad) {
|
||||
storageSync.set(
|
||||
{
|
||||
cursorToolOnLoad: 1,
|
||||
},
|
||||
function () {
|
||||
if (!chrome.runtime.lastError) {
|
||||
storageSync.remove("enableHandToolOnLoad");
|
||||
}
|
||||
}
|
||||
);
|
||||
} else {
|
||||
storageSync.remove("enableHandToolOnLoad");
|
||||
}
|
||||
}
|
||||
// Migration code for https://github.com/mozilla/pdf.js/pull/9479.
|
||||
if (typeof items.disableTextLayer === "boolean") {
|
||||
if (items.disableTextLayer) {
|
||||
storageSync.set(
|
||||
{
|
||||
textLayerMode: 0,
|
||||
},
|
||||
function () {
|
||||
if (!chrome.runtime.lastError) {
|
||||
storageSync.remove([
|
||||
"disableTextLayer",
|
||||
"enhanceTextSelection",
|
||||
]);
|
||||
}
|
||||
}
|
||||
);
|
||||
} else {
|
||||
storageSync.remove(["disableTextLayer", "enhanceTextSelection"]);
|
||||
}
|
||||
}
|
||||
// Migration code for https://github.com/mozilla/pdf.js/pull/10502.
|
||||
if (typeof items.showPreviousViewOnLoad === "boolean") {
|
||||
if (!items.showPreviousViewOnLoad) {
|
||||
storageSync.set(
|
||||
{
|
||||
viewOnLoad: 1,
|
||||
},
|
||||
function () {
|
||||
if (!chrome.runtime.lastError) {
|
||||
storageSync.remove([
|
||||
"showPreviousViewOnLoad",
|
||||
"disablePageMode",
|
||||
]);
|
||||
}
|
||||
}
|
||||
);
|
||||
} else {
|
||||
storageSync.remove(["showPreviousViewOnLoad", "disablePageMode"]);
|
||||
}
|
||||
}
|
||||
}
|
||||
);
|
||||
}
|
||||
});
|
||||
185
extensions/chromium/options/options.html
Normal file
185
extensions/chromium/options/options.html
Normal file
@@ -0,0 +1,185 @@
|
||||
<!doctype html>
|
||||
<!--
|
||||
Copyright 2015 Mozilla Foundation
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
-->
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>PDF.js viewer options</title>
|
||||
<style>
|
||||
body {
|
||||
min-width: 400px; /* a page at the settings page is at least 400px wide */
|
||||
margin: 14px 17px; /* already added by default in Chrome 40.0.2212.0 */
|
||||
}
|
||||
.settings-row {
|
||||
margin: 1em 0;
|
||||
}
|
||||
.checkbox label {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
}
|
||||
.checkbox label input {
|
||||
flex-shrink: 0;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div id="settings-boxes"></div>
|
||||
<button id="reset-button" type="button">Restore default settings</button>
|
||||
|
||||
<template id="checkbox-template">
|
||||
<div class="settings-row checkbox">
|
||||
<label>
|
||||
<input type="checkbox">
|
||||
<span></span>
|
||||
</label>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<template id="viewerCssTheme-template">
|
||||
<div class="settings-row">
|
||||
<label>
|
||||
<span></span>
|
||||
<select>
|
||||
<option value="0">Use system theme</option>
|
||||
<option value="1">Light theme</option>
|
||||
<option value="2">Dark theme</option>
|
||||
</select>
|
||||
</label>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<template id="viewOnLoad-template">
|
||||
<div class="settings-row">
|
||||
<label>
|
||||
<span></span>
|
||||
<select>
|
||||
<option value="-1">Default</option>
|
||||
<option value="0">Show previous position</option>
|
||||
<option value="1">Show initial position</option>
|
||||
</select>
|
||||
</label>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<template id="defaultZoomValue-template">
|
||||
<div class="settings-row">
|
||||
<label>
|
||||
<span></span>
|
||||
<select>
|
||||
<option value="auto" selected="selected">Automatic Zoom</option>
|
||||
<option value="page-actual">Actual Size</option>
|
||||
<option value="page-fit">Page Fit</option>
|
||||
<option value="page-width">Page Width</option>
|
||||
<option value="custom" class="custom-zoom" hidden></option>
|
||||
<option value="50">50%</option>
|
||||
<option value="75">75%</option>
|
||||
<option value="100">100%</option>
|
||||
<option value="125">125%</option>
|
||||
<option value="150">150%</option>
|
||||
<option value="200">200%</option>
|
||||
<option value="300">300%</option>
|
||||
<option value="400">400%</option>
|
||||
</select>
|
||||
</label>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<template id="sidebarViewOnLoad-template">
|
||||
<div class="settings-row">
|
||||
<label>
|
||||
<span></span>
|
||||
<select>
|
||||
<option value="-1">Default</option>
|
||||
<option value="0">Do not show sidebar</option>
|
||||
<option value="1">Show thumbnails in sidebar</option>
|
||||
<option value="2">Show document outline in sidebar</option>
|
||||
<option value="3">Show attachments in sidebar</option>
|
||||
</select>
|
||||
</label>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<template id="cursorToolOnLoad-template">
|
||||
<div class="settings-row">
|
||||
<label>
|
||||
<span></span>
|
||||
<select>
|
||||
<option value="0">Text selection tool</option>
|
||||
<option value="1">Hand tool</option>
|
||||
</select>
|
||||
</label>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<template id="textLayerMode-template">
|
||||
<div class="settings-row">
|
||||
<label>
|
||||
<span></span>
|
||||
<select>
|
||||
<option value="0">Disable text selection</option>
|
||||
<option value="1">Enable text selection</option>
|
||||
</select>
|
||||
</label>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<template id="externalLinkTarget-template">
|
||||
<div class="settings-row">
|
||||
<label>
|
||||
<span></span>
|
||||
<select>
|
||||
<option value="0">Default</option>
|
||||
<option value="1">Current window/tab</option>
|
||||
<option value="2">New window/tab</option>
|
||||
<option value="3">Parent window/tab</option>
|
||||
<option value="4">Top window/tab</option>
|
||||
</select>
|
||||
</label>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<template id="scrollModeOnLoad-template">
|
||||
<div class="settings-row">
|
||||
<label>
|
||||
<span></span>
|
||||
<select>
|
||||
<option value="-1">Default</option>
|
||||
<option value="3">Page scrolling</option>
|
||||
<option value="0">Vertical scrolling</option>
|
||||
<option value="1">Horizontal scrolling</option>
|
||||
<option value="2">Wrapped scrolling</option>
|
||||
</select>
|
||||
</label>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<template id="spreadModeOnLoad-template">
|
||||
<div class="settings-row">
|
||||
<label>
|
||||
<span></span>
|
||||
<select>
|
||||
<option value="-1">Default</option>
|
||||
<option value="0">No spreads</option>
|
||||
<option value="1">Odd spreads</option>
|
||||
<option value="2">Even spreads</option>
|
||||
</select>
|
||||
</label>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script src="options.js"></script>
|
||||
</body>
|
||||
</html>
|
||||
210
extensions/chromium/options/options.js
Normal file
210
extensions/chromium/options/options.js
Normal file
@@ -0,0 +1,210 @@
|
||||
/*
|
||||
Copyright 2015 Mozilla Foundation
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
"use strict";
|
||||
var storageAreaName = chrome.storage.sync ? "sync" : "local";
|
||||
var storageArea = chrome.storage[storageAreaName];
|
||||
|
||||
Promise.all([
|
||||
new Promise(function getManagedPrefs(resolve) {
|
||||
if (!chrome.storage.managed) {
|
||||
resolve({});
|
||||
return;
|
||||
}
|
||||
// Get preferences as set by the system administrator.
|
||||
chrome.storage.managed.get(null, function (prefs) {
|
||||
// Managed storage may be disabled, e.g. in Opera.
|
||||
resolve(prefs || {});
|
||||
});
|
||||
}),
|
||||
new Promise(function getUserPrefs(resolve) {
|
||||
storageArea.get(null, function (prefs) {
|
||||
resolve(prefs || {});
|
||||
});
|
||||
}),
|
||||
new Promise(function getStorageSchema(resolve) {
|
||||
// Get the storage schema - a dictionary of preferences.
|
||||
var x = new XMLHttpRequest();
|
||||
var schema_location = chrome.runtime.getManifest().storage.managed_schema;
|
||||
x.open("get", chrome.runtime.getURL(schema_location));
|
||||
x.onload = function () {
|
||||
resolve(x.response.properties);
|
||||
};
|
||||
x.responseType = "json";
|
||||
x.send();
|
||||
}),
|
||||
])
|
||||
.then(function (values) {
|
||||
var managedPrefs = values[0];
|
||||
var userPrefs = values[1];
|
||||
var schema = values[2];
|
||||
function getPrefValue(prefName) {
|
||||
if (prefName in userPrefs) {
|
||||
return userPrefs[prefName];
|
||||
} else if (prefName in managedPrefs) {
|
||||
return managedPrefs[prefName];
|
||||
}
|
||||
return schema[prefName].default;
|
||||
}
|
||||
var prefNames = Object.keys(schema);
|
||||
var renderPreferenceFunctions = {};
|
||||
// Render options
|
||||
prefNames.forEach(function (prefName) {
|
||||
var prefSchema = schema[prefName];
|
||||
if (!prefSchema.title) {
|
||||
// Don't show preferences if the title is missing.
|
||||
return;
|
||||
}
|
||||
|
||||
// A DOM element with a method renderPreference.
|
||||
var renderPreference;
|
||||
if (prefSchema.type === "boolean") {
|
||||
// Most prefs are booleans, render them in a generic way.
|
||||
renderPreference = renderBooleanPref(
|
||||
prefSchema.title,
|
||||
prefSchema.description,
|
||||
prefName
|
||||
);
|
||||
} else if (prefSchema.type === "integer" && prefSchema.enum) {
|
||||
// Most other prefs are integer-valued enumerations, render them in a
|
||||
// generic way too.
|
||||
// Unlike the renderBooleanPref branch, each preference handled by this
|
||||
// branch still needs its own template in options.html with
|
||||
// id="$prefName-template".
|
||||
renderPreference = renderEnumPref(prefSchema.title, prefName);
|
||||
} else if (prefName === "defaultZoomValue") {
|
||||
renderPreference = renderDefaultZoomValue(prefSchema.title);
|
||||
} else {
|
||||
// Should NEVER be reached. Only happens if a new type of preference is
|
||||
// added to the storage manifest.
|
||||
console.error("Don't know how to handle " + prefName + "!");
|
||||
return;
|
||||
}
|
||||
|
||||
renderPreference(getPrefValue(prefName));
|
||||
renderPreferenceFunctions[prefName] = renderPreference;
|
||||
});
|
||||
|
||||
// Names of preferences that are displayed in the UI.
|
||||
var renderedPrefNames = Object.keys(renderPreferenceFunctions);
|
||||
|
||||
// Reset button to restore default settings.
|
||||
document.getElementById("reset-button").onclick = function () {
|
||||
userPrefs = {};
|
||||
storageArea.remove(prefNames, function () {
|
||||
renderedPrefNames.forEach(function (prefName) {
|
||||
renderPreferenceFunctions[prefName](getPrefValue(prefName));
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
// Automatically update the UI when the preferences were changed elsewhere.
|
||||
chrome.storage.onChanged.addListener(function (changes, areaName) {
|
||||
var prefs = null;
|
||||
if (areaName === storageAreaName) {
|
||||
prefs = userPrefs;
|
||||
} else if (areaName === "managed") {
|
||||
prefs = managedPrefs;
|
||||
}
|
||||
if (prefs) {
|
||||
renderedPrefNames.forEach(function (prefName) {
|
||||
var prefChanges = changes[prefName];
|
||||
if (prefChanges) {
|
||||
if ("newValue" in prefChanges) {
|
||||
userPrefs[prefName] = prefChanges.newValue;
|
||||
} else {
|
||||
// Otherwise the pref was deleted
|
||||
delete userPrefs[prefName];
|
||||
}
|
||||
renderPreferenceFunctions[prefName](getPrefValue(prefName));
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
})
|
||||
.then(null, console.error.bind(console));
|
||||
|
||||
function importTemplate(id) {
|
||||
return document.importNode(document.getElementById(id).content, true);
|
||||
}
|
||||
|
||||
// Helpers to create UI elements that display the preference, and return a
|
||||
// function which updates the UI with the preference.
|
||||
|
||||
function renderBooleanPref(shortDescription, description, prefName) {
|
||||
var wrapper = importTemplate("checkbox-template");
|
||||
wrapper.title = description;
|
||||
|
||||
var checkbox = wrapper.querySelector('input[type="checkbox"]');
|
||||
checkbox.onchange = function () {
|
||||
var pref = {};
|
||||
pref[prefName] = this.checked;
|
||||
storageArea.set(pref);
|
||||
};
|
||||
wrapper.querySelector("span").textContent = shortDescription;
|
||||
document.getElementById("settings-boxes").append(wrapper);
|
||||
|
||||
function renderPreference(value) {
|
||||
checkbox.checked = value;
|
||||
}
|
||||
return renderPreference;
|
||||
}
|
||||
|
||||
function renderEnumPref(shortDescription, prefName) {
|
||||
var wrapper = importTemplate(prefName + "-template");
|
||||
var select = wrapper.querySelector("select");
|
||||
select.onchange = function () {
|
||||
var pref = {};
|
||||
pref[prefName] = parseInt(this.value);
|
||||
storageArea.set(pref);
|
||||
};
|
||||
wrapper.querySelector("span").textContent = shortDescription;
|
||||
document.getElementById("settings-boxes").append(wrapper);
|
||||
|
||||
function renderPreference(value) {
|
||||
select.value = value;
|
||||
}
|
||||
return renderPreference;
|
||||
}
|
||||
|
||||
function renderDefaultZoomValue(shortDescription) {
|
||||
var wrapper = importTemplate("defaultZoomValue-template");
|
||||
var select = wrapper.querySelector("select");
|
||||
select.onchange = function () {
|
||||
storageArea.set({
|
||||
defaultZoomValue: this.value,
|
||||
});
|
||||
};
|
||||
wrapper.querySelector("span").textContent = shortDescription;
|
||||
document.getElementById("settings-boxes").append(wrapper);
|
||||
|
||||
function renderPreference(value) {
|
||||
value = value || "auto";
|
||||
select.value = value;
|
||||
var customOption = select.querySelector("option.custom-zoom");
|
||||
if (select.selectedIndex === -1 && value) {
|
||||
// Custom zoom percentage, e.g. set via managed preferences.
|
||||
// [zoom] or [zoom],[left],[top]
|
||||
customOption.text = value.indexOf(",") > 0 ? value : value + "%";
|
||||
customOption.value = value;
|
||||
customOption.hidden = false;
|
||||
customOption.selected = true;
|
||||
} else {
|
||||
customOption.hidden = true;
|
||||
}
|
||||
}
|
||||
return renderPreference;
|
||||
}
|
||||
Reference in New Issue
Block a user