Fix: implement styleViaAPI

This commit is contained in:
eight 2018-10-13 21:29:06 +08:00
parent 7c3d49c005
commit ecb622c93c
3 changed files with 37 additions and 49 deletions

View File

@ -26,7 +26,7 @@ const styleManager = (() => {
maybeMatch: Set<styleId>, maybeMatch: Set<styleId>,
sections: Object<styleId => { sections: Object<styleId => {
id: styleId, id: styleId,
code: String code: Array<String>
}> }>
} */ } */
const cachedStyleForUrl = createCache({ const cachedStyleForUrl = createCache({
@ -353,13 +353,13 @@ const styleManager = (() => {
if (urlMatchStyle(url, data) !== true) { if (urlMatchStyle(url, data) !== true) {
return; return;
} }
let code = ''; const code = [];
for (const section of data.sections) { for (const section of data.sections) {
if (urlMatchSection(url, section) === true && !styleCodeEmpty(section.code)) { if (urlMatchSection(url, section) === true && !styleCodeEmpty(section.code)) {
code += section.code; code.push(section.code);
} }
} }
return code; return code.length && code;
} }
function prepare() { function prepare() {

View File

@ -23,14 +23,14 @@ API_METHODS.styleViaAPI = !CHROME && (() => {
let observingTabs = false; let observingTabs = false;
return function (request) { return function (request) {
const action = ACTIONS[request.action]; const action = ACTIONS[request.method];
return !action ? NOP : return !action ? NOP :
action(request, this.sender) action(request, this.sender)
.catch(onError) .catch(onError)
.then(maybeToggleObserver); .then(maybeToggleObserver);
}; };
function styleApply({id = null, ignoreUrlCheck}, {tab, frameId, url}) { function styleApply({id = null, ignoreUrlCheck = false}, {tab, frameId, url}) {
if (prefs.get('disableAll')) { if (prefs.get('disableAll')) {
return NOP; return NOP;
} }
@ -42,15 +42,11 @@ API_METHODS.styleViaAPI = !CHROME && (() => {
const tasks = []; const tasks = [];
for (const section of Object.values(sections)) { for (const section of Object.values(sections)) {
const styleId = section.id; const styleId = section.id;
const code = section.code; const code = section.code.join('\n');
if (!code) {
delete frameStyles[styleId];
continue;
}
if (code === (frameStyles[styleId] || []).join('\n')) { if (code === (frameStyles[styleId] || []).join('\n')) {
continue; continue;
} }
frameStyles[styleId] = [code]; frameStyles[styleId] = section.code;
tasks.push( tasks.push(
browser.tabs.insertCSS(tab.id, { browser.tabs.insertCSS(tab.id, {
code, code,

View File

@ -7,6 +7,7 @@
// define a constant so it throws when redefined // define a constant so it throws when redefined
const APPLY = (() => { const APPLY = (() => {
const CHROME = chrome.app ? parseInt(navigator.userAgent.match(/Chrom\w+\/(?:\d+\.){2}(\d+)|$/)[1]) : NaN; const CHROME = chrome.app ? parseInt(navigator.userAgent.match(/Chrom\w+\/(?:\d+\.){2}(\d+)|$/)[1]) : NaN;
const STYLE_VIA_API = !chrome.app && document instanceof XMLDocument;
var ID_PREFIX = 'stylus-'; var ID_PREFIX = 'stylus-';
var ROOT; var ROOT;
var isOwnPage = location.protocol.endsWith('-extension:'); var isOwnPage = location.protocol.endsWith('-extension:');
@ -29,26 +30,23 @@ const APPLY = (() => {
let parentDomain; let parentDomain;
// FIXME: does it work with styleViaAPI?
prefs.subscribe(['disableAll'], (key, value) => doDisableAll(value)); prefs.subscribe(['disableAll'], (key, value) => doDisableAll(value));
if (window !== parent) { if (window !== parent) {
prefs.subscribe(['exposeIframes'], updateExposeIframes); prefs.subscribe(['exposeIframes'], updateExposeIframes);
} }
function init() { function init() {
// FIXME: styleViaAPI
// FIXME: getStylesFallback? // FIXME: getStylesFallback?
if (!chrome.app && document instanceof XMLDocument) { if (STYLE_VIA_API) {
return API.styleViaAPI({action: 'styleApply'}); return API.styleViaAPI({method: 'styleApply'});
} }
return API.getSectionsByUrl(getMatchUrl()) return API.getSectionsByUrl(getMatchUrl())
.then(result => { .then(result => {
ROOT = document.documentElement; ROOT = document.documentElement;
const styles = Object.values(result); applyStyles(result, () => {
// CSS transition bug workaround: since we insert styles asynchronously, // CSS transition bug workaround: since we insert styles asynchronously,
// the browsers, especially Firefox, may apply all transitions on page load // the browsers, especially Firefox, may apply all transitions on page load
applyStyles(styles, () => { if ([...styleElements.values()].some(n => n.textContent.includes('transition'))) {
if (styles.some(s => s.code.includes('transition'))) {
applyTransitionPatch(); applyTransitionPatch();
} }
}); });
@ -136,10 +134,6 @@ const APPLY = (() => {
return matchUrl; return matchUrl;
} }
function buildSections(cache) {
return Object.values(cache);
}
/** /**
* TODO: remove when FF fixes the bug. * TODO: remove when FF fixes the bug.
* Firefox borks sendMessage in same-origin iframes that have 'src' with a real path on the site. * Firefox borks sendMessage in same-origin iframes that have 'src' with a real path on the site.
@ -163,12 +157,12 @@ const APPLY = (() => {
// } // }
function applyOnMessage(request) { function applyOnMessage(request) {
if (!chrome.app && document instanceof XMLDocument && request.method !== 'ping') { if (request.method === 'ping') {
request.action = request.method; return true;
request.method = null; }
request.styles = null; if (STYLE_VIA_API) {
if (request.style) { if (request.method === 'urlChanged') {
request.style.sections = null; request.method = 'styleReplaceAll';
} }
API.styleViaAPI(request); API.styleViaAPI(request);
return; return;
@ -188,7 +182,7 @@ const APPLY = (() => {
if (!sections[request.style.id]) { if (!sections[request.style.id]) {
removeStyle(request.style); removeStyle(request.style);
} else { } else {
applyStyles(buildSections(sections)); applyStyles(sections);
} }
}); });
} else { } else {
@ -199,20 +193,15 @@ const APPLY = (() => {
case 'styleAdded': case 'styleAdded':
if (request.style.enabled) { if (request.style.enabled) {
API.getSectionsByUrl(getMatchUrl(), request.style.id) API.getSectionsByUrl(getMatchUrl(), request.style.id)
.then(buildSections)
.then(applyStyles); .then(applyStyles);
} }
break; break;
case 'urlChanged': case 'urlChanged':
API.getSectionsByUrl(getMatchUrl()) API.getSectionsByUrl(getMatchUrl())
.then(buildSections)
.then(replaceAll); .then(replaceAll);
break; break;
case 'ping':
return true;
case 'backgroundReady': case 'backgroundReady':
initializing.catch(err => { initializing.catch(err => {
if (msg.RX_NO_RECEIVER.test(err.message)) { if (msg.RX_NO_RECEIVER.test(err.message)) {
@ -232,6 +221,9 @@ const APPLY = (() => {
return; return;
} }
disableAll = disable; disableAll = disable;
if (STYLE_VIA_API) {
API.styleViaAPI({method: 'prefChanged', prefs: {disableAll}});
} else {
Array.prototype.forEach.call(document.styleSheets, stylesheet => { Array.prototype.forEach.call(document.styleSheets, stylesheet => {
if (stylesheet.ownerNode.matches(`style.stylus[id^="${ID_PREFIX}"]`) if (stylesheet.ownerNode.matches(`style.stylus[id^="${ID_PREFIX}"]`)
&& stylesheet.disabled !== disable) { && stylesheet.disabled !== disable) {
@ -239,6 +231,7 @@ const APPLY = (() => {
} }
}); });
} }
}
function fetchParentDomain() { function fetchParentDomain() {
if (parentDomain) { if (parentDomain) {
@ -290,7 +283,6 @@ const APPLY = (() => {
disabledElements.delete(id); disabledElements.delete(id);
} else { } else {
return API.getSectionsByUrl(getMatchUrl(), id) return API.getSectionsByUrl(getMatchUrl(), id)
.then(buildSections)
.then(applyStyles); .then(applyStyles);
} }
} else { } else {
@ -313,8 +305,8 @@ const APPLY = (() => {
} }
} }
function applyStyles(styles, done) { function applyStyles(sections, done) {
if (!styles.length) { if (!Object.keys(sections).length) {
if (done) { if (done) {
done(); done();
} }
@ -325,7 +317,7 @@ const APPLY = (() => {
new MutationObserver((mutations, observer) => { new MutationObserver((mutations, observer) => {
if (document.documentElement) { if (document.documentElement) {
observer.disconnect(); observer.disconnect();
applyStyles(styles, done); applyStyles(sections, done);
} }
}).observe(document, {childList: true}); }).observe(document, {childList: true});
return; return;
@ -336,8 +328,8 @@ const APPLY = (() => {
} else { } else {
initDocRootObserver(); initDocRootObserver();
} }
for (const section of styles) { for (const section of Object.values(sections)) {
applySections(section.id, section.code); applySections(section.id, section.code.join(''));
} }
docRootObserver.firstStart(); docRootObserver.firstStart();