New warehouse

This commit is contained in:
2025-10-24 00:09:45 +08:00
commit ac07e27908
75 changed files with 26814 additions and 0 deletions

83
web/static/lib/README.md Normal file
View File

@@ -0,0 +1,83 @@
# ColorMode 模块WIP
开箱即用的主题切换(深色/浅色/自定义)模块,具有自动数据持久性。
**基本使用**
```js
layui.use(['colorMode'], function () {
var colorMode = layui.colorMode
var theme = colorMode.init()
}
);
```
**配置**
模块仅处理 DOM 属性更改,以便在 CSS 中应用正确的选择器,不会处理实际的样式,主题或 CSS。
默认情况下,使用 auto 模式(与用户的浏览器首选项匹配),将类 dark 应用于 html 标签时启用深色模式,返回一个对象,用来获取和改变主题。
```js
var theme = colorMode.init()
theme.mode() // 'dark' | 'light'
theme.setMode('dark') // 设置为深色模式并持久化到 localstorage
theme.setMode('auto') // 设置为 auto 模式
```
也可以自定义以使其适用于大多数场景
```js
var theme = colorMode.init({
selector: 'body',
attribute: 'theme-mode',
initialValue: 'light',
modes: {
auto: '',
light: 'light',
dark: 'dark',
contrast: 'dark contrast',
},
storage: localStorage,
storageKey: 'xxx-theme-mode',
disableTransition: true,
})
```
如果上述配置仍不能满足您的需求,可以使用 onChanged 选项完全控制处理更新的方式
```js
var theme = colorMode.init({
onChanged: function(mode, defaultHandler){
// 自定义更新方式
}
})
```
**API**
```ts
/**
* @typedef {object} initOptions
* @prop {string} [selector='html'] - 应用于目标元素的 CSS 选择器
* @prop {string} [attribute='class'] - 应用于目标元素的 HTML 属性
* @prop {string} [initialValue='auto'] - 初始颜色模式
* @prop {Object.<string, string>} [modes]- 颜色模式。value 为添加到 HTML 属性上的值
* @prop {(mode: string, defaultHandler: () => void) => void} [onChanged] - 用于处理更新的自定义处理程序指定时默认行为将被覆盖。mode 为颜色模式defaultHandler 为默认处理程序
* @prop {Storage} [storage=localStorage] - 将数据持久化到 localStorage/sessionStorage 的键。传递 `null` 以禁用持久性
* @prop {string | null} [storageKey='color-scheme'] - 持久化使用的 key
* @prop {boolean} [disableTransition=true] - 禁用切换时的过渡 {@link https://paco.me/writing/disable-theme-transitions}
*
*/
/**
*
* @param {initOptions} options
* @returns {{ mode: () => string; setMode: (mode: string) => void;}}
*/
colorMode.init(options)
```

191
web/static/lib/colorMode.js Executable file
View File

