@techexp/webitem 0.5.3 → 0.7.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/README-dev.md +2 -2
- package/README.md +30 -10
- package/dist/webitem-esm.js +16 -21
- package/dist/webitem-script-min.js +5 -5
- package/dist/webitem-script.js +61 -99
- package/eslint.config.js +95 -0
- package/package.json +12 -11
- package/src/index.html +1 -1
- package/src/test/perf-test.css +3 -0
- package/src/test/webitem.perf.test.js +107 -0
- package/src/test/webitem.test.js +1 -1
- package/src/webitem.js +23 -17
- package/.eslintrc.js +0 -92
package/README-dev.md
CHANGED
|
@@ -5,13 +5,13 @@ This file contains info to help the developer of the library.
|
|
|
5
5
|
|
|
6
6
|
## Project Directory Structure
|
|
7
7
|
|
|
8
|
-
1. The root of the project
|
|
8
|
+
1. The root of the project contains these files
|
|
9
9
|
1. `.ackrc`: Config for [Ack](https://beyondgrep.com/) grep tool
|
|
10
10
|
2. `.editorconfig`: Config for [EditorConfig](https://editorconfig.org/)
|
|
11
11
|
3. `.eslintrc`: ES Lint customized rules
|
|
12
12
|
4. `.gitignore`: List of files to be ignored by git
|
|
13
13
|
5. `.npmrc`: Configuration for npm.
|
|
14
|
-
6. `LICENSE`: License file,
|
|
14
|
+
6. `LICENSE`: License file, using Apache v 2.0
|
|
15
15
|
7. `package.json`, `package-lock.json`: NPM package definition.
|
|
16
16
|
8. `README.md`: Info about using the library.
|
|
17
17
|
9. `README-dev.md`: This file.
|
package/README.md
CHANGED
|
@@ -4,7 +4,7 @@ A library to simplify creating HTML5 Web Components (Custom Elements).
|
|
|
4
4
|
## Introduction
|
|
5
5
|
In modern HTML, you can create web components using
|
|
6
6
|
[customElements.define()](https://developer.mozilla.org/en-US/docs/Web/Web_Components).
|
|
7
|
-
This API is
|
|
7
|
+
This API is powerful, but can be verbose and complicated. The _webitem.js_ library provides a wrapper
|
|
8
8
|
around that API in an attempt to make it simple for the application's programmer.
|
|
9
9
|
|
|
10
10
|
## Install
|
|
@@ -71,7 +71,8 @@ object with the following keys:
|
|
|
71
71
|
`(webitem) => string`. Look down for an example.
|
|
72
72
|
3. `css`: Optional, String. The CSS to apply on the web component. This CSS will be name-spaced
|
|
73
73
|
within the component, and is not visible outside it.
|
|
74
|
-
4. `
|
|
74
|
+
4. `styleSheets`: Optional, array of `CSSStyleSheet` objects. This way you can share style sheets among components.
|
|
75
|
+
5. `propertyList`: Optional, Array of objects. Objects defining properties of the component. Each property
|
|
75
76
|
definition consists of `{name, value, [sel], [attr]}`.
|
|
76
77
|
1. `name`: Name of the property.
|
|
77
78
|
2. `value`: Initial value of the property.
|
|
@@ -79,18 +80,18 @@ object with the following keys:
|
|
|
79
80
|
4. `attr`: Optional, String. An attribute on the DOM element to bind its value.
|
|
80
81
|
5. `onChange`: Optional. Function. A function to be called when the property's value change through
|
|
81
82
|
an API call. The function can take three arguments `(webitem, oldValue, newValue)`
|
|
82
|
-
|
|
83
|
+
6. `eventHandlerList`: Optional, Array of objects. Objects define event handlers of the component.
|
|
83
84
|
Each event handler definition consists of `{sel, eventName, listener}`.
|
|
84
85
|
1. `sel`: A CSS selector of an element in the component.
|
|
85
86
|
2. `eventName`: Name of the event to bind to, e.g. `click`.
|
|
86
87
|
3. `listener`: A function to be called when the event occures. The function accepts two arguments,
|
|
87
88
|
an [event](https://developer.mozilla.org/en-US/docs/Web/API/Event) object, and `webitem` which is the web component.
|
|
88
|
-
|
|
89
|
+
7. `actionList`: Optional, Array of objects. Objects define actions that can be defined on the component.
|
|
89
90
|
Each action definition consists of `{name, action}`.
|
|
90
91
|
1. `name`: Name of the action.
|
|
91
92
|
2. `action`: a function definition. If you declare this function as a _classic_ (not arrow) function, using
|
|
92
93
|
`this` inside the function will refer to the component.
|
|
93
|
-
|
|
94
|
+
8. `display`: Optional, String. A CSS display attribute. A possible value can be
|
|
94
95
|
`inline` (default if missing), `inline-block`, or `block`. This controls how the component is displayed
|
|
95
96
|
inside its container.
|
|
96
97
|
|
|
@@ -99,7 +100,7 @@ already exists, in which case it will not be re-created.
|
|
|
99
100
|
|
|
100
101
|
The `defineElement()` function defines a standard _Custom Element_/_Web Component_ with all the
|
|
101
102
|
standard properties. It also adds an extra property `wi` that contains extra properties and
|
|
102
|
-
functions supported
|
|
103
|
+
functions supported by this library as follows:
|
|
103
104
|
|
|
104
105
|
1. `wi.properties`: An object with key/value as defined in the `propertyList` during element
|
|
105
106
|
definition.
|
|
@@ -124,8 +125,27 @@ functions supported bby this library as follows:
|
|
|
124
125
|
CSS applied to a web component (_through shadow DOM_) is scoped to the component, it does not interact
|
|
125
126
|
with CSS outside the component.
|
|
126
127
|
|
|
127
|
-
If you need to use a common CSS
|
|
128
|
-
|
|
128
|
+
If you need to use a common CSS among components, there are two options:
|
|
129
|
+
|
|
130
|
+
1. Use `CSSStyleSheet` object and pass in the `styleSheets` option. This is the recommended approach.
|
|
131
|
+
For example:
|
|
132
|
+
|
|
133
|
+
```js
|
|
134
|
+
const sheet = new CSSStyleSheet()
|
|
135
|
+
sheet.replaceSync('h3 { color: red; }')
|
|
136
|
+
|
|
137
|
+
webitem.defineElement({
|
|
138
|
+
nameWithDash: 'with-sheets',
|
|
139
|
+
html: `
|
|
140
|
+
<div style="background-color:green">
|
|
141
|
+
<h3>with-sheets Web Item</h3>
|
|
142
|
+
</div>
|
|
143
|
+
`,
|
|
144
|
+
styleSheets: [sheet]
|
|
145
|
+
})
|
|
146
|
+
```
|
|
147
|
+
|
|
148
|
+
2. Use the `<link>` tag in the component's html, for example, add the next line at the top of your component's html:
|
|
129
149
|
|
|
130
150
|
```html
|
|
131
151
|
<link rel="stylesheet" href="css/common.css">
|
|
@@ -137,7 +157,7 @@ Next we will show some as well.
|
|
|
137
157
|
|
|
138
158
|
### Provide html as a function
|
|
139
159
|
This example shows how to provide the html content of the component as a function. The function takes
|
|
140
|
-
the
|
|
160
|
+
the component itself as an argument and returns a string representing the html of the component.
|
|
141
161
|
|
|
142
162
|
This approach allows you to introspect the definition of the element as given on the page.
|
|
143
163
|
|
|
@@ -210,7 +230,7 @@ console.log($('#bounded').wi.properties.country) // prints USA
|
|
|
210
230
|
The binding is _bi-directional_, changing the property's value will change the view, and changing the
|
|
211
231
|
value in the view will change the property's value.
|
|
212
232
|
|
|
213
|
-
Binding properties to DOM elements is optional, you can choose to define a
|
|
233
|
+
Binding properties to DOM elements is optional, you can choose to define a property without `sel` value.
|
|
214
234
|
|
|
215
235
|
For more details about bound properties, check [Data Bind](https://www.npmjs.com/package/@techexp/data-bind)
|
|
216
236
|
NPM package which is used by this library.
|
package/dist/webitem-esm.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
// webitem.js Library to simplify creating HTML5 Custom Elements
|
|
2
2
|
// https://github.com/ahabra/webitem
|
|
3
|
-
// Copyright 2021 (C) Abdul Habra. Version 0.
|
|
3
|
+
// Copyright 2021 (C) Abdul Habra. Version 0.7.0.
|
|
4
4
|
// Apache License Version 2.0
|
|
5
5
|
|
|
6
6
|
|
|
@@ -12,18 +12,18 @@ function defineElement({
|
|
|
12
12
|
nameWithDash,
|
|
13
13
|
html,
|
|
14
14
|
css,
|
|
15
|
+
styleSheets,
|
|
15
16
|
display,
|
|
16
17
|
propertyList,
|
|
17
18
|
actionList,
|
|
18
19
|
eventHandlerList
|
|
19
20
|
}) {
|
|
20
|
-
if (customElements.get(nameWithDash))
|
|
21
|
-
return false;
|
|
21
|
+
if (customElements.get(nameWithDash)) return false;
|
|
22
22
|
const el = class extends HTMLElement {
|
|
23
23
|
constructor() {
|
|
24
24
|
super();
|
|
25
25
|
const root = this;
|
|
26
|
-
addHtml(this, html, css, display);
|
|
26
|
+
addHtml(this, html, css, styleSheets, display);
|
|
27
27
|
this.wi = {};
|
|
28
28
|
this.wi.properties = bindProperties(this, propertyList);
|
|
29
29
|
this.wi.actions = defineActions(this, actionList);
|
|
@@ -41,8 +41,7 @@ function defineElement({
|
|
|
41
41
|
}
|
|
42
42
|
function bindProperties(root, propertyList) {
|
|
43
43
|
const result = {};
|
|
44
|
-
if (!validatePropertyList(propertyList))
|
|
45
|
-
return result;
|
|
44
|
+
if (!validatePropertyList(propertyList)) return result;
|
|
46
45
|
propertyList.forEach((p) => addProperty(result, p, root));
|
|
47
46
|
return result;
|
|
48
47
|
}
|
|
@@ -54,13 +53,11 @@ function addProperty(obj, prop, root) {
|
|
|
54
53
|
}
|
|
55
54
|
}
|
|
56
55
|
function createOnChange(prop, root) {
|
|
57
|
-
if (!prop.onChange)
|
|
58
|
-
return void 0;
|
|
56
|
+
if (!prop.onChange) return void 0;
|
|
59
57
|
return (oldValue, newValue) => prop.onChange(root, oldValue, newValue);
|
|
60
58
|
}
|
|
61
59
|
function validatePropertyList(propertyList) {
|
|
62
|
-
if (!propertyList)
|
|
63
|
-
return false;
|
|
60
|
+
if (!propertyList) return false;
|
|
64
61
|
if (!Array.isArray(propertyList)) {
|
|
65
62
|
throw "propertyList must be an array of {name, value, [sel], [attr]} objects";
|
|
66
63
|
}
|
|
@@ -68,21 +65,18 @@ function validatePropertyList(propertyList) {
|
|
|
68
65
|
}
|
|
69
66
|
function defineActions(root, actionList) {
|
|
70
67
|
const actions = {};
|
|
71
|
-
if (!actionList)
|
|
72
|
-
return actions;
|
|
68
|
+
if (!actionList) return actions;
|
|
73
69
|
actionList.forEach((pair) => {
|
|
74
70
|
addAction(root, actions, pair.name, pair.action);
|
|
75
71
|
});
|
|
76
72
|
return actions;
|
|
77
73
|
}
|
|
78
74
|
function addAction(root, actions, name, action) {
|
|
79
|
-
if (!Objecter.isString(name) || !Objecter.isFunction(action))
|
|
80
|
-
return;
|
|
75
|
+
if (!Objecter.isString(name) || !Objecter.isFunction(action)) return;
|
|
81
76
|
actions[name] = action.bind(root);
|
|
82
77
|
}
|
|
83
78
|
function addEventListeners(root, eventHandlerList) {
|
|
84
|
-
if (!eventHandlerList)
|
|
85
|
-
return;
|
|
79
|
+
if (!eventHandlerList) return;
|
|
86
80
|
if (!Array.isArray(eventHandlerList)) {
|
|
87
81
|
throw "eventHandlerList must be an array of {sel, eventName, listener} objects";
|
|
88
82
|
}
|
|
@@ -96,11 +90,14 @@ function addHandler(root, { sel, eventName, listener }) {
|
|
|
96
90
|
});
|
|
97
91
|
});
|
|
98
92
|
}
|
|
99
|
-
function addHtml(root, html, css, display) {
|
|
93
|
+
function addHtml(root, html, css, styleSheets, display) {
|
|
100
94
|
html = getHtml(root, html);
|
|
101
95
|
const shadow = root.attachShadow({ mode: "open" });
|
|
102
96
|
const nodes = Domer.createElements(getCss(css, display) + html);
|
|
103
97
|
shadow.append(...nodes);
|
|
98
|
+
if (Array.isArray(styleSheets) && styleSheets.length > 0) {
|
|
99
|
+
shadow.adoptedStyleSheets.push(...styleSheets);
|
|
100
|
+
}
|
|
104
101
|
}
|
|
105
102
|
function getHtml(root, html) {
|
|
106
103
|
return Objecter.isFunction(html) ? html(root) : html;
|
|
@@ -110,8 +107,7 @@ function getCss(css, display) {
|
|
|
110
107
|
}
|
|
111
108
|
function buildCss(css) {
|
|
112
109
|
css = Stringer.trim(css);
|
|
113
|
-
if (css.length === 0)
|
|
114
|
-
return "";
|
|
110
|
+
if (css.length === 0) return "";
|
|
115
111
|
if (!Stringer.startsWith(css, "<style>", false)) {
|
|
116
112
|
css = Domer.tag("style", {}, css);
|
|
117
113
|
}
|
|
@@ -119,8 +115,7 @@ function buildCss(css) {
|
|
|
119
115
|
}
|
|
120
116
|
function displayStyle(display) {
|
|
121
117
|
display = Stringer.trim(display);
|
|
122
|
-
if (display.length === 0)
|
|
123
|
-
return "";
|
|
118
|
+
if (display.length === 0) return "";
|
|
124
119
|
return `
|
|
125
120
|
<style>
|
|
126
121
|
:host { display: ${display};}
|
|
@@ -1,15 +1,15 @@
|
|
|
1
1
|
// webitem.js Library to simplify creating HTML5 Custom Elements
|
|
2
2
|
// https://github.com/ahabra/webitem
|
|
3
|
-
// Copyright 2021 (C) Abdul Habra. Version 0.
|
|
3
|
+
// Copyright 2021 (C) Abdul Habra. Version 0.7.0.
|
|
4
4
|
// Apache License Version 2.0
|
|
5
5
|
|
|
6
6
|
|
|
7
|
-
var webitem=(()=>{var
|
|
7
|
+
var webitem=(()=>{var S=Object.defineProperty;var re=Object.getOwnPropertyDescriptor;var ie=Object.getOwnPropertyNames;var ue=Object.prototype.hasOwnProperty;var oe=(e,t)=>{for(var n in t)S(e,n,{get:t[n],enumerable:!0})},fe=(e,t,n,r)=>{if(t&&typeof t=="object"||typeof t=="function")for(let i of ie(t))!ue.call(e,i)&&i!==n&&S(e,i,{get:()=>t[i],enumerable:!(r=re(t,i))||r.enumerable});return e};var se=e=>fe(S({},"__esModule",{value:!0}),e);var ct={};oe(ct,{defineElement:()=>Ze});var ae=Object.defineProperty,p=(e,t)=>{for(var n in t)ae(e,n,{get:t[n],enumerable:!0})},l={};p(l,{add:()=>Ce,all:()=>M,classPresentIf:()=>Pe,createElement:()=>Le,createElements:()=>_,first:()=>we,getAttributes:()=>Ae,id:()=>be,removeElements:()=>$e,setContent:()=>Te,tag:()=>W});var d={};p(d,{equals:()=>F,forEachEntry:()=>O,has:()=>de,isDate:()=>A,isFunction:()=>R,isInteger:()=>le,isNil:()=>ce,isNumber:()=>j,isRegExp:()=>q,isString:()=>y});function ce(e){return e==null}function y(e){return m(e,"String")}function R(e){return m(e,"Function")}function A(e){return m(e,"Date")}function j(e){return m(e,"Number")?Number.isNaN(e)?!1:Number.isFinite(e):!y(e)||(e=e.trim(),e==="")?!1:!isNaN(e)}function le(e){return j(e)?Number.isInteger(Number.parseFloat(e)):!1}function q(e){return m(e,"RegExp")}function m(e,t){return Object.prototype.toString.call(e)===`[object ${t}]`}function O(e,t){if(!(!e||!t)){if(Array.isArray(e)){e.forEach((n,r)=>{t(r,n)});return}Object.entries(e).forEach(n=>t(n[0],n[1]))}}function de(e,t){return!e||!t?!1:Object.prototype.hasOwnProperty.call(e,t)}function F(e,t){return e===t?!0:e===void 0||t===void 0?!1:me(e,t)}function me(e,t){return T(e)||T(t)?e===t:ge(e,t)}var he=new Set(["boolean","number","bigint","string","symbol"]);function T(e){return he.has(typeof e)}function ge(e,t){return pe(e,t)?ye(e,t)?!0:Ee(e,t):!1}function pe(e,t){return $(e)===$(t)}function $(e){return Object.prototype.toString.call(e)}function ye(e,t){return A(e)&&A(t)?e.getTime()===t.getTime():!1}function Ee(e,t){let n=Object.keys(e);return n.length!==Object.keys(t).length?!1:n.every(r=>F(e[r],t[r]))}function be(e,t=document){return x(t)&&(t=t.shadowRoot),t.getElementById(e)}function M(e,t=document){return x(t)&&(t=t.shadowRoot),Array.from(t.querySelectorAll(e))}function we(e,t=document){return x(t)&&(t=t.shadowRoot),e.includes("/")?ve(e,t):t.querySelector(e)}function ve(e,t){let n=e.split("/").map(r=>r.trim()).filter(r=>r.length>0);for(let r of n)if(t=Se(r,t),t===null)break;return t}function Se(e,t){return e==="shadowRoot"||e==="shadow-root"?t.shadowRoot:t.querySelector(e)}function x(e){return e&&e.shadowRoot&&e.tagName.includes("-")}function Ae(e){let t={},n=e.attributes;if(!n||n.length===0)return t;for(let r=0;r<n.length;r++){let i=n[r];t[i.name]=i.value}return t}function _(e=""){if(e=e.trim(),!e)return[];let t=document.createElement("template");return t.innerHTML=e,Array.from(t.content.childNodes)}function Le(e,t={},n=""){let r=W(e,t,n),i=_(r);return i.length===0?null:i[0]}function W(e,t={},n=""){if(!e)return"";let r=Oe(t);return`<${e}${r}>${n}</${e}>`}function Oe(e){let t=[];return O(e,(r,i)=>{t.push(`${r}="${i}"`)}),(t.length>0?" ":"")+t.join(" ")}var xe=new Set(["beforebegin","afterbegin","beforeend","afterend"]);function Ce(e,t,n="beforeend"){return n=n.toLowerCase(),xe.has(n)?(y(t)?e.insertAdjacentHTML(n,t):Ne(e,t,n),!0):!1}function Ne(e,t,n){Array.isArray(t)?t.forEach(r=>e.insertAdjacentElement(n,r)):e.insertAdjacentElement(n,t)}function Te(e,...t){e.innerHTML="",e.append(...t)}function $e(e,t=document){M(e,t).forEach(r=>{r.parentNode.removeChild(r)})}function Pe(e,t,n){if(!e)return;let r=n?"add":"remove";e.classList[r](t)}var h={};p(h,{endsWith:()=>H,indexOf:()=>C,indexOfFirstMatch:()=>Re,indexOfLastMatch:()=>je,isEmpty:()=>E,removePrefix:()=>I,removeSuffix:()=>V,removeSurrounding:()=>qe,replaceAll:()=>k,replaceTemplate:()=>_e,startsWith:()=>D,strip:()=>He,stripEnd:()=>De,stripStart:()=>We,substringAfter:()=>Fe,substringBefore:()=>Me,trim:()=>L});function C(e,t,n=0,r=!1){return e?r?e.toLowerCase().indexOf(t.toLowerCase(),n):e.indexOf(t,n):-1}function Re(e,t){return!t||!e?-1:e.split("").findIndex(t)}function je(e,t){if(!t||!e)return-1;let n=e.split("");for(let r=n.length;r>=0;--r)if(t(n[r],r))return r;return-1}function D(e="",t=void 0,n=!1){if(n){let r=e.substring(0,t.length).toLowerCase();return t.toLowerCase()===r}return e.startsWith(t)}function H(e,t,n=!1){return n?e.toLowerCase().endsWith(t.toLowerCase()):e.endsWith(t)}function I(e,t,n=!1){return D(e,t,n)&&(e=e.substring(t.length)),e}function V(e,t,n=!1){return H(e,t,n)&&(e=e.substring(0,e.length-t.length)),e}function qe(e,t,n,r=!1){return V(I(e,t,r),n,r)}function Fe(e,t,n=!1){if(!t)return e;let r=C(e,t,0,n);return r<0?"":e.substring(r+t.length)}function Me(e,t,n=!1){if(!t)return"";let r=C(e,t,0,n);return r<0?e:e.substring(0,r)}function L(e){return E(e)?"":(y(e)||(e=String(e)),e.trim(e))}function E(e){return e==null||e===""}function k(e,t,n){if(R(String.prototype.replaceAll))return e.replaceAll(t,n);if(q(t))return e.replace(t,n);let r=new RegExp(t,"g");return e.replace(r,n)}function _e(e="",t={},n="${",r="}"){return O(t,(i,u)=>{u!==void 0&&(i=n+i+r,e=k(e,i,u))}),e}function We(e,t=""){return E(e)?"":t?B(e,new Set(Array.from(t))):e}function B(e,t){for(let n=0;n<e.length;n++)if(!t.has(e.charAt(n)))return e.substring(n);return""}function De(e,t=""){return E(e)?"":t?z(e,new Set(Array.from(t))):e}function z(e,t){for(let n=e.length-1;n>=0;n--)if(!t.has(e.charAt(n)))return e.substring(0,n+1);return""}function He(e,t=""){if(e===void 0||e==="")return"";if(!t)return e;let n=new Set(Array.from(t));return e=B(e,n),e?z(e,n):""}var Ie={};p(Ie,{compareLines:()=>Ve});function Ve(e,t,{trim:n=!0,skipEmpty:r=!0,caseSensitive:i=!0}={trim:!0,skipEmpty:!0,caseSensitive:!0}){return e=P(e,{trim:n,skipEmpty:r}),t=P(t,{trim:n,skipEmpty:r}),e.length!==t.length?`t1 has ${e.length} lines(s) while t2 has ${t.length} line(s).`:ke(e,t,i)}function ke(e,t,n){for(let r=0;r<e.length;r++){let i=Be(e[r],t[r],r,n);if(i.length>0)return i}return""}function Be(e,t,n,r){let i=r?e:e.toLowerCase(),u=r?t:t.toLowerCase();return i!==u?`Line #${n+1} mismatch.
|
|
8
8
|
${e}
|
|
9
|
-
${t}`:""}function
|
|
10
|
-
`),t&&(e=e.map(r=>
|
|
9
|
+
${t}`:""}function P(e,{trim:t,skipEmpty:n}){return t&&(e=L(e)),e=e.split(`
|
|
10
|
+
`),t&&(e=e.map(r=>L(r))),n&&(e=e.filter(r=>!!r)),e}function N({obj:e={},prop:t,sel:n,attr:r,root:i=document,getter:u,setter:o,onChange:f}){Ye(t),Ge(e,t);let g={};return u||(u=()=>Je({prop:t,sel:n,attr:r,root:i,objNotBound:g})),o||(o=s=>Ke({prop:t,value:s,root:i,sel:n,attr:r,objNotBound:g})),ze({obj:e,prop:t,getter:u,setter:o,onChange:f})}function ze({obj:e,prop:t,getter:n,setter:r,onChange:i}){return Object.defineProperty(e,t,{get:()=>n(),set:o=>{if(i){let f=n(t);f!==o&&i(f,o)}r(o)},configurable:!0,enumerable:!0}),e}var b=e=>e.type==="checkbox",w=e=>e.type==="radio",J=e=>e.nodeName.toLowerCase()==="select",K=e=>e.nodeName.toLowerCase()==="input-field",Q=e=>"value"in e,G=e=>new Set(Array.isArray(e)?e:[e]);function Ge(e,t){let n=e[t];return n!==void 0&&(console.info(`Property '${t}' already exists in object. Will override previous definition but retain old value of ${n}.`),e[t]=n),n}function Je({prop:e,root:t,sel:n,attr:r,objNotBound:i}){return n?Qe(t,n,r):i[e]}function Ke({prop:e,value:t,root:n,sel:r,attr:i,objNotBound:u}){if(r){Ue(n,r,t,i);return}u[e]=t}function Qe(e,t,n){let r=U(e,t);if(r.length===0)return null;let i=r[0];if(n)return i.getAttribute(n);if(!Q(i))return i.innerHTML;if(b(i))return r.filter(u=>b(u)&&u.checked).map(u=>u.value==="on"?u.name:u.value);if(J(i))return[...i.querySelectorAll("option")].filter(o=>o.selected).map(o=>o.value);if(!(w(i)&&(i=r.filter(w).find(u=>u.checked),!i)))return K(i)?i.getAttribute("value"):i.value}function Ue(e,t,n,r){let i=U(e,t);if(i.length===0)return;let u=i[0];if(b(u)){let o=G(n);i.filter(b).forEach(f=>f.checked=o.has(f.value)||o.has(f.name));return}if(J(u)){let o=G(n);u.querySelectorAll("option").forEach(f=>f.selected=o.has(f.value));return}if(w(u)){i.filter(w).forEach(o=>o.checked=o.value===n);return}i.forEach(o=>Xe(o,n,r))}function Xe(e,t,n){n?e.setAttribute(n,t):Q(e)?e.value=t:K(e)?e.setAttribute("value",t):e.innerHTML=t}function U(e,t){let n=e.querySelectorAll(t);return n.length===0&&console.warn(`No elements found matching selector ${t}`),[...n]}function Ye(e){if(typeof e!="string"||e.length===0)throw"'prop' argument must be a String defining the name a property."}function Ze({nameWithDash:e,html:t,css:n,styleSheets:r,display:i,propertyList:u,actionList:o,eventHandlerList:f}){if(customElements.get(e))return!1;let g=class extends HTMLElement{constructor(){super();let s=this;ut(this,t,n,r,i),this.wi={},this.wi.properties=et(this,u),this.wi.actions=rt(this,o),it(this,f),this.wi.addProperty=function(a,c,v,ee,te){let ne={name:a,value:c,sel:v,attr:ee,onChange:te};X(s.wi.properties,ne,s)},this.wi.addAction=(a,c)=>Y(s,s.wi.actions,a,c),this.wi.addEventListener=(a,c,v)=>Z(s,{sel:a,eventName:c,listener:v})}};return customElements.define(e,g),!0}function et(e,t){let n={};return nt(t)&&t.forEach(r=>X(n,r,e)),n}function X(e,t,n){let r=tt(t,n);N({obj:e,prop:t.name,sel:t.sel,attr:t.attr,root:n.shadowRoot,onChange:r}),t.value!==void 0&&(e[t.name]=t.value)}function tt(e,t){if(e.onChange)return(n,r)=>e.onChange(t,n,r)}function nt(e){if(!e)return!1;if(!Array.isArray(e))throw"propertyList must be an array of {name, value, [sel], [attr]} objects";return!0}function rt(e,t){let n={};return t&&t.forEach(r=>{Y(e,n,r.name,r.action)}),n}function Y(e,t,n,r){!d.isString(n)||!d.isFunction(r)||(t[n]=r.bind(e))}function it(e,t){if(t){if(!Array.isArray(t))throw"eventHandlerList must be an array of {sel, eventName, listener} objects";t.forEach(n=>Z(e,n))}}function Z(e,{sel:t,eventName:n,listener:r}){l.all(t,e.shadowRoot).forEach(u=>{u.addEventListener(n,o=>{r(o,e)})})}function ut(e,t,n,r,i){t=ot(e,t);let u=e.attachShadow({mode:"open"}),o=l.createElements(ft(n,i)+t);u.append(...o),Array.isArray(r)&&r.length>0&&u.adoptedStyleSheets.push(...r)}function ot(e,t){return d.isFunction(t)?t(e):t}function ft(e,t){return at(t)+st(e)}function st(e){return e=h.trim(e),e.length===0?"":(h.startsWith(e,"<style>",!1)||(e=l.tag("style",{},e)),e)}function at(e){return e=h.trim(e),e.length===0?"":`
|
|
11
11
|
<style>
|
|
12
12
|
:host { display: ${e};}
|
|
13
13
|
:host([hidden]) {display: none;}
|
|
14
14
|
</style>
|
|
15
|
-
`}return
|
|
15
|
+
`}return se(ct);})();
|
package/dist/webitem-script.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
// webitem.js Library to simplify creating HTML5 Custom Elements
|
|
2
2
|
// https://github.com/ahabra/webitem
|
|
3
|
-
// Copyright 2021 (C) Abdul Habra. Version 0.
|
|
3
|
+
// Copyright 2021 (C) Abdul Habra. Version 0.7.0.
|
|
4
4
|
// Apache License Version 2.0
|
|
5
5
|
|
|
6
6
|
|
|
@@ -76,20 +76,16 @@ var webitem = (() => {
|
|
|
76
76
|
}
|
|
77
77
|
function isNumber(n) {
|
|
78
78
|
if (isType(n, "Number")) {
|
|
79
|
-
if (Number.isNaN(n))
|
|
80
|
-
return false;
|
|
79
|
+
if (Number.isNaN(n)) return false;
|
|
81
80
|
return Number.isFinite(n);
|
|
82
81
|
}
|
|
83
|
-
if (!isString(n))
|
|
84
|
-
return false;
|
|
82
|
+
if (!isString(n)) return false;
|
|
85
83
|
n = n.trim();
|
|
86
|
-
if (n === "")
|
|
87
|
-
return false;
|
|
84
|
+
if (n === "") return false;
|
|
88
85
|
return !isNaN(n);
|
|
89
86
|
}
|
|
90
87
|
function isInteger(n) {
|
|
91
|
-
if (!isNumber(n))
|
|
92
|
-
return false;
|
|
88
|
+
if (!isNumber(n)) return false;
|
|
93
89
|
return Number.isInteger(Number.parseFloat(n));
|
|
94
90
|
}
|
|
95
91
|
function isRegExp(re) {
|
|
@@ -99,8 +95,7 @@ var webitem = (() => {
|
|
|
99
95
|
return Object.prototype.toString.call(v) === `[object ${type}]`;
|
|
100
96
|
}
|
|
101
97
|
function forEachEntry(object, func) {
|
|
102
|
-
if (!object || !func)
|
|
103
|
-
return;
|
|
98
|
+
if (!object || !func) return;
|
|
104
99
|
if (Array.isArray(object)) {
|
|
105
100
|
object.forEach((v, index) => {
|
|
106
101
|
func(index, v);
|
|
@@ -110,20 +105,16 @@ var webitem = (() => {
|
|
|
110
105
|
Object.entries(object).forEach((p) => func(p[0], p[1]));
|
|
111
106
|
}
|
|
112
107
|
function has(object, propName) {
|
|
113
|
-
if (!object || !propName)
|
|
114
|
-
return false;
|
|
108
|
+
if (!object || !propName) return false;
|
|
115
109
|
return Object.prototype.hasOwnProperty.call(object, propName);
|
|
116
110
|
}
|
|
117
111
|
function equals(a, b) {
|
|
118
|
-
if (a === b)
|
|
119
|
-
|
|
120
|
-
if (a === void 0 || b === void 0)
|
|
121
|
-
return false;
|
|
112
|
+
if (a === b) return true;
|
|
113
|
+
if (a === void 0 || b === void 0) return false;
|
|
122
114
|
return isEqual(a, b);
|
|
123
115
|
}
|
|
124
116
|
function isEqual(a, b) {
|
|
125
|
-
if (isSimpleType(a) || isSimpleType(b))
|
|
126
|
-
return a === b;
|
|
117
|
+
if (isSimpleType(a) || isSimpleType(b)) return a === b;
|
|
127
118
|
return isEqualCompoundType(a, b);
|
|
128
119
|
}
|
|
129
120
|
var simpleTypes = /* @__PURE__ */ new Set(["boolean", "number", "bigint", "string", "symbol"]);
|
|
@@ -131,10 +122,8 @@ var webitem = (() => {
|
|
|
131
122
|
return simpleTypes.has(typeof v);
|
|
132
123
|
}
|
|
133
124
|
function isEqualCompoundType(a, b) {
|
|
134
|
-
if (!isEqualType(a, b))
|
|
135
|
-
|
|
136
|
-
if (isEqualDates(a, b))
|
|
137
|
-
return true;
|
|
125
|
+
if (!isEqualType(a, b)) return false;
|
|
126
|
+
if (isEqualDates(a, b)) return true;
|
|
138
127
|
return isEqualObjects(a, b);
|
|
139
128
|
}
|
|
140
129
|
function isEqualType(a, b) {
|
|
@@ -151,8 +140,7 @@ var webitem = (() => {
|
|
|
151
140
|
}
|
|
152
141
|
function isEqualObjects(a, b) {
|
|
153
142
|
const akeys = Object.keys(a);
|
|
154
|
-
if (akeys.length !== Object.keys(b).length)
|
|
155
|
-
return false;
|
|
143
|
+
if (akeys.length !== Object.keys(b).length) return false;
|
|
156
144
|
return akeys.every((k) => equals(a[k], b[k]));
|
|
157
145
|
}
|
|
158
146
|
function id(elementId, root = document) {
|
|
@@ -174,11 +162,13 @@ var webitem = (() => {
|
|
|
174
162
|
if (!selector.includes("/")) {
|
|
175
163
|
return root.querySelector(selector);
|
|
176
164
|
}
|
|
165
|
+
return traverseSelectorPath(selector, root);
|
|
166
|
+
}
|
|
167
|
+
function traverseSelectorPath(selector, root) {
|
|
177
168
|
const path = selector.split("/").map((p) => p.trim()).filter((p) => p.length > 0);
|
|
178
169
|
for (const p of path) {
|
|
179
170
|
root = nextChild(p, root);
|
|
180
|
-
if (root === null)
|
|
181
|
-
break;
|
|
171
|
+
if (root === null) break;
|
|
182
172
|
}
|
|
183
173
|
return root;
|
|
184
174
|
}
|
|
@@ -192,8 +182,7 @@ var webitem = (() => {
|
|
|
192
182
|
function getAttributes(el) {
|
|
193
183
|
const result = {};
|
|
194
184
|
const atts = el.attributes;
|
|
195
|
-
if (!atts || atts.length === 0)
|
|
196
|
-
return result;
|
|
185
|
+
if (!atts || atts.length === 0) return result;
|
|
197
186
|
for (let i = 0; i < atts.length; i++) {
|
|
198
187
|
const a = atts[i];
|
|
199
188
|
result[a.name] = a.value;
|
|
@@ -202,8 +191,7 @@ var webitem = (() => {
|
|
|
202
191
|
}
|
|
203
192
|
function createElements(html = "") {
|
|
204
193
|
html = html.trim();
|
|
205
|
-
if (!html)
|
|
206
|
-
return [];
|
|
194
|
+
if (!html) return [];
|
|
207
195
|
const temp = document.createElement("template");
|
|
208
196
|
temp.innerHTML = html;
|
|
209
197
|
return Array.from(temp.content.childNodes);
|
|
@@ -211,13 +199,11 @@ var webitem = (() => {
|
|
|
211
199
|
function createElement(name, attributes = {}, content = "") {
|
|
212
200
|
const html = tag(name, attributes, content);
|
|
213
201
|
const elements = createElements(html);
|
|
214
|
-
if (elements.length === 0)
|
|
215
|
-
return null;
|
|
202
|
+
if (elements.length === 0) return null;
|
|
216
203
|
return elements[0];
|
|
217
204
|
}
|
|
218
205
|
function tag(name, attributes = {}, content = "") {
|
|
219
|
-
if (!name)
|
|
220
|
-
return "";
|
|
206
|
+
if (!name) return "";
|
|
221
207
|
const atts = attsToString(attributes);
|
|
222
208
|
return `<${name}${atts}>${content}</${name}>`;
|
|
223
209
|
}
|
|
@@ -232,8 +218,7 @@ var webitem = (() => {
|
|
|
232
218
|
var LOCATIONS = /* @__PURE__ */ new Set(["beforebegin", "afterbegin", "beforeend", "afterend"]);
|
|
233
219
|
function add(target, tobeAdded, location = "beforeend") {
|
|
234
220
|
location = location.toLowerCase();
|
|
235
|
-
if (!LOCATIONS.has(location))
|
|
236
|
-
return false;
|
|
221
|
+
if (!LOCATIONS.has(location)) return false;
|
|
237
222
|
if (isString(tobeAdded)) {
|
|
238
223
|
target.insertAdjacentHTML(location, tobeAdded);
|
|
239
224
|
} else {
|
|
@@ -259,8 +244,7 @@ var webitem = (() => {
|
|
|
259
244
|
});
|
|
260
245
|
}
|
|
261
246
|
function classPresentIf(el, cssClass, condition) {
|
|
262
|
-
if (!el)
|
|
263
|
-
return;
|
|
247
|
+
if (!el) return;
|
|
264
248
|
const func = condition ? "add" : "remove";
|
|
265
249
|
el.classList[func](cssClass);
|
|
266
250
|
}
|
|
@@ -285,25 +269,21 @@ var webitem = (() => {
|
|
|
285
269
|
trim: () => trim
|
|
286
270
|
});
|
|
287
271
|
function indexOf(st, search, fromIndex = 0, ignoreCase = false) {
|
|
288
|
-
if (!st)
|
|
289
|
-
return -1;
|
|
272
|
+
if (!st) return -1;
|
|
290
273
|
if (ignoreCase) {
|
|
291
274
|
return st.toLowerCase().indexOf(search.toLowerCase(), fromIndex);
|
|
292
275
|
}
|
|
293
276
|
return st.indexOf(search, fromIndex);
|
|
294
277
|
}
|
|
295
278
|
function indexOfFirstMatch(st, callback) {
|
|
296
|
-
if (!callback || !st)
|
|
297
|
-
return -1;
|
|
279
|
+
if (!callback || !st) return -1;
|
|
298
280
|
return st.split("").findIndex(callback);
|
|
299
281
|
}
|
|
300
282
|
function indexOfLastMatch(st, callback) {
|
|
301
|
-
if (!callback || !st)
|
|
302
|
-
return -1;
|
|
283
|
+
if (!callback || !st) return -1;
|
|
303
284
|
const chars = st.split("");
|
|
304
285
|
for (let i = chars.length; i >= 0; --i) {
|
|
305
|
-
if (callback(chars[i], i))
|
|
306
|
-
return i;
|
|
286
|
+
if (callback(chars[i], i)) return i;
|
|
307
287
|
}
|
|
308
288
|
return -1;
|
|
309
289
|
}
|
|
@@ -340,8 +320,7 @@ var webitem = (() => {
|
|
|
340
320
|
return st;
|
|
341
321
|
}
|
|
342
322
|
const i = indexOf(st, search, 0, ignoreCase);
|
|
343
|
-
if (i < 0)
|
|
344
|
-
return "";
|
|
323
|
+
if (i < 0) return "";
|
|
345
324
|
return st.substring(i + search.length);
|
|
346
325
|
}
|
|
347
326
|
function substringBefore(st, search, ignoreCase = false) {
|
|
@@ -349,13 +328,11 @@ var webitem = (() => {
|
|
|
349
328
|
return "";
|
|
350
329
|
}
|
|
351
330
|
const i = indexOf(st, search, 0, ignoreCase);
|
|
352
|
-
if (i < 0)
|
|
353
|
-
return st;
|
|
331
|
+
if (i < 0) return st;
|
|
354
332
|
return st.substring(0, i);
|
|
355
333
|
}
|
|
356
334
|
function trim(s) {
|
|
357
|
-
if (isEmpty(s))
|
|
358
|
-
return "";
|
|
335
|
+
if (isEmpty(s)) return "";
|
|
359
336
|
if (!isString(s)) {
|
|
360
337
|
s = String(s);
|
|
361
338
|
}
|
|
@@ -384,10 +361,8 @@ var webitem = (() => {
|
|
|
384
361
|
return text;
|
|
385
362
|
}
|
|
386
363
|
function stripStart(s, stripChars = "") {
|
|
387
|
-
if (isEmpty(s))
|
|
388
|
-
|
|
389
|
-
if (!stripChars)
|
|
390
|
-
return s;
|
|
364
|
+
if (isEmpty(s)) return "";
|
|
365
|
+
if (!stripChars) return s;
|
|
391
366
|
return stripStart_(s, new Set(Array.from(stripChars)));
|
|
392
367
|
}
|
|
393
368
|
function stripStart_(s, stripSet) {
|
|
@@ -399,10 +374,8 @@ var webitem = (() => {
|
|
|
399
374
|
return "";
|
|
400
375
|
}
|
|
401
376
|
function stripEnd(s, stripChars = "") {
|
|
402
|
-
if (isEmpty(s))
|
|
403
|
-
|
|
404
|
-
if (!stripChars)
|
|
405
|
-
return s;
|
|
377
|
+
if (isEmpty(s)) return "";
|
|
378
|
+
if (!stripChars) return s;
|
|
406
379
|
return stripEnd_(s, new Set(Array.from(stripChars)));
|
|
407
380
|
}
|
|
408
381
|
function stripEnd_(s, stripSet) {
|
|
@@ -414,14 +387,11 @@ var webitem = (() => {
|
|
|
414
387
|
return "";
|
|
415
388
|
}
|
|
416
389
|
function strip(s, stripChars = "") {
|
|
417
|
-
if (s === void 0 || s === "")
|
|
418
|
-
|
|
419
|
-
if (!stripChars)
|
|
420
|
-
return s;
|
|
390
|
+
if (s === void 0 || s === "") return "";
|
|
391
|
+
if (!stripChars) return s;
|
|
421
392
|
const stripSet = new Set(Array.from(stripChars));
|
|
422
393
|
s = stripStart_(s, stripSet);
|
|
423
|
-
if (!s)
|
|
424
|
-
return "";
|
|
394
|
+
if (!s) return "";
|
|
425
395
|
return stripEnd_(s, stripSet);
|
|
426
396
|
}
|
|
427
397
|
var LineCompare_exports = {};
|
|
@@ -434,6 +404,9 @@ var webitem = (() => {
|
|
|
434
404
|
if (t1.length !== t2.length) {
|
|
435
405
|
return `t1 has ${t1.length} lines(s) while t2 has ${t2.length} line(s).`;
|
|
436
406
|
}
|
|
407
|
+
return compareArraysOfLines(t1, t2, caseSensitive);
|
|
408
|
+
}
|
|
409
|
+
function compareArraysOfLines(t1, t2, caseSensitive) {
|
|
437
410
|
for (let i = 0; i < t1.length; i++) {
|
|
438
411
|
const result = compareTwoLines(t1[i], t2[i], i, caseSensitive);
|
|
439
412
|
if (result.length > 0) {
|
|
@@ -521,8 +494,7 @@ ${t2}`;
|
|
|
521
494
|
return oldValue;
|
|
522
495
|
}
|
|
523
496
|
function getValue({ prop, root, sel, attr, objNotBound }) {
|
|
524
|
-
if (sel)
|
|
525
|
-
return getDomVal(root, sel, attr);
|
|
497
|
+
if (sel) return getDomVal(root, sel, attr);
|
|
526
498
|
return objNotBound[prop];
|
|
527
499
|
}
|
|
528
500
|
function setValue({ prop, value, root, sel, attr, objNotBound }) {
|
|
@@ -534,13 +506,10 @@ ${t2}`;
|
|
|
534
506
|
}
|
|
535
507
|
function getDomVal(root, sel, attr) {
|
|
536
508
|
const elements = findElements(root, sel);
|
|
537
|
-
if (elements.length === 0)
|
|
538
|
-
return null;
|
|
509
|
+
if (elements.length === 0) return null;
|
|
539
510
|
let el = elements[0];
|
|
540
|
-
if (attr)
|
|
541
|
-
|
|
542
|
-
if (!isInput(el))
|
|
543
|
-
return el.innerHTML;
|
|
511
|
+
if (attr) return el.getAttribute(attr);
|
|
512
|
+
if (!isInput(el)) return el.innerHTML;
|
|
544
513
|
if (isCheckbox(el)) {
|
|
545
514
|
return elements.filter((e) => isCheckbox(e) && e.checked).map((e) => e.value === "on" ? e.name : e.value);
|
|
546
515
|
}
|
|
@@ -550,8 +519,7 @@ ${t2}`;
|
|
|
550
519
|
}
|
|
551
520
|
if (isRadio(el)) {
|
|
552
521
|
el = elements.filter(isRadio).find((e) => e.checked);
|
|
553
|
-
if (!el)
|
|
554
|
-
return void 0;
|
|
522
|
+
if (!el) return void 0;
|
|
555
523
|
}
|
|
556
524
|
if (isInputField(el)) {
|
|
557
525
|
return el.getAttribute("value");
|
|
@@ -560,8 +528,7 @@ ${t2}`;
|
|
|
560
528
|
}
|
|
561
529
|
function setDomVal(root, sel, val, attr) {
|
|
562
530
|
const elements = findElements(root, sel);
|
|
563
|
-
if (elements.length === 0)
|
|
564
|
-
return;
|
|
531
|
+
if (elements.length === 0) return;
|
|
565
532
|
const el = elements[0];
|
|
566
533
|
if (isCheckbox(el)) {
|
|
567
534
|
const v = toSet(val);
|
|
@@ -608,18 +575,18 @@ ${t2}`;
|
|
|
608
575
|
nameWithDash,
|
|
609
576
|
html,
|
|
610
577
|
css,
|
|
578
|
+
styleSheets,
|
|
611
579
|
display,
|
|
612
580
|
propertyList,
|
|
613
581
|
actionList,
|
|
614
582
|
eventHandlerList
|
|
615
583
|
}) {
|
|
616
|
-
if (customElements.get(nameWithDash))
|
|
617
|
-
return false;
|
|
584
|
+
if (customElements.get(nameWithDash)) return false;
|
|
618
585
|
const el = class extends HTMLElement {
|
|
619
586
|
constructor() {
|
|
620
587
|
super();
|
|
621
588
|
const root = this;
|
|
622
|
-
addHtml(this, html, css, display);
|
|
589
|
+
addHtml(this, html, css, styleSheets, display);
|
|
623
590
|
this.wi = {};
|
|
624
591
|
this.wi.properties = bindProperties(this, propertyList);
|
|
625
592
|
this.wi.actions = defineActions(this, actionList);
|
|
@@ -637,8 +604,7 @@ ${t2}`;
|
|
|
637
604
|
}
|
|
638
605
|
function bindProperties(root, propertyList) {
|
|
639
606
|
const result = {};
|
|
640
|
-
if (!validatePropertyList(propertyList))
|
|
641
|
-
return result;
|
|
607
|
+
if (!validatePropertyList(propertyList)) return result;
|
|
642
608
|
propertyList.forEach((p) => addProperty(result, p, root));
|
|
643
609
|
return result;
|
|
644
610
|
}
|
|
@@ -650,13 +616,11 @@ ${t2}`;
|
|
|
650
616
|
}
|
|
651
617
|
}
|
|
652
618
|
function createOnChange(prop, root) {
|
|
653
|
-
if (!prop.onChange)
|
|
654
|
-
return void 0;
|
|
619
|
+
if (!prop.onChange) return void 0;
|
|
655
620
|
return (oldValue, newValue) => prop.onChange(root, oldValue, newValue);
|
|
656
621
|
}
|
|
657
622
|
function validatePropertyList(propertyList) {
|
|
658
|
-
if (!propertyList)
|
|
659
|
-
return false;
|
|
623
|
+
if (!propertyList) return false;
|
|
660
624
|
if (!Array.isArray(propertyList)) {
|
|
661
625
|
throw "propertyList must be an array of {name, value, [sel], [attr]} objects";
|
|
662
626
|
}
|
|
@@ -664,21 +628,18 @@ ${t2}`;
|
|
|
664
628
|
}
|
|
665
629
|
function defineActions(root, actionList) {
|
|
666
630
|
const actions = {};
|
|
667
|
-
if (!actionList)
|
|
668
|
-
return actions;
|
|
631
|
+
if (!actionList) return actions;
|
|
669
632
|
actionList.forEach((pair) => {
|
|
670
633
|
addAction(root, actions, pair.name, pair.action);
|
|
671
634
|
});
|
|
672
635
|
return actions;
|
|
673
636
|
}
|
|
674
637
|
function addAction(root, actions, name, action) {
|
|
675
|
-
if (!Objecter_exports.isString(name) || !Objecter_exports.isFunction(action))
|
|
676
|
-
return;
|
|
638
|
+
if (!Objecter_exports.isString(name) || !Objecter_exports.isFunction(action)) return;
|
|
677
639
|
actions[name] = action.bind(root);
|
|
678
640
|
}
|
|
679
641
|
function addEventListeners(root, eventHandlerList) {
|
|
680
|
-
if (!eventHandlerList)
|
|
681
|
-
return;
|
|
642
|
+
if (!eventHandlerList) return;
|
|
682
643
|
if (!Array.isArray(eventHandlerList)) {
|
|
683
644
|
throw "eventHandlerList must be an array of {sel, eventName, listener} objects";
|
|
684
645
|
}
|
|
@@ -692,11 +653,14 @@ ${t2}`;
|
|
|
692
653
|
});
|
|
693
654
|
});
|
|
694
655
|
}
|
|
695
|
-
function addHtml(root, html, css, display) {
|
|
656
|
+
function addHtml(root, html, css, styleSheets, display) {
|
|
696
657
|
html = getHtml(root, html);
|
|
697
658
|
const shadow = root.attachShadow({ mode: "open" });
|
|
698
659
|
const nodes = Domer_exports.createElements(getCss(css, display) + html);
|
|
699
660
|
shadow.append(...nodes);
|
|
661
|
+
if (Array.isArray(styleSheets) && styleSheets.length > 0) {
|
|
662
|
+
shadow.adoptedStyleSheets.push(...styleSheets);
|
|
663
|
+
}
|
|
700
664
|
}
|
|
701
665
|
function getHtml(root, html) {
|
|
702
666
|
return Objecter_exports.isFunction(html) ? html(root) : html;
|
|
@@ -706,8 +670,7 @@ ${t2}`;
|
|
|
706
670
|
}
|
|
707
671
|
function buildCss(css) {
|
|
708
672
|
css = Stringer_exports.trim(css);
|
|
709
|
-
if (css.length === 0)
|
|
710
|
-
return "";
|
|
673
|
+
if (css.length === 0) return "";
|
|
711
674
|
if (!Stringer_exports.startsWith(css, "<style>", false)) {
|
|
712
675
|
css = Domer_exports.tag("style", {}, css);
|
|
713
676
|
}
|
|
@@ -715,8 +678,7 @@ ${t2}`;
|
|
|
715
678
|
}
|
|
716
679
|
function displayStyle(display) {
|
|
717
680
|
display = Stringer_exports.trim(display);
|
|
718
|
-
if (display.length === 0)
|
|
719
|
-
return "";
|
|
681
|
+
if (display.length === 0) return "";
|
|
720
682
|
return `
|
|
721
683
|
<style>
|
|
722
684
|
:host { display: ${display};}
|
package/eslint.config.js
ADDED
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
import js from '@eslint/js'
|
|
2
|
+
import globals from "globals"
|
|
3
|
+
import { defineConfig } from 'eslint/config'
|
|
4
|
+
|
|
5
|
+
const error = 'error'
|
|
6
|
+
const readonly = 'readonly'
|
|
7
|
+
const always = 'always'
|
|
8
|
+
const never = 'never'
|
|
9
|
+
|
|
10
|
+
export default defineConfig([
|
|
11
|
+
{
|
|
12
|
+
files: ['**/*.js'],
|
|
13
|
+
plugins: { js },
|
|
14
|
+
extends: ['js/recommended'],
|
|
15
|
+
|
|
16
|
+
languageOptions: {
|
|
17
|
+
ecmaVersion: 'latest',
|
|
18
|
+
sourceType: 'module',
|
|
19
|
+
|
|
20
|
+
globals: {
|
|
21
|
+
...globals.browser,
|
|
22
|
+
describe: readonly,
|
|
23
|
+
it: readonly,
|
|
24
|
+
beforeEach: readonly,
|
|
25
|
+
afterEach: readonly
|
|
26
|
+
}
|
|
27
|
+
},
|
|
28
|
+
|
|
29
|
+
rules: {
|
|
30
|
+
indent: [error, 2],
|
|
31
|
+
'linebreak-style': [error, 'unix'],
|
|
32
|
+
quotes: [error, 'single'],
|
|
33
|
+
semi: [error, never],
|
|
34
|
+
|
|
35
|
+
'block-scoped-var': [error],
|
|
36
|
+
complexity: [error, 6],
|
|
37
|
+
'dot-location': [error, 'object'],
|
|
38
|
+
eqeqeq: [error, always],
|
|
39
|
+
'no-else-return': [error],
|
|
40
|
+
'no-multi-spaces': [error, { ignoreEOLComments: true }],
|
|
41
|
+
'no-octal': [error],
|
|
42
|
+
'no-octal-escape': [error],
|
|
43
|
+
'no-return-assign': [error, always],
|
|
44
|
+
'no-sequences': [error],
|
|
45
|
+
'no-useless-concat': [error],
|
|
46
|
+
'no-useless-return': [error],
|
|
47
|
+
radix: [error],
|
|
48
|
+
yoda: [error],
|
|
49
|
+
|
|
50
|
+
'no-label-var': [error],
|
|
51
|
+
'brace-style': [error, '1tbs', {allowSingleLine: true}],
|
|
52
|
+
'comma-spacing': [error, {before: false, after: true}],
|
|
53
|
+
'comma-style': [error, 'last'],
|
|
54
|
+
'func-call-spacing': [error, never],
|
|
55
|
+
'key-spacing': [error, {beforeColon: false, afterColon:true}],
|
|
56
|
+
'keyword-spacing': [error],
|
|
57
|
+
'max-depth': [error, 4],
|
|
58
|
+
'max-len': [error, {code: 120, comments: 100, ignoreUrls: true}],
|
|
59
|
+
'max-lines': [error, {max: 300, skipBlankLines: true, skipComments: false}],
|
|
60
|
+
'max-lines-per-function': [error, {max: 200, skipBlankLines: true, skipComments: true, IIFEs: false}],
|
|
61
|
+
'max-nested-callbacks': [error, 4],
|
|
62
|
+
'max-params': [error, 5],
|
|
63
|
+
'max-statements': [error, 10],
|
|
64
|
+
'max-statements-per-line': [error, {max: 2}],
|
|
65
|
+
'new-cap': [error],
|
|
66
|
+
'new-parens': [error, always],
|
|
67
|
+
'no-array-constructor': [error],
|
|
68
|
+
'no-bitwise': [error],
|
|
69
|
+
'no-lonely-if': [error],
|
|
70
|
+
'no-multi-assign': [error],
|
|
71
|
+
'no-multiple-empty-lines': [error, {max: 3, maxBOF: 1, maxEOF: 1}],
|
|
72
|
+
'no-nested-ternary': [error],
|
|
73
|
+
'no-new-object': [error],
|
|
74
|
+
'no-tabs': [error],
|
|
75
|
+
'no-trailing-spaces': [error],
|
|
76
|
+
'no-unneeded-ternary': [error],
|
|
77
|
+
'no-whitespace-before-property': [error],
|
|
78
|
+
'nonblock-statement-body-position': [error, 'beside'],
|
|
79
|
+
'prefer-exponentiation-operator': [error],
|
|
80
|
+
'quote-props': [error, 'as-needed'],
|
|
81
|
+
'semi-spacing': [error],
|
|
82
|
+
'semi-style': [error],
|
|
83
|
+
'space-before-function-paren': [error, never],
|
|
84
|
+
'space-infix-ops': [error],
|
|
85
|
+
'spaced-comment': [error, always],
|
|
86
|
+
'switch-colon-spacing': [error],
|
|
87
|
+
'no-duplicate-imports': [error],
|
|
88
|
+
'no-useless-computed-key': [error],
|
|
89
|
+
'no-useless-constructor': [error],
|
|
90
|
+
'no-var': [error],
|
|
91
|
+
'prefer-const': [error],
|
|
92
|
+
'prefer-rest-params': [error]
|
|
93
|
+
},
|
|
94
|
+
}
|
|
95
|
+
]);
|
package/package.json
CHANGED
|
@@ -1,11 +1,12 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@techexp/webitem",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.7.0",
|
|
4
4
|
"description": "Library to simplify creating Web Components/Custom Elements",
|
|
5
5
|
"author": "Abdul Habra",
|
|
6
6
|
"license": "Apache",
|
|
7
7
|
"repository": "ahabra/webitem",
|
|
8
8
|
"main": "dist/webitem-esm.js",
|
|
9
|
+
"type": "module",
|
|
9
10
|
"keywords": [
|
|
10
11
|
"web component",
|
|
11
12
|
"custom element"
|
|
@@ -29,18 +30,18 @@
|
|
|
29
30
|
},
|
|
30
31
|
"devDependencies": {
|
|
31
32
|
"@esm-bundle/chai": "^4.3.4",
|
|
32
|
-
"@web/test-runner": "^0.
|
|
33
|
+
"@web/test-runner": "^0.20.2",
|
|
33
34
|
"@web/test-runner-commands": "^0.9.0",
|
|
34
|
-
"@web/test-runner-puppeteer": "^0.
|
|
35
|
-
"chalk": "^5.
|
|
36
|
-
"esbuild": "^0.
|
|
37
|
-
"eslint": "^
|
|
38
|
-
"fs-extra": "^11.
|
|
39
|
-
"npm-check-updates": "^
|
|
40
|
-
"serve": "^14.2.
|
|
35
|
+
"@web/test-runner-puppeteer": "^0.18.0",
|
|
36
|
+
"chalk": "^5.6.2",
|
|
37
|
+
"esbuild": "^0.27.2",
|
|
38
|
+
"eslint": "^9.39.2",
|
|
39
|
+
"fs-extra": "^11.3.3",
|
|
40
|
+
"npm-check-updates": "^19.3.1",
|
|
41
|
+
"serve": "^14.2.5"
|
|
41
42
|
},
|
|
42
43
|
"dependencies": {
|
|
43
|
-
"@techexp/data-bind": "^0.9.
|
|
44
|
-
"@techexp/jshelper": "^0.
|
|
44
|
+
"@techexp/data-bind": "^0.9.5",
|
|
45
|
+
"@techexp/jshelper": "^0.7.2"
|
|
45
46
|
}
|
|
46
47
|
}
|
package/src/index.html
CHANGED
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
import {expect} from '@esm-bundle/chai'
|
|
2
|
+
import * as webitem from '../webitem'
|
|
3
|
+
import {Domer} from "@techexp/jshelper";
|
|
4
|
+
|
|
5
|
+
describe('webitem performance tests', () => {
|
|
6
|
+
const pathToLocalCss = 'src/test/perf-test.css'
|
|
7
|
+
const propertyList = [ {name: 'life', value:42} ]
|
|
8
|
+
const count = 10000
|
|
9
|
+
|
|
10
|
+
console.log(`Each benchmark repeats ${count} times:`)
|
|
11
|
+
|
|
12
|
+
it('benchmark with no css', () => {
|
|
13
|
+
const nameWithDash = 'wi-perf-no-css'
|
|
14
|
+
const html = `<h1>${nameWithDash}</h1>`
|
|
15
|
+
|
|
16
|
+
const wasCreated = webitem.defineElement({nameWithDash, html, propertyList})
|
|
17
|
+
expect(wasCreated).to.be.true
|
|
18
|
+
const el = createAndAddElement(nameWithDash, `hello`)
|
|
19
|
+
expect(getH1Color(el)).to.equal('rgb(0, 0, 0)')
|
|
20
|
+
|
|
21
|
+
const usualDelay = 80
|
|
22
|
+
benchmark('No CSS', nameWithDash, count, usualDelay)
|
|
23
|
+
})
|
|
24
|
+
|
|
25
|
+
it('benchmark with style in body', () => {
|
|
26
|
+
const nameWithDash = 'wi-perf-style-in-body'
|
|
27
|
+
const html = `
|
|
28
|
+
<style>
|
|
29
|
+
h1 { color: red; }
|
|
30
|
+
</style>
|
|
31
|
+
<h1>${nameWithDash}</h1>`
|
|
32
|
+
|
|
33
|
+
const wasCreated = webitem.defineElement({nameWithDash, html, propertyList})
|
|
34
|
+
expect(wasCreated).to.be.true
|
|
35
|
+
const el = createAndAddElement(nameWithDash, `hello`)
|
|
36
|
+
expect(getH1Color(el)).to.equal('rgb(255, 0, 0)')
|
|
37
|
+
|
|
38
|
+
const usualDelay = 80
|
|
39
|
+
benchmark('CSS style in body', nameWithDash, count, usualDelay)
|
|
40
|
+
})
|
|
41
|
+
|
|
42
|
+
|
|
43
|
+
it('benchmark with css link in html', () => {
|
|
44
|
+
const nameWithDash = 'wi-perf-css-in-html'
|
|
45
|
+
const html = `
|
|
46
|
+
<link rel="stylesheet" href="${pathToLocalCss}">
|
|
47
|
+
<h1>${nameWithDash}</h1>`
|
|
48
|
+
|
|
49
|
+
const wasCreated = webitem.defineElement({nameWithDash, html, propertyList})
|
|
50
|
+
expect(wasCreated).to.be.true
|
|
51
|
+
const el = createAndAddElement(nameWithDash, `hello`)
|
|
52
|
+
// FIXME why does this fail?
|
|
53
|
+
// expect(getH1Color(el)).to.equal('rgb(255, 0, 0)')
|
|
54
|
+
|
|
55
|
+
const usualDelay = 140
|
|
56
|
+
benchmark('CSS link in html', nameWithDash, count, usualDelay)
|
|
57
|
+
})
|
|
58
|
+
|
|
59
|
+
it('benchmark with constructable sheet', () => {
|
|
60
|
+
const nameWithDash = 'wi-perf-constructable-sheet'
|
|
61
|
+
const html = `<h1 id="title">${nameWithDash}</h1>`
|
|
62
|
+
|
|
63
|
+
const sheet = new CSSStyleSheet()
|
|
64
|
+
sheet.replaceSync('h1 { color: red; }')
|
|
65
|
+
|
|
66
|
+
const styleSheets = [sheet]
|
|
67
|
+
|
|
68
|
+
const wasCreated = webitem.defineElement({nameWithDash, html,
|
|
69
|
+
styleSheets,
|
|
70
|
+
propertyList})
|
|
71
|
+
expect(wasCreated).to.be.true
|
|
72
|
+
const el = createAndAddElement(nameWithDash, `hello`)
|
|
73
|
+
expect(getH1Color(el)).to.equal('rgb(255, 0, 0)')
|
|
74
|
+
|
|
75
|
+
const usualDelay = 70
|
|
76
|
+
benchmark('Constructable sheet', nameWithDash, count, usualDelay)
|
|
77
|
+
})
|
|
78
|
+
|
|
79
|
+
})
|
|
80
|
+
|
|
81
|
+
function benchmark(title, wiName, count, usualDelay) {
|
|
82
|
+
// warm up
|
|
83
|
+
for (let i=0; i< 100; i++) {
|
|
84
|
+
const el = createAndAddElement(wiName, `hello ${i}`)
|
|
85
|
+
expect(el.wi.properties.life).to.equal(42)
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
const t0 = Date.now()
|
|
89
|
+
for (let i=0; i< count; i++) {
|
|
90
|
+
createAndAddElement(wiName, `hello ${i}`)
|
|
91
|
+
}
|
|
92
|
+
const end = Date.now()
|
|
93
|
+
console.log(`${title}: Duration=${end-t0} millis. Usually about ${usualDelay} millis.`)
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
function createAndAddElement(name, content) {
|
|
97
|
+
const el = Domer.createElement(name, {}, content)
|
|
98
|
+
document.body.appendChild(el)
|
|
99
|
+
return el
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
function getH1Color(el) {
|
|
103
|
+
const h1 = Domer.first('h1', el.shadowRoot)
|
|
104
|
+
const style = window.getComputedStyle(h1)
|
|
105
|
+
return style.color
|
|
106
|
+
}
|
|
107
|
+
|
package/src/test/webitem.test.js
CHANGED
|
@@ -5,7 +5,7 @@ import {Domer, Objecter} from '@techexp/jshelper'
|
|
|
5
5
|
|
|
6
6
|
describe('webitem.defineElement()', () => {
|
|
7
7
|
|
|
8
|
-
describe('element
|
|
8
|
+
describe('element creation', () => {
|
|
9
9
|
it('creates a new element', () => {
|
|
10
10
|
const name = 'wi-t1'
|
|
11
11
|
webitem.defineElement({nameWithDash: name})
|
package/src/webitem.js
CHANGED
|
@@ -3,32 +3,35 @@ import bind from '@techexp/data-bind'
|
|
|
3
3
|
|
|
4
4
|
/**
|
|
5
5
|
* Define a custom element
|
|
6
|
+
*
|
|
6
7
|
* @param options An object containing the following fields
|
|
7
|
-
* nameWithDash
|
|
8
|
-
* html
|
|
9
|
-
* css
|
|
10
|
-
*
|
|
8
|
+
* * `nameWithDash`: Required. String. Name of the custom element.
|
|
9
|
+
* * `html`: Optional. String or Function. The HTML content of the element
|
|
10
|
+
* * `css`: Optional. String. The CSS to apply on the element
|
|
11
|
+
* * `styleSheets`: Optional: An array of `CSSStyleSheet` objects. This way you can share
|
|
12
|
+
* style sheets among components.
|
|
13
|
+
* * `propertyList`: Optional. Array. Objects defining properties of the element. Each property
|
|
11
14
|
* definition consists of {name, value, [sel], [attr], [onChange]}
|
|
12
|
-
* actionList
|
|
15
|
+
* * `actionList`: Optional. Array. Objects defining actions. Each action definition consists of
|
|
13
16
|
* {name, action}, where action is a function definition.
|
|
14
|
-
* eventHandlerList
|
|
17
|
+
* * `eventHandlerList`: Optional. Array. Objects defining event handlers of element. Each
|
|
15
18
|
* handler definition consists of {sel, eventName, listener}
|
|
16
|
-
* display
|
|
17
|
-
* @returns true if the element was created, false if the element already exists, in which case
|
|
19
|
+
* * `display`: Optional. String. CSS display attribute. One of inline (default), inline-block, block.
|
|
20
|
+
* @returns `true` if the element was created, `false` if the element already exists, in which case
|
|
18
21
|
* it will not be re-created.
|
|
19
22
|
*
|
|
20
|
-
* The created element is a standard DOM custom element with and extra property
|
|
23
|
+
* The created element is a standard DOM custom element with and extra property `wi` that
|
|
21
24
|
* contains the following members:
|
|
22
|
-
* properties
|
|
23
|
-
* actions
|
|
24
|
-
* addProperty(name, value, sel, attr, onChange)
|
|
25
|
+
* * `properties`: an object that contains all the defined properties in propertyList
|
|
26
|
+
* * `actions`: an object that contains all the defined actions in actionList
|
|
27
|
+
* * `addProperty(name, value, sel, attr, onChange)`: a function with the given arguments to
|
|
25
28
|
* add new properties on the instance of the web element
|
|
26
|
-
* addAction(name, action)
|
|
29
|
+
* * `addAction(name, action)`: a function with the given arguments to add new actions
|
|
27
30
|
* on the instance of the web element
|
|
28
|
-
* addEventListener(sel, eventName, listener)
|
|
31
|
+
* * `addEventListener(sel, eventName, listener)`: a function with the given arguments to
|
|
29
32
|
* add new event listeners on the instance of the web element
|
|
30
33
|
*/
|
|
31
|
-
export function defineElement({nameWithDash, html, css, display,
|
|
34
|
+
export function defineElement({nameWithDash, html, css, styleSheets, display,
|
|
32
35
|
propertyList, actionList, eventHandlerList}) {
|
|
33
36
|
|
|
34
37
|
if (customElements.get(nameWithDash)) return false
|
|
@@ -37,7 +40,7 @@ export function defineElement({nameWithDash, html, css, display,
|
|
|
37
40
|
constructor() {
|
|
38
41
|
super()
|
|
39
42
|
const root = this
|
|
40
|
-
addHtml(this, html, css, display)
|
|
43
|
+
addHtml(this, html, css, styleSheets, display)
|
|
41
44
|
this.wi = {}
|
|
42
45
|
this.wi.properties = bindProperties(this, propertyList)
|
|
43
46
|
this.wi.actions = defineActions(this, actionList)
|
|
@@ -117,12 +120,15 @@ function addHandler(root, {sel, eventName, listener}) {
|
|
|
117
120
|
})
|
|
118
121
|
}
|
|
119
122
|
|
|
120
|
-
function addHtml(root, html, css, display) {
|
|
123
|
+
function addHtml(root, html, css, styleSheets, display) {
|
|
121
124
|
html = getHtml(root, html)
|
|
122
125
|
|
|
123
126
|
const shadow = root.attachShadow({mode: 'open'})
|
|
124
127
|
const nodes = Domer.createElements(getCss(css, display) + html)
|
|
125
128
|
shadow.append(...nodes)
|
|
129
|
+
if (Array.isArray(styleSheets) && styleSheets.length > 0) {
|
|
130
|
+
shadow.adoptedStyleSheets.push(...styleSheets)
|
|
131
|
+
}
|
|
126
132
|
}
|
|
127
133
|
|
|
128
134
|
function getHtml(root, html) {
|
package/.eslintrc.js
DELETED
|
@@ -1,92 +0,0 @@
|
|
|
1
|
-
const error = 'error'
|
|
2
|
-
const readonly = 'readonly'
|
|
3
|
-
const always = 'always'
|
|
4
|
-
const never = 'never'
|
|
5
|
-
|
|
6
|
-
module.exports = {
|
|
7
|
-
extends: 'eslint:recommended',
|
|
8
|
-
|
|
9
|
-
env: {
|
|
10
|
-
browser: true,
|
|
11
|
-
es2021: true
|
|
12
|
-
},
|
|
13
|
-
|
|
14
|
-
parserOptions: {
|
|
15
|
-
ecmaVersion: 12,
|
|
16
|
-
sourceType: 'module'
|
|
17
|
-
},
|
|
18
|
-
|
|
19
|
-
globals: {
|
|
20
|
-
describe: readonly,
|
|
21
|
-
it: readonly,
|
|
22
|
-
beforeEach: readonly,
|
|
23
|
-
afterEach: readonly
|
|
24
|
-
},
|
|
25
|
-
|
|
26
|
-
rules: {
|
|
27
|
-
indent: [error, 2],
|
|
28
|
-
'linebreak-style': [error, 'unix'],
|
|
29
|
-
quotes: [error, 'single'],
|
|
30
|
-
semi: [error, never],
|
|
31
|
-
|
|
32
|
-
'block-scoped-var': [error],
|
|
33
|
-
complexity: [error, 4],
|
|
34
|
-
'dot-location': [error, 'object'],
|
|
35
|
-
eqeqeq: [error, always],
|
|
36
|
-
'no-else-return': [error],
|
|
37
|
-
'no-multi-spaces': [error, { ignoreEOLComments: true }],
|
|
38
|
-
'no-octal': [error],
|
|
39
|
-
'no-octal-escape': [error],
|
|
40
|
-
'no-return-assign': [error, always],
|
|
41
|
-
'no-sequences': [error],
|
|
42
|
-
'no-useless-concat': [error],
|
|
43
|
-
'no-useless-return': [error],
|
|
44
|
-
radix: [error],
|
|
45
|
-
yoda: [error],
|
|
46
|
-
|
|
47
|
-
'no-label-var': [error],
|
|
48
|
-
'brace-style': [error, '1tbs', {allowSingleLine: true}],
|
|
49
|
-
'comma-spacing': [error, {before: false, after: true}],
|
|
50
|
-
'comma-style': [error, 'last'],
|
|
51
|
-
'func-call-spacing': [error, never],
|
|
52
|
-
'key-spacing': [error, {beforeColon: false, afterColon:true}],
|
|
53
|
-
'keyword-spacing': [error],
|
|
54
|
-
'max-depth': [error, 4],
|
|
55
|
-
'max-len': [error, {code: 120, comments: 100, ignoreUrls: true}],
|
|
56
|
-
'max-lines': [error, {max: 250, skipBlankLines: true, skipComments: false}],
|
|
57
|
-
'max-lines-per-function': [error, {max: 200, skipBlankLines: true, skipComments: true, IIFEs: false}],
|
|
58
|
-
'max-nested-callbacks': [error, 4],
|
|
59
|
-
'max-params': [error, 5],
|
|
60
|
-
'max-statements': [error, 10],
|
|
61
|
-
'max-statements-per-line': [error, {max: 2}],
|
|
62
|
-
'new-cap': [error],
|
|
63
|
-
'new-parens': [error, always],
|
|
64
|
-
'no-array-constructor': [error],
|
|
65
|
-
'no-bitwise': [error],
|
|
66
|
-
'no-lonely-if': [error],
|
|
67
|
-
'no-multi-assign': [error],
|
|
68
|
-
'no-multiple-empty-lines': [error, {max: 3, maxBOF: 1, maxEOF: 1}],
|
|
69
|
-
'no-nested-ternary': [error],
|
|
70
|
-
'no-new-object': [error],
|
|
71
|
-
'no-tabs': [error],
|
|
72
|
-
'no-trailing-spaces': [error],
|
|
73
|
-
'no-unneeded-ternary': [error],
|
|
74
|
-
'no-whitespace-before-property': [error],
|
|
75
|
-
'nonblock-statement-body-position': [error, 'beside'],
|
|
76
|
-
'prefer-exponentiation-operator': [error],
|
|
77
|
-
'quote-props': [error, 'as-needed'],
|
|
78
|
-
'semi-spacing': [error],
|
|
79
|
-
'semi-style': [error],
|
|
80
|
-
'space-before-function-paren': [error, never],
|
|
81
|
-
'space-infix-ops': [error],
|
|
82
|
-
'spaced-comment': [error, always],
|
|
83
|
-
'switch-colon-spacing': [error],
|
|
84
|
-
'no-duplicate-imports': [error],
|
|
85
|
-
'no-useless-computed-key': [error],
|
|
86
|
-
'no-useless-constructor': [error],
|
|
87
|
-
'no-var': [error],
|
|
88
|
-
'prefer-const': [error],
|
|
89
|
-
'prefer-rest-params': [error]
|
|
90
|
-
|
|
91
|
-
}
|
|
92
|
-
}
|