somehow these files have been marked a changed after the pull

This commit is contained in:
Reinier Balt 2008-06-16 15:24:02 +02:00
parent 12b2c06b71
commit 8a3ba65bb7
7 changed files with 3110 additions and 3110 deletions

View file

@ -1,69 +1,69 @@
/* /*
* Copyright 2004 ThoughtWorks, Inc * Copyright 2004 ThoughtWorks, Inc
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
* You may obtain a copy of the License at * You may obtain a copy of the License at
* *
* http://www.apache.org/licenses/LICENSE-2.0 * http://www.apache.org/licenses/LICENSE-2.0
* *
* Unless required by applicable law or agreed to in writing, software * Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, * distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and * See the License for the specific language governing permissions and
* limitations under the License. * limitations under the License.
* *
*/ */
elementFindMatchingChildren = function(element, selector) { elementFindMatchingChildren = function(element, selector) {
var matches = []; var matches = [];
var childCount = element.childNodes.length; var childCount = element.childNodes.length;
for (var i=0; i<childCount; i++) { for (var i=0; i<childCount; i++) {
var child = element.childNodes[i]; var child = element.childNodes[i];
if (selector(child)) { if (selector(child)) {
matches.push(child); matches.push(child);
} else { } else {
childMatches = elementFindMatchingChildren(child, selector); childMatches = elementFindMatchingChildren(child, selector);
matches.push(childMatches); matches.push(childMatches);
} }
} }
return matches.flatten(); return matches.flatten();
} }
ELEMENT_NODE_TYPE = 1; ELEMENT_NODE_TYPE = 1;
elementFindFirstMatchingChild = function(element, selector) { elementFindFirstMatchingChild = function(element, selector) {
var childCount = element.childNodes.length; var childCount = element.childNodes.length;
for (var i=0; i<childCount; i++) { for (var i=0; i<childCount; i++) {
var child = element.childNodes[i]; var child = element.childNodes[i];
if (child.nodeType == ELEMENT_NODE_TYPE) { if (child.nodeType == ELEMENT_NODE_TYPE) {
if (selector(child)) { if (selector(child)) {
return child; return child;
} }
result = elementFindFirstMatchingChild(child, selector); result = elementFindFirstMatchingChild(child, selector);
if (result) { if (result) {
return result; return result;
} }
} }
} }
return null; return null;
} }
elementFindFirstMatchingParent = function(element, selector) { elementFindFirstMatchingParent = function(element, selector) {
var current = element.parentNode; var current = element.parentNode;
while (current != null) { while (current != null) {
if (selector(current)) { if (selector(current)) {
break; break;
} }
current = current.parentNode; current = current.parentNode;
} }
return current; return current;
} }
elementFindMatchingChildById = function(element, id) { elementFindMatchingChildById = function(element, id) {
return elementFindFirstMatchingChild(element, function(element){return element.id==id} ); return elementFindFirstMatchingChild(element, function(element){return element.id==id} );
} }

View file

@ -1,70 +1,70 @@
/* /*
This is an experiment in using the Narcissus JavaScript engine This is an experiment in using the Narcissus JavaScript engine
to allow Selenium scripts to be written in plain JavaScript. to allow Selenium scripts to be written in plain JavaScript.
The 'jsparse' function will compile each high level block into a Selenium table script. The 'jsparse' function will compile each high level block into a Selenium table script.
TODO: TODO:
1) Test! (More browsers, more sample scripts) 1) Test! (More browsers, more sample scripts)
2) Stepping and walking lower levels of the parse tree 2) Stepping and walking lower levels of the parse tree
3) Calling Selenium commands directly from JavaScript 3) Calling Selenium commands directly from JavaScript
4) Do we want comments to appear in the TestRunner? 4) Do we want comments to appear in the TestRunner?
5) Fix context so variables don't have to be global 5) Fix context so variables don't have to be global
For now, variables defined with "var" won't be found For now, variables defined with "var" won't be found
if used later on in a script. if used later on in a script.
6) Fix formatting 6) Fix formatting
*/ */
function jsparse() { function jsparse() {
var script = document.getElementById('sejs') var script = document.getElementById('sejs')
var fname = 'javascript script'; var fname = 'javascript script';
parse_result = parse(script.text, fname, 0); parse_result = parse(script.text, fname, 0);
var x2 = new ExecutionContext(GLOBAL_CODE); var x2 = new ExecutionContext(GLOBAL_CODE);
ExecutionContext.current = x2; ExecutionContext.current = x2;
var new_test_source = ''; var new_test_source = '';
var new_line = ''; var new_line = '';
for (i=0;i<parse_result.$length;i++){ for (i=0;i<parse_result.$length;i++){
var the_start = parse_result[i].start; var the_start = parse_result[i].start;
var the_end; var the_end;
if ( i == (parse_result.$length-1)) { if ( i == (parse_result.$length-1)) {
the_end = parse_result.tokenizer.source.length; the_end = parse_result.tokenizer.source.length;
} else { } else {
the_end = parse_result[i+1].start; the_end = parse_result[i+1].start;
} }
var script_fragment = parse_result.tokenizer.source.slice(the_start,the_end) var script_fragment = parse_result.tokenizer.source.slice(the_start,the_end)
new_line = '<tr><td style="display:none;" class="js">getEval</td>' + new_line = '<tr><td style="display:none;" class="js">getEval</td>' +
'<td style="display:none;">currentTest.doNextCommand()</td>' + '<td style="display:none;">currentTest.doNextCommand()</td>' +
'<td style="white-space: pre;">' + script_fragment + '</td>' + '<td style="white-space: pre;">' + script_fragment + '</td>' +
'<td></td></tr>\n'; '<td></td></tr>\n';
new_test_source += new_line; new_test_source += new_line;
//eval(script_fragment); //eval(script_fragment);
}; };
execute(parse_result,x2) execute(parse_result,x2)
// Create HTML Table // Create HTML Table
body = document.body body = document.body
body.innerHTML += "<table class='selenium' id='se-js-table'>"+ body.innerHTML += "<table class='selenium' id='se-js-table'>"+
"<tbody>" + "<tbody>" +
"<tr><td>// " + document.title + "</td></tr>" + "<tr><td>// " + document.title + "</td></tr>" +
new_test_source + new_test_source +
"</tbody" + "</tbody" +
"</table>"; "</table>";
//body.innerHTML = "<pre>" + parse_result + "</pre>" //body.innerHTML = "<pre>" + parse_result + "</pre>"
} }