@@ -0,0 +1,191 @@
/**
* WIP
* 移植自 https://github.com/vueuse/vueuse/tree/main/packages/core/useColorMode
*/
// @ts-ignore
layui.define(['jquery'], function (exports) {
'use strict';
/** @type {jQuery}*/
var $ = layui.jquery;
var MOD_NAME = 'colorMode';
var defaultWindow = window;
var document = defaultWindow.document;
var colorMode = {
/**
* @typedef {object} initOptions
* @prop {string} [selector="html"] - 应用于目标元素的 CSS 选择器
* @prop {string} [attribute="class"] - 应用于目标元素的 HTML 属性
* @prop {string} [initialValue='auto'] - 初始颜色模式
* @prop {Object.<string, string>} [modes]- 颜色模式。value 为添加到 HTML 属性上的值
* @prop {(mode: string, defaultHandler: (window?: Window) => void) => void} [onChanged] - 用于处理更新的自定义处理程序,指定时,默认行为将被覆盖。
* @prop {Storage} [storage=localStorage] - 将数据持久化到 localStorage/sessionStorage 的键。传递 `null` 以禁用持久性
* @prop {string | null} [storageKey='color-scheme'] - 持久化使用的 key
* @prop {boolean} [disableTransition=true] - 禁用切换时的过渡 {@link https://paco.me/writing/disable-theme-transitions}
*
*/
/**
*
* @param {initOptions} options
* @returns {{mode: () => string; setMode: (mode: string, window?: Window) => void; }}
*/
init: function (options) {
var defaults = {
selector: 'html',
attribute: 'class',
initialValue: 'auto',
modes: {
auto: '',
light: 'light',
dark: 'dark',
},
storage: localStorage,
storageKey: 'color-scheme',
disableTransition: true,
};
var opts = $.extend(true, {}, defaults, options);
// 当前颜色模式
var state;
// 系统颜色模式
var system;
// 初始化 storage
var store =
opts.storageKey == null
? opts.initialValue
: (function () {
var v = opts.storage.getItem(opts.storageKey);
if (!v) {
opts.storage.setItem(opts.storageKey, opts.initialValue);
return opts.initialValue;
}
return v;
})();
/**
* 更新 HTML 属性值
* @param {String} selector
* @param {String} attribute
* @param {String} value
* @param {Window} win
*/
var updateHTMLAttrs = function (selector, attribute, value, win) {
win = win || defaultWindow;
var document = win.document;
var el = typeof selector === 'string' ? document.querySelector(selector) : undefined;
if (!el) return;
/**@type HTMLStyleElement */
var style;
if (opts.disableTransition) {
style = document.createElement('style');
style.appendChild(
document.createTextNode(
'*,*::before,*::after{-webkit-transition:none!important;-moz-transition:none!important;-o-transition:none!important;-ms-transition:none!important;transition:none!important}'
)
);
document.head.appendChild(style);
}
if (attribute === 'class') {
var current = value.split(/\s/g);
$.each(opts.modes, function (_, modeval) {
$.each((modeval || '').split(/\s/g), function (_, v) {
if (!v) return;
if (current.indexOf(v) !== -1) {
el.classList.add(v);
} else {
el.classList.remove(v);
}
});
});
} else {
el.setAttribute(attribute, value);
}
if (opts.disableTransition) {
// 调用 getComputedStyle 强制浏览器重绘
// @ts-expect-error 未使用的变量
var _ = window.getComputedStyle(style).opacity;
document.head.removeChild(style);
}
};
/**
* 更新状态
* @param {String} mode - 颜色模式
*/
var updateState = function (mode) {
store = opts.storageKey == null ? mode : opts.storage.getItem(opts.storageKey);
state = store === 'auto' ? system : store;
};
var prefersColorScheme = function () {
var isSupported = window && 'matchMedia' in window && typeof window.matchMedia === 'function';
if (!isSupported) {
system = 'light';
onChanged(system);
return;
}
var darkThemeMediaQuery = window.matchMedia('(prefers-color-scheme: dark)');
var update = function () {
var preferredDark = darkThemeMediaQuery.matches;
system = preferredDark ? 'dark' : 'light';
onChanged(system);
};
update();
if ('addEventListener' in darkThemeMediaQuery) {
darkThemeMediaQuery.addEventListener('change', update);
} else {
// @ts-ignore 已弃用
darkThemeMediaQuery.addListener(update);
}
};
prefersColorScheme();
function defaultOnChanged(win) {
updateHTMLAttrs(opts.selector, opts.attribute, opts.modes[state], win);
}
function onChanged(mode, win) {
updateState(mode);
if (opts.onChanged) {
opts.onChanged(state, defaultOnChanged);
} else {
defaultOnChanged(win);
}
}
return {
setMode: function (mode, win) {
if (opts.storageKey) {
opts.storage.setItem(opts.storageKey, mode);
}
onChanged(mode, win);
},
mode: function () {
return state;
},
};
},
addStyle: function (id, cssStr) {
var el = /** @type {HTMLStyleElement} */ (document.getElementById(id) || document.createElement('style'));
if (!el.isConnected) {
el.type = 'text/css';
el.id = id;
document.head.appendChild(el);
}
el.textContent = cssStr;
},
};
exports(MOD_NAME, colorMode);
});

View File

