diff --git a/_locales/en/messages.json b/_locales/en/messages.json
index df58ec97..95c6ce81 100644
--- a/_locales/en/messages.json
+++ b/_locales/en/messages.json
@@ -415,8 +415,13 @@
}
},
"installUpdateFromLabel": {
- "message": "Install update from this URL",
- "description": "Label for the checkbox to save current URL for update check"
+ "message": "Install update from $url$",
+ "description": "Label for the checkbox to save current URL for update check",
+ "placeholders": {
+ "url": {
+ "content": "$1"
+ }
+ }
},
"license": {
"message": "License",
diff --git a/edit.html b/edit.html
index 5882e907..09c3a602 100644
--- a/edit.html
+++ b/edit.html
@@ -59,6 +59,9 @@
+
+
+
diff --git a/edit/edit.css b/edit/edit.css
index 19e57589..e1aff510 100644
--- a/edit/edit.css
+++ b/edit/edit.css
@@ -167,20 +167,10 @@ h2 .svg-icon, label .svg-icon {
margin-left: 0.25rem;
}
/* code */
-.CodeMirror-hint:hover {
- color: white;
- background: #08f;
-}
.code {
height: 10rem;
width: 40rem;
}
-.CodeMirror {
- border: solid #CCC 1px;
-}
-.CodeMirror-lint-mark-warning {
- background: none;
-}
.resize-grip-enabled .CodeMirror-scroll {
height: auto !important;;
position: absolute !important;
@@ -198,22 +188,6 @@ h2 .svg-icon, label .svg-icon {
.resize-grip-enabled .CodeMirror-scrollbar-filler {
bottom: 7px; /* make space for resize-grip */
}
-.CodeMirror-dialog {
- -webkit-animation: highlight 3s ease-out;
-}
-.CodeMirror-focused {
- outline: -webkit-focus-ring-color auto 5px;
- outline-offset: -2px;
-}
-.CodeMirror-search-field {
- width: 10em;
-}
-.CodeMirror-jump-field {
- width: 5em;
-}
-.CodeMirror-search-hint {
- color: #888;
-}
body[data-match-highlight="token"] .cm-matchhighlight-approved .cm-matchhighlight,
body[data-match-highlight="token"] .CodeMirror-selection-highlight-scrollbar {
animation: fadein-match-highlighter 1s cubic-bezier(.97,.01,.42,.98);
diff --git a/edit/edit.js b/edit/edit.js
index a4d7932a..0c45ea80 100644
--- a/edit/edit.js
+++ b/edit/edit.js
@@ -164,111 +164,16 @@ function setCleanSection(section) {
function initCodeMirror() {
const CM = CodeMirror;
- const isWindowsOS = navigator.appVersion.indexOf('Windows') > 0;
// lint.js is not loaded initially
- // CodeMirror miserably fails on keyMap='' so let's ensure it's not
- if (!prefs.get('editor.keyMap')) {
- prefs.reset('editor.keyMap');
- }
-
- // default option values
- Object.assign(CM.defaults, {
- mode: 'css',
- lineNumbers: true,
- lineWrapping: true,
- foldGutter: true,
- gutters: [
- 'CodeMirror-linenumbers',
- 'CodeMirror-foldgutter',
- ...(prefs.get('editor.linter') ? ['CodeMirror-lint-markers'] : []),
- ],
- matchBrackets: true,
- highlightSelectionMatches: {showToken: /[#.\-\w]/, annotateScrollbar: true},
- hintOptions: {},
- lint: linterConfig.getForCodeMirror(),
- lintReportDelay: prefs.get('editor.lintReportDelay'),
- styleActiveLine: true,
- theme: 'default',
- keyMap: prefs.get('editor.keyMap'),
- extraKeys: {
- // independent of current keyMap
- 'Alt-Enter': 'toggleStyle',
- 'Alt-PageDown': 'nextEditor',
- 'Alt-PageUp': 'prevEditor'
- }
- }, prefs.get('editor.options'));
+ CM.defaults.lint = linterConfig.getForCodeMirror();
// additional commands
CM.commands.jumpToLine = jumpToLine;
CM.commands.nextEditor = cm => nextPrevEditor(cm, 1);
CM.commands.prevEditor = cm => nextPrevEditor(cm, -1);
CM.commands.save = save;
- CM.commands.blockComment = cm => {
- 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
-
- const extraKeysCommands = {};
- Object.keys(CM.defaults.extraKeys).forEach(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';
- }
- if (!extraKeysCommands.autocomplete) {
- // will be used by 'sublime' on PC via fallthrough
- CM.keyMap.pcDefault['Ctrl-Space'] = 'autocomplete';
- // OSX uses Ctrl-Space and Cmd-Space for something else
- CM.keyMap.macDefault['Alt-Space'] = 'autocomplete';
- // copied from 'emacs' keymap
- CM.keyMap.emacsy['Alt-/'] = 'autocomplete';
- // 'vim' and 'emacs' define their own autocomplete hotkeys
- }
- if (!extraKeysCommands.blockComment) {
- CM.keyMap.sublime['Shift-Ctrl-/'] = 'blockComment';
- }
-
- if (isWindowsOS) {
- // 'pcDefault' keymap on Windows should have F3/Shift-F3
- if (!extraKeysCommands.findNext) {
- CM.keyMap.pcDefault['F3'] = 'findNext';
- }
- if (!extraKeysCommands.findPrev) {
- CM.keyMap.pcDefault['Shift-F3'] = 'findPrev';
- }
-
- // try to remap non-interceptable Ctrl-(Shift-)N/T/W hotkeys
- ['N', 'T', 'W'].forEach(char => {
- [
- {from: 'Ctrl-', to: ['Alt-', 'Ctrl-Alt-']},
- // Note: modifier order in CM is S-C-A
- {from: 'Shift-Ctrl-', to: ['Ctrl-Alt-', 'Shift-Ctrl-Alt-']}
- ].forEach(remap => {
- const oldKey = remap.from + char;
- Object.keys(CM.keyMap).forEach(keyMapName => {
- const keyMap = CM.keyMap[keyMapName];
- const command = keyMap[oldKey];
- if (!command) {
- return;
- }
- remap.to.some(newMod => {
- const newKey = newMod + char;
- if (!(newKey in keyMap)) {
- delete keyMap[oldKey];
- keyMap[newKey] = command;
- return true;
- }
- });
- });
- });
- });
- }
-
// user option values
CM.getOption = o => CodeMirror.defaults[o];
CM.setOption = (o, v) => {
@@ -278,8 +183,6 @@ function initCodeMirror() {
});
};
- CM.modeURL = '/vendor/codemirror/mode/%N/%N.js';
-
CM.prototype.getSection = function () {
return this.display.wrapper.parentNode;
};
diff --git a/edit/source-editor.js b/edit/source-editor.js
index e9ab02a7..635038d3 100644
--- a/edit/source-editor.js
+++ b/edit/source-editor.js
@@ -6,11 +6,6 @@
'use strict';
function createSourceEditor(style) {
- const MODE = {
- stylus: 'stylus',
- uso: 'css'
- };
-
// style might be an object reference to background page
style = deepCopy(style);
@@ -403,10 +398,9 @@ function createSourceEditor(style) {
$('#enabled').checked = style.enabled;
$('#url').href = style.url;
const {usercssData: {preprocessor}} = style;
- cm.setOption('mode', MODE[preprocessor] || 'css');
- CodeMirror.autoLoadMode(cm, MODE[preprocessor] || 'css');
+ cm.setPreprocessor(preprocessor);
// beautify only works with regular CSS
- $('#beautify').disabled = MODE[preprocessor] && MODE[preprocessor] !== 'css';
+ $('#beautify').disabled = cm.getOption('mode') !== 'css';
updateTitle();
}
diff --git a/install-usercss/install-usercss.css b/install-usercss/install-usercss.css
index 1922f0ec..b9bf9307 100644
--- a/install-usercss/install-usercss.css
+++ b/install-usercss/install-usercss.css
@@ -10,16 +10,17 @@ body {
.container {
display: flex;
- min-height: 100vh;
+ height: 100vh;
align-items: stretch;
}
.header {
- width: 280px;
+ flex: 0 0 280px;
padding: 15px;
border-right: 1px dashed #aaa;
box-shadow: 0 0 50px -18px black;
overflow-wrap: break-word;
+ overflow: auto;
}
.header > :first-child {
@@ -51,8 +52,8 @@ h1 small {
}
.actions label {
- width: fit-content;
- width: -moz-fit-content;
+ max-width: fit-content;
+ max-width: -moz-fit-content;
display: flex;
align-items: center;
margin: 0.5em 0;
@@ -60,6 +61,11 @@ h1 small {
.actions label input {
margin: 0 0.5em 0 0;
+ flex: 0 0 auto;
+}
+
+.actions label span {
+ min-width: 0;
}
.external {
@@ -75,7 +81,13 @@ h1 small {
}
.main {
- flex-grow: 1;
+ flex: 1 1 auto;
overflow: hidden;
overflow-wrap: break-word;
+ min-width: 0;
+}
+
+.main .code,
+.main .CodeMirror {
+ height: 100%;
}
diff --git a/install-usercss/install-usercss.html b/install-usercss/install-usercss.html
index 72490773..65cdf144 100644
--- a/install-usercss/install-usercss.html
+++ b/install-usercss/install-usercss.html
@@ -6,13 +6,44 @@
Loading...
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
@@ -21,7 +52,7 @@
diff --git a/install-usercss/install-usercss.js b/install-usercss/install-usercss.js
index 9c64f29d..2429954f 100644
--- a/install-usercss/install-usercss.js
+++ b/install-usercss/install-usercss.js
@@ -13,10 +13,18 @@
port.onMessage.addListener(msg => {
switch (msg.method) {
case 'getSourceCodeResponse':
- initSourceCode(msg.sourceCode);
+ if (msg.error) {
+ alert(msg.error);
+ } else {
+ initSourceCode(msg.sourceCode);
+ }
break;
}
});
+ port.onDisconnect.addListener(() => {
+ // FIXME: Firefox: 1) window.close doesn't work. 2) onDisconnect is fired only if the tab is closed.
+ window.close();
+ });
const cm = CodeMirror.fromTextArea($('.code textarea'), {readOnly: true});
@@ -38,11 +46,11 @@
.then(result => {
$$('.warning')
.forEach(el => el.remove());
- $('button.install').textContent = 'Installed';
- $('button.install').disabled = true;
- $('button.install').classList.add('installed');
- $('.set-update-url').disabled = true;
- $('.set-update-url-label').title = result.updateUrl ?
+ $('.install').textContent = 'Installed';
+ $('.install').disabled = true;
+ $('.install').classList.add('installed');
+ $('.set-update-url input[type=checkbox]').disabled = true;
+ $('.set-update-url').title = result.updateUrl ?
t('installUpdateFrom', result.updateUrl) : '';
window.dispatchEvent(new CustomEvent('installed', {detail: result}));
})
@@ -76,6 +84,7 @@
const dupData = dup && dup.usercssData;
const versionTest = dup && semverCompare(data.version, dupData.version);
+ // update UI
if (versionTest < 0) {
$('.actions').parentNode.insertBefore(
$element({className: 'warning', textContent: t('versionInvalidOlder')}),
@@ -94,8 +103,10 @@
}
};
+ // set updateUrl
const setUpdate = $('.set-update-url input[type=checkbox]');
const updateUrl = new URL(params.updateUrl);
+ $('.set-update-url > span').textContent = t('installUpdateFromLabel', updateUrl.href);
if (dup && dup.updateUrl === updateUrl.href) {
setUpdate.checked = true;
// there is no way to "unset" updateUrl, you can only overwrite it.
@@ -112,6 +123,9 @@
}
};
+ // update editor
+ cm.setPreprocessor(data.preprocessor);
+
// update metas
document.title = data.name;
diff --git a/vendor-overwrites/codemirror/codemirror-default.css b/vendor-overwrites/codemirror/codemirror-default.css
new file mode 100644
index 00000000..96626241
--- /dev/null
+++ b/vendor-overwrites/codemirror/codemirror-default.css
@@ -0,0 +1,26 @@
+.CodeMirror-hint:hover {
+ color: white;
+ background: #08f;
+}
+.CodeMirror {
+ border: solid #CCC 1px;
+}
+.CodeMirror-lint-mark-warning {
+ background: none;
+}
+.CodeMirror-dialog {
+ -webkit-animation: highlight 3s ease-out;
+}
+.CodeMirror-focused {
+ outline: -webkit-focus-ring-color auto 5px;
+ outline-offset: -2px;
+}
+.CodeMirror-search-field {
+ width: 10em;
+}
+.CodeMirror-jump-field {
+ width: 5em;
+}
+.CodeMirror-search-hint {
+ color: #888;
+}
diff --git a/vendor-overwrites/codemirror/codemirror-default.js b/vendor-overwrites/codemirror/codemirror-default.js
new file mode 100644
index 00000000..bea87073
--- /dev/null
+++ b/vendor-overwrites/codemirror/codemirror-default.js
@@ -0,0 +1,114 @@
+/* global CodeMirror prefs */
+
+'use strict';
+
+(function () {
+ // CodeMirror miserably fails on keyMap='' so let's ensure it's not
+ if (!prefs.get('editor.keyMap')) {
+ prefs.reset('editor.keyMap');
+ }
+
+ const defaults = {
+ mode: 'css',
+ lineNumbers: true,
+ lineWrapping: true,
+ foldGutter: true,
+ gutters: [
+ 'CodeMirror-linenumbers',
+ 'CodeMirror-foldgutter',
+ ...(prefs.get('editor.linter') ? ['CodeMirror-lint-markers'] : []),
+ ],
+ matchBrackets: true,
+ highlightSelectionMatches: {showToken: /[#.\-\w]/, annotateScrollbar: true},
+ hintOptions: {},
+ lintReportDelay: prefs.get('editor.lintReportDelay'),
+ styleActiveLine: true,
+ theme: 'default',
+ keyMap: prefs.get('editor.keyMap'),
+ extraKeys: {
+ // independent of current keyMap
+ 'Alt-Enter': 'toggleStyle',
+ 'Alt-PageDown': 'nextEditor',
+ 'Alt-PageUp': 'prevEditor'
+ }
+ };
+
+ Object.assign(CodeMirror.defaults, defaults, prefs.get('editor.options'));
+
+ CodeMirror.commands.blockComment = cm => {
+ cm.blockComment(cm.getCursor('from'), cm.getCursor('to'), {fullLines: false});
+ };
+
+ // 'basic' keymap only has basic keys by design, so we skip it
+
+ const extraKeysCommands = {};
+ Object.keys(CodeMirror.defaults.extraKeys).forEach(key => {
+ extraKeysCommands[CodeMirror.defaults.extraKeys[key]] = true;
+ });
+ if (!extraKeysCommands.jumpToLine) {
+ CodeMirror.keyMap.sublime['Ctrl-G'] = 'jumpToLine';
+ CodeMirror.keyMap.emacsy['Ctrl-G'] = 'jumpToLine';
+ CodeMirror.keyMap.pcDefault['Ctrl-J'] = 'jumpToLine';
+ CodeMirror.keyMap.macDefault['Cmd-J'] = 'jumpToLine';
+ }
+ if (!extraKeysCommands.autocomplete) {
+ // will be used by 'sublime' on PC via fallthrough
+ CodeMirror.keyMap.pcDefault['Ctrl-Space'] = 'autocomplete';
+ // OSX uses Ctrl-Space and Cmd-Space for something else
+ CodeMirror.keyMap.macDefault['Alt-Space'] = 'autocomplete';
+ // copied from 'emacs' keymap
+ CodeMirror.keyMap.emacsy['Alt-/'] = 'autocomplete';
+ // 'vim' and 'emacs' define their own autocomplete hotkeys
+ }
+ if (!extraKeysCommands.blockComment) {
+ CodeMirror.keyMap.sublime['Shift-Ctrl-/'] = 'blockComment';
+ }
+
+ if (navigator.appVersion.includes('Windows')) {
+ // 'pcDefault' keymap on Windows should have F3/Shift-F3
+ if (!extraKeysCommands.findNext) {
+ CodeMirror.keyMap.pcDefault['F3'] = 'findNext';
+ }
+ if (!extraKeysCommands.findPrev) {
+ CodeMirror.keyMap.pcDefault['Shift-F3'] = 'findPrev';
+ }
+
+ // try to remap non-interceptable Ctrl-(Shift-)N/T/W hotkeys
+ ['N', 'T', 'W'].forEach(char => {
+ [
+ {from: 'Ctrl-', to: ['Alt-', 'Ctrl-Alt-']},
+ // Note: modifier order in CodeMirror is S-C-A
+ {from: 'Shift-Ctrl-', to: ['Ctrl-Alt-', 'Shift-Ctrl-Alt-']}
+ ].forEach(remap => {
+ const oldKey = remap.from + char;
+ Object.keys(CodeMirror.keyMap).forEach(keyMapName => {
+ const keyMap = CodeMirror.keyMap[keyMapName];
+ const command = keyMap[oldKey];
+ if (!command) {
+ return;
+ }
+ remap.to.some(newMod => {
+ const newKey = newMod + char;
+ if (!(newKey in keyMap)) {
+ delete keyMap[oldKey];
+ keyMap[newKey] = command;
+ return true;
+ }
+ });
+ });
+ });
+ });
+ }
+
+ CodeMirror.modeURL = '/vendor/codemirror/mode/%N/%N.js';
+
+ const MODE = {
+ stylus: 'stylus',
+ uso: 'css'
+ };
+
+ CodeMirror.prototype.setPreprocessor = function(preprocessor) {
+ this.setOption('mode', MODE[preprocessor] || 'css');
+ CodeMirror.autoLoadMode(this, MODE[preprocessor] || 'css');
+ };
+})();