make editor load even faster
* reorder scripts * make style request earlier
This commit is contained in:
parent
2e1a903cc7
commit
bc6c9c826a
45
edit.html
45
edit.html
|
@ -18,6 +18,22 @@
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|
||||||
|
<link id="cm-theme" rel="stylesheet">
|
||||||
|
|
||||||
|
<script src="js/polyfill.js"></script>
|
||||||
|
<script src="js/dom.js"></script>
|
||||||
|
<script src="js/messaging.js"></script>
|
||||||
|
<script src="js/prefs.js"></script>
|
||||||
|
<script src="js/localization.js"></script>
|
||||||
|
<script src="js/script-loader.js"></script>
|
||||||
|
<script src="js/storage-util.js"></script>
|
||||||
|
<script src="js/msg.js"></script>
|
||||||
|
|
||||||
|
<script src="content/style-injector.js"></script>
|
||||||
|
<script src="content/apply.js"></script>
|
||||||
|
|
||||||
|
<script src="edit/edit.js"></script> <!-- run it ASAP to send a request for the style -->
|
||||||
|
|
||||||
<link href="vendor/codemirror/lib/codemirror.css" rel="stylesheet">
|
<link href="vendor/codemirror/lib/codemirror.css" rel="stylesheet">
|
||||||
<script src="vendor/codemirror/lib/codemirror.js"></script>
|
<script src="vendor/codemirror/lib/codemirror.js"></script>
|
||||||
|
|
||||||
|
@ -63,44 +79,27 @@
|
||||||
|
|
||||||
<script src="vendor-overwrites/codemirror-addon/match-highlighter.js"></script>
|
<script src="vendor-overwrites/codemirror-addon/match-highlighter.js"></script>
|
||||||
|
|
||||||
<script src="js/polyfill.js"></script>
|
<script src="msgbox/msgbox.js" async></script>
|
||||||
<script src="js/dom.js"></script>
|
|
||||||
<script src="js/messaging.js"></script>
|
|
||||||
<script src="js/prefs.js"></script>
|
|
||||||
<script src="js/localization.js"></script>
|
|
||||||
<script src="js/script-loader.js"></script>
|
|
||||||
<script src="js/storage-util.js"></script>
|
|
||||||
<script src="js/msg.js"></script>
|
|
||||||
<script src="js/worker-util.js"></script>
|
|
||||||
|
|
||||||
<script src="content/style-injector.js"></script>
|
|
||||||
<script src="content/apply.js"></script>
|
|
||||||
|
|
||||||
<link href="edit/global-search.css" rel="stylesheet">
|
|
||||||
<script src="edit/global-search.js"></script>
|
|
||||||
|
|
||||||
<link href="edit/codemirror-default.css" rel="stylesheet">
|
<link href="edit/codemirror-default.css" rel="stylesheet">
|
||||||
<script src="edit/codemirror-default.js"></script>
|
<script src="edit/codemirror-default.js"></script>
|
||||||
|
<script src="edit/codemirror-factory.js"></script>
|
||||||
<script src="edit/util.js"></script>
|
<script src="edit/util.js"></script>
|
||||||
<script src="edit/regexp-tester.js"></script>
|
<script src="edit/regexp-tester.js"></script>
|
||||||
<script src="edit/live-preview.js"></script>
|
<script src="edit/live-preview.js"></script>
|
||||||
<script src="edit/applies-to-line-widget.js"></script>
|
<script src="edit/applies-to-line-widget.js"></script>
|
||||||
<script src="edit/reroute-hotkeys.js"></script>
|
<script src="edit/reroute-hotkeys.js"></script>
|
||||||
<script src="edit/codemirror-factory.js"></script>
|
<link href="edit/global-search.css" rel="stylesheet">
|
||||||
|
<script src="edit/global-search.js"></script>
|
||||||
<script src="edit/colorpicker-helper.js"></script>
|
<script src="edit/colorpicker-helper.js"></script>
|
||||||
<script src="edit/beautify.js"></script>
|
<script src="edit/beautify.js"></script>
|
||||||
<script src="edit/show-keymap-help.js"></script>
|
<script src="edit/show-keymap-help.js"></script>
|
||||||
<script src="edit/codemirror-themes.js"></script>
|
<script src="edit/codemirror-themes.js"></script>
|
||||||
|
|
||||||
<script src="edit/source-editor.js"></script>
|
<script src="edit/source-editor.js"></script>
|
||||||
<script src="edit/sections-editor-section.js"></script>
|
<script src="edit/sections-editor-section.js"></script>
|
||||||
<script src="edit/sections-editor.js"></script>
|
<script src="edit/sections-editor.js"></script>
|
||||||
|
|
||||||
<script src="edit/edit.js"></script>
|
<script src="js/worker-util.js"></script>
|
||||||
|
|
||||||
<script src="msgbox/msgbox.js" async></script>
|
|
||||||
|
|
||||||
<script src="edit/linter.js"></script>
|
<script src="edit/linter.js"></script>
|
||||||
<script src="edit/linter-defaults.js"></script>
|
<script src="edit/linter-defaults.js"></script>
|
||||||
<script src="edit/linter-engines.js"></script>
|
<script src="edit/linter-engines.js"></script>
|
||||||
|
@ -109,8 +108,6 @@
|
||||||
<script src="edit/linter-report.js"></script>
|
<script src="edit/linter-report.js"></script>
|
||||||
<script src="edit/linter-config-dialog.js"></script>
|
<script src="edit/linter-config-dialog.js"></script>
|
||||||
|
|
||||||
<link id="cm-theme" rel="stylesheet">
|
|
||||||
|
|
||||||
<template data-id="appliesTo">
|
<template data-id="appliesTo">
|
||||||
<li class="applies-to-item">
|
<li class="applies-to-item">
|
||||||
<div class="select-resizer">
|
<div class="select-resizer">
|
||||||
|
|
155
edit/edit.js
155
edit/edit.js
|
@ -1,15 +1,11 @@
|
||||||
/* global CodeMirror onDOMready prefs setupLivePrefs $ $$ $create t tHTML
|
/* global CodeMirror onDOMready prefs setupLivePrefs $ $$ $create t tHTML
|
||||||
createSourceEditor sessionStorageHash getOwnTab FIREFOX API tryCatch
|
createSourceEditor sessionStorageHash getOwnTab FIREFOX API tryCatch
|
||||||
closeCurrentTab messageBox debounce workerUtil
|
closeCurrentTab messageBox debounce
|
||||||
initBeautifyButton ignoreChromeError dirtyReporter
|
initBeautifyButton ignoreChromeError dirtyReporter linter
|
||||||
moveFocus msg createSectionsEditor rerouteHotkeys CODEMIRROR_THEMES */
|
moveFocus msg createSectionsEditor rerouteHotkeys CODEMIRROR_THEMES */
|
||||||
/* exported showCodeMirrorPopup editorWorker toggleContextMenuDelete */
|
/* exported showCodeMirrorPopup editorWorker toggleContextMenuDelete */
|
||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
const editorWorker = workerUtil.createWorker({
|
|
||||||
url: '/edit/editor-worker.js'
|
|
||||||
});
|
|
||||||
|
|
||||||
let saveSizeOnClose;
|
let saveSizeOnClose;
|
||||||
|
|
||||||
// direct & reverse mapping of @-moz-document keywords and internal property names
|
// direct & reverse mapping of @-moz-document keywords and internal property names
|
||||||
|
@ -28,27 +24,37 @@ document.addEventListener('visibilitychange', beforeUnload);
|
||||||
window.addEventListener('beforeunload', beforeUnload);
|
window.addEventListener('beforeunload', beforeUnload);
|
||||||
msg.onExtension(onRuntimeMessage);
|
msg.onExtension(onRuntimeMessage);
|
||||||
|
|
||||||
preinit();
|
lazyInit();
|
||||||
|
|
||||||
(async function init() {
|
(async function init() {
|
||||||
const [style] = await Promise.all([
|
const [style] = await Promise.all([
|
||||||
initStyleData(),
|
initStyleData(),
|
||||||
onDOMready(),
|
onDOMready(),
|
||||||
prefs.initializing,
|
prefs.initializing.then(() => new Promise(resolve => {
|
||||||
|
const theme = prefs.get('editor.theme');
|
||||||
|
const el = $('#cm-theme');
|
||||||
|
if (theme === 'default') {
|
||||||
|
resolve();
|
||||||
|
} else {
|
||||||
|
// preload the theme so CodeMirror can use the correct metrics
|
||||||
|
el.href = `vendor/codemirror/theme/${theme}.css`;
|
||||||
|
el.addEventListener('load', resolve, {once: true});
|
||||||
|
}
|
||||||
|
})),
|
||||||
]);
|
]);
|
||||||
const usercss = isUsercss(style);
|
const usercss = isUsercss(style);
|
||||||
const dirty = dirtyReporter();
|
const dirty = dirtyReporter();
|
||||||
let wasDirty = false;
|
let wasDirty = false;
|
||||||
let nameTarget;
|
let nameTarget;
|
||||||
|
|
||||||
|
prefs.subscribe(['editor.linter'], updateLinter);
|
||||||
prefs.subscribe(['editor.keyMap'], showHotkeyInTooltip);
|
prefs.subscribe(['editor.keyMap'], showHotkeyInTooltip);
|
||||||
addEventListener('showHotkeyInTooltip', showHotkeyInTooltip);
|
addEventListener('showHotkeyInTooltip', showHotkeyInTooltip);
|
||||||
showHotkeyInTooltip();
|
showHotkeyInTooltip();
|
||||||
|
|
||||||
buildThemeElement();
|
buildThemeElement();
|
||||||
buildKeymapElement();
|
buildKeymapElement();
|
||||||
setupLivePrefs();
|
setupLivePrefs();
|
||||||
initNameArea(style, usercss);
|
initNameArea();
|
||||||
initBeautifyButton($('#beautify'), () => editor.getEditors());
|
initBeautifyButton($('#beautify'), () => editor.getEditors());
|
||||||
initResizeListener();
|
initResizeListener();
|
||||||
detectLayout();
|
detectLayout();
|
||||||
|
@ -70,7 +76,7 @@ preinit();
|
||||||
$('#name').required = !usercss;
|
$('#name').required = !usercss;
|
||||||
$('#save-button').onclick = editor.save;
|
$('#save-button').onclick = editor.save;
|
||||||
|
|
||||||
function initNameArea(style, usercss) {
|
function initNameArea() {
|
||||||
const nameEl = $('#name');
|
const nameEl = $('#name');
|
||||||
const resetEl = $('#reset-name');
|
const resetEl = $('#reset-name');
|
||||||
const isCustomName = style.updateUrl || usercss;
|
const isCustomName = style.updateUrl || usercss;
|
||||||
|
@ -116,6 +122,8 @@ preinit();
|
||||||
function buildThemeElement() {
|
function buildThemeElement() {
|
||||||
CODEMIRROR_THEMES.unshift(chrome.i18n.getMessage('defaultTheme'));
|
CODEMIRROR_THEMES.unshift(chrome.i18n.getMessage('defaultTheme'));
|
||||||
$('#editor.theme').append(...CODEMIRROR_THEMES.map(s => $create('option', s)));
|
$('#editor.theme').append(...CODEMIRROR_THEMES.map(s => $create('option', s)));
|
||||||
|
// move the theme after built-in CSS so that its same-specificity selectors win
|
||||||
|
document.head.appendChild($('#cm-theme'));
|
||||||
}
|
}
|
||||||
|
|
||||||
function buildKeymapElement() {
|
function buildKeymapElement() {
|
||||||
|
@ -216,81 +224,68 @@ preinit();
|
||||||
function updateTitle() {
|
function updateTitle() {
|
||||||
document.title = `${dirty.isDirty() ? '* ' : ''}${style.customName || style.name}`;
|
document.title = `${dirty.isDirty() ? '* ' : ''}${style.customName || style.name}`;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function updateLinter(key, value) {
|
||||||
|
$('body').classList.toggle('linter-disabled', value === '');
|
||||||
|
linter.run();
|
||||||
|
}
|
||||||
})();
|
})();
|
||||||
|
|
||||||
function preinit() {
|
/* Stuff not needed for the main init so we can let it run at its own tempo */
|
||||||
// preload the theme so that CodeMirror can calculate its metrics in DOMContentLoaded->setupLivePrefs()
|
async function lazyInit() {
|
||||||
new MutationObserver((mutations, observer) => {
|
const ownTabId = (await getOwnTab()).id;
|
||||||
const themeElement = $('#cm-theme');
|
// use browser history back when 'back to manage' is clicked
|
||||||
if (themeElement) {
|
if (sessionStorageHash('manageStylesHistory').value[ownTabId] === location.href) {
|
||||||
themeElement.href = prefs.get('editor.theme') === 'default' ? ''
|
onDOMready().then(() => {
|
||||||
: 'vendor/codemirror/theme/' + prefs.get('editor.theme') + '.css';
|
$('#cancel-button').onclick = event => {
|
||||||
observer.disconnect();
|
event.stopPropagation();
|
||||||
}
|
event.preventDefault();
|
||||||
}).observe(document, {subtree: true, childList: true});
|
history.back();
|
||||||
|
};
|
||||||
if (chrome.windows) {
|
|
||||||
browser.tabs.query({currentWindow: true}).then(tabs => {
|
|
||||||
const windowId = tabs[0].windowId;
|
|
||||||
if (prefs.get('openEditInWindow')) {
|
|
||||||
if (
|
|
||||||
/true/.test(sessionStorage.saveSizeOnClose) &&
|
|
||||||
'left' in prefs.get('windowPosition', {}) &&
|
|
||||||
!isWindowMaximized()
|
|
||||||
) {
|
|
||||||
// window was reopened via Ctrl-Shift-T etc.
|
|
||||||
chrome.windows.update(windowId, prefs.get('windowPosition'));
|
|
||||||
}
|
|
||||||
if (tabs.length === 1 && window.history.length === 1) {
|
|
||||||
chrome.windows.getAll(windows => {
|
|
||||||
if (windows.length > 1) {
|
|
||||||
sessionStorageHash('saveSizeOnClose').set(windowId, true);
|
|
||||||
saveSizeOnClose = true;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
} else {
|
|
||||||
saveSizeOnClose = sessionStorageHash('saveSizeOnClose').value[windowId];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
// no windows on android
|
||||||
getOwnTab().then(tab => {
|
if (!chrome.windows) {
|
||||||
const ownTabId = tab.id;
|
return;
|
||||||
|
}
|
||||||
// use browser history back when 'back to manage' is clicked
|
const tabs = await browser.tabs.query({currentWindow: true});
|
||||||
if (sessionStorageHash('manageStylesHistory').value[ownTabId] === location.href) {
|
const windowId = tabs[0].windowId;
|
||||||
onDOMready().then(() => {
|
if (prefs.get('openEditInWindow')) {
|
||||||
$('#cancel-button').onclick = event => {
|
if (
|
||||||
event.stopPropagation();
|
/true/.test(sessionStorage.saveSizeOnClose) &&
|
||||||
event.preventDefault();
|
'left' in prefs.get('windowPosition', {}) &&
|
||||||
history.back();
|
!isWindowMaximized()
|
||||||
};
|
) {
|
||||||
});
|
// window was reopened via Ctrl-Shift-T etc.
|
||||||
|
chrome.windows.update(windowId, prefs.get('windowPosition'));
|
||||||
}
|
}
|
||||||
// no windows on android
|
if (tabs.length === 1 && window.history.length === 1) {
|
||||||
if (!chrome.windows) {
|
chrome.windows.getAll(windows => {
|
||||||
|
if (windows.length > 1) {
|
||||||
|
sessionStorageHash('saveSizeOnClose').set(windowId, true);
|
||||||
|
saveSizeOnClose = true;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
saveSizeOnClose = sessionStorageHash('saveSizeOnClose').value[windowId];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
chrome.tabs.onAttached.addListener((tabId, info) => {
|
||||||
|
if (tabId !== ownTabId) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
// When an edit page gets attached or detached, remember its state
|
if (info.newPosition !== 0) {
|
||||||
// so we can do the same to the next one to open.
|
prefs.set('openEditInWindow', false);
|
||||||
chrome.tabs.onAttached.addListener((tabId, info) => {
|
return;
|
||||||
if (tabId !== ownTabId) {
|
}
|
||||||
return;
|
chrome.windows.get(info.newWindowId, {populate: true}, win => {
|
||||||
|
// If there's only one tab in this window, it's been dragged to new window
|
||||||
|
const openEditInWindow = win.tabs.length === 1;
|
||||||
|
if (openEditInWindow && FIREFOX) {
|
||||||
|
// FF-only because Chrome retardedly resets the size during dragging
|
||||||
|
chrome.windows.update(info.newWindowId, prefs.get('windowPosition'));
|
||||||
}
|
}
|
||||||
if (info.newPosition !== 0) {
|
prefs.set('openEditInWindow', openEditInWindow);
|
||||||
prefs.set('openEditInWindow', false);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
chrome.windows.get(info.newWindowId, {populate: true}, win => {
|
|
||||||
// If there's only one tab in this window, it's been dragged to new window
|
|
||||||
const openEditInWindow = win.tabs.length === 1;
|
|
||||||
if (openEditInWindow && FIREFOX) {
|
|
||||||
// FF-only because Chrome retardedly resets the size during dragging
|
|
||||||
chrome.windows.update(info.newWindowId, prefs.get('windowPosition'));
|
|
||||||
}
|
|
||||||
prefs.set('openEditInWindow', openEditInWindow);
|
|
||||||
});
|
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -507,10 +502,6 @@ function rememberWindowSize() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
prefs.subscribe(['editor.linter'], (key, value) => {
|
|
||||||
$('body').classList.toggle('linter-disabled', value === '');
|
|
||||||
});
|
|
||||||
|
|
||||||
function fixedHeader() {
|
function fixedHeader() {
|
||||||
const scrollPoint = $('#header').clientHeight - 40;
|
const scrollPoint = $('#header').clientHeight - 40;
|
||||||
const linterEnabled = prefs.get('editor.linter') !== '';
|
const linterEnabled = prefs.get('editor.linter') !== '';
|
||||||
|
|
|
@ -1,6 +1,11 @@
|
||||||
/* global prefs */
|
/* global workerUtil */
|
||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
|
/* exported editorWorker */
|
||||||
|
const editorWorker = workerUtil.createWorker({
|
||||||
|
url: '/edit/editor-worker.js'
|
||||||
|
});
|
||||||
|
|
||||||
/* exported linter */
|
/* exported linter */
|
||||||
const linter = (() => {
|
const linter = (() => {
|
||||||
const lintingUpdatedListeners = [];
|
const lintingUpdatedListeners = [];
|
||||||
|
@ -59,8 +64,3 @@ const linter = (() => {
|
||||||
.then(results => [].concat(...results.filter(Boolean)));
|
.then(results => [].concat(...results.filter(Boolean)));
|
||||||
}
|
}
|
||||||
})();
|
})();
|
||||||
|
|
||||||
// FIXME: this should be put inside edit.js
|
|
||||||
prefs.subscribe(['editor.linter'], () => {
|
|
||||||
linter.run();
|
|
||||||
});
|
|
||||||
|
|
|
@ -71,7 +71,7 @@ function createSectionsEditor(editorBase) {
|
||||||
});
|
});
|
||||||
|
|
||||||
function fitToContent(section) {
|
function fitToContent(section) {
|
||||||
const {cm, cm: {display: {wrapper, sizer}}} = section;
|
const {el, cm, cm: {display: {wrapper, sizer}}} = section;
|
||||||
if (cm.display.renderedView) {
|
if (cm.display.renderedView) {
|
||||||
resize();
|
resize();
|
||||||
} else {
|
} else {
|
||||||
|
@ -84,7 +84,7 @@ function createSectionsEditor(editorBase) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (headerOffset == null) {
|
if (headerOffset == null) {
|
||||||
headerOffset = wrapper.getBoundingClientRect().top;
|
headerOffset = el.getBoundingClientRect().top;
|
||||||
}
|
}
|
||||||
contentHeight += 9; // border & resize grip
|
contentHeight += 9; // border & resize grip
|
||||||
cm.off('update', resize);
|
cm.off('update', resize);
|
||||||
|
@ -95,16 +95,15 @@ function createSectionsEditor(editorBase) {
|
||||||
}
|
}
|
||||||
|
|
||||||
function fitToAvailableSpace() {
|
function fitToAvailableSpace() {
|
||||||
const available =
|
const ch = container.offsetHeight;
|
||||||
Math.floor(container.offsetHeight - sections.reduce((h, s) => h + s.el.offsetHeight, 0)) ||
|
let available = ch - sections[sections.length - 1].el.getBoundingClientRect().bottom + headerOffset;
|
||||||
window.innerHeight - container.offsetHeight;
|
if (available <= 1) available = window.innerHeight - ch - headerOffset;
|
||||||
if (available <= 0) {
|
const delta = Math.floor(available / sections.length);
|
||||||
return;
|
if (delta > 1) {
|
||||||
|
sections.forEach(({cm}) => {
|
||||||
|
cm.setSize(null, cm.display.wrapper.offsetHeight + delta);
|
||||||
|
});
|
||||||
}
|
}
|
||||||
const cmHeights = sections.map(s => s.cm.getWrapperElement().offsetHeight);
|
|
||||||
sections.forEach((section, i) => {
|
|
||||||
section.cm.setSize(null, cmHeights[i] + Math.floor(available / sections.length));
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function genId() {
|
function genId() {
|
||||||
|
|
Loading…
Reference in New Issue
Block a user