@@ -0,0 +1,317 @@
.layer-drawer.layui-layer {
border-radius: 0 !important;
overflow: auto;
}
.layer-drawer.layui-layer.position-absolute {
position: absolute !important;
}
.layer-drawer-anim,
.layer-drawer-anim.layui-anim {
-webkit-animation-duration: .3s;
animation-duration: .3s;
-webkit-animation-timing-function: cubic-bezier(0.7, 0.3, 0.1, 1);
animation-timing-function: cubic-bezier(0.7, 0.3, 0.1, 1);
}
/* right to left */
@keyframes layer-rl {
from {
-webkit-transform: translate3d(100%, 0, 0);
-ms-transform: translate3d(100%, 0, 0);
transform: translate3d(100%, 0, 0);
opacity: 1;
}
to {
-webkit-transform: translate3d(0, 0, 0);
-ms-transform: translate3d(0, 0, 0);
transform: translate3d(0, 0, 0);
opacity: 1;
}
}
@-webkit-keyframes layer-rl {
from {
-webkit-transform: translate3d(100%, 0, 0);
-ms-transform: translate3d(100%, 0, 0);
transform: translate3d(100%, 0, 0);
opacity: 1;
}
to {
-webkit-transform: translate3d(0, 0, 0);
-ms-transform: translate3d(0, 0, 0);
transform: translate3d(0, 0, 0);
opacity: 1;
}
}
.layer-anim-rl {
-webkit-animation-name: layer-rl;
animation-name: layer-rl;
}
/* right to left close */
@keyframes layer-rl-close {
from {
-webkit-transform: translate3d(0, 0, 0);
-ms-transform: translate3d(0, 0, 0);
transform: translate3d(0, 0, 0);
}
to {
-webkit-transform: translate3d(100%, 0, 0);
-ms-transform: translate3d(100%, 0, 0);
transform: translate3d(100%, 0, 0);
}
}
@-webkit-keyframes layer-rl-close {
from {
-webkit-transform: translate3d(0, 0, 0);
-ms-transform: translate3d(0, 0, 0);
transform: translate3d(0, 0, 0);
}
to {
-webkit-transform: translate3d(100%, 0, 0);
-ms-transform: translate3d(100%, 0, 0);
transform: translate3d(100%, 0, 0);
}
}
.layer-anim-rl-close,
.layer-anim-rl.layer-anim-close {
-webkit-animation-name: layer-rl-close;
animation-name: layer-rl-close;
}
/* left to right */
@-webkit-keyframes layer-lr {
from {
-webkit-transform: translate3d(0, 0, 0);
-ms-transform: translate3d(0, 0, 0);
transform: translate3d(0, 0, 0);
opacity: 1
}
to {
-webkit-transform: translate3d(-100%, 0, 0);
-ms-transform: translate3d(-100%, 0, 0);
transform: translate3d(-100%, 0, 0);
opacity: 1
}
}
@keyframes layer-lr {
from {
-webkit-transform: translate3d(-100%, 0, 0);
-ms-transform: translate3d(-100%, 0, 0);
transform: translate3d(-100%, 0, 0);
opacity: 1
}
to {
-webkit-transform: translate3d(0, 0, 0);
-ms-transform: translate3d(0, 0, 0);
transform: translate3d(0, 0, 0);
opacity: 1
}
}
.layer-anim-lr {
-webkit-animation-name: layer-lr;
animation-name: layer-lr
}
/* left to right close */
@-webkit-keyframes layer-lr-close {
from {
-webkit-transform: translate3d(0, 0, 0);
-ms-transform: translate3d(0, 0, 0);
transform: translate3d(0, 0, 0);
}
to {
-webkit-transform: translate3d(-100%, 0, 0);
-ms-transform: translate3d(-100%, 0, 0);
transform: translate3d(-100%, 0, 0);
}
}
@keyframes layer-lr-close {
from {
-webkit-transform: translate3d(0, 0, 0);
-ms-transform: translate3d(0, 0, 0);
transform: translate3d(0, 0, 0);
}
to {
-webkit-transform: translate3d(-100%, 0, 0);
-ms-transform: translate3d(-100%, 0, 0);
transform: translate3d(-100%, 0, 0);
}
}
.layer-anim-lr-close,
.layer-anim-lr.layer-anim-close {
-webkit-animation-name: layer-lr-close;
animation-name: layer-lr-close
}
/* top to bottom */
@-webkit-keyframes layer-tb {
from {
-webkit-transform: translate3d(0, -100%, 0);
-ms-transform: translate3d(0, -100%, 0);
transform: translate3d(0, -100%, 0);
opacity: 1;
animation-timing-function: cubic-bezier(0.7, 0.3, 0.1, 1);
}
to {
-webkit-transform: translate3d(0, 0, 0);
-ms-transform: translate3d(0, 0, 0);
transform: translate3d(0, 0, 0);
opacity: 1;
animation-timing-function: cubic-bezier(0.7, 0.3, 0.1, 1);
}
}
@keyframes layer-tb {
from {
-webkit-transform: translate3d(0, -100%, 0);
-ms-transform: translate3d(0, -100%, 0);
transform: translate3d(0, -100%, 0);
opacity: 1;
animation-timing-function: cubic-bezier(0.7, 0.3, 0.1, 1);
}
to {
-webkit-transform: translate3d(0, 0, 0);
-ms-transform: translate3d(0, 0, 0);
transform: translate3d(0, 0, 0);
opacity: 1;
animation-timing-function: cubic-bezier(0.7, 0.3, 0.1, 1);
}
}
.layer-anim-tb {
-webkit-animation-name: layer-tb;
animation-name: layer-tb
}
/* top to bottom close */
@-webkit-keyframes layer-tb-close {
from {
-webkit-transform: translate3d(0, 0, 0);
-ms-transform: translate3d(0, 0, 0);
transform: translate3d(0, 0, 0);
}
to {
-webkit-transform: translate3d(0, -100%, 0);
-ms-transform: translate3d(0, -100%, 0);
transform: translate3d(0, -100%, 0);
}
}
@keyframes layer-tb-close {
from {
-webkit-transform: translate3d(0, 0, 0);
-ms-transform: translate3d(0, 0, 0);
transform: translate3d(0, 0, 0);
}
to {
-webkit-transform: translate3d(0, -100%, 0);
-ms-transform: translate3d(0, -100%, 0);
transform: translate3d(0, -100%, 0);
}
}
.layer-anim-tb-close,
.layer-anim-tb.layer-anim-close {
-webkit-animation-name: layer-tb-close;
animation-name: layer-tb-close
}
/* bottom to top */
@-webkit-keyframes layer-bt {
from {
-webkit-transform: translate3d(0, 100%, 0);
-ms-transform: translate3d(0, 100%, 0);
transform: translate3d(0, 100%, 0);
opacity: 1
}
to {
-webkit-transform: translate3d(0, 0, 0);
-ms-transform: translate3d(0, 0, 0);
transform: translate3d(0, 0, 0);
opacity: 1
}
}
@keyframes layer-bt {
from {
-webkit-transform: translate3d(0, 100%, 0);
-ms-transform: translate3d(0, 100%, 0);
transform: translate3d(0, 100%, 0);
opacity: 1
}
to {
-webkit-transform: translate3d(0, 0, 0);
-ms-transform: translate3d(0, 0, 0);
transform: translate3d(0, 0, 0);
opacity: 1
}
}
.layer-anim-bt {
-webkit-animation-name: layer-bt;
animation-name: layer-bt
}
/* bottom to top close */
@-webkit-keyframes layer-bt-close {
from {
-webkit-transform: translate3d(0, 0, 0);
-ms-transform: translate3d(0, 0, 0);
transform: translate3d(0, 0, 0);
}
to {
-webkit-transform: translate3d(0, 100%, 0);
-ms-transform: translate3d(0, 100%, 0);
transform: translate3d(0, 100%, 0);
}
}
@keyframes layer-bt-close {
from {
-webkit-transform: translate3d(0, 0, 0);
-ms-transform: translate3d(0, 0, 0);
transform: translate3d(0, 0, 0);
}
to {
-webkit-transform: translate3d(0, 100%, 0);
-ms-transform: translate3d(0, 100%, 0);
transform: translate3d(0, 100%, 0);
}
}
.layer-anim-bt-close,
.layer-anim-bt.layer-anim-close {
-webkit-animation-name: layer-bt-close;
animation-name: layer-bt-close
}

