Add: a draggable list to customize injection order (#1364)
+ implement messageBox.close() + fix require() with root urls in /dir/page.html + limit messageBox focus shift to config-dialog + flatten vendor dirs and simplify build-vendor: + replace the unicode symbol with ASCII `->` + flatten dirs by default to simplify writing the rules and improve their readability + rename and sort functions in the order they run + use `node-fetch` instead of the gargantuan `make-fetch-happen` + use `glob` which is already installed by other deps Co-authored-by: tophf <tophf@gmx.com>
This commit is contained in:
parent
8ddeef221b
commit
ddc09f3511
|
@ -1667,6 +1667,14 @@
|
||||||
"styleIncludeLabel": {
|
"styleIncludeLabel": {
|
||||||
"message": "Custom included sites"
|
"message": "Custom included sites"
|
||||||
},
|
},
|
||||||
|
"styleInjectionOrder": {
|
||||||
|
"message": "Style injection order",
|
||||||
|
"description": "Tooltip for the button in the manager to open the dialog and also the title of this dialog"
|
||||||
|
},
|
||||||
|
"styleInjectionOrderHint": {
|
||||||
|
"message": "Drag'n'drop a style to change its position. Styles are injected sequentially in the order shown below so a style further down the list can override the earlier styles.",
|
||||||
|
"description": "Hint in the injection order dialog in the manager"
|
||||||
|
},
|
||||||
"styleExcludeLabel": {
|
"styleExcludeLabel": {
|
||||||
"message": "Custom excluded sites"
|
"message": "Custom excluded sites"
|
||||||
},
|
},
|
||||||
|
|
|
@ -59,6 +59,7 @@ const styleMan = (() => {
|
||||||
const DELETE_IF_NULL = ['id', 'customName', 'md5Url', 'originalMd5'];
|
const DELETE_IF_NULL = ['id', 'customName', 'md5Url', 'originalMd5'];
|
||||||
/** @type {Promise|boolean} will be `true` to avoid wasting a microtask tick on each `await` */
|
/** @type {Promise|boolean} will be `true` to avoid wasting a microtask tick on each `await` */
|
||||||
let ready = init();
|
let ready = init();
|
||||||
|
let order = {};
|
||||||
|
|
||||||
chrome.runtime.onConnect.addListener(handleLivePreview);
|
chrome.runtime.onConnect.addListener(handleLivePreview);
|
||||||
// function handleColorScheme() {
|
// function handleColorScheme() {
|
||||||
|
@ -70,6 +71,17 @@ const styleMan = (() => {
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
prefs.subscribe(['injectionOrder'], (key, value) => {
|
||||||
|
order = {};
|
||||||
|
value.forEach((uid, i) => {
|
||||||
|
const id = uuidIndex.get(uid);
|
||||||
|
if (id) {
|
||||||
|
order[id] = i;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
msg.broadcast({method: 'styleSort', order});
|
||||||
|
});
|
||||||
|
|
||||||
//#endregion
|
//#endregion
|
||||||
//#region Exports
|
//#region Exports
|
||||||
|
|
||||||
|
@ -148,7 +160,11 @@ const styleMan = (() => {
|
||||||
async getSectionsByUrl(url, id, isInitialApply) {
|
async getSectionsByUrl(url, id, isInitialApply) {
|
||||||
if (ready.then) await ready;
|
if (ready.then) await ready;
|
||||||
if (isInitialApply && prefs.get('disableAll')) {
|
if (isInitialApply && prefs.get('disableAll')) {
|
||||||
return {disableAll: true};
|
return {
|
||||||
|
cfg: {
|
||||||
|
disableAll: true,
|
||||||
|
},
|
||||||
|
};
|
||||||
}
|
}
|
||||||
const sender = CHROME && this && this.sender || {};
|
const sender = CHROME && this && this.sender || {};
|
||||||
if (sender.frameId === 0) {
|
if (sender.frameId === 0) {
|
||||||
|
@ -170,7 +186,7 @@ const styleMan = (() => {
|
||||||
}
|
}
|
||||||
return id
|
return id
|
||||||
? cache.sections[id] ? {[id]: cache.sections[id]} : {}
|
? cache.sections[id] ? {[id]: cache.sections[id]} : {}
|
||||||
: cache.sections;
|
: Object.assign({cfg: {order}}, cache.sections);
|
||||||
},
|
},
|
||||||
|
|
||||||
/** @returns {Promise<StyleObj>} */
|
/** @returns {Promise<StyleObj>} */
|
||||||
|
|
|
@ -56,6 +56,7 @@
|
||||||
return NOP;
|
return NOP;
|
||||||
}
|
}
|
||||||
return API.styles.getSectionsByUrl(url, id).then(sections => {
|
return API.styles.getSectionsByUrl(url, id).then(sections => {
|
||||||
|
delete sections.cfg;
|
||||||
const tasks = [];
|
const tasks = [];
|
||||||
for (const section of Object.values(sections)) {
|
for (const section of Object.values(sections)) {
|
||||||
const styleId = section.id;
|
const styleId = section.id;
|
||||||
|
|
|
@ -13,11 +13,19 @@
|
||||||
let hasStyles = false;
|
let hasStyles = false;
|
||||||
let isDisabled = false;
|
let isDisabled = false;
|
||||||
let isTab = !chrome.tabs || location.pathname !== '/popup.html';
|
let isTab = !chrome.tabs || location.pathname !== '/popup.html';
|
||||||
|
let order = {};
|
||||||
const isFrame = window !== parent;
|
const isFrame = window !== parent;
|
||||||
const isFrameAboutBlank = isFrame && location.href === 'about:blank';
|
const isFrameAboutBlank = isFrame && location.href === 'about:blank';
|
||||||
const isUnstylable = !chrome.app && document instanceof XMLDocument;
|
const isUnstylable = !chrome.app && document instanceof XMLDocument;
|
||||||
const styleInjector = StyleInjector({
|
const styleInjector = StyleInjector({
|
||||||
compare: (a, b) => a.id - b.id,
|
compare: (a, b) => {
|
||||||
|
const ia = order[a.id];
|
||||||
|
const ib = order[b.id];
|
||||||
|
if (ia === ib) return 0;
|
||||||
|
if (ia == null) return 1;
|
||||||
|
if (ib == null) return -1;
|
||||||
|
return ia - ib;
|
||||||
|
},
|
||||||
onUpdate: onInjectorUpdate,
|
onUpdate: onInjectorUpdate,
|
||||||
});
|
});
|
||||||
// dynamic iframes don't have a URL yet so we'll use their parent's URL (hash isn't inherited)
|
// dynamic iframes don't have a URL yet so we'll use their parent's URL (hash isn't inherited)
|
||||||
|
@ -100,7 +108,11 @@
|
||||||
parentStyles && await new Promise(onFrameElementInView) && parentStyles ||
|
parentStyles && await new Promise(onFrameElementInView) && parentStyles ||
|
||||||
!isFrameAboutBlank && chrome.app && !chrome.tabs && tryCatch(getStylesViaXhr) ||
|
!isFrameAboutBlank && chrome.app && !chrome.tabs && tryCatch(getStylesViaXhr) ||
|
||||||
await API.styles.getSectionsByUrl(matchUrl, null, true);
|
await API.styles.getSectionsByUrl(matchUrl, null, true);
|
||||||
isDisabled = styles.disableAll;
|
if (styles.cfg) {
|
||||||
|
isDisabled = styles.cfg.disableAll;
|
||||||
|
order = styles.cfg.order || {};
|
||||||
|
delete styles.cfg;
|
||||||
|
}
|
||||||
hasStyles = !isDisabled;
|
hasStyles = !isDisabled;
|
||||||
if (hasStyles) {
|
if (hasStyles) {
|
||||||
window[SYM] = styles;
|
window[SYM] = styles;
|
||||||
|
@ -166,10 +178,16 @@
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case 'styleSort':
|
||||||
|
order = request.order;
|
||||||
|
styleInjector.sort();
|
||||||
|
break;
|
||||||
|
|
||||||
case 'urlChanged':
|
case 'urlChanged':
|
||||||
if (!hasStyles && isDisabled || matchUrl === request.url) break;
|
if (!hasStyles && isDisabled || matchUrl === request.url) break;
|
||||||
matchUrl = request.url;
|
matchUrl = request.url;
|
||||||
API.styles.getSectionsByUrl(matchUrl).then(sections => {
|
API.styles.getSectionsByUrl(matchUrl).then(sections => {
|
||||||
|
delete sections.cfg;
|
||||||
hasStyles = true;
|
hasStyles = true;
|
||||||
styleInjector.replace(sections);
|
styleInjector.replace(sections);
|
||||||
});
|
});
|
||||||
|
|
|
@ -78,6 +78,8 @@ window.StyleInjector = window.INJECTED === 1 ? window.StyleInjector : ({
|
||||||
_addRemoveElements(enable);
|
_addRemoveElements(enable);
|
||||||
if (enable) _toggleObservers(true);
|
if (enable) _toggleObservers(true);
|
||||||
},
|
},
|
||||||
|
|
||||||
|
sort: _sort,
|
||||||
};
|
};
|
||||||
|
|
||||||
function _add(style) {
|
function _add(style) {
|
||||||
|
|
58
injection-order/injection-order.css
Normal file
58
injection-order/injection-order.css
Normal file
|
@ -0,0 +1,58 @@
|
||||||
|
#message-box.injection-order > div {
|
||||||
|
height: 100%;
|
||||||
|
max-width: 80vw;
|
||||||
|
}
|
||||||
|
#message-box.injection-order #message-box-contents {
|
||||||
|
padding: 0;
|
||||||
|
overflow: hidden;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
--border: 1px solid rgba(128, 128, 128, .25);
|
||||||
|
}
|
||||||
|
.injection-order header {
|
||||||
|
padding: 1rem;
|
||||||
|
width: 0;
|
||||||
|
min-width: 100%;
|
||||||
|
box-sizing: border-box;
|
||||||
|
}
|
||||||
|
.injection-order ol {
|
||||||
|
height: 100%;
|
||||||
|
padding: 1px 0 0; /* 1px for keyboard-focused element's outline */
|
||||||
|
margin: 0;
|
||||||
|
font-size: 14px;
|
||||||
|
overflow-y: auto;
|
||||||
|
border-top: var(--border);
|
||||||
|
}
|
||||||
|
.injection-order a {
|
||||||
|
display: block;
|
||||||
|
color: #000;
|
||||||
|
text-decoration: none;
|
||||||
|
transition: transform .25s ease-in-out;
|
||||||
|
z-index: 1;
|
||||||
|
user-select: none;
|
||||||
|
padding: 0.3em .5em;
|
||||||
|
white-space: nowrap;
|
||||||
|
overflow: hidden;
|
||||||
|
text-overflow: ellipsis;
|
||||||
|
cursor: move;
|
||||||
|
}
|
||||||
|
.injection-order a.enabled {
|
||||||
|
font-weight: bold;
|
||||||
|
}
|
||||||
|
.injection-order a:hover {
|
||||||
|
text-decoration: underline;
|
||||||
|
}
|
||||||
|
.injection-order a:not(:first-child) {
|
||||||
|
border-top: var(--border);
|
||||||
|
}
|
||||||
|
.injection-order a::before {
|
||||||
|
content: "\2261";
|
||||||
|
padding: 0.6em;
|
||||||
|
font-weight: normal;
|
||||||
|
}
|
||||||
|
.injection-order .draggable-list-target {
|
||||||
|
position: relative;
|
||||||
|
background: lightcyan;
|
||||||
|
transition: none;
|
||||||
|
z-index: 100;
|
||||||
|
}
|
79
injection-order/injection-order.js
Normal file
79
injection-order/injection-order.js
Normal file
|
@ -0,0 +1,79 @@
|
||||||
|
/* global $create messageBoxProxy */// dom.js
|
||||||
|
/* global API */// msg.js
|
||||||
|
/* global DraggableList */
|
||||||
|
/* global prefs */
|
||||||
|
/* global t */// localization.js
|
||||||
|
'use strict';
|
||||||
|
|
||||||
|
/* exported InjectionOrder */
|
||||||
|
async function InjectionOrder(show = true) {
|
||||||
|
if (!show) {
|
||||||
|
return messageBoxProxy.close();
|
||||||
|
}
|
||||||
|
const entries = (await getOrderedStyles()).map(makeEntry);
|
||||||
|
const ol = $create('ol');
|
||||||
|
let maxTranslateY;
|
||||||
|
ol.append(...entries.map(l => l.el));
|
||||||
|
ol.on('d:dragstart', ({detail: d}) => {
|
||||||
|
d.origin.dataTransfer.setDragImage(new Image(), 0, 0);
|
||||||
|
maxTranslateY = ol.scrollHeight + ol.offsetTop - d.dragTarget.offsetHeight - d.dragTarget.offsetTop;
|
||||||
|
});
|
||||||
|
ol.on('d:dragmove', ({detail: d}) => {
|
||||||
|
d.origin.stopPropagation(); // preserves dropEffect
|
||||||
|
d.origin.dataTransfer.dropEffect = 'move';
|
||||||
|
const y = Math.min(d.currentPos.y - d.startPos.y, maxTranslateY);
|
||||||
|
d.dragTarget.style.transform = `translateY(${y}px)`;
|
||||||
|
});
|
||||||
|
ol.on('d:dragend', ({detail: d}) => {
|
||||||
|
const [item] = entries.splice(d.originalIndex, 1);
|
||||||
|
entries.splice(d.spliceIndex, 0, item);
|
||||||
|
ol.insertBefore(d.dragTarget, d.insertBefore);
|
||||||
|
prefs.set('injectionOrder', entries.map(l => l.style._id));
|
||||||
|
});
|
||||||
|
DraggableList(ol, {scrollContainer: ol});
|
||||||
|
|
||||||
|
await messageBoxProxy.show({
|
||||||
|
title: t('styleInjectionOrder'),
|
||||||
|
contents: $create('fragment', [
|
||||||
|
$create('header', t('styleInjectionOrderHint')),
|
||||||
|
ol,
|
||||||
|
]),
|
||||||
|
className: 'injection-order center-dialog',
|
||||||
|
blockScroll: true,
|
||||||
|
buttons: [t('confirmClose')],
|
||||||
|
});
|
||||||
|
|
||||||
|
async function getOrderedStyles() {
|
||||||
|
const [styles] = await Promise.all([
|
||||||
|
API.styles.getAll(),
|
||||||
|
prefs.ready,
|
||||||
|
]);
|
||||||
|
const styleSet = new Set(styles);
|
||||||
|
const uuidIndex = new Map();
|
||||||
|
for (const s of styleSet) {
|
||||||
|
uuidIndex.set(s._id, s);
|
||||||
|
}
|
||||||
|
const orderedStyles = [];
|
||||||
|
for (const uid of prefs.get('injectionOrder')) {
|
||||||
|
const s = uuidIndex.get(uid);
|
||||||
|
if (s) {
|
||||||
|
uuidIndex.delete(uid);
|
||||||
|
orderedStyles.push(s);
|
||||||
|
styleSet.delete(s);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
orderedStyles.push(...styleSet);
|
||||||
|
return orderedStyles;
|
||||||
|
}
|
||||||
|
|
||||||
|
function makeEntry(style) {
|
||||||
|
return {
|
||||||
|
style,
|
||||||
|
el: $create('a', {
|
||||||
|
className: style.enabled ? 'enabled' : '',
|
||||||
|
href: '/edit.html?id=' + style.id,
|
||||||
|
target: '_blank',
|
||||||
|
}, style.name),
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
|
@ -12,6 +12,19 @@ window.messageBox = {
|
||||||
_resolve: null,
|
_resolve: null,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
messageBox.close = async isAnimated => {
|
||||||
|
window.off('keydown', messageBox.listeners.key, true);
|
||||||
|
window.off('scroll', messageBox.listeners.scroll);
|
||||||
|
window.off('mouseup', messageBox.listeners.mouseUp);
|
||||||
|
window.off('mousemove', messageBox.listeners.mouseMove);
|
||||||
|
if (isAnimated) {
|
||||||
|
await animateElement(messageBox.element, 'fadeout');
|
||||||
|
}
|
||||||
|
messageBox.element.remove();
|
||||||
|
messageBox.element = null;
|
||||||
|
messageBox._resolve = null;
|
||||||
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param {Object} params
|
* @param {Object} params
|
||||||
* @param {String} params.title
|
* @param {String} params.title
|
||||||
|
@ -46,7 +59,8 @@ messageBox.show = async ({
|
||||||
|
|
||||||
messageBox._originalFocus = document.activeElement;
|
messageBox._originalFocus = document.activeElement;
|
||||||
// focus the first focusable child but skip the first external link which is usually `feedback`
|
// focus the first focusable child but skip the first external link which is usually `feedback`
|
||||||
if ((moveFocus(messageBox.element, 0) || {}).target === '_blank') {
|
if ((moveFocus(messageBox.element, 0) || {}).target === '_blank' &&
|
||||||
|
/config-dialog/.test(className)) {
|
||||||
moveFocus(messageBox.element, 1);
|
moveFocus(messageBox.element, 1);
|
||||||
}
|
}
|
||||||
// suppress focus outline when invoked via click
|
// suppress focus outline when invoked via click
|
||||||
|
@ -143,9 +157,7 @@ messageBox.show = async ({
|
||||||
|
|
||||||
function resolveWith(value) {
|
function resolveWith(value) {
|
||||||
setTimeout(messageBox._resolve, 0, value);
|
setTimeout(messageBox._resolve, 0, value);
|
||||||
unbindGlobalListeners();
|
messageBox.close(true);
|
||||||
animateElement(messageBox.element, 'fadeout')
|
|
||||||
.then(removeSelf);
|
|
||||||
if (messageBox.element.contains(document.activeElement)) {
|
if (messageBox.element.contains(document.activeElement)) {
|
||||||
messageBox._originalFocus.focus();
|
messageBox._originalFocus.focus();
|
||||||
}
|
}
|
||||||
|
@ -153,8 +165,7 @@ messageBox.show = async ({
|
||||||
|
|
||||||
function createElement() {
|
function createElement() {
|
||||||
if (messageBox.element) {
|
if (messageBox.element) {
|
||||||
unbindGlobalListeners();
|
messageBox.close();
|
||||||
removeSelf();
|
|
||||||
}
|
}
|
||||||
const id = 'message-box';
|
const id = 'message-box';
|
||||||
messageBox.element =
|
messageBox.element =
|
||||||
|
@ -186,19 +197,6 @@ messageBox.show = async ({
|
||||||
}
|
}
|
||||||
window.on('keydown', messageBox.listeners.key, true);
|
window.on('keydown', messageBox.listeners.key, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
function unbindGlobalListeners() {
|
|
||||||
window.off('keydown', messageBox.listeners.key, true);
|
|
||||||
window.off('scroll', messageBox.listeners.scroll);
|
|
||||||
window.off('mouseup', messageBox.listeners.mouseUp);
|
|
||||||
window.off('mousemove', messageBox.listeners.mouseMove);
|
|
||||||
}
|
|
||||||
|
|
||||||
function removeSelf() {
|
|
||||||
messageBox.element.remove();
|
|
||||||
messageBox.element = null;
|
|
||||||
messageBox._resolve = null;
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -15,7 +15,7 @@
|
||||||
window.on('click', showTooltipNote);
|
window.on('click', showTooltipNote);
|
||||||
window.on('resize', () => debounce(addTooltipsToEllipsized, 100));
|
window.on('resize', () => debounce(addTooltipsToEllipsized, 100));
|
||||||
// Removing transition-suppressor rule
|
// Removing transition-suppressor rule
|
||||||
const {sheet} = $('link[href^="global.css"]');
|
const {sheet} = $('link[href$="global.css"]');
|
||||||
for (let i = 0, rule; (rule = sheet.cssRules[i]); i++) {
|
for (let i = 0, rule; (rule = sheet.cssRules[i]); i++) {
|
||||||
if (/#\\1\s?transition-suppressor/.test(rule.selectorText)) {
|
if (/#\\1\s?transition-suppressor/.test(rule.selectorText)) {
|
||||||
sheet.deleteRule(i);
|
sheet.deleteRule(i);
|
||||||
|
|
|
@ -86,7 +86,7 @@
|
||||||
const tag = isCss ? 'link' : 'script';
|
const tag = isCss ? 'link' : 'script';
|
||||||
const attr = isCss ? 'href' : 'src';
|
const attr = isCss ? 'href' : 'src';
|
||||||
if (!isCss && !url.endsWith('.js')) url += '.js';
|
if (!isCss && !url.endsWith('.js')) url += '.js';
|
||||||
if (url.startsWith('/')) url = url.slice(1);
|
if (url[0] === '/' && location.pathname.indexOf('/', 1) < 0) url = url.slice(1);
|
||||||
let el = document.head.querySelector(`${tag}[${attr}$="${url}"]`);
|
let el = document.head.querySelector(`${tag}[${attr}$="${url}"]`);
|
||||||
if (!el) {
|
if (!el) {
|
||||||
el = document.createElement(tag);
|
el = document.createElement(tag);
|
||||||
|
|
|
@ -17,6 +17,7 @@
|
||||||
* @namespace PrefsValues
|
* @namespace PrefsValues
|
||||||
*/
|
*/
|
||||||
const defaults = {
|
const defaults = {
|
||||||
|
// TODO: sort everything aphabetically
|
||||||
'openEditInWindow': false, // new editor opens in a own browser window
|
'openEditInWindow': false, // new editor opens in a own browser window
|
||||||
'openEditInWindow.popup': false, // new editor opens in a simplified browser window without omnibox
|
'openEditInWindow.popup': false, // new editor opens in a simplified browser window without omnibox
|
||||||
'windowPosition': {}, // detached window position
|
'windowPosition': {}, // detached window position
|
||||||
|
@ -132,6 +133,8 @@
|
||||||
'popupWidth': 246, // popup width in pixels
|
'popupWidth': 246, // popup width in pixels
|
||||||
|
|
||||||
'updateInterval': 24, // user-style automatic update interval, hours (0 = disable)
|
'updateInterval': 24, // user-style automatic update interval, hours (0 = disable)
|
||||||
|
|
||||||
|
'injectionOrder': [],
|
||||||
};
|
};
|
||||||
const knownKeys = Object.keys(defaults);
|
const knownKeys = Object.keys(defaults);
|
||||||
/** @type {PrefsValues} */
|
/** @type {PrefsValues} */
|
||||||
|
|
|
@ -313,8 +313,8 @@
|
||||||
</a>
|
</a>
|
||||||
</label>
|
</label>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<button id="manage-options-button" i18n-text="openOptions"></button>
|
<button id="manage-options-button" i18n-text="openOptions"></button>
|
||||||
|
<button id="injection-order-button" i18n-title="styleInjectionOrder">↑↓</button>
|
||||||
</details>
|
</details>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
|
@ -1165,3 +1165,4 @@ a:hover {
|
||||||
margin-left: -2px;
|
margin-left: -2px;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -61,6 +61,7 @@ newUI.renderClass();
|
||||||
installed.on('mouseover', Events.lazyAddEntryTitle, {passive: true});
|
installed.on('mouseover', Events.lazyAddEntryTitle, {passive: true});
|
||||||
installed.on('mouseout', Events.lazyAddEntryTitle, {passive: true});
|
installed.on('mouseout', Events.lazyAddEntryTitle, {passive: true});
|
||||||
$('#manage-options-button').onclick = () => router.updateHash('#stylus-options');
|
$('#manage-options-button').onclick = () => router.updateHash('#stylus-options');
|
||||||
|
$('#injection-order-button').onclick = () => router.updateHash('#injection-order');
|
||||||
$('#sync-styles').onclick = () => router.updateHash('#stylus-options');
|
$('#sync-styles').onclick = () => router.updateHash('#stylus-options');
|
||||||
$$('#header a[href^="http"]').forEach(a => (a.onclick = Events.external));
|
$$('#header a[href^="http"]').forEach(a => (a.onclick = Events.external));
|
||||||
document.on('visibilitychange', handleVisibilityChange);
|
document.on('visibilitychange', handleVisibilityChange);
|
||||||
|
@ -101,6 +102,7 @@ newUI.renderClass();
|
||||||
msg.onExtension(onRuntimeMessage);
|
msg.onExtension(onRuntimeMessage);
|
||||||
window.on('closeOptions', () => router.updateHash(''));
|
window.on('closeOptions', () => router.updateHash(''));
|
||||||
router.watch({hash: '#stylus-options'}, toggleEmbeddedOptions);
|
router.watch({hash: '#stylus-options'}, toggleEmbeddedOptions);
|
||||||
|
router.watch({hash: '#injection-order'}, toggleInjectionOrder);
|
||||||
|
|
||||||
function onRuntimeMessage(msg) {
|
function onRuntimeMessage(msg) {
|
||||||
switch (msg.method) {
|
switch (msg.method) {
|
||||||
|
@ -137,3 +139,18 @@ async function toggleEmbeddedOptions(state) {
|
||||||
el.remove();
|
el.remove();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async function toggleInjectionOrder(state) {
|
||||||
|
const shown = $('.injection-order');
|
||||||
|
if (state && !shown) {
|
||||||
|
await require([
|
||||||
|
'/vendor/draggable-list/draggable-list.iife.min.js',
|
||||||
|
'/injection-order/injection-order.css',
|
||||||
|
'/injection-order/injection-order', /* global InjectionOrder */
|
||||||
|
]);
|
||||||
|
await InjectionOrder();
|
||||||
|
router.updateHash('');
|
||||||
|
} else if (!state && shown) {
|
||||||
|
await InjectionOrder(false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
2113
package-lock.json
generated
2113
package-lock.json
generated
File diff suppressed because it is too large
Load Diff
|
@ -9,6 +9,7 @@
|
||||||
"codemirror": "WARNING! Always use an exact version and test it for a while before releasing"
|
"codemirror": "WARNING! Always use an exact version and test it for a while before releasing"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
|
"@eight04/draggable-list": "^0.3.0",
|
||||||
"codemirror": "5.63.3",
|
"codemirror": "5.63.3",
|
||||||
"db-to-cloud": "^0.7.0",
|
"db-to-cloud": "^0.7.0",
|
||||||
"jsonlint": "^1.6.3",
|
"jsonlint": "^1.6.3",
|
||||||
|
@ -21,12 +22,11 @@
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"archiver": "^4.0.1",
|
"archiver": "^4.0.1",
|
||||||
"endent": "^1.4.0",
|
|
||||||
"eslint": "^7.20.0",
|
"eslint": "^7.20.0",
|
||||||
"fs-extra": "^9.0.0",
|
"fs-extra": "^9.0.0",
|
||||||
"make-fetch-happen": "^8.0.7",
|
"glob": "^7.2.0",
|
||||||
|
"node-fetch": "^2.6.6",
|
||||||
"sync-version": "^1.0.1",
|
"sync-version": "^1.0.1",
|
||||||
"tiny-glob": "^0.2.6",
|
|
||||||
"web-ext": "^6.5.0"
|
"web-ext": "^6.5.0"
|
||||||
},
|
},
|
||||||
"scripts": {
|
"scripts": {
|
||||||
|
|
|
@ -1,14 +1,16 @@
|
||||||
/* eslint-env node */
|
|
||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
|
const fetch = require('node-fetch');
|
||||||
|
const fs = require('fs');
|
||||||
|
const fse = require('fs-extra');
|
||||||
|
const glob = require('glob').sync;
|
||||||
const path = require('path');
|
const path = require('path');
|
||||||
|
|
||||||
const endent = require('endent');
|
const KEEP_DIRECTORIES = null;
|
||||||
const fetch = require('make-fetch-happen');
|
|
||||||
const fse = require('fs-extra');
|
|
||||||
const glob = require('tiny-glob');
|
|
||||||
|
|
||||||
const files = {
|
const files = {
|
||||||
'codemirror': [
|
'codemirror': [
|
||||||
|
KEEP_DIRECTORIES,
|
||||||
'addon/comment/comment.js',
|
'addon/comment/comment.js',
|
||||||
'addon/dialog',
|
'addon/dialog',
|
||||||
'addon/edit/closebrackets.js',
|
'addon/edit/closebrackets.js',
|
||||||
|
@ -35,30 +37,33 @@ const files = {
|
||||||
'theme/*',
|
'theme/*',
|
||||||
],
|
],
|
||||||
'jsonlint': [
|
'jsonlint': [
|
||||||
'lib/jsonlint.js → jsonlint.js',
|
'lib/jsonlint.js',
|
||||||
'README.md → LICENSE',
|
'README.md -> LICENSE',
|
||||||
],
|
],
|
||||||
'less-bundle': [
|
'less-bundle': [
|
||||||
'dist/less.min.js → less.min.js',
|
'dist/less.min.js',
|
||||||
],
|
],
|
||||||
'lz-string-unsafe': [
|
'lz-string-unsafe': [
|
||||||
'lz-string-unsafe.min.js',
|
'lz-string-unsafe.min.js',
|
||||||
],
|
],
|
||||||
'stylelint-bundle': [
|
'stylelint-bundle': [
|
||||||
'dist/stylelint-bundle.min.js → stylelint-bundle.min.js',
|
'dist/stylelint-bundle.min.js',
|
||||||
'https://github.com/stylelint/stylelint/raw/{VERSION}/LICENSE → LICENSE',
|
'https://github.com/stylelint/stylelint/raw/{VERSION}/LICENSE',
|
||||||
],
|
],
|
||||||
'stylus-lang-bundle': [
|
'stylus-lang-bundle': [
|
||||||
'dist/stylus-renderer.min.js → stylus-renderer.min.js',
|
'dist/stylus-renderer.min.js',
|
||||||
],
|
],
|
||||||
'usercss-meta': [
|
'usercss-meta': [
|
||||||
'dist/usercss-meta.min.js → usercss-meta.min.js',
|
'dist/usercss-meta.min.js',
|
||||||
],
|
],
|
||||||
'db-to-cloud': [
|
'db-to-cloud': [
|
||||||
'dist/db-to-cloud.min.js → db-to-cloud.min.js',
|
'dist/db-to-cloud.min.js',
|
||||||
],
|
],
|
||||||
'webext-launch-web-auth-flow': [
|
'webext-launch-web-auth-flow': [
|
||||||
'dist/webext-launch-web-auth-flow.min.js → webext-launch-web-auth-flow.min.js',
|
'dist/webext-launch-web-auth-flow.min.js',
|
||||||
|
],
|
||||||
|
'@eight04/draggable-list': [
|
||||||
|
'dist/draggable-list.iife.min.js',
|
||||||
],
|
],
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -66,96 +71,97 @@ main().catch(console.error);
|
||||||
|
|
||||||
async function main() {
|
async function main() {
|
||||||
fse.emptyDirSync('vendor');
|
fse.emptyDirSync('vendor');
|
||||||
for (const pkg in files) {
|
await Promise.all(Object.keys(files).map(async pkg => {
|
||||||
console.log('\x1b[32m%s\x1b[0m', `Building ${pkg}...`);
|
console.log(`Building ${pkg}...`);
|
||||||
// other files
|
const pkgName = getFileName(pkg);
|
||||||
const [fetched, copied] = await buildFiles(pkg, files[pkg]);
|
const flatPkg = pkg === pkgName || files[pkgName]
|
||||||
// README
|
? pkg.replace(/\//g, '-')
|
||||||
await fse.outputFile(`vendor/${pkg}/README.md`, generateReadme(pkg, fetched, copied));
|
: pkgName;
|
||||||
// LICENSE
|
const res = await buildFiles(pkg, flatPkg, files[pkg]);
|
||||||
await copyLicense(pkg);
|
buildLicense(pkg, flatPkg);
|
||||||
}
|
buildReadme(pkg, flatPkg, res);
|
||||||
console.log('\x1b[32m%s\x1b[0m', 'updating codemirror themes list...');
|
}));
|
||||||
await fse.outputFile('edit/codemirror-themes.js', await generateThemeList());
|
console.log('Building CodeMirror theme list...');
|
||||||
|
buildThemeList();
|
||||||
}
|
}
|
||||||
|
|
||||||
async function generateThemeList() {
|
async function buildFiles(pkg, flatPkg, patterns) {
|
||||||
const themes = (await fse.readdir('vendor/codemirror/theme'))
|
const keepDirs = patterns.includes(KEEP_DIRECTORIES);
|
||||||
.filter(name => name.endsWith('.css'))
|
let fetched = '';
|
||||||
.map(name => name.replace('.css', ''))
|
let copied = '';
|
||||||
.sort();
|
for (let pattern of patterns) {
|
||||||
return endent`
|
if (pattern === KEEP_DIRECTORIES) continue;
|
||||||
|
pattern = pattern.replace('{VERSION}', require(`${pkg}/package.json`).version);
|
||||||
|
const [src, dest = !keepDirs && getFileName(src)] = pattern.split(/\s*->\s*/);
|
||||||
|
if (/^https?:/.test(src)) {
|
||||||
|
fse.outputFileSync(`vendor/${flatPkg}/${dest}`, await (await fetch(src)).text());
|
||||||
|
fetched += `* ${dest}: ${src}\n`;
|
||||||
|
} else {
|
||||||
|
const files = glob(`node_modules/${pkg}/${src}`);
|
||||||
|
if (!files.length) {
|
||||||
|
throw new Error(`Pattern ${src} matches no files`);
|
||||||
|
}
|
||||||
|
for (const file of files) {
|
||||||
|
fse.copySync(file, dest
|
||||||
|
? `vendor/${flatPkg}/${dest}`
|
||||||
|
: `vendor/${path.relative('node_modules', file).replace(pkg + '/', flatPkg + '/')}`);
|
||||||
|
const relSrc = path.relative(`node_modules/${pkg}`, file).replace(/\\/g, '/');
|
||||||
|
copied += dest && dest !== relSrc
|
||||||
|
? `* ${dest}: ${
|
||||||
|
keepDirs || getFileName(dest) !== getFileName(relSrc)
|
||||||
|
? relSrc
|
||||||
|
: relSrc.replace(/[^/]+$/, '*')
|
||||||
|
}\n`
|
||||||
|
: `* ${relSrc}\n`;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return {fetched, copied};
|
||||||
|
}
|
||||||
|
|
||||||
|
function buildLicense(pkg, flatPkg) {
|
||||||
|
const LICENSE = `vendor/${flatPkg}/LICENSE`;
|
||||||
|
if (!fs.existsSync(LICENSE)) {
|
||||||
|
const [src] = glob(`node_modules/${pkg}/LICEN[SC]E*`);
|
||||||
|
if (!src) throw new Error(`Cannot find license file for ${pkg}`);
|
||||||
|
fse.copySync(src, LICENSE);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function buildReadme(pkg, flatPkg, {fetched, copied}) {
|
||||||
|
const {name, version} = require(`${pkg}/package.json`);
|
||||||
|
fse.outputFileSync(`vendor/${flatPkg}/README.md`, [
|
||||||
|
`## ${name} v${version}`,
|
||||||
|
fetched && `Files downloaded from URL:\n${fetched}`,
|
||||||
|
copied && `Files copied from NPM (node_modules):\n${copied}`,
|
||||||
|
].filter(Boolean).join('\n\n'));
|
||||||
|
}
|
||||||
|
|
||||||
|
function buildThemeList() {
|
||||||
|
fse.outputFileSync('edit/codemirror-themes.js', deindent(`\
|
||||||
/* Do not edit. This file is auto-generated by build-vendor.js */
|
/* Do not edit. This file is auto-generated by build-vendor.js */
|
||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
/* exported CODEMIRROR_THEMES */
|
/* exported CODEMIRROR_THEMES */
|
||||||
const CODEMIRROR_THEMES = [
|
const CODEMIRROR_THEMES = [
|
||||||
${
|
${
|
||||||
themes.map(t => ` '${t.replace(/'/g, '\\$&')}',\n`).join('')
|
fs.readdirSync('vendor/codemirror/theme')
|
||||||
}];
|
.filter(name => name.endsWith('.css'))
|
||||||
` + '\n';
|
.map(name => name.replace('.css', ''))
|
||||||
}
|
.sort()
|
||||||
|
.map(t => ` '${t.replace(/'/g, '\\$&')}',`).join('\n')
|
||||||
async function copyLicense(pkg) {
|
|
||||||
try {
|
|
||||||
await fse.access(`vendor/${pkg}/LICENSE`);
|
|
||||||
return;
|
|
||||||
} catch (err) {
|
|
||||||
// pass
|
|
||||||
}
|
|
||||||
for (const file of await glob(`node_modules/${pkg}/LICEN[SC]E*`)) {
|
|
||||||
await fse.copy(file, `vendor/${pkg}/LICENSE`);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
throw new Error(`cannot find license file for ${pkg}`);
|
|
||||||
}
|
|
||||||
|
|
||||||
async function buildFiles(pkg, patterns) {
|
|
||||||
const fetchedFiles = [];
|
|
||||||
const copiedFiles = [];
|
|
||||||
for (let pattern of patterns) {
|
|
||||||
pattern = pattern.replace('{VERSION}', require(`${pkg}/package.json`).version);
|
|
||||||
const [src, dest] = pattern.split(/\s*→\s*/);
|
|
||||||
if (src.startsWith('http')) {
|
|
||||||
const content = await (await fetch(src)).text();
|
|
||||||
await fse.outputFile(`vendor/${pkg}/${dest}`, content);
|
|
||||||
fetchedFiles.push([src, dest]);
|
|
||||||
} else {
|
|
||||||
let dirty = false;
|
|
||||||
for (const file of await glob(`node_modules/${pkg}/${src}`)) {
|
|
||||||
if (dest) {
|
|
||||||
await fse.copy(file, `vendor/${pkg}/${dest}`);
|
|
||||||
} else {
|
|
||||||
await fse.copy(file, path.join('vendor', path.relative('node_modules', file)));
|
|
||||||
}
|
|
||||||
copiedFiles.push([path.relative(`node_modules/${pkg}`, file), dest]);
|
|
||||||
dirty = true;
|
|
||||||
}
|
|
||||||
if (!dirty) {
|
|
||||||
throw new Error(`Pattern ${src} matches no files`);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
];
|
||||||
return [fetchedFiles, copiedFiles];
|
`));
|
||||||
}
|
}
|
||||||
|
|
||||||
function generateReadme(lib, fetched, copied) {
|
function deindent(str) {
|
||||||
const pkg = require(`${lib}/package.json`);
|
const indent = str.match(/^\s*/)[0];
|
||||||
let txt = `## ${pkg.name} v${pkg.version}\n\n`;
|
return indent
|
||||||
if (fetched.length) {
|
? str.replace(new RegExp('^' + indent, 'gm'), '')
|
||||||
txt += `Following files are downloaded from HTTP:\n\n${generateList(fetched)}\n\n`;
|
: str;
|
||||||
}
|
|
||||||
if (copied.length) {
|
|
||||||
txt += `Following files are copied from npm (node_modules):\n\n${generateList(copied)}\n`;
|
|
||||||
}
|
|
||||||
return txt;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function generateList(list) {
|
function getFileName(path) {
|
||||||
return list.map(([src, dest]) => {
|
return path.split('/').pop();
|
||||||
if (dest) {
|
|
||||||
return `* ${dest}: ${src}`;
|
|
||||||
}
|
|
||||||
return `* ${src}`;
|
|
||||||
}).join('\n');
|
|
||||||
}
|
}
|
||||||
|
|
193
vendor/codemirror/README.md
vendored
193
vendor/codemirror/README.md
vendored
|
@ -1,99 +1,98 @@
|
||||||
## codemirror v5.63.3
|
## codemirror v5.63.3
|
||||||
|
|
||||||
Following files are copied from npm (node_modules):
|
Files copied from NPM (node_modules):
|
||||||
|
* addon/comment/comment.js
|
||||||
* addon\comment\comment.js
|
* addon/dialog
|
||||||
* addon\dialog
|
* addon/edit/closebrackets.js
|
||||||
* addon\edit\closebrackets.js
|
* addon/edit/matchbrackets.js
|
||||||
* addon\edit\matchbrackets.js
|
* addon/fold/brace-fold.js
|
||||||
* addon\fold\brace-fold.js
|
* addon/fold/comment-fold.js
|
||||||
* addon\fold\comment-fold.js
|
* addon/fold/foldcode.js
|
||||||
* addon\fold\foldcode.js
|
* addon/fold/foldgutter.css
|
||||||
* addon\fold\foldgutter.css
|
* addon/fold/foldgutter.js
|
||||||
* addon\fold\foldgutter.js
|
* addon/fold/indent-fold.js
|
||||||
* addon\fold\indent-fold.js
|
* addon/hint/css-hint.js
|
||||||
* addon\hint\css-hint.js
|
* addon/hint/show-hint.css
|
||||||
* addon\hint\show-hint.css
|
* addon/hint/show-hint.js
|
||||||
* addon\hint\show-hint.js
|
* addon/lint/css-lint.js
|
||||||
* addon\lint\css-lint.js
|
* addon/lint/json-lint.js
|
||||||
* addon\lint\json-lint.js
|
* addon/lint/lint.css
|
||||||
* addon\lint\lint.css
|
* addon/lint/lint.js
|
||||||
* addon\lint\lint.js
|
* addon/scroll/annotatescrollbar.js
|
||||||
* addon\scroll\annotatescrollbar.js
|
* addon/search/matchesonscrollbar.css
|
||||||
* addon\search\matchesonscrollbar.css
|
* addon/search/matchesonscrollbar.js
|
||||||
* addon\search\matchesonscrollbar.js
|
* addon/search/searchcursor.js
|
||||||
* addon\search\searchcursor.js
|
* addon/selection/active-line.js
|
||||||
* addon\selection\active-line.js
|
* keymap/emacs.js
|
||||||
* keymap\emacs.js
|
* keymap/sublime.js
|
||||||
* keymap\sublime.js
|
* keymap/vim.js
|
||||||
* keymap\vim.js
|
* lib/codemirror.css
|
||||||
* lib\codemirror.css
|
* lib/codemirror.js
|
||||||
* lib\codemirror.js
|
* mode/css
|
||||||
* mode\css
|
* mode/javascript
|
||||||
* mode\javascript
|
* mode/stylus
|
||||||
* mode\stylus
|
* theme/3024-day.css
|
||||||
* theme\3024-day.css
|
* theme/3024-night.css
|
||||||
* theme\3024-night.css
|
* theme/abbott.css
|
||||||
* theme\abbott.css
|
* theme/abcdef.css
|
||||||
* theme\abcdef.css
|
* theme/ambiance-mobile.css
|
||||||
* theme\ambiance-mobile.css
|
* theme/ambiance.css
|
||||||
* theme\ambiance.css
|
* theme/ayu-dark.css
|
||||||
* theme\ayu-dark.css
|
* theme/ayu-mirage.css
|
||||||
* theme\ayu-mirage.css
|
* theme/base16-dark.css
|
||||||
* theme\base16-dark.css
|
* theme/base16-light.css
|
||||||
* theme\base16-light.css
|
* theme/bespin.css
|
||||||
* theme\bespin.css
|
* theme/blackboard.css
|
||||||
* theme\blackboard.css
|
* theme/cobalt.css
|
||||||
* theme\cobalt.css
|
* theme/colorforth.css
|
||||||
* theme\colorforth.css
|
* theme/darcula.css
|
||||||
* theme\darcula.css
|
* theme/dracula.css
|
||||||
* theme\dracula.css
|
* theme/duotone-dark.css
|
||||||
* theme\duotone-dark.css
|
* theme/duotone-light.css
|
||||||
* theme\duotone-light.css
|
* theme/eclipse.css
|
||||||
* theme\eclipse.css
|
* theme/elegant.css
|
||||||
* theme\elegant.css
|
* theme/erlang-dark.css
|
||||||
* theme\erlang-dark.css
|
* theme/gruvbox-dark.css
|
||||||
* theme\gruvbox-dark.css
|
* theme/hopscotch.css
|
||||||
* theme\hopscotch.css
|
* theme/icecoder.css
|
||||||
* theme\icecoder.css
|
* theme/idea.css
|
||||||
* theme\idea.css
|
* theme/isotope.css
|
||||||
* theme\isotope.css
|
* theme/juejin.css
|
||||||
* theme\juejin.css
|
* theme/lesser-dark.css
|
||||||
* theme\lesser-dark.css
|
* theme/liquibyte.css
|
||||||
* theme\liquibyte.css
|
* theme/lucario.css
|
||||||
* theme\lucario.css
|
* theme/material-darker.css
|
||||||
* theme\material-darker.css
|
* theme/material-ocean.css
|
||||||
* theme\material-ocean.css
|
* theme/material-palenight.css
|
||||||
* theme\material-palenight.css
|
* theme/material.css
|
||||||
* theme\material.css
|
* theme/mbo.css
|
||||||
* theme\mbo.css
|
* theme/mdn-like.css
|
||||||
* theme\mdn-like.css
|
* theme/midnight.css
|
||||||
* theme\midnight.css
|
* theme/monokai.css
|
||||||
* theme\monokai.css
|
* theme/moxer.css
|
||||||
* theme\moxer.css
|
* theme/neat.css
|
||||||
* theme\neat.css
|
* theme/neo.css
|
||||||
* theme\neo.css
|
* theme/night.css
|
||||||
* theme\night.css
|
* theme/nord.css
|
||||||
* theme\nord.css
|
* theme/oceanic-next.css
|
||||||
* theme\oceanic-next.css
|
* theme/panda-syntax.css
|
||||||
* theme\panda-syntax.css
|
* theme/paraiso-dark.css
|
||||||
* theme\paraiso-dark.css
|
* theme/paraiso-light.css
|
||||||
* theme\paraiso-light.css
|
* theme/pastel-on-dark.css
|
||||||
* theme\pastel-on-dark.css
|
* theme/railscasts.css
|
||||||
* theme\railscasts.css
|
* theme/rubyblue.css
|
||||||
* theme\rubyblue.css
|
* theme/seti.css
|
||||||
* theme\seti.css
|
* theme/shadowfox.css
|
||||||
* theme\shadowfox.css
|
* theme/solarized.css
|
||||||
* theme\solarized.css
|
* theme/ssms.css
|
||||||
* theme\ssms.css
|
* theme/the-matrix.css
|
||||||
* theme\the-matrix.css
|
* theme/tomorrow-night-bright.css
|
||||||
* theme\tomorrow-night-bright.css
|
* theme/tomorrow-night-eighties.css
|
||||||
* theme\tomorrow-night-eighties.css
|
* theme/ttcn.css
|
||||||
* theme\ttcn.css
|
* theme/twilight.css
|
||||||
* theme\twilight.css
|
* theme/vibrant-ink.css
|
||||||
* theme\vibrant-ink.css
|
* theme/xq-dark.css
|
||||||
* theme\xq-dark.css
|
* theme/xq-light.css
|
||||||
* theme\xq-light.css
|
* theme/yeti.css
|
||||||
* theme\yeti.css
|
* theme/yonce.css
|
||||||
* theme\yonce.css
|
* theme/zenburn.css
|
||||||
* theme\zenburn.css
|
|
||||||
|
|
5
vendor/db-to-cloud/README.md
vendored
5
vendor/db-to-cloud/README.md
vendored
|
@ -1,5 +1,4 @@
|
||||||
## db-to-cloud v0.7.0
|
## db-to-cloud v0.7.0
|
||||||
|
|
||||||
Following files are copied from npm (node_modules):
|
Files copied from NPM (node_modules):
|
||||||
|
* db-to-cloud.min.js: dist/*
|
||||||
* db-to-cloud.min.js: dist\db-to-cloud.min.js
|
|
||||||
|
|
22
vendor/draggable-list/LICENSE
vendored
Normal file
22
vendor/draggable-list/LICENSE
vendored
Normal file
|
@ -0,0 +1,22 @@
|
||||||
|
The MIT License (MIT)
|
||||||
|
|
||||||
|
Copyright (c) 2021 eight
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
of this software and associated documentation files (the "Software"), to deal
|
||||||
|
in the Software without restriction, including without limitation the rights
|
||||||
|
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
copies of the Software, and to permit persons to whom the Software is
|
||||||
|
furnished to do so, subject to the following conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be included in all
|
||||||
|
copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
|
SOFTWARE.
|
||||||
|
|
4
vendor/draggable-list/README.md
vendored
Normal file
4
vendor/draggable-list/README.md
vendored
Normal file
|
@ -0,0 +1,4 @@
|
||||||
|
## @eight04/draggable-list v0.3.0
|
||||||
|
|
||||||
|
Files copied from NPM (node_modules):
|
||||||
|
* draggable-list.iife.min.js: dist/*
|
1
vendor/draggable-list/draggable-list.iife.min.js
vendored
Normal file
1
vendor/draggable-list/draggable-list.iife.min.js
vendored
Normal file
|
@ -0,0 +1 @@
|
||||||
|
var DraggableList=function(){"use strict";const t="draggable-list-transformed";return function(e,{bound:r,scrollContainer:n}={}){for(const t of e.children)t.draggable=!0;new MutationObserver((t=>{for(const e of t)for(const t of e.addedNodes)t.draggable=!0})).observe(e,{childList:!0});let a=null,o=0,s=0,l=null,d=[],i=null,c=!1,g=0;function f(t,r,n){const o={origin:t,startPos:a,currentPos:l,dragTarget:i};n&&Object.assign(o,n),e.dispatchEvent(new CustomEvent(r,{detail:o}))}e.addEventListener("dragstart",(t=>{if(t.target.parentNode!==e)return;i=t.target,c=!1;const r=n?n.scrollLeft:0,u=n?n.scrollTop:0;a={x:t.pageX+r,y:t.pageY+u},o=[...e.children].indexOf(t.target),s=o,l=a,d=[...e.children].map((t=>{const e=t.getBoundingClientRect();return{top:e.top+window.scrollY+u,bottom:e.bottom+window.scrollY+u}})),g=o+1<d.length?d[o+1].top-d[o].top:o>0?d[o].bottom-d[o-1].bottom:0,i.classList.add("draggable-list-target"),e.classList.add("draggable-list-dragging"),f(t,"d:dragstart")})),e.addEventListener("dragenter",(t=>{i&&(t.preventDefault(),f(t,"d:dragmove"))})),e.addEventListener("dragover",(a=>{if(!i)return;a.preventDefault();const c=n?n.scrollLeft:0,u=n?n.scrollTop:0,p={x:a.pageX+c,y:a.pageY+u},m=function(t,e,r,n){if(r<t[0].top&&n)return e;for(let n=0;n<e;n++)if(!(t[n].bottom<r))return n;if(r>t[t.length-1].bottom&&n)return e;for(let n=t.length-1;n>e;n--)if(!(t[n].top>r))return n;return e}(d,o,p.y,r);!function(e,r,n,a,o){function s(r,n,a,o){for(let s=n;s<=a;s++)r&&!e[s].classList.contains(t)?(e[s].classList.add(t),e[s].style.transform=o):!r&&e[s].classList.contains(t)&&(e[s].classList.remove(t),e[s].style="")}a>n?(s(!1,n,Math.min(r-1,a-1)),r<e.length-1&&s(!0,Math.max(n+1,r+1),a,"translateY(".concat(-o,"px)"))):(s(!1,Math.max(r+1,a+1),n),r>0&&s(!0,a,Math.min(n-1,r-1),"translateY(".concat(o,"px)")))}(e.children,o,s,m,g),s=m,l=p,f(a,"d:dragmove")})),document.addEventListener("dragend",(r=>{if(i){for(const r of e.children)r.classList.remove(t),r.style="";i.classList.remove("draggable-list-target"),e.classList.remove("draggable-list-dragging"),f(r,"d:dragend",{originalIndex:o,spliceIndex:s,insertBefore:s<o?e.children[s]:e.children[s+1],dropped:c}),i=null}})),e.addEventListener("drop",(t=>{i&&(c=!0,t.preventDefault())}))}}();
|
5
vendor/jsonlint/README.md
vendored
5
vendor/jsonlint/README.md
vendored
|
@ -1,6 +1,5 @@
|
||||||
## jsonlint v1.6.3
|
## jsonlint v1.6.3
|
||||||
|
|
||||||
Following files are copied from npm (node_modules):
|
Files copied from NPM (node_modules):
|
||||||
|
* jsonlint.js: lib/*
|
||||||
* jsonlint.js: lib\jsonlint.js
|
|
||||||
* LICENSE: README.md
|
* LICENSE: README.md
|
||||||
|
|
5
vendor/less-bundle/README.md
vendored
5
vendor/less-bundle/README.md
vendored
|
@ -1,5 +1,4 @@
|
||||||
## less-bundle v0.1.0
|
## less-bundle v0.1.0
|
||||||
|
|
||||||
Following files are copied from npm (node_modules):
|
Files copied from NPM (node_modules):
|
||||||
|
* less.min.js: dist/*
|
||||||
* less.min.js: dist\less.min.js
|
|
||||||
|
|
3
vendor/lz-string-unsafe/README.md
vendored
3
vendor/lz-string-unsafe/README.md
vendored
|
@ -1,5 +1,4 @@
|
||||||
## lz-string-unsafe v1.4.4-fork-1
|
## lz-string-unsafe v1.4.4-fork-1
|
||||||
|
|
||||||
Following files are copied from npm (node_modules):
|
Files copied from NPM (node_modules):
|
||||||
|
|
||||||
* lz-string-unsafe.min.js
|
* lz-string-unsafe.min.js
|
||||||
|
|
7
vendor/stylelint-bundle/README.md
vendored
7
vendor/stylelint-bundle/README.md
vendored
|
@ -1,9 +1,8 @@
|
||||||
## stylelint-bundle v13.8.0
|
## stylelint-bundle v13.8.0
|
||||||
|
|
||||||
Following files are downloaded from HTTP:
|
Files downloaded from URL:
|
||||||
|
|
||||||
* LICENSE: https://github.com/stylelint/stylelint/raw/13.8.0/LICENSE
|
* LICENSE: https://github.com/stylelint/stylelint/raw/13.8.0/LICENSE
|
||||||
|
|
||||||
Following files are copied from npm (node_modules):
|
|
||||||
|
|
||||||
* stylelint-bundle.min.js: dist\stylelint-bundle.min.js
|
Files copied from NPM (node_modules):
|
||||||
|
* stylelint-bundle.min.js: dist/*
|
||||||
|
|
5
vendor/stylus-lang-bundle/README.md
vendored
5
vendor/stylus-lang-bundle/README.md
vendored
|
@ -1,5 +1,4 @@
|
||||||
## stylus-lang-bundle v0.54.7
|
## stylus-lang-bundle v0.54.7
|
||||||
|
|
||||||
Following files are copied from npm (node_modules):
|
Files copied from NPM (node_modules):
|
||||||
|
* stylus-renderer.min.js: dist/*
|
||||||
* stylus-renderer.min.js: dist\stylus-renderer.min.js
|
|
||||||
|
|
5
vendor/usercss-meta/README.md
vendored
5
vendor/usercss-meta/README.md
vendored
|
@ -1,5 +1,4 @@
|
||||||
## usercss-meta v0.12.0
|
## usercss-meta v0.12.0
|
||||||
|
|
||||||
Following files are copied from npm (node_modules):
|
Files copied from NPM (node_modules):
|
||||||
|
* usercss-meta.min.js: dist/*
|
||||||
* usercss-meta.min.js: dist\usercss-meta.min.js
|
|
||||||
|
|
5
vendor/webext-launch-web-auth-flow/README.md
vendored
5
vendor/webext-launch-web-auth-flow/README.md
vendored
|
@ -1,5 +1,4 @@
|
||||||
## webext-launch-web-auth-flow v0.1.1
|
## webext-launch-web-auth-flow v0.1.1
|
||||||
|
|
||||||
Following files are copied from npm (node_modules):
|
Files copied from NPM (node_modules):
|
||||||
|
* webext-launch-web-auth-flow.min.js: dist/*
|
||||||
* webext-launch-web-auth-flow.min.js: dist\webext-launch-web-auth-flow.min.js
|
|
||||||
|
|
Loading…
Reference in New Issue
Block a user