1 |
|
2 |
|
3 |
|
4 | USE_SPAN_INSTEAD_OF_TEXT_NODES = false
|
5 | try
|
6 | testTxtNode = document.createTextNode('')
|
7 | testTxtNode.testProperty = ''
|
8 | catch Error
|
9 | USE_SPAN_INSTEAD_OF_TEXT_NODES = true
|
10 |
|
11 | K = window.K
|
12 |
|
13 | class K.NateHtmlDom
|
14 | @ON_CLICK_EVENT_BLOCKER: () ->
|
15 | event = arguments[0] || window.event
|
16 | rv = (event.button != 0)
|
17 | event.returnValue = rv
|
18 | return rv
|
19 |
|
20 | constructor: (parentOrElem) ->
|
21 | @children = []
|
22 | @nateParent = null
|
23 | @elem = null
|
24 |
|
25 | if parentOrElem?
|
26 | if parentOrElem instanceof K.NateHtmlDom
|
27 | @nateParent = parentOrElem
|
28 | throw 'Nate parent is not properly handled in constructor yet !'
|
29 | else if K.Elem.isElem(parentOrElem) or K.Elem.isText(parentOrElem)
|
30 | if parentOrElem.nate?
|
31 | throw 'Cannot create 2nd Nate object for same elem! The element you provided as elem for Nate is already a elem for different nate object'
|
32 | else
|
33 |
|
34 | @attachNateToElem(parentOrElem)
|
35 |
|
36 | if parentOrElem.parentNode? and parentOrElem.parentNode.nate?
|
37 | parentOrElem.parentNode.nate.addNateChild @
|
38 | else
|
39 | throw 'parentOrElem should be Nate object or html-element'
|
40 | else
|
41 | throw 'parentOrElem should be Nate object or html-element - cannot be null'
|
42 |
|
43 | deleteAllChildren: () ->
|
44 |
|
45 | while @children.length > 0
|
46 | @children[0].delete()
|
47 |
|
48 | delete: () ->
|
49 |
|
50 | if @nateParent?
|
51 | @nateParent.removeNateChild(@)
|
52 | else
|
53 | @elem.style.backgroundColor = '#f00000'
|
54 | throw 'Removal from non-nates is NOT supported. You tried to remove [elem:' + @elem + ']'
|
55 |
|
56 | addNateChild: (nateChild) ->
|
57 | if nateChild.nateParent?
|
58 | throw 'Moving nate-child between parents not yet supported.'
|
59 |
|
60 | nateChild.nateParent = @
|
61 | @children.push(nateChild)
|
62 | if @elem? and nateChild.elem? and (nateChild.elem.parentNode isnt @elem)
|
63 | @elem.appendChild(nateChild.elem)
|
64 |
|
65 | removeNateChild: (nateChild) ->
|
66 | if nateChild.nateParent != @
|
67 | throw 'Can\'t remove nateChild from me, as the child claims his parent is another object.'
|
68 |
|
69 | K.Array.removeAll(@children, nateChild)
|
70 | if @elem? and nateChild.elem
|
71 | try
|
72 | @elem.removeChild(nateChild.elem)
|
73 | catch err
|
74 | console.log 'Error during removeChild parent is:', @elem, 'child is:', nateChild.elem
|
75 | nateChild.nateParent = null
|
76 |
|
77 | newNate: (elem = null) ->
|
78 | return new K.NateHtmlDom(elem)
|
79 |
|
80 | newChildFromElement: (elem, text) ->
|
81 | newNate = @newNate(elem)
|
82 | @addNateChild(newNate)
|
83 | if text?
|
84 | newNate.set('innerHTML', text)
|
85 | return newNate
|
86 |
|
87 | newTextNode: (text = '') ->
|
88 | if USE_SPAN_INSTEAD_OF_TEXT_NODES
|
89 | return @newSpan(text)
|
90 | else
|
91 | textNode = document.createTextNode(text)
|
92 | return @newChildFromElement(textNode)
|
93 |
|
94 | newTxt: (theTxt) ->
|
95 | return @newTextNode(theTxt)
|
96 |
|
97 | newSpan: (text = null) ->
|
98 | span = document.createElement('span')
|
99 | return @newChildFromElement(span, text)
|
100 |
|
101 | newDiv: (text = null) ->
|
102 | div = document.createElement('div')
|
103 | return @newChildFromElement(div, text)
|
104 |
|
105 | newA: (text = null) ->
|
106 | a = document.createElement('a')
|
107 | return @newChildFromElement(a, text)
|
108 |
|
109 | newB: (text = null) ->
|
110 | a = document.createElement('b')
|
111 | return @newChildFromElement(a, text)
|
112 |
|
113 | newH1: (text = null) ->
|
114 | a = document.createElement('h1')
|
115 | return @newChildFromElement(a, text)
|
116 |
|
117 | newH2: (text = null) ->
|
118 | a = document.createElement('h2')
|
119 | return @newChildFromElement(a, text)
|
120 |
|
121 | newH3: (text = null) ->
|
122 | a = document.createElement('h3')
|
123 | return @newChildFromElement(a, text)
|
124 |
|
125 | newImg: (text = null) ->
|
126 | a = document.createElement('img')
|
127 | return @newChildFromElement(a, text)
|
128 |
|
129 | newLabel: (text = null) ->
|
130 | a = document.createElement('label')
|
131 | return @newChildFromElement(a, text)
|
132 |
|
133 | newP: (text = null) ->
|
134 | a = document.createElement('p')
|
135 | return @newChildFromElement(a, text)
|
136 |
|
137 | newUl: (text = null) ->
|
138 | a = document.createElement('ul')
|
139 | return @newChildFromElement(a, text)
|
140 |
|
141 | newLi: (text = null) ->
|
142 | a = document.createElement('Li')
|
143 | return @newChildFromElement(a, text)
|
144 |
|
145 |
|
146 |
|
147 |
|
148 | newTable: (text = null) ->
|
149 | a = document.createElement('table')
|
150 | return @newChildFromElement(a, text)
|
151 |
|
152 | newTBody: (text = null) ->
|
153 | a = document.createElement('tbody')
|
154 | return @newChildFromElement(a, text)
|
155 |
|
156 | newTr: (text = null) ->
|
157 | a = document.createElement('tr')
|
158 | return @newChildFromElement(a, text)
|
159 |
|
160 | newTd: (text = null) ->
|
161 | a = document.createElement('td')
|
162 | return @newChildFromElement(a, text)
|
163 |
|
164 | newTh: (text = null) ->
|
165 | a = document.createElement('th')
|
166 | return @newChildFromElement(a, text)
|
167 |
|
168 |
|
169 |
|
170 |
|
171 | newTextArea: () ->
|
172 | textarea = document.createElement('textarea')
|
173 | return @newChildFromElement(textarea)
|
174 |
|
175 | newOption: (text = null) ->
|
176 | option = document.createElement('option')
|
177 | return @newChildFromElement(option, text)
|
178 |
|
179 | newSelect: () ->
|
180 | return @newInputSelect()
|
181 |
|
182 | newInputCheckbox: () ->
|
183 | input = document.createElement('input')
|
184 | input.type = "checkbox"
|
185 | return @newChildFromElement(input)
|
186 |
|
187 | newInputText: () ->
|
188 | input = document.createElement('input')
|
189 | input.type = "text"
|
190 | return @newChildFromElement(input)
|
191 |
|
192 | newInputPassword: () ->
|
193 | input = document.createElement('input')
|
194 | input.type = "password"
|
195 | return @newChildFromElement(input)
|
196 |
|
197 | newInputRadio: () ->
|
198 | input = document.createElement('input')
|
199 | input.type = "radio"
|
200 | return @newChildFromElement(input)
|
201 |
|
202 | newInputSelect: () ->
|
203 | input = document.createElement('select')
|
204 | return @newChildFromElement(input)
|
205 |
|
206 |
|
207 |
|
208 |
|
209 | newCanvas: (text = null) ->
|
210 | a = document.createElement('canvas')
|
211 | return @newChildFromElement(a, text)
|
212 |
|
213 | newSvg: () ->
|
214 | a = document.createElementNS('http://www.w3.org/2000/svg', 'svg')
|
215 | return @newChildFromElement(a)
|
216 |
|
217 |
|
218 |
|
219 |
|
220 | attachNateToElem: (elem) ->
|
221 |
|
222 | if elem.nate?
|
223 | throw 'Provided elem already has Nate object'
|
224 |
|
225 |
|
226 | if @elem?
|
227 | throw 'This nate object is already attached to element.'
|
228 |
|
229 |
|
230 | @elem = elem
|
231 | @elem.nate = @
|
232 | for child in @children
|
233 | throw 'This needs to be updated...'
|
234 | @elem.appendChild(child)
|
235 |
|
236 | getElem: () ->
|
237 | return @elem
|
238 |
|
239 | get$: () ->
|
240 | return $(@elem)
|
241 |
|
242 | setText: (txt) ->
|
243 | @set('innerHTML', txt)
|
244 | return @
|
245 |
|
246 | setOnClickEventBlocker: () ->
|
247 | @set('onclick', K.NateHtmlDom.ON_CLICK_EVENT_BLOCKER)
|
248 | return @
|
249 |
|
250 | set: (param, value) ->
|
251 | switch param
|
252 | when 'rect'
|
253 | value.applyToHtmlElement(@elem)
|
254 | when 'checked', 'href', 'id', 'innerHTML', 'value', \
|
255 | 'selected', 'onclick', 'src', 'rowSpan', 'colSpan'
|
256 | K.updateProperty(@elem, param, value)
|
257 | when 'for'
|
258 | K.updateProperty(@elem, 'htmlFor', value)
|
259 | when 'style'
|
260 | K.updateProperty(@elem.style, 'cssText', value)
|
261 | when 'cssText', 'cursor', \
|
262 | 'display', 'float', \
|
263 | 'height', 'width', 'left', 'top', 'right', 'bottom',\
|
264 | 'margin', 'padding', \
|
265 | 'overflow', 'overflowX', 'overflowY', \
|
266 | 'position', 'visibility', 'zIndex', \
|
267 | 'textAlign', 'verticalAlign', \
|
268 | 'backgroundColor', 'color', \
|
269 | 'border', 'borderCollapse', \
|
270 | 'font', 'fontWeight'
|
271 | K.updateProperty(@elem.style, param, value)
|
272 | when 'on'
|
273 |
|
274 | if value
|
275 | @set 'display', 'block'
|
276 | else
|
277 | @set 'display', 'none'
|
278 | when 'class'
|
279 | K.updateProperty(@elem, 'className', value)
|
280 |
|
281 | when 'cols', 'name', 'rows', 'wrap'
|
282 | @elem.setAttribute(param, value)
|
283 | else
|
284 | throw 'No handling for given property implemented: ' + param
|
285 | return @
|
286 |
|
287 | setData: (key, value) ->
|
288 | @elem.setAttribute('data-' + key, value)
|
289 | return @
|
290 |
|
291 | _decodeHtmlEntitiesToPlainText: (html) ->
|
292 |
|
293 |
|
294 |
|
295 | tempDivElement = document.createElement('div')
|
296 | tempDivElement.innerHTML = html
|
297 |
|
298 | if tempDivElement.childNodes.length is 0
|
299 | rv = ""
|
300 | else
|
301 | rv = tempDivElement.childNodes[0].nodeValue
|
302 | return rv
|
303 |
|
304 | setTitle: (title) ->
|
305 |
|
306 |
|
307 |
|
308 | document.title = @_decodeHtmlEntitiesToPlainText(title)
|