-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathComponent.js
More file actions
114 lines (110 loc) · 4.85 KB
/
Component.js
File metadata and controls
114 lines (110 loc) · 4.85 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
import { asyncLoadResByUrl, setResource, waitResource } from "./loadResources.js";
const mcComponents = {};
setResource("MCComponent", mcComponents);
const sleep = ms => new Promise(s => setTimeout(s, ms));
class MCComponent extends HTMLElement {
static setBorderAndWaitImg(uri, styleSelector = "." + uri, styleDeclarations = {}) {
if (!("preloadStyleRules" in this)) this.preloadStyleRules = [];
if (!uri.startsWith("mc-ui-")) uri = "mc-ui-" + uri + "-img";
const keepCenter = "keepCenter" in styleDeclarations? styleDeclarations.keepCenter: true;
delete styleDeclarations.keepCenter;
styleDeclarations = {
...styleDeclarations,
"border-color": "transparent",
"border-style": "solid",
"border-image": `var(--${uri})
var(--${uri}-border-top)
var(--${uri}-border-right)
var(--${uri}-border-bottom)
var(--${uri}-border-left)
${keepCenter? "fill": ""} stretch`,
};
let rule = styleSelector + " {\n"
+ Object.entries(styleDeclarations).map(([property, value]) => `${property}: ${value};`).join("\n")
+ "\n}";
this.preloadStyleRules.push(rule);
return waitResource(uri);
};
static setBackgroundAndWaitImg(uri, styleSelector = "." + uri, styleDeclarations = {}) {
if (!("preloadStyleRules" in this)) this.preloadStyleRules = [];
if (!uri.startsWith("mc-ui-")) uri = "mc-ui-" + uri + "-img";
const setIfNotExist = obj => Object.entries(obj).forEach(([property, value]) =>
styleDeclarations[property] = styleDeclarations[property] || value);
setIfNotExist({
"background-image": `var(--${uri})`,
"background-size": "cover",
"background-repeat": "no-repeat",
});
let rule = styleSelector + " {\n"
+ Object.entries(styleDeclarations).map(([property, value]) => `${property}: ${value};`).join("\n")
+ "\n}";
this.preloadStyleRules.push(rule);
return waitResource(uri);
};
static genTemplate(text, id = text) {
if (mcComponents[id]) return mcComponents[id];
let template = document.createElement("template");
template.innerHTML = (this.preloadStyleRules
? "<style> " + this.preloadStyleRules.join("\n") + "</style>"
: "") + text;
mcComponents[id] = template;
return template;
};
static get templateUrlPrefix() { return "./" };
static get templateUrlFilename() { return this.name; };
static get templateUrl() { return this.templateUrlPrefix + this.templateUrlFilename + ".html"; };
static asyncLoadTemplateByUrl(url = this.templateUrl) {
return asyncLoadResByUrl(url).then(text => {
if (typeof text !== "string") return text;
let tmp = this.genTemplate(text, url);
setResource(url, tmp);
return tmp;
});
};
static get componentName() { return this.name.replace(/([A-Z]+|[a-z])([A-Z])/g, "$1-$2").toLowerCase(); };
static define(componentName = this.componentName) {
if (!componentName) throw "Component registration failed: Missing componentName.";
return customElements.define(componentName, this);
};
static asyncLoadAndDefine() {
return this.asyncLoadTemplateByUrl().then(_ => this.define());
};
static getTemplateByUrl(url = this.templateUrl) {
return mcComponents[url];
};
get template() { return this.constructor.getTemplateByUrl(); };
appendTemplate(template = this.template) {
return template.content
? this.shadowRoot.appendChild(template.content.cloneNode(true))
: null;
};
constructor() {
super();
if (new.target.name === "MCComponent")
throw "Class 'MCComponent' cannot be instantiated!";
this.attachShadow({mode: 'open'});
if (this.template) this.appendTemplate();
};
async connectedCallback(...args) { if (this.onConnected) { await sleep(0); this.onConnected(...args); } };
async disconnectedCallback(...args) { if (this.onDisconnected) { await sleep(0); this.onDisconnected(...args); } };
async adoptedCallback(...args) { if (this.onAdopted) { await sleep(0); this.onAdopted(...args); } };
async attributeChangedCallback(...args) { if (args[1] !== args[2] && this.onAttrChanged) { await sleep(0); this.onAttrChanged(...args); } };
dispatchEvent(type, {
global = false,
data = {}
} = {}) {
return type instanceof Event
? super.dispatchEvent(type)
: super.dispatchEvent(new CustomEvent(type, {
...(global? {
bubbles: true,
cancelable: true,
composed: true,
}: {}),
detail: data,
}));
};
};
export {
MCComponent,
};