View file

@ -1,63 +1,63 @@
/* /*
This is an experiment in creating a "selenese" parser that drastically This is an experiment in creating a "selenese" parser that drastically
cuts down on the line noise associated with writing tests in HTML. cuts down on the line noise associated with writing tests in HTML.
The 'parse' function will accept the follow sample commands. The 'parse' function will accept the follow sample commands.
test-cases: test-cases:
//comment //comment
command "param" command "param"
command "param" // comment command "param" // comment
command "param" "param2" command "param" "param2"
command "param" "param2" // this is a comment command "param" "param2" // this is a comment
TODO: TODO:
1) Deal with multiline parameters 1) Deal with multiline parameters
2) Escape quotes properly 2) Escape quotes properly
3) Determine whether this should/will become the "preferred" syntax 3) Determine whether this should/will become the "preferred" syntax
for delivered Selenium self-test scripts for delivered Selenium self-test scripts
*/ */
function separse(doc) { function separse(doc) {
// Get object // Get object
script = doc.getElementById('testcase') script = doc.getElementById('testcase')
// Split into lines // Split into lines
lines = script.text.split('\n'); lines = script.text.split('\n');
var command_pattern = / *(\w+) *"([^"]*)" *(?:"([^"]*)"){0,1}(?: *(\/\/ *.+))*/i; var command_pattern = / *(\w+) *"([^"]*)" *(?:"([^"]*)"){0,1}(?: *(\/\/ *.+))*/i;
var comment_pattern = /^ *(\/\/ *.+)/ var comment_pattern = /^ *(\/\/ *.+)/
// Regex each line into selenium command and convert into table row. // Regex each line into selenium command and convert into table row.
// eg. "<command> <quote> <quote> <comment>" // eg. "<command> <quote> <quote> <comment>"
var new_test_source = ''; var new_test_source = '';
var new_line = ''; var new_line = '';
for (var x=0; x < lines.length; x++) { for (var x=0; x < lines.length; x++) {
result = lines[x].match(command_pattern); result = lines[x].match(command_pattern);
if (result != null) { if (result != null) {
new_line = "<tr><td>" + (result[1] || '&nbsp;') + "</td>" + new_line = "<tr><td>" + (result[1] || '&nbsp;') + "</td>" +
"<td>" + (result[2] || '&nbsp;') + "</td>" + "<td>" + (result[2] || '&nbsp;') + "</td>" +
"<td>" + (result[3] || '&nbsp;') + "</td>" + "<td>" + (result[3] || '&nbsp;') + "</td>" +
"<td>" + (result[4] || '&nbsp;') + "</td></tr>\n"; "<td>" + (result[4] || '&nbsp;') + "</td></tr>\n";
new_test_source += new_line; new_test_source += new_line;
} }
result = lines[x].match(comment_pattern); result = lines[x].match(comment_pattern);
if (result != null) { if (result != null) {
new_line = '<tr><td rowspan="1" colspan="4">' + new_line = '<tr><td rowspan="1" colspan="4">' +
(result[1] || '&nbsp;') + (result[1] || '&nbsp;') +
'</td></tr>'; '</td></tr>';
new_test_source += new_line; new_test_source += new_line;
} }
} }
// Create HTML Table // Create HTML Table
body = doc.body body = doc.body
body.innerHTML += "<table class='selenium' id='testtable'>"+ body.innerHTML += "<table class='selenium' id='testtable'>"+
new_test_source + new_test_source +
"</table>"; "</table>";
} }

View file

@ -1,43 +1,43 @@
body, table { body, table {
font-family: Verdana, Arial, sans-serif; font-family: Verdana, Arial, sans-serif;
font-size: 12; font-size: 12;
} }
table { table {
border-collapse: collapse; border-collapse: collapse;
border: 1px solid #ccc; border: 1px solid #ccc;
} }
th, td { th, td {
padding-left: 0.3em; padding-left: 0.3em;
padding-right: 0.3em; padding-right: 0.3em;
} }
a { a {
text-decoration: none; text-decoration: none;
} }
.title { .title {
font-style: italic; font-style: italic;
} }
.selected { .selected {
background-color: #ffffcc; background-color: #ffffcc;
} }
.status_done { .status_done {
background-color: #eeffee; background-color: #eeffee;
} }
.status_passed { .status_passed {
background-color: #ccffcc; background-color: #ccffcc;
} }
.status_failed { .status_failed {
background-color: #ffcccc; background-color: #ffcccc;
} }
.breakpoint { .breakpoint {
background-color: #cccccc; background-color: #cccccc;
border: 1px solid black; border: 1px solid black;
} }

View file

