simplify localization
This commit is contained in:
parent
151805f1bb
commit
b8322ecf01
|
@ -1,4 +1,10 @@
|
|||
/* global CodeMirror prefs editor $ template */
|
||||
/* global
|
||||
$
|
||||
CodeMirror
|
||||
editor
|
||||
prefs
|
||||
t
|
||||
*/
|
||||
|
||||
'use strict';
|
||||
|
||||
|
@ -183,7 +189,7 @@
|
|||
// setTimeout(() => {
|
||||
// $('.CodeMirror-dialog', section).focus();
|
||||
// });
|
||||
cm.openDialog(template.jumpToLine.cloneNode(true), str => {
|
||||
cm.openDialog(t.template.jumpToLine.cloneNode(true), str => {
|
||||
const m = str.match(/^\s*(\d+)(?:\s*:\s*(\d+))?\s*$/);
|
||||
if (m) {
|
||||
cm.setCursor(m[1] - 1, m[2] ? m[2] - 1 : cur.ch);
|
||||
|
|
|
@ -26,7 +26,6 @@
|
|||
setupLivePrefs
|
||||
SourceEditor
|
||||
t
|
||||
tHTML
|
||||
tryCatch
|
||||
tryJSONparse
|
||||
*/
|
||||
|
@ -449,7 +448,7 @@ function showHelp(title = '', body) {
|
|||
const contents = $('.contents', div);
|
||||
contents.textContent = '';
|
||||
if (body) {
|
||||
contents.appendChild(typeof body === 'string' ? tHTML(body) : body);
|
||||
contents.appendChild(typeof body === 'string' ? t.HTML(body) : body);
|
||||
}
|
||||
|
||||
$('.title', div).textContent = title;
|
||||
|
|
|
@ -1,5 +1,18 @@
|
|||
/* global CodeMirror focusAccessibility colorMimicry editor chromeLocal
|
||||
onDOMready $ $$ $create t debounce tryRegExp stringAsRegExp template */
|
||||
/* global
|
||||
$
|
||||
$$
|
||||
$create
|
||||
chromeLocal
|
||||
CodeMirror
|
||||
colorMimicry
|
||||
debounce
|
||||
editor
|
||||
focusAccessibility
|
||||
onDOMready
|
||||
stringAsRegExp
|
||||
t
|
||||
tryRegExp
|
||||
*/
|
||||
'use strict';
|
||||
|
||||
onDOMready().then(() => {
|
||||
|
@ -563,14 +576,14 @@ onDOMready().then(() => {
|
|||
state.originalFocus = document.activeElement;
|
||||
state.firstRun = true;
|
||||
|
||||
const dialog = state.dialog = template.searchReplaceDialog.cloneNode(true);
|
||||
const dialog = state.dialog = t.template.searchReplaceDialog.cloneNode(true);
|
||||
Object.assign(dialog, DIALOG_PROPS.dialog);
|
||||
dialog.addEventListener('focusout', EVENTS.onfocusout);
|
||||
dialog.dataset.type = type;
|
||||
dialog.style.pointerEvents = 'auto';
|
||||
|
||||
const content = $('[data-type="content"]', dialog);
|
||||
content.parentNode.replaceChild(template[type].cloneNode(true), content);
|
||||
content.parentNode.replaceChild(t.template[type].cloneNode(true), content);
|
||||
|
||||
createInput(0, 'input', state.find);
|
||||
createInput(1, 'input2', state.replace);
|
||||
|
@ -633,7 +646,7 @@ onDOMready().then(() => {
|
|||
input.value = value;
|
||||
Object.assign(input, DIALOG_PROPS[name]);
|
||||
|
||||
input.parentElement.appendChild(template.clearSearch.cloneNode(true));
|
||||
input.parentElement.appendChild(t.template.clearSearch.cloneNode(true));
|
||||
$('[data-action]', input.parentElement)._input = input;
|
||||
}
|
||||
|
||||
|
|
|
@ -9,7 +9,6 @@
|
|||
prefs
|
||||
regExpTester
|
||||
t
|
||||
template
|
||||
tryCatch
|
||||
*/
|
||||
'use strict';
|
||||
|
@ -55,7 +54,7 @@ function MozSectionWidget(
|
|||
$create('ul' + C_LIST),
|
||||
]),
|
||||
listItem:
|
||||
template.appliesTo.cloneNode(true),
|
||||
t.template.appliesTo.cloneNode(true),
|
||||
appliesToEverything:
|
||||
$create('li.applies-to-everything', t('appliesToEverything')),
|
||||
};
|
||||
|
|
|
@ -1,4 +1,12 @@
|
|||
/* global showHelp $ $create tryRegExp URLS t template openURL */
|
||||
/* global
|
||||
$
|
||||
$create
|
||||
openURL
|
||||
showHelp
|
||||
t
|
||||
tryRegExp
|
||||
URLS
|
||||
*/
|
||||
/* exported regExpTester */
|
||||
'use strict';
|
||||
|
||||
|
@ -86,7 +94,7 @@ const regExpTester = (() => {
|
|||
full: {data: [], label: t('styleRegexpTestFull')},
|
||||
partial: {data: [], label: [
|
||||
t('styleRegexpTestPartial'),
|
||||
template.regexpTestPartial.cloneNode(true),
|
||||
t.template.regexpTestPartial.cloneNode(true),
|
||||
]},
|
||||
none: {data: [], label: t('styleRegexpTestNone')},
|
||||
invalid: {data: [], label: t('styleRegexpTestInvalid')},
|
||||
|
|
|
@ -9,7 +9,6 @@
|
|||
prefs
|
||||
regExpTester
|
||||
t
|
||||
template
|
||||
trimCommentLabel
|
||||
tryRegExp
|
||||
*/
|
||||
|
@ -26,7 +25,7 @@
|
|||
function createSection(originalSection, genId, si) {
|
||||
const {dirty} = editor;
|
||||
const sectionId = genId();
|
||||
const el = template.section.cloneNode(true);
|
||||
const el = t.template.section.cloneNode(true);
|
||||
const elLabel = $('.code-label', el);
|
||||
const cm = cmFactory.create(wrapper => {
|
||||
// making it tall during initial load so IntersectionObserver sees only one adjacent CM
|
||||
|
@ -265,8 +264,8 @@ function createSection(originalSection, genId, si) {
|
|||
function createApply({type = 'url', value, all = false}) {
|
||||
const applyId = genId();
|
||||
const dirtyPrefix = `section.${sectionId}.apply.${applyId}`;
|
||||
const el = all ? template.appliesToEverything.cloneNode(true) :
|
||||
template.appliesTo.cloneNode(true);
|
||||
const el = all ? t.template.appliesToEverything.cloneNode(true) :
|
||||
t.template.appliesTo.cloneNode(true);
|
||||
|
||||
const selectEl = !all && $('.applies-type', el);
|
||||
if (selectEl) {
|
||||
|
@ -359,7 +358,7 @@ function createSection(originalSection, genId, si) {
|
|||
function createResizeGrip(cm) {
|
||||
const wrapper = cm.display.wrapper;
|
||||
wrapper.classList.add('resize-grip-enabled');
|
||||
const resizeGrip = template.resizeGrip.cloneNode(true);
|
||||
const resizeGrip = t.template.resizeGrip.cloneNode(true);
|
||||
wrapper.appendChild(resizeGrip);
|
||||
let lastClickTime = 0;
|
||||
let initHeight;
|
||||
|
|
|
@ -1,5 +1,14 @@
|
|||
/* global CodeMirror showHelp onDOMready $ $$ $create template t
|
||||
prefs stringAsRegExp */
|
||||
/* global
|
||||
$
|
||||
$$
|
||||
$create
|
||||
CodeMirror
|
||||
onDOMready
|
||||
prefs
|
||||
showHelp
|
||||
stringAsRegExp
|
||||
t
|
||||
*/
|
||||
'use strict';
|
||||
|
||||
onDOMready().then(() => {
|
||||
|
@ -11,7 +20,7 @@ function showKeyMapHelp() {
|
|||
const keyMapSorted = Object.keys(keyMap)
|
||||
.map(key => ({key, cmd: keyMap[key]}))
|
||||
.sort((a, b) => (a.cmd < b.cmd || (a.cmd === b.cmd && a.key < b.key) ? -1 : 1));
|
||||
const table = template.keymapHelp.cloneNode(true);
|
||||
const table = t.template.keymapHelp.cloneNode(true);
|
||||
const tBody = table.tBodies[0];
|
||||
const row = tBody.rows[0];
|
||||
const cellA = row.children[0];
|
||||
|
|
|
@ -1,97 +1,90 @@
|
|||
/* global tryCatch */
|
||||
/* exported tHTML formatDate */
|
||||
'use strict';
|
||||
|
||||
const template = {};
|
||||
tDocLoader();
|
||||
|
||||
|
||||
function t(key, params) {
|
||||
const s = chrome.i18n.getMessage(key, params);
|
||||
if (!s) throw `Missing string "${key}"`;
|
||||
return s;
|
||||
}
|
||||
|
||||
Object.assign(t, {
|
||||
template: {},
|
||||
DOMParser: new DOMParser(),
|
||||
ALLOWED_TAGS: 'a,b,code,i,sub,sup,wbr'.split(','),
|
||||
RX_WORD_BREAK: new RegExp([
|
||||
'(',
|
||||
/[\d\w\u007B-\uFFFF]{10}/,
|
||||
'|',
|
||||
/[\d\w\u007B-\uFFFF]{5,10}[!-/]/,
|
||||
'|',
|
||||
/((?!\s)\W){10}/,
|
||||
')',
|
||||
/(?!\b|\s|$)/,
|
||||
].map(rx => rx.source || rx).join(''), 'g'),
|
||||
|
||||
function tHTML(html, tag) {
|
||||
// body is a text node without HTML tags
|
||||
if (typeof html === 'string' && !tag && /<\w+/.test(html) === false) {
|
||||
return document.createTextNode(html);
|
||||
}
|
||||
if (typeof html === 'string') {
|
||||
// spaces are removed; use for an explicit space
|
||||
html = html.replace(/>\s+</g, '><').trim();
|
||||
if (tag) {
|
||||
html = `<${tag}>${html}</${tag}>`;
|
||||
}
|
||||
const body = t.DOMParser.parseFromString(html, 'text/html').body;
|
||||
if (html.includes('i18n-')) {
|
||||
tNodeList(body.getElementsByTagName('*'));
|
||||
}
|
||||
// the html string may contain more than one top-level node
|
||||
if (!body.childNodes[1]) {
|
||||
return body.firstChild;
|
||||
}
|
||||
const fragment = document.createDocumentFragment();
|
||||
while (body.firstChild) {
|
||||
fragment.appendChild(body.firstChild);
|
||||
}
|
||||
return fragment;
|
||||
}
|
||||
return html;
|
||||
}
|
||||
HTML(html) {
|
||||
return typeof html !== 'string'
|
||||
? html
|
||||
: /<\w+/.test(html) // check for html tags
|
||||
? t.createHtml(html.replace(/>\n\s*</g, '><').trim())
|
||||
: document.createTextNode(html);
|
||||
},
|
||||
|
||||
|
||||
function tNodeList(nodes) {
|
||||
const PREFIX = 'i18n-';
|
||||
|
||||
for (let n = nodes.length; --n >= 0;) {
|
||||
const node = nodes[n];
|
||||
if (node.nodeType !== Node.ELEMENT_NODE) {
|
||||
continue;
|
||||
}
|
||||
if (node.localName === 'template') {
|
||||
createTemplate(node);
|
||||
continue;
|
||||
}
|
||||
for (let a = node.attributes.length; --a >= 0;) {
|
||||
const attr = node.attributes[a];
|
||||
const name = attr.nodeName;
|
||||
if (!name.startsWith(PREFIX)) {
|
||||
NodeList(nodes) {
|
||||
const PREFIX = 'i18n-';
|
||||
for (let n = nodes.length; --n >= 0;) {
|
||||
const node = nodes[n];
|
||||
if (node.nodeType !== Node.ELEMENT_NODE) {
|
||||
continue;
|
||||
}
|
||||
const type = name.substr(PREFIX.length);
|
||||
const value = t(attr.value);
|
||||
let toInsert, before;
|
||||
switch (type) {
|
||||
case 'word-break':
|
||||
// we already know that: hasWordBreak
|
||||
break;
|
||||
case 'text':
|
||||
before = node.firstChild;
|
||||
// fallthrough to text-append
|
||||
case 'text-append':
|
||||
toInsert = createText(value);
|
||||
break;
|
||||
case 'html': {
|
||||
toInsert = createHtml(value);
|
||||
break;
|
||||
if (node.localName === 'template') {
|
||||
t.createTemplate(node);
|
||||
continue;
|
||||
}
|
||||
for (let a = node.attributes.length; --a >= 0;) {
|
||||
const attr = node.attributes[a];
|
||||
const name = attr.nodeName;
|
||||
if (!name.startsWith(PREFIX)) {
|
||||
continue;
|
||||
}
|
||||
default:
|
||||
node.setAttribute(type, value);
|
||||
const type = name.substr(PREFIX.length);
|
||||
const value = t(attr.value);
|
||||
let toInsert, before;
|
||||
switch (type) {
|
||||
case 'word-break':
|
||||
// we already know that: hasWordBreak
|
||||
break;
|
||||
case 'text':
|
||||
before = node.firstChild;
|
||||
// fallthrough to text-append
|
||||
case 'text-append':
|
||||
toInsert = t.createText(value);
|
||||
break;
|
||||
case 'html': {
|
||||
toInsert = t.createHtml(value);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
node.setAttribute(type, value);
|
||||
}
|
||||
t.stopObserver();
|
||||
if (toInsert) {
|
||||
node.insertBefore(toInsert, before || null);
|
||||
}
|
||||
node.removeAttribute(name);
|
||||
}
|
||||
tDocLoader.pause();
|
||||
if (toInsert) {
|
||||
node.insertBefore(toInsert, before || null);
|
||||
}
|
||||
node.removeAttribute(name);
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
function createTemplate(node) {
|
||||
/** Adds soft hyphens every 10 characters to ensure the long words break before breaking the layout */
|
||||
breakWord(text) {
|
||||
return text.length <= 10 ? text :
|
||||
text.replace(t.RX_WORD_BREAK, '$&\u00AD');
|
||||
},
|
||||
|
||||
createTemplate(node) {
|
||||
const elements = node.content.querySelectorAll('*');
|
||||
tNodeList(elements);
|
||||
template[node.dataset.id] = elements[0];
|
||||
t.NodeList(elements);
|
||||
t.template[node.dataset.id] = elements[0];
|
||||
// compress inter-tag whitespace to reduce number of DOM nodes by 25%
|
||||
const walker = document.createTreeWalker(elements[0], NodeFilter.SHOW_TEXT);
|
||||
const toRemove = [];
|
||||
|
@ -101,104 +94,96 @@ function tNodeList(nodes) {
|
|||
toRemove.push(textNode);
|
||||
}
|
||||
}
|
||||
tDocLoader.pause();
|
||||
t.stopObserver();
|
||||
toRemove.forEach(el => el.remove());
|
||||
}
|
||||
},
|
||||
|
||||
function createText(str) {
|
||||
return document.createTextNode(tWordBreak(str));
|
||||
}
|
||||
createText(str) {
|
||||
return document.createTextNode(t.breakWord(str));
|
||||
},
|
||||
|
||||
function createHtml(value) {
|
||||
// <a> and <code> are the only acceptable HTML elements,
|
||||
// <a> also allows `href` attribute with an http/https URL
|
||||
const rx = /(<)(a|code)(\s[^>]*|)>(.*?)<\/\2>/i;
|
||||
createHtml(str, trusted) {
|
||||
const root = t.DOMParser.parseFromString(str, 'text/html').body;
|
||||
if (!trusted) {
|
||||
t.sanitizeHtml(root);
|
||||
} else if (str.includes('i18n-')) {
|
||||
t.NodeList(root.getElementsByTagName('*'));
|
||||
}
|
||||
const bin = document.createDocumentFragment();
|
||||
for (let parts = value.split(rx), i = 0; i < parts.length; i++) {
|
||||
const s = parts[i];
|
||||
if (s === '<') {
|
||||
const tag = parts[++i].toLowerCase();
|
||||
const el = bin.appendChild(document.createElement(tag));
|
||||
const attrs = parts[++i];
|
||||
const href = tag === 'a' && /(?:^|\s)href\s*=\s*(["'])?(https?:\/\/\S*?)\1/i.exec(attrs);
|
||||
if (href) el.href = href[2];
|
||||
el.appendChild(createText(parts[++i]));
|
||||
} else {
|
||||
bin.appendChild(createText(s));
|
||||
}
|
||||
while (root.firstChild) {
|
||||
bin.appendChild(root.firstChild);
|
||||
}
|
||||
return bin;
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
|
||||
function tDocLoader() {
|
||||
t.DOMParser = new DOMParser();
|
||||
t.RX_WORD_BREAK = new RegExp([
|
||||
'(',
|
||||
/[\d\w\u007B-\uFFFF]{10}/,
|
||||
'|',
|
||||
/[\d\w\u007B-\uFFFF]{5,10}[!-/]/,
|
||||
'|',
|
||||
/((?!\s)\W){10}/,
|
||||
')',
|
||||
/(?!\b|\s|$)/,
|
||||
].map(rx => rx.source || rx).join(''), 'g');
|
||||
|
||||
Object.assign(tDocLoader, {
|
||||
observer: new MutationObserver(process),
|
||||
start() {
|
||||
if (!tDocLoader.observing) {
|
||||
tDocLoader.observing = true;
|
||||
tDocLoader.observer.observe(document, {subtree: true, childList: true});
|
||||
sanitizeHtml(root) {
|
||||
const toRemove = [];
|
||||
const walker = document.createTreeWalker(root);
|
||||
for (let n; (n = walker.nextNode());) {
|
||||
if (n.nodeType === Node.TEXT_NODE) {
|
||||
n.nodeValue = t.breakWord(n.nodeValue);
|
||||
} else if (t.ALLOWED_TAGS.includes(n.localName)) {
|
||||
for (const attr of n.attributes) {
|
||||
if (n.localName !== 'a' || attr.localName !== 'href' || !/^https?:/.test(n.href)) {
|
||||
n.removeAttribute(attr.name);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
toRemove.push(n);
|
||||
}
|
||||
},
|
||||
stop() {
|
||||
tDocLoader.pause();
|
||||
document.removeEventListener('DOMContentLoaded', onLoad);
|
||||
},
|
||||
pause() {
|
||||
if (tDocLoader.observing) {
|
||||
tDocLoader.observing = false;
|
||||
tDocLoader.observer.disconnect();
|
||||
}
|
||||
for (const n of toRemove) {
|
||||
const parent = n.parentNode;
|
||||
if (parent) parent.removeChild(n); // not using .remove() as there may be a non-element
|
||||
}
|
||||
},
|
||||
|
||||
formatDate(date) {
|
||||
if (!date) {
|
||||
return '';
|
||||
}
|
||||
try {
|
||||
const newDate = new Date(Number(date) || date);
|
||||
const string = newDate.toLocaleDateString([chrome.i18n.getUILanguage(), 'en'], {
|
||||
day: '2-digit',
|
||||
month: 'short',
|
||||
year: newDate.getYear() === new Date().getYear() ? undefined : '2-digit',
|
||||
});
|
||||
return string === 'Invalid Date' ? '' : string;
|
||||
} catch (e) {
|
||||
return '';
|
||||
}
|
||||
},
|
||||
});
|
||||
|
||||
(() => {
|
||||
const observer = new MutationObserver(process);
|
||||
let observing = false;
|
||||
Object.assign(t, {
|
||||
stopObserver() {
|
||||
if (observing) {
|
||||
observing = false;
|
||||
observer.disconnect();
|
||||
}
|
||||
},
|
||||
});
|
||||
document.addEventListener('DOMContentLoaded', () => {
|
||||
process(observer.takeRecords());
|
||||
t.stopObserver();
|
||||
}, {once: true});
|
||||
|
||||
tNodeList(document.getElementsByTagName('*'));
|
||||
tDocLoader.start();
|
||||
document.addEventListener('DOMContentLoaded', onLoad);
|
||||
t.NodeList(document.getElementsByTagName('*'));
|
||||
start();
|
||||
|
||||
function process(mutations) {
|
||||
for (const mutation of mutations) {
|
||||
tNodeList(mutation.addedNodes);
|
||||
mutations.forEach(m => t.NodeList(m.addedNodes));
|
||||
start();
|
||||
}
|
||||
|
||||
function start() {
|
||||
if (!observing) {
|
||||
observing = true;
|
||||
observer.observe(document, {subtree: true, childList: true});
|
||||
}
|
||||
tDocLoader.start();
|
||||
}
|
||||
|
||||
function onLoad() {
|
||||
document.removeEventListener('DOMContentLoaded', onLoad);
|
||||
process(tDocLoader.observer.takeRecords());
|
||||
tDocLoader.stop();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
function tWordBreak(text) {
|
||||
// adds soft hyphens every 10 characters to ensure the long words break before breaking the layout
|
||||
return text.length <= 10 ? text :
|
||||
text.replace(t.RX_WORD_BREAK, '$&\u00AD');
|
||||
}
|
||||
|
||||
|
||||
function formatDate(date) {
|
||||
return !date ? '' : tryCatch(() => {
|
||||
const newDate = new Date(Number(date) || date);
|
||||
const string = newDate.toLocaleDateString([t.cache.browserUIlanguage, 'en'], {
|
||||
day: '2-digit',
|
||||
month: 'short',
|
||||
year: newDate.getYear() === new Date().getYear() ? undefined : '2-digit',
|
||||
});
|
||||
return string === 'Invalid Date' ? '' : string;
|
||||
}) || '';
|
||||
}
|
||||
})();
|
||||
|
|
|
@ -1,5 +1,15 @@
|
|||
/* global messageBox deepCopy $create $createLink $ t tWordBreak
|
||||
prefs setupLivePrefs debounce API */
|
||||
/* global
|
||||
$
|
||||
$create
|
||||
$createLink
|
||||
API
|
||||
debounce
|
||||
deepCopy
|
||||
messageBox
|
||||
prefs
|
||||
setupLivePrefs
|
||||
t
|
||||
*/
|
||||
/* exported configDialog */
|
||||
'use strict';
|
||||
|
||||
|
@ -305,7 +315,7 @@ function configDialog(style) {
|
|||
|
||||
elements.push(
|
||||
$create(`label.config-${va.type}`, [
|
||||
$create('span.config-name', tWordBreak(va.label)),
|
||||
$create('span.config-name', t.breakWord(va.label)),
|
||||
...children,
|
||||
resetter,
|
||||
]));
|
||||
|
|
|
@ -9,7 +9,6 @@
|
|||
configDialog
|
||||
debounce
|
||||
filterAndAppend
|
||||
formatDate
|
||||
getOwnTab
|
||||
getStyleWithNoCode
|
||||
handleUpdateInstalled
|
||||
|
@ -25,8 +24,6 @@
|
|||
showFiltersStats
|
||||
sorter
|
||||
t
|
||||
template
|
||||
tWordBreak
|
||||
VIVALDI
|
||||
*/
|
||||
'use strict';
|
||||
|
@ -187,7 +184,7 @@ function showStyles(styles = [], matchUrlIds) {
|
|||
function createStyleElement({style, name: nameLC}) {
|
||||
// query the sub-elements just once, then reuse the references
|
||||
if ((createStyleElement.parts || {}).newUI !== newUI.enabled) {
|
||||
const entry = template[`style${newUI.enabled ? 'Compact' : ''}`];
|
||||
const entry = t.template[`style${newUI.enabled ? 'Compact' : ''}`];
|
||||
createStyleElement.parts = {
|
||||
newUI: newUI.enabled,
|
||||
entry,
|
||||
|
@ -197,7 +194,7 @@ function createStyleElement({style, name: nameLC}) {
|
|||
editLink: $('.style-edit-link', entry) || {},
|
||||
editHrefBase: 'edit.html?id=',
|
||||
homepage: $('.homepage', entry),
|
||||
homepageIcon: template[`homepageIcon${newUI.enabled ? 'Small' : 'Big'}`],
|
||||
homepageIcon: t.template[`homepageIcon${newUI.enabled ? 'Small' : 'Big'}`],
|
||||
appliesTo: $('.applies-to', entry),
|
||||
targets: $('.targets', entry),
|
||||
expander: $('.expander', entry),
|
||||
|
@ -215,7 +212,7 @@ function createStyleElement({style, name: nameLC}) {
|
|||
const configurable = style.usercssData && style.usercssData.vars && Object.keys(style.usercssData.vars).length > 0;
|
||||
const name = style.customName || style.name;
|
||||
parts.checker.checked = style.enabled;
|
||||
parts.nameLink.textContent = tWordBreak(name);
|
||||
parts.nameLink.textContent = t.breakWord(name);
|
||||
parts.nameLink.href = parts.editLink.href = parts.editHrefBase + style.id;
|
||||
parts.homepage.href = parts.homepage.title = style.url || '';
|
||||
if (!newUI.enabled) {
|
||||
|
@ -243,10 +240,10 @@ function createStyleElement({style, name: nameLC}) {
|
|||
$('.homepage', entry).appendChild(parts.homepageIcon.cloneNode(true));
|
||||
}
|
||||
if (style.updateUrl && newUI.enabled) {
|
||||
$('.actions', entry).appendChild(template.updaterIcons.cloneNode(true));
|
||||
$('.actions', entry).appendChild(t.template.updaterIcons.cloneNode(true));
|
||||
}
|
||||
if (configurable && newUI.enabled) {
|
||||
$('.actions', entry).appendChild(template.configureIcon.cloneNode(true));
|
||||
$('.actions', entry).appendChild(t.template.configureIcon.cloneNode(true));
|
||||
}
|
||||
|
||||
createStyleTargetsElement({entry, style});
|
||||
|
@ -287,12 +284,12 @@ function createStyleTargetsElement({entry, expanded, style = entry.styleMeta}) {
|
|||
el = next;
|
||||
continue;
|
||||
}
|
||||
const element = template.appliesToTarget.cloneNode(true);
|
||||
const element = t.template.appliesToTarget.cloneNode(true);
|
||||
if (!newUI.enabled) {
|
||||
if (numTargets === maxTargets) {
|
||||
container = container.appendChild(template.extraAppliesTo.cloneNode(true));
|
||||
container = container.appendChild(t.template.extraAppliesTo.cloneNode(true));
|
||||
} else if (numTargets > 0) {
|
||||
container.appendChild(template.appliesToSeparator.cloneNode(true));
|
||||
container.appendChild(t.template.appliesToSeparator.cloneNode(true));
|
||||
}
|
||||
}
|
||||
element.dataset.type = type;
|
||||
|
@ -311,7 +308,7 @@ function createStyleTargetsElement({entry, expanded, style = entry.styleMeta}) {
|
|||
if (entryTargets.firstElementChild) {
|
||||
entryTargets.textContent = '';
|
||||
}
|
||||
entryTargets.appendChild(template.appliesToEverything.cloneNode(true));
|
||||
entryTargets.appendChild(t.template.appliesToEverything.cloneNode(true));
|
||||
}
|
||||
entry.classList.toggle('global', !numTargets);
|
||||
entry._allTargetsRendered = allTargetsRendered;
|
||||
|
@ -525,7 +522,7 @@ Object.assign(handleEvent, {
|
|||
{prop: 'installDate', name: 'dateInstalled'},
|
||||
{prop: 'updateDate', name: 'dateUpdated'},
|
||||
].map(({prop, name}) =>
|
||||
t(name) + ': ' + (formatDate(entry.styleMeta[prop]) || '—')).join('\n');
|
||||
t(name) + ': ' + (t.formatDate(entry.styleMeta[prop]) || '—')).join('\n');
|
||||
},
|
||||
});
|
||||
|
||||
|
|
|
@ -1,11 +1,18 @@
|
|||
/* global focusAccessibility moveFocus $ $create t tHTML animateElement */
|
||||
/* global
|
||||
$
|
||||
$create
|
||||
animateElement
|
||||
focusAccessibility
|
||||
moveFocus
|
||||
t
|
||||
*/
|
||||
'use strict';
|
||||
|
||||
/**
|
||||
* @param {Object} params
|
||||
* @param {String} params.title
|
||||
* @param {String|Node|Object|Array<String|Node|Object>} params.contents
|
||||
* a string gets parsed via tHTML,
|
||||
* a string gets parsed via t.HTML,
|
||||
* a non-string is passed as is to $create()
|
||||
* @param {String} [params.className]
|
||||
* CSS class name of the message box element
|
||||
|
@ -116,7 +123,7 @@ function messageBox({
|
|||
$create('SVG:path', {d: 'M11.69,10l4.55,4.55-1.69,1.69L10,11.69,' +
|
||||
'5.45,16.23,3.77,14.55,8.31,10,3.77,5.45,5.45,3.77,10,8.31l4.55-4.55,1.69,1.69Z',
|
||||
}))),
|
||||
$create(`#${id}-contents`, tHTML(contents)),
|
||||
$create(`#${id}-contents`, t.HTML(contents)),
|
||||
$create(`#${id}-buttons`,
|
||||
buttons.map((content, buttonIndex) => content &&
|
||||
$create('button', Object.assign({
|
||||
|
|
|
@ -1,7 +1,23 @@
|
|||
/* global configDialog hotkeys msg
|
||||
getActiveTab CHROME FIREFOX URLS API onDOMready $ $$ prefs
|
||||
setupLivePrefs template t $create animateElement
|
||||
tryJSONparse CHROME_HAS_BORDER_BUG */
|
||||
/* global
|
||||
$
|
||||
$$
|
||||
$create
|
||||
animateElement
|
||||
API
|
||||
CHROME
|
||||
CHROME_HAS_BORDER_BUG
|
||||
configDialog
|
||||
FIREFOX
|
||||
getActiveTab
|
||||
hotkeys
|
||||
msg
|
||||
onDOMready
|
||||
prefs
|
||||
setupLivePrefs
|
||||
t
|
||||
tryJSONparse
|
||||
URLS
|
||||
*/
|
||||
|
||||
'use strict';
|
||||
|
||||
|
@ -165,7 +181,7 @@ function initPopup(frames) {
|
|||
setTimeout(ping, 100, tab, --retryCountdown);
|
||||
return;
|
||||
}
|
||||
const info = template.unreachableInfo;
|
||||
const info = t.template.unreachableInfo;
|
||||
if (!FIREFOX) {
|
||||
// Chrome "Allow access to file URLs" in chrome://extensions message
|
||||
info.appendChild($create('p', t('unreachableFileHint')));
|
||||
|
@ -204,7 +220,7 @@ function createWriterElement(frame) {
|
|||
const targets = $create('span');
|
||||
|
||||
// For this URL
|
||||
const urlLink = template.writeStyle.cloneNode(true);
|
||||
const urlLink = t.template.writeStyle.cloneNode(true);
|
||||
const isAboutBlank = url === ABOUT_BLANK;
|
||||
Object.assign(urlLink, {
|
||||
href: 'edit.html?url-prefix=' + encodeURIComponent(url),
|
||||
|
@ -233,7 +249,7 @@ function createWriterElement(frame) {
|
|||
if (domains.length > 1 && numParts === 1) {
|
||||
continue;
|
||||
}
|
||||
const domainLink = template.writeStyle.cloneNode(true);
|
||||
const domainLink = t.template.writeStyle.cloneNode(true);
|
||||
Object.assign(domainLink, {
|
||||
href: 'edit.html?domain=' + encodeURIComponent(domain),
|
||||
textContent: numParts > 2 ? domain.split('.')[0] : domain,
|
||||
|
@ -322,7 +338,7 @@ function showStyles(frameResults) {
|
|||
if (entries.size) {
|
||||
resortEntries([...entries.values()]);
|
||||
} else {
|
||||
installed.appendChild(template.noStyles);
|
||||
installed.appendChild(t.template.noStyles);
|
||||
}
|
||||
window.dispatchEvent(new Event('showStyles:done'));
|
||||
}
|
||||
|
@ -337,7 +353,7 @@ function resortEntries(entries) {
|
|||
function createStyleElement(style) {
|
||||
let entry = $.entry(style);
|
||||
if (!entry) {
|
||||
entry = template.style.cloneNode(true);
|
||||
entry = t.template.style.cloneNode(true);
|
||||
entry.setAttribute('style-id', style.id);
|
||||
Object.assign(entry, {
|
||||
id: ENTRY_ID_PREFIX_RAW + style.id,
|
||||
|
@ -384,7 +400,7 @@ function createStyleElement(style) {
|
|||
|
||||
$('.delete', entry).onclick = handleEvent.delete;
|
||||
|
||||
const indicator = template.regexpProblemIndicator.cloneNode(true);
|
||||
const indicator = t.template.regexpProblemIndicator.cloneNode(true);
|
||||
indicator.appendChild(document.createTextNode('!'));
|
||||
indicator.onclick = handleEvent.indicator;
|
||||
$('.main-controls', entry).appendChild(indicator);
|
||||
|
@ -587,7 +603,7 @@ Object.assign(handleEvent, {
|
|||
|
||||
indicator(event) {
|
||||
const entry = handleEvent.getClickedStyleElement(event);
|
||||
const info = template.regexpProblemExplanation.cloneNode(true);
|
||||
const info = t.template.regexpProblemExplanation.cloneNode(true);
|
||||
$.remove('#' + info.id);
|
||||
$$('a', info).forEach(el => (el.onclick = handleEvent.openURLandHide));
|
||||
$$('button', info).forEach(el => (el.onclick = handleEvent.closeExplanation));
|
||||
|
@ -684,7 +700,7 @@ function handleDelete(id) {
|
|||
const el = $.entry(id);
|
||||
if (el) {
|
||||
el.remove();
|
||||
if (!$('.entry')) installed.appendChild(template.noStyles);
|
||||
if (!$('.entry')) installed.appendChild(t.template.noStyles);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -714,9 +730,9 @@ async function getStyleDataMerged(url, id) {
|
|||
function blockPopup(isBlocked = true) {
|
||||
document.body.classList.toggle('blocked', isBlocked);
|
||||
if (isBlocked) {
|
||||
document.body.prepend(template.unavailableInfo);
|
||||
document.body.prepend(t.template.unavailableInfo);
|
||||
} else {
|
||||
template.unavailableInfo.remove();
|
||||
template.noStyles.remove();
|
||||
t.template.unavailableInfo.remove();
|
||||
t.template.noStyles.remove();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,5 +1,18 @@
|
|||
/* global URLS tabURL handleEvent $ $$ prefs template FIREFOX debounce
|
||||
$create t API tWordBreak formatDate tryCatch download */
|
||||
/* global
|
||||
$
|
||||
$$
|
||||
$create
|
||||
API
|
||||
debounce
|
||||
download
|
||||
FIREFOX
|
||||
handleEvent
|
||||
prefs
|
||||
t
|
||||
tabURL
|
||||
tryCatch
|
||||
URLS
|
||||
*/
|
||||
'use strict';
|
||||
|
||||
window.addEventListener('showStyles:done', () => {
|
||||
|
@ -103,7 +116,7 @@ window.addEventListener('showStyles:done', () => {
|
|||
const navOnClick = {prev, next};
|
||||
for (const place of ['top', 'bottom']) {
|
||||
const nav = $(`.search-results-nav[data-type="${place}"]`);
|
||||
nav.appendChild(template.searchNav.cloneNode(true));
|
||||
nav.appendChild(t.template.searchNav.cloneNode(true));
|
||||
dom.nav[place] = nav;
|
||||
for (const child of $$('[data-type]', nav)) {
|
||||
const type = child.dataset.type;
|
||||
|
@ -257,7 +270,7 @@ window.addEventListener('showStyles:done', () => {
|
|||
* @returns {Node}
|
||||
*/
|
||||
function createSearchResultNode(result) {
|
||||
const entry = template.searchResult.cloneNode(true);
|
||||
const entry = t.template.searchResult.cloneNode(true);
|
||||
const {
|
||||
i: id,
|
||||
n: name,
|
||||
|
@ -276,7 +289,7 @@ window.addEventListener('showStyles:done', () => {
|
|||
href: URLS.usoArchive + `?category=${category}&style=${id}`,
|
||||
});
|
||||
$('.search-result-title span', entry).textContent =
|
||||
tWordBreak(name.length < 300 ? name : name.slice(0, 300) + '...');
|
||||
t.breakWord(name.length < 300 ? name : name.slice(0, 300) + '...');
|
||||
// screenshot
|
||||
const auto = URLS.uso + `auto_style_screenshots/${id}${USO_AUTO_PIC_SUFFIX}`;
|
||||
Object.assign($('.search-result-screenshot', entry), {
|
||||
|
@ -303,7 +316,7 @@ window.addEventListener('showStyles:done', () => {
|
|||
// time
|
||||
Object.assign($('[data-type="updated"] time', entry), {
|
||||
dateTime: updateTime * 1000,
|
||||
textContent: formatDate(updateTime * 1000),
|
||||
textContent: t.formatDate(updateTime * 1000),
|
||||
});
|
||||
// totals
|
||||
$('[data-type="weekly"] dd', entry).textContent = formatNumber(weeklyInstalls);
|
||||
|
|
Loading…
Reference in New Issue
Block a user