200
web/static/lib/drawer/drawer.js Executable file
View File

@@ -0,0 +1,200 @@
/**
* 抽屉模块
*/
layui.define(['jquery', 'layer'], function (exports) {
('use strict');
var MOD_NAME = 'drawer';
var $ = layui.jquery;
var layer = layui.layer;
layui.link(layui.cache.base + 'drawer/drawer.css');
var drawer = new (function () {
this.open = function (option) {
return layerDrawer(option);
};
this.title = layer.title;
this.style = layer.style;
this.close = layer.close;
this.closeAll = layer.closeAll;
})();
/**
*
* 封装 layer.open
*
* @param {object} option, `type`, `anim`, `move`, `fixed`, `skin`,`maxWidth`, `maxHeight`, `moveOut`, `moveEnd` 不可用,其它参数和 layer.open 一致, 新增 `iframe`和 `url`参数
* @returns {number} 原生 layer 的 index
*/
function layerDrawer(option) {
var opt = normalizeOption(option);
if (opt.target) appendToTarget(opt);
if (opt.url) loadFragment(opt);
if (opt.shade) {
$('<style/>')
.attr('id', 'layer-drawer')
.html('.layui-layer-shade{opacity: 0;transition: opacity .35s cubic-bezier(0.34, 0.69, 0.1, 1);}') // fadeIn
.appendTo('head');
option.end = Aspect(option.end, undefined, function (layero, index) {
$('#layer-drawer').remove();
});
}
return layer.open(opt);
}
/**
* 加载 HTML 片段到 layer content
* @param {object} option 设置选项
*/
function loadFragment(option) {
option.success = Aspect(option.success, function (layero) {
$.ajax({
url: option.url,
dataType: 'html',
success: function (result) {
layero.children('.layui-layer-content').html(result);
},
});
});
}
/**
*将 layer 附加到指定节点
* @param {object} opt 设置选项
*/
function appendToTarget(opt) {
var targetDOM = $(opt.target);
var contentDOM = opt.content;
contentDOM.appendTo(targetDOM);
opt.skin = getDrawerAnimationClass(opt.offset, true);
opt.offset = calcOffset(opt.offset, opt.area, targetDOM);
// 处理关闭后偶现 DOM 仍显示的问题
opt.end = Aspect(opt.end, function () {
contentDOM.css('display', 'none');
});
if (opt.shade) {
opt.success = Aspect(opt.success, function (layero, index) {
var shadeDOM = $('#layui-layer-shade' + index);
shadeDOM.css('position', 'absolute');
shadeDOM.appendTo(layero.parent());
});
}
}
/**
* 规范化 layer.open 选项
* @param {object} option layer.open 的选项
* @returns 规范化后的选项
*/
function normalizeOption(option) {
option.type = option.iframe ? 2 : 1;
option.anim = -1;
option.move = false;
option.fixed = true;
option.content = option.iframe ? option.iframe : option.content;
if (option.offset === undefined) option.offset = 'r';
option.area = calcDrawerArea(option.offset, option.area);
option.skin = getDrawerAnimationClass(option.offset);
if (option.title === undefined) option.title = false;
if (option.closeBtn === undefined) option.closeBtn = false;
if (option.shade === undefined) option.shade = 0.3;
if (option.shadeClose === undefined) option.shadeClose = true;
if (option.resize === undefined) option.resize = false;
if (option.success === undefined) option.success = function () {}; // 处理遮罩需要
if (option.end === undefined) option.end = function () {};
return option;
}
/**
* 计算抽屉宽高
* @param {string} offset 抽屉方向 l = 左, r = 右, t = 上, b = 下
* @param {string[] | string} drawerArea 抽屉大小,字符串数组格式[width, height]["200px","100%"],字符串格式:"30%" "200px"。
* @returns{string[]} 抽屉宽高数组
*/
function calcDrawerArea(offset, drawerArea) {
if (drawerArea instanceof Array) {
return drawerArea;
}
drawerArea = drawerArea === undefined || drawerArea === 'auto' ? '30%' : drawerArea;
if (offset === 'l' || offset === 'r') {
return [drawerArea, '100%'];
} else if (offset === 't' || offset === 'b') {
return ['100%', drawerArea];
}
}
/**
* 获取抽屉动画类,指定挂载容器时需要设置绝对定位
* @param {string} offset 抽屉方向 l = 左, r = 右, t = 上, b = 下
* @param {boolean} [isAbsolute] 是否是绝对定位
* @returns {string} 抽屉入场动画类
*/
function getDrawerAnimationClass(offset, isAbsolute) {
var prefixClass = 'layer-drawer layer-drawer-anim layui-anim layer-anim-';
var suffix = 'rl';
if (offset === 'l') {
suffix = 'lr';
} else if (offset === 'r') {
suffix = 'rl';
} else if (offset === 't') {
suffix = 'tb';
} else if (offset === 'b') {
suffix = 'bt';
}
return prefixClass + suffix + (isAbsolute ? ' position-absolute ' : '');
}
/**
* 指定挂载容器重新计算 offset
*
* layer 源码中使用窗口宽高计算位置,所以此
* @param {string} offset 位置
* @param {string | string[]} area 范围大小
* @param {*} targetEl 挂载节点
* @returns 包含抽屉位置信息的数组,[top, left]
*/
function calcOffset(offset, area, targetEl) {
// https://gitee.com/layui/layui/blob/main/src/modules/layer.js#L560
if (offset === undefined || offset === 'l' || offset === 't') {
offset = 'lt';
} else if (offset === 'r') {
// https://gitee.com/layui/layui/blob/main/src/modules/layer.js#L554
area = area instanceof Array ? area[0] : area;
var left = /%$/.test(area)
? targetEl.innerWidth() * (1 - window.parseFloat(area) / 100)
: targetEl.innerWidth() - window.parseFloat(area);
offset = ['0', left];
} else if (offset === 'b') {
area = area instanceof Array ? area[1] : area;
var top = /%$/.test(area)
? targetEl.innerHeight() * (1 - window.parseFloat(area) / 100)
: targetEl.innerHeight() - window.parseFloat(area);
offset = [top, '0'];
}
return offset;
}
/**
* 简易的切面
* @param {Function} target 被通知的对象,原函数
* @param {Function | undefined} [before] 前置通知
* @param {Function | undefined} [after] 后置通知
* @returns 代理函数
*/
function Aspect(target, before, after) {
function proxyFunc() {
if (before && typeof before === 'function') {
before.apply(this, arguments);
}
target.apply(this, arguments);
if (after && typeof after === 'function') {
after.apply(this, arguments);
}
}
return proxyFunc;
}
exports(MOD_NAME, drawer);
});

