browsercms 3.1.4 → 3.1.5

Sign up to get free protection for your applications and to get access to all the features.
Files changed (164) hide show
  1. data/app/controllers/cms/content_block_controller.rb +2 -2
  2. data/app/controllers/cms/section_nodes_controller.rb +6 -1
  3. data/app/controllers/cms/sections_controller.rb +1 -1
  4. data/app/helpers/cms/application_helper.rb +1 -1
  5. data/app/helpers/cms/content_block_helper.rb +27 -0
  6. data/app/helpers/cms/section_nodes_helper.rb +43 -5
  7. data/app/models/abstract_file_block.rb +16 -1
  8. data/app/models/attachment.rb +17 -35
  9. data/app/models/file_block.rb +0 -12
  10. data/app/models/image_block.rb +0 -12
  11. data/app/models/link.rb +4 -21
  12. data/app/models/page.rb +31 -34
  13. data/app/models/section.rb +82 -44
  14. data/app/models/section_node.rb +39 -24
  15. data/app/models/user.rb +5 -0
  16. data/app/views/cms/blocks/index.html.erb +4 -4
  17. data/app/views/cms/file_blocks/_form.html.erb +1 -1
  18. data/app/views/cms/image_blocks/_form.html.erb +1 -1
  19. data/app/views/cms/section_nodes/_link.html.erb +6 -3
  20. data/app/views/cms/section_nodes/_node.html.erb +11 -1
  21. data/app/views/cms/section_nodes/_page.html.erb +13 -7
  22. data/app/views/cms/section_nodes/_section.html.erb +24 -8
  23. data/app/views/cms/section_nodes/index.html.erb +28 -16
  24. data/app/views/layouts/templates/default.html.erb +17 -0
  25. data/browsercms.gemspec +28 -1413
  26. data/db/migrate/20120117144039_browsercms315.rb +94 -0
  27. data/db/migrate/{20081114172307_load_seed_data.rb → 20121114172307_load_seeds.rb} +8 -1
  28. data/lib/acts_as_list.rb +1 -1
  29. data/lib/browsercms.rb +2 -0
  30. data/lib/cms/addressable.rb +83 -0
  31. data/lib/cms/behaviors/attaching.rb +44 -24
  32. data/lib/cms/behaviors/connecting.rb +2 -1
  33. data/lib/cms/behaviors/publishing.rb +12 -3
  34. data/lib/cms/behaviors/versioning.rb +83 -53
  35. data/lib/cms/content_rendering_support.rb +3 -3
  36. data/lib/cms/error_pages.rb +8 -0
  37. data/lib/cms/init.rb +5 -3
  38. data/lib/cms/version.rb +1 -1
  39. data/templates/blank.rb +2 -0
  40. data/templates/demo.rb +2 -0
  41. data/templates/module.rb +2 -0
  42. data/test/custom_assertions.rb +7 -1
  43. data/test/factories.rb +3 -1
  44. data/test/factories/sitemap_factories.rb +28 -0
  45. data/test/fixtures/connectors.yml +97 -0
  46. data/test/fixtures/content_type_groups.yml +13 -0
  47. data/test/fixtures/content_types.yml +50 -0
  48. data/test/fixtures/dynamic_view_versions.yml +26 -0
  49. data/test/fixtures/dynamic_views.yml +26 -0
  50. data/test/fixtures/group_permissions.yml +16 -0
  51. data/test/fixtures/group_sections.yml +31 -0
  52. data/test/fixtures/group_type_permissions.yml +11 -0
  53. data/test/fixtures/group_types.yml +25 -0
  54. data/test/fixtures/groups.yml +25 -0
  55. data/test/fixtures/html_block_versions.yml +67 -0
  56. data/test/fixtures/html_blocks.yml +63 -0
  57. data/test/fixtures/page_versions.yml +265 -0
  58. data/test/fixtures/pages.yml +85 -0
  59. data/test/fixtures/permissions.yml +28 -0
  60. data/test/fixtures/section_nodes.yml +46 -0
  61. data/test/fixtures/sections.yml +19 -0
  62. data/test/fixtures/sites.yml +9 -0
  63. data/test/fixtures/user_group_memberships.yml +11 -0
  64. data/test/fixtures/users.yml +15 -0
  65. data/test/functional/cms/content_controller_test.rb +6 -1
  66. data/test/functional/cms/file_blocks_controller_test.rb +1 -0
  67. data/test/functional/cms/html_blocks_controller_test.rb +1 -0
  68. data/test/functional/cms/image_blocks_controller_test.rb +39 -32
  69. data/test/functional/cms/section_nodes_controller_test.rb +48 -20
  70. data/test/functional/cms/sections_controller_test.rb +3 -1
  71. data/test/functional/tests/pretend_controller_test.rb +6 -3
  72. data/test/integration/cms/ckeditor_test.rb +5 -2
  73. data/test/integration/sitemap_performance_test.rb +26 -0
  74. data/test/selenium-core/Blank.html +7 -0
  75. data/test/selenium-core/InjectedRemoteRunner.html +8 -0
  76. data/test/selenium-core/RemoteRunner.html +110 -0
  77. data/test/selenium-core/SeleniumLog.html +109 -0
  78. data/test/selenium-core/TestPrompt.html +145 -0
  79. data/test/selenium-core/TestRunner-splash.html +55 -0
  80. data/test/selenium-core/TestRunner.hta +176 -0
  81. data/test/selenium-core/TestRunner.html +176 -0
  82. data/test/selenium-core/domviewer/butmin.gif +0 -0
  83. data/test/selenium-core/domviewer/butplus.gif +0 -0
  84. data/test/selenium-core/domviewer/domviewer.css +298 -0
  85. data/test/selenium-core/domviewer/domviewer.html +16 -0
  86. data/test/selenium-core/domviewer/selenium-domviewer.js +205 -0
  87. data/test/selenium-core/icons/all.png +0 -0
  88. data/test/selenium-core/icons/continue.png +0 -0
  89. data/test/selenium-core/icons/continue_disabled.png +0 -0
  90. data/test/selenium-core/icons/pause.png +0 -0
  91. data/test/selenium-core/icons/pause_disabled.png +0 -0
  92. data/test/selenium-core/icons/selected.png +0 -0
  93. data/test/selenium-core/icons/step.png +0 -0
  94. data/test/selenium-core/icons/step_disabled.png +0 -0
  95. data/test/selenium-core/iedoc-core.xml +1515 -0
  96. data/test/selenium-core/iedoc.xml +1469 -0
  97. data/test/selenium-core/lib/cssQuery/cssQuery-p.js +6 -0
  98. data/test/selenium-core/lib/cssQuery/src/cssQuery-level2.js +142 -0
  99. data/test/selenium-core/lib/cssQuery/src/cssQuery-level3.js +150 -0
  100. data/test/selenium-core/lib/cssQuery/src/cssQuery-standard.js +53 -0
  101. data/test/selenium-core/lib/cssQuery/src/cssQuery.js +356 -0
  102. data/test/selenium-core/lib/prototype.js +2006 -0
  103. data/test/selenium-core/lib/scriptaculous/builder.js +101 -0
  104. data/test/selenium-core/lib/scriptaculous/controls.js +815 -0
  105. data/test/selenium-core/lib/scriptaculous/dragdrop.js +915 -0
  106. data/test/selenium-core/lib/scriptaculous/effects.js +958 -0
  107. data/test/selenium-core/lib/scriptaculous/scriptaculous.js +47 -0
  108. data/test/selenium-core/lib/scriptaculous/slider.js +283 -0
  109. data/test/selenium-core/lib/scriptaculous/unittest.js +383 -0
  110. data/test/selenium-core/scripts/find_matching_child.js +69 -0
  111. data/test/selenium-core/scripts/htmlutils.js +894 -0
  112. data/test/selenium-core/scripts/injection.html +72 -0
  113. data/test/selenium-core/scripts/js2html.js +70 -0
  114. data/test/selenium-core/scripts/narcissus-defs.js +175 -0
  115. data/test/selenium-core/scripts/narcissus-exec.js +1054 -0
  116. data/test/selenium-core/scripts/narcissus-parse.js +1003 -0
  117. data/test/selenium-core/scripts/se2html.js +63 -0
  118. data/test/selenium-core/scripts/selenium-api.js +2409 -0
  119. data/test/selenium-core/scripts/selenium-browserbot.js +2203 -0
  120. data/test/selenium-core/scripts/selenium-browserdetect.js +150 -0
  121. data/test/selenium-core/scripts/selenium-commandhandlers.js +377 -0
  122. data/test/selenium-core/scripts/selenium-executionloop.js +175 -0
  123. data/test/selenium-core/scripts/selenium-logging.js +147 -0
  124. data/test/selenium-core/scripts/selenium-remoterunner.js +571 -0
  125. data/test/selenium-core/scripts/selenium-testrunner.js +1333 -0
  126. data/test/selenium-core/scripts/selenium-version.js +5 -0
  127. data/test/selenium-core/scripts/user-extensions.js +3 -0
  128. data/test/selenium-core/scripts/user-extensions.js.sample +75 -0
  129. data/test/selenium-core/scripts/xmlextras.js +153 -0
  130. data/test/selenium-core/selenium-logo.png +0 -0
  131. data/test/selenium-core/selenium-test.css +43 -0
  132. data/test/selenium-core/selenium.css +299 -0
  133. data/test/selenium-core/xpath/dom.js +428 -0
  134. data/test/selenium-core/xpath/misc.js +252 -0
  135. data/test/selenium-core/xpath/xpath.js +2223 -0
  136. data/test/selenium/_login_as_cmsadmin.rsel +4 -0
  137. data/test/selenium/dashboard.rsel +5 -0
  138. data/test/selenium/html_blocks.rsel +4 -0
  139. data/test/selenium/login/failed_login.rsel +8 -0
  140. data/test/selenium/login/successful_login.rsel +9 -0
  141. data/test/selenium/page_templates.rsel +12 -0
  142. data/test/selenium/pages/edit_properties.rsel +5 -0
  143. data/test/selenium/site/view_home_page.rsel +4 -0
  144. data/test/selenium/sitemap/move_page.rsel +9 -0
  145. data/test/selenium/sitemap/open_section.rsel +6 -0
  146. data/test/selenium/sitemap/select_page.rsel +12 -0
  147. data/test/selenium/sitemap/select_section.rsel +17 -0
  148. data/test/test_helper.rb +30 -12
  149. data/test/unit/behaviors/attaching_test.rb +4 -6
  150. data/test/unit/behaviors/connectable_test.rb +29 -0
  151. data/test/unit/behaviors/publishable_test.rb +40 -9
  152. data/test/unit/behaviors/versioning_test.rb +36 -0
  153. data/test/unit/helpers/menu_helper_test.rb +5 -2
  154. data/test/unit/helpers/page_helper_test.rb +2 -0
  155. data/test/unit/lib/cms/sitemap_test.rb +206 -0
  156. data/test/unit/models/attachment_test.rb +51 -31
  157. data/test/unit/models/file_block_test.rb +74 -55
  158. data/test/unit/models/link_test.rb +44 -0
  159. data/test/unit/models/page_test.rb +290 -224
  160. data/test/unit/models/sections_test.rb +144 -44
  161. data/test/unit/models/user_test.rb +28 -18
  162. metadata +581 -350
  163. data/app/views/cms/section_nodes/_section_node.html.erb +0 -10
  164. data/test/unit/models/section_node_test.rb +0 -92
