Requires

Provides

DOM.js

Provides DOM-compliant interface to play around with other widgets

License:
Public domain (http://unlicense.org).
Authors:
Yaroslaff Fedin
  1. 25
  2. 26
  3. 27
  4. 28
  5. 29
  6. 30
  7. 31
  8. 32
  9. 33
  10. 34
  11. 35
  12. 36
  13. 37
  14. 38
  15. 39
  16. 40
  17. 41
  18. 42
  19. 43
  20. 44
  21. 45
  22. 46
  23. 47
  24. 48
  25. 49
  26. 50
  27. 51
  28. 52
  29. 53
  30. 54
  31. 55
  32. 56
  33. 57
  34. 58
  35. 59
  36. 60
  37. 61
  38. 62
  39. 63
  40. 64
  41. 65
  42. 66
  43. 67
  44. 68
  45. 69
  46. 70
  47. 71
  48. 72
  49. 73
  50. 74
  51. 75
  52. 76
  53. 77
  54. 78
  55. 79
  56. 80
  57. 81
  58. 82
  59. 83
  60. 84
  61. 85
  62. 86
  63. 87
  64. 88
  65. 89
  66. 90
  67. 91
  68. 92
  69. 93
  70. 94
  71. 95
  72. 96
  73. 97
  74. 98
  75. 99
  76. 100
  77. 101
  78. 102
  79. 103
  80. 104
  81. 105
  82. 106
  83. 107
  84. 108
  85. 109
  86. 110
  87. 111
  88. 112
  89. 113
  90. 114
  91. 115
  92. 116
  93. 117
  94. 118
  95. 119
  96. 120
  97. 121
  98. 122
  99. 123
  100. 124
  101. 125
  102. 126
  103. 127
  104. 128
  105. 129
  106. 130
  107. 131
  108. 132
  109. 133
  110. 134
  111. 135
  112. 136
  113. 137
  114. 138
  115. 139
  116. 140
  117. 141
  118. 142
  119. 143
  120. 144
  121. 145
  122. 146
  123. 147
  124. 148
  125. 149
  126. 150
  127. 151
  128. 152
  129. 153
  130. 154
  131. 155
  132. 156
  133. 157
  134. 158
  135. 159
  136. 160
  137. 161
  138. 162
  139. 163
  140. 164
  141. 165
  142. 166
  143. 167
  144. 168
  145. 169
  146. 170
  147. 171
  148. 172
  149. 173
  150. 174
  151. 175
  152. 176
  153. 177
  154. 178
  155. 179
  156. 180
  157. 181
  158. 182
  159. 183
  160. 184
  161. 185
  162. 186
  163. 187
  164. 188
  165. 189
  166. 190
  167. 191
  168. 192
  169. 193
  170. 194
  171. 195
  172. 196
  173. 197
  174. 198
  175. 199
  176. 200
  177. 201
  178. 202
  179. 203
  180. 204
  181. 205
  182. 206
  183. 207
  184. 208
  185. 209
  186. 210
  187. 211
  188. 212
  189. 213
  190. 214
  191. 215
  192. 216
  193. 217
  194. 218
  195. 219
  196. 220
  197. 221
  198. 222
  199. 223
  200. 224
  201. 225
  202. 226
  203. 227
  204. 228
  205. 229
  206. 230
  207. 231
  208. 232
  209. 233
  210. 234
  211. 235
  212. 236
  213. 237
  214. 238
  215. 239
  216. 240
  217. 241
  218. 242
  219. 243
  220. 244
  221. 245
  222. 246
  223. 247
  224. 248
  225. 249
  226. 250
  227. 251
  228. 252
  229. 253
  230. 254
  231. 255
  232. 256
  233. 257
  234. 258
  235. 259
  236. 260
  237. 261
  238. 262
  239. 263
  240. 264
  241. 265
  242. 266
  243. 267
  244. 268
  245. 269
  246. 270
  247. 271
  248. 272
  249. 273
  250. 274
  251. 275
  252. 276
  253. 277
  254. 278
  255. 279
  256. 280
  257. 281
  258. 282
  259. 283
  260. 284
  261. 285
  262. 286
  263. 287
  264. 288
  265. 289
  266. 290
  267. 291
  268. 292
  269. 293
  270. 294
  271. 295
  272. 296
  273. 297
  274. 298
  275. 299
  276. 300
  277. 301
  278. 302
  279. 303
  280. 304
  281. 305
  282. 306
;(function() { var inserters = { before: function(context, element){ var parent = element.parentNode; if (parent) return parent.insertBefore(context, element); }, after: function(context, element){ var parent = element.parentNode; if (parent) return parent.insertBefore(context, element.nextSibling); }, bottom: function(context, element){ return element.appendChild(context); }, top: function(context, element){ return element.insertBefore(context, element.firstChild); } }; LSD.Module.DOM = new Class({ options: { nodeType: 1, events: { _dom: { element: { 'dispose': 'dispose' } } } }, initialize: function() { if (!this.childNodes) this.childNodes = []; this.nodeType = this.options.nodeType this.parentNode = this.nextSibling = this.previousSibling = null; this.fireEvent('initialize') this.parent.apply(this, arguments); this.nodeName = this.tagName = this.options.tag; }, toElement: function(){ if (!this.built) this.build(); return this.element; }, build: function() { var options = this.options, attrs = Object.append({}, options.element); var tag = attrs.tag || options.tag; delete attrs.tag; if (!this.element) this.element = new Element(tag, attrs); else var element = this.element.set(attrs); var classes = new FastArray; if (options.tag != tag) classes.push('lsd', options.tag || this.tagName); if (options.id) classes.push('id-' + options.id); classes.concat(this.classes); this.element.store('widget', this); if (Object.getLength(classes)) this.element.className = classes.join(' '); if (this.attributes) for (var name in this.attributes) if (name != 'width' && name != 'height') { var value = this.attributes[name]; if (!element || element[name] != value) { this.element.setAttribute(name, value); } } if (this.style) for (var property in this.style.element) this.element.setStyle(property, this.style.element[property]); this.element.fireEvent('build', [this, this.element]); }, getElements: function(selector) { return Slick.search(this, selector) }, getElement: function(selector) { return Slick.find(this, selector) }, contains: function(element) { while (element = element.parentNode) if (element == this) return true; return false; }, getChildren: function() { return this.childNodes; }, getRoot: function() { var widget = this; while (widget.parentNode) widget = widget.parentNode; return widget; }, setParent: function(widget){ if ('localName' in widget) widget = Element.get(widget, 'widget'); this.parentNode = widget; this.fireEvent('setParent', [widget, widget.document]) var siblings = widget.childNodes; var length = siblings.length; if (length == 1) widget.firstChild = this; widget.lastChild = this; var previous = siblings[length - 2]; if (previous) { previous.nextSibling = this; this.previousSibling = previous; } }, unsetParent: function(widget) { var parent = this.parentNode; if (parent.firstChild == this) delete parent.firstChild; if (parent.lastChild == this) delete parent.lastChild; delete this.parentNode; }, appendChild: function(widget, adoption) { if (!adoption && this.canAppendChild && !this.canAppendChild(widget)) { if (widget.parentNode) widget.dispose(); else if (widget.element.parentNode) widget.element.dispose(); return false; } if (widget.id) this[widget.id] = widget; this.childNodes.push(widget); widget.setParent(this); if (!widget.quiet && (adoption !== false) && this.toElement()) (adoption || function() { this.element.appendChild(document.id(widget)); }).apply(this, arguments); delete widget.quiet; this.fireEvent('adopt', [widget]); widget.walk(function(node) { this.dispatchEvent('nodeInserted', node); }.bind(this)); return true; }, removeChild: function(widget) { widget.unsetParent(this); widget.walk(function(node) { this.dispatchEvent('nodeRemoved', node); node.fireEvent('dispose') }.bind(this)); this.childNodes.erase(widget); }, insertBefore: function(insertion, element) { return this.appendChild(insertion, function() { element.parentNode.insertBefore(document.id(insertion), document.id(element)) }); }, grab: function(el, where){ inserters[where || 'bottom'](document.id(el, true), this); return this; }, extractDocument: function(widget) { var element = ('localName' in widget) ? widget : widget.element; var isDocument = widget.documentElement || (instanceOf(widget, LSD.Document)); var parent = this.parentNode; if (isDocument // if document || (parent && parent.dominjected) //already injected widget || (widget.ownerDocument && (widget.ownerDocument.body == widget)) //body element || element.offsetParent) { //element in dom (costy check) return (parent && parent.document) || (isDocument ? widget : LSD.Module.DOM.findDocument(widget)); } }, setDocument: function(document) { return this.walk(function(child) { child.ownerDocument = child.document = document; child.fireEvent('dominject', [child.element.parentNode, document]); child.dominjected = true; }); }, inject: function(widget, where, quiet) { var isElement = 'localName' in widget; if (isElement) { var instance = Element.retrieve(widget, 'widget'); if (instance) { widget = instance; isElement = false; } } this.quiet = quiet || (widget.documentElement && this.element && this.element.parentNode); if (where === false) widget.appendChild(this, false) else if (!inserters[where || 'bottom'](isElement ? this.toElement() : this, widget) && !quiet) return false; if (quiet !== true || widget.document) { var document = widget.document || (this.documentElement ? this : this.extractDocument(widget)); if (document) this.setDocument(document); } this.fireEvent('inject', this.parentNode); return true; }, onDOMInject: function(callback) { if (this.document) callback.call(this, document.id(this.document)) else this.addEvent('dominject', callback.bind(this)) }, destroy: function() { this.dispose(); }, dispose: function(element) { var parent = this.parentNode; if (!parent) return; parent.removeChild(this); this.fireEvent('dispose', parent); if (!element) this.parent.apply(this, arguments); }, dispatchEvent: function(type, args){ var node = this; type = type.replace(/^on([A-Z])/, function(match, letter) { return letter.toLowerCase(); }); while (node) { var events = node.$events; if (events && events[type]) events[type].each(function(fn){ return fn[args.push ? 'apply' : 'call'](node, args); }, node); node = node.parentNode; } return this; }, walk: function(callback) { var children = this.childNodes, length = children.length; callback(this); for (var i = 0; i < length; i++) callback(children[i]) }, collect: function(callback) { var result = []; this.walk(function(child) { if (!callback || callback(child)) result.push(child); }); return result; } }); LSD.Module.DOM.findDocument = function(target) { if (target.documentElement) return target; if (target.document) return target.document; if (!target.localName) return; var body = target.ownerDocument.body; var document = (target != body) && Element.retrieve(body, 'widget'); while (!document && (target = target.parentNode)) { var widget = Element.retrieve(target, 'widget') if (widget) document = (widget instanceof LSD.Document) ? widget : widget.document; } return document; } Element.Events.ready = { onAdd: function(fn) { var widget = this.retrieve('widget'); if (widget) { fn.call(this, widget) } else { this.addEvent('build', function(widget) { fn.call(this, widget); }.bind(this)); } } }; Element.Events.contentready = { onAdd: function(fn) { fn.call(this, this) this.addEvent('update', fn) } }; })();