@ -1,428 +1,428 @@
// Copyright 2005 Google Inc. // Copyright 2005 Google Inc.
// All Rights Reserved // All Rights Reserved
// //
// An XML parse and a minimal DOM implementation that just supportes // An XML parse and a minimal DOM implementation that just supportes
// the subset of the W3C DOM that is used in the XSLT implementation. // the subset of the W3C DOM that is used in the XSLT implementation.
// //
// References: // References:
// //
// [DOM] W3C DOM Level 3 Core Specification // [DOM] W3C DOM Level 3 Core Specification
// <http://www.w3.org/TR/2004/REC-DOM-Level-3-Core-20040407/>. // <http://www.w3.org/TR/2004/REC-DOM-Level-3-Core-20040407/>.
// //
// //
// Author: Steffen Meschkat <mesch@google.com> // Author: Steffen Meschkat <mesch@google.com>
// NOTE: The split() method in IE omits empty result strings. This is // NOTE: The split() method in IE omits empty result strings. This is
// utterly annoying. So we don't use it here. // utterly annoying. So we don't use it here.
// Resolve entities in XML text fragments. According to the DOM // Resolve entities in XML text fragments. According to the DOM
// specification, the DOM is supposed to resolve entity references at // specification, the DOM is supposed to resolve entity references at
// the API level. I.e. no entity references are passed through the // the API level. I.e. no entity references are passed through the
// API. See "Entities and the DOM core", p.12, DOM 2 Core // API. See "Entities and the DOM core", p.12, DOM 2 Core
// Spec. However, different browsers actually pass very different // Spec. However, different browsers actually pass very different
// values at the API. // values at the API.
// //
function xmlResolveEntities(s) { function xmlResolveEntities(s) {
var parts = stringSplit(s, '&'); var parts = stringSplit(s, '&');
var ret = parts[0]; var ret = parts[0];
for (var i = 1; i < parts.length; ++i) { for (var i = 1; i < parts.length; ++i) {
var rp = stringSplit(parts[i], ';'); var rp = stringSplit(parts[i], ';');
if (rp.length == 1) { if (rp.length == 1) {
// no entity reference: just a & but no ; // no entity reference: just a & but no ;
ret += parts[i]; ret += parts[i];
continue; continue;
} }
var ch; var ch;
switch (rp[0]) { switch (rp[0]) {
case 'lt': case 'lt':
ch = '<'; ch = '<';
break; break;
case 'gt': case 'gt':
ch = '>'; ch = '>';
break; break;
case 'amp': case 'amp':
ch = '&'; ch = '&';
break; break;
case 'quot': case 'quot':
ch = '"'; ch = '"';
break; break;
case 'apos': case 'apos':
ch = '\''; ch = '\'';
break; break;
case 'nbsp': case 'nbsp':
ch = String.fromCharCode(160); ch = String.fromCharCode(160);
break; break;
default: default:
// Cool trick: let the DOM do the entity decoding. We assign // Cool trick: let the DOM do the entity decoding. We assign
// the entity text through non-W3C DOM properties and read it // the entity text through non-W3C DOM properties and read it
// through the W3C DOM. W3C DOM access is specified to resolve // through the W3C DOM. W3C DOM access is specified to resolve
// entities. // entities.
var span = window.document.createElement('span'); var span = window.document.createElement('span');
span.innerHTML = '&' + rp[0] + '; '; span.innerHTML = '&' + rp[0] + '; ';
ch = span.childNodes[0].nodeValue.charAt(0); ch = span.childNodes[0].nodeValue.charAt(0);
} }
ret += ch + rp[1]; ret += ch + rp[1];
} }
return ret; return ret;
} }
// Parses the given XML string with our custom, JavaScript XML parser. Written // Parses the given XML string with our custom, JavaScript XML parser. Written
// by Steffen Meschkat (mesch@google.com). // by Steffen Meschkat (mesch@google.com).
function xmlParse(xml) { function xmlParse(xml) {
Timer.start('xmlparse'); Timer.start('xmlparse');
var regex_empty = /\/$/; var regex_empty = /\/$/;
// See also <http://www.w3.org/TR/REC-xml/#sec-common-syn> for // See also <http://www.w3.org/TR/REC-xml/#sec-common-syn> for
// allowed chars in a tag and attribute name. TODO(mesch): the // allowed chars in a tag and attribute name. TODO(mesch): the
// following is still not completely correct. // following is still not completely correct.
var regex_tagname = /^([\w:-]*)/; var regex_tagname = /^([\w:-]*)/;
var regex_attribute = /([\w:-]+)\s?=\s?('([^\']*)'|"([^\"]*)")/g; var regex_attribute = /([\w:-]+)\s?=\s?('([^\']*)'|"([^\"]*)")/g;
var xmldoc = new XDocument(); var xmldoc = new XDocument();
var root = xmldoc; var root = xmldoc;
// For the record: in Safari, we would create native DOM nodes, but // For the record: in Safari, we would create native DOM nodes, but
// in Opera that is not possible, because the DOM only allows HTML // in Opera that is not possible, because the DOM only allows HTML
// element nodes to be created, so we have to do our own DOM nodes. // element nodes to be created, so we have to do our own DOM nodes.
// xmldoc = document.implementation.createDocument('','',null); // xmldoc = document.implementation.createDocument('','',null);
// root = xmldoc; // .createDocumentFragment(); // root = xmldoc; // .createDocumentFragment();
// NOTE(mesch): using the DocumentFragment instead of the Document // NOTE(mesch): using the DocumentFragment instead of the Document
// crashes my Safari 1.2.4 (v125.12). // crashes my Safari 1.2.4 (v125.12).
var stack = []; var stack = [];
var parent = root; var parent = root;
stack.push(parent); stack.push(parent);
var x = stringSplit(xml, '<'); var x = stringSplit(xml, '<');
for (var i = 1; i < x.length; ++i) { for (var i = 1; i < x.length; ++i) {
var xx = stringSplit(x[i], '>'); var xx = stringSplit(x[i], '>');
var tag = xx[0]; var tag = xx[0];
var text = xmlResolveEntities(xx[1] || ''); var text = xmlResolveEntities(xx[1] || '');
if (tag.charAt(0) == '/') { if (tag.charAt(0) == '/') {
stack.pop(); stack.pop();
parent = stack[stack.length-1]; parent = stack[stack.length-1];
} else if (tag.charAt(0) == '?') { } else if (tag.charAt(0) == '?') {
// Ignore XML declaration and processing instructions // Ignore XML declaration and processing instructions
} else if (tag.charAt(0) == '!') { } else if (tag.charAt(0) == '!') {
// Ignore notation and comments // Ignore notation and comments
} else { } else {
var empty = tag.match(regex_empty); var empty = tag.match(regex_empty);
var tagname = regex_tagname.exec(tag)[1]; var tagname = regex_tagname.exec(tag)[1];
var node = xmldoc.createElement(tagname); var node = xmldoc.createElement(tagname);
var att; var att;
while (att = regex_attribute.exec(tag)) { while (att = regex_attribute.exec(tag)) {
var val = xmlResolveEntities(att[3] || att[4] || ''); var val = xmlResolveEntities(att[3] || att[4] || '');
node.setAttribute(att[1], val); node.setAttribute(att[1], val);
} }
if (empty) { if (empty) {
parent.appendChild(node); parent.appendChild(node);
} else { } else {
parent.appendChild(node); parent.appendChild(node);
parent = node; parent = node;
stack.push(node); stack.push(node);
} }
} }
if (text && parent != root) { if (text && parent != root) {
parent.appendChild(xmldoc.createTextNode(text)); parent.appendChild(xmldoc.createTextNode(text));
} }
} }
Timer.end('xmlparse'); Timer.end('xmlparse');
return root; return root;
} }
// Our W3C DOM Node implementation. Note we call it XNode because we // Our W3C DOM Node implementation. Note we call it XNode because we
// can't define the identifier Node. We do this mostly for Opera, // can't define the identifier Node. We do this mostly for Opera,
// where we can't reuse the HTML DOM for parsing our own XML, and for // where we can't reuse the HTML DOM for parsing our own XML, and for
// Safari, where it is too expensive to have the template processor // Safari, where it is too expensive to have the template processor
// operate on native DOM nodes. // operate on native DOM nodes.
function XNode(type, name, value, owner) { function XNode(type, name, value, owner) {
this.attributes = []; this.attributes = [];
this.childNodes = []; this.childNodes = [];
XNode.init.call(this, type, name, value, owner); XNode.init.call(this, type, name, value, owner);
} }
// Don't call as method, use apply() or call(). // Don't call as method, use apply() or call().
XNode.init = function(type, name, value, owner) { XNode.init = function(type, name, value, owner) {
this.nodeType = type - 0; this.nodeType = type - 0;
this.nodeName = '' + name; this.nodeName = '' + name;
this.nodeValue = '' + value; this.nodeValue = '' + value;
this.ownerDocument = owner; this.ownerDocument = owner;
this.firstChild = null; this.firstChild = null;
this.lastChild = null; this.lastChild = null;
this.nextSibling = null; this.nextSibling = null;
this.previousSibling = null; this.previousSibling = null;
this.parentNode = null; this.parentNode = null;
} }
XNode.unused_ = []; XNode.unused_ = [];
XNode.recycle = function(node) { XNode.recycle = function(node) {
if (!node) { if (!node) {
return; return;
} }
if (node.constructor == XDocument) { if (node.constructor == XDocument) {
XNode.recycle(node.documentElement); XNode.recycle(node.documentElement);
return; return;
} }
if (node.constructor != this) { if (node.constructor != this) {
return; return;
} }
XNode.unused_.push(node); XNode.unused_.push(node);
for (var a = 0; a < node.attributes.length; ++a) { for (var a = 0; a < node.attributes.length; ++a) {
XNode.recycle(node.attributes[a]); XNode.recycle(node.attributes[a]);
} }
for (var c = 0; c < node.childNodes.length; ++c) { for (var c = 0; c < node.childNodes.length; ++c) {
XNode.recycle(node.childNodes[c]); XNode.recycle(node.childNodes[c]);
} }
node.attributes.length = 0; node.attributes.length = 0;
node.childNodes.length = 0; node.childNodes.length = 0;
XNode.init.call(node, 0, '', '', null); XNode.init.call(node, 0, '', '', null);
} }
XNode.create = function(type, name, value, owner) { XNode.create = function(type, name, value, owner) {
if (XNode.unused_.length > 0) { if (XNode.unused_.length > 0) {
var node = XNode.unused_.pop(); var node = XNode.unused_.pop();
XNode.init.call(node, type, name, value, owner); XNode.init.call(node, type, name, value, owner);
return node; return node;
} else { } else {
return new XNode(type, name, value, owner); return new XNode(type, name, value, owner);
} }
} }
XNode.prototype.appendChild = function(node) { XNode.prototype.appendChild = function(node) {
// firstChild // firstChild
if (this.childNodes.length == 0) { if (this.childNodes.length == 0) {
this.firstChild = node; this.firstChild = node;
} }
// previousSibling // previousSibling
node.previousSibling = this.lastChild; node.previousSibling = this.lastChild;
// nextSibling // nextSibling
node.nextSibling = null; node.nextSibling = null;
if (this.lastChild) { if (this.lastChild) {
this.lastChild.nextSibling = node; this.lastChild.nextSibling = node;
} }
// parentNode // parentNode
node.parentNode = this; node.parentNode = this;
// lastChild // lastChild
this.lastChild = node; this.lastChild = node;
// childNodes // childNodes
this.childNodes.push(node); this.childNodes.push(node);
} }
XNode.prototype.replaceChild = function(newNode, oldNode) { XNode.prototype.replaceChild = function(newNode, oldNode) {
if (oldNode == newNode) { if (oldNode == newNode) {
return; return;
} }
for (var i = 0; i < this.childNodes.length; ++i) { for (var i = 0; i < this.childNodes.length; ++i) {
if (this.childNodes[i] == oldNode) { if (this.childNodes[i] == oldNode) {
this.childNodes[i] = newNode; this.childNodes[i] = newNode;
var p = oldNode.parentNode; var p = oldNode.parentNode;
oldNode.parentNode = null; oldNode.parentNode = null;
newNode.parentNode = p; newNode.parentNode = p;
p = oldNode.previousSibling; p = oldNode.previousSibling;
oldNode.previousSibling = null; oldNode.previousSibling = null;
newNode.previousSibling = p; newNode.previousSibling = p;
if (newNode.previousSibling) { if (newNode.previousSibling) {
newNode.previousSibling.nextSibling = newNode; newNode.previousSibling.nextSibling = newNode;
} }
p = oldNode.nextSibling; p = oldNode.nextSibling;
oldNode.nextSibling = null; oldNode.nextSibling = null;
newNode.nextSibling = p; newNode.nextSibling = p;
if (newNode.nextSibling) { if (newNode.nextSibling) {
newNode.nextSibling.previousSibling = newNode; newNode.nextSibling.previousSibling = newNode;
} }
if (this.firstChild == oldNode) { if (this.firstChild == oldNode) {
this.firstChild = newNode; this.firstChild = newNode;
} }
if (this.lastChild == oldNode) { if (this.lastChild == oldNode) {
this.lastChild = newNode; this.lastChild = newNode;
} }
break; break;
} }
} }
} }
XNode.prototype.insertBefore = function(newNode, oldNode) { XNode.prototype.insertBefore = function(newNode, oldNode) {
if (oldNode == newNode) { if (oldNode == newNode) {
return; return;
} }
if (oldNode.parentNode != this) { if (oldNode.parentNode != this) {
return; return;
} }
if (newNode.parentNode) { if (newNode.parentNode) {
newNode.parentNode.removeChild(newNode); newNode.parentNode.removeChild(newNode);
} }
var newChildren = []; var newChildren = [];
for (var i = 0; i < this.childNodes.length; ++i) { for (var i = 0; i < this.childNodes.length; ++i) {
var c = this.childNodes[i]; var c = this.childNodes[i];
if (c == oldNode) { if (c == oldNode) {
newChildren.push(newNode); newChildren.push(newNode);
newNode.parentNode = this; newNode.parentNode = this;
newNode.previousSibling = oldNode.previousSibling; newNode.previousSibling = oldNode.previousSibling;
oldNode.previousSibling = newNode; oldNode.previousSibling = newNode;
if (newNode.previousSibling) { if (newNode.previousSibling) {
newNode.previousSibling.nextSibling = newNode; newNode.previousSibling.nextSibling = newNode;
} }
newNode.nextSibling = oldNode; newNode.nextSibling = oldNode;
if (this.firstChild == oldNode) { if (this.firstChild == oldNode) {
this.firstChild = newNode; this.firstChild = newNode;
} }
} }
newChildren.push(c); newChildren.push(c);
} }
this.childNodes = newChildren; this.childNodes = newChildren;
} }
XNode.prototype.removeChild = function(node) { XNode.prototype.removeChild = function(node) {
var newChildren = []; var newChildren = [];
for (var i = 0; i < this.childNodes.length; ++i) { for (var i = 0; i < this.childNodes.length; ++i) {
var c = this.childNodes[i]; var c = this.childNodes[i];
if (c != node) { if (c != node) {
newChildren.push(c); newChildren.push(c);
} else { } else {
if (c.previousSibling) { if (c.previousSibling) {
c.previousSibling.nextSibling = c.nextSibling; c.previousSibling.nextSibling = c.nextSibling;
} }
if (c.nextSibling) { if (c.nextSibling) {
c.nextSibling.previousSibling = c.previousSibling; c.nextSibling.previousSibling = c.previousSibling;
} }
if (this.firstChild == c) { if (this.firstChild == c) {
this.firstChild = c.nextSibling; this.firstChild = c.nextSibling;
} }
if (this.lastChild == c) { if (this.lastChild == c) {
this.lastChild = c.previousSibling; this.lastChild = c.previousSibling;
} }
} }
} }
this.childNodes = newChildren; this.childNodes = newChildren;
} }
XNode.prototype.hasAttributes = function() { XNode.prototype.hasAttributes = function() {
return this.attributes.length > 0; return this.attributes.length > 0;
} }
XNode.prototype.setAttribute = function(name, value) { XNode.prototype.setAttribute = function(name, value) {
for (var i = 0; i < this.attributes.length; ++i) { for (var i = 0; i < this.attributes.length; ++i) {
if (this.attributes[i].nodeName == name) { if (this.attributes[i].nodeName == name) {
this.attributes[i].nodeValue = '' + value; this.attributes[i].nodeValue = '' + value;
return; return;
} }
} }
this.attributes.push(new XNode(DOM_ATTRIBUTE_NODE, name, value)); this.attributes.push(new XNode(DOM_ATTRIBUTE_NODE, name, value));
} }
XNode.prototype.getAttribute = function(name) { XNode.prototype.getAttribute = function(name) {
for (var i = 0; i < this.attributes.length; ++i) { for (var i = 0; i < this.attributes.length; ++i) {
if (this.attributes[i].nodeName == name) { if (this.attributes[i].nodeName == name) {
return this.attributes[i].nodeValue; return this.attributes[i].nodeValue;
} }
} }
return null; return null;
} }
XNode.prototype.removeAttribute = function(name) { XNode.prototype.removeAttribute = function(name) {
var a = []; var a = [];
for (var i = 0; i < this.attributes.length; ++i) { for (var i = 0; i < this.attributes.length; ++i) {
if (this.attributes[i].nodeName != name) { if (this.attributes[i].nodeName != name) {
a.push(this.attributes[i]); a.push(this.attributes[i]);
} }
} }
this.attributes = a; this.attributes = a;
} }
function XDocument() { function XDocument() {
XNode.call(this, DOM_DOCUMENT_NODE, '#document', null, this); XNode.call(this, DOM_DOCUMENT_NODE, '#document', null, this);
this.documentElement = null; this.documentElement = null;
} }
XDocument.prototype = new XNode(DOM_DOCUMENT_NODE, '#document'); XDocument.prototype = new XNode(DOM_DOCUMENT_NODE, '#document');
XDocument.prototype.clear = function() { XDocument.prototype.clear = function() {
XNode.recycle(this.documentElement); XNode.recycle(this.documentElement);
this.documentElement = null; this.documentElement = null;
} }
XDocument.prototype.appendChild = function(node) { XDocument.prototype.appendChild = function(node) {
XNode.prototype.appendChild.call(this, node); XNode.prototype.appendChild.call(this, node);
this.documentElement = this.childNodes[0]; this.documentElement = this.childNodes[0];
} }
XDocument.prototype.createElement = function(name) { XDocument.prototype.createElement = function(name) {
return XNode.create(DOM_ELEMENT_NODE, name, null, this); return XNode.create(DOM_ELEMENT_NODE, name, null, this);
} }
XDocument.prototype.createDocumentFragment = function() { XDocument.prototype.createDocumentFragment = function() {
return XNode.create(DOM_DOCUMENT_FRAGMENT_NODE, '#document-fragment', return XNode.create(DOM_DOCUMENT_FRAGMENT_NODE, '#document-fragment',
null, this); null, this);
} }
XDocument.prototype.createTextNode = function(value) { XDocument.prototype.createTextNode = function(value) {
return XNode.create(DOM_TEXT_NODE, '#text', value, this); return XNode.create(DOM_TEXT_NODE, '#text', value, this);
} }
XDocument.prototype.createAttribute = function(name) { XDocument.prototype.createAttribute = function(name) {
return XNode.create(DOM_ATTRIBUTE_NODE, name, null, this); return XNode.create(DOM_ATTRIBUTE_NODE, name, null, this);
} }
XDocument.prototype.createComment = function(data) { XDocument.prototype.createComment = function(data) {
return XNode.create(DOM_COMMENT_NODE, '#comment', data, this); return XNode.create(DOM_COMMENT_NODE, '#comment', data, this);
} }
XNode.prototype.getElementsByTagName = function(name, list) { XNode.prototype.getElementsByTagName = function(name, list) {
if (!list) { if (!list) {
list = []; list = [];
} }
if (this.nodeName == name) { if (this.nodeName == name) {
list.push(this); list.push(this);
} }
for (var i = 0; i < this.childNodes.length; ++i) { for (var i = 0; i < this.childNodes.length; ++i) {
this.childNodes[i].getElementsByTagName(name, list); this.childNodes[i].getElementsByTagName(name, list);
} }
return list; return list;
} }

