diff --git a/edit/edit.js b/edit/edit.js index 93c2ba4b..ed9dd8d6 100644 --- a/edit/edit.js +++ b/edit/edit.js @@ -1,23 +1,23 @@ -/* eslint no-tabs: 0, no-var: 0, indent-legacy: [2, tab, {VariableDeclarator: 0, SwitchCase: 1}], quotes: 0 */ -/* global CodeMirror */ -"use strict"; +/* eslint brace-style: 0, operator-linebreak: 0 */ +/* global CodeMirror exports parserlib CSSLint */ +'use strict'; -var styleId = null; -var dirty = {}; // only the actually dirty items here -var editors = []; // array of all CodeMirror instances -var saveSizeOnClose; -var useHistoryBack; // use browser history back when "back to manage" is clicked +let styleId = null; +let dirty = {}; // only the actually dirty items here +const editors = []; // array of all CodeMirror instances +let saveSizeOnClose; +let useHistoryBack; // use browser history back when 'back to manage' is clicked // direct & reverse mapping of @-moz-document keywords and internal property names -var propertyToCss = {urls: "url", urlPrefixes: "url-prefix", domains: "domain", regexps: "regexp"}; -var CssToProperty = {"url": "urls", "url-prefix": "urlPrefixes", "domain": "domains", "regexp": "regexps"}; +const propertyToCss = {urls: 'url', urlPrefixes: 'url-prefix', domains: 'domain', regexps: 'regexp'}; +const CssToProperty = {'url': 'urls', 'url-prefix': 'urlPrefixes', 'domain': 'domains', 'regexp': 'regexps'}; // if background page hasn't been loaded yet, increase the chances it has before DOMContentLoaded onBackgroundReady(); // make querySelectorAll enumeration code readable -["forEach", "some", "indexOf", "map"].forEach(function(method) { - NodeList.prototype[method]= Array.prototype[method]; +['forEach', 'some', 'indexOf', 'map'].forEach(function(method) { + NodeList.prototype[method] = Array.prototype[method]; }); // Chrome pre-34 @@ -25,24 +25,28 @@ Element.prototype.matches = Element.prototype.matches || Element.prototype.webki // Chrome pre-41 polyfill Element.prototype.closest = Element.prototype.closest || function(selector) { - for (var e = this; e && !e.matches(selector); e = e.parentElement) {} + let e; + // eslint-disable-next-line no-empty + for (e = this; e && !e.matches(selector); e = e.parentElement) {} return e; }; +// eslint-disable-next-line no-extend-native Array.prototype.rotate = function(amount) { // negative amount == rotate left - var r = this.slice(-amount, this.length); + const r = this.slice(-amount, this.length); Array.prototype.push.apply(r, this.slice(0, this.length - r.length)); return r; }; -Object.defineProperty(Array.prototype, "last", {get: function() { return this[this.length - 1]; }}); +// eslint-disable-next-line no-extend-native +Object.defineProperty(Array.prototype, 'last', {get: function() { return this[this.length - 1]; }}); // preload the theme so that CodeMirror can calculate its metrics in DOMContentLoaded->setupLivePrefs() new MutationObserver((mutations, observer) => { - const themeElement = document.getElementById("cm-theme"); + const themeElement = document.getElementById('cm-theme'); if (themeElement) { - themeElement.href = prefs.get("editor.theme") == "default" ? "" - : "vendor/codemirror/theme/" + prefs.get("editor.theme") + ".css"; + themeElement.href = prefs.get('editor.theme') == 'default' ? '' + : 'vendor/codemirror/theme/' + prefs.get('editor.theme') + '.css'; observer.disconnect(); } }).observe(document, {subtree: true, childList: true}); @@ -50,7 +54,7 @@ new MutationObserver((mutations, observer) => { getCodeMirrorThemes(); // reroute handling to nearest editor when keypress resolves to one of these commands -var hotkeyRerouter = { +const hotkeyRerouter = { commands: { save: true, jumpToLine: true, nextEditor: true, prevEditor: true, find: true, findNext: true, findPrev: true, replace: true, replaceAll: true, @@ -58,13 +62,15 @@ var hotkeyRerouter = { }, setState: function(enable) { setTimeout(function() { - document[(enable ? "add" : "remove") + "EventListener"]("keydown", hotkeyRerouter.eventHandler); + document[(enable ? 'add' : 'remove') + 'EventListener']('keydown', hotkeyRerouter.eventHandler); }, 0); }, eventHandler: function(event) { - var keyName = CodeMirror.keyName(event); - if ("handled" == CodeMirror.lookupKey(keyName, CodeMirror.getOption("keyMap"), handleCommand) - || "handled" == CodeMirror.lookupKey(keyName, CodeMirror.defaults.extraKeys, handleCommand)) { + const keyName = CodeMirror.keyName(event); + if ( + CodeMirror.lookupKey(keyName, CodeMirror.getOption('keyMap'), handleCommand) == 'handled' || + CodeMirror.lookupKey(keyName, CodeMirror.defaults.extraKeys, handleCommand) == 'handled' + ) { event.preventDefault(); event.stopPropagation(); } @@ -78,13 +84,13 @@ var hotkeyRerouter = { }; function onChange(event) { - var node = event.target; - if ("savedValue" in node) { - var currentValue = "checkbox" === node.type ? node.checked : node.value; + const node = event.target; + if ('savedValue' in node) { + const currentValue = node.type === 'checkbox' ? node.checked : node.value; setCleanItem(node, node.savedValue === currentValue); } else { // the manually added section's applies-to is dirty only when the value is non-empty - setCleanItem(node, node.localName != "input" || !node.value.trim()); + setCleanItem(node, node.localName != 'input' || !node.value.trim()); delete node.savedValue; // only valid when actually saved } updateTitle(); @@ -92,7 +98,7 @@ function onChange(event) { // Set .dirty on stylesheet contributors that have changed function setDirtyClass(node, isDirty) { - node.classList.toggle("dirty", isDirty); + node.classList.toggle('dirty', isDirty); } function setCleanItem(node, isClean) { @@ -106,7 +112,7 @@ function setCleanItem(node, isClean) { if (node.CodeMirror) { node.savedValue = node.CodeMirror.changeGeneration(); } else { - node.savedValue = "checkbox" === node.type ? node.checked : node.value; + node.savedValue = node.type === 'checkbox' ? node.checked : node.value; } } else { dirty[node.id] = true; @@ -116,27 +122,27 @@ function setCleanItem(node, isClean) { } function isCleanGlobal() { - var clean = Object.keys(dirty).length == 0; + const clean = Object.keys(dirty).length == 0; setDirtyClass(document.body, !clean); - var saveBtn = document.getElementById("save-button") - if (clean){ - //saveBtn.removeAttribute('disabled'); - }else{ - //saveBtn.setAttribute('disabled', true); - } + // let saveBtn = document.getElementById('save-button') + // if (clean){ + // //saveBtn.removeAttribute('disabled'); + // }else{ + // //saveBtn.setAttribute('disabled', true); + // } return clean; } function setCleanGlobal() { - document.querySelectorAll("#header, #sections > div").forEach(setCleanSection); + document.querySelectorAll('#header, #sections > div').forEach(setCleanSection); dirty = {}; // forget the dirty applies-to ids from a deleted section after the style was saved } function setCleanSection(section) { - section.querySelectorAll(".style-contributor").forEach(function(node) { setCleanItem(node, true) }); + section.querySelectorAll('.style-contributor').forEach(function(node) { setCleanItem(node, true); }); // #header section has no codemirror - var cm = section.CodeMirror; + const cm = section.CodeMirror; if (cm) { section.savedValue = cm.changeGeneration(); indicateCodeChange(cm); @@ -144,10 +150,10 @@ function setCleanSection(section) { } function initCodeMirror() { - var CM = CodeMirror; - var isWindowsOS = navigator.appVersion.indexOf("Windows") > 0; + const CM = CodeMirror; + const isWindowsOS = navigator.appVersion.indexOf('Windows') > 0; - // CodeMirror miserably fails on keyMap="" so let's ensure it's not + // CodeMirror miserably fails on keyMap='' so let's ensure it's not if (!prefs.get('editor.keyMap')) { prefs.reset('editor.keyMap'); } @@ -158,77 +164,77 @@ function initCodeMirror() { lineNumbers: true, lineWrapping: true, foldGutter: true, - gutters: ["CodeMirror-linenumbers", "CodeMirror-foldgutter", "CodeMirror-lint-markers"], + gutters: ['CodeMirror-linenumbers', 'CodeMirror-foldgutter', 'CodeMirror-lint-markers'], matchBrackets: true, highlightSelectionMatches: {showToken: /[#.\-\w]/, annotateScrollbar: true}, hintOptions: {}, - lint: {getAnnotations: CodeMirror.lint.css, delay: prefs.get("editor.lintDelay")}, - lintReportDelay: prefs.get("editor.lintReportDelay"), + lint: {getAnnotations: CodeMirror.lint.css, delay: prefs.get('editor.lintDelay')}, + lintReportDelay: prefs.get('editor.lintReportDelay'), styleActiveLine: true, - theme: "default", - keyMap: prefs.get("editor.keyMap"), + theme: 'default', + keyMap: prefs.get('editor.keyMap'), extraKeys: { // independent of current keyMap - "Alt-Enter": "toggleStyle", - "Alt-PageDown": "nextEditor", - "Alt-PageUp": "prevEditor" + 'Alt-Enter': 'toggleStyle', + 'Alt-PageDown': 'nextEditor', + 'Alt-PageUp': 'prevEditor' } - }, prefs.get("editor.options")); + }, prefs.get('editor.options')); // additional commands CM.commands.jumpToLine = jumpToLine; - CM.commands.nextEditor = function(cm) { nextPrevEditor(cm, 1) }; - CM.commands.prevEditor = function(cm) { nextPrevEditor(cm, -1) }; + CM.commands.nextEditor = function(cm) { nextPrevEditor(cm, 1); }; + CM.commands.prevEditor = function(cm) { nextPrevEditor(cm, -1); }; CM.commands.save = save; CM.commands.blockComment = function(cm) { - cm.blockComment(cm.getCursor("from"), cm.getCursor("to"), {fullLines: false}); + cm.blockComment(cm.getCursor('from'), cm.getCursor('to'), {fullLines: false}); }; CM.commands.toggleStyle = toggleStyle; - // "basic" keymap only has basic keys by design, so we skip it + // 'basic' keymap only has basic keys by design, so we skip it - var extraKeysCommands = {}; + const extraKeysCommands = {}; Object.keys(CM.defaults.extraKeys).forEach(function(key) { extraKeysCommands[CM.defaults.extraKeys[key]] = true; }); if (!extraKeysCommands.jumpToLine) { - CM.keyMap.sublime["Ctrl-G"] = "jumpToLine"; - CM.keyMap.emacsy["Ctrl-G"] = "jumpToLine"; - CM.keyMap.pcDefault["Ctrl-J"] = "jumpToLine"; - CM.keyMap.macDefault["Cmd-J"] = "jumpToLine"; + CM.keyMap.sublime['Ctrl-G'] = 'jumpToLine'; + CM.keyMap.emacsy['Ctrl-G'] = 'jumpToLine'; + CM.keyMap.pcDefault['Ctrl-J'] = 'jumpToLine'; + CM.keyMap.macDefault['Cmd-J'] = 'jumpToLine'; } if (!extraKeysCommands.autocomplete) { - CM.keyMap.pcDefault["Ctrl-Space"] = "autocomplete"; // will be used by "sublime" on PC via fallthrough - CM.keyMap.macDefault["Alt-Space"] = "autocomplete"; // OSX uses Ctrl-Space and Cmd-Space for something else - CM.keyMap.emacsy["Alt-/"] = "autocomplete"; // copied from "emacs" keymap - // "vim" and "emacs" define their own autocomplete hotkeys + CM.keyMap.pcDefault['Ctrl-Space'] = 'autocomplete'; // will be used by 'sublime' on PC via fallthrough + CM.keyMap.macDefault['Alt-Space'] = 'autocomplete'; // OSX uses Ctrl-Space and Cmd-Space for something else + CM.keyMap.emacsy['Alt-/'] = 'autocomplete'; // copied from 'emacs' keymap + // 'vim' and 'emacs' define their own autocomplete hotkeys } if (!extraKeysCommands.blockComment) { - CM.keyMap.sublime["Shift-Ctrl-/"] = "blockComment"; + CM.keyMap.sublime['Shift-Ctrl-/'] = 'blockComment'; } if (isWindowsOS) { - // "pcDefault" keymap on Windows should have F3/Shift-F3 + // 'pcDefault' keymap on Windows should have F3/Shift-F3 if (!extraKeysCommands.findNext) { - CM.keyMap.pcDefault["F3"] = "findNext"; + CM.keyMap.pcDefault['F3'] = 'findNext'; } if (!extraKeysCommands.findPrev) { - CM.keyMap.pcDefault["Shift-F3"] = "findPrev"; + CM.keyMap.pcDefault['Shift-F3'] = 'findPrev'; } // try to remap non-interceptable Ctrl-(Shift-)N/T/W hotkeys - ["N", "T", "W"].forEach(function(char) { - [{from: "Ctrl-", to: ["Alt-", "Ctrl-Alt-"]}, - {from: "Shift-Ctrl-", to: ["Ctrl-Alt-", "Shift-Ctrl-Alt-"]} // Note: modifier order in CM is S-C-A + ['N', 'T', 'W'].forEach(function(char) { + [{from: 'Ctrl-', to: ['Alt-', 'Ctrl-Alt-']}, + {from: 'Shift-Ctrl-', to: ['Ctrl-Alt-', 'Shift-Ctrl-Alt-']} // Note: modifier order in CM is S-C-A ].forEach(function(remap) { - var oldKey = remap.from + char; + const oldKey = remap.from + char; Object.keys(CM.keyMap).forEach(function(keyMapName) { - var keyMap = CM.keyMap[keyMapName]; - var command = keyMap[oldKey]; + const keyMap = CM.keyMap[keyMapName]; + const command = keyMap[oldKey]; if (!command) { return; } remap.to.some(function(newMod) { - var newKey = newMod + char; + const newKey = newMod + char; if (!(newKey in keyMap)) { delete keyMap[oldKey]; keyMap[newKey] = command; @@ -241,10 +247,10 @@ function initCodeMirror() { } // user option values - CM.getOption = function (o) { + CM.getOption = function(o) { return CodeMirror.defaults[o]; }; - CM.setOption = function (o, v) { + CM.setOption = function(o, v) { CodeMirror.defaults[o] = v; editors.forEach(function(editor) { editor.setOption(o, v); @@ -257,66 +263,67 @@ function initCodeMirror() { // initialize global editor controls function optionsHtmlFromArray(options) { - return options.map(function(opt) { return ""; }).join(""); + return options.map(function(opt) { return ''; }).join(''); } - var themeControl = document.getElementById("editor.theme"); + const themeControl = document.getElementById('editor.theme'); const themeList = localStorage.codeMirrorThemes; if (themeList) { themeControl.innerHTML = optionsHtmlFromArray(themeList.split(/\s+/)); } else { // Chrome is starting up and shows our edit.html, but the background page isn't loaded yet - const theme = prefs.get("editor.theme"); - themeControl.innerHTML = optionsHtmlFromArray([theme == "default" ? t("defaultTheme") : theme]); + const theme = prefs.get('editor.theme'); + themeControl.innerHTML = optionsHtmlFromArray([theme == 'default' ? t('defaultTheme') : theme]); getCodeMirrorThemes().then(() => { const themes = (localStorage.codeMirrorThemes || '').split(/\s+/); themeControl.innerHTML = optionsHtmlFromArray(themes); themeControl.selectedIndex = Math.max(0, themes.indexOf(theme)); }); } - document.getElementById("editor.keyMap").innerHTML = optionsHtmlFromArray(Object.keys(CM.keyMap).sort()); - document.getElementById("options").addEventListener("change", acmeEventListener, false); + document.getElementById('editor.keyMap').innerHTML = optionsHtmlFromArray(Object.keys(CM.keyMap).sort()); + document.getElementById('options').addEventListener('change', acmeEventListener, false); setupLivePrefs(); hotkeyRerouter.setState(true); } function acmeEventListener(event) { - var el = event.target; - var option = el.id.replace(/^editor\./, ''); - //console.log("acmeEventListener heard %s on %s", event.type, el.id); + const el = event.target; + const option = el.id.replace(/^editor\./, ''); + //console.log('acmeEventListener heard %s on %s', event.type, el.id); if (!option) { - console.error("acmeEventListener: no 'cm_option' %O", el); + console.error('acmeEventListener: no "cm_option" %O', el); return; } - var value = el.type == "checkbox" ? el.checked : el.value; + let value = el.type == 'checkbox' ? el.checked : el.value; + let url; + const themeLink = document.getElementById('cm-theme'); switch (option) { - case "tabSize": - CodeMirror.setOption("indentUnit", Number(value)); + case 'tabSize': + CodeMirror.setOption('indentUnit', Number(value)); break; - case "theme": - var themeLink = document.getElementById("cm-theme"); - // use non-localized "default" internally - if (!value || value == "default" || value == t("defaultTheme")) { - value = "default"; + case 'theme': + // use non-localized 'default' internally + if (!value || value == 'default' || value == t('defaultTheme')) { + value = 'default'; if (prefs.get(el.id) != value) { prefs.set(el.id, value); } - themeLink.href = ""; + themeLink.href = ''; el.selectedIndex = 0; break; } - var url = chrome.runtime.getURL("vendor/codemirror/theme/" + value + ".css"); + url = chrome.runtime.getURL('vendor/codemirror/theme/' + value + '.css'); if (themeLink.href == url) { // preloaded in initCodeMirror() break; } // avoid flicker: wait for the second stylesheet to load, then apply the theme - document.head.insertAdjacentHTML("beforeend", + document.head.insertAdjacentHTML('beforeend', ''); (function() { setTimeout(function() { CodeMirror.setOption(option, value); themeLink.remove(); - document.getElementById("cm-theme2").id = "cm-theme"; + document.getElementById('cm-theme2').id = 'cm-theme'; }, 100); })(); return; @@ -327,7 +334,7 @@ function acmeEventListener(event) { cm[onOff]('pick', autocompletePicked); }); return; - case "matchHighlight": + case 'matchHighlight': switch (value) { case 'token': case 'selection': @@ -377,9 +384,9 @@ function setupCodeMirror(textarea, index) { return; } lastClickTime = Date.now(); - const minHeight = cm.defaultTextHeight() - + cm.display.lineDiv.offsetParent.offsetTop /* .CodeMirror-lines padding */ - + wrapper.offsetHeight - wrapper.clientHeight /* borders */; + const minHeight = cm.defaultTextHeight() + + cm.display.lineDiv.offsetParent.offsetTop + /* .CodeMirror-lines padding */ + wrapper.offsetHeight - wrapper.clientHeight; /* borders */ wrapper.style.pointerEvents = 'none'; document.body.style.cursor = 's-resize'; function resize(e) { @@ -403,29 +410,29 @@ function setupCodeMirror(textarea, index) { } function indicateCodeChange(cm) { - var section = cm.getSection(); + const section = cm.getSection(); setCleanItem(section, cm.isClean(section.savedValue)); updateTitle(); updateLintReport(cm); } function getSectionForChild(e) { - return e.closest("#sections > div"); + return e.closest('#sections > div'); } function getSections() { - return document.querySelectorAll("#sections > div"); + return document.querySelectorAll('#sections > div'); } // remind Chrome to repaint a previously invisible editor box by toggling any element's transform // this bug is present in some versions of Chrome (v37-40 or something) -document.addEventListener("scroll", function(event) { - var style = document.getElementById("name").style; - style.webkitTransform = style.webkitTransform ? "" : "scale(1)"; +document.addEventListener('scroll', function() { + const style = document.getElementById('name').style; + style.webkitTransform = style.webkitTransform ? '' : 'scale(1)'; }); // Shift-Ctrl-Wheel scrolls entire page even when mouse is over a code editor -document.addEventListener("wheel", function(event) { +document.addEventListener('wheel', function(event) { if (event.shiftKey && event.ctrlKey && !event.altKey && !event.metaKey) { // Chrome scrolls horizontally when Shift is pressed but on some PCs this might be different window.scrollBy(0, event.deltaX || event.deltaY); @@ -434,8 +441,8 @@ document.addEventListener("wheel", function(event) { }); queryTabs({currentWindow: true}).then(tabs => { - var windowId = tabs[0].windowId; - if (prefs.get("openEditInWindow")) { + const windowId = tabs[0].windowId; + if (prefs.get('openEditInWindow')) { if (sessionStorage.saveSizeOnClose && 'left' in prefs.get('windowPosition', {}) && !isWindowMaximized()) { @@ -445,24 +452,24 @@ queryTabs({currentWindow: true}).then(tabs => { if (tabs.length == 1 && window.history.length == 1) { chrome.windows.getAll(function(windows) { if (windows.length > 1) { - sessionStorageHash("saveSizeOnClose").set(windowId, true); + sessionStorageHash('saveSizeOnClose').set(windowId, true); saveSizeOnClose = true; } }); } else { - saveSizeOnClose = sessionStorageHash("saveSizeOnClose").value[windowId]; + saveSizeOnClose = sessionStorageHash('saveSizeOnClose').value[windowId]; } } chrome.tabs.onRemoved.addListener(function(tabId, info) { - sessionStorageHash("manageStylesHistory").unset(tabId); + sessionStorageHash('manageStylesHistory').unset(tabId); if (info.windowId == windowId && info.isWindowClosing) { - sessionStorageHash("saveSizeOnClose").unset(windowId); + sessionStorageHash('saveSizeOnClose').unset(windowId); } }); }); getActiveTab().then(tab => { - useHistoryBack = sessionStorageHash("manageStylesHistory").value[tab.id] == location.href; + useHistoryBack = sessionStorageHash('manageStylesHistory').value[tab.id] == location.href; }); function goBackToManage(event) { @@ -483,8 +490,8 @@ function isWindowMaximized() { } window.onbeforeunload = function() { - if (saveSizeOnClose && !isWindowMaximized()) { - prefs.set("windowPosition", { + if (saveSizeOnClose && !isWindowMaximized()) { + prefs.set('windowPosition', { left: screenLeft, top: screenTop, width: outerWidth, @@ -500,44 +507,47 @@ window.onbeforeunload = function() { }; function addAppliesTo(list, name, value) { - var showingEverything = list.querySelector(".applies-to-everything") != null; - // blow away "Everything" if it's there + const showingEverything = list.querySelector('.applies-to-everything') !== null; + // blow away 'Everything' if it's there if (showingEverything) { list.removeChild(list.firstChild); } - var e; + let e; if (name && value) { e = template.appliesTo.cloneNode(true); - e.querySelector("[name=applies-type]").value = name; - e.querySelector("[name=applies-value]").value = value; - e.querySelector(".remove-applies-to").addEventListener("click", removeAppliesTo, false); + e.querySelector('[name=applies-type]').value = name; + e.querySelector('[name=applies-value]').value = value; + e.querySelector('.remove-applies-to').addEventListener('click', removeAppliesTo, false); } else if (showingEverything || list.hasChildNodes()) { e = template.appliesTo.cloneNode(true); if (list.hasChildNodes()) { - e.querySelector("[name=applies-type]").value = list.querySelector("li:last-child [name='applies-type']").value; + e.querySelector('[name=applies-type]').value = list.querySelector('li:last-child [name="applies-type"]').value; } - e.querySelector(".remove-applies-to").addEventListener("click", removeAppliesTo, false); + e.querySelector('.remove-applies-to').addEventListener('click', removeAppliesTo, false); } else { e = template.appliesToEverything.cloneNode(true); } - e.querySelector(".add-applies-to").addEventListener("click", function() {addAppliesTo(this.parentNode.parentNode)}, false); + e.querySelector('.add-applies-to').addEventListener('click', function() { + addAppliesTo(this.parentNode.parentNode); + }, false); list.appendChild(e); } function addSection(event, section) { - var div = template.section.cloneNode(true); - div.querySelector(".applies-to-help").addEventListener("click", showAppliesToHelp, false); - div.querySelector(".remove-section").addEventListener("click", removeSection, false); - div.querySelector(".add-section").addEventListener("click", addSection, false); - div.querySelector(".beautify-section").addEventListener("click", beautify); + const div = template.section.cloneNode(true); + div.querySelector('.applies-to-help').addEventListener('click', showAppliesToHelp, false); + div.querySelector('.remove-section').addEventListener('click', removeSection, false); + div.querySelector('.add-section').addEventListener('click', addSection, false); + div.querySelector('.beautify-section').addEventListener('click', beautify); - var codeElement = div.querySelector(".code"); - var appliesTo = div.querySelector(".applies-to-list"); - var appliesToAdded = false; + const codeElement = div.querySelector('.code'); + const appliesTo = div.querySelector('.applies-to-list'); + let appliesToAdded = false; if (section) { codeElement.value = section.code; - for (var i in propertyToCss) { + let i; + for (i in propertyToCss) { if (section[i]) { section[i].forEach(function(url) { addAppliesTo(appliesTo, propertyToCss[i], url); @@ -550,8 +560,8 @@ function addSection(event, section) { addAppliesTo(appliesTo); } - appliesTo.addEventListener("change", onChange); - appliesTo.addEventListener("input", onChange); + appliesTo.addEventListener('change', onChange); + appliesTo.addEventListener('input', onChange); toggleTestRegExpVisibility(); appliesTo.addEventListener('change', toggleTestRegExpVisibility); @@ -570,18 +580,19 @@ function addSection(event, section) { }); } - var sections = document.getElementById("sections"); + const sections = document.getElementById('sections'); + let cm; if (event) { - var clickedSection = getSectionForChild(event.target); + const clickedSection = getSectionForChild(event.target); sections.insertBefore(div, clickedSection.nextElementSibling); - var newIndex = getSections().indexOf(clickedSection) + 1; - var cm = setupCodeMirror(codeElement, newIndex); + const newIndex = getSections().indexOf(clickedSection) + 1; + cm = setupCodeMirror(codeElement, newIndex); makeSectionVisible(cm); - cm.focus() + cm.focus(); renderLintReport(); } else { sections.appendChild(div); - var cm = setupCodeMirror(codeElement); + cm = setupCodeMirror(codeElement); } div.CodeMirror = cm; @@ -590,8 +601,8 @@ function addSection(event, section) { } function removeAppliesTo(event) { - var appliesTo = event.target.parentNode, - appliesToList = appliesTo.parentNode; + const appliesTo = event.target.parentNode, + appliesToList = appliesTo.parentNode; removeAreaAndSetDirty(appliesTo); if (!appliesToList.hasChildNodes()) { addAppliesTo(appliesToList); @@ -599,16 +610,16 @@ function removeAppliesTo(event) { } function removeSection(event) { - var section = getSectionForChild(event.target); - var cm = section.CodeMirror; + const section = getSectionForChild(event.target); + const cm = section.CodeMirror; removeAreaAndSetDirty(section); editors.splice(editors.indexOf(cm), 1); renderLintReport(); } function removeAreaAndSetDirty(area) { - var contributors = area.querySelectorAll('.style-contributor'); - if(!contributors.length){ + const contributors = area.querySelectorAll('.style-contributor'); + if (!contributors.length) { setCleanItem(area, false); } contributors.some(function(node) { @@ -627,9 +638,12 @@ function removeAreaAndSetDirty(area) { } function makeSectionVisible(cm) { - var section = cm.getSection(); - var bounds = section.getBoundingClientRect(); - if ((bounds.bottom > window.innerHeight && bounds.top > 0) || (bounds.top < 0 && bounds.bottom < window.innerHeight)) { + const section = cm.getSection(); + const bounds = section.getBoundingClientRect(); + if ( + (bounds.bottom > window.innerHeight && bounds.top > 0) || + (bounds.top < 0 && bounds.bottom < window.innerHeight) + ) { if (bounds.top < 0) { window.scrollBy(0, bounds.top - 1); } else { @@ -639,19 +653,19 @@ function makeSectionVisible(cm) { } function setupGlobalSearch() { - var originalCommand = { + const originalCommand = { find: CodeMirror.commands.find, findNext: CodeMirror.commands.findNext, findPrev: CodeMirror.commands.findPrev, replace: CodeMirror.commands.replace }; - var originalOpenDialog = CodeMirror.prototype.openDialog; - var originalOpenConfirm = CodeMirror.prototype.openConfirm; + const originalOpenDialog = CodeMirror.prototype.openDialog; + const originalOpenConfirm = CodeMirror.prototype.openConfirm; - var curState; // cm.state.search for last used 'find' + let curState; // cm.state.search for last used 'find' function shouldIgnoreCase(query) { // treat all-lowercase non-regexp queries as case-insensitive - return typeof query == "string" && query == query.toLowerCase(); + return typeof query == 'string' && query == query.toLowerCase(); } function updateState(cm, newState) { @@ -668,7 +682,7 @@ function setupGlobalSearch() { query: newState.query, overlay: newState.overlay, annotate: cm.showMatchesOnScrollbar(newState.query, shouldIgnoreCase(newState.query)) - } + }; cm.addOverlay(newState.overlay); return cm.state.search; } @@ -685,12 +699,11 @@ function setupGlobalSearch() { function focusClosestCM(activeCM) { editors.lastActive = activeCM; - var cm = getEditorInSight(); + const cm = getEditorInSight(); if (cm != activeCM) { cm.focus(); } return cm; - } function find(activeCM) { @@ -703,7 +716,7 @@ function setupGlobalSearch() { } editors.forEach(function(cm) { if (cm != activeCM) { - cm.execCommand("clearSearch"); + cm.execCommand('clearSearch'); updateState(cm, curState); } }); @@ -715,27 +728,27 @@ function setupGlobalSearch() { } function findNext(activeCM, reverse) { - var state = updateState(activeCM); + let state = updateState(activeCM); if (!state || !state.query) { find(activeCM); return; } - var pos = activeCM.getCursor(reverse ? "from" : "to"); + let pos = activeCM.getCursor(reverse ? 'from' : 'to'); activeCM.setSelection(activeCM.getCursor()); // clear the selection, don't move the cursor - var rxQuery = typeof state.query == "object" - ? state.query : stringAsRegExp(state.query, shouldIgnoreCase(state.query) ? "i" : ""); + const rxQuery = typeof state.query == 'object' + ? state.query : stringAsRegExp(state.query, shouldIgnoreCase(state.query) ? 'i' : ''); - if (document.activeElement && document.activeElement.name == "applies-value" + if (document.activeElement && document.activeElement.name == 'applies-value' && searchAppliesTo(activeCM)) { return; } - for (var i=0, cm=activeCM; i < editors.length; i++) { + for (let i = 0, cm = activeCM; i < editors.length; i++) { state = updateState(cm); if (!cm.hasFocus()) { pos = reverse ? CodeMirror.Pos(cm.lastLine()) : CodeMirror.Pos(0, 0); } - var searchCursor = cm.getSearchCursor(state.query, pos, shouldIgnoreCase(state.query)); + const searchCursor = cm.getSearchCursor(state.query, pos, shouldIgnoreCase(state.query)); if (searchCursor.find(reverse)) { if (editors.length > 1) { makeSectionVisible(cm); @@ -744,7 +757,7 @@ function setupGlobalSearch() { // speedup the original findNext state.posFrom = reverse ? searchCursor.to() : searchCursor.from(); state.posTo = CodeMirror.Pos(state.posFrom.line, state.posFrom.ch); - originalCommand[reverse ? "findPrev" : "findNext"](cm); + originalCommand[reverse ? 'findPrev' : 'findNext'](cm); return; } else if (!reverse && searchAppliesTo(cm)) { return; @@ -755,24 +768,24 @@ function setupGlobalSearch() { } } // nothing found so far, so call the original search with wrap-around - originalCommand[reverse ? "findPrev" : "findNext"](activeCM); + originalCommand[reverse ? 'findPrev' : 'findNext'](activeCM); function searchAppliesTo(cm) { - var inputs = [].slice.call(cm.getSection().querySelectorAll(".applies-value")); + let inputs = [].slice.call(cm.getSection().querySelectorAll('.applies-value')); if (reverse) { inputs = inputs.reverse(); } inputs.splice(0, inputs.indexOf(document.activeElement) + 1); return inputs.some(function(input) { - var match = rxQuery.exec(input.value); + const match = rxQuery.exec(input.value); if (match) { input.focus(); - var end = match.index + match[0].length; + const end = match.index + match[0].length; // scroll selected part into view in long inputs, // works only outside of current event handlers chain, hence timeout=0 setTimeout(function() { input.setSelectionRange(end, end); - input.setSelectionRange(match.index, end) + input.setSelectionRange(match.index, end); }, 0); return true; } @@ -785,21 +798,25 @@ function setupGlobalSearch() { } function replace(activeCM, all) { - var queue, query, replacement; + let queue, query, replacement; activeCM = focusClosestCM(activeCM); - customizeOpenDialog(activeCM, template[all ? "replaceAll" : "replace"], function(txt) { + customizeOpenDialog(activeCM, template[all ? 'replaceAll' : 'replace'], function(txt) { query = txt; customizeOpenDialog(activeCM, template.replaceWith, function(txt) { replacement = txt; queue = editors.rotate(-editors.indexOf(activeCM)); - all ? editors.forEach(doReplace) : doReplace(); + if (all) { + editors.forEach(doReplace); + } else { + doReplace(); + } }); this(query); }); originalCommand.replace(activeCM, all); function doReplace() { - var cm = queue.shift(); + const cm = queue.shift(); if (!cm) { if (!all) { editors.lastActive.focus(); @@ -815,7 +832,7 @@ function setupGlobalSearch() { } else { doConfirm(cm); callback(replacement); - if (!cm.getWrapperElement().querySelector(".CodeMirror-dialog")) { + if (!cm.getWrapperElement().querySelector('.CodeMirror-dialog')) { // no dialog == nothing found in the current CM, move to the next doReplace(); } @@ -826,28 +843,28 @@ function setupGlobalSearch() { originalCommand.replace(cm, all); } function doConfirm(cm) { - var wrapAround = false; - var origPos = cm.getCursor(); + let wrapAround = false; + const origPos = cm.getCursor(); cm.openConfirm = function overrideConfirm(tmpl, callbacks, opt) { - var ovrCallbacks = callbacks.map(function(callback) { + const ovrCallbacks = callbacks.map(function(callback) { return function() { makeSectionVisible(cm); cm.openConfirm = overrideConfirm; setTimeout(function() { cm.openConfirm = originalOpenConfirm; }, 0); - var pos = cm.getCursor(); + const pos = cm.getCursor(); callback(); - var cmp = CodeMirror.cmpPos(cm.getCursor(), pos); + const cmp = CodeMirror.cmpPos(cm.getCursor(), pos); wrapAround |= cmp <= 0; - var dlg = cm.getWrapperElement().querySelector(".CodeMirror-dialog"); + const dlg = cm.getWrapperElement().querySelector('.CodeMirror-dialog'); if (!dlg || cmp == 0 || wrapAround && CodeMirror.cmpPos(cm.getCursor(), origPos) >= 0) { if (dlg) { dlg.remove(); } doReplace(); } - } + }; }); originalOpenConfirm.call(cm, template.replaceConfirm.innerHTML, ovrCallbacks, opt); }; @@ -866,14 +883,14 @@ function setupGlobalSearch() { } function jumpToLine(cm) { - var cur = cm.getCursor(); + const cur = cm.getCursor(); refocusMinidialog(cm); cm.openDialog(template.jumpToLine.innerHTML, function(str) { - var m = str.match(/^\s*(\d+)(?:\s*:\s*(\d+))?\s*$/); + const m = str.match(/^\s*(\d+)(?:\s*:\s*(\d+))?\s*$/); if (m) { cm.setCursor(m[1] - 1, m[2] ? m[2] - 1 : cur.ch); } - }, {value: cur.line+1}); + }, {value: cur.line + 1}); } function toggleStyle() { @@ -903,9 +920,11 @@ function toggleSectionHeight(cm) { } function autocompleteOnTyping(cm, info, debounced) { - if (cm.state.completionActive - || info.origin && !info.origin.includes('input') - || !info.text.last) { + if ( + cm.state.completionActive || + info.origin && !info.origin.includes('input') || + !info.text.last + ) { return; } if (cm.state.autocompletePicked) { @@ -931,15 +950,15 @@ function autocompletePicked(cm) { } function refocusMinidialog(cm) { - var section = cm.getSection(); - if (!section.querySelector(".CodeMirror-dialog")) { + const section = cm.getSection(); + if (!section.querySelector('.CodeMirror-dialog')) { return; } // close the currently opened minidialog cm.focus(); // make sure to focus the input in newly opened minidialog setTimeout(function() { - section.querySelector(".CodeMirror-dialog").focus(); + section.querySelector('.CodeMirror-dialog').focus(); }, 0); } @@ -951,26 +970,26 @@ function nextPrevEditor(cm, direction) { function getEditorInSight(nearbyElement) { // priority: 1. associated CM for applies-to element 2. last active if visible 3. first visible - var cm; - if (nearbyElement && nearbyElement.className.indexOf("applies-") >= 0) { + let cm; + if (nearbyElement && nearbyElement.className.indexOf('applies-') >= 0) { cm = getSectionForChild(nearbyElement).CodeMirror; } else { cm = editors.lastActive; } if (!cm || offscreenDistance(cm) > 0) { - var sorted = editors - .map(function(cm, index) { return {cm: cm, distance: offscreenDistance(cm), index: index} }) - .sort(function(a, b) { return a.distance - b.distance || a.index - b.index }); + const sorted = editors + .map(function(cm, index) { return {cm: cm, distance: offscreenDistance(cm), index: index}; }) + .sort(function(a, b) { return a.distance - b.distance || a.index - b.index; }); cm = sorted[0].cm; if (sorted[0].distance > 0) { - makeSectionVisible(cm) + makeSectionVisible(cm); } } return cm; function offscreenDistance(cm) { - var LINES_VISIBLE = 2; // closest editor should have at least # lines visible - var bounds = cm.getSection().getBoundingClientRect(); + const LINES_VISIBLE = 2; // closest editor should have at least # lines visible + const bounds = cm.getSection().getBoundingClientRect(); if (bounds.top < 0) { return -bounds.top; } else if (bounds.top < window.innerHeight - cm.defaultTextHeight() * LINES_VISIBLE) { @@ -988,10 +1007,10 @@ function updateLintReport(cm, delay) { return; } if (delay > 0) { - setTimeout(cm => { cm.performLint(); update(cm) }, delay, cm); + setTimeout(cm => { cm.performLint(); update(cm); }, delay, cm); return; } - var state = cm.state.lint; + const state = cm.state.lint; if (!state) { return; } @@ -999,37 +1018,38 @@ function updateLintReport(cm, delay) { // or update it as soon as possible (default: 500ms lint + 100ms) in case an existing issue was just fixed clearTimeout(state.reportTimeout); state.reportTimeout = setTimeout(update, state.options.delay + 100, cm); - state.postponeNewIssues = delay == undefined || delay == null; + state.postponeNewIssues = delay == undefined || delay === null; function update(cm) { - var scope = cm ? [cm] : editors; - var changed = false; - var fixedOldIssues = false; + const scope = cm ? [cm] : editors; + let changed = false; + let fixedOldIssues = false; + let state; scope.forEach(function(cm) { - var state = cm.state.lint || {}; - var oldMarkers = state.markedLast || {}; - var newMarkers = {}; - var html = !state.marked || state.marked.length == 0 ? "" : "" + + state = cm.state.lint || {}; + const oldMarkers = state.markedLast || {}; + const newMarkers = {}; + const html = !state.marked || state.marked.length == 0 ? '' : '' + state.marked.map(function(mark) { - var info = mark.__annotation; - var isActiveLine = info.from.line == cm.getCursor().line; - var pos = isActiveLine ? "cursor" : (info.from.line + "," + info.from.ch); - var message = escapeHtml(info.message.replace(/ at line \d.+$/, "")); + const info = mark.__annotation; + const isActiveLine = info.from.line == cm.getCursor().line; + const pos = isActiveLine ? 'cursor' : (info.from.line + ',' + info.from.ch); + let message = escapeHtml(info.message.replace(/ at line \d.+$/, '')); if (message.length > 100) { - message = message.substr(0, 100) + "..."; + message = message.substr(0, 100) + '...'; } if (isActiveLine || oldMarkers[pos] == message) { delete oldMarkers[pos]; } newMarkers[pos] = message; - return "" + - "" + - info.severity + "" + - "" + (info.from.line+1) + "" + - ":" + - "" + (info.from.ch+1) + "" + - "" + message + ""; - }).join("") + ""; + return '' + + '' + + info.severity + '' + + '' + (info.from.line + 1) + '' + + ':' + + '' + (info.from.ch + 1) + '' + + '' + message + ''; + }).join('') + ''; state.markedLast = newMarkers; fixedOldIssues |= state.reportDisplayed && Object.keys(oldMarkers).length > 0; if (state.html != html) { @@ -1049,27 +1069,27 @@ function updateLintReport(cm, delay) { } } function escapeHtml(html) { - var chars = {"&": "&", "<": "<", ">": ">", '"': '"', "'": ''', "/": '/'}; - return html.replace(/[&<>"'\/]/g, function(char) { return chars[char] }); + const chars = {'&': '&', '<': '<', '>': '>', '"': '"', '\'': ''', '/': '/'}; + return html.replace(/[&<>"'/]/g, function(char) { return chars[char]; }); } } function renderLintReport(someBlockChanged) { - var container = document.getElementById("lint"); - var content = container.children[1]; - var label = t("sectionCode"); - var newContent = content.cloneNode(false); - var issueCount = 0; + const container = document.getElementById('lint'); + const content = container.children[1]; + const label = t('sectionCode'); + const newContent = content.cloneNode(false); + let issueCount = 0; editors.forEach(function(cm, index) { if (cm.state.lint && cm.state.lint.html) { - var newBlock = newContent.appendChild(document.createElement("table")); - var html = "" + label + " " + (index+1) + "" + cm.state.lint.html; + const newBlock = newContent.appendChild(document.createElement('table')); + const html = '' + label + ' ' + (index + 1) + '' + cm.state.lint.html; newBlock.innerHTML = html; newBlock.cm = cm; issueCount += newBlock.rows.length; - var block = content.children[newContent.children.length - 1]; - var blockChanged = !block || cm != block.cm || html != block.innerHTML; + const block = content.children[newContent.children.length - 1]; + const blockChanged = !block || cm != block.cm || html != block.innerHTML; someBlockChanged |= blockChanged; cm.state.lint.reportDisplayed = blockChanged; } @@ -1077,16 +1097,16 @@ function renderLintReport(someBlockChanged) { if (someBlockChanged || newContent.children.length != content.children.length) { document.getElementById('issue-count').textContent = issueCount; container.replaceChild(newContent, content); - container.style.display = newContent.children.length ? "block" : "none"; + container.style.display = newContent.children.length ? 'block' : 'none'; resizeLintReport(null, newContent); } } function resizeLintReport(event, content) { - content = content || document.getElementById("lint").children[1]; + content = content || document.getElementById('lint').children[1]; if (content.children.length) { - var bounds = content.getBoundingClientRect(); - var newMaxHeight = bounds.bottom <= innerHeight ? '' : (innerHeight - bounds.top) + "px"; + const bounds = content.getBoundingClientRect(); + const newMaxHeight = bounds.bottom <= innerHeight ? '' : (innerHeight - bounds.top) + 'px'; if (newMaxHeight != content.style.maxHeight) { content.style.maxHeight = newMaxHeight; } @@ -1094,57 +1114,57 @@ function resizeLintReport(event, content) { } function gotoLintIssue(event) { - var issue = event.target.closest("tr"); + const issue = event.target.closest('tr'); if (!issue) { return; } - var block = issue.closest("table"); + const block = issue.closest('table'); makeSectionVisible(block.cm); block.cm.focus(); block.cm.setSelection({ - line: parseInt(issue.querySelector("td[role='line']").textContent) - 1, - ch: parseInt(issue.querySelector("td[role='col']").textContent) - 1 + line: parseInt(issue.querySelector('td[role="line"]').textContent) - 1, + ch: parseInt(issue.querySelector('td[role="col"]').textContent) - 1 }); } function toggleLintReport() { - document.getElementById("lint").classList.toggle("collapsed"); + document.getElementById('lint').classList.toggle('collapsed'); } function beautify(event) { if (exports.css_beautify) { // thanks to csslint's definition of 'exports' doBeautify(); } else { - var script = document.head.appendChild(document.createElement("script")); - script.src = "vendor-overwrites/beautify/beautify-css-mod.js"; + const script = document.head.appendChild(document.createElement('script')); + script.src = 'vendor-overwrites/beautify/beautify-css-mod.js'; script.onload = doBeautify; } function doBeautify() { - var tabs = prefs.get("editor.indentWithTabs"); - var options = prefs.get("editor.beautify"); - options.indent_size = tabs ? 1 : prefs.get("editor.tabSize"); - options.indent_char = tabs ? "\t" : " "; + const tabs = prefs.get('editor.indentWithTabs'); + const options = prefs.get('editor.beautify'); + options.indent_size = tabs ? 1 : prefs.get('editor.tabSize'); + options.indent_char = tabs ? '\t' : ' '; - var section = getSectionForChild(event.target); - var scope = section ? [section.CodeMirror] : editors; + const section = getSectionForChild(event.target); + const scope = section ? [section.CodeMirror] : editors; - showHelp(t("styleBeautify"), "
" + - optionHtml(".selector1,", "selector_separator_newline") + - optionHtml(".selector2,", "newline_before_open_brace") + - optionHtml("{", "newline_after_open_brace") + - optionHtml("border: none;", "newline_between_properties", true) + - optionHtml("display: block;", "newline_before_close_brace", true) + - optionHtml("}", "newline_between_rules") + + showHelp(t('styleBeautify'), '
' + + optionHtml('.selector1,', 'selector_separator_newline') + + optionHtml('.selector2,', 'newline_before_open_brace') + + optionHtml('{', 'newline_after_open_brace') + + optionHtml('border: none;', 'newline_between_properties', true) + + optionHtml('display: block;', 'newline_before_close_brace', true) + + optionHtml('}', 'newline_between_rules') + `' + - "
" + - "
"); + '
' + + '
'); - var undoButton = document.querySelector("#help-popup button[role='undo']"); - undoButton.textContent = t(scope.length == 1 ? "undo" : "undoGlobal"); - undoButton.addEventListener("click", function() { - var undoable = false; + const undoButton = document.querySelector('#help-popup button[role="undo"]'); + undoButton.textContent = t(scope.length == 1 ? 'undo' : 'undoGlobal'); + undoButton.addEventListener('click', function() { + let undoable = false; scope.forEach(function(cm) { if (cm.beautifyChange && cm.beautifyChange[cm.changeGeneration()]) { delete cm.beautifyChange[cm.changeGeneration()]; @@ -1161,8 +1181,8 @@ function beautify(event) { const pos = options.translate_positions = [].concat.apply([], cm.doc.sel.ranges.map(r => [Object.assign({}, r.anchor), Object.assign({}, r.head)])); - var text = cm.getValue(); - var newText = exports.css_beautify(text, options); + const text = cm.getValue(); + const newText = exports.css_beautify(text, options); if (newText != text) { if (!cm.beautifyChange || !cm.beautifyChange[cm.changeGeneration()]) { // clear the list if last change wasn't a css-beautify @@ -1190,27 +1210,28 @@ function beautify(event) { }; function optionHtml(label, optionName, indent) { - var value = options[optionName]; - return "
" + - "" + label + "" + - "
"; + const value = options[optionName]; + return '
' + + '' + label + '' + + '
'; } } } -document.addEventListener("DOMContentLoaded", init); +document.addEventListener('DOMContentLoaded', init); function init() { initCodeMirror(); - var params = getParams(); + const params = getParams(); if (!params.id) { // match should be 2 - one for the whole thing, one for the parentheses // This is an add - tE("heading", "addStyleTitle"); - var section = {code: ""} - for (var i in CssToProperty) { + tE('heading', 'addStyleTitle'); + const section = {code: ''}; + let i; + for (i in CssToProperty) { if (params[i]) { section[CssToProperty[i]] = [params[i]]; } @@ -1220,13 +1241,13 @@ function init() { addSection(null, section); editors[0].setOption('lint', CodeMirror.defaults.lint); // default to enabled - document.getElementById("enabled").checked = true + document.getElementById('enabled').checked = true; initHooks(); }; return; } // This is an edit - tE("heading", "editStyleHeading", null, false); + tE('heading', 'editStyleHeading', null, false); getStylesSafe({id: params.id}).then(styles => { let style = styles[0]; if (!style) { @@ -1246,9 +1267,9 @@ function init() { } function setStyleMeta(style) { - document.getElementById("name").value = style.name; - document.getElementById("enabled").checked = style.enabled; - document.getElementById("url").href = style.url; + document.getElementById('name').value = style.name; + document.getElementById('enabled').checked = style.enabled; + document.getElementById('url').href = style.url; } function initWithStyle({style, codeIsUpdated}) { @@ -1262,8 +1283,8 @@ function initWithStyle({style, codeIsUpdated}) { // if this was done in response to an update, we need to clear existing sections getSections().forEach(function(div) { div.remove(); }); - var queue = style.sections.length ? style.sections.slice() : [{code: ""}]; - var queueStart = new Date().getTime(); + const queue = style.sections.length ? style.sections.slice() : [{code: ''}]; + const queueStart = new Date().getTime(); // after 100ms the sections will be added asynchronously while (new Date().getTime() - queueStart <= 100 && queue.length) { add(); @@ -1277,37 +1298,37 @@ function initWithStyle({style, codeIsUpdated}) { initHooks(); function add() { - var sectionDiv = addSection(null, queue.shift()); + const sectionDiv = addSection(null, queue.shift()); maximizeCodeHeight(sectionDiv, !queue.length); const cm = sectionDiv.CodeMirror; setTimeout(() => { cm.setOption('lint', CodeMirror.defaults.lint); updateLintReport(cm, 0); - }, prefs.get("editor.lintDelay")); + }, prefs.get('editor.lintDelay')); } } function initHooks() { - document.querySelectorAll("#header .style-contributor").forEach(function(node) { - node.addEventListener("change", onChange); - node.addEventListener("input", onChange); + document.querySelectorAll('#header .style-contributor').forEach(function(node) { + node.addEventListener('change', onChange); + node.addEventListener('input', onChange); }); - document.getElementById("toggle-style-help").addEventListener("click", showToggleStyleHelp); - document.getElementById("to-mozilla").addEventListener("click", showMozillaFormat, false); - document.getElementById("to-mozilla-help").addEventListener("click", showToMozillaHelp, false); - document.getElementById("from-mozilla").addEventListener("click", fromMozillaFormat); - document.getElementById("beautify").addEventListener("click", beautify); - document.getElementById("save-button").addEventListener("click", save, false); - document.getElementById("sections-help").addEventListener("click", showSectionHelp, false); - document.getElementById("keyMap-help").addEventListener("click", showKeyMapHelp, false); - document.getElementById("cancel-button").addEventListener("click", goBackToManage); - document.getElementById("lint-help").addEventListener("click", showLintHelp); - document.getElementById("lint").addEventListener("click", gotoLintIssue); - window.addEventListener("resize", resizeLintReport); + document.getElementById('toggle-style-help').addEventListener('click', showToggleStyleHelp); + document.getElementById('to-mozilla').addEventListener('click', showMozillaFormat, false); + document.getElementById('to-mozilla-help').addEventListener('click', showToMozillaHelp, false); + document.getElementById('from-mozilla').addEventListener('click', fromMozillaFormat); + document.getElementById('beautify').addEventListener('click', beautify); + document.getElementById('save-button').addEventListener('click', save, false); + document.getElementById('sections-help').addEventListener('click', showSectionHelp, false); + document.getElementById('keyMap-help').addEventListener('click', showKeyMapHelp, false); + document.getElementById('cancel-button').addEventListener('click', goBackToManage); + document.getElementById('lint-help').addEventListener('click', showLintHelp); + document.getElementById('lint').addEventListener('click', gotoLintIssue); + window.addEventListener('resize', resizeLintReport); // touch devices don't have onHover events so the element we'll be toggled via clicking (touching) - if ("ontouchstart" in document.body) { - document.querySelector("#lint h2").addEventListener("click", toggleLintReport); + if ('ontouchstart' in document.body) { + document.querySelector('#lint h2').addEventListener('click', toggleLintReport); } document.querySelectorAll( @@ -1333,22 +1354,22 @@ function toggleContextMenuDelete(event) { function maximizeCodeHeight(sectionDiv, isLast) { - var cm = sectionDiv.CodeMirror; - var stats = maximizeCodeHeight.stats = maximizeCodeHeight.stats || {totalHeight: 0, deltas: []}; + const cm = sectionDiv.CodeMirror; + const stats = maximizeCodeHeight.stats = maximizeCodeHeight.stats || {totalHeight: 0, deltas: []}; if (!stats.cmActualHeight) { stats.cmActualHeight = getComputedHeight(cm.display.wrapper); } if (!stats.sectionMarginTop) { stats.sectionMarginTop = parseFloat(getComputedStyle(sectionDiv).marginTop); } - var sectionTop = sectionDiv.getBoundingClientRect().top - stats.sectionMarginTop; + const sectionTop = sectionDiv.getBoundingClientRect().top - stats.sectionMarginTop; if (!stats.firstSectionTop) { stats.firstSectionTop = sectionTop; } - var extrasHeight = getComputedHeight(sectionDiv) - stats.cmActualHeight; - var cmMaxHeight = window.innerHeight - extrasHeight - sectionTop - stats.sectionMarginTop; - var cmDesiredHeight = cm.display.sizer.clientHeight + 2*cm.defaultTextHeight(); - var cmGrantableHeight = Math.max(stats.cmActualHeight, Math.min(cmMaxHeight, cmDesiredHeight)); + const extrasHeight = getComputedHeight(sectionDiv) - stats.cmActualHeight; + const cmMaxHeight = window.innerHeight - extrasHeight - sectionTop - stats.sectionMarginTop; + const cmDesiredHeight = cm.display.sizer.clientHeight + 2 * cm.defaultTextHeight(); + const cmGrantableHeight = Math.max(stats.cmActualHeight, Math.min(cmMaxHeight, cmDesiredHeight)); stats.deltas.push(cmGrantableHeight - stats.cmActualHeight); stats.totalHeight += cmGrantableHeight + extrasHeight; if (!isLast) { @@ -1362,45 +1383,45 @@ function maximizeCodeHeight(sectionDiv, isLast) { return; } // scale heights to fill the gap between last section and bottom edge of the window - var sections = document.getElementById("sections"); - var available = window.innerHeight - sections.getBoundingClientRect().bottom - + const sections = document.getElementById('sections'); + const available = window.innerHeight - sections.getBoundingClientRect().bottom - parseFloat(getComputedStyle(sections).marginBottom); if (available <= 0) { return; } - var totalDelta = stats.deltas.reduce(function(sum, d) { return sum + d; }, 0); - var q = available / totalDelta; - var baseHeight = stats.cmActualHeight - stats.sectionMarginTop; + const totalDelta = stats.deltas.reduce(function(sum, d) { return sum + d; }, 0); + const q = available / totalDelta; + const baseHeight = stats.cmActualHeight - stats.sectionMarginTop; stats.deltas.forEach(function(delta, index) { editors[index].setSize(null, baseHeight + Math.floor(q * delta)); }); } function updateTitle() { - var DIRTY_TITLE = "* $"; + const DIRTY_TITLE = '* $'; - var name = document.getElementById("name").savedValue; - var clean = isCleanGlobal(); - var title = styleId === null ? t("addStyleTitle") : t('editStyleTitle', [name]); - document.title = clean ? title : DIRTY_TITLE.replace("$", title); + const name = document.getElementById('name').savedValue; + const clean = isCleanGlobal(); + const title = styleId === null ? t('addStyleTitle') : t('editStyleTitle', [name]); + document.title = clean ? title : DIRTY_TITLE.replace('$', title); } function validate() { - var name = document.getElementById("name").value; - if (name == "") { - return t("styleMissingName"); + const name = document.getElementById('name').value; + if (name == '') { + return t('styleMissingName'); } // validate the regexps - if (document.querySelectorAll(".applies-to-list").some(function(list) { + if (document.querySelectorAll('.applies-to-list').some(function(list) { return list.childNodes.some(function(li) { if (li.className == template.appliesToEverything.className) { return false; } - var valueElement = li.querySelector("[name=applies-value]"); - var type = li.querySelector("[name=applies-type]").value; - var value = valueElement.value; + const valueElement = li.querySelector('[name=applies-value]'); + const type = li.querySelector('[name=applies-type]').value; + const value = valueElement.value; if (type && value) { - if (type == "regexp") { + if (type == 'regexp') { try { new RegExp(value); } catch (ex) { @@ -1412,7 +1433,7 @@ function validate() { return false; }); })) { - return t("styleBadRegexp"); + return t('styleBadRegexp'); } return null; } @@ -1421,17 +1442,17 @@ function save() { updateLintReport(null, 0); // save the contents of the CodeMirror editors back into the textareas - for (var i=0; i < editors.length; i++) { + for (let i = 0; i < editors.length; i++) { editors[i].save(); } - var error = validate(); + const error = validate(); if (error) { alert(error); return; } - var name = document.getElementById("name").value; - var enabled = document.getElementById("enabled").checked; + const name = document.getElementById('name').value; + const enabled = document.getElementById('enabled').checked; saveStyleSafe({ id: styleId, name: name, @@ -1443,10 +1464,10 @@ function save() { } function getSectionsHashes() { - var sections = []; + const sections = []; getSections().forEach(function(div) { - var meta = getMeta(div); - var code = div.CodeMirror.getValue(); + const meta = getMeta(div); + const code = div.CodeMirror.getValue(); if (/^\s*$/.test(code) && Object.keys(meta).length == 0) { return; } @@ -1457,15 +1478,15 @@ function getSectionsHashes() { } function getMeta(e) { - var meta = {urls: [], urlPrefixes: [], domains: [], regexps: []}; - e.querySelector(".applies-to-list").childNodes.forEach(function(li) { + const meta = {urls: [], urlPrefixes: [], domains: [], regexps: []}; + e.querySelector('.applies-to-list').childNodes.forEach(function(li) { if (li.className == template.appliesToEverything.className) { return; } - var type = li.querySelector("[name=applies-type]").value; - var value = li.querySelector("[name=applies-value]").value; + const type = li.querySelector('[name=applies-type]').value; + const value = li.querySelector('[name=applies-value]').value; if (type && value) { - var property = CssToProperty[type]; + const property = CssToProperty[type]; meta[property].push(value); } }); @@ -1477,96 +1498,100 @@ function saveComplete(style) { setCleanGlobal(); // Go from new style URL to edit style URL - if (location.href.indexOf("id=") == -1) { - history.replaceState({}, document.title, "edit.html?id=" + style.id); - tE("heading", "editStyleHeading", null, false); + if (location.href.indexOf('id=') == -1) { + history.replaceState({}, document.title, 'edit.html?id=' + style.id); + tE('heading', 'editStyleHeading', null, false); } updateTitle(); } function showMozillaFormat() { - var popup = showCodeMirrorPopup(t("styleToMozillaFormatTitle"), "", {readOnly: true}); + const popup = showCodeMirrorPopup(t('styleToMozillaFormatTitle'), '', {readOnly: true}); popup.codebox.setValue(toMozillaFormat()); - popup.codebox.execCommand("selectAll"); + popup.codebox.execCommand('selectAll'); } function toMozillaFormat() { return getSectionsHashes().map(function(section) { - var cssMds = []; - for (var i in propertyToCss) { + let cssMds = []; + let i; + for (i in propertyToCss) { if (section[i]) { - cssMds = cssMds.concat(section[i].map(function (v){ - return propertyToCss[i] + "(\"" + v.replace(/\\/g, "\\\\") + "\")"; + cssMds = cssMds.concat(section[i].map(function(v) { + return propertyToCss[i] + '("' + v.replace(/\\/g, '\\\\') + '")'; })); } } - return cssMds.length ? "@-moz-document " + cssMds.join(", ") + " {\n" + section.code + "\n}" : section.code; - }).join("\n\n"); + return cssMds.length ? '@-moz-document ' + cssMds.join(', ') + ' {\n' + section.code + '\n}' : section.code; + }).join('\n\n'); } function fromMozillaFormat() { - var popup = showCodeMirrorPopup(t("styleFromMozillaFormatPrompt"), tHTML("
\ - \ - \ -
").innerHTML); + const popup = showCodeMirrorPopup(t('styleFromMozillaFormatPrompt'), tHTML(`
+ + +
` + ).innerHTML); - var contents = popup.querySelector(".contents"); + const contents = popup.querySelector('.contents'); contents.insertBefore(popup.codebox.display.wrapper, contents.firstElementChild); popup.codebox.focus(); - popup.querySelector("[name='import-append']").addEventListener("click", doImport); - popup.querySelector("[name='import-replace']").addEventListener("click", doImport); + popup.querySelector('[name="import-append"]').addEventListener('click', doImport); + popup.querySelector('[name="import-replace"]').addEventListener('click', doImport); - popup.codebox.on("change", function() { + popup.codebox.on('change', function() { clearTimeout(popup.mozillaTimeout); popup.mozillaTimeout = setTimeout(function() { - popup.classList.toggle("ready", trimNewLines(popup.codebox.getValue())); + popup.classList.toggle('ready', trimNewLines(popup.codebox.getValue())); }, 100); }); function doImport() { - var replaceOldStyle = this.name == "import-replace"; - popup.querySelector(".dismiss").onclick(); - var mozStyle = trimNewLines(popup.codebox.getValue()); - var parser = new parserlib.css.Parser(), lines = mozStyle.split("\n"); - var sectionStack = [{code: "", start: {line: 1, col: 1}}]; - var errors = "", oldSectionCount = editors.length; - var firstAddedCM; + const replaceOldStyle = this.name == 'import-replace'; + popup.querySelector('.dismiss').onclick(); + const mozStyle = trimNewLines(popup.codebox.getValue()); + const parser = new parserlib.css.Parser(); + const lines = mozStyle.split('\n'); + const sectionStack = [{code: '', start: {line: 1, col: 1}}]; + let errors = ''; + // let oldSectionCount = editors.length; + let firstAddedCM; - parser.addListener("startdocument", function(e) { - var outerText = getRange(sectionStack.last.start, (--e.col, e)); - var gapComment = outerText.match(/(\/\*[\s\S]*?\*\/)[\s\n]*$/); - var section = {code: "", start: backtrackTo(this, parserlib.css.Tokens.LBRACE, "end")}; + parser.addListener('startdocument', function(e) { + let outerText = getRange(sectionStack.last.start, (--e.col, e)); + const gapComment = outerText.match(/(\/\*[\s\S]*?\*\/)[\s\n]*$/); + const section = {code: '', start: backtrackTo(this, parserlib.css.Tokens.LBRACE, 'end')}; // move last comment before @-moz-document inside the section if (gapComment && !gapComment[1].match(/\/\*\s*AGENT_SHEET\s*\*\//)) { - section.code = gapComment[1] + "\n"; + section.code = gapComment[1] + '\n'; outerText = trimNewLines(outerText.substring(0, gapComment.index)); } if (outerText.trim()) { sectionStack.last.code = outerText; doAddSection(sectionStack.last); - sectionStack.last.code = ""; + sectionStack.last.code = ''; } e.functions.forEach(function(f) { - var m = f.match(/^(url|url-prefix|domain|regexp)\((['"]?)(.+?)\2?\)$/); - var aType = CssToProperty[m[1]]; - var aValue = aType != "regexps" ? m[3] : m[3].replace(/\\\\/g, "\\"); + const m = f.match(/^(url|url-prefix|domain|regexp)\((['"]?)(.+?)\2?\)$/); + const aType = CssToProperty[m[1]]; + const aValue = aType != 'regexps' ? m[3] : m[3].replace(/\\\\/g, '\\'); (section[aType] = section[aType] || []).push(aValue); }); sectionStack.push(section); }); - parser.addListener("enddocument", function(e) { - var end = backtrackTo(this, parserlib.css.Tokens.RBRACE, "start"); - var section = sectionStack.pop(); + parser.addListener('enddocument', function() { + const end = backtrackTo(this, parserlib.css.Tokens.RBRACE, 'start'); + const section = sectionStack.pop(); section.code += getRange(section.start, end); sectionStack.last.start = (++end.col, end); doAddSection(section); }); - parser.addListener("endstylesheet", function() { + parser.addListener('endstylesheet', function() { // add nonclosed outer sections (either broken or the last global one) - var endOfText = {line: lines.length, col: lines.last.length + 1}; + const endOfText = {line: lines.length, col: lines.last.length + 1}; sectionStack.last.code += getRange(sectionStack.last.start, endOfText); sectionStack.forEach(doAddSection); @@ -1579,19 +1604,21 @@ function fromMozillaFormat() { firstAddedCM.focus(); if (errors) { - showHelp(t("issues"), errors); + showHelp(t('issues'), errors); } }); - parser.addListener("error", function(e) { - errors += e.line + ":" + e.col + " " + e.message.replace(/ at line \d.+$/, "") + "
"; + parser.addListener('error', function(e) { + errors += e.line + ':' + e.col + ' ' + e.message.replace(/ at line \d.+$/, '') + '
'; }); parser.parse(mozStyle); - function getRange( start, end) { - const L1 = start.line - 1, C1 = start.col - 1; - const L2 = end.line - 1, C2 = end.col - 1; + function getRange(start, end) { + const L1 = start.line - 1; + const C1 = start.col - 1; + const L2 = end.line - 1; + const C2 = end.col - 1; if (L1 == L2) { return lines[L1].substr(C1, C2 - C1 + 1); } else { @@ -1603,11 +1630,13 @@ function fromMozillaFormat() { function doAddSection(section) { section.code = section.code.trim(); // don't add empty sections - if (!section.code - && !section.urls - && !section.urlPrefixes - && !section.domains - && !section.regexps) { + if ( + !section.code && + !section.urls && + !section.urlPrefixes && + !section.domains && + !section.regexps + ) { return; } if (!firstAddedCM) { @@ -1621,8 +1650,8 @@ function fromMozillaFormat() { // do onetime housekeeping as the imported text is confirmed to be a valid style function initFirstSection(section) { // skip adding the first global section when there's no code/comments - if (!section.code.replace("@namespace url(http://www.w3.org/1999/xhtml);", "") /* ignore boilerplate NS */ - .replace(/[\s\n]/g, "")) { /* ignore all whitespace including new lines */ + if (!section.code.replace('@namespace url(http://www.w3.org/1999/xhtml);', '') /* ignore boilerplate NS */ + .replace(/[\s\n]/g, '')) { /* ignore all whitespace including new lines */ return false; } if (replaceOldStyle) { @@ -1631,7 +1660,7 @@ function fromMozillaFormat() { }); } else if (!editors.last.getValue()) { // nuke the last blank section - if (editors.last.getSection().querySelector(".applies-to-everything")) { + if (editors.last.getSection().querySelector('.applies-to-everything')) { removeSection({target: editors.last.getSection()}); } } @@ -1639,81 +1668,81 @@ function fromMozillaFormat() { } } function backtrackTo(parser, tokenType, startEnd) { - var tokens = parser._tokenStream._lt; - for (var i = parser._tokenStream._ltIndex - 1; i >= 0; --i) { + const tokens = parser._tokenStream._lt; + for (let i = parser._tokenStream._ltIndex - 1; i >= 0; --i) { if (tokens[i].type == tokenType) { - return {line: tokens[i][startEnd+"Line"], col: tokens[i][startEnd+"Col"]}; + return {line: tokens[i][startEnd + 'Line'], col: tokens[i][startEnd + 'Col']}; } } } function trimNewLines(s) { - return s.replace(/^[\s\n]+/, "").replace(/[\s\n]+$/, ""); + return s.replace(/^[\s\n]+/, '').replace(/[\s\n]+$/, ''); } } function showSectionHelp() { - showHelp(t("styleSectionsTitle"), t("sectionHelp")); + showHelp(t('styleSectionsTitle'), t('sectionHelp')); } function showAppliesToHelp() { - showHelp(t("appliesLabel"), t("appliesHelp")); + showHelp(t('appliesLabel'), t('appliesHelp')); } function showToMozillaHelp() { - showHelp(t("styleMozillaFormatHeading"), t("styleToMozillaFormatHelp")); + showHelp(t('styleMozillaFormatHeading'), t('styleToMozillaFormatHelp')); } function showToggleStyleHelp() { - showHelp(t("helpAlt"), t("styleEnabledToggleHint")); + showHelp(t('helpAlt'), t('styleEnabledToggleHint')); } function showKeyMapHelp() { - var keyMap = mergeKeyMaps({}, prefs.get("editor.keyMap"), CodeMirror.defaults.extraKeys); - var keyMapSorted = Object.keys(keyMap) - .map(function(key) { return {key: key, cmd: keyMap[key]} }) - .concat([{key: "Shift-Ctrl-Wheel", cmd: "scrollWindow"}]) - .sort(function(a, b) { return a.cmd < b.cmd || (a.cmd == b.cmd && a.key < b.key) ? -1 : 1 }); - showHelp(t("cm_keyMap") + ": " + prefs.get("editor.keyMap"), + const keyMap = mergeKeyMaps({}, prefs.get('editor.keyMap'), CodeMirror.defaults.extraKeys); + const keyMapSorted = Object.keys(keyMap) + .map(function(key) { return {key: key, cmd: keyMap[key]}; }) + .concat([{key: 'Shift-Ctrl-Wheel', cmd: 'scrollWindow'}]) + .sort(function(a, b) { return a.cmd < b.cmd || (a.cmd == b.cmd && a.key < b.key) ? -1 : 1; }); + showHelp(t('cm_keyMap') + ': ' + prefs.get('editor.keyMap'), '' + - '' + - '' + - "" + keyMapSorted.map(function(value) { - return ""; - }).join("") + - "" + - "
" + value.key + "" + value.cmd + "
"); + '' + + '' + + '' + keyMapSorted.map(function(value) { + return '' + value.key + '' + value.cmd + ''; + }).join('') + + '' + + ''); - var table = document.querySelector("#help-popup table"); - table.addEventListener("input", filterTable); + const table = document.querySelector('#help-popup table'); + table.addEventListener('input', filterTable); - var inputs = table.querySelectorAll("input"); - inputs[0].addEventListener("keydown", hotkeyHandler); + const inputs = table.querySelectorAll('input'); + inputs[0].addEventListener('keydown', hotkeyHandler); inputs[1].focus(); function hotkeyHandler(event) { - var keyName = CodeMirror.keyName(event); - if (keyName == "Esc" || keyName == "Tab" || keyName == "Shift-Tab") { + const keyName = CodeMirror.keyName(event); + if (keyName == 'Esc' || keyName == 'Tab' || keyName == 'Shift-Tab') { return; } event.preventDefault(); event.stopPropagation(); // normalize order of modifiers, - // for modifier-only keys ("Ctrl-Shift") a dummy main key has to be temporarily added - var keyMap = {}; - keyMap[keyName.replace(/(Shift|Ctrl|Alt|Cmd)$/, "$&-dummy")] = ""; - var normalizedKey = Object.keys(CodeMirror.normalizeKeyMap(keyMap))[0]; - this.value = normalizedKey.replace("-dummy", ""); + // for modifier-only keys ('Ctrl-Shift') a dummy main key has to be temporarily added + const keyMap = {}; + keyMap[keyName.replace(/(Shift|Ctrl|Alt|Cmd)$/, '$&-dummy')] = ''; + const normalizedKey = Object.keys(CodeMirror.normalizeKeyMap(keyMap))[0]; + this.value = normalizedKey.replace('-dummy', ''); filterTable(event); } function filterTable(event) { - var input = event.target; - var query = stringAsRegExp(input.value, "gi"); - var col = input.parentNode.cellIndex; - inputs[1 - col].value = ""; + const input = event.target; + const query = stringAsRegExp(input.value, 'gi'); + const col = input.parentNode.cellIndex; + inputs[1 - col].value = ''; table.tBodies[0].childNodes.forEach(function(row) { - var cell = row.children[col]; - cell.innerHTML = cell.textContent.replace(query, "$&"); - row.style.display = query.test(cell.textContent) ? "" : "none"; + let cell = row.children[col]; + cell.innerHTML = cell.textContent.replace(query, '$&'); + row.style.display = query.test(cell.textContent) ? '' : 'none'; // clear highlight from the other column cell = row.children[1 - col]; cell.innerHTML = cell.textContent; @@ -1721,18 +1750,18 @@ function showKeyMapHelp() { } function mergeKeyMaps(merged, ...more) { more.forEach(keyMap => { - if (typeof keyMap == "string") { + if (typeof keyMap == 'string') { keyMap = CodeMirror.keyMap[keyMap]; } Object.keys(keyMap).forEach(function(key) { - var cmd = keyMap[key]; + let cmd = keyMap[key]; // filter out '...', 'attach', etc. (hotkeys start with an uppercase letter) - if (!merged[key] && !key.match(/^[a-z]/) && cmd != "...") { - if (typeof cmd == "function") { + if (!merged[key] && !key.match(/^[a-z]/) && cmd != '...') { + if (typeof cmd == 'function') { // for 'emacs' keymap: provide at least something meaningful (hotkeys and the function body) // for 'vim*' keymaps: almost nothing as it doesn't rely on CM keymap mechanism - cmd = cmd.toString().replace(/^function.*?\{[\s\r\n]*([\s\S]+?)[\s\r\n]*\}$/, "$1"); - merged[key] = cmd.length <= 200 ? cmd : cmd.substr(0, 200) + "..."; + cmd = cmd.toString().replace(/^function.*?\{[\s\r\n]*([\s\S]+?)[\s\r\n]*\}$/, '$1'); + merged[key] = cmd.length <= 200 ? cmd : cmd.substr(0, 200) + '...'; } else { merged[key] = cmd; } @@ -1747,10 +1776,10 @@ function showKeyMapHelp() { } function showLintHelp() { - showHelp(t("issues"), t("issuesHelp") + "' ); } @@ -1860,60 +1889,62 @@ function showRegExpTester(event, section = getSectionForChild(this)) { } function showHelp(title, text) { - var div = document.getElementById("help-popup"); - div.classList.remove("big"); - div.querySelector(".contents").innerHTML = text; - div.querySelector(".title").innerHTML = title; + const div = document.getElementById('help-popup'); + div.classList.remove('big'); + div.querySelector('.contents').innerHTML = text; + div.querySelector('.title').innerHTML = title; - if (getComputedStyle(div).display == "none") { - document.addEventListener("keydown", closeHelp); - div.querySelector(".dismiss").onclick = closeHelp; // avoid chaining on multiple showHelp() calls + if (getComputedStyle(div).display == 'none') { + document.addEventListener('keydown', closeHelp); + div.querySelector('.dismiss').onclick = closeHelp; // avoid chaining on multiple showHelp() calls } - div.style.display = "block"; + div.style.display = 'block'; return div; function closeHelp(e) { - if (!e - || e.type == "click" - || ((e.keyCode || e.which) == 27 && !e.altKey && !e.ctrlKey && !e.shiftKey && !e.metaKey)) { - div.style.display = ""; - document.querySelector(".contents").innerHTML = ""; - document.removeEventListener("keydown", closeHelp); + if ( + !e || + e.type == 'click' || + ((e.keyCode || e.which) == 27 && !e.altKey && !e.ctrlKey && !e.shiftKey && !e.metaKey) + ) { + div.style.display = ''; + document.querySelector('.contents').innerHTML = ''; + document.removeEventListener('keydown', closeHelp); } } } function showCodeMirrorPopup(title, html, options) { - var popup = showHelp(title, html); - popup.classList.add("big"); + const popup = showHelp(title, html); + popup.classList.add('big'); - popup.codebox = CodeMirror(popup.querySelector(".contents"), Object.assign({ - mode: "css", + popup.codebox = CodeMirror(popup.querySelector('.contents'), Object.assign({ + mode: 'css', lineNumbers: true, lineWrapping: true, foldGutter: true, - gutters: ["CodeMirror-linenumbers", "CodeMirror-foldgutter", "CodeMirror-lint-markers"], + gutters: ['CodeMirror-linenumbers', 'CodeMirror-foldgutter', 'CodeMirror-lint-markers'], matchBrackets: true, lint: {getAnnotations: CodeMirror.lint.css, delay: 0}, styleActiveLine: true, - theme: prefs.get("editor.theme"), - keyMap: prefs.get("editor.keyMap") + theme: prefs.get('editor.theme'), + keyMap: prefs.get('editor.keyMap') }, options)); popup.codebox.focus(); - popup.codebox.on("focus", function() { hotkeyRerouter.setState(false) }); - popup.codebox.on("blur", function() { hotkeyRerouter.setState(true) }); + popup.codebox.on('focus', function() { hotkeyRerouter.setState(false); }); + popup.codebox.on('blur', function() { hotkeyRerouter.setState(true); }); return popup; } function getParams() { - var params = {}; - var urlParts = location.href.split("?", 2); + const params = {}; + const urlParts = location.href.split('?', 2); if (urlParts.length == 1) { return params; } - urlParts[1].split("&").forEach(function(keyValue) { - var splitKeyValue = keyValue.split("=", 2); + urlParts[1].split('&').forEach(function(keyValue) { + const splitKeyValue = keyValue.split('=', 2); params[decodeURIComponent(splitKeyValue[0])] = decodeURIComponent(splitKeyValue[1]); }); return params; @@ -1923,7 +1954,7 @@ chrome.runtime.onMessage.addListener(onRuntimeMessage); function onRuntimeMessage(request) { switch (request.method) { - case "styleUpdated": + case 'styleUpdated': if (styleId && styleId == request.style.id && request.reason != 'editSave') { if ((request.style.sections[0] || {}).code === null) { // the code-less style came from notifyAllTabs @@ -1936,14 +1967,14 @@ function onRuntimeMessage(request) { } } break; - case "styleDeleted": + case 'styleDeleted': if (styleId && styleId == request.id) { window.onbeforeunload = function() {}; window.close(); break; } break; - case "prefChanged": + case 'prefChanged': if ('editor.smartIndent' in request.prefs) { CodeMirror.setOption('smartIndent', request.prefs['editor.smartIndent']); } @@ -1955,7 +1986,7 @@ function onRuntimeMessage(request) { } function getComputedHeight(el) { - var compStyle = getComputedStyle(el); + const compStyle = getComputedStyle(el); return el.getBoundingClientRect().height + parseFloat(compStyle.marginTop) + parseFloat(compStyle.marginBottom); } diff --git a/js/dom.js b/js/dom.js index 2dca2090..88fd44b6 100644 --- a/js/dom.js +++ b/js/dom.js @@ -12,6 +12,7 @@ for (const type of [NodeList, NamedNodeMap, HTMLCollection, HTMLAllCollection]) } // add favicon in Firefox +// eslint-disable-next-line no-unused-expressions navigator.userAgent.includes('Firefox') && setTimeout(() => { const iconset = ['', 'light/'][prefs.get('iconset')] || ''; for (const size of [38, 32, 19, 16]) { diff --git a/manage/manage.js b/manage/manage.js index da268c6b..434e7b49 100644 --- a/manage/manage.js +++ b/manage/manage.js @@ -128,8 +128,11 @@ function showStyles(styles = []) { function renderStyles() { const t0 = performance.now(); let rendered = 0; - while (index < sorted.length - && (shouldRenderAll || ++rendered < 10 || performance.now() - t0 < 10)) { + while ( + index < sorted.length && + // eslint-disable-next-line no-unmodified-loop-condition + (shouldRenderAll || ++rendered < 10 || performance.now() - t0 < 10) + ) { renderBin.appendChild(createStyleElement(sorted[index++])); } filterAndAppend({container: renderBin}); @@ -976,9 +979,14 @@ function objectDiff(first, second, path = '') { continue; } if (a && typeof a.filter == 'function' && b && typeof b.filter == 'function') { - if (a.length != b.length - || a.some((el, i) => !el || typeof el != 'object' ? el != b[i] - : objectDiff(el, b[i], path + key + '[' + i + '].').length) + if ( + a.length != b.length || + a.some((el, i) => { + const result = !el || typeof el != 'object' + ? el != b[i] + : objectDiff(el, b[i], path + key + '[' + i + '].').length; + return result; + }) ) { diff.push({path, key, values: [a, b], type: 'changed'}); }