UNPKG

8.33 kBJavaScriptView Raw
1const K = window.K;
2
3// -----------------------------------------------------------------------------
4// Prototypes
5// -----------------------------------------------------------------------------
6
7K.NateHtmlDomProto = Object.assign({}, K.NateAbstractDomProto, {
8 commonAttributeSetter(nNode, key, value) {
9 nNode.elem.setAttribute(key, value)
10 },
11
12 commonPropertySetter(nNode, key, value) {
13 K.updateProperty(nNode.elem, key, value)
14 },
15
16 commonStyleAttributeSetter(nNode, key, value) {
17 K.updateProperty(nNode.elem.style, key, value)
18 },
19
20 commonCreateHtmlTag(tagName, params)
21 {
22 const newHtmlElem = document.createElement(tagName)
23 return this.newChildFromElement(newHtmlElem, params);
24 },
25
26 // TODO: Static.
27 ON_CLICK_EVENT_BLOCKER()
28 {
29 let rv = null;
30
31 event = arguments[0] || window.event;
32
33 if (event.shiftKey || event.ctrlKey)
34 {
35 // (SHIFT + click) or (CTRL + click) - don't block.
36 rv = true;
37 }
38 else
39 {
40 rv = (event.button != 0)
41
42 event.returnValue = rv
43 }
44
45 return rv;
46 },
47
48 init(parentOrElem, namespace)
49 {
50 K.NateAbstractDomProto.init.call(this, parentOrElem, namespace);
51
52 // Check the type of parentOrElem.
53 let isInstanceOfNate = parentOrElem && parentOrElem._getDefaultNamespace
54 let isInstanceOfHtmlDom = (parentOrElem instanceof K.NateHtmlDom);
55 let isInstanceOfSvgDom = false;
56
57 if (K.Object.isNotNull(K.NateSvgDom))
58 {
59 // K.NateSvgDom may be not included in the build
60 isInstanceOfSvgDom = (parentOrElem instanceof K.NateSvgDom)
61 }
62
63 const isElemOrText = K.Elem.isElem(parentOrElem) || K.Elem.isText(parentOrElem);
64
65 if ((!isInstanceOfNate) && (!isInstanceOfHtmlDom) && (!isElemOrText) && (!isInstanceOfSvgDom))
66 {
67 throw('parentOrElem should be Nate object or html-element');
68 }
69 },
70
71 _getDefaultNamespace() {
72 // Default namespace for all NateHtmlDom elements used when there is no
73 // parent item.
74 return K.nateHtmlDomNamespace
75 },
76
77 newChildFromElement(elem, params)
78 {
79 newNate = this.getNamespace().createNate(this);
80 newNate.attachElemToNate(elem);
81
82 if (params) {
83 newNate.setFromMap(params)
84 }
85
86 return newNate;
87 },
88
89 newTextNode(text = '')
90 {
91 const textNode = document.createTextNode(text);
92
93 return this.newChildFromElement(textNode);
94 },
95
96 newTxt(text)
97 {
98 return this.newTextNode(text);
99 },
100
101 br()
102 {
103 // TODO: br vs newBr()
104 return this.newBr();
105 },
106
107 newScriptJsonLd(dataObj = null)
108 {
109 const a = document.createElement('script');
110
111 a.type = 'type=application/ld+json';
112
113 return this.newChildFromElement(a, {
114 innerJSON: dataObj
115 })
116 },
117
118 //
119 // SVG, canvas etc.
120 //
121
122 newSvgNate(params)
123 {
124 const svgElem = document.createElementNS('http://www.w3.org/2000/svg', 'svg');
125 const svgNate = K.NateSvgDom(svgElem, K.BSC.NateAbstractProto.USE_DEFAULT_NAMESPACE);
126
127 this.addNateChild(svgNate);
128 svgNate.setFromMap(params);
129
130 return svgNate;
131 },
132
133 //
134 // nate methods
135 //
136
137 get$()
138 {
139 // Don't call it anymore. We removed jQuery.
140 K.Error.reportNotImplemented('K.NateHtmlDom::get$');
141
142 // OLD IMPLEMENTATION
143 //this._confirmIsNotDeleted()
144 //return $(this.elem)
145 },
146
147 setText(txt)
148 {
149 this.set('innerHTML', txt);
150 return this;
151 },
152
153 setOnClickEventBlocker()
154 {
155 this.set('onclick', K.NateHtmlDomProto.ON_CLICK_EVENT_BLOCKER);
156
157 return this;
158 },
159
160 set(param, value)
161 {
162 this._confirmIsNotDeleted();
163
164 const fct = this.namespace.getSetter(param)
165
166 if (fct) {
167 fct(this, param, value)
168 } else {
169 throw('No handling for given property implemented: ' + param);
170 }
171
172 return this;
173 },
174
175 setData(key, value)
176 {
177 this._confirmIsNotDeleted();
178 this._validateDataKey(key);
179
180 this.elem.setAttribute('data-' + key, value);
181
182 return this;
183 },
184
185 _decodeHtmlEntitiesToPlainText(html)
186 {
187 // Example:
188 // input : Median & average
189 // output : Median & average
190
191 let rv = '';
192
193 const tempDivElement = document.createElement('div');
194
195 tempDivElement.innerHTML = html;
196
197 if (tempDivElement.childNodes.length > 0)
198 {
199 rv = tempDivElement.childNodes[0].nodeValue;
200 }
201
202 return rv;
203 }
204});
205
206K.NateHtmlDomHeadProto = Object.assign({}, K.NateHtmlDomProto,
207{
208 setTitle(title)
209 {
210 // We decode title to plain text, because document.title works in different way
211 // than static <title> tag. Browser's side title needs plain, decoded text
212 // instead of html.
213 document.title = this._decodeHtmlEntitiesToPlainText(title);
214 },
215
216 setDocumentTitle(title)
217 {
218 this.setTitle(title);
219 }
220});
221
222// -----------------------------------------------------------------------------
223// HTML namespace
224// -----------------------------------------------------------------------------
225
226K.nateHtmlDomNamespace =
227 K.BSC.nateNullNamespace.createExtension('HtmlDom', {nateProto: K.NateHtmlDomProto})
228
229// -----------------------------------------------------------------------------
230// HTML setters
231// -----------------------------------------------------------------------------
232
233// Common attribute setter.
234K.BSC.nateCommonHtmlProperties.forEach((key) => {
235 K.nateHtmlDomNamespace.addSetter(key, K.NateHtmlDomProto.commonPropertySetter)
236})
237
238// Common style attribute setter.
239K.BSC.nateCommonStyleAttributes.forEach((key) => {
240 K.nateHtmlDomNamespace.addSetter(key, K.NateHtmlDomProto.commonStyleAttributeSetter)
241})
242
243// Common HTML attributes.
244K.BSC.nateCommonHtmlAttributes.forEach((key) => {
245 K.nateHtmlDomNamespace.addSetter(key, K.NateHtmlDomProto.commonAttributeSetter)
246})
247
248K.nateHtmlDomNamespace.addSetter('style', (nNode, key, value) => {
249 nNode.set('cssText', value)
250})
251
252K.nateHtmlDomNamespace.addSetter('rect', (nNode, key, value) => {
253 value.applyToHtmlElement(nNode.elem);
254})
255
256K.nateHtmlDomNamespace.addSetter('on', (nNode, key, value) => {
257 // TODO: handling of other things than 'block'
258 if (value)
259 {
260 nNode.set('display', 'block');
261 }
262 else
263 {
264 nNode.set('display', 'none');
265 }
266})
267
268// Special handlers to set inner content directly from strings (i.e. skip
269// newXxx() API).
270K.nateHtmlDomNamespace.addSetter('textContent', K.NateAbstractDomProto.commonInnerContentSetter)
271K.nateHtmlDomNamespace.addSetter('innerHTML' , K.NateAbstractDomProto.commonInnerContentSetter)
272K.nateHtmlDomNamespace.addSetter('innerText' , K.NateAbstractDomProto.commonInnerContentSetter)
273
274// -----------------------------------------------------------------------------
275// HTML tags
276// -----------------------------------------------------------------------------
277
278K.BSC.nateCommonHtmlOpenCloseTags.forEach((key) => {
279 K.nateHtmlDomNamespace.addCreateFunction(key, K.NateHtmlDomProto.commonCreateHtmlTag);
280})
281
282K.BSC.nateCommonHtmlOpenCloseAtOnceTags.forEach((key) => {
283 K.nateHtmlDomNamespace.addCreateFunction(key, K.NateHtmlDomProto.commonCreateHtmlTag);
284})
285
286K.BSC.nateCommonHtmlInputTypes.forEach((inputType) => {
287 const key = 'input' + inputType.charAt(0).toUpperCase() + inputType.substr(1);
288
289 K.nateHtmlDomNamespace.addCreateFunction(key, function(tagName, params = {}) {
290 const newHtmlElem = document.createElement('input');
291 newHtmlElem.type = inputType;
292 return this.newChildFromElement(newHtmlElem);
293 });
294})
295
296K.nateHtmlDomNamespace.addCreateFunction('svg', function(tagName, params) {
297 const a = document.createElementNS('http://www.w3.org/2000/svg', 'svg');
298 return this.newChildFromElement(a, params);
299});
300
301// -----------------------------------------------------------------------------
302// Factory functions
303// -----------------------------------------------------------------------------
304
305K.NateHtmlDom = K.nateHtmlDomNamespace.createFactoryFunction(K.NateHtmlDomProto);
306K.NateHtmlDomHead = K.nateHtmlDomNamespace.createFactoryFunction(K.NateHtmlDomHeadProto);