diff --git a/edit/preinit.js b/edit/preinit.js index b651338d..f62cd346 100644 --- a/edit/preinit.js +++ b/edit/preinit.js @@ -10,9 +10,9 @@ define(require => { tryJSONparse, } = require('/js/toolbox'); const {$, waitForSelector} = require('/js/dom'); + const {MozDocMapper} = require('/js/sections-util'); const prefs = require('/js/prefs'); const editor = require('./editor'); - const util = require('./util'); const lazyKeymaps = { emacs: '/vendor/codemirror/keymap/emacs', @@ -114,7 +114,7 @@ define(require => { '', enabled: true, sections: [ - util.DocFuncMapper.toSection([...params], {code: ''}), + MozDocMapper.toSection([...params], {code: ''}), ], }; // switching the mode here to show the correct page ASAP, usually before DOMContentLoaded diff --git a/edit/sections-editor-section.js b/edit/sections-editor-section.js index 683160f5..4bb13757 100644 --- a/edit/sections-editor-section.js +++ b/edit/sections-editor-section.js @@ -5,10 +5,11 @@ define(require => { const {$} = require('/js/dom'); const t = require('/js/localization'); const prefs = require('/js/prefs'); + const {MozDocMapper} = require('/js/sections-util'); const cmFactory = require('./codemirror-factory'); const editor = require('./editor'); const linterMan = require('./linter-manager'); - const {DocFuncMapper, trimCommentLabel} = require('./util'); + const {trimCommentLabel} = require('./util'); /** @type {RegExpTester} */ let regExpTester; @@ -40,7 +41,7 @@ define(require => { const appliesToContainer = $('.applies-to-list', el); const appliesTo = []; - DocFuncMapper.forEachProp(originalSection, (type, value) => + MozDocMapper.forEachProp(originalSection, (type, value) => insertApplyAfter({type, value})); if (!appliesTo.length) { insertApplyAfter({all: true}); @@ -61,7 +62,7 @@ define(require => { appliesTo, getModel() { const items = appliesTo.map(a => !a.all && [a.type, a.value]); - return DocFuncMapper.toSection(items, {code: cm.getValue()}); + return MozDocMapper.toSection(items, {code: cm.getValue()}); }, remove() { linterMan.disableForEditor(cm); diff --git a/edit/sections-editor.js b/edit/sections-editor.js index 23088756..8a5b4b40 100644 --- a/edit/sections-editor.js +++ b/edit/sections-editor.js @@ -26,7 +26,6 @@ define(require => function SectionsEditor() { clipString, helpPopup, rerouteHotkeys, - sectionsToMozFormat, showCodeMirrorPopup, } = require('./util'); @@ -332,9 +331,11 @@ define(require => function SectionsEditor() { } function showMozillaFormat() { - const popup = showCodeMirrorPopup(t('styleToMozillaFormatTitle'), '', {readOnly: true}); - popup.codebox.setValue(sectionsToMozFormat(getModel())); - popup.codebox.execCommand('selectAll'); + require(['/js/sections-util'], util => { + const popup = showCodeMirrorPopup(t('styleToMozillaFormatTitle'), '', {readOnly: true}); + popup.codebox.setValue(util.MozDocMapper.styleToCss(getModel())); + popup.codebox.execCommand('selectAll'); + }); } function showMozillaFormatImport(text = '') { diff --git a/edit/source-editor.js b/edit/source-editor.js index cf23f702..b6adbc8e 100644 --- a/edit/source-editor.js +++ b/edit/source-editor.js @@ -12,6 +12,7 @@ define(require => function SourceEditor() { } = require('/js/dom'); const t = require('/js/localization'); const prefs = require('/js/prefs'); + const {MozDocMapper} = require('/js/sections-util'); const {chromeSync} = require('/js/storage-util'); const cmFactory = require('./codemirror-factory'); const editor = require('./editor'); @@ -19,7 +20,6 @@ define(require => function SourceEditor() { const linterMan = require('./linter-manager'); const sectionFinder = require('./moz-section-finder'); const sectionWidget = require('./moz-section-widget'); - const {sectionsToMozFormat} = require('./util'); const {CodeMirror} = cmFactory; const {style, /** @type DirtyReporter */dirty} = editor; @@ -158,10 +158,10 @@ define(require => function SourceEditor() { async function setupNewStyle(style) { style.sections[0].code = ' '.repeat(prefs.get('editor.tabSize')) + `/* ${t('usercssReplaceTemplateSectionBody')} */`; - let section = sectionsToMozFormat(style); + let section = MozDocMapper.styleToCss(style); if (!section.includes('@-moz-document')) { style.sections[0].domains = ['example.com']; - section = sectionsToMozFormat(style); + section = MozDocMapper.styleToCss(style); } const DEFAULT_CODE = ` /* ==UserStyle== diff --git a/edit/util.js b/edit/util.js index ebc72b1e..fbf5c40f 100644 --- a/edit/util.js +++ b/edit/util.js @@ -13,49 +13,6 @@ define(require => { let CodeMirror; - // TODO: maybe move to sections-util.js - const DocFuncMapper = { - TO_CSS: { - urls: 'url', - urlPrefixes: 'url-prefix', - domains: 'domain', - regexps: 'regexp', - }, - FROM_CSS: { - 'url': 'urls', - 'url-prefix': 'urlPrefixes', - 'domain': 'domains', - 'regexp': 'regexps', - }, - /** - * @param {Object} section - * @param {function(func:string, value:string)} fn - */ - forEachProp(section, fn) { - for (const [propName, func] of Object.entries(DocFuncMapper.TO_CSS)) { - const props = section[propName]; - if (props) props.forEach(value => fn(func, value)); - } - }, - /** - * @param {Array} funcItems - * @param {?Object} [section] - * @returns {Object} section - */ - toSection(funcItems, section = {}) { - for (const item of funcItems) { - const [func, value] = item || []; - const propName = DocFuncMapper.FROM_CSS[func]; - if (propName) { - const props = section[propName] || (section[propName] = []); - if (Array.isArray(value)) props.push(...value); - else props.push(value); - } - } - return section; - }, - }; - const util = { get CodeMirror() { @@ -64,7 +21,6 @@ define(require => { set CodeMirror(val) { CodeMirror = val; }, - DocFuncMapper, helpPopup: { show(title = '', body) { @@ -169,17 +125,6 @@ define(require => { require(['./reroute-hotkeys'], res => res(...args)); }, - sectionsToMozFormat(style) { - return style.sections.map(section => { - const cssFuncs = []; - DocFuncMapper.forEachProp(section, (type, value) => - cssFuncs.push(`${type}("${value.replace(/\\/g, '\\\\')}")`)); - return cssFuncs.length ? - `@-moz-document ${cssFuncs.join(', ')} {\n${section.code}\n}` : - section.code; - }).join('\n\n'); - }, - showCodeMirrorPopup(title, html, options) { const popup = util.helpPopup.show(title, html); popup.classList.add('big'); diff --git a/js/moz-parser.js b/js/moz-parser.js index f64f199f..08a7c51c 100644 --- a/js/moz-parser.js +++ b/js/moz-parser.js @@ -2,7 +2,8 @@ define([ '/js/csslint/parserlib', -], parserlib => ({ + '/js/sections-util', +], (parserlib, util) => ({ /** * Extracts @-moz-document blocks into sections and the code between them into global sections. @@ -16,12 +17,6 @@ define([ * @property {?number} lastStyleId */ extractSections: function fn({code, styleId, fast = true}) { - const CssToProperty = { - 'url': 'urls', - 'url-prefix': 'urlPrefixes', - 'domain': 'domains', - 'regexp': 'regexps', - }; const hasSingleEscapes = /([^\\]|^)\\([^\\]|$)/; const parser = new parserlib.css.Parser({ starHack: true, @@ -57,7 +52,7 @@ define([ lastSection.code = ''; } for (const {name, expr, uri} of e.functions) { - const aType = CssToProperty[name.toLowerCase()]; + const aType = util.MozDocMapper.FROM_CSS[name.toLowerCase()]; const p0 = expr && expr.parts[0]; if (p0 && aType === 'regexps') { const s = p0.text; diff --git a/js/sections-util.js b/js/sections-util.js index e09f8c74..306e8711 100644 --- a/js/sections-util.js +++ b/js/sections-util.js @@ -1,7 +1,65 @@ 'use strict'; define(require => { - const exports = { + const util = { + + MozDocMapper: { + TO_CSS: { + urls: 'url', + urlPrefixes: 'url-prefix', + domains: 'domain', + regexps: 'regexp', + }, + FROM_CSS: { + 'url': 'urls', + 'url-prefix': 'urlPrefixes', + 'domain': 'domains', + 'regexp': 'regexps', + }, + /** + * @param {Object} section + * @param {function(func:string, value:string)} fn + */ + forEachProp(section, fn) { + for (const [propName, func] of Object.entries(util.MozDocMapper.TO_CSS)) { + const props = section[propName]; + if (props) props.forEach(value => fn(func, value)); + } + }, + /** + * @param {Array} funcItems + * @param {?Object} [section] + * @returns {Object} section + */ + toSection(funcItems, section = {}) { + for (const item of funcItems) { + const [func, value] = item || []; + const propName = util.MozDocMapper.FROM_CSS[func]; + if (propName) { + const props = section[propName] || (section[propName] = []); + if (Array.isArray(value)) props.push(...value); + else props.push(value); + } + } + return section; + }, + /** + * @param {StyleObj} style + * @returns {string} + */ + styleToCss(style) { + const res = []; + for (const section of style.sections) { + const funcs = []; + util.MozDocMapper.forEachProp(section, (type, value) => + funcs.push(`${type}("${value.replace(/[\\"]/g, '\\$&')}")`)); + res.push(funcs.length + ? `@-moz-document ${funcs.join(', ')} {\n${section.code}\n}` + : section.code); + } + return res.join('\n\n'); + }, + }, async calcStyleDigest(style) { const src = style.usercssData @@ -90,5 +148,5 @@ define(require => { })); } - return exports; + return util; });