pseudo-dom 0.4.0 → 0.5.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.
@@ -8,6 +8,9 @@
8
8
  * @type {PseudoHTMLElement}
9
9
  */
10
10
  import { HTMLElementService as PseudoHTMLElement } from '../services/HTMLElementService';
11
+ import { TextService, CommentService } from '../services/NodeService';
12
+ import { DocumentFragmentService } from '../services/DocumentFragmentService';
13
+ import { PseudoNode } from '../interfaces/PseudoNode';
11
14
  /**
12
15
  * Simulate the behaviour of the HTMLDocument Class when there is no DOM available.
13
16
  * @author Joshua Heagle <joshuaheagle@gmail.com>
@@ -25,11 +28,40 @@ declare class PseudoHTMLDocument extends PseudoHTMLElement {
25
28
  * @constructor
26
29
  */
27
30
  constructor();
31
+ get nodeName(): string;
32
+ get nodeType(): number;
33
+ get textContent(): string | null;
34
+ set textContent(text: string | null);
28
35
  /**
29
- * Create and return a PseudoHTMLElement, which is not added to the document until it is appended somewhere
36
+ * Make an element of the given type which belongs to this document but is not added anywhere until it is appended.
30
37
  * @param {string} tagName - Tag Name is a string representing the type of Dom element this represents
31
38
  * @returns {PseudoHTMLElement}
32
39
  */
33
40
  createElement(tagName?: string): PseudoHTMLElement;
41
+ /**
42
+ * Make a text node which belongs to this document.
43
+ * @param {string} [data=''] The text
44
+ * @returns {TextService}
45
+ */
46
+ createTextNode(data?: string): TextService;
47
+ /**
48
+ * Make a comment which belongs to this document.
49
+ * @param {string} [data=''] The comment
50
+ * @returns {CommentService}
51
+ */
52
+ createComment(data?: string): CommentService;
53
+ /**
54
+ * Make an empty document fragment which belongs to this document, a container for nodes which can be built up and
55
+ * then inserted in one go.
56
+ * @returns {DocumentFragmentService}
57
+ */
58
+ createDocumentFragment(): DocumentFragmentService;
59
+ /**
60
+ * Make a copy of this document. The copy has no parent or listeners, and a deep copy has copies of everything in the
61
+ * document (a shallow one is an empty document).
62
+ * @param {boolean} [deep=false] Copy everything in the document as well
63
+ * @returns {PseudoNode}
64
+ */
65
+ cloneNode(deep?: boolean): PseudoNode;
34
66
  }
35
67
  export default PseudoHTMLDocument;
@@ -1,5 +1,8 @@
1
1
  'use strict'
2
2
 
3
+ require('core-js/modules/esnext.iterator.constructor.js')
4
+ require('core-js/modules/esnext.iterator.find.js')
5
+ require('core-js/modules/esnext.iterator.for-each.js')
3
6
  Object.defineProperty(exports, '__esModule', {
4
7
  value: true
5
8
  })
