CETEIcean 1.7.2 → 1.8.0-beta.1
Sign up to get free protection for your applications and to get access to all the features.
- package/README.md +14 -0
- package/package.json +10 -3
- package/src/CETEI.js +61 -67
- package/src/defaultBehaviors.js +17 -12
- package/src/utilities.js +70 -11
- package/test/externalgetTest.html +0 -1
- package/test/nodeTest.js +24 -0
package/README.md
CHANGED
@@ -52,6 +52,20 @@ new CETEI({
|
|
52
52
|
})
|
53
53
|
```
|
54
54
|
|
55
|
+
### Usage with Node
|
56
|
+
|
57
|
+
CETEIcean can be used on the server by providing a DOM implementation, such as [JSDOM](https://github.com/jsdom/jsdom). You can pass a document object as an option when instantiating CETEIcean.
|
58
|
+
|
59
|
+
```js
|
60
|
+
import { JSDOM } from 'jsdom';
|
61
|
+
import CETEI from 'CETEIcean';
|
62
|
+
|
63
|
+
const jdom = new JSDOM(`<TEI xmlns="http://www.tei-c.org/ns/1.0" />`, {contentType: 'text/xml'});
|
64
|
+
new CETEI({
|
65
|
+
documentObject: jdom.window.document
|
66
|
+
})
|
67
|
+
```
|
68
|
+
|
55
69
|
### Other methods
|
56
70
|
|
57
71
|
#### getHTML5( url, callback, perElementFn )
|
package/package.json
CHANGED
@@ -1,8 +1,9 @@
|
|
1
1
|
{
|
2
2
|
"name": "CETEIcean",
|
3
|
-
"version": "1.
|
3
|
+
"version": "1.8.0-beta.1",
|
4
4
|
"description": "JavaScript library to load a TEI XML document and register it as HTML5 custom elements.",
|
5
5
|
"main": "src/CETEI.js",
|
6
|
+
"type": "module",
|
6
7
|
"keywords": [
|
7
8
|
"TEI",
|
8
9
|
"XML",
|
@@ -15,20 +16,26 @@
|
|
15
16
|
"type": "git",
|
16
17
|
"url": "https://github.com/TEIC/CETEIcean.git"
|
17
18
|
},
|
19
|
+
"exports": {
|
20
|
+
".": "./src/CETEI.js",
|
21
|
+
"./utilities.js": "./src/utilities.js"
|
22
|
+
},
|
18
23
|
"devDependencies": {
|
19
24
|
"@babel/core": "^7.15.5",
|
20
25
|
"@babel/preset-env": "7.15.6",
|
21
26
|
"@rollup/plugin-babel": "^5.3.0",
|
22
27
|
"babel-preset-env": "^1.7.0",
|
23
28
|
"http-server": "^14.1.1",
|
29
|
+
"jsdom": "^21.1.0",
|
24
30
|
"onchange": "^6.1.1",
|
25
31
|
"rollup": "^2.57.0",
|
26
32
|
"rollup-plugin-terser": "^7.0.2",
|
27
33
|
"terser": "^5.14.2"
|
28
34
|
},
|
29
35
|
"scripts": {
|
30
|
-
"build": "rollup -c rollup.config.js",
|
36
|
+
"build": "npm test && rollup -c rollup.config.js",
|
31
37
|
"build:tutorial": "npm run build && cp dist/CETEI.js tutorial/js/CETEI.js",
|
32
|
-
"dev": "npm run build && http-server -p 8888 & onchange src -- npm run build"
|
38
|
+
"dev": "npm run build && http-server -p 8888 & onchange src -- npm run build",
|
39
|
+
"test": "node test/nodeTest.js"
|
33
40
|
}
|
34
41
|
}
|
package/src/CETEI.js
CHANGED
@@ -7,6 +7,17 @@ class CETEI {
|
|
7
7
|
constructor(options){
|
8
8
|
this.options = options ? options : {}
|
9
9
|
|
10
|
+
// Set a local reference to the Document object
|
11
|
+
// Determine document in this order of preference: options, window, global
|
12
|
+
this.document = this.options.documentObject ? this.options.documentObject : undefined
|
13
|
+
if (this.document === undefined) {
|
14
|
+
if (typeof window !== 'undefined' && window.document) {
|
15
|
+
this.document = window.document
|
16
|
+
} else if (typeof global !== 'undefined' && global.document) {
|
17
|
+
this.document = global.document
|
18
|
+
}
|
19
|
+
}
|
20
|
+
|
10
21
|
// Bind methods
|
11
22
|
this.addBehaviors = addBehaviors.bind(this);
|
12
23
|
this.addBehavior = addBehavior.bind(this);
|
@@ -100,12 +111,7 @@ class CETEI {
|
|
100
111
|
return this.domToHTML5(this.XML_dom, callback, perElementFn);
|
101
112
|
}
|
102
113
|
|
103
|
-
|
104
|
-
Converts the supplied XML DOM into HTML5 Custom Elements. If a callback
|
105
|
-
function is supplied, calls it on the result.
|
106
|
-
*/
|
107
|
-
domToHTML5(XML_dom, callback, perElementFn){
|
108
|
-
|
114
|
+
preprocess(XML_dom, callback, perElementFn) {
|
109
115
|
this.els = learnElementNames(XML_dom, this.namespaces);
|
110
116
|
|
111
117
|
let convertEl = (el) => {
|
@@ -114,9 +120,9 @@ class CETEI {
|
|
114
120
|
let newElement;
|
115
121
|
if (this.namespaces.has(el.namespaceURI ? el.namespaceURI : "")) {
|
116
122
|
let prefix = this.namespaces.get(el.namespaceURI ? el.namespaceURI : "");
|
117
|
-
newElement = document.createElement(`${prefix}-${el.localName}`);
|
123
|
+
newElement = this.document.createElement(`${prefix}-${el.localName}`);
|
118
124
|
} else {
|
119
|
-
newElement = document.importNode(el, false);
|
125
|
+
newElement = this.document.importNode(el, false);
|
120
126
|
}
|
121
127
|
// Copy attributes; @xmlns, @xml:id, @xml:lang, and
|
122
128
|
// @rendition get special handling.
|
@@ -148,16 +154,18 @@ class CETEI {
|
|
148
154
|
}
|
149
155
|
// <head> elements need to know their level
|
150
156
|
if (el.localName == "head") {
|
157
|
+
// 1 is XPathResult.NUMBER_TYPE
|
151
158
|
let level = XML_dom.evaluate("count(ancestor::*[tei:head])", el, function(ns) {
|
152
159
|
if (ns == "tei") return "http://www.tei-c.org/ns/1.0";
|
153
|
-
},
|
160
|
+
}, 1, null);
|
154
161
|
newElement.setAttribute("data-level", level.numberValue);
|
155
162
|
}
|
156
163
|
// Turn <rendition scheme="css"> elements into HTML styles
|
157
164
|
if (el.localName == "tagsDecl") {
|
158
|
-
let style = document.createElement("style");
|
165
|
+
let style = this.document.createElement("style");
|
159
166
|
for (let node of Array.from(el.childNodes)){
|
160
|
-
|
167
|
+
// nodeType 1 is Node.ELEMENT_NODE
|
168
|
+
if (node.nodeType == 1 && node.localName == "rendition" && node.getAttribute("scheme") == "css") {
|
161
169
|
let rule = "";
|
162
170
|
if (node.hasAttribute("selector")) {
|
163
171
|
//rewrite element names in selectors
|
@@ -168,7 +176,7 @@ class CETEI {
|
|
168
176
|
rule += node.textContent;
|
169
177
|
}
|
170
178
|
rule += "\n}\n";
|
171
|
-
style.appendChild(document.createTextNode(rule));
|
179
|
+
style.appendChild(this.document.createTextNode(rule));
|
172
180
|
}
|
173
181
|
}
|
174
182
|
if (style.childNodes.length > 0) {
|
@@ -185,7 +193,8 @@ class CETEI {
|
|
185
193
|
};
|
186
194
|
}
|
187
195
|
for (let node of Array.from(el.childNodes)) {
|
188
|
-
|
196
|
+
// Node.ELEMENT_NODE
|
197
|
+
if (node.nodeType == 1 ) {
|
189
198
|
newElement.appendChild(convertEl(node));
|
190
199
|
}
|
191
200
|
else {
|
@@ -201,6 +210,27 @@ class CETEI {
|
|
201
210
|
this.dom = convertEl(XML_dom.documentElement);
|
202
211
|
this.utilities.dom = this.dom;
|
203
212
|
|
213
|
+
if (callback) {
|
214
|
+
callback(this.dom, this);
|
215
|
+
if (window) {
|
216
|
+
window.dispatchEvent(ceteiceanLoad);
|
217
|
+
}
|
218
|
+
} else {
|
219
|
+
if (typeof window !== 'undefined') {
|
220
|
+
window.dispatchEvent(ceteiceanLoad);
|
221
|
+
}
|
222
|
+
return this.dom;
|
223
|
+
}
|
224
|
+
}
|
225
|
+
|
226
|
+
/*
|
227
|
+
Converts the supplied XML DOM into HTML5 Custom Elements. If a callback
|
228
|
+
function is supplied, calls it on the result.
|
229
|
+
*/
|
230
|
+
domToHTML5(XML_dom, callback, perElementFn){
|
231
|
+
|
232
|
+
this.preprocess(XML_dom, null, perElementFn);
|
233
|
+
|
204
234
|
this.applyBehaviors();
|
205
235
|
this.done = true;
|
206
236
|
if (callback) {
|
@@ -209,7 +239,7 @@ class CETEI {
|
|
209
239
|
window.dispatchEvent(ceteiceanLoad);
|
210
240
|
}
|
211
241
|
} else {
|
212
|
-
if (window) {
|
242
|
+
if (typeof window !== 'undefined') {
|
213
243
|
window.dispatchEvent(ceteiceanLoad);
|
214
244
|
}
|
215
245
|
return this.dom;
|
@@ -223,7 +253,7 @@ class CETEI {
|
|
223
253
|
c.processPage();
|
224
254
|
*/
|
225
255
|
processPage() {
|
226
|
-
this.els = learnCustomElementNames(document);
|
256
|
+
this.els = learnCustomElementNames(this.document);
|
227
257
|
this.applyBehaviors();
|
228
258
|
}
|
229
259
|
|
@@ -348,7 +378,7 @@ getFallback(behaviors, fn) {
|
|
348
378
|
if (behaviors[fn] instanceof Function) {
|
349
379
|
return behaviors[fn];
|
350
380
|
} else {
|
351
|
-
return decorator(behaviors[fn]);
|
381
|
+
return this.decorator(behaviors[fn]);
|
352
382
|
}
|
353
383
|
}
|
354
384
|
}
|
@@ -368,9 +398,10 @@ getHandler(behaviors, fn) {
|
|
368
398
|
}
|
369
399
|
|
370
400
|
insert(elt, strings) {
|
371
|
-
let span = document.createElement("span");
|
401
|
+
let span = this.document.createElement("span");
|
372
402
|
for (let node of Array.from(elt.childNodes)) {
|
373
|
-
|
403
|
+
// nodeType 1 is Node.ELEMENT_NODE
|
404
|
+
if (node.nodeType === 1 && !node.hasAttribute("data-processed")) {
|
374
405
|
this.processElement(node);
|
375
406
|
}
|
376
407
|
}
|
@@ -402,21 +433,13 @@ processElement(elt) {
|
|
402
433
|
}
|
403
434
|
}
|
404
435
|
for (let node of Array.from(elt.childNodes)) {
|
405
|
-
|
436
|
+
// nodeType 1 is Node.ELEMENT_NODE
|
437
|
+
if (node.nodeType === 1) {
|
406
438
|
this.processElement(node);
|
407
439
|
}
|
408
440
|
}
|
409
441
|
}
|
410
442
|
|
411
|
-
// Given a qualified name (e.g. tei:text), return the element name
|
412
|
-
tagName(name) {
|
413
|
-
if (name.includes(":"), 1) {
|
414
|
-
return name.replace(/:/,"-").toLowerCase();
|
415
|
-
} else {
|
416
|
-
return "ceteicean-" + name.toLowerCase();
|
417
|
-
}
|
418
|
-
}
|
419
|
-
|
420
443
|
template(str, elt) {
|
421
444
|
let result = str;
|
422
445
|
if (str.search(/\$(\w*)(@([a-zA-Z:]+))/ )) {
|
@@ -439,7 +462,7 @@ template(str, elt) {
|
|
439
462
|
|
440
463
|
// Define or apply behaviors for the document
|
441
464
|
applyBehaviors() {
|
442
|
-
if (window.customElements) {
|
465
|
+
if (typeof window !== 'undefined' && window.customElements) {
|
443
466
|
this.define.call(this, this.els);
|
444
467
|
} else {
|
445
468
|
this.fallback.call(this, this.els);
|
@@ -453,37 +476,8 @@ applyBehaviors() {
|
|
453
476
|
*/
|
454
477
|
define(names) {
|
455
478
|
for (let name of names) {
|
456
|
-
|
457
|
-
|
458
|
-
window.customElements.define(this.tagName(name), class extends HTMLElement {
|
459
|
-
constructor() {
|
460
|
-
super();
|
461
|
-
if (!this.matches(":defined")) { // "Upgraded" undefined elements can have attributes & children; new elements can't
|
462
|
-
if (fn) {
|
463
|
-
fn.call(this);
|
464
|
-
}
|
465
|
-
// We don't want to double-process elements, so add a flag
|
466
|
-
this.setAttribute("data-processed", "");
|
467
|
-
}
|
468
|
-
}
|
469
|
-
// Process new elements when they are connected to the browser DOM
|
470
|
-
connectedCallback() {
|
471
|
-
if (!this.hasAttribute("data-processed")) {
|
472
|
-
if (fn) {
|
473
|
-
fn.call(this);
|
474
|
-
}
|
475
|
-
this.setAttribute("data-processed", "");
|
476
|
-
}
|
477
|
-
};
|
478
|
-
});
|
479
|
-
} catch (error) {
|
480
|
-
// When using the same CETEIcean instance for multiple TEI files, this error becomes very common.
|
481
|
-
// It's muted by default unless the debug option is set.
|
482
|
-
if (this.debug) {
|
483
|
-
console.log(this.tagName(name) + " couldn't be registered or is already registered.");
|
484
|
-
console.log(error);
|
485
|
-
}
|
486
|
-
}
|
479
|
+
const fn = this.getHandler(this.behaviors, name);
|
480
|
+
utilities.defineCustomElement(name, fn, this.debug);
|
487
481
|
}
|
488
482
|
}
|
489
483
|
|
@@ -496,15 +490,15 @@ define(names) {
|
|
496
490
|
*/
|
497
491
|
fallback(names) {
|
498
492
|
for (let name of names) {
|
499
|
-
let fn = getFallback(this.behaviors, name);
|
493
|
+
let fn = this.getFallback(this.behaviors, name);
|
500
494
|
if (fn) {
|
501
495
|
for (let elt of Array.from((
|
502
496
|
this.dom && !this.done
|
503
497
|
? this.dom
|
504
|
-
: document
|
505
|
-
).getElementsByTagName(tagName(name)))) {
|
498
|
+
: this.document
|
499
|
+
).getElementsByTagName(utilities.tagName(name)))) {
|
506
500
|
if (!elt.hasAttribute("data-processed")) {
|
507
|
-
append(fn, elt);
|
501
|
+
this.append(fn, elt);
|
508
502
|
}
|
509
503
|
}
|
510
504
|
}
|
@@ -530,7 +524,7 @@ fallback(names) {
|
|
530
524
|
}
|
531
525
|
} else {
|
532
526
|
setTimeout(function() {
|
533
|
-
let h = document.querySelector(window.decodeURI(window.location.hash));
|
527
|
+
let h = this.document.querySelector(window.decodeURI(window.location.hash));
|
534
528
|
if (h) {
|
535
529
|
h.scrollIntoView();
|
536
530
|
}
|
@@ -541,7 +535,7 @@ fallback(names) {
|
|
541
535
|
}
|
542
536
|
|
543
537
|
try {
|
544
|
-
if (window) {
|
538
|
+
if (typeof window !== 'undefined') {
|
545
539
|
window.CETEI = CETEI;
|
546
540
|
window.addEventListener("beforeunload", CETEI.savePosition);
|
547
541
|
var ceteiceanLoad = new Event("ceteiceanload");
|
@@ -551,4 +545,4 @@ try {
|
|
551
545
|
console.log(e);
|
552
546
|
}
|
553
547
|
|
554
|
-
export default CETEI
|
548
|
+
export default CETEI;
|
package/src/defaultBehaviors.js
CHANGED
@@ -27,16 +27,18 @@ export default {
|
|
27
27
|
"list": [
|
28
28
|
// will only run on a list where @type="gloss"
|
29
29
|
["[type=gloss]", function(elt) {
|
30
|
-
|
30
|
+
const doc = elt.ownerDocument;
|
31
|
+
let dl = doc.createElement("dl");
|
31
32
|
for (let child of Array.from(elt.children)) {
|
32
|
-
|
33
|
+
// nodeType 1 is Node.ELEMENT_NODE
|
34
|
+
if (child.nodeType == 1) {
|
33
35
|
if (child.localName == "tei-label") {
|
34
|
-
let dt =
|
36
|
+
let dt = doc.createElement("dt");
|
35
37
|
dt.innerHTML = child.innerHTML;
|
36
38
|
dl.appendChild(dt);
|
37
39
|
}
|
38
40
|
if (child.localName == "tei-item") {
|
39
|
-
let dd =
|
41
|
+
let dd = doc.createElement("dd");
|
40
42
|
dd.innerHTML = child.innerHTML;
|
41
43
|
dl.appendChild(dd);
|
42
44
|
}
|
@@ -48,25 +50,26 @@ export default {
|
|
48
50
|
"note": [
|
49
51
|
// Make endnotes
|
50
52
|
["[place=end]", function(elt){
|
53
|
+
const doc = elt.ownerDocument;
|
51
54
|
if (!this.noteIndex){
|
52
55
|
this["noteIndex"] = 1;
|
53
56
|
} else {
|
54
57
|
this.noteIndex++;
|
55
58
|
}
|
56
59
|
let id = "_note_" + this.noteIndex;
|
57
|
-
let link =
|
60
|
+
let link = doc.createElement("a");
|
58
61
|
link.setAttribute("id", "src" + id);
|
59
62
|
link.setAttribute("href", "#" + id);
|
60
63
|
link.innerHTML = this.noteIndex;
|
61
|
-
let content =
|
64
|
+
let content = doc.createElement("sup");
|
62
65
|
content.appendChild(link);
|
63
|
-
let notes =
|
66
|
+
let notes = doc.querySelector("ol.notes");
|
64
67
|
if (!notes) {
|
65
|
-
notes =
|
68
|
+
notes = doc.createElement("ol");
|
66
69
|
notes.setAttribute("class", "notes");
|
67
70
|
this.dom.appendChild(notes);
|
68
71
|
}
|
69
|
-
let note =
|
72
|
+
let note = doc.createElement("li");
|
70
73
|
note.id = id;
|
71
74
|
note.innerHTML = elt.innerHTML
|
72
75
|
notes.appendChild(note);
|
@@ -79,15 +82,17 @@ export default {
|
|
79
82
|
},
|
80
83
|
"title": [
|
81
84
|
["tei-titlestmt>tei-title", function(elt) {
|
82
|
-
|
85
|
+
const doc = elt.ownerDocument;
|
86
|
+
let title = doc.createElement("title");
|
83
87
|
title.innerHTML = elt.innerText;
|
84
|
-
|
88
|
+
doc.querySelector("head").appendChild(title);
|
85
89
|
}]
|
86
90
|
],
|
87
91
|
},
|
88
92
|
"teieg": {
|
89
93
|
"egXML": function(elt) {
|
90
|
-
|
94
|
+
const doc = elt.ownerDocument;
|
95
|
+
let pre = doc.createElement("pre");
|
91
96
|
let content = this.serialize(elt, true).replace(/</g, "<");
|
92
97
|
let ws = content.match(/^[\t ]+/);
|
93
98
|
if (ws) {
|
package/src/utilities.js
CHANGED
@@ -16,8 +16,12 @@ export function getOrdinality(elt, name) {
|
|
16
16
|
out child elements introduced by CETEIcean.
|
17
17
|
*/
|
18
18
|
export function copyAndReset(node) {
|
19
|
+
const doc = node.ownerDocument;
|
19
20
|
let clone = (n) => {
|
20
|
-
|
21
|
+
// nodeType 1 is Node.ELEMENT_NODE
|
22
|
+
let result = n.nodeType === 1
|
23
|
+
? doc.createElement(n.nodeName)
|
24
|
+
: n.cloneNode(true);
|
21
25
|
if (n.attributes) {
|
22
26
|
for (let att of Array.from(n.attributes)) {
|
23
27
|
if (att.name !== "data-processed") {
|
@@ -26,12 +30,14 @@ export function copyAndReset(node) {
|
|
26
30
|
}
|
27
31
|
}
|
28
32
|
for (let nd of Array.from(n.childNodes)){
|
29
|
-
|
33
|
+
// nodeType 1 is Node.ELEMENT_NODE
|
34
|
+
if (nd.nodeType == 1) {
|
30
35
|
if (!n.hasAttribute("data-empty")) {
|
31
36
|
if (nd.hasAttribute("data-original")) {
|
32
37
|
for (let childNode of Array.from(nd.childNodes)) {
|
33
38
|
let child = result.appendChild(clone(childNode));
|
34
|
-
|
39
|
+
// nodeType 1 is Node.ELEMENT_NODE
|
40
|
+
if (child.nodeType === 1 && child.hasAttribute("data-origid")) {
|
35
41
|
child.setAttribute("id", child.getAttribute("data-origid"));
|
36
42
|
child.removeAttribute("data-origid");
|
37
43
|
}
|
@@ -64,14 +70,16 @@ export function first(urls) {
|
|
64
70
|
with display set to "none".
|
65
71
|
*/
|
66
72
|
export function hideContent(elt, rewriteIds = true) {
|
73
|
+
const doc = elt.ownerDocument;
|
67
74
|
if (elt.childNodes.length > 0) {
|
68
|
-
let hidden =
|
75
|
+
let hidden = doc.createElement("span");
|
69
76
|
elt.appendChild(hidden);
|
70
77
|
hidden.setAttribute("hidden", "");
|
71
78
|
hidden.setAttribute("data-original", "");
|
72
79
|
for (let node of Array.from(elt.childNodes)) {
|
73
80
|
if (node !== hidden) {
|
74
|
-
|
81
|
+
// nodeType 1 is Node.ELEMENT_NODE
|
82
|
+
if (node.nodeType === 1) {
|
75
83
|
node.setAttribute("data-processed", "");
|
76
84
|
for (let e of node.querySelectorAll("*")) {
|
77
85
|
e.setAttribute("data-processed", "");
|
@@ -148,7 +156,8 @@ export function serialize(el, stripElt, ws) {
|
|
148
156
|
let ignorable = (txt) => {
|
149
157
|
return !(/[^\t\n\r ]/.test(txt));
|
150
158
|
}
|
151
|
-
|
159
|
+
// nodeType 1 is Node.ELEMENT_NODE
|
160
|
+
if (!stripElt && el.nodeType == 1) {
|
152
161
|
if ((typeof ws === "string") && ws !== "") {
|
153
162
|
str += "\n" + ws + "<";
|
154
163
|
} else {
|
@@ -173,18 +182,21 @@ export function serialize(el, stripElt, ws) {
|
|
173
182
|
}
|
174
183
|
//TODO: Be smarter about skipping generated content with hidden original
|
175
184
|
for (let node of Array.from(el.childNodes)) {
|
185
|
+
// nodeType 1 is Node.ELEMENT_NODE
|
186
|
+
// nodeType 7 is Node.PROCESSING_INSTRUCTION_NODE
|
187
|
+
// nodeType 8 is Node.COMMENT_NODE
|
176
188
|
switch (node.nodeType) {
|
177
|
-
case
|
189
|
+
case 1:
|
178
190
|
if (typeof ws === "string") {
|
179
|
-
str +=
|
191
|
+
str += serialize(node, false, ws + " ");
|
180
192
|
} else {
|
181
|
-
str +=
|
193
|
+
str += serialize(node, false, ws);
|
182
194
|
}
|
183
195
|
break;
|
184
|
-
case
|
196
|
+
case 7:
|
185
197
|
str += "<?" + node.nodeValue + "?>";
|
186
198
|
break;
|
187
|
-
case
|
199
|
+
case 8:
|
188
200
|
str += "<!--" + node.nodeValue + "-->";
|
189
201
|
break;
|
190
202
|
default:
|
@@ -214,3 +226,50 @@ export function unEscapeEntities(str) {
|
|
214
226
|
.replace(/'/, "'")
|
215
227
|
.replace(/&/, "&");
|
216
228
|
}
|
229
|
+
|
230
|
+
// Given a qualified name (e.g. tei:text), return the element name
|
231
|
+
export function tagName(name) {
|
232
|
+
if (name.includes(":"), 1) {
|
233
|
+
return name.replace(/:/,"-").toLowerCase();
|
234
|
+
} else {
|
235
|
+
return "ceteicean-" + name.toLowerCase();
|
236
|
+
}
|
237
|
+
}
|
238
|
+
|
239
|
+
export function defineCustomElement(name, behavior = null, debug = false) {
|
240
|
+
/*
|
241
|
+
Registers the list of elements provided with the browser.
|
242
|
+
Called by makeHTML5(), but can be called independently if, for example,
|
243
|
+
you've created Custom Elements via an XSLT transformation instead.
|
244
|
+
*/
|
245
|
+
try {
|
246
|
+
window.customElements.define(tagName(name), class extends HTMLElement {
|
247
|
+
constructor() {
|
248
|
+
super();
|
249
|
+
if (!this.matches(":defined")) { // "Upgraded" undefined elements can have attributes & children; new elements can't
|
250
|
+
if (behavior) {
|
251
|
+
behavior.call(this);
|
252
|
+
}
|
253
|
+
// We don't want to double-process elements, so add a flag
|
254
|
+
this.setAttribute("data-processed", "");
|
255
|
+
}
|
256
|
+
}
|
257
|
+
// Process new elements when they are connected to the browser DOM
|
258
|
+
connectedCallback() {
|
259
|
+
if (!this.hasAttribute("data-processed")) {
|
260
|
+
if (behavior) {
|
261
|
+
behavior.call(this);
|
262
|
+
}
|
263
|
+
this.setAttribute("data-processed", "");
|
264
|
+
}
|
265
|
+
};
|
266
|
+
});
|
267
|
+
} catch (error) {
|
268
|
+
// When using the same CETEIcean instance for multiple TEI files, this error becomes very common.
|
269
|
+
// It's muted by default unless the debug option is set.
|
270
|
+
if (debug) {
|
271
|
+
console.log(tagName(name) + " couldn't be registered or is already registered.");
|
272
|
+
console.log(error);
|
273
|
+
}
|
274
|
+
}
|
275
|
+
}
|
package/test/nodeTest.js
ADDED
@@ -0,0 +1,24 @@
|
|
1
|
+
import { JSDOM } from 'jsdom';
|
2
|
+
import CETEI from '../src/CETEI.js';
|
3
|
+
|
4
|
+
const jdom = new JSDOM(`<TEI xmlns="http://www.tei-c.org/ns/1.0"><div>test</div></TEI>`, {contentType: 'text/xml'});
|
5
|
+
const teiDoc = jdom.window.document;
|
6
|
+
|
7
|
+
const test = () => {
|
8
|
+
console.log('Get HTML5 from JSDOM');
|
9
|
+
const processedTEI = (new CETEI({documentObject: teiDoc})).domToHTML5(teiDoc);
|
10
|
+
if (processedTEI) {
|
11
|
+
console.log(' > pass');
|
12
|
+
} else {
|
13
|
+
console.log(' > fail');
|
14
|
+
return;
|
15
|
+
}
|
16
|
+
console.log('Check content');
|
17
|
+
if (processedTEI.querySelector("tei-div")) {
|
18
|
+
console.log(' > pass');
|
19
|
+
} else {
|
20
|
+
console.log(' > fail');
|
21
|
+
}
|
22
|
+
};
|
23
|
+
|
24
|
+
test();
|