@webtides/element-js 1.0.0-alpha.1 → 1.0.0-alpha.2

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.
@@ -6,10 +6,12 @@ export const ATTRIBUTE_NODE = 2;
6
6
  export const TEXT_NODE = 3;
7
7
  /* A Comment node, such as <!-- … --> */
8
8
  export const COMMENT_NODE = 8;
9
+ /* A Document Fragment, a document without a parent */
10
+ export const DOCUMENT_FRAGMENT_NODE = 11;
9
11
 
10
12
  /**
11
- * Gets list of (childNode) indexes for the given node
12
- * @param node
13
+ * Gets a list of (childNode) indexes for the given node
14
+ * @param {Node} node
13
15
  * @return {number[]}
14
16
  */
15
17
  export const getNodePath = (node) => {
@@ -23,6 +25,11 @@ export const getNodePath = (node) => {
23
25
  return path;
24
26
  };
25
27
 
28
+ /**
29
+ * Get a list of all parent nodes up the DOM tree
30
+ * @param {Node} domNode
31
+ * @returns {Node[]}
32
+ */
26
33
  export function getAllParentNodes(domNode) {
27
34
  let node = domNode.parentElement;
28
35
  let parents = [];
@@ -34,7 +41,12 @@ export function getAllParentNodes(domNode) {
34
41
  return parents;
35
42
  }
36
43
 
37
- // https://stackoverflow.com/questions/27453617/how-can-i-tell-if-an-element-is-in-a-shadow-dom
44
+ /**
45
+ * Gets the parent/root element of a shadow root or the global document body if not in shadow root.
46
+ * https://stackoverflow.com/questions/27453617/how-can-i-tell-if-an-element-is-in-a-shadow-dom
47
+ * @param {Node} element
48
+ * @returns {ShadowRoot | HTMLElement}
49
+ */
38
50
  export function getShadowParentOrBody(element) {
39
51
  if (element instanceof ShadowRoot) {
40
52
  return element;
@@ -50,6 +62,11 @@ export function getShadowParentOrBody(element) {
50
62
 
51
63
  // TODO: add function for getClosestParentOfNodeType('custom-element')
52
64
 
65
+ /**
66
+ * Get the closest/first parent node that is a custom element
67
+ * @param {Node} domNode
68
+ * @returns {Node}
69
+ */
53
70
  export function getClosestParentCustomElementNode(domNode) {
54
71
  const customElementParents = getAllParentNodes(domNode).filter((node) => {
55
72
  return node.localName && node.localName.indexOf('-') !== -1;
@@ -58,19 +75,31 @@ export function getClosestParentCustomElementNode(domNode) {
58
75
  return customElementParents.pop();
59
76
  }
60
77
 
78
+ /**
79
+ * Checks whether two nodes are of the same node type
80
+ * @param {Node} nodeA
81
+ * @param {Node} nodeB
82
+ * @returns {boolean}
83
+ */
61
84
  export function isOfSameNodeType(nodeA, nodeB) {
62
85
  if (!nodeA && !nodeA.localName) return false;
63
86
  if (!nodeB && !nodeB.localName) return false;
64
87
  return nodeA.localName === nodeB.localName;
65
88
  }
66
89
 
67
- export const supportsAdoptingStyleSheets = () =>
68
- 'adoptedStyleSheets' in Document.prototype && 'replace' in CSSStyleSheet.prototype;
69
-
70
- // for IE11 we are using the ShadyDOM Polyfill. With the polyfill we cannot append stylesheets to the shadowRoot
71
- export const supportsAppendingStyleSheets = !window.ShadyDOM;
90
+ /**
91
+ * Checks if adopting style sheets is supported in browser
92
+ * @returns {boolean}
93
+ */
94
+ export const supportsAdoptingStyleSheets = () => {
95
+ return 'adoptedStyleSheets' in Document.prototype && 'replace' in CSSStyleSheet.prototype;
96
+ };
72
97
 
73
- // better hasChildNodes check because the native check will also count for empty whitespace as child nodes... :(
98
+ /**
99
+ * Better implementation of hasChildNodes check because the native check will also count for empty whitespace as child nodes... :(
100
+ * @param {Node} node
101
+ * @returns {boolean}
102
+ */
74
103
  export const hasChildNodes = (node) => {
75
104
  const childNodesLength = node.childNodes.length;
76
105
 
@@ -86,7 +115,7 @@ export const hasChildNodes = (node) => {
86
115
  };
87
116
 
88
117
  /**
89
- * Parses the given template string and returns a real DOM element.
118
+ * Parses the given string as HTML template and returns a real DOM element
90
119
  * @param {string} template
91
120
  * @returns {HTMLElement}
92
121
  */
@@ -97,8 +126,8 @@ export const convertStringToHTML = (template) => {
97
126
  };
98
127
 
99
128
  /**
100
- * Parses the given string and returns a DocumentFragment
101
- * which contains the DOM subtree representing the <template> element's template contents.
129
+ * Parses the given string and returns a DocumentFragment which contains the DOM subtree
130
+ * representing the <template> element's template contents.
102
131
  * @param {string} string
103
132
  * @return {DocumentFragment}
104
133
  */
@@ -111,8 +140,8 @@ export const convertStringToTemplate = (string) => {
111
140
 
112
141
  /**
113
142
  * Diff the attributes for a live DOM element against a template DOM element
114
- * @param {Element} templateElement The new template
115
- * @param {Element} domElement The existing DOM node
143
+ * @param {Element} templateElement - The new template
144
+ * @param {Element} domElement - The existing DOM node
116
145
  */
117
146
  export const diffAttributes = function (templateElement, domElement) {
118
147
  // remove or update previous attributes
@@ -2,6 +2,9 @@ export class Directive {
2
2
  /** @type {Element} */
3
3
  node = undefined;
4
4
 
5
+ /**
6
+ * @param {Node} node
7
+ */
5
8
  constructor(node) {
6
9
  this.node = node;
7
10
  }
@@ -10,6 +13,16 @@ export class Directive {
10
13
  * @abstract
11
14
  */
12
15
  update() {}
16
+
17
+ // TODO: this is somewhat custom... maybe we could set the initial values in the constructor and then simply override the default toString() method?!
18
+ /**
19
+ * Implement the stringify method and return a string for rendering the directive in SSR mode
20
+ * @param {...any} values
21
+ * @returns {string}
22
+ */
23
+ stringify(...values) {
24
+ return '';
25
+ }
13
26
  }
14
27
 
15
28
  /**
package/src/util/Store.js CHANGED
@@ -1,11 +1,14 @@
1
1
  import { isObjectLike, deepEquals } from './AttributeParser.js';
2
- import { BaseElement } from '../BaseElement';
2
+ import { BaseElement } from '../BaseElement.js';
3
3
 
4
4
  export class Store {
5
5
  _observer = new Set();
6
6
  _singlePropertyMode = false;
7
7
  _state = {};
8
8
 
9
+ /**
10
+ * @param {* | object} value
11
+ */
9
12
  constructor(value) {
10
13
  // wrap primitives with a generic "value" field to generate getter and setter
11
14
  this._singlePropertyMode = arguments.length > 0 && !isObjectLike(value);
@@ -33,6 +36,11 @@ export class Store {
33
36
  });
34
37
  }
35
38
 
39
+ /**
40
+ * Properties to be defined and assigned on the store. Can be overridden in extended classes.
41
+ * Properties defined here will also trigger an update cycle when changed.
42
+ * @return {{}}
43
+ */
36
44
  properties() {
37
45
  return {};
38
46
  }
@@ -40,34 +48,47 @@ export class Store {
40
48
  /**
41
49
  * When a property as the key was changed in the store, the callback function defined as value
42
50
  * will be called with `newValue` and `oldValue`
43
- * eg. { property: (oldValue, newValue) => { console.log('property changed!, oldValue, newValue); } }
44
51
  * @return {{}}
45
52
  */
46
53
  watch() {
47
54
  return {};
48
55
  }
49
56
 
57
+ /**
58
+ * Overrides `valueOf` to automatically return .value
59
+ * @returns {* | {}}
60
+ */
50
61
  valueOf() {
51
62
  return this._singlePropertyMode ? this._state.value : this._state;
52
63
  }
53
64
 
65
+ /**
66
+ * Overrides `toString` to automatically return .value
67
+ * @returns {string}
68
+ */
54
69
  toString() {
55
70
  return `${this._singlePropertyMode ? this._state.value : this._state}`;
56
71
  }
57
72
 
58
73
  /**
59
- * @param {BaseElement|Function} observer
74
+ * Add an observer
75
+ * @param {BaseElement | Function} observer
60
76
  */
61
77
  subscribe(observer) {
62
78
  this._observer.add(observer);
63
79
  }
80
+
64
81
  /**
65
- * @param {BaseElement|Function} observer
82
+ * Remove an observer
83
+ * @param {BaseElement | Function} observer
66
84
  */
67
85
  unsubscribe(observer) {
68
86
  this._observer.delete(observer);
69
87
  }
70
88
 
89
+ /**
90
+ * Request and batch an asynchronous update cycle
91
+ */
71
92
  requestUpdate() {
72
93
  this._observer.forEach(async (observer) => {
73
94
  if (observer instanceof BaseElement) {
@@ -1,7 +1,7 @@
1
1
  /**
2
2
  * Wrapper for defining custom elements so that registering an element multiple times won't crash
3
- * @param name for the tag
4
- * @param constructor for the custom element
3
+ * @param {string} name - name for the element tag
4
+ * @param {CustomElementConstructor} constructor for the custom element
5
5
  */
6
6
  export function defineElement(name, constructor) {
7
7
  try {
package/src/util/i18n.js CHANGED
@@ -1,9 +1,9 @@
1
1
  /**
2
2
  * Retrieves a translated key from a dictionary on the window object
3
3
  * Example: ${i18n('CustomElement.buttonLabel', 'Label')}
4
- * @param key to be translated
5
- * @param fallback to be used if key is not defined
6
- * @return String of the translated key or fallback or original key
4
+ * @param {string} key - to be translated
5
+ * @param {string} fallback - to be used if key is not defined
6
+ * @return {string} - String of the translated key or fallback or original key
7
7
  */
8
8
  export function i18n(key, fallback) {
9
9
  try {
@@ -1,8 +1,8 @@
1
1
  /**
2
2
  * Little wrapper function for JSON.stringify() to easily convert objects and arrays to strings
3
3
  * to be able to set them as attributes on custom elements
4
- * @param value to be stringified
5
- * @return String of the stringified value
4
+ * @param {object | array} value - to be stringified
5
+ * @return {string}
6
6
  */
7
7
  export function toString(value) {
8
8
  try {