Kill hidden globals

This commit is contained in:
eight 2018-10-10 23:05:20 +08:00
parent 22d4767511
commit d2b36a168e
32 changed files with 135 additions and 219 deletions

View File

@ -8,64 +8,6 @@ env:
es6: true
webextensions: true
globals:
# messaging.js
KEEP_CHANNEL_OPEN: false
CHROME: false
FIREFOX: false
VIVALDI: false
OPERA: false
URLS: false
BG: false
API: false
notifyAllTabs: false
sendMessage: false
queryTabs: false
getTab: false
getOwnTab: false
getActiveTab: false
getActiveTabRealURL: false
getTabRealURL: false
openURL: false
activateTab: false
stringAsRegExp: false
ignoreChromeError: false
tryCatch: false
tryRegExp: false
tryJSONparse: false
debounce: false
deepCopy: false
sessionStorageHash: false
download: false
invokeOrPostpone: false
# localization.js
template: false
t: false
o: false
tE: false
tHTML: false
tNodeList: false
tDocLoader: false
tWordBreak: false
formatDate: false
# dom.js
onDOMready: false
onDOMscriptReady: false
scrollElementIntoView: false
enforceInputRange: false
animateElement: false
$: false
$$: false
$create: false
$createLink: false
# prefs.js
prefs: false
setupLivePrefs: false
# storage-util.js
chromeLocal: false
chromeSync: false
LZString: false
rules:
accessor-pairs: [2]
array-bracket-spacing: [2, never]
@ -214,7 +156,6 @@ rules:
no-trailing-spaces: [2]
no-undef-init: [2]
no-undef: [2]
no-undefined: [0]
no-underscore-dangle: [0]
no-unexpected-multiline: [2]
no-unmodified-loop-condition: [0]
@ -224,7 +165,7 @@ rules:
no-unsafe-negation: [2]
no-unused-expressions: [1]
no-unused-labels: [0]
no-unused-vars: [1, {args: after-used, vars: local, argsIgnorePattern: ^_}]
no-unused-vars: [2, {args: after-used}]
no-use-before-define: [2, nofunc]
no-useless-call: [2]
no-useless-computed-key: [2]

View File

@ -329,11 +329,15 @@ function webNavIframeHelperFF({tabId, frameId}) {
.catch(() => false)
.then(pong => {
if (pong) return;
// insert apply.js to iframe
const files = chrome.runtime.getManifest().content_scripts[0].js;
for (const file of files) {
chrome.tabs.executeScript(tabId, {
frameId,
file: '/content/apply.js',
file,
matchAboutBlank: true,
}, ignoreChromeError);
}
});
}

View File