View file

@ -1,255 +1,255 @@
// Copyright 2005 Google Inc. // Copyright 2005 Google Inc.
// All Rights Reserved // All Rights Reserved
// //
// Miscellania that support the ajaxslt implementation. // Miscellania that support the ajaxslt implementation.
// //
// Author: Steffen Meschkat <mesch@google.com> // Author: Steffen Meschkat <mesch@google.com>
// //
function el(i) { function el(i) {
return document.getElementById(i); return document.getElementById(i);
} }
function px(x) { function px(x) {
return x + 'px'; return x + 'px';
} }
// Split a string s at all occurrences of character c. This is like // Split a string s at all occurrences of character c. This is like
// the split() method of the string object, but IE omits empty // the split() method of the string object, but IE omits empty
// strings, which violates the invariant (s.split(x).join(x) == s). // strings, which violates the invariant (s.split(x).join(x) == s).
function stringSplit(s, c) { function stringSplit(s, c) {
var a = s.indexOf(c); var a = s.indexOf(c);
if (a == -1) { if (a == -1) {
return [ s ]; return [ s ];
} }
var parts = []; var parts = [];
parts.push(s.substr(0,a)); parts.push(s.substr(0,a));
while (a != -1) { while (a != -1) {
var a1 = s.indexOf(c, a + 1); var a1 = s.indexOf(c, a + 1);
if (a1 != -1) { if (a1 != -1) {
parts.push(s.substr(a + 1, a1 - a - 1)); parts.push(s.substr(a + 1, a1 - a - 1));
} else { } else {
parts.push(s.substr(a + 1)); parts.push(s.substr(a + 1));
} }
a = a1; a = a1;
} }
return parts; return parts;
} }
// Returns the text value if a node; for nodes without children this // Returns the text value if a node; for nodes without children this
// is the nodeValue, for nodes with children this is the concatenation // is the nodeValue, for nodes with children this is the concatenation
// of the value of all children. // of the value of all children.
function xmlValue(node) { function xmlValue(node) {
if (!node) { if (!node) {
return ''; return '';
} }
var ret = ''; var ret = '';
if (node.nodeType == DOM_TEXT_NODE || if (node.nodeType == DOM_TEXT_NODE ||
node.nodeType == DOM_CDATA_SECTION_NODE || node.nodeType == DOM_CDATA_SECTION_NODE ||
node.nodeType == DOM_ATTRIBUTE_NODE) { node.nodeType == DOM_ATTRIBUTE_NODE) {
ret += node.nodeValue; ret += node.nodeValue;
} else if (node.nodeType == DOM_ELEMENT_NODE || } else if (node.nodeType == DOM_ELEMENT_NODE ||
node.nodeType == DOM_DOCUMENT_NODE || node.nodeType == DOM_DOCUMENT_NODE ||
node.nodeType == DOM_DOCUMENT_FRAGMENT_NODE) { node.nodeType == DOM_DOCUMENT_FRAGMENT_NODE) {
for (var i = 0; i < node.childNodes.length; ++i) { for (var i = 0; i < node.childNodes.length; ++i) {
ret += arguments.callee(node.childNodes[i]); ret += arguments.callee(node.childNodes[i]);
} }
} }
return ret; return ret;
} }
// Returns the representation of a node as XML text. // Returns the representation of a node as XML text.
function xmlText(node) { function xmlText(node) {
var ret = ''; var ret = '';
if (node.nodeType == DOM_TEXT_NODE) { if (node.nodeType == DOM_TEXT_NODE) {
ret += xmlEscapeText(node.nodeValue); ret += xmlEscapeText(node.nodeValue);
} else if (node.nodeType == DOM_ELEMENT_NODE) { } else if (node.nodeType == DOM_ELEMENT_NODE) {
ret += '<' + node.nodeName; ret += '<' + node.nodeName;
for (var i = 0; i < node.attributes.length; ++i) { for (var i = 0; i < node.attributes.length; ++i) {
var a = node.attributes[i]; var a = node.attributes[i];
if (a && a.nodeName && a.nodeValue) { if (a && a.nodeName && a.nodeValue) {
ret += ' ' + a.nodeName; ret += ' ' + a.nodeName;
ret += '="' + xmlEscapeAttr(a.nodeValue) + '"'; ret += '="' + xmlEscapeAttr(a.nodeValue) + '"';
} }
} }
if (node.childNodes.length == 0) { if (node.childNodes.length == 0) {
ret += '/>'; ret += '/>';
} else { } else {
ret += '>'; ret += '>';
for (var i = 0; i < node.childNodes.length; ++i) { for (var i = 0; i < node.childNodes.length; ++i) {
ret += arguments.callee(node.childNodes[i]); ret += arguments.callee(node.childNodes[i]);
} }
ret += '</' + node.nodeName + '>'; ret += '</' + node.nodeName + '>';
} }
} else if (node.nodeType == DOM_DOCUMENT_NODE || } else if (node.nodeType == DOM_DOCUMENT_NODE ||
node.nodeType == DOM_DOCUMENT_FRAGMENT_NODE) { node.nodeType == DOM_DOCUMENT_FRAGMENT_NODE) {
for (var i = 0; i < node.childNodes.length; ++i) { for (var i = 0; i < node.childNodes.length; ++i) {
ret += arguments.callee(node.childNodes[i]); ret += arguments.callee(node.childNodes[i]);
} }
} }
return ret; return ret;
} }
// Applies the given function to each element of the array. // Applies the given function to each element of the array.
function mapExec(array, func) { function mapExec(array, func) {
for (var i = 0; i < array.length; ++i) { for (var i = 0; i < array.length; ++i) {
func(array[i]); func(array[i]);
} }
} }
// Returns an array that contains the return value of the given // Returns an array that contains the return value of the given
// function applied to every element of the input array. // function applied to every element of the input array.
function mapExpr(array, func) { function mapExpr(array, func) {
var ret = []; var ret = [];
for (var i = 0; i < array.length; ++i) { for (var i = 0; i < array.length; ++i) {
ret.push(func(array[i])); ret.push(func(array[i]));
} }
return ret; return ret;
}; };
// Reverses the given array in place. // Reverses the given array in place.
function reverseInplace(array) { function reverseInplace(array) {
for (var i = 0; i < array.length / 2; ++i) { for (var i = 0; i < array.length / 2; ++i) {
var h = array[i]; var h = array[i];
var ii = array.length - i - 1; var ii = array.length - i - 1;
array[i] = array[ii]; array[i] = array[ii];
array[ii] = h; array[ii] = h;
} }
} }
// Shallow-copies an array. // Shallow-copies an array.
function copyArray(dst, src) { function copyArray(dst, src) {
for (var i = 0; i < src.length; ++i) { for (var i = 0; i < src.length; ++i) {
dst.push(src[i]); dst.push(src[i]);
} }
} }
function assert(b) { function assert(b) {
if (!b) { if (!b) {
throw 'assertion failed'; throw 'assertion failed';
} }
} }
// Based on // Based on
// <http://www.w3.org/TR/2000/REC-DOM-Level-2-Core-20001113/core.html#ID-1950641247> // <http://www.w3.org/TR/2000/REC-DOM-Level-2-Core-20001113/core.html#ID-1950641247>
var DOM_ELEMENT_NODE = 1; var DOM_ELEMENT_NODE = 1;
var DOM_ATTRIBUTE_NODE = 2; var DOM_ATTRIBUTE_NODE = 2;
var DOM_TEXT_NODE = 3; var DOM_TEXT_NODE = 3;
var DOM_CDATA_SECTION_NODE = 4; var DOM_CDATA_SECTION_NODE = 4;
var DOM_ENTITY_REFERENCE_NODE = 5; var DOM_ENTITY_REFERENCE_NODE = 5;
var DOM_ENTITY_NODE = 6; var DOM_ENTITY_NODE = 6;
var DOM_PROCESSING_INSTRUCTION_NODE = 7; var DOM_PROCESSING_INSTRUCTION_NODE = 7;
var DOM_COMMENT_NODE = 8; var DOM_COMMENT_NODE = 8;
var DOM_DOCUMENT_NODE = 9; var DOM_DOCUMENT_NODE = 9;
var DOM_DOCUMENT_TYPE_NODE = 10; var DOM_DOCUMENT_TYPE_NODE = 10;
var DOM_DOCUMENT_FRAGMENT_NODE = 11; var DOM_DOCUMENT_FRAGMENT_NODE = 11;
var DOM_NOTATION_NODE = 12; var DOM_NOTATION_NODE = 12;
var xpathdebug = false; // trace xpath parsing var xpathdebug = false; // trace xpath parsing
var xsltdebug = false; // trace xslt processing var xsltdebug = false; // trace xslt processing
// Escape XML special markup chracters: tag delimiter < > and entity // Escape XML special markup chracters: tag delimiter < > and entity
// reference start delimiter &. The escaped string can be used in XML // reference start delimiter &. The escaped string can be used in XML
// text portions (i.e. between tags). // text portions (i.e. between tags).
function xmlEscapeText(s) { function xmlEscapeText(s) {
return s.replace(/&/g, '&amp;').replace(/</g, '&lt;').replace(/>/g, '&gt;'); return s.replace(/&/g, '&amp;').replace(/</g, '&lt;').replace(/>/g, '&gt;');
} }
// Escape XML special markup characters: tag delimiter < > entity // Escape XML special markup characters: tag delimiter < > entity
// reference start delimiter & and quotes ". The escaped string can be // reference start delimiter & and quotes ". The escaped string can be
// used in double quoted XML attribute value portions (i.e. in // used in double quoted XML attribute value portions (i.e. in
// attributes within start tags). // attributes within start tags).
function xmlEscapeAttr(s) { function xmlEscapeAttr(s) {
return xmlEscapeText(s).replace(/\"/g, '&quot;'); return xmlEscapeText(s).replace(/\"/g, '&quot;');
} }
// Escape markup in XML text, but don't touch entity references. The // Escape markup in XML text, but don't touch entity references. The
// escaped string can be used as XML text (i.e. between tags). // escaped string can be used as XML text (i.e. between tags).
function xmlEscapeTags(s) { function xmlEscapeTags(s) {
return s.replace(/</g, '&lt;').replace(/>/g, '&gt;'); return s.replace(/</g, '&lt;').replace(/>/g, '&gt;');
} }
// An implementation of the debug log. // An implementation of the debug log.
var logging__ = false; var logging__ = false;
function Log() {}; function Log() {};
Log.lines = []; Log.lines = [];
Log.write = function(s) { Log.write = function(s) {
if (logging__) { if (logging__) {
this.lines.push(xmlEscapeText(s)); this.lines.push(xmlEscapeText(s));
this.show(); this.show();
} }
}; };
// Writes the given XML with every tag on a new line. // Writes the given XML with every tag on a new line.
Log.writeXML = function(xml) { Log.writeXML = function(xml) {
if (logging__) { if (logging__) {
var s0 = xml.replace(/</g, '\n<'); var s0 = xml.replace(/</g, '\n<');
var s1 = xmlEscapeText(s0); var s1 = xmlEscapeText(s0);
var s2 = s1.replace(/\s*\n(\s|\n)*/g, '<br/>'); var s2 = s1.replace(/\s*\n(\s|\n)*/g, '<br/>');
this.lines.push(s2); this.lines.push(s2);
this.show(); this.show();
} }
} }
// Writes without any escaping // Writes without any escaping
Log.writeRaw = function(s) { Log.writeRaw = function(s) {
if (logging__) { if (logging__) {
this.lines.push(s); this.lines.push(s);
this.show(); this.show();
} }
} }
Log.clear = function() { Log.clear = function() {
if (logging__) { if (logging__) {
var l = this.div(); var l = this.div();
l.innerHTML = ''; l.innerHTML = '';
this.lines = []; this.lines = [];
} }
} }
Log.show = function() { Log.show = function() {
var l = this.div(); var l = this.div();
l.innerHTML += this.lines.join('<br/>') + '<br/>'; l.innerHTML += this.lines.join('<br/>') + '<br/>';
this.lines = []; this.lines = [];
l.scrollTop = l.scrollHeight; l.scrollTop = l.scrollHeight;
} }
Log.div = function() { Log.div = function() {
var l = document.getElementById('log'); var l = document.getElementById('log');
if (!l) { if (!l) {
l = document.createElement('div'); l = document.createElement('div');
l.id = 'log'; l.id = 'log';
l.style.position = 'absolute'; l.style.position = 'absolute';
l.style.right = '5px'; l.style.right = '5px';
l.style.top = '5px'; l.style.top = '5px';
l.style.width = '250px'; l.style.width = '250px';
l.style.height = '150px'; l.style.height = '150px';
l.style.overflow = 'auto'; l.style.overflow = 'auto';
l.style.backgroundColor = '#f0f0f0'; l.style.backgroundColor = '#f0f0f0';
l.style.border = '1px solid gray'; l.style.border = '1px solid gray';
l.style.fontSize = '10px'; l.style.fontSize = '10px';
l.style.padding = '5px'; l.style.padding = '5px';
document.body.appendChild(l); document.body.appendChild(l);
} }
return l; return l;
} }
function Timer() {} function Timer() {}
Timer.start = function() {} Timer.start = function() {}
Timer.end = function() {} Timer.end = function() {}

File diff suppressed because it is too large Load diff