142
web/static/lib/include.js Executable file
View File

@@ -0,0 +1,142 @@
/**
* @typedef {object} IncludeFile
*
* @prop {boolean} ok
* @prop {number} status
* @prop {string} html
*/
/** @type {Map<string,IncludeFile | Promise<IncludeFile>>} */
const includeFiles = new Map();
/**
*
* @param {string} src
* @param {'cors' | 'no-cors' | 'same-origin'} [mode='cors']
*
* @returns {Promise<IncludeFile>}
*/
export function requestInclude(src, mode = 'cors'){
const prev = includeFiles.get(src);
if (prev !== undefined) {
return Promise.resolve(prev);
}
const fileDataPromise = fetch(src, { mode: mode }).then(async response => {
const res = {
ok: response.ok,
status: response.status,
html: await response.text()
};
includeFiles.set(src, res);
return res;
});
includeFiles.set(src, fileDataPromise);
return fileDataPromise;
}
class HtmlImport extends HTMLElement {
constructor () {
super();
}
static get observedAttributes () {
return ['src', 'mode', 'allow-scripts'];
}
get src() {
return this.getAttribute('src') || '';
}
set src(value) {
this.setAttribute('src', value);
}
get mode() {
return this.getAttribute('mode') || 'cors';
}
set mode(value) {
this.setAttribute('mode', value);
}
get allowScripts() {
return this.hasAttribute('allow-scripts');
}
set allowScripts(value) {
this.toggleAttribute('allow-scripts', value);
}
/**
* 执行 innerHTML 中的 <script></script>
* @param {HTMLScriptElement} scripts
*/
async executeScript(scripts) {
const execQueue = function (script) {
const newScript = document.createElement('script');
[...script.attributes].forEach(attr => newScript.setAttribute(attr.name, attr.value));
newScript.textContent = script.textContent;
script.parentNode && script.parentNode.replaceChild(newScript, script);
return script.src ? new Promise((resolve) => {
newScript.async = false;
newScript.addEventListener('load', e => resolve(e));
newScript.addEventListener('error', e => resolve(e));
}) : Promise.resolve();
};
// 按 <script> 顺序执行,确保上下文关联
for (const script of scripts) {
await execQueue(script);
// console.log(`${script.src||script} loaded`, Date.now());
}
}
async handleSrcChange() {
try {
const src = this.src;
const file = await requestInclude(src, this.mode);
if (src !== this.src) {
return;
}
if (!file.ok) {
this.emit('error', { detail: { status: file.status } });
return;
}
this.innerHTML = file.html;
if (this.allowScripts) {
await this.executeScript(this.querySelectorAll('script'));
}
this.emit('load');
} catch {
this.emit('error', { detail: { status: -1 } });
}
}
attributeChangedCallback (name) {
if (name == 'src') {
this.handleSrcChange();
}
}
emit(name, options) {
const event = new CustomEvent(name, {
bubbles: true,
cancelable: false,
composed: true,
detail: {},
...options
});
this.dispatchEvent(event);
return event;
}
}
if (!customElements.get('wc-include')) {
customElements.define('wc-include', HtmlImport);
}

11360
web/static/lib/less.js Executable file

File diff suppressed because it is too large Load Diff