@ -74,10 +74,14 @@ const db = (() => {
} else {
const transaction = database.transaction(['styles'], 'readwrite');
const store = transaction.objectStore('styles');
try {
Object.assign(store[method](...args), {
onsuccess: event => resolve(event, store, transaction, database),
onerror: reject,
});
} catch (err) {
reject(err);
}
}
},
onerror(event) {

View File

@ -43,6 +43,7 @@ const styleManager = (() => {
}
let id;
port.onMessage.addListener(data => {
console.log(data);
if (!id) {
id = data.id;
}
@ -167,7 +168,7 @@ const styleManager = (() => {
}
function setStyleExclusions(id, exclusions) {
const data = Object.assign({}, styles.get(id), {exclusions});
const data = Object.assign({}, styles.get(id).data, {exclusions});
return saveStyle(data)
.then(newData => handleSave(newData, 'exclusions', 'styleUpdated'));
}
@ -257,6 +258,9 @@ const styleManager = (() => {
if (!style.name) {
throw new Error('style name is empty');
}
if (style.id == null) {
delete style.id;
}
return db.exec('put', style)
.then(event => {
if (style.id == null) {

View File

@ -82,7 +82,7 @@
metaOnly,
vars,
}) {
return usercss.buildMeta(sourceCode)
return Promise.resolve(usercss.buildMeta(sourceCode))
.then(style =>
Promise.all([
metaOnly ? style : doBuild(style),
@ -150,7 +150,7 @@
return styleManager.get(styleOrData.id);
}
const {name, namespace} = styleOrData.usercssData || styleOrData;
return styleManager.getAllStyles(styleList => {
return styleManager.getAllStyles().then(styleList => {
for (const dup of styleList) {
const data = dup.usercssData;
if (!data) continue;

View File

@ -134,21 +134,11 @@
applyStyles(request.styles);
break;
case 'styleReplaceAll':
replaceAll(request.styles);
break;
case 'prefChanged':
if ('disableAll' in request.prefs) {
doDisableAll(request.prefs.disableAll);
}
if ('exposeIframes' in request.prefs) {
doExposeIframes(request.prefs.exposeIframes);
}
break;
case 'urlChanged':
// TODO
console.log('url changed', location.href);
API.getSectionsByUrl(getMatchUrl(), {enabled: true})
.then(buildSections)
.then(replaceAll);
break;
case 'ping':
@ -384,15 +374,6 @@
}
function replaceAll(newStyles) {
if ('disableAll' in newStyles &&
disableAll === newStyles.disableAll &&
styleElements.size === countStylesInHash(newStyles) &&
[...styleElements.values()].every(el =>
el.disabled === disableAll &&
el.parentNode === ROOT &&
el.textContent === (newStyles[getStyleId(el)] || []).map(({code}) => code).join('\n'))) {
return;
}
const oldStyles = Array.prototype.slice.call(
document.querySelectorAll(`style.stylus[id^="${ID_PREFIX}"]`));
oldStyles.forEach(el => (el.id += '-ghost'));
@ -401,9 +382,11 @@
[...retiredStyleTimers.values()].forEach(clearTimeout);
retiredStyleTimers.clear();
applyStyles(newStyles);
if (docRewriteObserver) {
docRootObserver.evade(() =>
oldStyles.forEach(el => el.remove()));
}
}
function applyTransitionPatch() {
// CSS transition bug workaround: since we insert styles asynchronously,

View File

@ -11,8 +11,6 @@ const cmFactory = (() => {
const INSERT_TAB_COMMAND = CodeMirror.commands.insertTab;
const INSERT_SOFT_TAB_COMMAND = CodeMirror.commands.insertSoftTab;
console.log(INSERT_SOFT_TAB_COMMAND, INSERT_TAB_COMMAND);
CodeMirror.defineOption('tabSize', prefs.get('editor.tabSize'), (cm, value) => {
cm.setOption('indentUnit', Number(value));
});

View File

@ -407,7 +407,6 @@ function initStyleData() {
const params = new URLSearchParams(location.search.replace(/^\?/, ''));
const id = Number(params.get('id'));
const createEmptyStyle = () => ({
id: null,
name: params.get('domain') ||
tryCatch(() => new URL(params.get('url-prefix')).hostname) ||
'',

View File

@ -28,7 +28,7 @@ const rerouteHotkeys = (() => {
}
function rerouteHandler(event) {
if (!editor) {
if (typeof editor === 'undefined') {
return;
}
const keyName = CodeMirror.keyName(event);

View File

@ -85,7 +85,7 @@ function createSourceEditor(style) {
sourceCode: style.sourceCode,
vars: style.usercssData.vars
})
.then(newStyle => {
.then(({style: newStyle}) => {
delete newStyle.enabled;
return Object.assign(style, newStyle);
});
@ -234,17 +234,17 @@ function createSourceEditor(style) {
function save() {
if (!dirty.isDirty()) return;
const code = cm.getValue();
const exclusionList = exclusions.get();
exclusions.save({
id: style.id,
exclusionList
});
// const exclusionList = exclusions.get();
// exclusions.save({
// id: style.id,
// exclusionList
// });
return ensureUniqueStyle(code)
.then(() => API.editSaveUsercss({
id: style.id,
enabled: style.enabled,
sourceCode: code,
exclusions: exclusionList
// exclusions: exclusionList
}))
.then(replaceStyle)
.catch(err => {

View File

@ -79,9 +79,19 @@ const msg = (() => {
}
}
function broadcastError(err) {
if (err.message && (
/Receiving end does not exist/.test(err.message) ||
/The message port closed before a response was received/.test(err.message)
)) {
return;
}
console.warn(err);
}
function broadcast(data, filter) {
return Promise.all([
send(data, 'both').catch(console.warn),
send(data, 'both').catch(broadcastError),
broadcastTab(data, filter, null, true, 'both')
]);
}
@ -116,14 +126,14 @@ const msg = (() => {
if (message.id) {
request = withCleanup(request, () => bg._msg.storage.delete(message.id));
}
requests.push(request.catch(console.warn));
requests.push(request.catch(broadcastError));
}
return Promise.all(requests);
});
}
function broadcastExtension(...args) {
return send(...args).catch(console.warn);
return send(...args).catch(broadcastError);
}
function on(fn) {

View File

@ -1,8 +1,8 @@
/* global prefs: true, contextMenus, FIREFOX_NO_DOM_STORAGE */
/* global deepCopy debounce API tryJSONparse chromeSync FIREFOX CHROME */
/* exported prefs */
'use strict';
// eslint-disable-next-line no-var
var prefs = new function Prefs() {
const prefs = new function Prefs() {
const BG = undefined;
const defaults = {
'openEditInWindow': false, // new editor opens in a own browser window

View File

@ -1,5 +1,12 @@
/* exported promisify */
'use strict';
/*
Convert chrome APIs into promises. Example:
const storageSyncGet = promisify(chrome.storage.sync.get.bind(chrome.storage.sync));
storageSyncGet(['key']).then(result => {...});
*/
function promisify(fn) {
return (...args) =>
new Promise((resolve, reject) => {

View File

@ -1,8 +1,8 @@
/* exported loadScript */
'use strict';
// loadScript(script: Array<Promise|string>|string): Promise
// eslint-disable-next-line no-var
var loadScript = (() => {
const loadScript = (() => {
const cache = new Map();
function inject(file) {

View File

@ -1,3 +1,4 @@
/* exported styleSectionsEqual */
'use strict';
/**

View File

@ -1,20 +1,14 @@
/* global loadScript */
/* global loadScript tryJSONparse API */
/* exported chromeLocal chromeSync */
'use strict';
// eslint-disable-next-line no-var
var [chromeLocal, chromeSync] = (() => {
const native = 'sync' in chrome.storage &&
!chrome.runtime.id.includes('@temporary');
if (!native && BG !== window) {
setupOnChangeRelay();
}
const [chromeLocal, chromeSync] = (() => {
return [
createWrapper('local'),
createWrapper('sync'),
];
function createWrapper(name) {
if (!native) createDummyStorage(name);
const storage = chrome.storage[name];
const wrapper = {
get: data => new Promise(resolve => storage.get(data, resolve)),
@ -58,39 +52,10 @@ var [chromeLocal, chromeSync] = (() => {
return wrapper;
}
function createDummyStorage(name) {
chrome.storage[name] = {
get: (data, cb) => API.dummyStorageGet({data, name}).then(cb),
set: (data, cb) => API.dummyStorageSet({data, name}).then(cb),
remove: (data, cb) => API.dummyStorageRemove({data, name}).then(cb),
};
}
function loadLZStringScript() {
return window.LZString ?
Promise.resolve(window.LZString) :
loadScript('/vendor/lz-string-unsafe/lz-string-unsafe.min.js').then(() =>
(window.LZString = window.LZString || window.LZStringUnsafe));
}
function setupOnChangeRelay() {
const listeners = new Set();
const onMessage = msg => {
if (!msg.dummyStorageChanges) return;
for (const fn of listeners.values()) {
fn(msg.dummyStorageChanges, msg.dummyStorageName);
}
};
Object.assign(chrome.storage.onChanged, {
addListener(fn) {
if (!listeners.size) chrome.runtime.onMessage.addListener(onMessage);
listeners.add(fn);
},
hasListener: fn => listeners.has(fn),
removeListener(fn) {
listeners.delete(fn);
if (!listeners.size) chrome.runtime.onMessage.removeListener(onMessage);
}
});
}
})();

View File

@ -1,8 +1,8 @@
/* global loadScript semverCompare colorConverter styleCodeEmpty */
/* exported usercss */
'use strict';
// eslint-disable-next-line no-var
var usercss = (() => {
const usercss = (() => {
// true = global
// false or 0 = private
// <string> = global key name

View File

@ -1,4 +1,6 @@
/* global messageBox */
/* global messageBox deepCopy $create $createLink $ t tWordBreak
prefs setupLivePrefs debounce API */
/* exported configDialog */
'use strict';
function configDialog(style) {
@ -171,7 +173,7 @@ function configDialog(style) {
return;
}
saving = true;
return API.configUsercssVar(style.id, style.usercssData.vars)
return API.configUsercssVars(style.id, style.usercssData.vars)
.then(newVars => {
varsInitial = getInitialValues(newVars);
vars.forEach(va => onchange({target: va.input, justSaved: true}));

View File

@ -1,5 +1,5 @@
/* global installed messageBox */
/* global sorter */
/* global installed messageBox sorter $ $$ $create t debounce prefs API onDOMready */
/* exported filterAndAppend */
'use strict';
const filtersSelector = {

View File

@ -1,4 +1,5 @@
/* global messageBox handleUpdate handleDelete applyOnMessage styleSectionsEqual */
/* global messageBox handleUpdate handleDelete styleSectionsEqual getOwnTab API
tryJSONparse scrollElementIntoView $ $$ API $create t animateElement */
'use strict';
const STYLISH_DUMP_FILE_EXT = '.txt';
@ -94,8 +95,8 @@ function importFromString(jsonString, oldStyles) {
if (info) {
// using saveStyle directly since json was parsed in background page context
// FIXME: rewrite importStyle
// return API.saveStyle(Object.assign(item, SAVE_OPTIONS))
// .then(style => account({style, info, resolve}));
return API.saveStyle(Object.assign(item, SAVE_OPTIONS))
.then(style => account({style, info, resolve}));
}
}
renderQueue.forEach(style => handleUpdate(style, {reason: 'import'}));

View File

@ -1,4 +1,5 @@
/* global installed */
/* global installed onDOMready $create debounce $ scrollElementIntoView
animateElement */
'use strict';
onDOMready().then(() => {

View File

@ -1,10 +1,13 @@
/*
global messageBox getStyleWithNoCode retranslateCSS
global filtersSelector filterAndAppend urlFilterParam showFiltersStats
global checkUpdate handleUpdateInstalled
global objectDiff
global configDialog
global sorter msg
global messageBox getStyleWithNoCode
filterAndAppend urlFilterParam showFiltersStats
checkUpdate handleUpdateInstalled
objectDiff
configDialog
sorter msg prefs API onDOMready $ $$ $create template setupLivePrefs
URLS enforceInputRange t tWordBreak formatDate
getOwnTab getActiveTab openURL animateElement sessionStorageHash debounce
scrollElementIntoView CHROME VIVALDI FIREFOX
*/
'use strict';

View File

@ -1,3 +1,4 @@
/* exported objectDiff */
'use strict';
function objectDiff(first, second, path = '') {

View File

@ -1,5 +1,5 @@
/* global installed */
/* global messageBox */
/* global installed messageBox t $ $create prefs */
/* exported sorter */
'use strict';
const sorter = (() => {

View File

@ -1,6 +1,6 @@
/* global messageBox */
/* global ENTRY_ID_PREFIX, newUI */
/* global filtersSelector, filterAndAppend, sorter */
/* global messageBox ENTRY_ID_PREFIX newUI filtersSelector filterAndAppend
sorter $ $$ $create API onDOMready scrollElementIntoView t chromeLocal */
/* exported handleUpdateInstalled */
'use strict';
onDOMready().then(() => {

View File

@ -1,5 +1,4 @@
/* global focusAccessibility */
/* global moveFocus */
/* global focusAccessibility moveFocus $ $create t tHTML animateElement */
'use strict';
/**

View File

@ -1,4 +1,6 @@
/* global messageBox msg */
/* global messageBox msg setupLivePrefs enforceInputRange
$ $$ $create $createLink
FIREFOX OPERA CHROME URLS openURL prefs t API ignoreChromeError */
'use strict';
setupLivePrefs();

View File

@ -1,8 +1,8 @@
/* global applyOnMessage installed */
/* global $ $$ API debounce $create t */
'use strict';
// eslint-disable-next-line no-var
var hotkeys = (() => {
/* exported hotkeys */
const hotkeys = (() => {
const entries = document.getElementsByClassName('entry');
let togglablesShown;
let togglables;

View File

@ -1,9 +1,9 @@
/*
global messageBox
global exclusions
global messageBox t $create getActiveTab tryRegExp animateElement $ API
*/
'use strict';
/* exported popupExclusions */
const popupExclusions = (() => {
// return matches on url ending to prevent duplicates in the exclusion list
@ -163,45 +163,29 @@ const popupExclusions = (() => {
entry.styleMeta = style;
entry.classList.toggle('excluded', excluded);
}
notifyAllTabs({method: 'exclusionsUpdated', style, id: entry.styleId, affects: true, excluded});
}
return Promise.resolve();
}
function handlePopupSave(style) {
if (typeof style.exclusions === 'undefined') {
style.exclusions = {};
if (!Array.isArray(style.exclusions)) {
style.exclusions = [];
}
const current = Object.keys(style.exclusions);
const current = new Set(style.exclusions);
const select = $('#popup-exclusions', messageBox.element);
const all = getMultiOptions({select});
const selected = getMultiOptions({select, selectedOnly: true});
// Add exclusions
selected.forEach(value => {
let exists = exclusionExists(current, value);
if (!exists.length) {
style.exclusions[value] = exclusions.createRegExp(value);
exists = [''];
const selected = new Set(getMultiOptions({select, selectedOnly: true}));
for (const value of all) {
if (current.has(value) && !selected.has(value)) {
const index = style.exclusions.indexOf(value);
style.exclusions.splice(index, 1);
}
exists.forEach(ending => {
const index = all.indexOf(value + ending);
if (index > -1) {
all.splice(index, 1);
if (!current.has(value) && selected.has(value)) {
style.exclusions.push(value);
}
});
});
// Remove exclusions (unselected in popup modal)
all.forEach(value => {
exclusionExists(current, value).forEach(ending => {
delete style.exclusions[value + ending];
});
});
exclusions.save({
id: style.id,
exclusionList: style.exclusions
});
}
API.setStyleExclusions(style.id, style.exclusions);
}
return {openPopupDialog, selectExclusions, isExcluded};
})();

View File

@ -1,6 +1,9 @@
/*
global configDialog hotkeys
global popupExclusions promisify onTabReady msg
popupExclusions onTabReady msg
getActiveTab FIREFOX getTabRealURL URLS API onDOMready $ $$ prefs CHROME
setupLivePrefs template ignoreChromeError t $create tWordBreak animateElement
tryJSONparse debounce
*/
'use strict';
@ -308,8 +311,8 @@ function createStyleElement({
$('.checker', entry).checked = false;
}
const excluded = popupExclusions.isExcluded(tabURL, style.exclusions);
entry.classList.toggle('excluded', excluded);
// const excluded = popupExclusions.isExcluded(tabURL, style.exclusions);
// entry.classList.toggle('excluded', excluded);
const styleName = $('.style-name', entry);
styleName.lastChild.textContent = style.name;

View File

@ -1,4 +1,6 @@
/* global tabURL handleEvent */
/* global tabURL handleEvent $ $$ prefs template FIREFOX chromeLocal debounce
$create t API tWordBreak formatDate tryCatch tryJSONparse LZString
ignoreChromeError */
'use strict';
window.addEventListener('showStyles:done', function _() {
@ -135,7 +137,7 @@ window.addEventListener('showStyles:done', function _() {
if (result) {
result.installed = false;
result.installedStyleId = -1;
(BG || window).clearTimeout(result.pingbackTimer);
window.clearTimeout(result.pingbackTimer);
renderActionButtons($('#' + RESULT_ID_PREFIX + result.id));
}
});
@ -581,7 +583,8 @@ window.addEventListener('showStyles:done', function _() {
}
function pingback(result) {
const wnd = BG || window;
const wnd = window;
// FIXME: move this to background page and create an API like installUSOStyle
result.pingbackTimer = wnd.setTimeout(wnd.download, PINGBACK_DELAY,
BASE_URL + '/styles/install/' + result.id + '?source=stylish-ch');
}

View File

@ -1,4 +1,5 @@
/* global CodeMirror colorConverter */
/* global colorConverter $create debounce */
/* exported colorMimicry */
'use strict';
(window.CodeMirror ? window.CodeMirror.prototype : window).colorpicker = function () {