p-elements-core 1.2.0-rc7 → 1.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.babelrc +29 -0
- package/demo/sample.js +20 -0
- package/{screen.css → demo/screen.css} +0 -0
- package/{theme.css → demo/theme.css} +0 -0
- package/dist/p-elements-core-modern.js +3 -4
- package/dist/p-elements-core.js +3 -14
- package/index.html +9 -9
- package/older-browsers-webpack.config.js +60 -0
- package/p-elements-core.d.ts +70 -20
- package/package.json +22 -46
- package/src/cache.ts +34 -0
- package/src/custom-element.ts +303 -0
- package/src/custom-style-element.ts +38 -20
- package/src/dom.ts +133 -0
- package/src/h.ts +86 -0
- package/src/index.ts +40 -0
- package/src/interfaces.ts +15 -0
- package/src/mapping.ts +79 -0
- package/src/projection.ts +730 -0
- package/src/projector.ts +110 -0
- package/src/sample.tsx +112 -50
- package/tsconfig.json +1 -1
- package/webpack.config.js +52 -162
- package/dist/sample.js +0 -2
- package/global.js +0 -1
- package/karma.conf.js +0 -32
- package/src/commonjs.js +0 -182
- package/src/custom-event-polyfill.js +0 -78
- package/src/index.tsx +0 -23
- package/src/sample.css +0 -20
- package/src/sample.spec.ts +0 -112
- package/src/utils/custom-element.ts +0 -241
- package/src/utils/maquette.ts +0 -1328
- package/types/custom-style-element.d.ts +0 -3
- package/types/index.d.ts +0 -1
- package/types/sample.d.ts +0 -1
- package/types/utils/custom-element.d.ts +0 -29
- package/types/utils/maquette.d.ts +0 -521
- package/webpack.config.karma.js +0 -35
package/index.html
CHANGED
|
@@ -2,16 +2,17 @@
|
|
|
2
2
|
<html lang="en">
|
|
3
3
|
<head>
|
|
4
4
|
<title>Sample</title>
|
|
5
|
-
<meta http-equiv="Content-Security-Policy" content="default-src 'self' '
|
|
5
|
+
<meta http-equiv="Content-Security-Policy" content="default-src 'self'; script-src 'self' 'unsafe-inline' 'unsafe-eval' ; style-src blob: 'self'; img-src *.pinimg.com">
|
|
6
6
|
<meta charset="UTF-8">
|
|
7
7
|
<meta name="viewport" content="width=device-width, initial-scale=1">
|
|
8
|
-
<link href="theme.css" is="custom-style" type="text/css">
|
|
9
|
-
<link href="screen.css" rel="stylesheet" type="text/css">
|
|
8
|
+
<link href="demo/theme.css" is="custom-style" type="text/css">
|
|
9
|
+
<link href="demo/screen.css" rel="stylesheet" type="text/css">
|
|
10
10
|
</head>
|
|
11
11
|
<body>
|
|
12
12
|
|
|
13
13
|
|
|
14
14
|
<h1>Sample custom element</h1>
|
|
15
|
+
|
|
15
16
|
<p-foo></p-foo>
|
|
16
17
|
|
|
17
18
|
<my-greetings name="Jan">
|
|
@@ -37,8 +38,8 @@
|
|
|
37
38
|
</script>
|
|
38
39
|
|
|
39
40
|
|
|
40
|
-
|
|
41
|
-
|
|
41
|
+
|
|
42
|
+
<script>
|
|
42
43
|
/**
|
|
43
44
|
* Safari 10.1 supports modules, but does not support the `nomodule` attribute
|
|
44
45
|
* This workaround is possible because Safari supports the non-standard 'beforeload' event.
|
|
@@ -68,13 +69,12 @@
|
|
|
68
69
|
}
|
|
69
70
|
}());
|
|
70
71
|
</script>
|
|
71
|
-
<!-- <script defer src="dist/p-elements-core.js"></script> -->
|
|
72
72
|
|
|
73
|
-
<script type="module" defer src="dist/p-elements-core-modern.js"></script>
|
|
74
|
-
<script nomodule defer src="dist/p-elements-core.js
|
|
73
|
+
<script type="module" defer src="dist/p-elements-core-modern.js?m=l"></script>
|
|
74
|
+
<script nomodule defer src="dist/p-elements-core.js?m=l"></script>
|
|
75
75
|
|
|
76
76
|
<!-- load component(s) -->
|
|
77
|
-
<script defer src="
|
|
77
|
+
<script defer src="demo/sample.js"></script>
|
|
78
78
|
|
|
79
79
|
|
|
80
80
|
</body>
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
const path = require("path");
|
|
2
|
+
const webpack = require('webpack');
|
|
3
|
+
const TerserPlugin = require("terser-webpack-plugin")
|
|
4
|
+
const package = require('./package.json');
|
|
5
|
+
const banner = `P-ELEMENTS ${package.version} - ${new Date()}`;
|
|
6
|
+
|
|
7
|
+
module.exports = {
|
|
8
|
+
optimization: {
|
|
9
|
+
minimize: true,
|
|
10
|
+
minimizer: [
|
|
11
|
+
new TerserPlugin({
|
|
12
|
+
terserOptions: {
|
|
13
|
+
format: {
|
|
14
|
+
comments: /^\**!/i,
|
|
15
|
+
},
|
|
16
|
+
},
|
|
17
|
+
extractComments: false,
|
|
18
|
+
}),
|
|
19
|
+
],
|
|
20
|
+
},
|
|
21
|
+
plugins: [
|
|
22
|
+
new webpack.BannerPlugin({banner}),
|
|
23
|
+
],
|
|
24
|
+
entry: {
|
|
25
|
+
"dist/p-elements-core": [
|
|
26
|
+
"@webcomponents/template/template.js",
|
|
27
|
+
"@babel/polyfill",
|
|
28
|
+
"whatwg-fetch",
|
|
29
|
+
"@webcomponents/shadydom/shadydom.min.js",
|
|
30
|
+
"@webcomponents/shadycss/apply-shim.min.js",
|
|
31
|
+
"@webcomponents/shadycss/custom-style-interface.min.js",
|
|
32
|
+
"document-register-element/build/document-register-element.js",
|
|
33
|
+
"underscore",
|
|
34
|
+
"./src/index.ts",
|
|
35
|
+
],
|
|
36
|
+
},
|
|
37
|
+
module: {
|
|
38
|
+
rules: [
|
|
39
|
+
{
|
|
40
|
+
test: /\.tsx?$/,
|
|
41
|
+
use: ["babel-loader", "ts-loader"],
|
|
42
|
+
exclude: /node_modules/,
|
|
43
|
+
},
|
|
44
|
+
],
|
|
45
|
+
},
|
|
46
|
+
resolve: {
|
|
47
|
+
extensions: [".tsx", ".ts", ".js"],
|
|
48
|
+
},
|
|
49
|
+
output: {
|
|
50
|
+
path: path.resolve(__dirname),
|
|
51
|
+
filename: "[name]" + ".js",
|
|
52
|
+
chunkFilename: "[chunkhash]" + ".js",
|
|
53
|
+
},
|
|
54
|
+
devServer: {
|
|
55
|
+
static: {
|
|
56
|
+
directory: __dirname,
|
|
57
|
+
},
|
|
58
|
+
port: 5001,
|
|
59
|
+
},
|
|
60
|
+
};
|
package/p-elements-core.d.ts
CHANGED
|
@@ -1,13 +1,22 @@
|
|
|
1
1
|
declare interface IElementConfig {
|
|
2
2
|
tagName: string;
|
|
3
3
|
options?: {
|
|
4
|
-
|
|
4
|
+
extends: string;
|
|
5
5
|
};
|
|
6
6
|
}
|
|
7
7
|
|
|
8
8
|
declare interface TransitionStrategy {
|
|
9
|
-
enter(
|
|
10
|
-
|
|
9
|
+
enter(
|
|
10
|
+
element: Element,
|
|
11
|
+
properties: VNodeProperties,
|
|
12
|
+
enterAnimation: string
|
|
13
|
+
): void;
|
|
14
|
+
exit(
|
|
15
|
+
element: Element,
|
|
16
|
+
properties: VNodeProperties,
|
|
17
|
+
exitAnimation: string,
|
|
18
|
+
removeElement: () => void
|
|
19
|
+
): void;
|
|
11
20
|
}
|
|
12
21
|
|
|
13
22
|
declare interface ProjectorOptions {
|
|
@@ -15,19 +24,46 @@ declare interface ProjectorOptions {
|
|
|
15
24
|
styleApplyer?(domNode: HTMLElement, styleName: string, value: string): void;
|
|
16
25
|
}
|
|
17
26
|
|
|
18
|
-
declare
|
|
27
|
+
declare interface ProjectionOptions extends ProjectorOptions {
|
|
19
28
|
readonly namespace?: string;
|
|
20
|
-
eventHandlerInterceptor?: (
|
|
29
|
+
eventHandlerInterceptor?: (
|
|
30
|
+
propertyName: string,
|
|
31
|
+
eventHandler: Function,
|
|
32
|
+
domNode: Node,
|
|
33
|
+
properties: VNodeProperties
|
|
34
|
+
) => Function;
|
|
21
35
|
}
|
|
22
36
|
|
|
23
37
|
declare interface VNodeProperties {
|
|
24
|
-
enterAnimation?:
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
38
|
+
enterAnimation?:
|
|
39
|
+
| ((element: Element, properties?: VNodeProperties) => void)
|
|
40
|
+
| string;
|
|
41
|
+
exitAnimation?:
|
|
42
|
+
| ((
|
|
43
|
+
element: Element,
|
|
44
|
+
removeElement: () => void,
|
|
45
|
+
properties?: VNodeProperties
|
|
46
|
+
) => void)
|
|
47
|
+
| string;
|
|
48
|
+
updateAnimation?: (
|
|
49
|
+
element: Element,
|
|
50
|
+
properties?: VNodeProperties,
|
|
51
|
+
previousProperties?: VNodeProperties
|
|
52
|
+
) => void;
|
|
53
|
+
afterCreate?(
|
|
54
|
+
element: Element,
|
|
55
|
+
projectionOptions: ProjectionOptions,
|
|
56
|
+
vnodeSelector: string,
|
|
57
|
+
properties: VNodeProperties,
|
|
58
|
+
children: VNode[]
|
|
59
|
+
): void;
|
|
60
|
+
afterUpdate?(
|
|
61
|
+
element: Element,
|
|
62
|
+
projectionOptions: ProjectionOptions,
|
|
63
|
+
vnodeSelector: string,
|
|
64
|
+
properties: VNodeProperties,
|
|
65
|
+
children: VNode[]
|
|
66
|
+
): void;
|
|
31
67
|
afterRemoved?(element: Element): void;
|
|
32
68
|
readonly bind?: Object;
|
|
33
69
|
readonly key?: Object;
|
|
@@ -66,7 +102,7 @@ declare interface VNodeProperties {
|
|
|
66
102
|
onmouseout?(ev?: MouseEvent): boolean | void;
|
|
67
103
|
onmouseover?(ev?: MouseEvent): boolean | void;
|
|
68
104
|
onmouseup?(ev?: MouseEvent): boolean | void;
|
|
69
|
-
onmousewheel?(ev?: WheelEvent
|
|
105
|
+
onmousewheel?(ev?: WheelEvent): boolean | void;
|
|
70
106
|
onscroll?(ev?: UIEvent): boolean | void;
|
|
71
107
|
onsubmit?(ev?: Event): boolean | void;
|
|
72
108
|
readonly spellcheck?: boolean;
|
|
@@ -101,7 +137,12 @@ declare interface VNode {
|
|
|
101
137
|
|
|
102
138
|
declare interface ProjectionOptions extends ProjectorOptions {
|
|
103
139
|
readonly namespace?: string;
|
|
104
|
-
eventHandlerInterceptor?: (
|
|
140
|
+
eventHandlerInterceptor?: (
|
|
141
|
+
propertyName: string,
|
|
142
|
+
eventHandler: Function,
|
|
143
|
+
domNode: Node,
|
|
144
|
+
properties: VNodeProperties
|
|
145
|
+
) => Function;
|
|
105
146
|
}
|
|
106
147
|
|
|
107
148
|
declare interface Projection {
|
|
@@ -121,16 +162,25 @@ declare interface Projector {
|
|
|
121
162
|
stop(): void;
|
|
122
163
|
}
|
|
123
164
|
|
|
124
|
-
declare const CustomElementConfig: (
|
|
165
|
+
declare const CustomElementConfig: (
|
|
166
|
+
config: IElementConfig
|
|
167
|
+
) => (Element: any) => void;
|
|
125
168
|
|
|
126
169
|
declare abstract class CustomElement extends HTMLElement {
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
170
|
+
protected templateFromString(html: string, shady?: boolean): any;
|
|
171
|
+
protected updateStyle(): void;
|
|
172
|
+
protected createProjector(
|
|
173
|
+
element: Element,
|
|
174
|
+
render: () => VNode
|
|
175
|
+
): Promise<Projector>;
|
|
176
|
+
protected renderNow(): void;
|
|
131
177
|
}
|
|
132
178
|
|
|
133
|
-
declare const Bind: (
|
|
179
|
+
declare const Bind: (
|
|
180
|
+
target: object,
|
|
181
|
+
propertyKey: string,
|
|
182
|
+
descriptor: any
|
|
183
|
+
) => void;
|
|
134
184
|
|
|
135
185
|
declare function PropertyRenderOnSet(target: object, propertyKey: string): void;
|
|
136
186
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "p-elements-core",
|
|
3
|
-
"version": "1.2.0
|
|
3
|
+
"version": "1.2.0",
|
|
4
4
|
"description": "P Elements Core V1",
|
|
5
5
|
"main": "dist/p-elements-core.js",
|
|
6
6
|
"types": "p-elements-core.d.ts",
|
|
@@ -9,61 +9,37 @@
|
|
|
9
9
|
"url": "gitlab.com:p-elements/p-element-core.git"
|
|
10
10
|
},
|
|
11
11
|
"scripts": {
|
|
12
|
-
"test": "
|
|
12
|
+
"test": "echo \"Error: no test specified\" && exit 1",
|
|
13
13
|
"clean": "rimraf ./dist",
|
|
14
|
-
"build
|
|
15
|
-
"build": "npm run clean &&
|
|
16
|
-
"build-default": "webpack --env.production",
|
|
17
|
-
"build-modern": "webpack --env.modern",
|
|
14
|
+
"build-old": "webpack --config older-browsers-webpack.config.js --mode=production",
|
|
15
|
+
"build": "npm run clean && webpack --mode=production && npm run build-old",
|
|
18
16
|
"ws": "echo \"set --https flag if you need ssl\" | ws -p 5001 -d ./ -c",
|
|
19
|
-
"
|
|
20
|
-
"declarations": "rimraf ./types && tsc --declaration --emitDeclarationOnly --declarationDir ./types && rimraf ./types/**/*.spec.d.ts",
|
|
21
|
-
"develop": "npm run ws | npm run build:dev"
|
|
17
|
+
"develop": "webpack serve --mode=development"
|
|
22
18
|
},
|
|
23
19
|
"author": "P.A. Huisman",
|
|
24
20
|
"license": "ISC",
|
|
25
21
|
"devDependencies": {
|
|
26
|
-
"@babel/
|
|
27
|
-
"@babel/
|
|
28
|
-
"@babel/
|
|
29
|
-
"@babel/
|
|
30
|
-
"@babel/
|
|
31
|
-
"@babel/preset-env": "=7.0.0",
|
|
32
|
-
"@babel/preset-react": "=7.0.0",
|
|
33
|
-
"@types/jasmine": "=2.8.14",
|
|
34
|
-
"@types/requirejs": "=2.1.31",
|
|
35
|
-
"@types/underscore": "=1.9.1",
|
|
22
|
+
"@babel/plugin-proposal-class-properties": "^7.16.7",
|
|
23
|
+
"@babel/plugin-proposal-object-rest-spread": "^7.16.7",
|
|
24
|
+
"@babel/polyfill": "^7.12.1",
|
|
25
|
+
"@babel/preset-env": "^7.16.7",
|
|
26
|
+
"@babel/preset-react": "^7.16.7",
|
|
36
27
|
"@webcomponents/shadycss": "=1.6.0",
|
|
37
28
|
"@webcomponents/shadydom": "github:webcomponents/shadydom#v1.0.4",
|
|
38
29
|
"@webcomponents/template": "github:webcomponents/template#v1.1.0",
|
|
39
30
|
"animejs": "=2.2.0",
|
|
40
|
-
"
|
|
41
|
-
"
|
|
42
|
-
"babel-plugin-jsx-auto-key-attr": "0.0.1",
|
|
43
|
-
"css-loader": "=0.28.11",
|
|
44
|
-
"cssnano": "=3.10.0",
|
|
31
|
+
"babel-loader": "^8.2.3",
|
|
32
|
+
"css-loader": "^6.5.1",
|
|
45
33
|
"document-register-element": "=1.13.1",
|
|
46
|
-
"
|
|
47
|
-
"
|
|
48
|
-
"
|
|
49
|
-
"
|
|
50
|
-
"
|
|
51
|
-
"karma-jasmine": "=1.1.2",
|
|
52
|
-
"karma-webpack": "=2.0.13",
|
|
53
|
-
"local-web-server": "=2.6.1",
|
|
54
|
-
"postcss-loader": "=1.3.3",
|
|
55
|
-
"rimraf": "=2.6.3",
|
|
56
|
-
"to-string-loader": "=1.1.5",
|
|
57
|
-
"tslint": "=4.3.1",
|
|
58
|
-
"typescript": "=2.9.2",
|
|
59
|
-
"uglifyjs-webpack-plugin": "=1.3.0",
|
|
34
|
+
"local-web-server": "^2.6.1",
|
|
35
|
+
"rimraf": "^3.0.2",
|
|
36
|
+
"terser-webpack-plugin": "^5.3.0",
|
|
37
|
+
"ts-loader": "^9.2.6",
|
|
38
|
+
"typescript": "^4.5.4",
|
|
60
39
|
"underscore": "=1.13.1",
|
|
61
|
-
"webpack": "
|
|
62
|
-
"webpack-
|
|
63
|
-
"
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
"> 2% in NL",
|
|
67
|
-
"last 2 versions"
|
|
68
|
-
]
|
|
40
|
+
"webpack": "^5.65.0",
|
|
41
|
+
"webpack-cli": "^4.9.1",
|
|
42
|
+
"webpack-dev-server": "^4.7.2",
|
|
43
|
+
"whatwg-fetch": "^3.6.2"
|
|
44
|
+
}
|
|
69
45
|
}
|
package/src/cache.ts
ADDED
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import { CalculationCache } from "./interfaces";
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Creates a [[CalculationCache]] object, useful for caching [[VNode]] trees.
|
|
5
|
+
* In practice, caching of [[VNode]] trees is not needed, because achieving 60 frames per second is almost never a problem.
|
|
6
|
+
* For more information, see [[CalculationCache]].
|
|
7
|
+
*
|
|
8
|
+
* @param <Result> The type of the value that is cached.
|
|
9
|
+
*/
|
|
10
|
+
export let createCache = <Result>(): CalculationCache<Result> => {
|
|
11
|
+
let cachedInputs: Object[] | undefined;
|
|
12
|
+
let cachedOutcome: Result | undefined;
|
|
13
|
+
return {
|
|
14
|
+
invalidate: () => {
|
|
15
|
+
cachedOutcome = undefined;
|
|
16
|
+
cachedInputs = undefined;
|
|
17
|
+
},
|
|
18
|
+
|
|
19
|
+
result: (inputs: Object[], calculation: () => Result) => {
|
|
20
|
+
if (cachedInputs) {
|
|
21
|
+
for (let i = 0; i < inputs.length; i++) {
|
|
22
|
+
if (cachedInputs[i] !== inputs[i]) {
|
|
23
|
+
cachedOutcome = undefined;
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
if (!cachedOutcome) {
|
|
28
|
+
cachedOutcome = calculation();
|
|
29
|
+
cachedInputs = inputs;
|
|
30
|
+
}
|
|
31
|
+
return cachedOutcome;
|
|
32
|
+
},
|
|
33
|
+
};
|
|
34
|
+
};
|
|
@@ -0,0 +1,303 @@
|
|
|
1
|
+
declare var HTMLElement: {
|
|
2
|
+
prototype: HTMLElement;
|
|
3
|
+
new (param?): HTMLElement;
|
|
4
|
+
};
|
|
5
|
+
|
|
6
|
+
export interface IElementConfig {
|
|
7
|
+
tagName: string;
|
|
8
|
+
options?: {
|
|
9
|
+
extends: string;
|
|
10
|
+
};
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
const cssMap = new Map();
|
|
14
|
+
|
|
15
|
+
export const Bind = (target, key, descriptor) => {
|
|
16
|
+
let fn = descriptor.value;
|
|
17
|
+
console.warn("@Bind decorator is deprecated, use arrow function expression");
|
|
18
|
+
if (typeof fn !== "function") {
|
|
19
|
+
throw new Error(
|
|
20
|
+
`@Bind decorator can only be applied to methods not: ${typeof fn}`
|
|
21
|
+
);
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
// In IE11 calling Object.defineProperty has a side-effect of evaluating the
|
|
25
|
+
// getter for the property which is being replaced. This causes infinite
|
|
26
|
+
// recursion and an "Out of stack space" error.
|
|
27
|
+
let definingProperty = false;
|
|
28
|
+
|
|
29
|
+
return {
|
|
30
|
+
configurable: true,
|
|
31
|
+
get() {
|
|
32
|
+
if (
|
|
33
|
+
definingProperty ||
|
|
34
|
+
this === target.prototype ||
|
|
35
|
+
this.hasOwnProperty(key) ||
|
|
36
|
+
typeof fn !== "function"
|
|
37
|
+
) {
|
|
38
|
+
return fn;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
let boundFn = fn.bind(this);
|
|
42
|
+
definingProperty = true;
|
|
43
|
+
Object.defineProperty(this, key, {
|
|
44
|
+
configurable: true,
|
|
45
|
+
get() {
|
|
46
|
+
return boundFn;
|
|
47
|
+
},
|
|
48
|
+
set(value) {
|
|
49
|
+
fn = value;
|
|
50
|
+
delete this[key];
|
|
51
|
+
},
|
|
52
|
+
});
|
|
53
|
+
definingProperty = false;
|
|
54
|
+
return boundFn;
|
|
55
|
+
},
|
|
56
|
+
set(value) {
|
|
57
|
+
fn = value;
|
|
58
|
+
},
|
|
59
|
+
};
|
|
60
|
+
};
|
|
61
|
+
|
|
62
|
+
export const CustomElementConfig = (config: IElementConfig) => {
|
|
63
|
+
return (Element) => {
|
|
64
|
+
setTimeout(() => {
|
|
65
|
+
customElements.define(config.tagName, Element, config.options);
|
|
66
|
+
}, 10);
|
|
67
|
+
const camelCased = config.tagName.replace(/-([a-z])/g, function (g) {
|
|
68
|
+
return g[1].toUpperCase();
|
|
69
|
+
});
|
|
70
|
+
(<any>window)[camelCased.charAt(0).toUpperCase() + camelCased.slice(1)] =
|
|
71
|
+
Element;
|
|
72
|
+
};
|
|
73
|
+
};
|
|
74
|
+
|
|
75
|
+
export function PropertyRenderOnSet(target, key) {
|
|
76
|
+
if (!Reflect.get(target, "_dp_" + key)) {
|
|
77
|
+
Reflect.defineProperty(target, "_dp_" + key, {
|
|
78
|
+
configurable: true,
|
|
79
|
+
enumerable: true,
|
|
80
|
+
get: function () {
|
|
81
|
+
return this["_" + key + "_value"];
|
|
82
|
+
},
|
|
83
|
+
set: function (value) {
|
|
84
|
+
this["_" + key + "_value"] = value;
|
|
85
|
+
},
|
|
86
|
+
});
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
if (!target["_dp_setters_" + key]) {
|
|
90
|
+
target["_dp_setters_" + key] = [];
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
const propertyRenderOnSetFunction = (o, v) => {
|
|
94
|
+
if (o && o.renderNow) {
|
|
95
|
+
o.renderNow();
|
|
96
|
+
}
|
|
97
|
+
};
|
|
98
|
+
|
|
99
|
+
target["_dp_setters_" + key].push(propertyRenderOnSetFunction);
|
|
100
|
+
|
|
101
|
+
const getter = function () {
|
|
102
|
+
return this["_" + key + "_value"];
|
|
103
|
+
};
|
|
104
|
+
|
|
105
|
+
const setter = function (newVal) {
|
|
106
|
+
this["_dp_" + key] = newVal;
|
|
107
|
+
if (target["_dp_setters_" + key]) {
|
|
108
|
+
target["_dp_setters_" + key].forEach((fn) => {
|
|
109
|
+
fn(this, newVal);
|
|
110
|
+
});
|
|
111
|
+
}
|
|
112
|
+
};
|
|
113
|
+
|
|
114
|
+
Object.defineProperty(target, key, {
|
|
115
|
+
configurable: true,
|
|
116
|
+
enumerable: true,
|
|
117
|
+
get: getter,
|
|
118
|
+
set: setter,
|
|
119
|
+
});
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
declare var HTMLElement: {
|
|
123
|
+
prototype: HTMLElement;
|
|
124
|
+
new (arg?: any): HTMLElement;
|
|
125
|
+
};
|
|
126
|
+
|
|
127
|
+
const installCE = require("document-register-element/pony");
|
|
128
|
+
const isNative = (fn) => {
|
|
129
|
+
return /\{\s*\[native code\]\s*\}/.test("" + fn);
|
|
130
|
+
};
|
|
131
|
+
if (!isNative((document as any).registerElement)) {
|
|
132
|
+
installCE(window, "auto");
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
export abstract class CustomElement extends HTMLElement {
|
|
136
|
+
constructor(self) {
|
|
137
|
+
self = super(self);
|
|
138
|
+
if (typeof (this as any).init === "function") {
|
|
139
|
+
(this as any).init();
|
|
140
|
+
}
|
|
141
|
+
return self;
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
private _projector: Projector;
|
|
145
|
+
|
|
146
|
+
protected get useInlineStyle() {
|
|
147
|
+
const s = document.querySelector(
|
|
148
|
+
"script[src*='/p-elements-core']"
|
|
149
|
+
) as HTMLScriptElement;
|
|
150
|
+
return s && s.src.indexOf("m=l") < 0;
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
protected templateFromString(html: string): any {
|
|
154
|
+
if (!this.shadowRoot) {
|
|
155
|
+
this.attachShadow({ mode: "open" });
|
|
156
|
+
}
|
|
157
|
+
this.shadowRoot.innerHTML = "";
|
|
158
|
+
const supportReplaceCssSync = (this.shadowRoot as any).adoptedStyleSheets && CSSStyleSheet;
|
|
159
|
+
|
|
160
|
+
let style = "<style></style>";
|
|
161
|
+
|
|
162
|
+
const styleMatch = html.match(/<style[^>]*>([\s\S]*?)<\/style>/);
|
|
163
|
+
if (styleMatch) {
|
|
164
|
+
style = styleMatch[0];
|
|
165
|
+
if (cssMap.has(this.tagName)) {
|
|
166
|
+
if (this.useInlineStyle) {
|
|
167
|
+
html = html.replace(
|
|
168
|
+
styleMatch[0],
|
|
169
|
+
`<style>${cssMap.get(this.tagName)}</style>`
|
|
170
|
+
);
|
|
171
|
+
} else {
|
|
172
|
+
html = html.replace(
|
|
173
|
+
styleMatch[0],
|
|
174
|
+
`<link rel="stylesheet" href="${cssMap.get(this.tagName)}">`
|
|
175
|
+
);
|
|
176
|
+
}
|
|
177
|
+
} else {
|
|
178
|
+
if (this.useInlineStyle) {
|
|
179
|
+
html = html.replace(styleMatch[0], `<style>${styleMatch[1]}</style>`);
|
|
180
|
+
} else {
|
|
181
|
+
|
|
182
|
+
if (supportReplaceCssSync) {
|
|
183
|
+
html = html.replace(styleMatch[0], "");
|
|
184
|
+
const styleSheet = new CSSStyleSheet();
|
|
185
|
+
(styleSheet as any).replaceSync(styleMatch[1]);
|
|
186
|
+
(this.shadowRoot as any).adoptedStyleSheets = [styleSheet];
|
|
187
|
+
} else {
|
|
188
|
+
const blob = new Blob([styleMatch[1]], { type: "text/css" });
|
|
189
|
+
html = html.replace(
|
|
190
|
+
styleMatch[0],
|
|
191
|
+
`<link rel="stylesheet" href="${URL.createObjectURL(
|
|
192
|
+
blob
|
|
193
|
+
)}" data-tmp="true">`
|
|
194
|
+
);
|
|
195
|
+
}
|
|
196
|
+
}
|
|
197
|
+
}
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
let myElementTemplate = document.createElement("template");
|
|
201
|
+
myElementTemplate.innerHTML = html;
|
|
202
|
+
let template = document.importNode(myElementTemplate.content, true);
|
|
203
|
+
|
|
204
|
+
const textContentForShadyStyle = () => {
|
|
205
|
+
if (cssMap.has(this.tagName)) {
|
|
206
|
+
return cssMap.get(this.tagName);
|
|
207
|
+
}
|
|
208
|
+
const t = document.createElement("template");
|
|
209
|
+
t.innerHTML = style;
|
|
210
|
+
const p = (window as any).ShadyCSS.prepareTemplate(t, "x-tmp");
|
|
211
|
+
const c = t.content.cloneNode(true);
|
|
212
|
+
const s = (c as any).querySelector("style").textContent;
|
|
213
|
+
cssMap.set(this.tagName, s);
|
|
214
|
+
return s;
|
|
215
|
+
};
|
|
216
|
+
|
|
217
|
+
const creatObjectUrlForShadyStyle = () => {
|
|
218
|
+
if (cssMap.has(this.tagName)) {
|
|
219
|
+
return cssMap.get(this.tagName);
|
|
220
|
+
}
|
|
221
|
+
const t = document.createElement("template");
|
|
222
|
+
t.innerHTML = style;
|
|
223
|
+
const p = (window as any).ShadyCSS.prepareTemplate(t, "x-tmp");
|
|
224
|
+
const c = t.content.cloneNode(true);
|
|
225
|
+
const cssTxt = (c as any).querySelector("style").textContent;
|
|
226
|
+
const blob = new Blob([cssTxt], { type: "text/css" });
|
|
227
|
+
const url = URL.createObjectURL(blob);
|
|
228
|
+
cssMap.set(this.tagName, url);
|
|
229
|
+
return url;
|
|
230
|
+
};
|
|
231
|
+
|
|
232
|
+
window.addEventListener("customStyleConnected", () => {
|
|
233
|
+
setTimeout(() => {
|
|
234
|
+
if (this.useInlineStyle) {
|
|
235
|
+
const styleElement = this.shadowRoot.querySelector("style");
|
|
236
|
+
if (styleElement) {
|
|
237
|
+
styleElement.textContent = textContentForShadyStyle();
|
|
238
|
+
}
|
|
239
|
+
} else {
|
|
240
|
+
|
|
241
|
+
if (supportReplaceCssSync) {
|
|
242
|
+
html = html.replace(styleMatch[0], "");
|
|
243
|
+
const styleSheet = new CSSStyleSheet();
|
|
244
|
+
(styleSheet as any).replaceSync(textContentForShadyStyle());
|
|
245
|
+
(this.shadowRoot as any).adoptedStyleSheets = [styleSheet];
|
|
246
|
+
}
|
|
247
|
+
else {
|
|
248
|
+
const link = this.shadowRoot.querySelector("link");
|
|
249
|
+
if (link) {
|
|
250
|
+
if (link.hasAttribute("data-tmp")) {
|
|
251
|
+
URL.revokeObjectURL(link.href);
|
|
252
|
+
link.removeAttribute("data-tmp");
|
|
253
|
+
}
|
|
254
|
+
link.href = creatObjectUrlForShadyStyle();
|
|
255
|
+
}
|
|
256
|
+
}
|
|
257
|
+
}
|
|
258
|
+
}, 300);
|
|
259
|
+
});
|
|
260
|
+
|
|
261
|
+
setTimeout(() => {
|
|
262
|
+
if (this.useInlineStyle) {
|
|
263
|
+
const styleElement = this.shadowRoot.querySelector("style");
|
|
264
|
+
if (styleElement) {
|
|
265
|
+
styleElement.textContent = textContentForShadyStyle();
|
|
266
|
+
}
|
|
267
|
+
} else {
|
|
268
|
+
const link = this.shadowRoot.querySelector("link");
|
|
269
|
+
if (link) {
|
|
270
|
+
if (link.hasAttribute("data-tmp")) {
|
|
271
|
+
URL.revokeObjectURL(link.href);
|
|
272
|
+
link.removeAttribute("data-tmp");
|
|
273
|
+
}
|
|
274
|
+
link.href = creatObjectUrlForShadyStyle();
|
|
275
|
+
}
|
|
276
|
+
}
|
|
277
|
+
}, 100);
|
|
278
|
+
return template;
|
|
279
|
+
}
|
|
280
|
+
|
|
281
|
+
protected createProjector(
|
|
282
|
+
element: Element,
|
|
283
|
+
render: () => VNode
|
|
284
|
+
): Promise<Projector> {
|
|
285
|
+
return new Promise<Projector>((resolve, reject) => {
|
|
286
|
+
let projector: Projector;
|
|
287
|
+
|
|
288
|
+
setTimeout(() => {
|
|
289
|
+
projector = (window as any).Maquette.createProjector();
|
|
290
|
+
projector.append(element, render);
|
|
291
|
+
this._projector = projector;
|
|
292
|
+
resolve(projector);
|
|
293
|
+
this.dispatchEvent(new CustomEvent("firstRender", {}));
|
|
294
|
+
}, 1);
|
|
295
|
+
});
|
|
296
|
+
}
|
|
297
|
+
|
|
298
|
+
protected renderNow() {
|
|
299
|
+
if (this._projector) {
|
|
300
|
+
this._projector.renderNow();
|
|
301
|
+
}
|
|
302
|
+
}
|
|
303
|
+
}
|