browsercms 3.1.4 → 3.1.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.
- data/app/controllers/cms/content_block_controller.rb +2 -2
- data/app/controllers/cms/section_nodes_controller.rb +6 -1
- data/app/controllers/cms/sections_controller.rb +1 -1
- data/app/helpers/cms/application_helper.rb +1 -1
- data/app/helpers/cms/content_block_helper.rb +27 -0
- data/app/helpers/cms/section_nodes_helper.rb +43 -5
- data/app/models/abstract_file_block.rb +16 -1
- data/app/models/attachment.rb +17 -35
- data/app/models/file_block.rb +0 -12
- data/app/models/image_block.rb +0 -12
- data/app/models/link.rb +4 -21
- data/app/models/page.rb +31 -34
- data/app/models/section.rb +82 -44
- data/app/models/section_node.rb +39 -24
- data/app/models/user.rb +5 -0
- data/app/views/cms/blocks/index.html.erb +4 -4
- data/app/views/cms/file_blocks/_form.html.erb +1 -1
- data/app/views/cms/image_blocks/_form.html.erb +1 -1
- data/app/views/cms/section_nodes/_link.html.erb +6 -3
- data/app/views/cms/section_nodes/_node.html.erb +11 -1
- data/app/views/cms/section_nodes/_page.html.erb +13 -7
- data/app/views/cms/section_nodes/_section.html.erb +24 -8
- data/app/views/cms/section_nodes/index.html.erb +28 -16
- data/app/views/layouts/templates/default.html.erb +17 -0
- data/browsercms.gemspec +28 -1413
- data/db/migrate/20120117144039_browsercms315.rb +94 -0
- data/db/migrate/{20081114172307_load_seed_data.rb → 20121114172307_load_seeds.rb} +8 -1
- data/lib/acts_as_list.rb +1 -1
- data/lib/browsercms.rb +2 -0
- data/lib/cms/addressable.rb +83 -0
- data/lib/cms/behaviors/attaching.rb +44 -24
- data/lib/cms/behaviors/connecting.rb +2 -1
- data/lib/cms/behaviors/publishing.rb +12 -3
- data/lib/cms/behaviors/versioning.rb +83 -53
- data/lib/cms/content_rendering_support.rb +3 -3
- data/lib/cms/error_pages.rb +8 -0
- data/lib/cms/init.rb +5 -3
- data/lib/cms/version.rb +1 -1
- data/templates/blank.rb +2 -0
- data/templates/demo.rb +2 -0
- data/templates/module.rb +2 -0
- data/test/custom_assertions.rb +7 -1
- data/test/factories.rb +3 -1
- data/test/factories/sitemap_factories.rb +28 -0
- data/test/fixtures/connectors.yml +97 -0
- data/test/fixtures/content_type_groups.yml +13 -0
- data/test/fixtures/content_types.yml +50 -0
- data/test/fixtures/dynamic_view_versions.yml +26 -0
- data/test/fixtures/dynamic_views.yml +26 -0
- data/test/fixtures/group_permissions.yml +16 -0
- data/test/fixtures/group_sections.yml +31 -0
- data/test/fixtures/group_type_permissions.yml +11 -0
- data/test/fixtures/group_types.yml +25 -0
- data/test/fixtures/groups.yml +25 -0
- data/test/fixtures/html_block_versions.yml +67 -0
- data/test/fixtures/html_blocks.yml +63 -0
- data/test/fixtures/page_versions.yml +265 -0
- data/test/fixtures/pages.yml +85 -0
- data/test/fixtures/permissions.yml +28 -0
- data/test/fixtures/section_nodes.yml +46 -0
- data/test/fixtures/sections.yml +19 -0
- data/test/fixtures/sites.yml +9 -0
- data/test/fixtures/user_group_memberships.yml +11 -0
- data/test/fixtures/users.yml +15 -0
- data/test/functional/cms/content_controller_test.rb +6 -1
- data/test/functional/cms/file_blocks_controller_test.rb +1 -0
- data/test/functional/cms/html_blocks_controller_test.rb +1 -0
- data/test/functional/cms/image_blocks_controller_test.rb +39 -32
- data/test/functional/cms/section_nodes_controller_test.rb +48 -20
- data/test/functional/cms/sections_controller_test.rb +3 -1
- data/test/functional/tests/pretend_controller_test.rb +6 -3
- data/test/integration/cms/ckeditor_test.rb +5 -2
- data/test/integration/sitemap_performance_test.rb +26 -0
- data/test/selenium-core/Blank.html +7 -0
- data/test/selenium-core/InjectedRemoteRunner.html +8 -0
- data/test/selenium-core/RemoteRunner.html +110 -0
- data/test/selenium-core/SeleniumLog.html +109 -0
- data/test/selenium-core/TestPrompt.html +145 -0
- data/test/selenium-core/TestRunner-splash.html +55 -0
- data/test/selenium-core/TestRunner.hta +176 -0
- data/test/selenium-core/TestRunner.html +176 -0
- data/test/selenium-core/domviewer/butmin.gif +0 -0
- data/test/selenium-core/domviewer/butplus.gif +0 -0
- data/test/selenium-core/domviewer/domviewer.css +298 -0
- data/test/selenium-core/domviewer/domviewer.html +16 -0
- data/test/selenium-core/domviewer/selenium-domviewer.js +205 -0
- data/test/selenium-core/icons/all.png +0 -0
- data/test/selenium-core/icons/continue.png +0 -0
- data/test/selenium-core/icons/continue_disabled.png +0 -0
- data/test/selenium-core/icons/pause.png +0 -0
- data/test/selenium-core/icons/pause_disabled.png +0 -0
- data/test/selenium-core/icons/selected.png +0 -0
- data/test/selenium-core/icons/step.png +0 -0
- data/test/selenium-core/icons/step_disabled.png +0 -0
- data/test/selenium-core/iedoc-core.xml +1515 -0
- data/test/selenium-core/iedoc.xml +1469 -0
- data/test/selenium-core/lib/cssQuery/cssQuery-p.js +6 -0
- data/test/selenium-core/lib/cssQuery/src/cssQuery-level2.js +142 -0
- data/test/selenium-core/lib/cssQuery/src/cssQuery-level3.js +150 -0
- data/test/selenium-core/lib/cssQuery/src/cssQuery-standard.js +53 -0
- data/test/selenium-core/lib/cssQuery/src/cssQuery.js +356 -0
- data/test/selenium-core/lib/prototype.js +2006 -0
- data/test/selenium-core/lib/scriptaculous/builder.js +101 -0
- data/test/selenium-core/lib/scriptaculous/controls.js +815 -0
- data/test/selenium-core/lib/scriptaculous/dragdrop.js +915 -0
- data/test/selenium-core/lib/scriptaculous/effects.js +958 -0
- data/test/selenium-core/lib/scriptaculous/scriptaculous.js +47 -0
- data/test/selenium-core/lib/scriptaculous/slider.js +283 -0
- data/test/selenium-core/lib/scriptaculous/unittest.js +383 -0
- data/test/selenium-core/scripts/find_matching_child.js +69 -0
- data/test/selenium-core/scripts/htmlutils.js +894 -0
- data/test/selenium-core/scripts/injection.html +72 -0
- data/test/selenium-core/scripts/js2html.js +70 -0
- data/test/selenium-core/scripts/narcissus-defs.js +175 -0
- data/test/selenium-core/scripts/narcissus-exec.js +1054 -0
- data/test/selenium-core/scripts/narcissus-parse.js +1003 -0
- data/test/selenium-core/scripts/se2html.js +63 -0
- data/test/selenium-core/scripts/selenium-api.js +2409 -0
- data/test/selenium-core/scripts/selenium-browserbot.js +2203 -0
- data/test/selenium-core/scripts/selenium-browserdetect.js +150 -0
- data/test/selenium-core/scripts/selenium-commandhandlers.js +377 -0
- data/test/selenium-core/scripts/selenium-executionloop.js +175 -0
- data/test/selenium-core/scripts/selenium-logging.js +147 -0
- data/test/selenium-core/scripts/selenium-remoterunner.js +571 -0
- data/test/selenium-core/scripts/selenium-testrunner.js +1333 -0
- data/test/selenium-core/scripts/selenium-version.js +5 -0
- data/test/selenium-core/scripts/user-extensions.js +3 -0
- data/test/selenium-core/scripts/user-extensions.js.sample +75 -0
- data/test/selenium-core/scripts/xmlextras.js +153 -0
- data/test/selenium-core/selenium-logo.png +0 -0
- data/test/selenium-core/selenium-test.css +43 -0
- data/test/selenium-core/selenium.css +299 -0
- data/test/selenium-core/xpath/dom.js +428 -0
- data/test/selenium-core/xpath/misc.js +252 -0
- data/test/selenium-core/xpath/xpath.js +2223 -0
- data/test/selenium/_login_as_cmsadmin.rsel +4 -0
- data/test/selenium/dashboard.rsel +5 -0
- data/test/selenium/html_blocks.rsel +4 -0
- data/test/selenium/login/failed_login.rsel +8 -0
- data/test/selenium/login/successful_login.rsel +9 -0
- data/test/selenium/page_templates.rsel +12 -0
- data/test/selenium/pages/edit_properties.rsel +5 -0
- data/test/selenium/site/view_home_page.rsel +4 -0
- data/test/selenium/sitemap/move_page.rsel +9 -0
- data/test/selenium/sitemap/open_section.rsel +6 -0
- data/test/selenium/sitemap/select_page.rsel +12 -0
- data/test/selenium/sitemap/select_section.rsel +17 -0
- data/test/test_helper.rb +30 -12
- data/test/unit/behaviors/attaching_test.rb +4 -6
- data/test/unit/behaviors/connectable_test.rb +29 -0
- data/test/unit/behaviors/publishable_test.rb +40 -9
- data/test/unit/behaviors/versioning_test.rb +36 -0
- data/test/unit/helpers/menu_helper_test.rb +5 -2
- data/test/unit/helpers/page_helper_test.rb +2 -0
- data/test/unit/lib/cms/sitemap_test.rb +206 -0
- data/test/unit/models/attachment_test.rb +51 -31
- data/test/unit/models/file_block_test.rb +74 -55
- data/test/unit/models/link_test.rb +44 -0
- data/test/unit/models/page_test.rb +290 -224
- data/test/unit/models/sections_test.rb +144 -44
- data/test/unit/models/user_test.rb +28 -18
- metadata +581 -350
- data/app/views/cms/section_nodes/_section_node.html.erb +0 -10
- 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, '&').replace(/</g, '<').replace(/>/g, '>');
|
|
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, '"');
|
|
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, '<').replace(/>/g, '>');
|
|
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() {}
|