CETEIcean 1.9.3 → 1.9.5

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/dist/CETEI.js CHANGED
@@ -1 +1 @@
1
- var CETEI=function(){"use strict";var e={namespaces:{tei:"http://www.tei-c.org/ns/1.0",teieg:"http://www.tei-c.org/ns/Examples",rng:"http://relaxng.org/ns/structure/1.0"},tei:{eg:["<pre>","</pre>"],ptr:['<a href="$rw@target">$@target</a>'],ref:[["[target]",['<a href="$rw@target">',"</a>"]]],graphic:function(e){let t=new Image;return t.src=this.rw(e.getAttribute("url")),e.hasAttribute("width")&&t.setAttribute("width",e.getAttribute("width")),e.hasAttribute("height")&&t.setAttribute("height",e.getAttribute("height")),t},list:[["[type=gloss]",function(e){const t=e.ownerDocument;let i=t.createElement("dl");for(let n of Array.from(e.children))if(1==n.nodeType){if("tei-label"==n.localName){let e=t.createElement("dt");e.innerHTML=n.innerHTML,i.appendChild(e)}if("tei-item"==n.localName){let e=t.createElement("dd");e.innerHTML=n.innerHTML,i.appendChild(e)}}return i}]],note:[["[place=end]",function(e){const t=e.ownerDocument;this.noteIndex?this.noteIndex++:this.noteIndex=1;let i="_note_"+this.noteIndex,n=t.createElement("a");n.setAttribute("id","src"+i),n.setAttribute("href","#"+i),n.innerHTML=this.noteIndex;let r=t.createElement("sup");r.appendChild(n);let s=t.querySelector("ol.notes");s||(s=t.createElement("ol"),s.setAttribute("class","notes"),this.dom.appendChild(s));let o=t.createElement("li");return o.id=i,o.innerHTML=e.innerHTML,s.appendChild(o),r}],["_",["(",")"]]],teiHeader:function(e){this.hideContent(e,!1)},title:[["tei-titlestmt>tei-title",function(e){const t=e.ownerDocument;let i=t.createElement("title");i.innerHTML=e.innerText,t.querySelector("head").appendChild(i)}]]},teieg:{egXML:function(e){const t=e.ownerDocument;let i=t.createElement("pre"),n=t.createElement("code");i.appendChild(n);let r=this.serialize(e,!0).replace(/</g,"&lt;"),s=r.match(/^[\t ]+/);return s&&(r=r.replace(new RegExp("^"+s[0],"mg"),"")),n.innerHTML=r,i}}};function t(e){const t=e.ownerDocument;let i=e=>{let n;switch(e.nodeType){case 1:n=t.createElement(e.nodeName);break;case 9:n=t.implementation.createDocument();break;case 11:n=t.createDocumentFragment();break;default:n=e.cloneNode(!0)}if(e.attributes)for(let t of Array.from(e.attributes))"data-processed"!==t.name&&n.setAttribute(t.name,t.value);for(let t of Array.from(e.childNodes))if(1==t.nodeType){if(t.hasAttribute("data-original")){for(let e of Array.from(t.childNodes)){let t=n.appendChild(i(e));1===t.nodeType&&t.hasAttribute("data-origid")&&(t.setAttribute("id",t.getAttribute("data-origid")),t.removeAttribute("data-origid"))}return n}t.hasAttribute("data-origname")&&n.appendChild(i(t))}else n.appendChild(t.cloneNode());return n};return i(e)}function i(e){return e.replace(/ .*$/,"")}function n(e,t=!0){const i=e.ownerDocument;if(e.childNodes.length>0){let n=i.createElement("cetei-original");e.appendChild(n),n.setAttribute("hidden",""),n.setAttribute("data-original","");for(let t of Array.from(e.childNodes))if(t!==n){if(1===t.nodeType){t.setAttribute("data-processed","");for(let e of t.querySelectorAll("*"))e.setAttribute("data-processed","")}n.appendChild(e.removeChild(t))}if(t)for(let e of Array.from(n.querySelectorAll("*")))e.hasAttribute("id")&&(e.setAttribute("data-origid",e.getAttribute("id")),e.removeAttribute("id"))}}function r(e,t,i){let n="";const s=e=>!/[^\t\n\r ]/.test(e);if(9!==e.nodeType&&11!==e.nodeType||(n+='<?xml version="1.0" encoding="UTF-8"?>\n'),!t&&1==e.nodeType){n+="string"==typeof i&&""!==i?"\n"+i+"<":"<",n+=e.getAttribute("data-origname");let t=e.hasAttribute("data-origatts")?e.getAttribute("data-origatts").split(" "):[];for(let i of Array.from(e.attributes))i.name.startsWith("data-")||["id","lang","class"].includes(i.name)||(n+=" "+t.find((function(e){return e.toLowerCase()==i.name}))+'="'+i.value+'"'),"data-xmlns"==i.name&&(n+=' xmlns="'+i.value+'"');e.childNodes.length>0?n+=">":n+="/>"}for(let o of Array.from(e.childNodes))switch(o.nodeType){case 1:n+=r(o,!1,"string"==typeof i?i+" ":i);break;case 7:n+=`<?${o.nodeName} ${o.nodeValue}?>`,9!==e.nodeType&&11!==e.nodeType||(n+="\n");break;case 8:n+=`\x3c!--${o.nodeValue}--\x3e`,9!==e.nodeType&&11!==e.nodeType||(n+="\n");break;default:if(t&&s(o.nodeValue)&&(n+=o.nodeValue.replace(/^\s*\n/,"")),"string"==typeof i&&s(o.nodeValue))break;n+=o.nodeValue}return!t&&1==e.nodeType&&e.childNodes.length>0&&(n+="string"==typeof i?"\n"+i+"</":"</",n+=e.getAttribute("data-origname")+">"),9!==e.nodeType&&11!==e.nodeType||(n+="\n"),n}function s(e){return e.includes(":"),e.replace(/:/,"-").toLowerCase()}function o(e,t=null,i=!1){try{window.customElements.define(s(e),class extends HTMLElement{constructor(){super(),this.matches(":defined")||t&&(t.call(this),this.setAttribute("data-processed",""))}connectedCallback(){this.hasAttribute("data-processed")||t&&(t.call(this),this.setAttribute("data-processed",""))}})}catch(t){i&&(console.log(s(e)+" couldn't be registered or is already registered."),console.log(t))}}var a=Object.freeze({__proto__:null,getOrdinality:function(e,t){let i=1,n=e;for(;n&&null!==n.previousElementSibling&&(!t||n.previousElementSibling.localName==t)&&(i++,n=n.previousElementSibling,n.previousElementSibling););return i},copyAndReset:t,first:i,hideContent:n,normalizeURI:function(e){return this.rw(this.first(e))},repeat:function(e,t){let i="";for(let n=0;n<t;n++)i+=e;return i},resolveURI:function(e){let t=this.prefixDefs[e.substring(0,e.indexOf(":"))];return e.replace(new RegExp(t.matchPattern),t.replacementPattern)},getPrefixDef:function(e){return this.prefixDefs[e]},rw:function(e){return e.match(/^(?:http|mailto|file|\/|#).*$/)?e:this.base+i(e)},resetAndSerialize:function(e,i,n){return r(t(e),i,n)},serialize:r,serializeHTML:function e(t,i,n){let r="";const s=e=>!/[^\t\n\r ]/.test(e);if(!i&&1==t.nodeType){r+="string"==typeof n&&""!==n?"\n"+n+"<":"<",r+=t.nodeName;for(let e of Array.from(t.attributes))r+=" "+e.name+'="'+e.value+'"';r+=">"}for(let o of Array.from(t.childNodes))switch(o.nodeType){case 1:r+=e(o,!1,"string"==typeof n?n+" ":n);break;case 7:r+=`<?${o.nodeName} ${o.nodeValue}?>`,9!==t.nodeType&&11!==t.nodeType||(r+="\n");break;case 8:r+=`\x3c!--${o.nodeValue}--\x3e`,9!==t.nodeType&&11!==t.nodeType||(r+="\n");break;default:if(i&&s(o.nodeValue)&&(r+=o.nodeValue.replace(/^\s*\n/,"")),"string"==typeof n&&s(o.nodeValue))break;r+=o.nodeValue.replace(/</g,"&lt;")}return["area","base","br","col","embed","hr","img","input","link","meta","param","source","track","wbr"].includes(t.nodeName)||i||1!=t.nodeType||(r+="string"==typeof n?`\n${n}</`:"</",r+=`${t.nodeName}>`),9!==t.nodeType&&11!==t.nodeType||(r+="\n"),r},unEscapeEntities:function(e){return e.replace(/&gt;/,">").replace(/&quot;/,'"').replace(/&apos;/,"'").replace(/&amp;/,"&")},tagName:s,defineCustomElement:o});function l(e){if(e.namespaces)for(let t of Object.keys(e.namespaces))this.namespaces.has(e.namespaces[t])||Array.from(this.namespaces.values()).includes(t)||this.namespaces.set(e.namespaces[t],t);for(let t of this.namespaces.values())if(e[t])for(let i of Object.keys(e[t]))this.behaviors[`${t}:${i}`]=e[t][i];if(e.functions)for(let t of Object.keys(e.functions))this.utilities[t]=e.functions[t].bind(this.utilities);e.handlers&&console.log("Behavior handlers are no longer used."),e.fallbacks&&console.log("Fallback behaviors are no longer used.")}function d(e,t,i){let n;if(e===Object(e))for(let t of Object.keys(e))this.namespaces.has(e[t])||(this.namespaces.set(e[t],t),n=t);else n=e;this.behaviors[`${n}:${t}`]=i}function c(e,t){let i;if(e===Object(e))for(let t of Object.keys(e))this.namespaces.has(e[t])||(this.namespaces.set(e[t],t),i=t);else i=e;delete this.behaviors[`${i}:${t}`]}class h{constructor(t){this.options=t||{},this.document=this.options.documentObject?this.options.documentObject:void 0,void 0===this.document&&("undefined"!=typeof window&&window.document?this.document=window.document:"undefined"!=typeof global&&global.document&&(this.document=global.document)),this.addBehaviors=l.bind(this),this.addBehavior=d.bind(this),this.removeBehavior=c.bind(this),this.utilities={};for(const e of Object.keys(a))["getPrefixDef","rw","resolveURI"].includes(e)?this.utilities[e]=a[e].bind(this):this.utilities[e]=a[e];if(this.els=[],this.namespaces=new Map,this.behaviors={},this.hasStyle=!1,this.prefixDefs=[],this.debug=!0===this.options.debug,this.discardContent=!0===this.options.discardContent,this.options.base)this.base=this.options.base;else try{window&&(this.base=window.location.href.replace(/\/[^\/]*$/,"/"))}catch(e){this.base=""}this.options.omitDefaultBehaviors||this.addBehaviors(e),this.options.ignoreFragmentId&&window&&window.removeEventListener("ceteiceanload",h.restorePosition)}async getHTML5(e,t,i){window&&window.location.href.startsWith(this.base)&&e.indexOf("/")>=0&&(this.base=e.replace(/\/[^\/]*$/,"/"));try{const n=await fetch(e);if(n.ok){const e=await n.text();return this.makeHTML5(e,t,i)}console.log(`Could not get XML file ${e}.\nServer returned ${n.status}: ${n.statusText}`)}catch(e){console.log(e)}}makeHTML5(e,t,i){return this.XML_dom=(new DOMParser).parseFromString(e,"text/xml"),this.domToHTML5(this.XML_dom,t,i)}preprocess(e,t,i){this.els=function(e,t){const i=e.documentElement;let n=1,r=function(e){return t.has(e.namespaceURI?e.namespaceURI:"")||t.set(e.namespaceURI,"ns"+n++),t.get(e.namespaceURI?e.namespaceURI:"")+":"+e.localName};const s=new Set(Array.from(i.querySelectorAll("*"),r));return s.add(r(i)),s}(e,this.namespaces);let n=t=>{let r;if(this.namespaces.has(t.namespaceURI?t.namespaceURI:"")){let e=this.namespaces.get(t.namespaceURI?t.namespaceURI:"");r=this.document.createElement(`${e}-${t.localName.toLowerCase()}`)}else r=this.document.importNode(t,!1);for(let e of Array.from(t.attributes))"xmlns"==e.name?r.setAttribute("data-xmlns",e.value):r.setAttribute(e.name,e.value),"xml:id"==e.name&&r.setAttribute("id",e.value),"xml:lang"==e.name&&r.setAttribute("lang",e.value),"rendition"==e.name&&r.setAttribute("class",e.value.replace(/#/g,""));if(r.setAttribute("data-origname",t.localName),t.hasAttributes()&&r.setAttribute("data-origatts",t.getAttributeNames().join(" ")),0==t.childNodes.length&&r.setAttribute("data-empty",""),"head"==t.localName){let i=e.evaluate("count(ancestor::*[tei:head])",t,(function(e){if("tei"==e)return"http://www.tei-c.org/ns/1.0"}),1,null);r.setAttribute("data-level",i.numberValue)}if("tagsDecl"==t.localName){let e=this.document.createElement("style");for(let i of Array.from(t.childNodes))if(1==i.nodeType&&"rendition"==i.localName&&"css"==i.getAttribute("scheme")){let t="";i.hasAttribute("selector")?(t+=i.getAttribute("selector").replace(/([^#, >]+\w*)/g,"tei-$1").replace(/#tei-/g,"#")+"{\n",t+=i.textContent):(t+="."+i.getAttribute("xml:id")+"{\n",t+=i.textContent),t+="\n}\n",e.appendChild(this.document.createTextNode(t))}e.childNodes.length>0&&(r.appendChild(e),this.hasStyle=!0)}"prefixDef"==t.localName&&(this.prefixDefs.push(t.getAttribute("ident")),this.prefixDefs[t.getAttribute("ident")]={matchPattern:t.getAttribute("matchPattern"),replacementPattern:t.getAttribute("replacementPattern")});for(let e of Array.from(t.childNodes))1==e.nodeType?r.appendChild(n(e)):r.appendChild(e.cloneNode());return i&&i(r,t),r};this.dom=this.document.createDocumentFragment();for(let t of Array.from(e.childNodes))1==t.nodeType&&this.dom.appendChild(n(t)),7==t.nodeType&&this.dom.appendChild(this.document.importNode(t,!0)),8==t.nodeType&&this.dom.appendChild(this.document.importNode(t,!0));if(this.utilities.dom=this.dom.firstElementChild,!t)return"undefined"!=typeof window&&window.dispatchEvent(u),this.dom;t(this.dom,this),window&&window.dispatchEvent(u)}domToHTML5(e,t,i){if(this.preprocess(e,null,i),this.applyBehaviors(),this.done=!0,!t)return"undefined"!=typeof window&&window.dispatchEvent(u),this.dom;t(this.dom,this),window&&window.dispatchEvent(u)}processPage(){var e;this.els=(e=this.document,new Set(Array.from(e.querySelectorAll("*[data-origname]"),(e=>e.localName.replace(/(\w+)-.+/,"$1:")+e.getAttribute("data-origname"))))),this.applyBehaviors(),window&&window.dispatchEvent(u)}unsetNamespace(e){this.namespaces.delete(e)}setBaseUrl(e){this.base=e}append(e,t){let i=this;if(!t||t.hasAttribute("data-processed"))return function(){if(!this.hasAttribute("data-processed")){let t=e.call(i.utilities,this);t&&i.appendBasic(this,t)}};{let n=e.call(i.utilities,t);n&&i.appendBasic(t,n)}}appendBasic(e,t){this.discardContent?e.innerHTML="":n(e,!0),e.appendChild(t)}bName(e){return e.tagName.substring(0,e.tagName.indexOf("-")).toLowerCase()+":"+e.getAttribute("data-origname")}childExists(e,t){return!(!e||e.nodeName!=t)||e&&e.nextElementSibling&&this.childExists(e.nextElementSibling,t)}decorator(e){if(Array.isArray(e)&&0==e.length)return function(e){};if(Array.isArray(e)&&!Array.isArray(e[0]))return this.applyDecorator(e);let t=this;return function(i){for(let n of e)if(i.matches(n[0])||"_"===n[0])return Array.isArray(n[1])?t.decorator(n[1]).call(this,i):n[1].call(this,i)}}applyDecorator(e){let t=this;return function(i){let n=[];for(let r=0;r<e.length;r++)n.push(t.template(e[r],i));return t.insert(i,n)}}getFallback(e,t){if(e[t])return e[t]instanceof Function?e[t]:this.decorator(e[t])}getHandler(e,t){if(e[t])return e[t]instanceof Function?this.append(e[t]):this.append(this.decorator(e[t]))}insert(e,t){let i=this.document.createElement("cetei-content");for(let t of Array.from(e.childNodes))1!==t.nodeType||t.hasAttribute("data-processed")||this.processElement(t);if(t[0].match("<[^>]+>")&&t[1]&&t[1].match("<[^>]+>"))i.innerHTML=t[0]+e.innerHTML+(t[1]?t[1]:"");else{i.innerHTML=t[0],i.setAttribute("data-before",t[0].replace(/<[^>]+>/g,"").length);for(let t of Array.from(e.childNodes))i.appendChild(t.cloneNode(!0));t.length>1&&(i.innerHTML+=t[1],i.setAttribute("data-after",t[1].replace(/<[^>]+>/g,"").length))}return i.childNodes.length<2?i.firstChild:i}processElement(e){if(e.hasAttribute("data-origname")&&!e.hasAttribute("data-processed")){let t=this.getFallback(this.bName(e));t&&(this.append(t,e),e.setAttribute("data-processed",""))}for(let t of Array.from(e.childNodes))1===t.nodeType&&this.processElement(t)}template(e,t){let i=e;if(e.search(/\$(\w*)(@([a-zA-Z:]+))/)){let n,r=/\$(\w*)@([a-zA-Z:]+)/g;for(;n=r.exec(e);)i=t.hasAttribute(n[2])?n[1]&&this.utilities[n[1]]?i.replace(n[0],this.utilities[n[1]](t.getAttribute(n[2]))):i.replace(n[0],t.getAttribute(n[2])):i.replace(n[0],"")}return i}applyBehaviors(){"undefined"!=typeof window&&window.customElements?this.define.call(this,this.els):this.fallback.call(this,this.els)}define(e){for(let t of e){o(t,this.getHandler(this.behaviors,t),this.debug)}}fallback(e){for(let t of e){let e=this.getFallback(this.behaviors,t);if(e)for(let i of Array.from((this.dom&&!this.done?this.dom:this.document).querySelectorAll(s(t))))i.hasAttribute("data-processed")||(this.append(e,i),i.setAttribute("data-processed",""))}}static savePosition(){window.sessionStorage.setItem(window.location+"-scroll",window.scrollY)}static restorePosition(){if(window.location.hash)setTimeout((function(){let e=this.document.querySelector(window.decodeURI(window.location.hash));e&&e.scrollIntoView()}),100);else{let e;(e=window.sessionStorage.getItem(window.location+"-scroll"))&&(window.sessionStorage.removeItem(window.location+"-scroll"),setTimeout((function(){window.scrollTo(0,e)}),100))}}}try{if("undefined"!=typeof window){window.CETEI=h,window.addEventListener("beforeunload",h.savePosition);var u=new Event("ceteiceanload");window.addEventListener("ceteiceanload",h.restorePosition)}}catch(e){console.log(e)}return h}();
1
+ var CETEI=function(){"use strict";var e={namespaces:{tei:"http://www.tei-c.org/ns/1.0",teieg:"http://www.tei-c.org/ns/Examples",rng:"http://relaxng.org/ns/structure/1.0"},tei:{eg:["<pre>","</pre>"],ptr:['<a href="$rw@target">$@target</a>'],ref:[["[target]",['<a href="$rw@target">',"</a>"]]],graphic:function(e){let t=e.ownerDocument.createElement("img");return t.src=this.rw(e.getAttribute("url")),e.hasAttribute("width")&&t.setAttribute("width",e.getAttribute("width")),e.hasAttribute("height")&&t.setAttribute("height",e.getAttribute("height")),t},list:[["[type=gloss]",function(e){const t=e.ownerDocument;let i=t.createElement("dl");for(let n of Array.from(e.children))if(1==n.nodeType){if("tei-label"==n.localName){let e=t.createElement("dt");e.innerHTML=n.innerHTML,i.appendChild(e)}if("tei-item"==n.localName){let e=t.createElement("dd");e.innerHTML=n.innerHTML,i.appendChild(e)}}return i}]],note:[["[place=end]",function(e){const t=e.ownerDocument;this.noteIndex?this.noteIndex++:this.noteIndex=1;let i="_note_"+this.noteIndex,n=t.createElement("a");n.setAttribute("id","src"+i),n.setAttribute("href","#"+i),n.innerHTML=this.noteIndex;let r=t.createElement("sup");r.appendChild(n);let a=t.querySelector("ol.notes");a||(a=t.createElement("ol"),a.setAttribute("class","notes"),this.dom.appendChild(a));let o=t.createElement("li");return o.id=i,o.innerHTML=e.innerHTML,a.appendChild(o),r}],["_",["(",")"]]],teiHeader:function(e){this.hideContent(e,!1)},title:[["tei-titlestmt>tei-title",function(e){const t=e.ownerDocument;let i=t.createElement("title");i.innerHTML=e.innerText,t.querySelector("head").appendChild(i)}]]},teieg:{egXML:function(e){const t=e.ownerDocument;let i=t.createElement("pre"),n=t.createElement("code");i.appendChild(n);let r=this.serialize(e,!0).replace(/</g,"&lt;"),a=r.match(/^[\t ]+/);return a&&(r=r.replace(new RegExp("^"+a[0],"mg"),"")),n.innerHTML=r,i}}};function t(e){const t=e.ownerDocument;let i=e=>{let n;switch(e.nodeType){case 1:n=t.createElement(e.nodeName);break;case 9:n=t.implementation.createDocument();break;case 11:n=t.createDocumentFragment();break;default:n=e.cloneNode(!0)}if(e.attributes)for(let t of Array.from(e.attributes))"data-processed"!==t.name&&n.setAttribute(t.name,t.value);for(let t of Array.from(e.childNodes))if(1==t.nodeType){if(t.hasAttribute("data-original")){for(let e of Array.from(t.childNodes)){let t=n.appendChild(i(e));1===t.nodeType&&t.hasAttribute("data-origid")&&(t.setAttribute("id",t.getAttribute("data-origid")),t.removeAttribute("data-origid"))}return n}t.hasAttribute("data-origname")&&n.appendChild(i(t))}else n.appendChild(t.cloneNode());return n};return i(e)}function i(e){return e.replace(/ .*$/,"")}function n(e){let t=!(arguments.length>1&&void 0!==arguments[1])||arguments[1];const i=e.ownerDocument;if(e.childNodes.length>0){let n=i.createElement("cetei-original");e.appendChild(n),n.setAttribute("hidden",""),n.setAttribute("data-original",""),n.setAttribute("role","none");for(let t of Array.from(e.childNodes))if(t!==n){if(1===t.nodeType){t.setAttribute("data-processed","");for(let e of t.querySelectorAll("*"))e.setAttribute("data-processed","")}n.appendChild(e.removeChild(t))}if(t)for(let e of Array.from(n.querySelectorAll("*")))e.hasAttribute("id")&&(e.setAttribute("data-origid",e.getAttribute("id")),e.removeAttribute("id"))}}function r(e,t,i){let n="";const a=e=>!/[^\t\n\r ]/.test(e);if(9!==e.nodeType&&11!==e.nodeType||(n+='<?xml version="1.0" encoding="UTF-8"?>\n'),!t&&1==e.nodeType){n+="string"==typeof i&&""!==i?"\n"+i+"<":"<",n+=e.getAttribute("data-origname");let t=e.hasAttribute("data-origatts")?e.getAttribute("data-origatts").split(" "):[];for(let i of Array.from(e.attributes))i.name.startsWith("data-")||i.name.startsWith("tei-")||i.name.startsWith("aria-")||["id","lang","class"].includes(i.name)||(n+=" "+t.find((function(e){return e.toLowerCase()==i.name}))+'="'+i.value+'"'),"data-xmlns"==i.name&&(n+=' xmlns="'+i.value+'"'),i.name.startsWith("tei-")&&(n+=" "+t.find((function(e){return e.toLowerCase()==i.name.replace("tei-","")}))+'="'+i.value+'"');e.childNodes.length>0?n+=">":n+="/>"}for(let o of Array.from(e.childNodes))switch(o.nodeType){case 1:n+=r(o,!1,"string"==typeof i?i+" ":i);break;case 7:n+=`<?${o.nodeName} ${o.nodeValue}?>`,9!==e.nodeType&&11!==e.nodeType||(n+="\n");break;case 8:n+=`\x3c!--${o.nodeValue}--\x3e`,9!==e.nodeType&&11!==e.nodeType||(n+="\n");break;default:if(t&&a(o.nodeValue)&&(n+=o.nodeValue.replace(/^\s*\n/,"")),"string"==typeof i&&a(o.nodeValue))break;n+=o.nodeValue}return!t&&1==e.nodeType&&e.childNodes.length>0&&(n+="string"==typeof i?"\n"+i+"</":"</",n+=e.getAttribute("data-origname")+">"),9!==e.nodeType&&11!==e.nodeType||(n+="\n"),n}function a(e){return e.includes(":"),e.replace(/:/,"-").toLowerCase()}function o(e){let t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:null,i=arguments.length>2&&void 0!==arguments[2]&&arguments[2];try{window.customElements.define(a(e),class extends HTMLElement{constructor(){super(),this.matches(":defined")||t&&(t.call(this),this.setAttribute("data-processed",""))}connectedCallback(){this.hasAttribute("data-processed")||t&&(t.call(this),this.setAttribute("data-processed",""))}})}catch(t){i&&(console.log(a(e)+" couldn't be registered or is already registered."),console.log(t))}}var s=Object.freeze({__proto__:null,copyAndReset:t,defineCustomElement:o,first:i,getOrdinality:function(e,t){let i=1,n=e;for(;n&&null!==n.previousElementSibling&&(!t||n.previousElementSibling.localName==t)&&(i++,n=n.previousElementSibling,n.previousElementSibling););return i},getPrefixDef:function(e){return this.prefixDefs[e]},hideContent:n,normalizeURI:function(e){return this.rw(this.first(e))},repeat:function(e,t){let i="";for(let n=0;n<t;n++)i+=e;return i},resetAndSerialize:function(e,i,n){return r(t(e),i,n)},resolveURI:function(e){let t=this.prefixDefs[e.substring(0,e.indexOf(":"))];return e.replace(new RegExp(t.matchPattern),t.replacementPattern)},rw:function(e){return e.trim().match(/^(?:http|mailto|file|\/|#).*$/)?e:this.base+i(e.trim())},serialize:r,serializeHTML:function e(t,i,n){let r="";const a=e=>!/[^\t\n\r ]/.test(e);if(!i&&1==t.nodeType){r+="string"==typeof n&&""!==n?"\n"+n+"<":"<",r+=t.nodeName;for(let e of Array.from(t.attributes))r+=" "+e.name+'="'+e.value+'"';r+=">"}for(let o of Array.from(t.childNodes))switch(o.nodeType){case 1:r+=e(o,!1,"string"==typeof n?n+" ":n);break;case 7:r+=`<?${o.nodeName} ${o.nodeValue}?>`,9!==t.nodeType&&11!==t.nodeType||(r+="\n");break;case 8:r+=`\x3c!--${o.nodeValue}--\x3e`,9!==t.nodeType&&11!==t.nodeType||(r+="\n");break;default:if(i&&a(o.nodeValue)&&(r+=o.nodeValue.replace(/^\s*\n/,"")),"string"==typeof n&&a(o.nodeValue))break;r+=o.nodeValue.replace(/</g,"&lt;")}return["area","base","br","col","embed","hr","img","input","link","meta","param","source","track","wbr"].includes(t.nodeName)||i||1!=t.nodeType||(r+="string"==typeof n?`\n${n}</`:"</",r+=`${t.nodeName}>`),9!==t.nodeType&&11!==t.nodeType||(r+="\n"),r},tagName:a,unEscapeEntities:function(e){return e.replace(/&gt;/,">").replace(/&quot;/,'"').replace(/&apos;/,"'").replace(/&amp;/,"&")}});function l(e){if(e.namespaces)for(let t of Object.keys(e.namespaces))this.namespaces.has(e.namespaces[t])||Array.from(this.namespaces.values()).includes(t)||this.namespaces.set(e.namespaces[t],t);for(let t of this.namespaces.values())if(e[t])for(let i of Object.keys(e[t]))this.behaviors[`${t}:${i}`]=e[t][i];if(e.functions)for(let t of Object.keys(e.functions))this.utilities[t]=e.functions[t].bind(this.utilities);e.handlers&&console.log("Behavior handlers are no longer used."),e.fallbacks&&console.log("Fallback behaviors are no longer used.")}function d(e,t,i){let n;if(e===Object(e))for(let t of Object.keys(e))this.namespaces.has(e[t])||(this.namespaces.set(e[t],t),n=t);else n=e;this.behaviors[`${n}:${t}`]=i}function c(e,t){let i;if(e===Object(e))for(let t of Object.keys(e))this.namespaces.has(e[t])||(this.namespaces.set(e[t],t),i=t);else i=e;delete this.behaviors[`${i}:${t}`]}class h{constructor(t){this.options=t||{},this.document=this.options.documentObject?this.options.documentObject:void 0,void 0===this.document&&("undefined"!=typeof window&&window.document?this.document=window.document:"undefined"!=typeof global&&global.document&&(this.document=global.document)),this.addBehaviors=l.bind(this),this.addBehavior=d.bind(this),this.removeBehavior=c.bind(this),this.utilities={};for(const e of Object.keys(s))["getPrefixDef","rw","resolveURI"].includes(e)?this.utilities[e]=s[e].bind(this):this.utilities[e]=s[e];if(this.els=[],this.namespaces=new Map,this.behaviors={},this.hasStyle=!1,this.prefixDefs=[],this.debug=!0===this.options.debug,this.discardContent=!0===this.options.discardContent,this.options.base)this.base=this.options.base;else try{window&&(this.base=window.location.href.replace(/\/[^\/]*$/,"/"))}catch(e){this.base=""}this.options.omitDefaultBehaviors||this.addBehaviors(e),this.options.ignoreFragmentId&&window&&window.removeEventListener("ceteiceanload",h.restorePosition)}async getHTML5(e,t,i){window&&window.location.href.startsWith(this.base)&&e.indexOf("/")>=0&&(this.base=e.replace(/\/[^\/]*$/,"/"));try{const n=await fetch(e);if(n.ok){const e=await n.text();return this.makeHTML5(e,t,i)}console.log(`Could not get XML file ${e}.\nServer returned ${n.status}: ${n.statusText}`)}catch(e){console.log(e)}}makeHTML5(e,t,i){return this.XML_dom=(new DOMParser).parseFromString(e,"text/xml"),this.domToHTML5(this.XML_dom,t,i)}preprocess(e,t,i){this.els=function(e,t){const i=e.documentElement;let n=1,r=function(e){return t.has(e.namespaceURI?e.namespaceURI:"")||t.set(e.namespaceURI,"ns"+n++),t.get(e.namespaceURI?e.namespaceURI:"")+":"+e.localName};const a=new Set(Array.from(i.querySelectorAll("*"),r));return a.add(r(i)),a}(e,this.namespaces);let n=e=>{let t;if(this.namespaces.has(e.namespaceURI?e.namespaceURI:"")){let r=this.namespaces.get(e.namespaceURI?e.namespaceURI:"");t=this.document.createElement(`${r}-${e.localName.toLowerCase()}`)}else t=this.document.importNode(e,!1);for(let a of Array.from(e.attributes))"xmlns"==a.name?t.setAttribute("data-xmlns",a.value):["role"].includes(a.name)||t.setAttribute(a.name,a.value),"xml:id"==a.name&&t.setAttribute("id",a.value),"xml:lang"==a.name&&t.setAttribute("lang",a.value),"rendition"==a.name&&t.setAttribute("class",a.value.replace(/#/g,"")),"role"==a.name&&t.setAttribute("tei-role",a.value);if(t.setAttribute("data-origname",e.localName),e.hasAttributes()&&t.setAttribute("data-origatts",e.getAttributeNames().join(" ")),0==e.childNodes.length&&t.setAttribute("data-empty",""),"head"==e.localName&&"http://www.tei-c.org/ns/1.0"==e.namespaceURI){function o(e){let t=0,i=e.parentElement;for(;i;){let e=i.children,n=0;for(;n<e.length;){if("head"===e[n].tagName.toLowerCase()&&"http://www.tei-c.org/ns/1.0"===e[n].namespaceURI){t++;break}n++}i=i.parentElement}return t}t.setAttribute("data-level",o(e))}if("tagsDecl"==e.localName){let s=this.document.createElement("style");for(let l of Array.from(e.childNodes))if(1==l.nodeType&&"rendition"==l.localName&&"css"==l.getAttribute("scheme")){let d="";l.hasAttribute("selector")?(d+=l.getAttribute("selector").replace(/([^#, >]+\w*)/g,"tei-$1").replace(/#tei-/g,"#")+"{\n",d+=l.textContent):(d+="."+l.getAttribute("xml:id")+"{\n",d+=l.textContent),d+="\n}\n",s.appendChild(this.document.createTextNode(d))}s.childNodes.length>0&&(t.appendChild(s),this.hasStyle=!0)}"prefixDef"==e.localName&&(this.prefixDefs.push(e.getAttribute("ident")),this.prefixDefs[e.getAttribute("ident")]={matchPattern:e.getAttribute("matchPattern"),replacementPattern:e.getAttribute("replacementPattern")}),"TEI"==e.localName&&t.setAttribute("role","main"),["body","front","back","div"].includes(e.localName)&&(t.setAttribute("role","region"),t.setAttribute("aria-label",e.getAttribute("xml:id")||e.getAttribute("n")||e.localName));for(let c of Array.from(e.childNodes))1==c.nodeType?t.appendChild(n(c)):t.appendChild(c.cloneNode());return i&&i(t,e),t};this.dom=this.document.createDocumentFragment();for(let t of Array.from(e.childNodes))1==t.nodeType&&this.dom.appendChild(n(t)),7==t.nodeType&&this.dom.appendChild(this.document.importNode(t,!0)),8==t.nodeType&&this.dom.appendChild(this.document.importNode(t,!0));if(this.utilities.dom=this.dom.firstElementChild,!t)return"undefined"!=typeof window&&window.dispatchEvent(u),this.dom;t(this.dom,this),window&&window.dispatchEvent(u)}domToHTML5(e,t,i){if(this.preprocess(e,null,i),this.applyBehaviors(),this.done=!0,!t)return"undefined"!=typeof window&&window.dispatchEvent(u),this.dom;t(this.dom,this),window&&window.dispatchEvent(u)}processPage(){var e;this.els=(e=this.document,new Set(Array.from(e.querySelectorAll("*[data-origname]"),(e=>e.localName.replace(/(\w+)-.+/,"$1:")+e.getAttribute("data-origname"))))),this.applyBehaviors(),window&&window.dispatchEvent(u)}unsetNamespace(e){this.namespaces.delete(e)}setBaseUrl(e){this.base=e}append(e,t){let i=this;if(!t||t.hasAttribute("data-processed"))return function(){if(!this.hasAttribute("data-processed")){let t=e.call(i.utilities,this);t&&i.appendBasic(this,t)}};{let n=e.call(i.utilities,t);n&&i.appendBasic(t,n)}}appendBasic(e,t){this.discardContent?e.innerHTML="":n(e,!0),e.appendChild(t)}bName(e){return e.tagName.substring(0,e.tagName.indexOf("-")).toLowerCase()+":"+e.getAttribute("data-origname")}childExists(e,t){return!(!e||e.nodeName!=t)||e&&e.nextElementSibling&&this.childExists(e.nextElementSibling,t)}decorator(e){if(Array.isArray(e)&&0==e.length)return function(e){};if(Array.isArray(e)&&!Array.isArray(e[0]))return this.applyDecorator(e);let t=this;return function(i){for(let n of e)if(i.matches(n[0])||"_"===n[0])return Array.isArray(n[1])?t.decorator(n[1]).call(this,i):n[1].call(this,i)}}applyDecorator(e){let t=this;return function(i){let n=[];for(let r=0;r<e.length;r++)n.push(t.template(e[r],i));return t.insert(i,n)}}getFallback(e,t){if(e[t])return e[t]instanceof Function?e[t]:this.decorator(e[t])}getHandler(e,t){if(e[t])return e[t]instanceof Function?this.append(e[t]):this.append(this.decorator(e[t]))}insert(e,t){let i=this.document.createElement("cetei-content");for(let t of Array.from(e.childNodes))1!==t.nodeType||t.hasAttribute("data-processed")||this.processElement(t);if(t[0].match("<[^>]+>")&&t[1]&&t[1].match("<[^>]+>"))i.innerHTML=t[0]+e.innerHTML+(t[1]?t[1]:"");else{i.innerHTML=t[0],i.setAttribute("data-before",t[0].replace(/<[^>]+>/g,"").length);for(let t of Array.from(e.childNodes))i.appendChild(t.cloneNode(!0));t.length>1&&(i.innerHTML+=t[1],i.setAttribute("data-after",t[1].replace(/<[^>]+>/g,"").length))}return i.childNodes.length<2?i.firstChild:i}processElement(e){if(e.hasAttribute("data-origname")&&!e.hasAttribute("data-processed")){let t=this.getFallback(this.bName(e));t&&(this.append(t,e),e.setAttribute("data-processed",""))}for(let t of Array.from(e.childNodes))1===t.nodeType&&this.processElement(t)}template(e,t){let i=e;if(e.search(/\$(\w*)(@([a-zA-Z:]+))/)){let n,r=/\$(\w*)@([a-zA-Z:]+)/g;for(;n=r.exec(e);)i=t.hasAttribute(n[2])?n[1]&&this.utilities[n[1]]?i.replace(n[0],this.utilities[n[1]](t.getAttribute(n[2]))):i.replace(n[0],t.getAttribute(n[2])):i.replace(n[0],"")}return i}applyBehaviors(){"undefined"!=typeof window&&window.customElements?this.define.call(this,this.els):this.fallback.call(this,this.els)}define(e){for(let t of e){o(t,this.getHandler(this.behaviors,t),this.debug)}}fallback(e){for(let t of e){let e=this.getFallback(this.behaviors,t);if(e)for(let i of Array.from((this.dom&&!this.done?this.dom:this.document).querySelectorAll(a(t))))i.hasAttribute("data-processed")||(this.append(e,i),i.setAttribute("data-processed",""))}}static savePosition(){window.sessionStorage.setItem(window.location+"-scroll",window.scrollY)}static restorePosition(){if(window.location.hash)setTimeout((function(){let e=this.document.querySelector(window.decodeURI(window.location.hash));e&&e.scrollIntoView()}),100);else{let e;(e=window.sessionStorage.getItem(window.location+"-scroll"))&&(window.sessionStorage.removeItem(window.location+"-scroll"),setTimeout((function(){window.scrollTo(0,e)}),100))}}}try{if("undefined"!=typeof window){window.CETEI=h,window.addEventListener("beforeunload",h.savePosition);var u=new Event("ceteiceanload");window.addEventListener("ceteiceanload",h.restorePosition)}}catch(e){console.log(e)}return h}();
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "CETEIcean",
3
- "version": "1.9.3",
3
+ "version": "1.9.5",
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
6
  "type": "module",
@@ -21,16 +21,15 @@
21
21
  "./utilities.js": "./src/utilities.js"
22
22
  },
23
23
  "devDependencies": {
24
- "@babel/core": "^7.15.5",
25
- "@babel/preset-env": "7.15.6",
26
- "@rollup/plugin-babel": "^5.3.0",
27
- "babel-preset-env": "^1.7.0",
24
+ "@babel/core": "^7.26.9",
25
+ "@babel/preset-env": "^7.26.9",
26
+ "@rollup/plugin-babel": "^6.0.4",
27
+ "@rollup/plugin-terser": "^0.4.4",
28
28
  "http-server": "^14.1.1",
29
- "jsdom": "^21.1.0",
30
- "onchange": "^6.1.1",
31
- "rollup": "^2.57.0",
32
- "rollup-plugin-terser": "^7.0.2",
33
- "terser": "^5.14.2"
29
+ "jsdom": "^26.0.0",
30
+ "onchange": "^7.1.0",
31
+ "rollup": "^4.34.8",
32
+ "terser": "^5.39.0"
34
33
  },
35
34
  "scripts": {
36
35
  "build": "npm test && rollup -c rollup.config.js",
package/rollup.config.js CHANGED
@@ -1,18 +1,19 @@
1
- import babel from '@rollup/plugin-babel';
2
- import { terser } from 'rollup-plugin-terser';
1
+ import babel from "@rollup/plugin-babel";
2
+ import terser from "@rollup/plugin-terser";
3
3
 
4
4
  export default {
5
- input: 'src/CETEI.js',
5
+ input: "src/CETEI.js",
6
6
  output: {
7
- file: 'dist/CETEI.js',
8
- format: 'iife',
9
- name: 'CETEI',
7
+ file: "dist/CETEI.js",
8
+ format: "iife",
9
+ name: "CETEI",
10
10
  sourcemap: false,
11
11
  },
12
12
  plugins: [
13
- babel({exclude: 'node_modules/**',
13
+ babel({exclude: "node_modules/**",
14
+ "babelHelpers": "bundled",
14
15
  "presets": [
15
- ["env", {
16
+ ["@babel/env", {
16
17
  "modules": false,
17
18
  "targets": {
18
19
  "chrome": 65,
package/src/CETEI.js CHANGED
@@ -116,7 +116,9 @@ class CETEI {
116
116
  //Strip default namespaces, but hang on to the values
117
117
  newElement.setAttribute("data-xmlns", att.value);
118
118
  } else {
119
- newElement.setAttribute(att.name, att.value);
119
+ if (!["role"].includes(att.name) ){
120
+ newElement.setAttribute(att.name, att.value);
121
+ }
120
122
  }
121
123
  if (att.name == "xml:id") {
122
124
  newElement.setAttribute("id", att.value);
@@ -127,6 +129,11 @@ class CETEI {
127
129
  if (att.name == "rendition") {
128
130
  newElement.setAttribute("class", att.value.replace(/#/g, ""));
129
131
  }
132
+ // @role has a name collision with the HTML5 role attribute, so we
133
+ // use a TEI-specific attribute instead.
134
+ if (att.name == "role") {
135
+ newElement.setAttribute("tei-role", att.value);
136
+ }
130
137
  }
131
138
  // Preserve element name so we can use it later
132
139
  newElement.setAttribute("data-origname", el.localName);
@@ -138,12 +145,25 @@ class CETEI {
138
145
  newElement.setAttribute("data-empty", "");
139
146
  }
140
147
  // <head> elements need to know their level
141
- if (el.localName == "head") {
142
- // 1 is XPathResult.NUMBER_TYPE
143
- let level = XML_dom.evaluate("count(ancestor::*[tei:head])", el, function(ns) {
144
- if (ns == "tei") return "http://www.tei-c.org/ns/1.0";
145
- }, 1, null);
146
- newElement.setAttribute("data-level", level.numberValue);
148
+ if (el.localName == "head" && el.namespaceURI == "http://www.tei-c.org/ns/1.0") {
149
+ function getLevel(el) {
150
+ let count = 0;
151
+ let ancestor = el.parentElement;
152
+ while (ancestor) {
153
+ let children = ancestor.children;
154
+ let i = 0;
155
+ while (i < children.length) {
156
+ if (children[i].tagName.toLowerCase() === "head" && children[i].namespaceURI === "http://www.tei-c.org/ns/1.0") {
157
+ count++;
158
+ break; // Only count once
159
+ }
160
+ i++;
161
+ }
162
+ ancestor = ancestor.parentElement; // Move to the next ancestor
163
+ }
164
+ return count;
165
+ }
166
+ newElement.setAttribute("data-level", getLevel(el));
147
167
  }
148
168
  // Turn <rendition scheme="css"> elements into HTML styles
149
169
  if (el.localName == "tagsDecl") {
@@ -177,6 +197,14 @@ class CETEI {
177
197
  "replacementPattern": el.getAttribute("replacementPattern")
178
198
  };
179
199
  }
200
+ // Aria roles for landmark elements
201
+ if (el.localName == "TEI") {
202
+ newElement.setAttribute("role", "main");
203
+ }
204
+ if (["body", "front", "back", "div"].includes(el.localName)) {
205
+ newElement.setAttribute("role", "region");
206
+ newElement.setAttribute("aria-label", el.getAttribute("xml:id") || el.getAttribute("n") || el.localName);
207
+ }
180
208
  for (let node of Array.from(el.childNodes)) {
181
209
  // Node.ELEMENT_NODE
182
210
  if (node.nodeType == 1 ) {
@@ -16,7 +16,7 @@ export default {
16
16
  ],
17
17
  // creates an img tag with the @url as the src attribute
18
18
  "graphic": function(elt) {
19
- let content = new Image();
19
+ let content = elt.ownerDocument.createElement("img");
20
20
  content.src = this.rw(elt.getAttribute("url"));
21
21
  if (elt.hasAttribute("width")) {
22
22
  content.setAttribute("width",elt.getAttribute("width"));
package/src/utilities.js CHANGED
@@ -82,6 +82,7 @@ export function hideContent(elt, rewriteIds = true) {
82
82
  elt.appendChild(hidden);
83
83
  hidden.setAttribute("hidden", "");
84
84
  hidden.setAttribute("data-original", "");
85
+ hidden.setAttribute("role", "none");
85
86
  for (let node of Array.from(elt.childNodes)) {
86
87
  if (node !== hidden) {
87
88
  // nodeType 1 is Node.ELEMENT_NODE
@@ -144,8 +145,8 @@ export function getPrefixDef(prefix) {
144
145
  HTML document
145
146
  */
146
147
  export function rw(url) {
147
- if (!url.match(/^(?:http|mailto|file|\/|#).*$/)) {
148
- return this.base + first(url);
148
+ if (!url.trim().match(/^(?:http|mailto|file|\/|#).*$/)) {
149
+ return this.base + first(url.trim());
149
150
  } else {
150
151
  return url;
151
152
  }
@@ -184,12 +185,18 @@ export function serialize(el, stripElt, ws) {
184
185
  // HTML5 lowercases all attribute names; @data-origatts contains the original names
185
186
  let attrNames = el.hasAttribute("data-origatts") ? el.getAttribute("data-origatts").split(" ") : [];
186
187
  for (let attr of Array.from(el.attributes)) {
187
- if (!attr.name.startsWith("data-") && !(["id", "lang", "class"].includes(attr.name))) {
188
+ if (!attr.name.startsWith("data-")
189
+ && !attr.name.startsWith("tei-")
190
+ && !attr.name.startsWith("aria-")
191
+ && !(["id", "lang", "class"].includes(attr.name))) {
188
192
  str += " " + attrNames.find(function(e) {return e.toLowerCase() == attr.name}) + "=\"" + attr.value + "\"";
189
193
  }
190
194
  if (attr.name == "data-xmlns") {
191
195
  str += " xmlns=\"" + attr.value +"\"";
192
196
  }
197
+ if (attr.name.startsWith("tei-")) {
198
+ str += " " + attrNames.find(function(e) {return e.toLowerCase() == attr.name.replace("tei-", "")}) + "=\"" + attr.value + "\"";
199
+ }
193
200
  }
194
201
  if (el.childNodes.length > 0) {
195
202
  str += ">";
package/test/1259.xml ADDED
@@ -0,0 +1,285 @@
1
+ <?xml version="1.0" encoding="UTF-8"?><?xml-model href="../../schema/CairoUrbanNews.rng" type="application/xml" schematypens="http://relaxng.org/ns/structure/1.0"?><?xml-model href="../../schema/CairoUrbanNews.rng" type="application/xml" schematypens="http://purl.oclc.org/dsdl/schematron"?><?xml-stylesheet type="text/css" href="../../css/oxygen.css"?><TEI xmlns="http://www.tei-c.org/ns/1.0">
2
+ <teiHeader>
3
+ <fileDesc>
4
+ <titleStmt>
5
+ <title>"Digital Cairo - Urbanism News from al-Waqāʾiʿ al-Miṣrīyah - An Ottoman Arabic Digital Humanities
6
+ Project"</title>
7
+ <editor xml:id="eNK">Nour Kanaan</editor>
8
+ <editor xml:id="eAM">Adam Mestyan</editor>
9
+ <editor xml:id="eDY">Danah Younis</editor>
10
+ <editor xml:id="eSG">Sarah Fathallah Gaara</editor>
11
+ <editor xml:id="eAE">Arif Erbil</editor>
12
+ <editor xml:id="eAK">Ahmed Kamal</editor>
13
+ <editor xml:id="eAS">Abram Smith</editor>
14
+ <editor xml:id="eCH">Clara Harms</editor>
15
+ <editor xml:id="eHS">Hüseyin Sağlam</editor>
16
+ <editor xml:id="eAT">Abdulrahman El-Taliawi</editor>
17
+ <editor xml:id="eHL">Hiba Laabadli</editor>
18
+ <editor xml:id="eOE">Othmane Echchabi</editor>
19
+ <editor xml:id="eFA">Fatemah Almahana</editor>
20
+ <editor xml:id="eMZ">Mahmoud Zaki</editor>
21
+ <editor xml:id="eNS">Nehal al-Shamy</editor>
22
+ <editor xml:id="eVJ">Vishal Jammulapati</editor>
23
+ <respStmt>
24
+ <resp>Project leader</resp>
25
+ <name>Hugh Cayless</name>
26
+ </respStmt>
27
+ <respStmt>
28
+ <resp>Project leader</resp>
29
+ <name>Adam Mestyan</name>
30
+ </respStmt>
31
+ <respStmt>
32
+ <resp>Project leader</resp>
33
+ <name>Mercedes Volait</name>
34
+ </respStmt>
35
+ <respStmt>
36
+ <resp>Research Assistant</resp>
37
+ <name>Sarah Fathallah Gaara</name>
38
+ </respStmt>
39
+ <respStmt>
40
+ <resp>Research Assistant</resp>
41
+ <name>Karima Nasr</name>
42
+ </respStmt>
43
+ <respStmt>
44
+ <resp>Research Assistant</resp>
45
+ <name>Rezk Nory</name>
46
+ </respStmt>
47
+ <respStmt>
48
+ <resp>Research Assistant</resp>
49
+ <name>Arif Erbil</name>
50
+ </respStmt>
51
+ <respStmt>
52
+ <resp>Research Assistant</resp>
53
+ <name>Ahmed Kamal</name>
54
+ </respStmt>
55
+ <respStmt>
56
+ <resp>Research Assistant</resp>
57
+ <name>Abram Smith</name>
58
+ </respStmt>
59
+ <respStmt>
60
+ <resp>Research Assistant</resp>
61
+ <name>Clara Harms</name>
62
+ </respStmt>
63
+ <respStmt>
64
+ <resp>Research Assistant</resp>
65
+ <name>Hüseyin Sağlam</name>
66
+ </respStmt>
67
+ <respStmt>
68
+ <resp>Research Assistant</resp>
69
+ <name>Abdulrahman El-Taliawi</name>
70
+ </respStmt>
71
+ <respStmt>
72
+ <resp>Research Assistant</resp>
73
+ <name>Hiba Laabadli</name>
74
+ </respStmt>
75
+ <respStmt>
76
+ <resp>Research Assistant</resp>
77
+ <name>Othmane Echchabi</name>
78
+ </respStmt>
79
+ <respStmt>
80
+ <resp>Research Assistant</resp>
81
+ <name>Fatemah Almahana</name>
82
+ </respStmt>
83
+ <respStmt>
84
+ <resp>Research Assistant</resp>
85
+ <name>Mahmoud Zaki</name>
86
+ </respStmt>
87
+ <respStmt>
88
+ <resp>Research Assistant</resp>
89
+ <name>Nehal al-Shamy</name>
90
+ </respStmt>
91
+ <respStmt>
92
+ <resp>Research Assistant</resp>
93
+ <name>Vishal Jammulapati</name>
94
+ </respStmt>
95
+ <sponsor>
96
+ <orgName>National Endowment for the Humanities</orgName>, <orgName>Institut français
97
+ d’archéologie orientale</orgName> (Ifao, Cairo); <orgName>Franklin Humanities Institute
98
+ and the Office of Global Affairs / Andrew W. Mellon Endowment for Global Studies, Duke
99
+ University</orgName>; <orgName>Duke University Libraries</orgName>; <orgName>Centre
100
+ national de la recherche scientifique</orgName>; <orgName>the Office of the Hungarian
101
+ Cultural Counsellor in Cairo</orgName>. </sponsor>
102
+ </titleStmt>
103
+ <publicationStmt>
104
+ <p>"XMl TEI Edition of Urbanism News in al-Waqāʾiʿ al-Miṣrīyah" in the project "La fabrique
105
+ du Caire moderne, 2018-2021" (Ifao-InVisu-Duke University).</p>
106
+ <p>"Digital Cairo" project sponsored by the National Endowment for the Humanities.</p>
107
+ <p>
108
+ <ref target="https://sites.duke.edu/cairemoderne/">Website</ref>
109
+ </p>
110
+ <p>Project directors: <persName>Adam Mestyan</persName>, <persName>Mercedes
111
+ Volait</persName>, <persName>Hugh Cayless</persName></p>
112
+ </publicationStmt>
113
+ <sourceDesc>
114
+ <p>Al-Waqāʾiʿ al-Miṣrīyah (Egyptian Affairs) newspaper, 1828–1914.</p>
115
+ <p>born digital document</p>
116
+ </sourceDesc>
117
+ </fileDesc>
118
+ <encodingDesc>
119
+ <projectDesc>
120
+ <p>This is a file in the "XMl TEI Edition of Urbanism News in al-Waqāʾiʿ al-Miṣrīyah" in the
121
+ project "La fabrique du Caire moderne, 2018-2021" (Ifao-InVisu-Duke University).</p>
122
+ <p>"Digital Cairo" project sponsored by the National Endowment for the Humanities.</p>
123
+ </projectDesc>
124
+ <editorialDecl>
125
+ <p>Rules of TEI XML MarkUp in This Project</p>
126
+ <p>We use the Arabic script but transliteration into Latin characters follows the Library of
127
+ Congress (LOC) <ref target="https://www.loc.gov/catdir/cpso/romanization/arabic.pdf">Arabic transliteration chart</ref>.</p>
128
+ <p>Each individual article has an individual xml:id number starting with "w1"</p>
129
+ <p>We only use persName, orgName, placeName elements, apart from bibliographical elements
130
+ and notes.</p>
131
+ <p>If the location or organization of responsibility is known from the text, it can be added
132
+ in an attribute to a persName.</p>
133
+ <p>"Mashaykhah" and "thumn" are orgNames and placeNames.</p>
134
+ <p>This project's schema considers Till Grallert's work in his <ref target="https://github.com/OpenArabicPE/OpenArabicPE_ODD">Open Arabic Periodical
135
+ Editions</ref>.</p>
136
+ </editorialDecl>
137
+ <charDecl>
138
+ <char xml:id="qhalf">
139
+ <localProp value="QIRMA FRACTION 1/2" name="name"/>
140
+ <unicodeProp value="1/2" name="Numeric_Value"/>
141
+ <mapping type="similar">𐋢</mapping>
142
+ <figure>
143
+ <graphic url="../../docs/images/qhalf.svg"/>
144
+ </figure>
145
+ </char>
146
+ <char xml:id="qthird">
147
+ <localProp value="QIRMA FRACTION 1/3" name="name"/>
148
+ <unicodeProp value="1/3" name="Numeric_Value"/>
149
+ <figure>
150
+ <graphic url="../../docs/images/qthird.svg"/>
151
+ </figure>
152
+ </char>
153
+ <char xml:id="qfourth">
154
+ <localProp value="QIRMA FRACTION 1/4" name="name"/>
155
+ <unicodeProp value="1/4" name="Numeric_Value"/>
156
+ <figure>
157
+ <graphic url="../../docs/images/qfourth.svg"/>
158
+ </figure>
159
+ </char>
160
+ <char xml:id="qsixth">
161
+ <localProp value="QIRMA FRACTION 1/6" name="name"/>
162
+ <unicodeProp value="1/6" name="Numeric_Value"/>
163
+ <figure>
164
+ <graphic url="../../docs/images/qsixth.svg"/>
165
+ </figure>
166
+ </char>
167
+ <char xml:id="qeighth">
168
+ <localProp value="QIRMA FRACTION 1/8" name="name"/>
169
+ <unicodeProp value="1/8" name="Numeric_Value"/>
170
+ <mapping type="similar">𐋤</mapping>
171
+ <figure>
172
+ <graphic url="../../docs/images/qeighth.svg"/>
173
+ </figure>
174
+ </char>
175
+ <char xml:id="qtwothirds">
176
+ <localProp value="QIRMA FRACTION 2/3" name="name"/>
177
+ <unicodeProp value="2/3" name="Numeric_Value"/>
178
+ <figure>
179
+ <graphic url="../../docs/images/qtwothirds.svg"/>
180
+ </figure>
181
+ </char>
182
+ </charDecl>
183
+ <refsDecl>
184
+ <citeStructure unit="article" match="//body/div" use="@xml:id">
185
+ <citeData property="http://purl.org/dc/terms/title" use="head[1]"/>
186
+ <citeData property="#function" use='split'/>
187
+ </citeStructure>
188
+ </refsDecl>
189
+ </encodingDesc>
190
+ <profileDesc>
191
+ <langUsage>
192
+ <language ident="ar">Arabic</language>
193
+ <language ident="en">English</language>
194
+ <language ident="ar-Latn-x-ala-LC">Arabic transcribed according to ALA-LC</language>
195
+ <language ident="ota">Ottoman</language>
196
+ </langUsage>
197
+
198
+ </profileDesc>
199
+ <revisionDesc status="cleared">
200
+ <listChange>
201
+ <change resp="#eAM" when="2023-06-16" status="cleared"/>
202
+ </listChange>
203
+ </revisionDesc>
204
+ </teiHeader>
205
+
206
+ <text xml:lang="ar">
207
+ <body>
208
+ <div xml:id="WA1259062401" resp="#eNK #eSG">
209
+ <head><date when-custom="1259-04-22">٢٢ ربيع الثاني <choice>
210
+ <sic>١٢٥٨</sic>
211
+ <corr>١٢٥٩</corr>
212
+ </choice></date>
213
+ <date when="1843-05-21">٢١ مايو ١٨٤٣</date>
214
+ <bibl><biblScope unit="issue">نمرة ٦٢٤</biblScope>
215
+ <biblScope unit="page">صفحة ٦</biblScope></bibl></head>
216
+ <head>فوايد مختلفة</head>
217
+ <p>قد تولى <persName role="شيخ طائفة الصعائدة">العلامة السيد احمد القيصاوى الصعيدى شيخا على
218
+ طائفة الصعائدة</persName> عوضا عن المرحوم <persName type=" شيخ-على-طائفة-الصعائدة">الشيخ
219
+ عبد الله القاضى</persName> فى هذا الخصوص بداعى ان الشيخ المذكور صعيدى وشيخ المالكية
220
+ المتولى الان بحيرى وقد جرت العادة انه بعد اتحاف شيخ المذهب <sic>بفرو سمور</sic> من الخديوى
221
+ وبفرو من حضرة شيخ الجامع قبل ذلك ينزل حالا الى <placeName xml:id="place-WA1259062401_01" type="بيت" ref="بيت-حضرة-نقيب-الاشراف">بيت حضرة نقيب الاشراف</placeName> وحضرة شيخ السادات الوفائية
222
+ فيتحف عند كل منهما بفرو سمور وقد حصل ذلك <persName>للشيخ الحبيشى</persName> ثم بعد ذلك
223
+ يطوف ببيوت الاعيان الذين لهم عادة الاتحاف المذكور فيكسوه كل على حسب مقامه وكذلك مشايخ
224
+ الاروقة الكبيرة فلبس شيخ المالكية المذكور زيادة على ذلك صوفا من عند حضرة قاضى الاسلام
225
+ وفروا من حضرة بركة وقته <persName>الشيخ الجوهرى</persName> وفروا من حفيد العلامة القويسنى
226
+ وفرجية جوخ من <persName role="مفتى السادة الحنفية">حضرة الشيخ التميمى مفتى السادة
227
+ الحنفية</persName> وشالا كشميريا من <persName>حضرة مصطفى باشا العروسى</persName> وفرجية
228
+ من عند <persName>الشيخ عبد الفتاح العنانى</persName> وكذلك لبس من عند <persName>السيد حنفى
229
+ مكرم</persName> وغيره من اصحاب العادات وكل من هؤلاء المذكورين اتحف <persName role="شيخ رواق الصعائدة">السيد القيصاوى شيخ رواق الصعائدة</persName>
230
+ <sic>بفرحية</sic> ومن جملتهم <persName>الشيخ محمد الحبيشى</persName> نفسه فقد كساه كما
231
+ كساه غيره واجاز من مدحه من الشعراء.</p>
232
+ </div>
233
+ <div xml:id="WA1259062402" resp="#eNK #eSG" n="RIZQA">
234
+ <head><date when-custom="1259-04-22">٢٢ ربيع الثاني <choice>
235
+ <sic>١٢٥٨</sic>
236
+ <corr>١٢٥٩</corr>
237
+ </choice></date>
238
+ <date when="1843-05-21">٢١ مايو ١٨٤٣</date>
239
+ <bibl><biblScope unit="issue">نمرة ٦٢٤</biblScope>
240
+ <biblScope unit="page">صفحة ٦</biblScope></bibl></head>
241
+ <head>اعلانات</head>
242
+ <p>بيان ما فى الدلالة من العقارات وغيرها</p>
243
+ <p>احد عشردكانا مسكونة فى <placeName xml:id="place-WA1259062402_01" ref="التربيعة">التربيعة</placeName> بلغت فى الدلالة من
244
+ القروش ١١٨٠٠</p>
245
+ <p>تسع دكاكين ب<placeName xml:id="place-WA1259062402_02" ref="العقادين">العقادين البلدى</placeName> بلغت من القروش
246
+ ٥٣٧٠٠</p>
247
+ <p><placeName xml:id="place-WA1259062402_03" type="وكالة" ref="وكالة-فى العقادين-البلدى">وكالة فى العقادين
248
+ البلدى</placeName> فى داخلها دكاكين وحواصل واوض وبيوت وبظهرها خربة بلغت من القروش
249
+ ٢٠٠٠</p>
250
+ <p>دكاكين خمسة ب<placeName xml:id="place-WA1259062402_04" type="خط" ref="خط-الوراقين">خط الوراقين</placeName> بلغت من
251
+ القروش ٧٠٠٠</p>
252
+ <p>اطيان رزقة بلا مال تعلق <persName>عبد الرحمن بيك</persName> ب<placeName xml:id="place-WA1259062402_05" type="ناحية" ref="ناحيه-سيله-فيوم">ناحية سيله فيوم</placeName> جميعها سواد قدرها مائة فدان وبها من
253
+ المهمات ثلاثة اقواس ومحراث واحد ومن المواشى ثور واحد بلغت من القروش ٢٠٠٠</p>
254
+ <p>خمسمائة فدان رزقة بلا مال تعلق البيك المذكور ب<placeName xml:id="place-WA1259062402_06" ref="الفيوم">الفيوم</placeName>
255
+ بها من المهمات محراثان واربعة عشر قوسا ونورج واحد ومن المواشى اربعة اثوار وحمار واحد بلغت
256
+ من القروش ١٠٠٠٠٠</p>
257
+ <p>ثلاثة مساكن تعلق المرحوم <persName>خليل افندى</persName> ووصيه <persName>عارف
258
+ بيك</persName> ب<placeName xml:id="place-WA1259062402_07" type="درب" ref="الدرب-الاحمر">الدرب الاحمر</placeName> فى
259
+ <placeName xml:id="place-WA1259062402_08" ref="التبانه">التبانه</placeName> بلغت فى الدلالة من القروش ٤٠٠٠</p>
260
+ <p>طيان تعلق<persName role="مديرالقليوبية">حسن بيك مدير<placeName xml:id="place-WA1259062402_09" ref="القليوبية">القليوبية</placeName> سابقا</persName> ب<placeName xml:id="place-WA1259062402_10" type="ناحية" ref="ناحية-ميت-العايد">ناحية ميت <choice>
261
+ <sic>العايد</sic>
262
+ <corr>القايد</corr>
263
+ </choice></placeName> ب<placeName xml:id="place-WA1259062402_11" type="اقليم" ref="اقليم-الجيزة">اقليم
264
+ الجيزة</placeName> رزقة بلا مال قطعة واحدة قدرها مائتان واربعة وعشرون فدانا بلغت فى
265
+ الدلالة من القروش ٥٠٠٠٠</p>
266
+ <p>مسكن تعلق المذكور ب<placeName xml:id="place-WA1259062402_12" type="ناحية" ref="ناحية-الجيزة">ناحية الجيزة</placeName>
267
+ بلغ من القروش ٢١٠٠٠ </p>
268
+ <p>اطيان تعلق المذكور ب<placeName xml:id="place-WA1259062402_13" type="ناحية" ref="ناحية-الدقى">ناحية الدقى</placeName> من
269
+ <placeName xml:id="place-WA1259062402_14" type="جهة" ref="جهة-الجيزة">جهة الجيزة</placeName> رزقة بلا مال قدرها <choice>
270
+ <sic>ابعة</sic>
271
+ <corr>اربعة</corr>
272
+ </choice> وعشرون فدانا بلغت من القروش ٣٢٥٠٠ </p>
273
+ <p>منزل ب<placeName xml:id="place-WA1259062402_15" ref="الجيزة">الجيزة</placeName> تعلق المذكور بلغ فى الدلالة ثمانين الف
274
+ قرش</p>
275
+ <p>تسعة دكاكين ب<placeName xml:id="place-WA1259062402_16" type="سوق" ref="سوق الجيزة">سوق الجيزة</placeName> و<placeName xml:id="place-WA1259062402_17" type="طاحونة">طاحونة</placeName> و<placeName xml:id="place-WA1259062402_18" type="فرن">فرن</placeName> و<placeName xml:id="place-WA1259062402_19" type="اصطبل">اصطبل</placeName> كبير بلغت اثنى عشر الف قرش</p>
276
+ <p>الف وستمائة فدان تعلق المذكور رزقة بلا مال ب<placeName xml:id="place-WA1259062402_20" type="ناحية" ref="ناحية-بوش">ناحية
277
+ بوش</placeName> بلغت ثلثمائة الف قرش وخمسة وثلاثين الفا</p>
278
+ <p>منزل ب<placeName xml:id="place-WA1259062402_21" ref="الدرب الاحمر">الدرب الاحمر</placeName> تعلق <persName role="باش جاويش بالديوان الخديوى">اسماعيل اغا باش جاويش ب<orgName type="ديوان" ref="الديوان-الخديوى">الديوان الخديوى</orgName></persName> بلغ فى الدلالة أحدا وثلاثين
279
+ الف قرش وخمسمائة قرش</p>
280
+ <p>منزل ب<placeName xml:id="place-WA1259062402_22" ref="الباطلية">الباطلية</placeName> ب<placeName xml:id="place-WA1259062402_23" type="ناحية" ref="ناحية الازهر">ناحية الازهر</placeName> تعلق <persName>الحاج على الاسكندرانى</persName>
281
+ بلغ من القروش ٦٢٥٠ </p>
282
+ </div>
283
+ </body>
284
+ </text>
285
+ </TEI>
@@ -1,7 +1,8 @@
1
- <html>
1
+ <html lang="en">
2
2
  <head>
3
3
  <meta charset="utf-8">
4
- <link rel="stylesheet" href="CETEIcean.css" charset="utf-8">
4
+ <link rel="stylesheet" href="CETEIcean.css">
5
+ <title>CETEIcean Add Behaviors Test</title>
5
6
  </head>
6
7
  <body>
7
8
  <div id="TEI">
@@ -0,0 +1,112 @@
1
+ <!DOCTYPE html>
2
+ <html lang="en">
3
+ <head>
4
+ <meta charset="UTF-8">
5
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
6
+ <title>Document</title>
7
+ <script src="../dist/CETEI.js"></script>
8
+ <style>
9
+ tei-teiheader * {
10
+ white-space: pre;
11
+ }
12
+ [lang=ar] *{
13
+ direction: rtl;
14
+ font-size: larger;
15
+ text-align: right;
16
+ }
17
+ tei-div, tei-head, tei-p {
18
+ display: block;
19
+ }
20
+ </style>
21
+ </head>
22
+ <body>
23
+ <script>
24
+ const c = new CETEI({omitDefaultBehaviors: true});
25
+ const behaviors = {
26
+ "namespaces": {
27
+ "tei": "http://www.tei-c.org/ns/1.0",
28
+ "teieg": "http://www.tei-c.org/ns/Examples"
29
+ },
30
+ tei: {
31
+ "div": function(elt) {
32
+ elt.setAttribute('contenteditable', 'true');
33
+ },
34
+ },
35
+ "functions": {
36
+ "tag": function(elt, type, name) {
37
+ const c = document.createElement('canvas');
38
+ const ctx = c.getContext('2d');
39
+ ctx.font='16px Courier';
40
+ const start = name ? name : `${elt.getAttribute('data-origname')} ${this.attributes(elt)}`.trim();
41
+ const end = name ? name : elt.getAttribute('data-origname');
42
+ ctx.textBaseline = 'middle';
43
+ const sm = ctx.measureText(start);
44
+ const h = 25;
45
+ if (type == 'start') {
46
+ const w = Math.ceil(sm.width + 10);
47
+ c.setAttribute('width', w);
48
+ c.setAttribute('height', h);
49
+ ctx.beginPath();
50
+ ctx.fillStyle = 'silver';
51
+ ctx.moveTo(3, Math.ceil(h/2));
52
+ ctx.lineTo(8, 1);
53
+ ctx.lineTo(8, h-1);
54
+ ctx.fill();
55
+ ctx.fillRect(8, 1, w-8, h - 2);
56
+ ctx.fillStyle = 'black';
57
+ ctx.font='16px Courier';
58
+ ctx.fillText(start,9,18);
59
+ c.addEventListener('click', function() {
60
+ alert('You clicked on ' + elt.getAttribute('data-origname'));
61
+ });
62
+ }
63
+ if (type == 'end') {
64
+ const m = ctx.measureText(end);
65
+ const w = Math.ceil(m.width + 8);
66
+ c.setAttribute('width', w);
67
+ c.setAttribute('height', h);
68
+ ctx.beginPath();
69
+ ctx.fillStyle = 'silver';
70
+ ctx.fillRect(0, 1, w-8, h - 2);
71
+ ctx.moveTo(w-3, Math.ceil(h/2));
72
+ ctx.lineTo(w-8, 1);
73
+ ctx.lineTo(w-8, h-1);
74
+ ctx.fill();
75
+ ctx.fillStyle = 'black';
76
+ ctx.font='16px Courier';
77
+ //ctx.textBaseline = 'middle';
78
+ ctx.fillText(end,2,18);
79
+ }
80
+ return c;
81
+ },
82
+ "attributes": (elt) => {
83
+ let result = ' ';
84
+ if (elt.hasAttribute('data-origatts')) {
85
+ const attrs = elt.getAttribute('data-origatts').split(' ');
86
+ for (const name of attrs) {
87
+ if (name == 'xmlns') {
88
+ result += `${name}="${elt.getAttribute('data-xmlns')}" `;
89
+ } else {
90
+ result += `${name}="${elt.getAttribute(name.toLowerCase())}" `;
91
+ }
92
+
93
+ }
94
+ }
95
+ return result.trim();
96
+ }
97
+ }
98
+ };
99
+ c.addBehaviors(behaviors);
100
+ c.getHTML5("1259.xml",
101
+ function(data) {
102
+ document.querySelector("div#TEI").appendChild(data);
103
+ },
104
+ function(newElt, elt) {
105
+ newElt.prepend(c.utilities.tag(newElt, 'start'));
106
+ newElt.append(c.utilities.tag(newElt, 'end'));
107
+ }
108
+ );
109
+ </script>
110
+ <div id="TEI"></div>
111
+ </body>
112
+ </html>
@@ -130,7 +130,7 @@ tei-lb:before {
130
130
  content: "\A";
131
131
  }
132
132
  ```
133
- This tells the browser to insert a new-line character (the "\A") before each `<tei-lb>` and to treat it as preformatted text (as you would a block of code, for example). We have to do this because in HTML new lines are normally ignored for formatting purposes. There's more we can do with CSS, but this is a good point to look at where you might use CETEIcean behaviors for formatting instead. HTML has an element equivalent to `<lb/>`, the `<br>` element. What if we just put a `<br>` inside our `<tei-lb>`? We can do that by adding some behaviors. In your index.html, add the following after between the first and second lines of the code in the `<script></script>` tags:
133
+ This tells the browser to insert a new-line character (the "\A") before each `<tei-lb>` and to treat it as preformatted text (as you would a block of code, for example). We have to do this because in HTML new lines are normally ignored for formatting purposes. There's more we can do with CSS, but this is a good point to look at where you might use CETEIcean behaviors for formatting instead. HTML has an element equivalent to `<lb/>`, the `<br>` element. What if we just put a `<br>` inside our `<tei-lb>`? We can do that by adding some behaviors. In your index.html, add the following after the first line of the code in the `<script></script>` tags:
134
134
  ```js
135
135
  let behaviors = {
136
136
  "tei": {
@@ -139,7 +139,20 @@ This tells the browser to insert a new-line character (the "\A") before each `<t
139
139
  };
140
140
  c.addBehaviors(behaviors);
141
141
  ```
142
- What this will do is create a Javascript object and assign it to a variable, `behaviors`, which we then pass to the `CETEI` object we created earlier, using the `addBehaviors` method. Inside that behaviors object, we have a section labeled "tei" (which is the prefix for all of our Custom Elements), and inside that, we define behaviors for elements. When CETEIcean sees a match for an element name, like "lb" (note that it uses the un-prefixed TEI name), it applies what it finds. For "lb", it sees an Array with one element, `<br>`, so it will insert that `<br>` tag before the content of any `<tei-lb>` element it finds. `<tei-lb>` is an empty element anyway, so the final result as seen by the browser will be
142
+ The code should now look like this:
143
+ ```js
144
+ let c = new CETEI();
145
+ let behaviors = {
146
+ "tei": {
147
+ "lb": ["<br>"],
148
+ }
149
+ };
150
+ c.addBehaviors(behaviors);
151
+ c.getHTML5('fpn-washington.xml', function(data) {
152
+ document.getElementsByTagName("body")[0].appendChild(data);
153
+ });
154
+ ```
155
+ This new code will create a Javascript object and assign it to a variable, `behaviors`, which we then pass to the `CETEI` object we created earlier, using the `addBehaviors` method. Inside that behaviors object, we have a section labeled "tei" (which is the prefix for all of our Custom Elements), and inside that, we define behaviors for elements. When CETEIcean sees a match for an element name, like "lb" (note that it uses the un-prefixed TEI name), it applies what it finds. For "lb", it sees an Array with one element, `<br>`, so it will insert that `<br>` tag before the content of any `<tei-lb>` element it finds. `<tei-lb>` is an empty element anyway, so the final result as seen by the browser will be
143
156
  ```html
144
157
  <tei-lb><br></tei-lb>
145
158
  ```