@@ -13,6 +16,8 @@ Object.defineProperty(exports, '__esModule', {
13
16
  * @type {PseudoHTMLElement}
14
17
  */
15
18
  const HTMLElementService_1 = require('../services/HTMLElementService')
19
+ const NodeService_1 = require('../services/NodeService')
20
+ const DocumentFragmentService_1 = require('../services/DocumentFragmentService')
16
21
  /**
17
22
  * Simulate the behaviour of the HTMLDocument Class when there is no DOM available.
18
23
  * @author Joshua Heagle <joshuaheagle@gmail.com>
@@ -51,16 +56,89 @@ class PseudoHTMLDocument extends HTMLElementService_1.HTMLElementService {
51
56
  html.appendChild(this.body)
52
57
  }
53
58
 
59
+ get nodeName () {
60
+ return '#document'
61
+ }
62
+
63
+ get nodeType () {
64
+ return NodeService_1.NodeService.DOCUMENT_NODE
65
+ }
66
+
67
+ // A document has no text of its own, and setting it does nothing
68
+ get textContent () {
69
+ return null
70
+ }
71
+
72
+ set textContent (text) {}
54
73
  /**
55
- * Create and return a PseudoHTMLElement, which is not added to the document until it is appended somewhere
74
+ * Make an element of the given type which belongs to this document but is not added anywhere until it is appended.
56
75
  * @param {string} tagName - Tag Name is a string representing the type of Dom element this represents
57
76
  * @returns {PseudoHTMLElement}
58
77
  */
59
78
  createElement (tagName = 'div') {
60
79
  // Like the DOM, the new element is not added anywhere: it has no parent until it is appended
61
- return new HTMLElementService_1.HTMLElementService({
80
+ const element = new HTMLElementService_1.HTMLElementService({
62
81
  tagName
63
82
  })
83
+ element.ownerDocumentStore = this
84
+ return element
85
+ }
86
+
87
+ /**
88
+ * Make a text node which belongs to this document.
89
+ * @param {string} [data=''] The text
90
+ * @returns {TextService}
91
+ */
92
+ createTextNode (data = '') {
93
+ const text = new NodeService_1.TextService(data)
94
+ text.ownerDocumentStore = this
95
+ return text
96
+ }
97
+
98
+ /**
99
+ * Make a comment which belongs to this document.
100
+ * @param {string} [data=''] The comment
101
+ * @returns {CommentService}
102
+ */
103
+ createComment (data = '') {
104
+ const comment = new NodeService_1.CommentService(data)
105
+ comment.ownerDocumentStore = this
106
+ return comment
107
+ }
108
+
109
+ /**
110
+ * Make an empty document fragment which belongs to this document, a container for nodes which can be built up and
111
+ * then inserted in one go.
112
+ * @returns {DocumentFragmentService}
113
+ */
114
+ createDocumentFragment () {
115
+ const fragment = new DocumentFragmentService_1.DocumentFragmentService()
116
+ fragment.ownerDocumentStore = this
117
+ return fragment
118
+ }
119
+
120
+ /**
121
+ * Make a copy of this document. The copy has no parent or listeners, and a deep copy has copies of everything in the
122
+ * document (a shallow one is an empty document).
123
+ * @param {boolean} [deep=false] Copy everything in the document as well
124
+ * @returns {PseudoNode}
125
+ */
126
+ cloneNode (deep = false) {
127
+ const copy = new PseudoHTMLDocument()
128
+ // The new document starts out with its own html, head and body, a copy has only what was copied from this one
129
+ while (copy.firstChild) {
130
+ copy.removeChild(copy.firstChild)
131
+ }
132
+ copy.head = null
133
+ copy.body = null
134
+ if (deep) {
135
+ Array.from(this.childNodes).forEach(child => copy.appendChild(child.cloneNode(true)))
136
+ const html = Array.from(copy.childNodes).find(child => child.tagName === 'html')
137
+ const inHtml = tagName => html ? Array.from(html.childNodes).find(child => child.tagName === tagName) || null : null
138
+ copy.head = inHtml('head')
139
+ copy.body = inHtml('body')
140
+ }
141
+ return copy
64
142
  }
65
143
  }
66
144
  exports.default = PseudoHTMLDocument
@@ -1 +1 @@
1
- "use strict";Object.defineProperty(exports,"__esModule",{value:!0});const HTMLElementService_1=require("../services/HTMLElementService");class PseudoHTMLDocument extends HTMLElementService_1.HTMLElementService{constructor(){super();const e=new HTMLElementService_1.HTMLElementService({tagName:"html"});this.appendChild(e),this.head=new HTMLElementService_1.HTMLElementService({tagName:"head"}),e.appendChild(this.head),this.body=new HTMLElementService_1.HTMLElementService({tagName:"body"}),e.appendChild(this.body)}createElement(e="div"){return new HTMLElementService_1.HTMLElementService({tagName:e})}}exports.default=PseudoHTMLDocument;
1
+ "use strict";require("core-js/modules/esnext.iterator.constructor.js"),require("core-js/modules/esnext.iterator.find.js"),require("core-js/modules/esnext.iterator.for-each.js"),Object.defineProperty(exports,"__esModule",{value:!0});const HTMLElementService_1=require("../services/HTMLElementService"),NodeService_1=require("../services/NodeService"),DocumentFragmentService_1=require("../services/DocumentFragmentService");class PseudoHTMLDocument extends HTMLElementService_1.HTMLElementService{constructor(){super();const e=new HTMLElementService_1.HTMLElementService({tagName:"html"});this.appendChild(e),this.head=new HTMLElementService_1.HTMLElementService({tagName:"head"}),e.appendChild(this.head),this.body=new HTMLElementService_1.HTMLElementService({tagName:"body"}),e.appendChild(this.body)}get nodeName(){return"#document"}get nodeType(){return NodeService_1.NodeService.DOCUMENT_NODE}get textContent(){return null}set textContent(e){}createElement(e="div"){const t=new HTMLElementService_1.HTMLElementService({tagName:e});return t.ownerDocumentStore=this,t}createTextNode(e=""){const t=new NodeService_1.TextService(e);return t.ownerDocumentStore=this,t}createComment(e=""){const t=new NodeService_1.CommentService(e);return t.ownerDocumentStore=this,t}createDocumentFragment(){const e=new DocumentFragmentService_1.DocumentFragmentService;return e.ownerDocumentStore=this,e}cloneNode(e=!1){const t=new PseudoHTMLDocument;for(;t.firstChild;)t.removeChild(t.firstChild);if(t.head=null,t.body=null,e){Array.from(this.childNodes).forEach(e=>t.appendChild(e.cloneNode(!0)));const e=Array.from(t.childNodes).find(e=>"html"===e.tagName),r=t=>e&&Array.from(e.childNodes).find(e=>e.tagName===t)||null;t.head=r("head"),t.body=r("body")}return t}}exports.default=PseudoHTMLDocument;
package/dist/main.d.ts CHANGED
@@ -20,6 +20,7 @@ import { FocusEventService as PseudoFocusEvent } from './services/FocusEventServ
20
20
  import { InputEventService as PseudoInputEvent } from './services/InputEventService';
21
21
  import { CustomEventService as PseudoCustomEvent } from './services/CustomEventService';
22
22
  import simulate from './simulate';
23
+ import { TextService as PseudoText, CommentService as PseudoComment } from './services/NodeService';
23
24
  /**
24
25
  * All methods exported from this module are encapsulated within pseudoDom.
25
26
  * @author Joshua Heagle <joshuaheagle@gmail.com>
@@ -52,9 +53,11 @@ declare const pseudoDom: {
52
53
  PseudoCustomEvent: typeof PseudoCustomEvent;
53
54
  PseudoEventTarget: typeof PseudoEventTarget;
54
55
  PseudoNode: typeof PseudoNode;
56
+ PseudoText: typeof PseudoText;
57
+ PseudoComment: typeof PseudoComment;
55
58
  PseudoElement: typeof PseudoElement;
56
59
  PseudoHTMLElement: typeof PseudoHTMLElement;
57
60
  PseudoHTMLDocument: typeof PseudoHTMLDocument;
58
61
  };
59
- export { generateDocument, createEvent, eventDefaults, simulate, PseudoEvent, PseudoUIEvent, PseudoMouseEvent, PseudoPointerEvent, PseudoKeyboardEvent, PseudoFocusEvent, PseudoInputEvent, PseudoCustomEvent, PseudoEventTarget, PseudoNode, PseudoElement, PseudoHTMLElement, PseudoHTMLDocument };
62
+ export { generateDocument, createEvent, eventDefaults, simulate, PseudoEvent, PseudoUIEvent, PseudoMouseEvent, PseudoPointerEvent, PseudoKeyboardEvent, PseudoFocusEvent, PseudoInputEvent, PseudoCustomEvent, PseudoEventTarget, PseudoNode, PseudoText, PseudoComment, PseudoElement, PseudoHTMLElement, PseudoHTMLDocument };
60
63
  export default pseudoDom;
package/dist/main.js CHANGED
@@ -15,7 +15,7 @@ const __importDefault = void 0 && (void 0).__importDefault || function (mod) {
15
15
  Object.defineProperty(exports, '__esModule', {
16
16
  value: true
17
17
  })
18
- exports.PseudoHTMLDocument = exports.PseudoHTMLElement = exports.PseudoElement = exports.PseudoNode = exports.PseudoEventTarget = exports.PseudoCustomEvent = exports.PseudoInputEvent = exports.PseudoFocusEvent = exports.PseudoKeyboardEvent = exports.PseudoPointerEvent = exports.PseudoMouseEvent = exports.PseudoUIEvent = exports.PseudoEvent = exports.simulate = exports.eventDefaults = exports.createEvent = exports.generateDocument = void 0
18
+ exports.PseudoHTMLDocument = exports.PseudoHTMLElement = exports.PseudoElement = exports.PseudoComment = exports.PseudoText = exports.PseudoNode = exports.PseudoEventTarget = exports.PseudoCustomEvent = exports.PseudoInputEvent = exports.PseudoFocusEvent = exports.PseudoKeyboardEvent = exports.PseudoPointerEvent = exports.PseudoMouseEvent = exports.PseudoUIEvent = exports.PseudoEvent = exports.simulate = exports.eventDefaults = exports.createEvent = exports.generateDocument = void 0
19
19
  const EventService_1 = require('./services/EventService')
20
20
  Object.defineProperty(exports, 'PseudoEvent', {
21
21
  enumerable: true,
@@ -105,6 +105,19 @@ Object.defineProperty(exports, 'PseudoCustomEvent', {
105
105
  })
106
106
  const simulate_1 = __importDefault(require('./simulate'))
107
107
  exports.simulate = simulate_1.default
108
+ const NodeService_2 = require('./services/NodeService')
109
+ Object.defineProperty(exports, 'PseudoText', {
110
+ enumerable: true,
111
+ get: function () {
112
+ return NodeService_2.TextService
113
+ }
114
+ })
115
+ Object.defineProperty(exports, 'PseudoComment', {
116
+ enumerable: true,
117
+ get: function () {
118
+ return NodeService_2.CommentService
119
+ }
120
+ })
108
121
  /**
109
122
  * All methods exported from this module are encapsulated within pseudoDom.
110
123
  * @author Joshua Heagle <joshuaheagle@gmail.com>
@@ -126,6 +139,8 @@ const pseudoDom = {
126
139
  PseudoCustomEvent: CustomEventService_1.CustomEventService,
127
140
  PseudoEventTarget: EventTargetService_1.default,
128
141
  PseudoNode: NodeService_1.NodeService,
142
+ PseudoText: NodeService_2.TextService,
143
+ PseudoComment: NodeService_2.CommentService,
129
144
  PseudoElement: ElementService_1.ElementService,
130
145
  PseudoHTMLElement: HTMLElementService_1.HTMLElementService,
131
146
  PseudoHTMLDocument: PseudoHTMLDocument_1.default
package/dist/main.min.js CHANGED
@@ -1 +1 @@
1
- "use strict";var __importDefault=function(e){return e&&e.__esModule?e:{default:e}};Object.defineProperty(exports,"__esModule",{value:!0}),exports.PseudoHTMLDocument=exports.PseudoHTMLElement=exports.PseudoElement=exports.PseudoNode=exports.PseudoEventTarget=exports.PseudoCustomEvent=exports.PseudoInputEvent=exports.PseudoFocusEvent=exports.PseudoKeyboardEvent=exports.PseudoPointerEvent=exports.PseudoMouseEvent=exports.PseudoUIEvent=exports.PseudoEvent=exports.simulate=exports.eventDefaults=exports.createEvent=exports.generateDocument=void 0;const EventService_1=require("./services/EventService");Object.defineProperty(exports,"PseudoEvent",{enumerable:!0,get:function(){return EventService_1.EventService}});const EventTargetService_1=__importDefault(require("./services/EventTargetService"));exports.PseudoEventTarget=EventTargetService_1.default;const NodeService_1=require("./services/NodeService");Object.defineProperty(exports,"PseudoNode",{enumerable:!0,get:function(){return NodeService_1.NodeService}});const ElementService_1=require("./services/ElementService");Object.defineProperty(exports,"PseudoElement",{enumerable:!0,get:function(){return ElementService_1.ElementService}});const HTMLElementService_1=require("./services/HTMLElementService");Object.defineProperty(exports,"PseudoHTMLElement",{enumerable:!0,get:function(){return HTMLElementService_1.HTMLElementService}});const PseudoHTMLDocument_1=__importDefault(require("./classes/PseudoHTMLDocument"));exports.PseudoHTMLDocument=PseudoHTMLDocument_1.default;const generateDocument_1=__importDefault(require("./factories/generateDocument"));exports.generateDocument=generateDocument_1.default;const createEvent_1=__importDefault(require("./factories/createEvent"));exports.createEvent=createEvent_1.default;const eventDefaults_1=__importDefault(require("./factories/eventDefaults"));exports.eventDefaults=eventDefaults_1.default;const UIEventService_1=require("./services/UIEventService");Object.defineProperty(exports,"PseudoUIEvent",{enumerable:!0,get:function(){return UIEventService_1.UIEventService}});const MouseEventService_1=require("./services/MouseEventService");Object.defineProperty(exports,"PseudoMouseEvent",{enumerable:!0,get:function(){return MouseEventService_1.MouseEventService}});const PointerEventService_1=require("./services/PointerEventService");Object.defineProperty(exports,"PseudoPointerEvent",{enumerable:!0,get:function(){return PointerEventService_1.PointerEventService}});const KeyboardEventService_1=require("./services/KeyboardEventService");Object.defineProperty(exports,"PseudoKeyboardEvent",{enumerable:!0,get:function(){return KeyboardEventService_1.KeyboardEventService}});const FocusEventService_1=require("./services/FocusEventService");Object.defineProperty(exports,"PseudoFocusEvent",{enumerable:!0,get:function(){return FocusEventService_1.FocusEventService}});const InputEventService_1=require("./services/InputEventService");Object.defineProperty(exports,"PseudoInputEvent",{enumerable:!0,get:function(){return InputEventService_1.InputEventService}});const CustomEventService_1=require("./services/CustomEventService");Object.defineProperty(exports,"PseudoCustomEvent",{enumerable:!0,get:function(){return CustomEventService_1.CustomEventService}});const simulate_1=__importDefault(require("./simulate"));exports.simulate=simulate_1.default;const pseudoDom={generateDocument:generateDocument_1.default,createEvent:createEvent_1.default,eventDefaults:eventDefaults_1.default,simulate:simulate_1.default,PseudoEvent:EventService_1.EventService,PseudoUIEvent:UIEventService_1.UIEventService,PseudoMouseEvent:MouseEventService_1.MouseEventService,PseudoPointerEvent:PointerEventService_1.PointerEventService,PseudoKeyboardEvent:KeyboardEventService_1.KeyboardEventService,PseudoFocusEvent:FocusEventService_1.FocusEventService,PseudoInputEvent:InputEventService_1.InputEventService,PseudoCustomEvent:CustomEventService_1.CustomEventService,PseudoEventTarget:EventTargetService_1.default,PseudoNode:NodeService_1.NodeService,PseudoElement:ElementService_1.ElementService,PseudoHTMLElement:HTMLElementService_1.HTMLElementService,PseudoHTMLDocument:PseudoHTMLDocument_1.default};exports.default=pseudoDom,"undefined"!=typeof window&&(window.pseudoDom=pseudoDom);
1
+ "use strict";var __importDefault=function(e){return e&&e.__esModule?e:{default:e}};Object.defineProperty(exports,"__esModule",{value:!0}),exports.PseudoHTMLDocument=exports.PseudoHTMLElement=exports.PseudoElement=exports.PseudoComment=exports.PseudoText=exports.PseudoNode=exports.PseudoEventTarget=exports.PseudoCustomEvent=exports.PseudoInputEvent=exports.PseudoFocusEvent=exports.PseudoKeyboardEvent=exports.PseudoPointerEvent=exports.PseudoMouseEvent=exports.PseudoUIEvent=exports.PseudoEvent=exports.simulate=exports.eventDefaults=exports.createEvent=exports.generateDocument=void 0;const EventService_1=require("./services/EventService");Object.defineProperty(exports,"PseudoEvent",{enumerable:!0,get:function(){return EventService_1.EventService}});const EventTargetService_1=__importDefault(require("./services/EventTargetService"));exports.PseudoEventTarget=EventTargetService_1.default;const NodeService_1=require("./services/NodeService");Object.defineProperty(exports,"PseudoNode",{enumerable:!0,get:function(){return NodeService_1.NodeService}});const ElementService_1=require("./services/ElementService");Object.defineProperty(exports,"PseudoElement",{enumerable:!0,get:function(){return ElementService_1.ElementService}});const HTMLElementService_1=require("./services/HTMLElementService");Object.defineProperty(exports,"PseudoHTMLElement",{enumerable:!0,get:function(){return HTMLElementService_1.HTMLElementService}});const PseudoHTMLDocument_1=__importDefault(require("./classes/PseudoHTMLDocument"));exports.PseudoHTMLDocument=PseudoHTMLDocument_1.default;const generateDocument_1=__importDefault(require("./factories/generateDocument"));exports.generateDocument=generateDocument_1.default;const createEvent_1=__importDefault(require("./factories/createEvent"));exports.createEvent=createEvent_1.default;const eventDefaults_1=__importDefault(require("./factories/eventDefaults"));exports.eventDefaults=eventDefaults_1.default;const UIEventService_1=require("./services/UIEventService");Object.defineProperty(exports,"PseudoUIEvent",{enumerable:!0,get:function(){return UIEventService_1.UIEventService}});const MouseEventService_1=require("./services/MouseEventService");Object.defineProperty(exports,"PseudoMouseEvent",{enumerable:!0,get:function(){return MouseEventService_1.MouseEventService}});const PointerEventService_1=require("./services/PointerEventService");Object.defineProperty(exports,"PseudoPointerEvent",{enumerable:!0,get:function(){return PointerEventService_1.PointerEventService}});const KeyboardEventService_1=require("./services/KeyboardEventService");Object.defineProperty(exports,"PseudoKeyboardEvent",{enumerable:!0,get:function(){return KeyboardEventService_1.KeyboardEventService}});const FocusEventService_1=require("./services/FocusEventService");Object.defineProperty(exports,"PseudoFocusEvent",{enumerable:!0,get:function(){return FocusEventService_1.FocusEventService}});const InputEventService_1=require("./services/InputEventService");Object.defineProperty(exports,"PseudoInputEvent",{enumerable:!0,get:function(){return InputEventService_1.InputEventService}});const CustomEventService_1=require("./services/CustomEventService");Object.defineProperty(exports,"PseudoCustomEvent",{enumerable:!0,get:function(){return CustomEventService_1.CustomEventService}});const simulate_1=__importDefault(require("./simulate"));exports.simulate=simulate_1.default;const NodeService_2=require("./services/NodeService");Object.defineProperty(exports,"PseudoText",{enumerable:!0,get:function(){return NodeService_2.TextService}}),Object.defineProperty(exports,"PseudoComment",{enumerable:!0,get:function(){return NodeService_2.CommentService}});const pseudoDom={generateDocument:generateDocument_1.default,createEvent:createEvent_1.default,eventDefaults:eventDefaults_1.default,simulate:simulate_1.default,PseudoEvent:EventService_1.EventService,PseudoUIEvent:UIEventService_1.UIEventService,PseudoMouseEvent:MouseEventService_1.MouseEventService,PseudoPointerEvent:PointerEventService_1.PointerEventService,PseudoKeyboardEvent:KeyboardEventService_1.KeyboardEventService,PseudoFocusEvent:FocusEventService_1.FocusEventService,PseudoInputEvent:InputEventService_1.InputEventService,PseudoCustomEvent:CustomEventService_1.CustomEventService,PseudoEventTarget:EventTargetService_1.default,PseudoNode:NodeService_1.NodeService,PseudoText:NodeService_2.TextService,PseudoComment:NodeService_2.CommentService,PseudoElement:ElementService_1.ElementService,PseudoHTMLElement:HTMLElementService_1.HTMLElementService,PseudoHTMLDocument:PseudoHTMLDocument_1.default};exports.default=pseudoDom,"undefined"!=typeof window&&(window.pseudoDom=pseudoDom);
@@ -22,6 +22,12 @@ export declare class AttrService extends NodeService implements PseudoAttr {
22
22
  * @constructor
23
23
  */
24
24
  constructor(name?: string, value?: string, ownerElement?: PseudoElement | null, namespaceURI?: string, prefix?: string | null);
25
+ protected get acceptsChildren(): boolean;
26
+ get nodeValue(): string | null;
27
+ set nodeValue(value: string | null);
28
+ get textContent(): string | null;
29
+ set textContent(text: string | null);
30
+ protected cloneShallow(): NodeService;
25
31
  get nodeType(): number;
26
32
  get localName(): string;
27
33
  get name(): string;
@@ -30,6 +30,30 @@ class AttrService extends NodeService_1.NodeService {
30
30
  this.nodeNameValue = name
31
31
  }
32
32
 
33
+ get acceptsChildren () {
34
+ return false
35
+ }
36
+
37
+ get nodeValue () {
38
+ return this.value
39
+ }
40
+
41
+ set nodeValue (value) {
42
+ this.value = value === null ? '' : String(value)
43
+ }
44
+
45
+ get textContent () {
46
+ return this.value
47
+ }
48
+
49
+ set textContent (text) {
50
+ this.value = text === null ? '' : String(text)
51
+ }
52
+
53
+ cloneShallow () {
54
+ return new AttrService(this.localName, this.value, null, this.namespaceURI, this.prefix)
55
+ }
56
+
33
57
  get nodeType () {
34
58
  return NodeService_1.NodeService.ATTRIBUTE_NODE
35
59
  }
@@ -1 +1 @@
1
- "use strict";Object.defineProperty(exports,"__esModule",{value:!0}),exports.AttrService=void 0;const NodeService_1=require("./NodeService");class AttrService extends NodeService_1.NodeService{constructor(e="",t="",r=null,i="",s=null){super(),this.attributeName=e,this.value=t,this.element=r,this.namespace=i,this.namespacePrefix=s,this.nodeNameValue=e}get nodeType(){return NodeService_1.NodeService.ATTRIBUTE_NODE}get localName(){return this.attributeName}get name(){return this.namespacePrefix?`${this.namespacePrefix}:${this.attributeName}`:this.attributeName}get namespaceURI(){return this.namespace}get ownerElement(){return this.element}get prefix(){return this.namespacePrefix}}exports.AttrService=AttrService;
1
+ "use strict";Object.defineProperty(exports,"__esModule",{value:!0}),exports.AttrService=void 0;const NodeService_1=require("./NodeService");class AttrService extends NodeService_1.NodeService{constructor(e="",t="",r=null,i="",n=null){super(),this.attributeName=e,this.value=t,this.element=r,this.namespace=i,this.namespacePrefix=n,this.nodeNameValue=e}get acceptsChildren(){return!1}get nodeValue(){return this.value}set nodeValue(e){this.value=null===e?"":String(e)}get textContent(){return this.value}set textContent(e){this.value=null===e?"":String(e)}cloneShallow(){return new AttrService(this.localName,this.value,null,this.namespaceURI,this.prefix)}get nodeType(){return NodeService_1.NodeService.ATTRIBUTE_NODE}get localName(){return this.attributeName}get name(){return this.namespacePrefix?`${this.namespacePrefix}:${this.attributeName}`:this.attributeName}get namespaceURI(){return this.namespace}get ownerElement(){return this.element}get prefix(){return this.namespacePrefix}}exports.AttrService=AttrService;
@@ -0,0 +1 @@
1
+ export { CommentService } from './NodeService';
@@ -0,0 +1,13 @@
1
+ 'use strict'
2
+
3
+ Object.defineProperty(exports, '__esModule', {
4
+ value: true
5
+ })
6
+ exports.CommentService = void 0
7
+ const NodeService_1 = require('./NodeService')
8
+ Object.defineProperty(exports, 'CommentService', {
9
+ enumerable: true,
10
+ get: function () {
11
+ return NodeService_1.CommentService
12
+ }
13
+ })
@@ -0,0 +1 @@
1
+ "use strict";Object.defineProperty(exports,"__esModule",{value:!0}),exports.CommentService=void 0;var NodeService_1=require("./NodeService");Object.defineProperty(exports,"CommentService",{enumerable:!0,get:function(){return NodeService_1.CommentService}});
@@ -50,6 +50,26 @@ export declare class ElementService extends NodeService implements Partial<Pseud
50
50
  parent?: PseudoNode | null;
51
51
  children?: Array<any>;
52
52
  });
53
+ /**
54
+ * The attributes with the values they have now: the ones which are also properties (className, id, style, ...) can
55
+ * have been changed through the property, which does not change the stored list.
56
+ * @returns {Array<{name: string, value: *}>}
57
+ */
58
+ private currentAttributes;
59
+ get nodeName(): string;
60
+ /**
61
+ * A copy of this element without its children: the same tag and attributes (the values which are objects, such as
62
+ * style, are copied too rather than shared), but not its parent or listeners.
63
+ * @returns {ElementService}
64
+ */
65
+ protected cloneShallow(): NodeService;
66
+ /**
67
+ * Elements are equal when they have the same tag and the same attributes (in any order), which is what isEqualNode
68
+ * checks before it compares the children.
69
+ * @param {NodeService} other The element to compare with
70
+ * @returns {boolean}
71
+ */
72
+ protected equalsShallow(other: NodeService): boolean;
53
73
  get tagName(): string;
54
74
  get nodeType(): number;
55
75
  get attributes(): PseudoNamedNodeMap;
@@ -1,6 +1,7 @@
1
1
  'use strict'
2
2
 
3
3
  require('core-js/modules/esnext.iterator.constructor.js')
4
+ require('core-js/modules/esnext.iterator.every.js')
4
5
  require('core-js/modules/esnext.iterator.find.js')
5
6
  require('core-js/modules/esnext.iterator.for-each.js')
6
7
  require('core-js/modules/esnext.iterator.map.js')
@@ -22,6 +23,8 @@ const AttrService_1 = require('./AttrService')
22
23
  const DOMTokenListService_1 = require('./DOMTokenListService')
23
24
  const NamedNodeMapService_1 = require('./NamedNodeMapService')
24
25
  const getParentNodesFromAttribute_1 = __importDefault(require('../functions/getParentNodesFromAttribute'))
26
+ const cloneObject_1 = __importDefault(require('si-funciona/dist/helpers/objects/cloneObject'))
27
+ const isEqual_1 = __importDefault(require('si-funciona/dist/helpers/objects/isEqual'))
25
28
  /**
26
29
  * Simulate the behaviour of the Element Class when there is no DOM available.
27
30
  * @author Joshua Heagle <joshuaheagle@gmail.com>
@@ -86,6 +89,70 @@ class ElementService extends NodeService_1.NodeService {
86
89
  }
87
90
  }
88
91
 
92
+ /**
93
+ * The attributes with the values they have now: the ones which are also properties (className, id, style, ...) can
94
+ * have been changed through the property, which does not change the stored list.
95
+ * @returns {Array<{name: string, value: *}>}
96
+ */
97
+ currentAttributes () {
98
+ return this.attributeList.map(({
99
+ name,
100
+ value
101
+ }) => ({
102
+ name,
103
+ value: this.propertyAttributes.indexOf(name) >= 0 ? this[name] : value
104
+ }))
105
+ }
106
+
107
+ get nodeName () {
108
+ return this.tag
109
+ }
110
+
111
+ /**
112
+ * A copy of this element without its children: the same tag and attributes (the values which are objects, such as
113
+ * style, are copied too rather than shared), but not its parent or listeners.
114
+ * @returns {ElementService}
115
+ */
116
+ cloneShallow () {
117
+ const copy = new this.constructor({
118
+ tagName: this.tag
119
+ })
120
+ copy.attributeList.length = 0
121
+ this.currentAttributes().forEach(({
122
+ name,
123
+ value
124
+ }) => {
125
+ const copied = typeof value === 'object' && value !== null ? (0, cloneObject_1.default)(value) : value
126
+ copy.attributeList.push({
127
+ name,
128
+ value: copied
129
+ })
130
+ if (copy.propertyAttributes.indexOf(name) >= 0) {
131
+ copy[name] = copied
132
+ }
133
+ })
134
+ copy.ownerDocumentStore = this.ownerDocumentStore
135
+ return copy
136
+ }
137
+
138
+ /**
139
+ * Elements are equal when they have the same tag and the same attributes (in any order), which is what isEqualNode
140
+ * checks before it compares the children.
141
+ * @param {NodeService} other The element to compare with
142
+ * @returns {boolean}
143
+ */
144
+ equalsShallow (other) {
145
+ const mine = this.currentAttributes()
146
+ const theirs = other.currentAttributes()
147
+ return this.nodeName === other.nodeName && mine.length === theirs.length && mine.every(({
148
+ name,
149
+ value
150
+ }) => {
151
+ const match = theirs.find(attributeOfOther => attributeOfOther.name === name)
152
+ return typeof match !== 'undefined' && (0, isEqual_1.default)(value, match.value)
153
+ })
154
+ }
155
+
89
156
  get tagName () {
90
157
  return this.tag
91
158
  }
@@ -95,7 +162,7 @@ class ElementService extends NodeService_1.NodeService {
95
162
  }
96
163
 
97
164
  get attributes () {
98
- return new NamedNodeMapService_1.NamedNodeMapService(this.attributeList.map(({
165
+ return new NamedNodeMapService_1.NamedNodeMapService(this.currentAttributes().map(({
99
166
  name,
100
167
  value
101
168
  }) => new AttrService_1.AttrService(name, String(value), this)))
@@ -193,7 +260,7 @@ class ElementService extends NodeService_1.NodeService {
193
260
  * @returns {string|null} The value, or null when there is no such attribute
194
261
  */
195
262
  getAttribute (attributeName) {
196
- const found = this.attributeList.find(({
263
+ const found = this.currentAttributes().find(({
197
264
  name
198
265
  }) => name === attributeName)
199
266
  return found ? found.value : null
@@ -1 +1 @@
1
- "use strict";require("core-js/modules/esnext.iterator.constructor.js"),require("core-js/modules/esnext.iterator.find.js"),require("core-js/modules/esnext.iterator.for-each.js"),require("core-js/modules/esnext.iterator.map.js"),require("core-js/modules/esnext.iterator.some.js");var __importDefault=function(e){return e&&e.__esModule?e:{default:e}};Object.defineProperty(exports,"__esModule",{value:!0}),exports.ElementService=void 0;const createEvent_1=__importDefault(require("../factories/createEvent")),NodeService_1=require("./NodeService"),AttrService_1=require("./AttrService"),DOMTokenListService_1=require("./DOMTokenListService"),NamedNodeMapService_1=require("./NamedNodeMapService"),getParentNodesFromAttribute_1=__importDefault(require("../functions/getParentNodesFromAttribute"));class ElementService extends NodeService_1.NodeService{constructor({tagName:e="",attributes:t=[],parent:r=null,children:i=[]}={}){super(),this.defaultEventApplied=!1,this.tokenList=new DOMTokenListService_1.DOMTokenListService,this.tag=e,this.attributeList=t.concat([{name:"className",value:""},{name:"id",value:""},{name:"innerHTML",value:""}]),this.propertyAttributes=this.attributeList.map(({name:e})=>e),this.attributeList.forEach(({name:e,value:t})=>{this[e]=t}),i.forEach(e=>{if(!e||"number"!=typeof e.nodeType)throw new TypeError("The children of an element must be nodes.");this.appendChild(e)}),r&&r.appendChild(this)}get tagName(){return this.tag}get nodeType(){return NodeService_1.NodeService.ELEMENT_NODE}get attributes(){return new NamedNodeMapService_1.NamedNodeMapService(this.attributeList.map(({name:e,value:t})=>new AttrService_1.AttrService(e,String(t),this)))}get classList(){return this.tokenList}get className(){return this.tokenList.value}set className(e){this.tokenList.value=e}applyDefaultEvent(){let e=e=>{};if(this.defaultEventApplied)return e;switch(this.tagName){case"button":case"input":e=e=>{const t=String(this.getAttribute("type")||this.type||"").toLowerCase(),r="button"===this.tagName?"button"!==t&&"reset"!==t:/^(submit|image)$/.test(t),i=(0,getParentNodesFromAttribute_1.default)("tagName","form",this);r&&i.length&&!this.hasAttribute("disabled")&&i[i.length-1].dispatchEvent((0,createEvent_1.default)("submit",{},{browser:!0,trusted:e.isTrusted}))},super.setDefaultEvent("click",e),this.defaultEventApplied=!0}return e}childInserted(e){"function"==typeof e.applyDefaultEvent&&e.applyDefaultEvent()}hasAttribute(e){return this.attributeList.some(({name:t})=>t===e)}setAttribute(e,t){const r=this.attributeList.find(({name:t})=>t===e);r?r.value=t:this.attributeList.push({name:e,value:t}),this.propertyAttributes.indexOf(e)>=0&&(this[e]=t)}getAttribute(e){const t=this.attributeList.find(({name:t})=>t===e);return t?t.value:null}removeAttribute(e){const t=this.attributeList.findIndex(({name:t})=>t===e);t>=0&&this.attributeList.splice(t,1)}}exports.ElementService=ElementService;
1
+ "use strict";require("core-js/modules/esnext.iterator.constructor.js"),require("core-js/modules/esnext.iterator.every.js"),require("core-js/modules/esnext.iterator.find.js"),require("core-js/modules/esnext.iterator.for-each.js"),require("core-js/modules/esnext.iterator.map.js"),require("core-js/modules/esnext.iterator.some.js");var __importDefault=function(e){return e&&e.__esModule?e:{default:e}};Object.defineProperty(exports,"__esModule",{value:!0}),exports.ElementService=void 0;const createEvent_1=__importDefault(require("../factories/createEvent")),NodeService_1=require("./NodeService"),AttrService_1=require("./AttrService"),DOMTokenListService_1=require("./DOMTokenListService"),NamedNodeMapService_1=require("./NamedNodeMapService"),getParentNodesFromAttribute_1=__importDefault(require("../functions/getParentNodesFromAttribute")),cloneObject_1=__importDefault(require("si-funciona/dist/helpers/objects/cloneObject")),isEqual_1=__importDefault(require("si-funciona/dist/helpers/objects/isEqual"));class ElementService extends NodeService_1.NodeService{constructor({tagName:e="",attributes:t=[],parent:r=null,children:i=[]}={}){super(),this.defaultEventApplied=!1,this.tokenList=new DOMTokenListService_1.DOMTokenListService,this.tag=e,this.attributeList=t.concat([{name:"className",value:""},{name:"id",value:""},{name:"innerHTML",value:""}]),this.propertyAttributes=this.attributeList.map(({name:e})=>e),this.attributeList.forEach(({name:e,value:t})=>{this[e]=t}),i.forEach(e=>{if(!e||"number"!=typeof e.nodeType)throw new TypeError("The children of an element must be nodes.");this.appendChild(e)}),r&&r.appendChild(this)}currentAttributes(){return this.attributeList.map(({name:e,value:t})=>({name:e,value:this.propertyAttributes.indexOf(e)>=0?this[e]:t}))}get nodeName(){return this.tag}cloneShallow(){const e=new this.constructor({tagName:this.tag});return e.attributeList.length=0,this.currentAttributes().forEach(({name:t,value:r})=>{const i="object"==typeof r&&null!==r?(0,cloneObject_1.default)(r):r;e.attributeList.push({name:t,value:i}),e.propertyAttributes.indexOf(t)>=0&&(e[t]=i)}),e.ownerDocumentStore=this.ownerDocumentStore,e}equalsShallow(e){const t=this.currentAttributes(),r=e.currentAttributes();return this.nodeName===e.nodeName&&t.length===r.length&&t.every(({name:e,value:t})=>{const i=r.find(t=>t.name===e);return void 0!==i&&(0,isEqual_1.default)(t,i.value)})}get tagName(){return this.tag}get nodeType(){return NodeService_1.NodeService.ELEMENT_NODE}get attributes(){return new NamedNodeMapService_1.NamedNodeMapService(this.currentAttributes().map(({name:e,value:t})=>new AttrService_1.AttrService(e,String(t),this)))}get classList(){return this.tokenList}get className(){return this.tokenList.value}set className(e){this.tokenList.value=e}applyDefaultEvent(){let e=e=>{};if(this.defaultEventApplied)return e;switch(this.tagName){case"button":case"input":e=e=>{const t=String(this.getAttribute("type")||this.type||"").toLowerCase(),r="button"===this.tagName?"button"!==t&&"reset"!==t:/^(submit|image)$/.test(t),i=(0,getParentNodesFromAttribute_1.default)("tagName","form",this);r&&i.length&&!this.hasAttribute("disabled")&&i[i.length-1].dispatchEvent((0,createEvent_1.default)("submit",{},{browser:!0,trusted:e.isTrusted}))},super.setDefaultEvent("click",e),this.defaultEventApplied=!0}return e}childInserted(e){"function"==typeof e.applyDefaultEvent&&e.applyDefaultEvent()}hasAttribute(e){return this.attributeList.some(({name:t})=>t===e)}setAttribute(e,t){const r=this.attributeList.find(({name:t})=>t===e);r?r.value=t:this.attributeList.push({name:e,value:t}),this.propertyAttributes.indexOf(e)>=0&&(this[e]=t)}getAttribute(e){const t=this.currentAttributes().find(({name:t})=>t===e);return t?t.value:null}removeAttribute(e){const t=this.attributeList.findIndex(({name:t})=>t===e);t>=0&&this.attributeList.splice(t,1)}}exports.ElementService=ElementService;
@@ -29,11 +29,21 @@ export declare class NodeService extends EventTargetService implements PseudoNod
29
29
  static readonly DOCUMENT_TYPE_NODE = 10;
30
30
  static readonly DOCUMENT_FRAGMENT_NODE = 11;
31
31
  static readonly NOTATION_NODE = 12;
32
+ static readonly DOCUMENT_POSITION_DISCONNECTED = 1;
33
+ static readonly DOCUMENT_POSITION_PRECEDING = 2;
34
+ static readonly DOCUMENT_POSITION_FOLLOWING = 4;
35
+ static readonly DOCUMENT_POSITION_CONTAINS = 8;
36
+ static readonly DOCUMENT_POSITION_CONTAINED_BY = 16;
37
+ static readonly DOCUMENT_POSITION_IMPLEMENTATION_SPECIFIC = 32;
38
+ private static nextNodeId;
32
39
  children: PseudoNodeList | LinkedTreeList;
33
40
  parent: PseudoNode | null;
34
41
  protected nodeNameValue: string;
35
42
  private nodeValueStore;
36
- private textContentStore;
43
+ /** The document which made this node (createElement and the like), for when it is not in a tree yet. */
44
+ protected ownerDocumentStore: PseudoDocument | null;
45
+ /** A number for each node in the order they were made, used to give nodes which are in different trees a consistent order. */
46
+ private readonly nodeId;
37
47
  /** The linker which holds this node in the children list of its parent, from which its siblings are found (null while it has no parent). */
38
48
  protected listLinker: TreeLinker | null;
39
49
  /**
@@ -63,6 +73,24 @@ export declare class NodeService extends EventTargetService implements PseudoNod
63
73
  * @returns {PseudoNode} The added node
64
74
  */
65
75
  appendChild(childNode: PseudoNode): PseudoNode;
76
+ /**
77
+ * Whether this kind of node can have children (text, comments and attributes cannot).
78
+ * @returns {boolean}
79
+ */
80
+ protected get acceptsChildren(): boolean;
81
+ /**
82
+ * Make a copy of this node without its children, its parent or its listeners, which is what cloneNode starts from.
83
+ * Kinds of node which are made with arguments override this to give them.
84
+ * @returns {NodeService}
85
+ */
86
+ protected cloneShallow(): NodeService;
87
+ /**
88
+ * Whether another node of the same type is equal to this one apart from its children, which isEqualNode compares
89
+ * afterwards. Kinds of node with more to compare (an element has attributes) override this.
90
+ * @param {NodeService} other The node to compare with
91
+ * @returns {boolean}
92
+ */
93
+ protected equalsShallow(other: NodeService): boolean;
66
94
  /**
67
95
  * Called each time a node has been inserted as a child of this node, so that nodes which need to react to children
68
96
  * (for example elements applying default events) can do so.
@@ -70,13 +98,19 @@ export declare class NodeService extends EventTargetService implements PseudoNod
70
98
  */
71
99
  protected childInserted(child: NodeService): void;
72
100
  /**
73
- * Not implemented yet.
74
- * @throws {Error}
101
+ * Make a copy of this node (without its parent, and without its event listeners). With deep the children are copied
102
+ * too, all the way down.
103
+ * @param {boolean} [deep=false] Copy the children as well
104
+ * @returns {PseudoNode}
75
105
  */
76
106
  cloneNode(deep?: boolean): PseudoNode;
77
107
  /**
78
- * Not implemented yet.
79
- * @throws {Error}
108
+ * Say where another node is in relation to this one, as the bits of NodeService.DOCUMENT_POSITION_*: 0 for this node
109
+ * itself, DISCONNECTED (with IMPLEMENTATION_SPECIFIC and a consistent PRECEDING or FOLLOWING) for a node in another tree,
110
+ * CONTAINS + PRECEDING when the other node is an ancestor, CONTAINED_BY + FOLLOWING when it is a descendant,
111
+ * otherwise PRECEDING or FOLLOWING by their order in the tree.
112
+ * @param {PseudoNode} otherNode The node to locate
113
+ * @returns {number}
80
114
  */
81
115
  compareDocumentPosition(otherNode: PseudoNode): number;
82
116
  /**
@@ -100,13 +134,18 @@ export declare class NodeService extends EventTargetService implements PseudoNod
100
134
  insertBefore(newNode: PseudoNode, referenceNode?: PseudoNode | null): PseudoNode | PseudoDocumentFragment;
101
135
  isDefaultNamespace(namespaceURI: string | null): boolean;
102
136
  /**
103
- * Not implemented yet.
104
- * @throws {Error}
137
+ * Whether another node is the same as this one, by what they hold: the same type, name and value (an element also
138
+ * needs the same attributes), and children which are equal in the same order.
139
+ * @param {PseudoNode|null} otherNode The node to compare with
140
+ * @returns {boolean}
105
141
  */
106
- isEqualNode(otherNode: PseudoNode): boolean;
142
+ isEqualNode(otherNode: PseudoNode | null): boolean;
107
143
  isSameNode(otherNode: PseudoNode): boolean;
108
144
  lookupPrefix(namespace: string): string | null;
109
145
  lookupNamespaceURI(prefix: string): string | null;
146
+ /**
147
+ * Tidy the text below this node: neighbouring text nodes are joined into one and empty text nodes are removed.
148
+ */
110
149
  normalize(): void;
111
150
  /**
112
151
  * Remove a child from this node, it no longer has a parent or siblings afterwards.
@@ -124,3 +163,61 @@ export declare class NodeService extends EventTargetService implements PseudoNod
124
163
  */
125
164
  replaceChild(newChild: PseudoNode, oldChild: PseudoNode): PseudoNode;
126
165
  }
166
+ /**
167
+ * Simulate the behaviour of the Text Class when there is no DOM available: the text in an element.
168
+ * @author Joshua Heagle <joshuaheagle@gmail.com>
169
+ * @class
170
+ * @augments NodeService
171
+ * @property {string} data - The text
172
+ * @property {number} length - How many characters there are
173
+ * @property {string} wholeText - The text of this node and of the text nodes next to it
174
+ */
175
+ export declare class TextService extends NodeService {
176
+ /**
177
+ * @param {string} [data=''] The text
178
+ * @constructor
179
+ */
180
+ constructor(data?: string);
181
+ protected get acceptsChildren(): boolean;
182
+ get nodeName(): string;
183
+ get nodeType(): number;
184
+ get data(): string;
185
+ set data(data: string);
186
+ get length(): number;
187
+ get textContent(): string | null;
188
+ set textContent(text: string | null);
189
+ get wholeText(): string;
190
+ /**
191
+ * Break this text node in two at a position: this node keeps the text before it and a new node with the rest is put
192
+ * after this one.
193
+ * @param {number} offset How many characters stay in this node
194
+ * @returns {TextService} The new node
195
+ * @throws {Error} When the offset is beyond the end of the text
196
+ */
197
+ splitText(offset: number): TextService;
198
+ protected cloneShallow(): NodeService;
199
+ }
200
+ /**
201
+ * Simulate the behaviour of the Comment Class when there is no DOM available: a note in the markup which is not shown.
202
+ * @author Joshua Heagle <joshuaheagle@gmail.com>
203
+ * @class
204
+ * @augments NodeService
205
+ * @property {string} data - The comment
206
+ * @property {number} length - How many characters there are
207
+ */
208
+ export declare class CommentService extends NodeService {
209
+ /**
210
+ * @param {string} [data=''] The comment
211
+ * @constructor
212
+ */
213
+ constructor(data?: string);
214
+ protected get acceptsChildren(): boolean;
215
+ get nodeName(): string;
216
+ get nodeType(): number;
217
+ get data(): string;
218
+ set data(data: string);
219
+ get length(): number;
220
+ get textContent(): string | null;
221
+ set textContent(text: string | null);
222
+ protected cloneShallow(): NodeService;
223
+ }