@gjsify/dom-elements 0.4.0 → 0.4.3
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/lib/types/location-stub.d.ts +1 -1
- package/package.json +78 -75
- package/src/attr.ts +0 -61
- package/src/character-data.ts +0 -79
- package/src/comment.ts +0 -31
- package/src/document-fragment.ts +0 -137
- package/src/document.ts +0 -103
- package/src/dom-matrix.ts +0 -109
- package/src/dom-token-list.ts +0 -140
- package/src/element.ts +0 -316
- package/src/font-face.ts +0 -97
- package/src/gst-time.ts +0 -26
- package/src/html-canvas-element.ts +0 -90
- package/src/html-element.ts +0 -502
- package/src/html-image-element.spec.ts +0 -285
- package/src/html-image-element.ts +0 -295
- package/src/html-media-element.ts +0 -123
- package/src/html-video-element.ts +0 -143
- package/src/image.ts +0 -31
- package/src/index.spec.ts +0 -914
- package/src/index.ts +0 -39
- package/src/intersection-observer.ts +0 -42
- package/src/location-stub.ts +0 -20
- package/src/match-media.ts +0 -32
- package/src/mutation-observer.ts +0 -39
- package/src/named-node-map.ts +0 -159
- package/src/namespace-uri.ts +0 -11
- package/src/node-list.ts +0 -52
- package/src/node-type.ts +0 -14
- package/src/node.ts +0 -280
- package/src/property-symbol.ts +0 -23
- package/src/register/canvas.ts +0 -23
- package/src/register/document.ts +0 -64
- package/src/register/font-face.ts +0 -18
- package/src/register/helpers.ts +0 -15
- package/src/register/image.ts +0 -8
- package/src/register/location.ts +0 -6
- package/src/register/match-media.ts +0 -6
- package/src/register/navigator.ts +0 -6
- package/src/register/observers.ts +0 -10
- package/src/register.spec.ts +0 -136
- package/src/register.ts +0 -13
- package/src/resize-observer.ts +0 -28
- package/src/stubs.spec.ts +0 -284
- package/src/test.browser.mts +0 -686
- package/src/test.mts +0 -9
- package/src/text.ts +0 -67
- package/src/types/i-html-image-element.ts +0 -44
- package/src/types/image-data.ts +0 -12
- package/src/types/index.ts +0 -3
- package/src/types/predefined-color-space.ts +0 -1
- package/tsconfig.json +0 -37
- package/tsconfig.tsbuildinfo +0 -1
package/package.json
CHANGED
|
@@ -1,80 +1,83 @@
|
|
|
1
1
|
{
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
2
|
+
"name": "@gjsify/dom-elements",
|
|
3
|
+
"version": "0.4.3",
|
|
4
|
+
"description": "DOM element hierarchy (Node, Element, HTMLElement, HTMLImageElement) for GJS",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"module": "lib/esm/index.js",
|
|
7
|
+
"types": "lib/types/index.d.ts",
|
|
8
|
+
"exports": {
|
|
9
|
+
".": {
|
|
10
|
+
"types": "./lib/types/index.d.ts",
|
|
11
|
+
"default": "./lib/esm/index.js"
|
|
12
|
+
},
|
|
13
|
+
"./register": {
|
|
14
|
+
"types": "./lib/types/register.d.ts",
|
|
15
|
+
"default": "./lib/esm/register.js"
|
|
16
|
+
},
|
|
17
|
+
"./register/document": {
|
|
18
|
+
"default": "./lib/esm/register/document.js"
|
|
19
|
+
},
|
|
20
|
+
"./register/canvas": {
|
|
21
|
+
"default": "./lib/esm/register/canvas.js"
|
|
22
|
+
},
|
|
23
|
+
"./register/image": {
|
|
24
|
+
"default": "./lib/esm/register/image.js"
|
|
25
|
+
},
|
|
26
|
+
"./register/observers": {
|
|
27
|
+
"default": "./lib/esm/register/observers.js"
|
|
28
|
+
},
|
|
29
|
+
"./register/font-face": {
|
|
30
|
+
"default": "./lib/esm/register/font-face.js"
|
|
31
|
+
},
|
|
32
|
+
"./register/match-media": {
|
|
33
|
+
"default": "./lib/esm/register/match-media.js"
|
|
34
|
+
},
|
|
35
|
+
"./register/location": {
|
|
36
|
+
"default": "./lib/esm/register/location.js"
|
|
37
|
+
},
|
|
38
|
+
"./register/navigator": {
|
|
39
|
+
"default": "./lib/esm/register/navigator.js"
|
|
40
|
+
}
|
|
12
41
|
},
|
|
13
|
-
"
|
|
14
|
-
|
|
15
|
-
|
|
42
|
+
"files": [
|
|
43
|
+
"lib"
|
|
44
|
+
],
|
|
45
|
+
"sideEffects": [
|
|
46
|
+
"./lib/esm/register.js",
|
|
47
|
+
"./lib/esm/register/*.js"
|
|
48
|
+
],
|
|
49
|
+
"scripts": {
|
|
50
|
+
"clear": "rm -rf lib tsconfig.tsbuildinfo tsconfig.types.tsbuildinfo test.gjs.mjs test.node.mjs || exit 0",
|
|
51
|
+
"check": "tsc --noEmit",
|
|
52
|
+
"build": "gjsify run build:gjsify && gjsify run build:types",
|
|
53
|
+
"build:gjsify": "gjsify build --library 'src/**/*.{ts,js}' --exclude 'src/**/*.spec.{mts,ts}' 'src/test.{mts,ts}'",
|
|
54
|
+
"build:types": "tsc",
|
|
55
|
+
"build:test": "gjsify run build:test:gjs",
|
|
56
|
+
"build:test:gjs": "gjsify build src/test.mts --app gjs --outfile test.gjs.mjs",
|
|
57
|
+
"build:test:browser": "gjsify build src/test.browser.mts --app browser --outfile dist/test.browser.mjs",
|
|
58
|
+
"test": "gjsify run build:gjsify && gjsify run build:test && gjsify run test:gjs",
|
|
59
|
+
"test:gjs": "gjsify run test.gjs.mjs"
|
|
16
60
|
},
|
|
17
|
-
"
|
|
18
|
-
|
|
61
|
+
"keywords": [
|
|
62
|
+
"gjs",
|
|
63
|
+
"dom",
|
|
64
|
+
"element",
|
|
65
|
+
"node"
|
|
66
|
+
],
|
|
67
|
+
"dependencies": {
|
|
68
|
+
"@girs/gdkpixbuf-2.0": "2.0.0-4.0.0-rc.15",
|
|
69
|
+
"@girs/gjs": "4.0.0-rc.15",
|
|
70
|
+
"@girs/glib-2.0": "2.88.0-4.0.0-rc.15",
|
|
71
|
+
"@gjsify/abort-controller": "workspace:^",
|
|
72
|
+
"@gjsify/canvas2d-core": "workspace:^",
|
|
73
|
+
"@gjsify/dom-events": "workspace:^",
|
|
74
|
+
"@gjsify/fetch": "workspace:^"
|
|
19
75
|
},
|
|
20
|
-
"
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
"./register/observers": {
|
|
27
|
-
"default": "./lib/esm/register/observers.js"
|
|
28
|
-
},
|
|
29
|
-
"./register/font-face": {
|
|
30
|
-
"default": "./lib/esm/register/font-face.js"
|
|
31
|
-
},
|
|
32
|
-
"./register/match-media": {
|
|
33
|
-
"default": "./lib/esm/register/match-media.js"
|
|
34
|
-
},
|
|
35
|
-
"./register/location": {
|
|
36
|
-
"default": "./lib/esm/register/location.js"
|
|
37
|
-
},
|
|
38
|
-
"./register/navigator": {
|
|
39
|
-
"default": "./lib/esm/register/navigator.js"
|
|
76
|
+
"devDependencies": {
|
|
77
|
+
"@girs/gst-1.0": "1.28.1-4.0.0-rc.15",
|
|
78
|
+
"@gjsify/cli": "workspace:^",
|
|
79
|
+
"@gjsify/unit": "workspace:^",
|
|
80
|
+
"@types/node": "^25.6.2",
|
|
81
|
+
"typescript": "^6.0.3"
|
|
40
82
|
}
|
|
41
|
-
|
|
42
|
-
"sideEffects": [
|
|
43
|
-
"./lib/esm/register.js",
|
|
44
|
-
"./lib/esm/register/*.js"
|
|
45
|
-
],
|
|
46
|
-
"scripts": {
|
|
47
|
-
"clear": "rm -rf lib tsconfig.tsbuildinfo tsconfig.types.tsbuildinfo test.gjs.mjs test.node.mjs || exit 0",
|
|
48
|
-
"check": "tsc --noEmit",
|
|
49
|
-
"build": "yarn build:gjsify && yarn build:types",
|
|
50
|
-
"build:gjsify": "gjsify build --library 'src/**/*.{ts,js}' --exclude 'src/**/*.spec.{mts,ts}' 'src/test.{mts,ts}'",
|
|
51
|
-
"build:types": "tsc",
|
|
52
|
-
"build:test": "yarn build:test:gjs",
|
|
53
|
-
"build:test:gjs": "gjsify build src/test.mts --app gjs --outfile test.gjs.mjs",
|
|
54
|
-
"build:test:browser": "gjsify build src/test.browser.mts --app browser --outfile dist/test.browser.mjs",
|
|
55
|
-
"test": "yarn build:gjsify && yarn build:test && yarn test:gjs",
|
|
56
|
-
"test:gjs": "gjsify run test.gjs.mjs"
|
|
57
|
-
},
|
|
58
|
-
"keywords": [
|
|
59
|
-
"gjs",
|
|
60
|
-
"dom",
|
|
61
|
-
"element",
|
|
62
|
-
"node"
|
|
63
|
-
],
|
|
64
|
-
"dependencies": {
|
|
65
|
-
"@girs/gdkpixbuf-2.0": "2.0.0-4.0.0-rc.15",
|
|
66
|
-
"@girs/gjs": "4.0.0-rc.15",
|
|
67
|
-
"@girs/glib-2.0": "2.88.0-4.0.0-rc.15",
|
|
68
|
-
"@gjsify/abort-controller": "^0.4.0",
|
|
69
|
-
"@gjsify/canvas2d-core": "^0.4.0",
|
|
70
|
-
"@gjsify/dom-events": "^0.4.0",
|
|
71
|
-
"@gjsify/fetch": "^0.4.0"
|
|
72
|
-
},
|
|
73
|
-
"devDependencies": {
|
|
74
|
-
"@girs/gst-1.0": "1.28.1-4.0.0-rc.15",
|
|
75
|
-
"@gjsify/cli": "^0.4.0",
|
|
76
|
-
"@gjsify/unit": "^0.4.0",
|
|
77
|
-
"@types/node": "^25.6.2",
|
|
78
|
-
"typescript": "^6.0.3"
|
|
79
|
-
}
|
|
80
|
-
}
|
|
83
|
+
}
|
package/src/attr.ts
DELETED
|
@@ -1,61 +0,0 @@
|
|
|
1
|
-
// Adapted from happy-dom (refs/happy-dom/packages/happy-dom/src/nodes/attr/Attr.ts)
|
|
2
|
-
// Copyright (c) David Ortner (capricorn86). MIT license.
|
|
3
|
-
// Modifications: Simplified for gjsify — lightweight data holder, does not extend Node
|
|
4
|
-
|
|
5
|
-
import * as PS from './property-symbol.js';
|
|
6
|
-
|
|
7
|
-
import type { Element } from './element.js';
|
|
8
|
-
|
|
9
|
-
/**
|
|
10
|
-
* Represents a DOM attribute.
|
|
11
|
-
*
|
|
12
|
-
* Reference: https://developer.mozilla.org/en-US/docs/Web/API/Attr
|
|
13
|
-
*/
|
|
14
|
-
export class Attr {
|
|
15
|
-
public [PS.name]: string;
|
|
16
|
-
public [PS.value]: string;
|
|
17
|
-
public [PS.ownerElement]: Element | null;
|
|
18
|
-
|
|
19
|
-
public readonly localName: string;
|
|
20
|
-
public readonly namespaceURI: string | null;
|
|
21
|
-
public readonly prefix: string | null;
|
|
22
|
-
public readonly specified = true;
|
|
23
|
-
|
|
24
|
-
constructor(
|
|
25
|
-
name: string,
|
|
26
|
-
value: string,
|
|
27
|
-
namespaceURI: string | null = null,
|
|
28
|
-
prefix: string | null = null,
|
|
29
|
-
ownerElement: Element | null = null,
|
|
30
|
-
) {
|
|
31
|
-
this[PS.name] = name;
|
|
32
|
-
this[PS.value] = value;
|
|
33
|
-
this[PS.ownerElement] = ownerElement;
|
|
34
|
-
this.namespaceURI = namespaceURI;
|
|
35
|
-
this.prefix = prefix;
|
|
36
|
-
|
|
37
|
-
// localName is the part after the prefix colon, or the full name if no prefix
|
|
38
|
-
const colonIndex = name.indexOf(':');
|
|
39
|
-
this.localName = colonIndex !== -1 ? name.slice(colonIndex + 1) : name;
|
|
40
|
-
}
|
|
41
|
-
|
|
42
|
-
get name(): string {
|
|
43
|
-
return this[PS.name];
|
|
44
|
-
}
|
|
45
|
-
|
|
46
|
-
get value(): string {
|
|
47
|
-
return this[PS.value];
|
|
48
|
-
}
|
|
49
|
-
|
|
50
|
-
set value(value: string) {
|
|
51
|
-
this[PS.value] = value;
|
|
52
|
-
}
|
|
53
|
-
|
|
54
|
-
get ownerElement(): Element | null {
|
|
55
|
-
return this[PS.ownerElement];
|
|
56
|
-
}
|
|
57
|
-
|
|
58
|
-
get [Symbol.toStringTag](): string {
|
|
59
|
-
return 'Attr';
|
|
60
|
-
}
|
|
61
|
-
}
|
package/src/character-data.ts
DELETED
|
@@ -1,79 +0,0 @@
|
|
|
1
|
-
// Adapted from happy-dom (refs/happy-dom/packages/happy-dom/src/nodes/character-data/CharacterData.ts)
|
|
2
|
-
// Copyright (c) David Ortner (capricorn86). MIT license.
|
|
3
|
-
// Modifications: Simplified for gjsify — no ChildNode utilities, no mutation observer hooks
|
|
4
|
-
|
|
5
|
-
import { Node } from './node.js';
|
|
6
|
-
import { NodeType } from './node-type.js';
|
|
7
|
-
import * as PS from './property-symbol.js';
|
|
8
|
-
|
|
9
|
-
/**
|
|
10
|
-
* CharacterData base class for Text and Comment nodes.
|
|
11
|
-
*
|
|
12
|
-
* Reference: https://developer.mozilla.org/en-US/docs/Web/API/CharacterData
|
|
13
|
-
*/
|
|
14
|
-
export class CharacterData extends Node {
|
|
15
|
-
private _data: string;
|
|
16
|
-
|
|
17
|
-
constructor(data = '') {
|
|
18
|
-
super();
|
|
19
|
-
this[PS.nodeType] = NodeType.TEXT_NODE;
|
|
20
|
-
this._data = data;
|
|
21
|
-
}
|
|
22
|
-
|
|
23
|
-
get data(): string {
|
|
24
|
-
return this._data;
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
set data(value: string) {
|
|
28
|
-
this._data = value;
|
|
29
|
-
}
|
|
30
|
-
|
|
31
|
-
get textContent(): string {
|
|
32
|
-
return this._data;
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
set textContent(value: string) {
|
|
36
|
-
this._data = value;
|
|
37
|
-
}
|
|
38
|
-
|
|
39
|
-
get nodeValue(): string {
|
|
40
|
-
return this._data;
|
|
41
|
-
}
|
|
42
|
-
|
|
43
|
-
set nodeValue(value: string) {
|
|
44
|
-
this._data = value;
|
|
45
|
-
}
|
|
46
|
-
|
|
47
|
-
get length(): number {
|
|
48
|
-
return this._data.length;
|
|
49
|
-
}
|
|
50
|
-
|
|
51
|
-
appendData(data: string): void {
|
|
52
|
-
this._data += data;
|
|
53
|
-
}
|
|
54
|
-
|
|
55
|
-
deleteData(offset: number, count: number): void {
|
|
56
|
-
this._data = this._data.substring(0, offset) + this._data.substring(offset + count);
|
|
57
|
-
}
|
|
58
|
-
|
|
59
|
-
insertData(offset: number, data: string): void {
|
|
60
|
-
this._data = this._data.substring(0, offset) + data + this._data.substring(offset);
|
|
61
|
-
}
|
|
62
|
-
|
|
63
|
-
replaceData(offset: number, count: number, data: string): void {
|
|
64
|
-
this._data = this._data.substring(0, offset) + data + this._data.substring(offset + count);
|
|
65
|
-
}
|
|
66
|
-
|
|
67
|
-
substringData(offset: number, count: number): string {
|
|
68
|
-
return this._data.substring(offset, offset + count);
|
|
69
|
-
}
|
|
70
|
-
|
|
71
|
-
cloneNode(_deep = false): CharacterData {
|
|
72
|
-
const clone = new (this.constructor as typeof CharacterData)(this._data);
|
|
73
|
-
return clone;
|
|
74
|
-
}
|
|
75
|
-
|
|
76
|
-
get [Symbol.toStringTag](): string {
|
|
77
|
-
return 'CharacterData';
|
|
78
|
-
}
|
|
79
|
-
}
|
package/src/comment.ts
DELETED
|
@@ -1,31 +0,0 @@
|
|
|
1
|
-
// Adapted from happy-dom (refs/happy-dom/packages/happy-dom/src/nodes/comment/Comment.ts)
|
|
2
|
-
// Copyright (c) David Ortner (capricorn86). MIT license.
|
|
3
|
-
// Modifications: Simplified for gjsify
|
|
4
|
-
|
|
5
|
-
import { CharacterData } from './character-data.js';
|
|
6
|
-
import { NodeType } from './node-type.js';
|
|
7
|
-
import * as PS from './property-symbol.js';
|
|
8
|
-
|
|
9
|
-
/**
|
|
10
|
-
* Comment node.
|
|
11
|
-
*
|
|
12
|
-
* Reference: https://developer.mozilla.org/en-US/docs/Web/API/Comment
|
|
13
|
-
*/
|
|
14
|
-
export class Comment extends CharacterData {
|
|
15
|
-
constructor(data = '') {
|
|
16
|
-
super(data);
|
|
17
|
-
this[PS.nodeType] = NodeType.COMMENT_NODE;
|
|
18
|
-
}
|
|
19
|
-
|
|
20
|
-
get nodeName(): string {
|
|
21
|
-
return '#comment';
|
|
22
|
-
}
|
|
23
|
-
|
|
24
|
-
cloneNode(_deep = false): Comment {
|
|
25
|
-
return new Comment(this.data);
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
get [Symbol.toStringTag](): string {
|
|
29
|
-
return 'Comment';
|
|
30
|
-
}
|
|
31
|
-
}
|
package/src/document-fragment.ts
DELETED
|
@@ -1,137 +0,0 @@
|
|
|
1
|
-
// Adapted from happy-dom (refs/happy-dom/packages/happy-dom/src/nodes/document-fragment/DocumentFragment.ts)
|
|
2
|
-
// Copyright (c) David Ortner (capricorn86). MIT license.
|
|
3
|
-
// Modifications: Simplified for gjsify — no querySelector/querySelectorAll, no HTML parsing
|
|
4
|
-
|
|
5
|
-
import { Node } from './node.js';
|
|
6
|
-
import { Element } from './element.js';
|
|
7
|
-
import { Text } from './text.js';
|
|
8
|
-
import { NodeType } from './node-type.js';
|
|
9
|
-
import * as PS from './property-symbol.js';
|
|
10
|
-
|
|
11
|
-
/**
|
|
12
|
-
* DocumentFragment.
|
|
13
|
-
*
|
|
14
|
-
* Reference: https://developer.mozilla.org/en-US/docs/Web/API/DocumentFragment
|
|
15
|
-
*/
|
|
16
|
-
export class DocumentFragment extends Node {
|
|
17
|
-
constructor() {
|
|
18
|
-
super();
|
|
19
|
-
this[PS.nodeType] = NodeType.DOCUMENT_FRAGMENT_NODE;
|
|
20
|
-
}
|
|
21
|
-
|
|
22
|
-
get nodeName(): string {
|
|
23
|
-
return '#document-fragment';
|
|
24
|
-
}
|
|
25
|
-
|
|
26
|
-
/** Element children only (excludes text/comment nodes) */
|
|
27
|
-
get children(): Element[] {
|
|
28
|
-
return this[PS.elementChildren] as Element[];
|
|
29
|
-
}
|
|
30
|
-
|
|
31
|
-
get childElementCount(): number {
|
|
32
|
-
return this[PS.elementChildren].length;
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
get firstElementChild(): Element | null {
|
|
36
|
-
return (this[PS.elementChildren][0] as Element) ?? null;
|
|
37
|
-
}
|
|
38
|
-
|
|
39
|
-
get lastElementChild(): Element | null {
|
|
40
|
-
const children = this[PS.elementChildren];
|
|
41
|
-
return (children[children.length - 1] as Element) ?? null;
|
|
42
|
-
}
|
|
43
|
-
|
|
44
|
-
get textContent(): string {
|
|
45
|
-
let text = '';
|
|
46
|
-
for (const child of this.childNodes) {
|
|
47
|
-
if (child.textContent !== null) {
|
|
48
|
-
text += child.textContent;
|
|
49
|
-
}
|
|
50
|
-
}
|
|
51
|
-
return text;
|
|
52
|
-
}
|
|
53
|
-
|
|
54
|
-
set textContent(value: string) {
|
|
55
|
-
// Remove all children
|
|
56
|
-
while (this.firstChild) {
|
|
57
|
-
this.removeChild(this.firstChild);
|
|
58
|
-
}
|
|
59
|
-
// Add text node if value is non-empty
|
|
60
|
-
if (value) {
|
|
61
|
-
// Import Text lazily to avoid circular dependency
|
|
62
|
-
this.appendChild(new Text(value));
|
|
63
|
-
}
|
|
64
|
-
}
|
|
65
|
-
|
|
66
|
-
/**
|
|
67
|
-
* Append nodes or strings to this fragment.
|
|
68
|
-
*/
|
|
69
|
-
append(...nodes: (Node | string)[]): void {
|
|
70
|
-
for (const node of nodes) {
|
|
71
|
-
if (typeof node === 'string') {
|
|
72
|
-
this.appendChild(new Text(node));
|
|
73
|
-
} else {
|
|
74
|
-
this.appendChild(node);
|
|
75
|
-
}
|
|
76
|
-
}
|
|
77
|
-
}
|
|
78
|
-
|
|
79
|
-
/**
|
|
80
|
-
* Prepend nodes or strings to this fragment.
|
|
81
|
-
*/
|
|
82
|
-
prepend(...nodes: (Node | string)[]): void {
|
|
83
|
-
const firstChild = this.firstChild;
|
|
84
|
-
for (const node of nodes) {
|
|
85
|
-
if (typeof node === 'string') {
|
|
86
|
-
this.insertBefore(new Text(node), firstChild);
|
|
87
|
-
} else {
|
|
88
|
-
this.insertBefore(node, firstChild);
|
|
89
|
-
}
|
|
90
|
-
}
|
|
91
|
-
}
|
|
92
|
-
|
|
93
|
-
/**
|
|
94
|
-
* Replace all children with the given nodes.
|
|
95
|
-
*/
|
|
96
|
-
replaceChildren(...nodes: (Node | string)[]): void {
|
|
97
|
-
while (this.firstChild) {
|
|
98
|
-
this.removeChild(this.firstChild);
|
|
99
|
-
}
|
|
100
|
-
this.append(...nodes);
|
|
101
|
-
}
|
|
102
|
-
|
|
103
|
-
/**
|
|
104
|
-
* Find an element by ID in this fragment's children.
|
|
105
|
-
*/
|
|
106
|
-
getElementById(id: string): Element | null {
|
|
107
|
-
for (const child of this.children) {
|
|
108
|
-
if (child.id === id) return child;
|
|
109
|
-
const found = this._findById(child, id);
|
|
110
|
-
if (found) return found;
|
|
111
|
-
}
|
|
112
|
-
return null;
|
|
113
|
-
}
|
|
114
|
-
|
|
115
|
-
private _findById(element: Element, id: string): Element | null {
|
|
116
|
-
for (const child of element.children) {
|
|
117
|
-
if (child.id === id) return child;
|
|
118
|
-
const found = this._findById(child, id);
|
|
119
|
-
if (found) return found;
|
|
120
|
-
}
|
|
121
|
-
return null;
|
|
122
|
-
}
|
|
123
|
-
|
|
124
|
-
cloneNode(deep = false): DocumentFragment {
|
|
125
|
-
const clone = new DocumentFragment();
|
|
126
|
-
if (deep) {
|
|
127
|
-
for (const child of this.childNodes) {
|
|
128
|
-
clone.appendChild(child.cloneNode(true));
|
|
129
|
-
}
|
|
130
|
-
}
|
|
131
|
-
return clone;
|
|
132
|
-
}
|
|
133
|
-
|
|
134
|
-
get [Symbol.toStringTag](): string {
|
|
135
|
-
return 'DocumentFragment';
|
|
136
|
-
}
|
|
137
|
-
}
|
package/src/document.ts
DELETED
|
@@ -1,103 +0,0 @@
|
|
|
1
|
-
// Document stub for GJS — original implementation
|
|
2
|
-
// Reference: refs/happy-dom/packages/happy-dom/src/nodes/document/Document.ts
|
|
3
|
-
|
|
4
|
-
import { Node } from './node.js';
|
|
5
|
-
import { Element } from './element.js';
|
|
6
|
-
import { HTMLElement } from './html-element.js';
|
|
7
|
-
import { HTMLImageElement } from './html-image-element.js';
|
|
8
|
-
import { HTMLVideoElement } from './html-video-element.js';
|
|
9
|
-
import { HTMLCanvasElement } from './html-canvas-element.js';
|
|
10
|
-
import { Text } from './text.js';
|
|
11
|
-
import { Comment } from './comment.js';
|
|
12
|
-
import { DocumentFragment } from './document-fragment.js';
|
|
13
|
-
import { Event } from '@gjsify/dom-events';
|
|
14
|
-
|
|
15
|
-
type ElementFactory = () => HTMLElement;
|
|
16
|
-
|
|
17
|
-
export class Document extends Node {
|
|
18
|
-
/** External packages register element factories here (e.g. @gjsify/iframe registers 'iframe') */
|
|
19
|
-
private static _elementFactories = new Map<string, ElementFactory>();
|
|
20
|
-
|
|
21
|
-
/** Stub body element */
|
|
22
|
-
readonly body: HTMLElement = new HTMLElement();
|
|
23
|
-
|
|
24
|
-
/** Stub head element */
|
|
25
|
-
readonly head: HTMLElement = new HTMLElement();
|
|
26
|
-
|
|
27
|
-
/** Stub documentElement */
|
|
28
|
-
readonly documentElement: HTMLElement = new HTMLElement();
|
|
29
|
-
|
|
30
|
-
constructor() {
|
|
31
|
-
super();
|
|
32
|
-
// Establish DOM tree: document → documentElement → body
|
|
33
|
-
// so event bubbling from any child of body reaches document.
|
|
34
|
-
this.appendChild(this.documentElement);
|
|
35
|
-
this.documentElement.appendChild(this.body);
|
|
36
|
-
}
|
|
37
|
-
|
|
38
|
-
/**
|
|
39
|
-
* Register a factory for a custom element tag name.
|
|
40
|
-
* Called as a side-effect by DOM packages to avoid circular dependencies.
|
|
41
|
-
*
|
|
42
|
-
* Example: `Document.registerElementFactory('iframe', () => new HTMLIFrameElement())`
|
|
43
|
-
*/
|
|
44
|
-
static registerElementFactory(tagName: string, factory: ElementFactory): void {
|
|
45
|
-
Document._elementFactories.set(tagName.toLowerCase(), factory);
|
|
46
|
-
}
|
|
47
|
-
|
|
48
|
-
createElementNS(_namespace: string | null, tagName: string): HTMLElement {
|
|
49
|
-
const tag = tagName.toLowerCase();
|
|
50
|
-
switch (tag) {
|
|
51
|
-
case 'img': return new HTMLImageElement();
|
|
52
|
-
case 'video': return new HTMLVideoElement();
|
|
53
|
-
case 'canvas': return new HTMLCanvasElement();
|
|
54
|
-
default: {
|
|
55
|
-
const factory = Document._elementFactories.get(tag);
|
|
56
|
-
if (factory) return factory();
|
|
57
|
-
return new HTMLElement();
|
|
58
|
-
}
|
|
59
|
-
}
|
|
60
|
-
}
|
|
61
|
-
|
|
62
|
-
createElement(tagName: string): HTMLElement {
|
|
63
|
-
return this.createElementNS('http://www.w3.org/1999/xhtml', tagName);
|
|
64
|
-
}
|
|
65
|
-
|
|
66
|
-
createTextNode(data: string): Text {
|
|
67
|
-
return new Text(data);
|
|
68
|
-
}
|
|
69
|
-
|
|
70
|
-
createComment(data: string): Comment {
|
|
71
|
-
return new Comment(data);
|
|
72
|
-
}
|
|
73
|
-
|
|
74
|
-
createDocumentFragment(): DocumentFragment {
|
|
75
|
-
return new DocumentFragment();
|
|
76
|
-
}
|
|
77
|
-
|
|
78
|
-
createEvent(type: string): Event {
|
|
79
|
-
return new Event(type);
|
|
80
|
-
}
|
|
81
|
-
|
|
82
|
-
/**
|
|
83
|
-
* Find an element by ID. Searches body's descendants.
|
|
84
|
-
*/
|
|
85
|
-
getElementById(id: string): Element | null {
|
|
86
|
-
return this._findById(this.body, id);
|
|
87
|
-
}
|
|
88
|
-
|
|
89
|
-
private _findById(element: Element, id: string): Element | null {
|
|
90
|
-
if (element.id === id) return element;
|
|
91
|
-
for (const child of element.children) {
|
|
92
|
-
const found = this._findById(child, id);
|
|
93
|
-
if (found) return found;
|
|
94
|
-
}
|
|
95
|
-
return null;
|
|
96
|
-
}
|
|
97
|
-
|
|
98
|
-
get [Symbol.toStringTag](): string {
|
|
99
|
-
return 'Document';
|
|
100
|
-
}
|
|
101
|
-
}
|
|
102
|
-
|
|
103
|
-
export const document = new Document();
|
package/src/dom-matrix.ts
DELETED
|
@@ -1,109 +0,0 @@
|
|
|
1
|
-
// DOMMatrix stub for GJS — minimal 2D/3D transformation matrix.
|
|
2
|
-
// Libraries like Excalibur construct `new DOMMatrix([a,b,c,d,e,f])` and pass
|
|
3
|
-
// the result to `ctx.setTransform(matrix)` — we store the 6 2D components
|
|
4
|
-
// plus 16 3D components. Our Canvas 2D context's setTransform() accepts
|
|
5
|
-
// either a DOMMatrix or six numbers, so this works transparently.
|
|
6
|
-
// Reference: https://developer.mozilla.org/en-US/docs/Web/API/DOMMatrix
|
|
7
|
-
|
|
8
|
-
/**
|
|
9
|
-
* Minimal DOMMatrix implementation — supports 2D and 3D construction, plus
|
|
10
|
-
* 2D multiply/inverse/translate/scale operations used by Canvas 2D libraries
|
|
11
|
-
* like Excalibur. Full 3D math (4x4 multiply, inverse) is NOT implemented.
|
|
12
|
-
*/
|
|
13
|
-
export class DOMMatrix {
|
|
14
|
-
// 2D components
|
|
15
|
-
a = 1; b = 0; c = 0; d = 1; e = 0; f = 0;
|
|
16
|
-
// 3D components (column-major)
|
|
17
|
-
m11 = 1; m12 = 0; m13 = 0; m14 = 0;
|
|
18
|
-
m21 = 0; m22 = 1; m23 = 0; m24 = 0;
|
|
19
|
-
m31 = 0; m32 = 0; m33 = 1; m34 = 0;
|
|
20
|
-
m41 = 0; m42 = 0; m43 = 0; m44 = 1;
|
|
21
|
-
is2D = true;
|
|
22
|
-
isIdentity = true;
|
|
23
|
-
|
|
24
|
-
constructor(init?: number[] | string) {
|
|
25
|
-
if (Array.isArray(init)) {
|
|
26
|
-
if (init.length === 6) {
|
|
27
|
-
// 2D affine: [a, b, c, d, e, f]
|
|
28
|
-
this.a = this.m11 = init[0];
|
|
29
|
-
this.b = this.m12 = init[1];
|
|
30
|
-
this.c = this.m21 = init[2];
|
|
31
|
-
this.d = this.m22 = init[3];
|
|
32
|
-
this.e = this.m41 = init[4];
|
|
33
|
-
this.f = this.m42 = init[5];
|
|
34
|
-
this.is2D = true;
|
|
35
|
-
} else if (init.length === 16) {
|
|
36
|
-
// 3D: column-major 4x4
|
|
37
|
-
this.m11 = init[0]; this.m12 = init[1]; this.m13 = init[2]; this.m14 = init[3];
|
|
38
|
-
this.m21 = init[4]; this.m22 = init[5]; this.m23 = init[6]; this.m24 = init[7];
|
|
39
|
-
this.m31 = init[8]; this.m32 = init[9]; this.m33 = init[10]; this.m34 = init[11];
|
|
40
|
-
this.m41 = init[12]; this.m42 = init[13]; this.m43 = init[14]; this.m44 = init[15];
|
|
41
|
-
this.a = this.m11; this.b = this.m12;
|
|
42
|
-
this.c = this.m21; this.d = this.m22;
|
|
43
|
-
this.e = this.m41; this.f = this.m42;
|
|
44
|
-
this.is2D = false;
|
|
45
|
-
}
|
|
46
|
-
this.isIdentity =
|
|
47
|
-
this.a === 1 && this.b === 0 && this.c === 0 &&
|
|
48
|
-
this.d === 1 && this.e === 0 && this.f === 0;
|
|
49
|
-
}
|
|
50
|
-
}
|
|
51
|
-
|
|
52
|
-
/**
|
|
53
|
-
* Multiply this 2D matrix by another 2D matrix and return a new matrix.
|
|
54
|
-
* [a c e] [a' c' e'] [a*a'+c*b' a*c'+c*d' a*e'+c*f'+e]
|
|
55
|
-
* [b d f] [b' d' f'] = [b*a'+d*b' b*c'+d*d' b*e'+d*f'+f]
|
|
56
|
-
* [0 0 1] [0 0 1 ] [0 0 1 ]
|
|
57
|
-
*/
|
|
58
|
-
multiply(other: { a: number; b: number; c: number; d: number; e: number; f: number }): DOMMatrix {
|
|
59
|
-
const a = this.a * other.a + this.c * other.b;
|
|
60
|
-
const b = this.b * other.a + this.d * other.b;
|
|
61
|
-
const c = this.a * other.c + this.c * other.d;
|
|
62
|
-
const d = this.b * other.c + this.d * other.d;
|
|
63
|
-
const e = this.a * other.e + this.c * other.f + this.e;
|
|
64
|
-
const f = this.b * other.e + this.d * other.f + this.f;
|
|
65
|
-
return new DOMMatrix([a, b, c, d, e, f]);
|
|
66
|
-
}
|
|
67
|
-
|
|
68
|
-
/** In-place multiply; returns this. */
|
|
69
|
-
multiplySelf(other: { a: number; b: number; c: number; d: number; e: number; f: number }): DOMMatrix {
|
|
70
|
-
const result = this.multiply(other);
|
|
71
|
-
this.a = result.a; this.b = result.b;
|
|
72
|
-
this.c = result.c; this.d = result.d;
|
|
73
|
-
this.e = result.e; this.f = result.f;
|
|
74
|
-
this.m11 = this.a; this.m12 = this.b;
|
|
75
|
-
this.m21 = this.c; this.m22 = this.d;
|
|
76
|
-
this.m41 = this.e; this.m42 = this.f;
|
|
77
|
-
this.isIdentity = false;
|
|
78
|
-
return this;
|
|
79
|
-
}
|
|
80
|
-
|
|
81
|
-
/** 2D inverse. Throws if non-invertible (det === 0). */
|
|
82
|
-
inverse(): DOMMatrix {
|
|
83
|
-
const det = this.a * this.d - this.b * this.c;
|
|
84
|
-
if (det === 0) return new DOMMatrix([1, 0, 0, 1, 0, 0]);
|
|
85
|
-
const invDet = 1 / det;
|
|
86
|
-
return new DOMMatrix([
|
|
87
|
-
this.d * invDet,
|
|
88
|
-
-this.b * invDet,
|
|
89
|
-
-this.c * invDet,
|
|
90
|
-
this.a * invDet,
|
|
91
|
-
(this.c * this.f - this.d * this.e) * invDet,
|
|
92
|
-
(this.b * this.e - this.a * this.f) * invDet,
|
|
93
|
-
]);
|
|
94
|
-
}
|
|
95
|
-
|
|
96
|
-
translate(tx = 0, ty = 0): DOMMatrix {
|
|
97
|
-
return this.multiply({ a: 1, b: 0, c: 0, d: 1, e: tx, f: ty });
|
|
98
|
-
}
|
|
99
|
-
|
|
100
|
-
scale(sx = 1, sy: number = sx): DOMMatrix {
|
|
101
|
-
return this.multiply({ a: sx, b: 0, c: 0, d: sy, e: 0, f: 0 });
|
|
102
|
-
}
|
|
103
|
-
}
|
|
104
|
-
|
|
105
|
-
/**
|
|
106
|
-
* DOMMatrixReadOnly alias — MDN specifies this as the immutable base class.
|
|
107
|
-
* We expose the same impl since consumers (Excalibur, three.js) rarely care.
|
|
108
|
-
*/
|
|
109
|
-
export const DOMMatrixReadOnly = DOMMatrix;
|