@@ -0,0 +1,428 @@
1
+ // Copyright 2005 Google Inc.
2
+ // All Rights Reserved
3
+ //
4
+ // An XML parse and a minimal DOM implementation that just supportes
5
+ // the subset of the W3C DOM that is used in the XSLT implementation.
6
+ //
7
+ // References:
8
+ //
9
+ // [DOM] W3C DOM Level 3 Core Specification
10
+ // <http://www.w3.org/TR/2004/REC-DOM-Level-3-Core-20040407/>.
11
+ //
12
+ //
13
+ // Author: Steffen Meschkat <mesch@google.com>
14
+
15
+ // NOTE: The split() method in IE omits empty result strings. This is
16
+ // utterly annoying. So we don't use it here.
17
+
18
+ // Resolve entities in XML text fragments. According to the DOM
19
+ // specification, the DOM is supposed to resolve entity references at
20
+ // the API level. I.e. no entity references are passed through the
21
+ // API. See "Entities and the DOM core", p.12, DOM 2 Core
22
+ // Spec. However, different browsers actually pass very different
23
+ // values at the API.
24
+ //
25
+ function xmlResolveEntities(s) {
26
+
27
+ var parts = stringSplit(s, '&');
28
+
29
+ var ret = parts[0];
30
+ for (var i = 1; i < parts.length; ++i) {
31
+ var rp = stringSplit(parts[i], ';');
32
+ if (rp.length == 1) {
33
+ // no entity reference: just a & but no ;
34
+ ret += parts[i];
35
+ continue;
36
+ }
37
+
38
+ var ch;
39
+ switch (rp[0]) {
40
+ case 'lt':
41
+ ch = '<';
42
+ break;
43
+ case 'gt':
44
+ ch = '>';
45
+ break;
46
+ case 'amp':
47
+ ch = '&';
48
+ break;
49
+ case 'quot':
50
+ ch = '"';
51
+ break;
52
+ case 'apos':
53
+ ch = '\'';
54
+ break;
55
+ case 'nbsp':
56
+ ch = String.fromCharCode(160);
57
+ break;
58
+ default:
59
+ // Cool trick: let the DOM do the entity decoding. We assign
60
+ // the entity text through non-W3C DOM properties and read it
61
+ // through the W3C DOM. W3C DOM access is specified to resolve
62
+ // entities.
63
+ var span = window.document.createElement('span');
64
+ span.innerHTML = '&' + rp[0] + '; ';
65
+ ch = span.childNodes[0].nodeValue.charAt(0);
66
+ }
67
+ ret += ch + rp[1];
68
+ }
69
+
70
+ return ret;
71
+ }
72
+
73
+
74
+ // Parses the given XML string with our custom, JavaScript XML parser. Written
75
+ // by Steffen Meschkat (mesch@google.com).
76
+ function xmlParse(xml) {
77
+ Timer.start('xmlparse');
78
+ var regex_empty = /\/$/;
79
+
80
+ // See also <http://www.w3.org/TR/REC-xml/#sec-common-syn> for
81
+ // allowed chars in a tag and attribute name. TODO(mesch): the
82
+ // following is still not completely correct.
83
+
84
+ var regex_tagname = /^([\w:-]*)/;
85
+ var regex_attribute = /([\w:-]+)\s?=\s?('([^\']*)'|"([^\"]*)")/g;
86
+
87
+ var xmldoc = new XDocument();
88
+ var root = xmldoc;
89
+
90
+ // For the record: in Safari, we would create native DOM nodes, but
91
+ // in Opera that is not possible, because the DOM only allows HTML
92
+ // element nodes to be created, so we have to do our own DOM nodes.
93
+
94
+ // xmldoc = document.implementation.createDocument('','',null);
95
+ // root = xmldoc; // .createDocumentFragment();
96
+ // NOTE(mesch): using the DocumentFragment instead of the Document
97
+ // crashes my Safari 1.2.4 (v125.12).
98
+ var stack = [];
99
+
100
+ var parent = root;
101
+ stack.push(parent);
102
+
103
+ var x = stringSplit(xml, '<');
104
+ for (var i = 1; i < x.length; ++i) {
105
+ var xx = stringSplit(x[i], '>');
106
+ var tag = xx[0];
107
+ var text = xmlResolveEntities(xx[1] || '');
108
+
109
+ if (tag.charAt(0) == '/') {
110
+ stack.pop();
111
+ parent = stack[stack.length-1];
112
+
113
+ } else if (tag.charAt(0) == '?') {
114
+ // Ignore XML declaration and processing instructions
115
+ } else if (tag.charAt(0) == '!') {
116
+ // Ignore notation and comments
117
+ } else {
118
+ var empty = tag.match(regex_empty);
119
+ var tagname = regex_tagname.exec(tag)[1];
120
+ var node = xmldoc.createElement(tagname);
121
+
122
+ var att;
123
+ while (att = regex_attribute.exec(tag)) {
124
+ var val = xmlResolveEntities(att[3] || att[4] || '');
125
+ node.setAttribute(att[1], val);
126
+ }
127
+
128
+ if (empty) {
129
+ parent.appendChild(node);
130
+ } else {
131
+ parent.appendChild(node);
132
+ parent = node;
133
+ stack.push(node);
134
+ }
135
+ }
136
+
137
+ if (text && parent != root) {
138
+ parent.appendChild(xmldoc.createTextNode(text));
139
+ }
140
+ }
141
+
142
+ Timer.end('xmlparse');
143
+ return root;
144
+ }
145
+
146
+
147
+ // Our W3C DOM Node implementation. Note we call it XNode because we
148
+ // can't define the identifier Node. We do this mostly for Opera,
149
+ // where we can't reuse the HTML DOM for parsing our own XML, and for
150
+ // Safari, where it is too expensive to have the template processor
151
+ // operate on native DOM nodes.
152
+ function XNode(type, name, value, owner) {
153
+ this.attributes = [];
154
+ this.childNodes = [];
155
+
156
+ XNode.init.call(this, type, name, value, owner);
157
+ }
158
+
159
+ // Don't call as method, use apply() or call().
160
+ XNode.init = function(type, name, value, owner) {
161
+ this.nodeType = type - 0;
162
+ this.nodeName = '' + name;
163
+ this.nodeValue = '' + value;
164
+ this.ownerDocument = owner;
165
+
166
+ this.firstChild = null;
167
+ this.lastChild = null;
168
+ this.nextSibling = null;
169
+ this.previousSibling = null;
170
+ this.parentNode = null;
171
+ }
172
+
173
+ XNode.unused_ = [];
174
+
175
+ XNode.recycle = function(node) {
176
+ if (!node) {
177
+ return;
178
+ }
179
+
180
+ if (node.constructor == XDocument) {
181
+ XNode.recycle(node.documentElement);
182
+ return;
183
+ }
184
+
185
+ if (node.constructor != this) {
186
+ return;
187
+ }
188
+
189
+ XNode.unused_.push(node);
190
+ for (var a = 0; a < node.attributes.length; ++a) {
191
+ XNode.recycle(node.attributes[a]);
192
+ }
193
+ for (var c = 0; c < node.childNodes.length; ++c) {
194
+ XNode.recycle(node.childNodes[c]);
195
+ }
196
+ node.attributes.length = 0;
197
+ node.childNodes.length = 0;
198
+ XNode.init.call(node, 0, '', '', null);
199
+ }
200
+
201
+ XNode.create = function(type, name, value, owner) {
202
+ if (XNode.unused_.length > 0) {
203
+ var node = XNode.unused_.pop();
204
+ XNode.init.call(node, type, name, value, owner);
205
+ return node;
206
+ } else {
207
+ return new XNode(type, name, value, owner);
208
+ }
209
+ }
210
+
211
+ XNode.prototype.appendChild = function(node) {
212
+ // firstChild
213
+ if (this.childNodes.length == 0) {
214
+ this.firstChild = node;
215
+ }
216
+
217
+ // previousSibling
218
+ node.previousSibling = this.lastChild;
219
+
220
+ // nextSibling
221
+ node.nextSibling = null;
222
+ if (this.lastChild) {
223
+ this.lastChild.nextSibling = node;
224
+ }
225
+
226
+ // parentNode
227
+ node.parentNode = this;
228
+
229
+ // lastChild
230
+ this.lastChild = node;
231
+
232
+ // childNodes
233
+ this.childNodes.push(node);
234
+ }
235
+
236
+
237
+ XNode.prototype.replaceChild = function(newNode, oldNode) {
238
+ if (oldNode == newNode) {
239
+ return;
240
+ }
241
+
242
+ for (var i = 0; i < this.childNodes.length; ++i) {
243
+ if (this.childNodes[i] == oldNode) {
244
+ this.childNodes[i] = newNode;
245
+
246
+ var p = oldNode.parentNode;
247
+ oldNode.parentNode = null;
248
+ newNode.parentNode = p;
249
+
250
+ p = oldNode.previousSibling;
251
+ oldNode.previousSibling = null;
252
+ newNode.previousSibling = p;
253
+ if (newNode.previousSibling) {
254
+ newNode.previousSibling.nextSibling = newNode;
255
+ }
256
+
257
+ p = oldNode.nextSibling;
258
+ oldNode.nextSibling = null;
259
+ newNode.nextSibling = p;
260
+ if (newNode.nextSibling) {
261
+ newNode.nextSibling.previousSibling = newNode;
262
+ }
263
+
264
+ if (this.firstChild == oldNode) {
265
+ this.firstChild = newNode;
266
+ }
267
+
268
+ if (this.lastChild == oldNode) {
269
+ this.lastChild = newNode;
270
+ }
271
+
272
+ break;
273
+ }
274
+ }
275
+ }
276
+
277
+ XNode.prototype.insertBefore = function(newNode, oldNode) {
278
+ if (oldNode == newNode) {
279
+ return;
280
+ }
281
+
282
+ if (oldNode.parentNode != this) {
283
+ return;
284
+ }
285
+
286
+ if (newNode.parentNode) {
287
+ newNode.parentNode.removeChild(newNode);
288
+ }
289
+
290
+ var newChildren = [];
291
+ for (var i = 0; i < this.childNodes.length; ++i) {
292
+ var c = this.childNodes[i];
293
+ if (c == oldNode) {
294
+ newChildren.push(newNode);
295
+
296
+ newNode.parentNode = this;
297
+
298
+ newNode.previousSibling = oldNode.previousSibling;
299
+ oldNode.previousSibling = newNode;
300
+ if (newNode.previousSibling) {
301
+ newNode.previousSibling.nextSibling = newNode;
302
+ }
303
+
304
+ newNode.nextSibling = oldNode;
305
+
306
+ if (this.firstChild == oldNode) {
307
+ this.firstChild = newNode;
308
+ }
309
+ }
310
+ newChildren.push(c);
311
+ }
312
+ this.childNodes = newChildren;
313
+ }
314
+
315
+ XNode.prototype.removeChild = function(node) {
316
+ var newChildren = [];
317
+ for (var i = 0; i < this.childNodes.length; ++i) {
318
+ var c = this.childNodes[i];
319
+ if (c != node) {
320
+ newChildren.push(c);
321
+ } else {
322
+ if (c.previousSibling) {
323
+ c.previousSibling.nextSibling = c.nextSibling;
324
+ }
325
+ if (c.nextSibling) {
326
+ c.nextSibling.previousSibling = c.previousSibling;
327
+ }
328
+ if (this.firstChild == c) {
329
+ this.firstChild = c.nextSibling;
330
+ }
331
+ if (this.lastChild == c) {
332
+ this.lastChild = c.previousSibling;
333
+ }
334
+ }
335
+ }
336
+ this.childNodes = newChildren;
337
+ }
338
+
339
+
340
+ XNode.prototype.hasAttributes = function() {
341
+ return this.attributes.length > 0;
342
+ }
343
+
344
+
345
+ XNode.prototype.setAttribute = function(name, value) {
346
+ for (var i = 0; i < this.attributes.length; ++i) {
347
+ if (this.attributes[i].nodeName == name) {
348
+ this.attributes[i].nodeValue = '' + value;
349
+ return;
350
+ }
351
+ }
352
+ this.attributes.push(new XNode(DOM_ATTRIBUTE_NODE, name, value));
353
+ }
354
+
355
+
356
+ XNode.prototype.getAttribute = function(name) {
357
+ for (var i = 0; i < this.attributes.length; ++i) {
358
+ if (this.attributes[i].nodeName == name) {
359
+ return this.attributes[i].nodeValue;
360
+ }
361
+ }
362
+ return null;
363
+ }
364
+
365
+ XNode.prototype.removeAttribute = function(name) {
366
+ var a = [];
367
+ for (var i = 0; i < this.attributes.length; ++i) {
368
+ if (this.attributes[i].nodeName != name) {
369
+ a.push(this.attributes[i]);
370
+ }
371
+ }
372
+ this.attributes = a;
373
+ }
374
+
375
+
376
+ function XDocument() {
377
+ XNode.call(this, DOM_DOCUMENT_NODE, '#document', null, this);
378
+ this.documentElement = null;
379
+ }
380
+
381
+ XDocument.prototype = new XNode(DOM_DOCUMENT_NODE, '#document');
382
+
383
+ XDocument.prototype.clear = function() {
384
+ XNode.recycle(this.documentElement);
385
+ this.documentElement = null;
386
+ }
387
+
388
+ XDocument.prototype.appendChild = function(node) {
389
+ XNode.prototype.appendChild.call(this, node);
390
+ this.documentElement = this.childNodes[0];
391
+ }
392
+
393
+ XDocument.prototype.createElement = function(name) {
394
+ return XNode.create(DOM_ELEMENT_NODE, name, null, this);
395
+ }
396
+
397
+ XDocument.prototype.createDocumentFragment = function() {
398
+ return XNode.create(DOM_DOCUMENT_FRAGMENT_NODE, '#document-fragment',
399
+ null, this);
400
+ }
401
+
402
+ XDocument.prototype.createTextNode = function(value) {
403
+ return XNode.create(DOM_TEXT_NODE, '#text', value, this);
404
+ }
405
+
406
+ XDocument.prototype.createAttribute = function(name) {
407
+ return XNode.create(DOM_ATTRIBUTE_NODE, name, null, this);
408
+ }
409
+
410
+ XDocument.prototype.createComment = function(data) {
411
+ return XNode.create(DOM_COMMENT_NODE, '#comment', data, this);
412
+ }
413
+
414
+ XNode.prototype.getElementsByTagName = function(name, list) {
415
+ if (!list) {
416
+ list = [];
417
+ }
418
+
419
+ if (this.nodeName == name) {
420
+ list.push(this);
421
+ }
422
+
423
+ for (var i = 0; i < this.childNodes.length; ++i) {
424
+ this.childNodes[i].getElementsByTagName(name, list);
425
+ }
426
+
427
+ return list;
428
+ }
@@ -0,0 +1,252 @@
1
+ // Copyright 2005 Google Inc.
2
+ // All Rights Reserved
3
+ //
4
+ // Miscellania that support the ajaxslt implementation.
5
+ //
6
+ // Author: Steffen Meschkat <mesch@google.com>
7
+ //
8
+
9
+ function el(i) {
10
+ return document.getElementById(i);
11
+ }
12
+
13
+ function px(x) {
14
+ return x + 'px';
15
+ }
16
+
17
+ // Split a string s at all occurrences of character c. This is like
18
+ // the split() method of the string object, but IE omits empty
19
+ // strings, which violates the invariant (s.split(x).join(x) == s).
20
+ function stringSplit(s, c) {
21
+ var a = s.indexOf(c);
22
+ if (a == -1) {
23
+ return [ s ];
24
+ }
25
+
26
+ var parts = [];
27
+ parts.push(s.substr(0,a));
28
+ while (a != -1) {
29
+ var a1 = s.indexOf(c, a + 1);
30
+ if (a1 != -1) {
31
+ parts.push(s.substr(a + 1, a1 - a - 1));
32
+ } else {
33
+ parts.push(s.substr(a + 1));
34
+ }
35
+ a = a1;
36
+ }
37
+
38
+ return parts;
39
+ }
40
+
41
+ // Returns the text value if a node; for nodes without children this
42
+ // is the nodeValue, for nodes with children this is the concatenation
43
+ // of the value of all children.
44
+ function xmlValue(node) {
45
+ if (!node) {
46
+ return '';
47
+ }
48
+
49
+ var ret = '';
50
+ if (node.nodeType == DOM_TEXT_NODE ||
51
+ node.nodeType == DOM_CDATA_SECTION_NODE ||
52
+ node.nodeType == DOM_ATTRIBUTE_NODE) {
53
+ ret += node.nodeValue;
54
+
55
+ } else if (node.nodeType == DOM_ELEMENT_NODE ||
56
+ node.nodeType == DOM_DOCUMENT_NODE ||
57
+ node.nodeType == DOM_DOCUMENT_FRAGMENT_NODE) {
58
+ for (var i = 0; i < node.childNodes.length; ++i) {
59
+ ret += arguments.callee(node.childNodes[i]);
60
+ }
61
+ }
62
+ return ret;
63
+ }
64
+
65
+ // Returns the representation of a node as XML text.
66
+ function xmlText(node) {
67
+ var ret = '';
68
+ if (node.nodeType == DOM_TEXT_NODE) {
69
+ ret += xmlEscapeText(node.nodeValue);
70
+
71
+ } else if (node.nodeType == DOM_ELEMENT_NODE) {
72
+ ret += '<' + node.nodeName;
73
+ for (var i = 0; i < node.attributes.length; ++i) {
74
+ var a = node.attributes[i];
75
+ if (a && a.nodeName && a.nodeValue) {
76
+ ret += ' ' + a.nodeName;
77
+ ret += '="' + xmlEscapeAttr(a.nodeValue) + '"';
78
+ }
79
+ }
80
+
81
+ if (node.childNodes.length == 0) {
82
+ ret += '/>';
83
+
84
+ } else {
85
+ ret += '>';
86
+ for (var i = 0; i < node.childNodes.length; ++i) {
87
+ ret += arguments.callee(node.childNodes[i]);
88
+ }
89
+ ret += '</' + node.nodeName + '>';
90
+ }
91
+
92
+ } else if (node.nodeType == DOM_DOCUMENT_NODE ||
93
+ node.nodeType == DOM_DOCUMENT_FRAGMENT_NODE) {
94
+ for (var i = 0; i < node.childNodes.length; ++i) {
95
+ ret += arguments.callee(node.childNodes[i]);
96
+ }
97
+ }
98
+
99
+ return ret;
100
+ }
101
+
102
+ // Applies the given function to each element of the array.
103
+ function mapExec(array, func) {
104
+ for (var i = 0; i < array.length; ++i) {
105
+ func(array[i]);
106
+ }
107
+ }
108
+
109
+ // Returns an array that contains the return value of the given
110
+ // function applied to every element of the input array.
111
+ function mapExpr(array, func) {
112
+ var ret = [];
113
+ for (var i = 0; i < array.length; ++i) {
114
+ ret.push(func(array[i]));
115
+ }
116
+ return ret;
117
+ };
118
+
119
+ // Reverses the given array in place.
120
+ function reverseInplace(array) {
121
+ for (var i = 0; i < array.length / 2; ++i) {
122
+ var h = array[i];
123
+ var ii = array.length - i - 1;
124
+ array[i] = array[ii];
125
+ array[ii] = h;
126
+ }
127
+ }
128
+
129
+ // Shallow-copies an array.
130
+ function copyArray(dst, src) {
131
+ for (var i = 0; i < src.length; ++i) {
132
+ dst.push(src[i]);
133
+ }
134
+ }
135
+
136
+ function assert(b) {
137
+ if (!b) {
138
+ throw 'assertion failed';
139
+ }
140
+ }
141
+
142
+ // Based on
143
+ // <http://www.w3.org/TR/2000/REC-DOM-Level-2-Core-20001113/core.html#ID-1950641247>
144
+ var DOM_ELEMENT_NODE = 1;
145
+ var DOM_ATTRIBUTE_NODE = 2;
146
+ var DOM_TEXT_NODE = 3;
147
+ var DOM_CDATA_SECTION_NODE = 4;
148
+ var DOM_ENTITY_REFERENCE_NODE = 5;
149
+ var DOM_ENTITY_NODE = 6;
150
+ var DOM_PROCESSING_INSTRUCTION_NODE = 7;
151
+ var DOM_COMMENT_NODE = 8;
152
+ var DOM_DOCUMENT_NODE = 9;
153
+ var DOM_DOCUMENT_TYPE_NODE = 10;
154
+ var DOM_DOCUMENT_FRAGMENT_NODE = 11;
155
+ var DOM_NOTATION_NODE = 12;
156
+
157
+
158
+ var xpathdebug = false; // trace xpath parsing
159
+ var xsltdebug = false; // trace xslt processing
160
+
161
+
162
+ // Escape XML special markup chracters: tag delimiter < > and entity
163
+ // reference start delimiter &. The escaped string can be used in XML
164
+ // text portions (i.e. between tags).
165
+ function xmlEscapeText(s) {
166
+ return s.replace(/&/g, '&amp;').replace(/</g, '&lt;').replace(/>/g, '&gt;');
167
+ }
168
+
169
+ // Escape XML special markup characters: tag delimiter < > entity
170
+ // reference start delimiter & and quotes ". The escaped string can be
171
+ // used in double quoted XML attribute value portions (i.e. in
172
+ // attributes within start tags).
173
+ function xmlEscapeAttr(s) {
174
+ return xmlEscapeText(s).replace(/\"/g, '&quot;');
175
+ }
176
+
177
+ // Escape markup in XML text, but don't touch entity references. The
178
+ // escaped string can be used as XML text (i.e. between tags).
179
+ function xmlEscapeTags(s) {
180
+ return s.replace(/</g, '&lt;').replace(/>/g, '&gt;');
181
+ }
182
+
183
+ // An implementation of the debug log.
184
+
185
+ var logging__ = false;
186
+
187
+ function Log() {};
188
+
189
+ Log.lines = [];
190
+
191
+ Log.write = function(s) {
192
+ LOG.debug("xpath logging: " + s);
193
+ };
194
+
195
+ // Writes the given XML with every tag on a new line.
196
+ Log.writeXML = function(xml) {
197
+ if (logging__) {
198
+ var s0 = xml.replace(/</g, '\n<');
199
+ var s1 = xmlEscapeText(s0);
200
+ var s2 = s1.replace(/\s*\n(\s|\n)*/g, '<br/>');
201
+ this.lines.push(s2);
202
+ this.show();
203
+ }
204
+ }
205
+
206
+ // Writes without any escaping
207
+ Log.writeRaw = function(s) {
208
+ if (logging__) {
209
+ this.lines.push(s);
210
+ this.show();
211
+ }
212
+ }
213
+
214
+ Log.clear = function() {
215
+ if (logging__) {
216
+ var l = this.div();
217
+ l.innerHTML = '';
218
+ this.lines = [];
219
+ }
220
+ }
221
+
222
+ Log.show = function() {
223
+ var l = this.div();
224
+ l.innerHTML += this.lines.join('<br/>') + '<br/>';
225
+ this.lines = [];
226
+ l.scrollTop = l.scrollHeight;
227
+ }
228
+
229
+ Log.div = function() {
230
+ var l = document.getElementById('log');
231
+ if (!l) {
232
+ l = document.createElement('div');
233
+ l.id = 'log';
234
+ l.style.position = 'absolute';
235
+ l.style.right = '5px';
236
+ l.style.top = '5px';
237
+ l.style.width = '250px';
238
+ l.style.height = '150px';
239
+ l.style.overflow = 'auto';
240
+ l.style.backgroundColor = '#f0f0f0';
241
+ l.style.border = '1px solid gray';
242
+ l.style.fontSize = '10px';
243
+ l.style.padding = '5px';
244
+ document.body.appendChild(l);
245
+ }
246
+ return l;
247
+ }
248
+
249
+
250
+ function Timer() {}
251
+ Timer.start = function() {}
252
+ Timer.end = function() {}