diff --git a/bin/evalserver b/bin/evalserver
index 4b25078..5fc6409 100755
--- a/bin/evalserver
+++ b/bin/evalserver
@@ -1,5 +1,6 @@
#!/home/ryan/perl5/perlbrew/perls/perl-5.14.1/bin/perl
+#use local::lib;
# Guess we're being activated inside bin/, so go up a directory.
BEGIN { if( not -e 'lib' and not -e 'etc' and -e 'bb3' ) { chdir ".."; } }
@@ -8,7 +9,7 @@ use lib "$FindBin::Bin/../lib";
use EvalServer;
use POSIX qw/setsid/;
-$ENV{PATH}="/usr/bin/:/bin/";
+$ENV{PATH}="/home/farnsworth/perl5/perlbrew/perls/perl-5.14.0/bin:/usr/bin/:/bin/";
# Only daemonize if we're asked to.
if( $ARGV[0] eq '-d' ) {
diff --git a/deps/env.js b/deps/env.js
index bb321b9..27d01f6 100644
--- a/deps/env.js
+++ b/deps/env.js
@@ -1,277 +1,1641 @@
/*
+ * Envjs core-env.1.2.13
* Pure JavaScript Browser Environment
- * By John Resig
- * Copyright 2008 John Resig, under the MIT License
+ * By John Resig and the Envjs Team
+ * Copyright 2008-2010 John Resig, under the MIT License
*/
+var Envjs = function(){
+ var i,
+ name,
+ override = function(){
+ for(i=0;i $cookies - see cookie.js <*/
-// read only boolean specifies whether the window has been closed
-var $closed = false;
-
-// a read/write string that specifies the default message that appears in the status line
-var $defaultStatus = "Done";
-
-// a read-only reference to the Document object belonging to this window
-/**> $document - See document.js <*/
-
-//IE only, refers to the most recent event object - this maybe be removed after review
-var $event = null;
-
-//A read-only array of window objects
-var $frames = [];
-
-// a read-only reference to the History object
-/**> $history - see location.js <**/
-
-// read-only properties that specify the height and width, in pixels
-var $innerHeight = 600, $innerWidth = 800;
-
-// a read-only reference to the Location object. the location object does expose read/write properties
-/**> $location - see location.js <**/
-
-// a read only property specifying the name of the window. Can be set when using open()
-// and may be used when specifying the target attribute of links
-var $name = 'Resig Env Browser';
-
-// a read-only reference to the Navigator object
-/**> $navigator - see navigator.js <**/
-
-// a read/write reference to the Window object that contained the script that called open() to
-//open this browser window. This property is valid only for top-level window objects.
-var $opener;
-
-// Read-only properties that specify the total height and width, in pixels, of the browser window.
-// These dimensions include the height and width of the menu bar, toolbars, scrollbars, window
-// borders and so on. These properties are not supported by IE and IE offers no alternative
-// properties;
-var $outerHeight = $innerHeight, $outerWidth = $innerWidth;
-
-// Read-only properties that specify the number of pixels that the current document has been scrolled
-//to the right and down. These are not supported by IE.
-var $pageXOffset = 0, $pageYOffset = 0;
-
-//A read-only reference to the Window object that contains this window or frame. If the window is
-// a top-level window, parent refers to the window itself. If this window is a frame, this property
-// refers to the window or frame that conatins it.
-var $parent;
-
-// a read-only refernce to the Screen object that specifies information about the screen:
-// the number of available pixels and the number of available colors.
-/**> $screen - see screen.js <**/
-
-// read only properties that specify the coordinates of the upper-left corner of the screen.
-var $screenX = 0, $screenY = 0;
-var $screenLeft = $screenX, $screenTop = $screenY;
-
-// a read-only refernce to this window itself.
-var $self;
-
-// a read/write string that specifies the current contents of the status line.
-var $status = '';
-
-// a read-only reference to the top-level window that contains this window. If this
-// window is a top-level window it is simply a refernce to itself. If this window
-// is a frame, the top property refers to the top-level window that contains the frame.
-var $top;
-
-// the window property is identical to the self property.
-var $window = $w;
-
-$debug("Initializing Window.");
-__extend__($w,{
- get closed(){return $closed;},
- get defaultStatus(){return $defaultStatus;},
- set defaultStatus(_defaultStatus){$defaultStatus = _defaultStatus;},
- //get document(){return $document;}, - see document.js
- get event(){return $event;},
- get frames(){return $frames;},
- //get history(){return $history;}, - see location.js
- get innerHeight(){return $innerHeight;},
- get innerWidth(){return $innerWidth;},
- get clientHeight(){return $innerHeight;},
- get clientWidth(){return $innerWidth;},
- //get location(){return $location;}, see location.js
- get name(){return $name;},
- //get navigator(){return $navigator;}, see navigator.js
- get opener(){return $opener;},
- get outerHeight(){return $outerHeight;},
- get outerWidth(){return $outerWidth;},
- get pageXOffest(){return $pageXOffset;},
- get pageYOffset(){return $pageYOffset;},
- get parent(){return $parent;},
- //get screen(){return $screen;}, see screen.js
- get screenLeft(){return $screenLeft;},
- get screenTop(){return $screenTop;},
- get screenX(){return $screenX;},
- get screenY(){return $screenY;},
- get self(){return $self;},
- get status(){return $status;},
- set status(_status){$status = _status;},
- get top(){return $top || $window;},
- get window(){return $window;}
-});
-
-$w.open = function(url, name, features, replace){
- //TODO
-};
-
-$w.close = function(){
- //TODO
-};
-
-/* Time related functions - see timer.js
-* - clearTimeout
-* - clearInterval
-* - setTimeout
-* - setInterval
-*/
+//eg "Gecko/20070309 Firefox/2.0.0.3"
+Envjs.appName = "Netscape";
+Envjs.version = "1.6";//?
+Envjs.revision = '';
/*
-* Events related functions - see event.js
-* - addEventListener
-* - attachEvent
-* - detachEvent
-* - removeEventListener
-*
-* These functions are identical to the Element equivalents.
-*/
+ * Envjs core-env.1.2.13
+ * Pure JavaScript Browser Environment
+ * By John Resig and the Envjs Team
+ * Copyright 2008-2010 John Resig, under the MIT License
+ */
-/*
-* UIEvents related functions - see uievent.js
-* - blur
-* - focus
-*
-* These functions are identical to the Element equivalents.
-*/
+//CLOSURE_START
+(function(){
-/* Dialog related functions - see dialog.js
-* - alert
-* - confirm
-* - prompt
-*/
-/* Screen related functions - see screen.js
-* - moveBy
-* - moveTo
-* - print
-* - resizeBy
-* - resizeTo
-* - scrollBy
-* - scrollTo
-*/
-/* CSS related functions - see css.js
-* - getComputedStyle
-*/
-/*
-* Shared utility methods
-*/
-// Helper method for extending one object with another.
+
+/**
+ * @author john resig
+ */
+// Helper method for extending one object with another.
function __extend__(a,b) {
- for ( var i in b ) {
- var g = b.__lookupGetter__(i), s = b.__lookupSetter__(i);
- if ( g || s ) {
- if ( g ) a.__defineGetter__(i, g);
- if ( s ) a.__defineSetter__(i, s);
- } else
- a[i] = b[i];
- } return a;
-};
-
+ for ( var i in b ) {
+ var g = b.__lookupGetter__(i), s = b.__lookupSetter__(i);
+ if ( g || s ) {
+ if ( g ) { a.__defineGetter__(i, g); }
+ if ( s ) { a.__defineSetter__(i, s); }
+ } else {
+ a[i] = b[i];
+ }
+ } return a;
+}
-// from ariel flesler http://flesler.blogspot.com/2008/11/fast-trim-function-for-javascript.html
-// this might be a good utility function to provide in the env.core
-// as in might be useful to the parser and other areas as well
-function trim( str ){
+/**
+ * @author ariel flesler
+ * http://flesler.blogspot.com/2008/11/fast-trim-function-for-javascript.html
+ * @param {Object} str
+ */
+function __trim__( str ){
return (str || "").replace( /^\s+|\s+$/g, "" );
-
-};
-/*function trim( str ){
- var start = -1,
- end = str.length;
- /*jsl:ignore*
- while( str.charCodeAt(--end) < 33 );
- while( str.charCodeAt(++start) < 33 );
- /*jsl:end*
- return str.slice( start, end + 1 );
-};*/
+}
+
+/**
+ * Writes message to system out
+ * @param {String} message
+ */
+Envjs.log = function(message){};
+
+/**
+ * Constants providing enumerated levels for logging in modules
+ */
+Envjs.DEBUG = 1;
+Envjs.INFO = 2;
+Envjs.WARN = 3;
+Envjs.ERROR = 3;
+Envjs.NONE = 3;
+
+/**
+ * Writes error info out to console
+ * @param {Error} e
+ */
+Envjs.lineSource = function(e){};
+
+
+/**
+ * TODO: used in ./event/eventtarget.js
+ * @param {Object} event
+ */
+Envjs.defaultEventBehaviors = {};
+
+
+/**
+ * describes which script src values will trigger Envjs to load
+ * the script like a browser would
+ */
+Envjs.scriptTypes = {
+ "text/javascript" :false,
+ "text/envjs" :true
+};
+
+/**
+ * will be called when loading a script throws an error
+ * @param {Object} script
+ * @param {Object} e
+ */
+Envjs.onScriptLoadError = function(script, e){
+ console.log('error loading script %s %s', script, e);
+};
+
+
+/**
+ * load and execute script tag text content
+ * @param {Object} script
+ */
+Envjs.loadInlineScript = function(script){
+ var tmpFile;
+ tmpFile = Envjs.writeToTempFile(script.text, 'js') ;
+ load(tmpFile);
+};
+
+/**
+ * Should evaluate script in some context
+ * @param {Object} context
+ * @param {Object} source
+ * @param {Object} name
+ */
+Envjs.eval = function(context, source, name){};
+
+
+/**
+ * Executes a script tag
+ * @param {Object} script
+ * @param {Object} parser
+ */
+Envjs.loadLocalScript = function(script){
+ //console.log("loading script %s", script);
+ var types,
+ src,
+ i,
+ base,
+ filename,
+ xhr;
+
+ if(script.type){
+ types = script.type.split(";");
+ for(i=0;i
+ * - Via an innerHTML parse of a
+ * - A modificiation of the 'src' attribute of an Image/HTMLImageElement
+ *
+ * NOTE: this is optional API. If this doesn't exist then the default
+ * 'loaded' event occurs.
+ *
+ * @param node {Object} the node
+ * @param node the src value
+ * @return 'true' to indicate the 'load' succeed, false otherwise
+ */
+Envjs.loadImage = function(node, src) {
+ return true;
+};
+
+
+/**
+ * A 'link' was requested by the document. Typically this occurs when:
+ * - During inital parse of a
+ * - Via an innerHTML parse of a
+ * - A modificiation of the 'href' attribute on a node in the tree
+ *
+ * @param node {Object} is the link node in question
+ * @param href {String} is the href.
+ *
+ * Return 'true' to indicate that the 'load' was successful, or false
+ * otherwise. The appropriate event is then triggered.
+ *
+ * NOTE: this is optional API. If this doesn't exist then the default
+ * 'loaded' event occurs
+ */
+Envjs.loadLink = function(node, href) {
+ return true;
+};
+
+(function(){
+
+
+/*
+ * cookie handling
+ * Private internal helper class used to save/retreive cookies
+ */
+
+/**
+ * Specifies the location of the cookie file
+ */
+Envjs.cookieFile = function(){
+ return 'file://'+Envjs.homedir+'/.cookies';
+};
+
+/**
+ * saves cookies to a local file
+ * @param {Object} htmldoc
+ */
+Envjs.saveCookies = function(){
+ var cookiejson = JSON.stringify(Envjs.cookies.peristent,null,'\t');
+ //console.log('persisting cookies %s', cookiejson);
+ Envjs.writeToFile(cookiejson, Envjs.cookieFile());
+};
+
+/**
+ * loads cookies from a local file
+ * @param {Object} htmldoc
+ */
+Envjs.loadCookies = function(){
+ var cookiejson,
+ js;
+ try{
+ cookiejson = Envjs.readFromFile(Envjs.cookieFile())
+ js = JSON.parse(cookiejson, null, '\t');
+ }catch(e){
+ //console.log('failed to load cookies %s', e);
+ js = {};
+ }
+ return js;
+};
+
+Envjs.cookies = {
+ persistent:{
+ //domain - key on domain name {
+ //path - key on path {
+ //name - key on name {
+ //value : cookie value
+ //other cookie properties
+ //}
+ //}
+ //}
+ //expire - provides a timestamp for expiring the cookie
+ //cookie - the cookie!
+ },
+ temporary:{//transient is a reserved word :(
+ //like above
+ }
+};
+
+var __cookies__;
+
+//HTMLDocument cookie
+Envjs.setCookie = function(url, cookie){
+ var i,
+ index,
+ name,
+ value,
+ properties = {},
+ attr,
+ attrs;
+ url = Envjs.urlsplit(url);
+ if(cookie)
+ attrs = cookie.split(";");
+ else
+ return;
+
+ //for now the strategy is to simply create a json object
+ //and post it to a file in the .cookies.js file. I hate parsing
+ //dates so I decided not to implement support for 'expires'
+ //(which is deprecated) and instead focus on the easier 'max-age'
+ //(which succeeds 'expires')
+ cookie = {};//keyword properties of the cookie
+ cookie['domain'] = url.hostname;
+ cookie['path'] = url.path||'/';
+ for(i=0;i -1){
+ name = __trim__(attrs[i].slice(0,index));
+ value = __trim__(attrs[i].slice(index+1));
+ if(name=='max-age'){
+ //we'll have to when to check these
+ //and garbage collect expired cookies
+ cookie[name] = parseInt(value, 10);
+ } else if( name == 'domain' ){
+ if(__domainValid__(url, value)){
+ cookie['domain'] = value;
+ }
+ } else if( name == 'path' ){
+ //not sure of any special logic for path
+ cookie['path'] = value;
+ } else {
+ //its not a cookie keyword so store it in our array of properties
+ //and we'll serialize individually in a moment
+ properties[name] = value;
+ }
+ }else{
+ if( attrs[i] == 'secure' ){
+ cookie[attrs[i]] = true;
+ }
+ }
+ }
+ if(!('max-age' in cookie)){
+ //it's a transient cookie so it only lasts as long as
+ //the window.location remains the same (ie in-memory cookie)
+ __mergeCookie__(Envjs.cookies.temporary, cookie, properties);
+ }else{
+ //the cookie is persistent
+ __mergeCookie__(Envjs.cookies.persistent, cookie, properties);
+ Envjs.saveCookies();
+ }
+};
+
+function __domainValid__(url, value){
+ var i,
+ domainParts = url.hostname.split('.').reverse(),
+ newDomainParts = value.split('.').reverse();
+ if(newDomainParts.length > 1){
+ for(i=0;i -1) {
+ for (name in cookies[domain][path]) {
+ // console.log('cookie domain path name %s', name);
+ cookieString +=
+ ((i++ > 0)?'; ':'') +
+ name + "=" +
+ cookies[domain][path][name].value;
+ }
+ }
+ }
+ }
+ }
+ return cookieString;
+};
+
+function __mergeCookie__(target, cookie, properties){
+ var name, now;
+ if(!target[cookie.domain]){
+ target[cookie.domain] = {};
+ }
+ if(!target[cookie.domain][cookie.path]){
+ target[cookie.domain][cookie.path] = {};
+ }
+ for(name in properties){
+ now = new Date().getTime();
+ target[cookie.domain][cookie.path][name] = {
+ "value":properties[name],
+ "secure":cookie.secure,
+ "max-age":cookie['max-age'],
+ "date-created":now,
+ "expiration":(cookie['max-age']===0) ?
+ 0 :
+ now + cookie['max-age']
+ };
+ //console.log('cookie is %o',target[cookie.domain][cookie.path][name]);
+ }
+};
+
+})();//end cookies
+/*
+ http://www.JSON.org/json2.js
+ 2008-07-15
+
+ Public Domain.
+
+ NO WARRANTY EXPRESSED OR IMPLIED. USE AT YOUR OWN RISK.
+
+ See http://www.JSON.org/js.html
+
+
+ This code should be minified before deployment.
+ See http://javascript.crockford.com/jsmin.html
+
+ USE YOUR OWN COPY. IT IS EXTREMELY UNWISE TO LOAD CODE FROM SERVERS YOU DO
+ NOT CONTROL.
+*/
+try{ JSON; }catch(e){
+JSON = function () {
+
+ function f(n) {
+ // Format integers to have at least two digits.
+ return n < 10 ? '0' + n : n;
+ }
+
+ Date.prototype.toJSON = function (key) {
+
+ return this.getUTCFullYear() + '-' +
+ f(this.getUTCMonth() + 1) + '-' +
+ f(this.getUTCDate()) + 'T' +
+ f(this.getUTCHours()) + ':' +
+ f(this.getUTCMinutes()) + ':' +
+ f(this.getUTCSeconds()) + 'Z';
+ };
+
+ String.prototype.toJSON = function (key) {
+ return String(this);
+ };
+ Number.prototype.toJSON =
+ Boolean.prototype.toJSON = function (key) {
+ return this.valueOf();
+ };
+
+ var cx = /[\u0000\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g,
+ escapeable = /[\\\"\x00-\x1f\x7f-\x9f\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g,
+ gap,
+ indent,
+ meta = { // table of character substitutions
+ '\b': '\\b',
+ '\t': '\\t',
+ '\n': '\\n',
+ '\f': '\\f',
+ '\r': '\\r',
+ '"' : '\\"',
+ '\\': '\\\\'
+ },
+ rep;
+
+
+ function quote(string) {
+
+ escapeable.lastIndex = 0;
+ return escapeable.test(string) ?
+ '"' + string.replace(escapeable, function (a) {
+ var c = meta[a];
+ if (typeof c === 'string') {
+ return c;
+ }
+ return '\\u' + ('0000' +
+ (+(a.charCodeAt(0))).toString(16)).slice(-4);
+ }) + '"' :
+ '"' + string + '"';
+ }
+
+
+ function str(key, holder) {
+
+ var i, // The loop counter.
+ k, // The member key.
+ v, // The member value.
+ length,
+ mind = gap,
+ partial,
+ value = holder[key];
+
+ if (value && typeof value === 'object' &&
+ typeof value.toJSON === 'function') {
+ value = value.toJSON(key);
+ }
+ if (typeof rep === 'function') {
+ value = rep.call(holder, key, value);
+ }
+
+ switch (typeof value) {
+ case 'string':
+ return quote(value);
+
+ case 'number':
+ return isFinite(value) ? String(value) : 'null';
+
+ case 'boolean':
+ case 'null':
+
+ return String(value);
+
+ case 'object':
+
+ if (!value) {
+ return 'null';
+ }
+ gap += indent;
+ partial = [];
+
+ if (typeof value.length === 'number' &&
+ !(value.propertyIsEnumerable('length'))) {
+
+ length = value.length;
+ for (i = 0; i < length; i += 1) {
+ partial[i] = str(i, value) || 'null';
+ }
+
+ v = partial.length === 0 ? '[]' :
+ gap ? '[\n' + gap +
+ partial.join(',\n' + gap) + '\n' +
+ mind + ']' :
+ '[' + partial.join(',') + ']';
+ gap = mind;
+ return v;
+ }
+
+ if (rep && typeof rep === 'object') {
+ length = rep.length;
+ for (i = 0; i < length; i += 1) {
+ k = rep[i];
+ if (typeof k === 'string') {
+ v = str(k, value);
+ if (v) {
+ partial.push(quote(k) + (gap ? ': ' : ':') + v);
+ }
+ }
+ }
+ } else {
+
+ for (k in value) {
+ if (Object.hasOwnProperty.call(value, k)) {
+ v = str(k, value);
+ if (v) {
+ partial.push(quote(k) + (gap ? ': ' : ':') + v);
+ }
+ }
+ }
+ }
+
+ v = partial.length === 0 ? '{}' :
+ gap ? '{\n' + gap + partial.join(',\n' + gap) + '\n' +
+ mind + '}' : '{' + partial.join(',') + '}';
+ gap = mind;
+ return v;
+ }
+ }
+
+ return {
+ stringify: function (value, replacer, space) {
+
+ var i;
+ gap = '';
+ indent = '';
+
+ if (typeof space === 'number') {
+ for (i = 0; i < space; i += 1) {
+ indent += ' ';
+ }
+
+ } else if (typeof space === 'string') {
+ indent = space;
+ }
+
+ rep = replacer;
+ if (replacer && typeof replacer !== 'function' &&
+ (typeof replacer !== 'object' ||
+ typeof replacer.length !== 'number')) {
+ throw new Error('JSON.stringify');
+ }
+
+ return str('', {'': value});
+ },
+
+
+ parse: function (text, reviver) {
+ var j;
+ function walk(holder, key) {
+ var k, v, value = holder[key];
+ if (value && typeof value === 'object') {
+ for (k in value) {
+ if (Object.hasOwnProperty.call(value, k)) {
+ v = walk(value, k);
+ if (v !== undefined) {
+ value[k] = v;
+ } else {
+ delete value[k];
+ }
+ }
+ }
+ }
+ return reviver.call(holder, key, value);
+ }
+
+ cx.lastIndex = 0;
+ if (cx.test(text)) {
+ text = text.replace(cx, function (a) {
+ return '\\u' + ('0000' +
+ (+(a.charCodeAt(0))).toString(16)).slice(-4);
+ });
+ }
+
+
+ if (/^[\],:{}\s]*$/.
+test(text.replace(/\\(?:["\\\/bfnrt]|u[0-9a-fA-F]{4})/g, '@').
+replace(/"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g, ']').
+replace(/(?:^|:|,)(?:\s*\[)+/g, ''))) {
+
+ j = eval('(' + text + ')');
+
+ return typeof reviver === 'function' ?
+ walk({'': j}, '') : j;
+ }
+
+ throw new SyntaxError('JSON.parse');
+ }
+ };
+}();
+
+}
+
+/**
+ * synchronizes thread modifications
+ * @param {Function} fn
+ */
+Envjs.sync = function(fn){};
+
+/**
+ * sleep thread for specified duration
+ * @param {Object} millseconds
+ */
+Envjs.sleep = function(millseconds){};
+
+/**
+ * Interval to wait on event loop when nothing is happening
+ */
+Envjs.WAIT_INTERVAL = 20;//milliseconds
+
+/*
+ * Copyright (c) 2010 Nick Galbreath
+ * http://code.google.com/p/stringencoders/source/browse/#svn/trunk/javascript
+ *
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use,
+ * copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following
+ * conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+/*
+ * url processing in the spirit of python's urlparse module
+ * see `pydoc urlparse` or
+ * http://docs.python.org/library/urlparse.html
+ *
+ * urlsplit: break apart a URL into components
+ * urlunsplit: reconsistute a URL from componets
+ * urljoin: join an absolute and another URL
+ * urldefrag: remove the fragment from a URL
+ *
+ * Take a look at the tests in urlparse-test.html
+ *
+ * On URL Normalization:
+ *
+ * urlsplit only does minor normalization the components Only scheme
+ * and hostname are lowercased urljoin does a bit more, normalizing
+ * paths with "." and "..".
+
+ * urlnormalize adds additional normalization
+ *
+ * * removes default port numbers
+ * http://abc.com:80/ -> http://abc.com/, etc
+ * * normalizes path
+ * http://abc.com -> http://abc.com/
+ * and other "." and ".." cleanups
+ * * if file, remove query and fragment
+ *
+ * It does not do:
+ * * normalizes escaped hex values
+ * http://abc.com/%7efoo -> http://abc.com/%7Efoo
+ * * normalize '+' <--> '%20'
+ *
+ * Differences with Python
+ *
+ * The javascript urlsplit returns a normal object with the following
+ * properties: scheme, netloc, hostname, port, path, query, fragment.
+ * All properties are read-write.
+ *
+ * In python, the resulting object is not a dict, but a specialized,
+ * read-only, and has alternative tuple interface (e.g. obj[0] ==
+ * obj.scheme). It's not clear why such a simple function requires
+ * a unique datastructure.
+ *
+ * urlunsplit in javascript takes an duck-typed object,
+ * { scheme: 'http', netloc: 'abc.com', ...}
+ * while in * python it takes a list-like object.
+ * ['http', 'abc.com'... ]
+ *
+ * For all functions, the javascript version use
+ * hostname+port if netloc is missing. In python
+ * hostname+port were always ignored.
+ *
+ * Similar functionality in different languages:
+ *
+ * http://php.net/manual/en/function.parse-url.php
+ * returns assocative array but cannot handle relative URL
+ *
+ * TODO: test allowfragments more
+ * TODO: test netloc missing, but hostname present
+ */
+
+var urlparse = {};
+
+// Unlike to be useful standalone
+//
+// NORMALIZE PATH with "../" and "./"
+// http://en.wikipedia.org/wiki/URL_normalization
+// http://tools.ietf.org/html/rfc3986#section-5.2.3
+//
+urlparse.normalizepath = function(path)
+{
+ if (!path || path === '/') {
+ return '/';
+ }
+
+ var parts = path.split('/');
+
+ var newparts = [];
+ // make sure path always starts with '/'
+ if (parts[0]) {
+ newparts.push('');
+ }
+
+ for (var i = 0; i < parts.length; ++i) {
+ if (parts[i] === '..') {
+ if (newparts.length > 1) {
+ newparts.pop();
+ } else {
+ newparts.push(parts[i]);
+ }
+ } else if (parts[i] != '.') {
+ newparts.push(parts[i]);
+ }
+ }
+
+ path = newparts.join('/');
+ if (!path) {
+ path = '/';
+ }
+ return path;
+};
+
+//
+// Does many of the normalizations that the stock
+// python urlsplit/urlunsplit/urljoin neglects
+//
+// Doesn't do hex-escape normalization on path or query
+// %7e -> %7E
+// Nor, '+' <--> %20 translation
+//
+urlparse.urlnormalize = function(url)
+{
+ var parts = urlparse.urlsplit(url);
+ switch (parts.scheme) {
+ case 'file':
+ // files can't have query strings
+ // and we don't bother with fragments
+ parts.query = '';
+ parts.fragment = '';
+ break;
+ case 'http':
+ case 'https':
+ // remove default port
+ if ((parts.scheme === 'http' && parts.port == 80) ||
+ (parts.scheme === 'https' && parts.port == 443)) {
+ parts.port = null;
+ // hostname is already lower case
+ parts.netloc = parts.hostname;
+ }
+ break;
+ default:
+ // if we don't have specific normalizations for this
+ // scheme, return the original url unmolested
+ return url;
+ }
+
+ // for [file|http|https]. Not sure about other schemes
+ parts.path = urlparse.normalizepath(parts.path);
+
+ return urlparse.urlunsplit(parts);
+};
+
+urlparse.urldefrag = function(url)
+{
+ var idx = url.indexOf('#');
+ if (idx == -1) {
+ return [ url, '' ];
+ } else {
+ return [ url.substr(0,idx), url.substr(idx+1) ];
+ }
+};
+
+urlparse.urlsplit = function(url, default_scheme, allow_fragments)
+{
+ var leftover;
+
+ if (typeof allow_fragments === 'undefined') {
+ allow_fragments = true;
+ }
+
+ // scheme (optional), host, port
+ var fullurl = /^([A-Za-z]+)?(:?\/\/)([0-9.\-A-Za-z]*)(?::(\d+))?(.*)$/;
+ // path, query, fragment
+ var parse_leftovers = /([^?#]*)?(?:\?([^#]*))?(?:#(.*))?$/;
+
+ var o = {};
+
+ var parts = url.match(fullurl);
+ if (parts) {
+ o.scheme = parts[1] || default_scheme || '';
+ o.hostname = parts[3].toLowerCase() || '';
+ o.port = parseInt(parts[4],10) || '';
+ // Probably should grab the netloc from regexp
+ // and then parse again for hostname/port
+
+ o.netloc = parts[3];
+ if (parts[4]) {
+ o.netloc += ':' + parts[4];
+ }
+
+ leftover = parts[5];
+ } else {
+ o.scheme = default_scheme || '';
+ o.netloc = '';
+ o.hostname = '';
+ leftover = url;
+ }
+ o.scheme = o.scheme.toLowerCase();
+
+ parts = leftover.match(parse_leftovers);
+
+ o.path = parts[1] || '';
+ o.query = parts[2] || '';
+
+ if (allow_fragments) {
+ o.fragment = parts[3] || '';
+ } else {
+ o.fragment = '';
+ }
+
+ return o;
+};
+
+urlparse.urlunsplit = function(o) {
+ var s = '';
+ if (o.scheme) {
+ s += o.scheme + '://';
+ }
+
+ if (o.netloc) {
+ if (s == '') {
+ s += '//';
+ }
+ s += o.netloc;
+ } else if (o.hostname) {
+ // extension. Python only uses netloc
+ if (s == '') {
+ s += '//';
+ }
+ s += o.hostname;
+ if (o.port) {
+ s += ':' + o.port;
+ }
+ }
+
+ if (o.path) {
+ s += o.path;
+ }
+
+ if (o.query) {
+ s += '?' + o.query;
+ }
+ if (o.fragment) {
+ s += '#' + o.fragment;
+ }
+ return s;
+};
+
+urlparse.urljoin = function(base, url, allow_fragments)
+{
+ if (typeof allow_fragments === 'undefined') {
+ allow_fragments = true;
+ }
+
+ var url_parts = urlparse.urlsplit(url);
+
+ // if url parts has a scheme (i.e. absolute)
+ // then nothing to do
+ if (url_parts.scheme) {
+ if (! allow_fragments) {
+ return url;
+ } else {
+ return urlparse.urldefrag(url)[0];
+ }
+ }
+ var base_parts = urlparse.urlsplit(base);
+
+ // copy base, only if not present
+ if (!base_parts.scheme) {
+ base_parts.scheme = url_parts.scheme;
+ }
+
+ // copy netloc, only if not present
+ if (!base_parts.netloc || !base_parts.hostname) {
+ base_parts.netloc = url_parts.netloc;
+ base_parts.hostname = url_parts.hostname;
+ base_parts.port = url_parts.port;
+ }
+
+ // paths
+ if (url_parts.path.length > 0) {
+ if (url_parts.path.charAt(0) == '/') {
+ base_parts.path = url_parts.path;
+ } else {
+ // relative path.. get rid of "current filename" and
+ // replace. Same as var parts =
+ // base_parts.path.split('/'); parts[parts.length-1] =
+ // url_parts.path; base_parts.path = parts.join('/');
+ var idx = base_parts.path.lastIndexOf('/');
+ if (idx == -1) {
+ base_parts.path = url_parts.path;
+ } else {
+ base_parts.path = base_parts.path.substr(0,idx) + '/' +
+ url_parts.path;
+ }
+ }
+ }
+
+ // clean up path
+ base_parts.path = urlparse.normalizepath(base_parts.path);
+
+ // copy query string
+ base_parts.query = url_parts.query;
+
+ // copy fragments
+ if (allow_fragments) {
+ base_parts.fragment = url_parts.fragment;
+ } else {
+ base_parts.fragment = '';
+ }
+
+ return urlparse.urlunsplit(base_parts);
+};
+
+/**
+ * getcwd - named after posix call of same name (see 'man 2 getcwd')
+ *
+ */
+Envjs.getcwd = function() {
+ return '.';
+};
+
+/**
+ * resolves location relative to doc location
+ *
+ * @param {Object} path Relative or absolute URL
+ * @param {Object} base (semi-optional) The base url used in resolving "path" above
+ */
+Envjs.uri = function(path, base) {
+ //console.log('constructing uri from path %s and base %s', path, base);
+
+ // Semi-common trick is to make an iframe with src='javascript:false'
+ // (or some equivalent). By returning '', the load is skipped
+ if (path.indexOf('javascript') === 0) {
+ return '';
+ }
+
+ // if path is absolute, then just normalize and return
+ if (path.match('^[a-zA-Z]+://')) {
+ return urlparse.urlnormalize(path);
+ }
+
+ // interesting special case, a few very large websites use
+ // '//foo/bar/' to mean 'http://foo/bar'
+ if (path.match('^//')) {
+ path = 'http:' + path;
+ }
+
+ // if base not passed in, try to get it from document
+ // Ideally I would like the caller to pass in document.baseURI to
+ // make this more self-sufficient and testable
+ if (!base && document) {
+ base = document.baseURI;
+ }
+
+ // about:blank doesn't count
+ if (base === 'about:blank'){
+ base = '';
+ }
+
+ // if base is still empty, then we are in QA mode loading local
+ // files. Get current working directory
+ if (!base) {
+ base = 'file://' + Envjs.getcwd() + '/';
+ }
+ // handles all cases if path is abosulte or relative to base
+ // 3rd arg is "false" --> remove fragments
+ var newurl = urlparse.urlnormalize(urlparse.urljoin(base, path, false));
+
+ return newurl;
+};
+
+
+
+/**
+ * Used in the XMLHttpRquest implementation to run a
+ * request in a seperate thread
+ * @param {Object} fn
+ */
+Envjs.runAsync = function(fn){};
+
+
+/**
+ * Used to write to a local file
+ * @param {Object} text
+ * @param {Object} url
+ */
+Envjs.writeToFile = function(text, url){};
+
+
+/**
+ * Used to write to a local file
+ * @param {Object} text
+ * @param {Object} suffix
+ */
+Envjs.writeToTempFile = function(text, suffix){};
+
+/**
+ * Used to read the contents of a local file
+ * @param {Object} url
+ */
+Envjs.readFromFile = function(url){};
+
+/**
+ * Used to delete a local file
+ * @param {Object} url
+ */
+Envjs.deleteFile = function(url){};
+
+/**
+ * establishes connection and calls responsehandler
+ * @param {Object} xhr
+ * @param {Object} responseHandler
+ * @param {Object} data
+ */
+Envjs.connection = function(xhr, responseHandler, data){};
+
+
+__extend__(Envjs, urlparse);
+
+/**
+ * Makes an object window-like by proxying object accessors
+ * @param {Object} scope
+ * @param {Object} parent
+ */
+Envjs.proxy = function(scope, parent, aliasList){};
+
+Envjs.javaEnabled = false;
+
+Envjs.homedir = '';
+Envjs.tmpdir = '';
+Envjs.os_name = '';
+Envjs.os_arch = '';
+Envjs.os_version = '';
+Envjs.lang = '';
+Envjs.platform = '';
+
+/**
+ *
+ * @param {Object} frameElement
+ * @param {Object} url
+ */
+Envjs.loadFrame = function(frame, url){
+ try {
+ if(frame.contentWindow){
+ //mark for garbage collection
+ frame.contentWindow = null;
+ }
+
+ //create a new scope for the window proxy
+ //platforms will need to override this function
+ //to make sure the scope is global-like
+ frame.contentWindow = (function(){return this;})();
+ new Window(frame.contentWindow, window);
+
+ //I dont think frames load asynchronously in firefox
+ //and I think the tests have verified this but for
+ //some reason I'm less than confident... Are there cases?
+ frame.contentDocument = frame.contentWindow.document;
+ frame.contentDocument.async = false;
+ if(url){
+ //console.log('envjs.loadFrame async %s', frame.contentDocument.async);
+ frame.contentWindow.location = url;
+ }
+ } catch(e) {
+ console.log("failed to load frame content: from %s %s", url, e);
+ }
+};
+
+
+// The following are in rhino/window.js
+// TODO: Envjs.unloadFrame
+// TODO: Envjs.proxy
+
+/**
+ * @author john resig & the envjs team
+ * @uri http://www.envjs.com/
+ * @copyright 2008-2010
+ * @license MIT
+ */
+//CLOSURE_END
+}());
+
+/**
+ * @author envjs team
+ */
+var Console,
+ console;
+
+/*
+ * Envjs console.1.2.13
+ * Pure JavaScript Browser Environment
+ * By John Resig and the Envjs Team
+ * Copyright 2008-2010 John Resig, under the MIT License
+ */
+
+//CLOSURE_START
+(function(){
+
+
+
+
+
+/**
+ * @author envjs team
+ * borrowed 99%-ish with love from firebug-lite
+ *
+ * http://wiki.commonjs.org/wiki/Console
+ */
+Console = function(module){
+ var $level,
+ $logger,
+ $null = function(){};
+
+
+ if(Envjs[module] && Envjs[module].loglevel){
+ $level = Envjs.module.loglevel;
+ $logger = {
+ log: function(level){
+ logFormatted(arguments, (module)+" ");
+ },
+ debug: $level>1 ? $null: function() {
+ logFormatted(arguments, (module)+" debug");
+ },
+ info: $level>2 ? $null:function(){
+ logFormatted(arguments, (module)+" info");
+ },
+ warn: $level>3 ? $null:function(){
+ logFormatted(arguments, (module)+" warning");
+ },
+ error: $level>4 ? $null:function(){
+ logFormatted(arguments, (module)+" error");
+ }
+ };
+ } else {
+ $logger = {
+ log: function(level){
+ logFormatted(arguments, "");
+ },
+ debug: $null,
+ info: $null,
+ warn: $null,
+ error: $null
+ };
+ }
+
+ return $logger;
+};
+
+console = new Console("console",1);
+
+function logFormatted(objects, className)
+{
+ var html = [];
+
+ var format = objects[0];
+ var objIndex = 0;
+
+ if (typeof(format) != "string")
+ {
+ format = "";
+ objIndex = -1;
+ }
+
+ var parts = parseFormat(format);
+ for (var i = 0; i < parts.length; ++i)
+ {
+ var part = parts[i];
+ if (part && typeof(part) == "object")
+ {
+ var object = objects[++objIndex];
+ part.appender(object, html);
+ }
+ else {
+ appendText(part, html);
+ }
+ }
+
+ for (var i = objIndex+1; i < objects.length; ++i)
+ {
+ appendText(" ", html);
+
+ var object = objects[i];
+ if (typeof(object) == "string") {
+ appendText(object, html);
+ } else {
+ appendObject(object, html);
+ }
+ }
+
+ Envjs.log(html.join(' '));
+}
+
+function parseFormat(format)
+{
+ var parts = [];
+
+ var reg = /((^%|[^\\]%)(\d+)?(\.)([a-zA-Z]))|((^%|[^\\]%)([a-zA-Z]))/;
+ var appenderMap = {s: appendText, d: appendInteger, i: appendInteger, f: appendFloat};
+
+ for (var m = reg.exec(format); m; m = reg.exec(format))
+ {
+ var type = m[8] ? m[8] : m[5];
+ var appender = type in appenderMap ? appenderMap[type] : appendObject;
+ var precision = m[3] ? parseInt(m[3]) : (m[4] == "." ? -1 : 0);
+
+ parts.push(format.substr(0, m[0][0] == "%" ? m.index : m.index+1));
+ parts.push({appender: appender, precision: precision});
+
+ format = format.substr(m.index+m[0].length);
+ }
+
+ parts.push(format);
+
+ return parts;
+}
+
+function escapeHTML(value)
+{
+ return value;
+}
+
+function objectToString(object)
+{
+ try
+ {
+ return object+"";
+ }
+ catch (exc)
+ {
+ return null;
+ }
+}
+
+// ********************************************************************************************
+
+function appendText(object, html)
+{
+ html.push(escapeHTML(objectToString(object)));
+}
+
+function appendNull(object, html)
+{
+ html.push(escapeHTML(objectToString(object)));
+}
+
+function appendString(object, html)
+{
+ html.push(escapeHTML(objectToString(object)));
+}
+
+function appendInteger(object, html)
+{
+ html.push(escapeHTML(objectToString(object)));
+}
+
+function appendFloat(object, html)
+{
+ html.push(escapeHTML(objectToString(object)));
+}
+
+function appendFunction(object, html)
+{
+ var reName = /function ?(.*?)\(/;
+ var m = reName.exec(objectToString(object));
+ var name = m ? m[1] : "function";
+ html.push(escapeHTML(name));
+}
+
+function appendObject(object, html)
+{
+ try
+ {
+ if (object == undefined) {
+ appendNull("undefined", html);
+ } else if (object == null) {
+ appendNull("null", html);
+ } else if (typeof object == "string") {
+ appendString(object, html);
+ } else if (typeof object == "number") {
+ appendInteger(object, html);
+ } else if (typeof object == "function") {
+ appendFunction(object, html);
+ } else if (object.nodeType == 1) {
+ appendSelector(object, html);
+ } else if (typeof object == "object") {
+ appendObjectFormatted(object, html);
+ } else {
+ appendText(object, html);
+ }
+ }
+ catch (exc)
+ {
+ }
+}
+
+function appendObjectFormatted(object, html)
+{
+ var text = objectToString(object);
+ var reObject = /\[object (.*?)\]/;
+
+ var m = reObject.exec(text);
+ html.push( m ? m[1] : text);
+}
+
+function appendSelector(object, html)
+{
+
+ html.push(escapeHTML(object.nodeName.toLowerCase()));
+ if (object.id) {
+ html.push(escapeHTML(object.id));
+ }
+ if (object.className) {
+ html.push(escapeHTML(object.className));
+ }
+}
+
+function appendNode(node, html)
+{
+ if (node.nodeType == 1)
+ {
+ html.push( node.nodeName.toLowerCase());
+
+ for (var i = 0; i < node.attributes.length; ++i)
+ {
+ var attr = node.attributes[i];
+ if (!attr.specified) {
+ continue;
+ }
+
+ html.push( attr.nodeName.toLowerCase(),escapeHTML(attr.nodeValue));
+ }
+
+ if (node.firstChild)
+ {
+ for (var child = node.firstChild; child; child = child.nextSibling) {
+ appendNode(child, html);
+ }
+
+ html.push( node.nodeName.toLowerCase());
+ }
+ }
+ else if (node.nodeType === 3)
+ {
+ html.push(escapeHTML(node.nodeValue));
+ }
+};
+
+/**
+ * @author john resig & the envjs team
+ * @uri http://www.envjs.com/
+ * @copyright 2008-2010
+ * @license MIT
+ */
+//CLOSURE_END
+}());
+/*
+ * Envjs dom.1.2.13
+ * Pure JavaScript Browser Environment
+ * By John Resig and the Envjs Team
+ * Copyright 2008-2010 John Resig, under the MIT License
+ *
+ * Parts of the implementation were originally written by:\
+ * and Jon van Noort (jon@webarcana.com.au) \
+ * and David Joham (djoham@yahoo.com)",\
+ * and Scott Severtson
+ *
+ * This file simply provides the global definitions we need to \
+ * be able to correctly implement to core browser DOM interfaces."
+ */
+
+var Attr,
+ CDATASection,
+ CharacterData,
+ Comment,
+ Document,
+ DocumentFragment,
+ DocumentType,
+ DOMException,
+ DOMImplementation,
+ Element,
+ Entity,
+ EntityReference,
+ NamedNodeMap,
+ Namespace,
+ Node,
+ NodeList,
+ Notation,
+ ProcessingInstruction,
+ Text,
+ Range,
+ XMLSerializer,
+ DOMParser;
+
+
+
+/*
+ * Envjs dom.1.2.13
+ * Pure JavaScript Browser Environment
+ * By John Resig and the Envjs Team
+ * Copyright 2008-2010 John Resig, under the MIT License
+ */
+
+//CLOSURE_START
+(function(){
+
+
+
+
+
+/**
+ * @author john resig
+ */
+// Helper method for extending one object with another.
+function __extend__(a,b) {
+ for ( var i in b ) {
+ var g = b.__lookupGetter__(i), s = b.__lookupSetter__(i);
+ if ( g || s ) {
+ if ( g ) { a.__defineGetter__(i, g); }
+ if ( s ) { a.__defineSetter__(i, s); }
+ } else {
+ a[i] = b[i];
+ }
+ } return a;
+}
+
+/**
+ * @author john resig
+ */
//from jQuery
function __setArray__( target, array ) {
- // Resetting the length to 0, then using the native Array push
- // is a super-fast way to populate an object with array-like properties
- target.length = 0;
- Array.prototype.push.apply( target, array );
-};
+ // Resetting the length to 0, then using the native Array push
+ // is a super-fast way to populate an object with array-like properties
+ target.length = 0;
+ Array.prototype.push.apply( target, array );
+}
-
-$debug("Defining NodeList");
-/*
-* NodeList - DOM Level 2
-*/
/**
- * @class DOMNodeList - provides the abstraction of an ordered collection of nodes
+ * @class NodeList -
+ * provides the abstraction of an ordered collection of nodes
*
- * @author Jon van Noort (jon@webarcana.com.au)
- *
- * @param ownerDocument : DOMDocument - the ownerDocument
- * @param parentNode : DOMNode - the node that the DOMNodeList is attached to (or null)
+ * @param ownerDocument : Document - the ownerDocument
+ * @param parentNode : Node - the node that the NodeList is attached to (or null)
*/
-var DOMNodeList = function(ownerDocument, parentNode) {
+NodeList = function(ownerDocument, parentNode) {
this.length = 0;
this.parentNode = parentNode;
this.ownerDocument = ownerDocument;
-
this._readonly = false;
-
__setArray__(this, []);
};
-__extend__(DOMNodeList.prototype, {
+
+__extend__(NodeList.prototype, {
item : function(index) {
var ret = null;
- //$log("NodeList item("+index+") = " + this[index]);
- if ((index >= 0) && (index < this.length)) { // bounds check
- ret = this[index]; // return selected Node
+ if ((index >= 0) && (index < this.length)) {
+ // bounds check
+ ret = this[index];
}
-
- return ret; // if the index is out of bounds, default value null is returned
+ // if the index is out of bounds, default value null is returned
+ return ret;
},
get xml() {
- var ret = "";
-
+ var ret = "",
+ i;
+
// create string containing the concatenation of the string values of each child
- for (var i=0; i < this.length; i++) {
+ for (i=0; i < this.length; i++) {
if(this[i]){
- if(this[i].nodeType == DOMNode.TEXT_NODE && i>0 && this[i-1].nodeType == DOMNode.TEXT_NODE){
+ if(this[i].nodeType == Node.TEXT_NODE && i>0 &&
+ this[i-1].nodeType == Node.TEXT_NODE){
//add a single space between adjacent text nodes
ret += " "+this[i].xml;
}else{
@@ -279,60 +1643,60 @@ __extend__(DOMNodeList.prototype, {
}
}
}
-
return ret;
},
toArray: function () {
- var children = [];
- for ( var i=0; i < this.length; i++) {
- children.push (this[i]);
+ var children = [],
+ i;
+ for ( i=0; i < this.length; i++) {
+ children.push (this[i]);
}
return children;
},
toString: function(){
- return "[ "+(this.length > 0?Array.prototype.join.apply(this, [", "]):"Empty NodeList")+" ]";
+ return "[object NodeList]";
}
});
/**
- * @method DOMNodeList._findItemIndex - find the item index of the node with the specified internal id
+ * @method __findItemIndex__
+ * find the item index of the node
* @author Jon van Noort (jon@webarcana.com.au)
- * @param id : int - unique internal id
+ * @param node : Node
* @return : int
*/
-var __findItemIndex__ = function (nodelist, id) {
- var ret = -1;
-
- // test that id is valid
- if (id > -1) {
- for (var i=0; i= 0) && (refChildIndex < nodelist.length)) { // bounds check
-
- if (newChild.nodeType == DOMNode.DOCUMENT_FRAGMENT_NODE) { // node is a DocumentFragment
+ if ((refChildIndex >= 0) && (refChildIndex <= nodelist.length)) {
+ // bounds check
+ if (newChild.nodeType == Node.DOCUMENT_FRAGMENT_NODE) {
+ // node is a DocumentFragment
// append the children of DocumentFragment
- Array.prototype.splice.apply(nodelist,[refChildIndex, 0].concat(newChild.childNodes.toArray()));
+ Array.prototype.splice.apply(nodelist,
+ [refChildIndex, 0].concat(newChild.childNodes.toArray()));
}
else {
// append the newChild
@@ -342,517 +1706,201 @@ var __insertBefore__ = function(nodelist, newChild, refChildIndex) {
};
/**
- * @method DOMNodeList._replaceChild - replace the specified Node in the NodeList at the specified index
- * Used by DOMNode.replaceChild(). Note: DOMNode.replaceChild() is responsible for Node Pointer surgery
- * DOMNodeList._replaceChild() simply modifies the internal data structure (Array).
+ * @method __replaceChild__
+ * replace the specified Node in the NodeList at the specified index
+ * Used by Node.replaceChild(). Note: Node.replaceChild() is responsible
+ * for Node Pointer surgery __replaceChild__ simply modifies the internal
+ * data structure (Array).
*
- * @author Jon van Noort (jon@webarcana.com.au)
- * @param newChild : DOMNode - the Node to be inserted
+ * @param newChild : Node - the Node to be inserted
* @param refChildIndex : int - the array index to hold the Node
*/
var __replaceChild__ = function(nodelist, newChild, refChildIndex) {
var ret = null;
-
- if ((refChildIndex >= 0) && (refChildIndex < nodelist.length)) { // bounds check
- ret = nodelist[refChildIndex]; // preserve old child for return
-
- if (newChild.nodeType == DOMNode.DOCUMENT_FRAGMENT_NODE) { // node is a DocumentFragment
+
+ // bounds check
+ if ((refChildIndex >= 0) && (refChildIndex < nodelist.length)) {
+ // preserve old child for return
+ ret = nodelist[refChildIndex];
+
+ if (newChild.nodeType == Node.DOCUMENT_FRAGMENT_NODE) {
+ // node is a DocumentFragment
// get array containing children prior to refChild
- Array.prototype.splice.apply(nodelist,[refChildIndex, 1].concat(newChild.childNodes.toArray()));
+ Array.prototype.splice.apply(nodelist,
+ [refChildIndex, 1].concat(newChild.childNodes.toArray()));
}
else {
- // simply replace node in array (links between Nodes are made at higher level)
+ // simply replace node in array (links between Nodes are
+ // made at higher level)
nodelist[refChildIndex] = newChild;
}
}
-
- return ret; // return replaced node
+ // return replaced node
+ return ret;
};
/**
- * @method DOMNodeList._removeChild - remove the specified Node in the NodeList at the specified index
- * Used by DOMNode.removeChild(). Note: DOMNode.removeChild() is responsible for Node Pointer surgery
- * DOMNodeList._replaceChild() simply modifies the internal data structure (Array).
- *
- * @author Jon van Noort (jon@webarcana.com.au)
+ * @method __removeChild__
+ * remove the specified Node in the NodeList at the specified index
+ * Used by Node.removeChild(). Note: Node.removeChild() is responsible
+ * for Node Pointer surgery __removeChild__ simply modifies the internal
+ * data structure (Array).
* @param refChildIndex : int - the array index holding the Node to be removed
*/
var __removeChild__ = function(nodelist, refChildIndex) {
var ret = null;
-
- if (refChildIndex > -1) { // found it!
- ret = nodelist[refChildIndex]; // return removed node
-
+
+ if (refChildIndex > -1) {
+ // found it!
+ // return removed node
+ ret = nodelist[refChildIndex];
+
// rebuild array without removed child
Array.prototype.splice.apply(nodelist,[refChildIndex, 1]);
}
-
- return ret; // return removed node
+ // return removed node
+ return ret;
};
/**
- * @method DOMNodeList._appendChild - append the specified Node to the NodeList
- * Used by DOMNode.appendChild(). Note: DOMNode.appendChild() is responsible for Node Pointer surgery
- * DOMNodeList._appendChild() simply modifies the internal data structure (Array).
- *
- * @author Jon van Noort (jon@webarcana.com.au)
- * @param newChild : DOMNode - the Node to be inserted
+ * @method __appendChild__
+ * append the specified Node to the NodeList. Used by Node.appendChild().
+ * Note: Node.appendChild() is responsible for Node Pointer surgery
+ * __appendChild__ simply modifies the internal data structure (Array).
+ * @param newChild : Node - the Node to be inserted
*/
var __appendChild__ = function(nodelist, newChild) {
- if (newChild.nodeType == DOMNode.DOCUMENT_FRAGMENT_NODE) { // node is a DocumentFragment
+ if (newChild.nodeType == Node.DOCUMENT_FRAGMENT_NODE) {
+ // node is a DocumentFragment
// append the children of DocumentFragment
- Array.prototype.push.apply(nodelist, newChild.childNodes.toArray() );
+ Array.prototype.push.apply(nodelist, newChild.childNodes.toArray() );
} else {
// simply add node to array (links between Nodes are made at higher level)
Array.prototype.push.apply(nodelist, [newChild]);
}
-
+
};
/**
- * @method DOMNodeList._cloneNodes - Returns a NodeList containing clones of the Nodes in this NodeList
- *
- * @author Jon van Noort (jon@webarcana.com.au)
- * @param deep : boolean - If true, recursively clone the subtree under each of the nodes;
- * if false, clone only the nodes themselves (and their attributes, if it is an Element).
- * @param parentNode : DOMNode - the new parent of the cloned NodeList
- * @return : DOMNodeList - NodeList containing clones of the Nodes in this NodeList
+ * @method __cloneNodes__ -
+ * Returns a NodeList containing clones of the Nodes in this NodeList
+ * @param deep : boolean -
+ * If true, recursively clone the subtree under each of the nodes;
+ * if false, clone only the nodes themselves (and their attributes,
+ * if it is an Element).
+ * @param parentNode : Node - the new parent of the cloned NodeList
+ * @return : NodeList - NodeList containing clones of the Nodes in this NodeList
*/
var __cloneNodes__ = function(nodelist, deep, parentNode) {
- var cloneNodeList = new DOMNodeList(nodelist.ownerDocument, parentNode);
-
+ var cloneNodeList = new NodeList(nodelist.ownerDocument, parentNode);
+
// create list containing clones of each child
for (var i=0; i < nodelist.length; i++) {
__appendChild__(cloneNodeList, nodelist[i].cloneNode(deep));
}
-
+
return cloneNodeList;
};
-$w.NodeList = DOMNodeList;
-/**
- * @class DOMNamedNodeMap - used to represent collections of nodes that can be accessed by name
- * typically a set of Element attributes
- *
- * @extends DOMNodeList - note W3C spec says that this is not the case,
- * but we need an item() method identicle to DOMNodeList's, so why not?
- * @author Jon van Noort (jon@webarcana.com.au)
- * @param ownerDocument : DOMDocument - the ownerDocument
- * @param parentNode : DOMNode - the node that the DOMNamedNodeMap is attached to (or null)
- */
-var DOMNamedNodeMap = function(ownerDocument, parentNode) {
- //$log("\t\tcreating dom namednodemap");
- this.DOMNodeList = DOMNodeList;
- this.DOMNodeList(ownerDocument, parentNode);
- __setArray__(this, []);
-};
-DOMNamedNodeMap.prototype = new DOMNodeList;
-__extend__(DOMNamedNodeMap.prototype, {
- getNamedItem : function(name) {
- var ret = null;
-
- // test that Named Node exists
- var itemIndex = __findNamedItemIndex__(this, name);
-
- if (itemIndex > -1) { // found it!
- ret = this[itemIndex]; // return NamedNode
- }
-
- return ret; // if node is not found, default value null is returned
- },
- setNamedItem : function(arg) {
- // test for exceptions
- if (__ownerDocument__(this).implementation.errorChecking) {
- // throw Exception if arg was not created by this Document
- if (this.ownerDocument != arg.ownerDocument) {
- throw(new DOMException(DOMException.WRONG_DOCUMENT_ERR));
- }
-
- // throw Exception if DOMNamedNodeMap is readonly
- if (this._readonly || (this.parentNode && this.parentNode._readonly)) {
- throw(new DOMException(DOMException.NO_MODIFICATION_ALLOWED_ERR));
- }
-
- // throw Exception if arg is already an attribute of another Element object
- if (arg.ownerElement && (arg.ownerElement != this.parentNode)) {
- throw(new DOMException(DOMException.INUSE_ATTRIBUTE_ERR));
- }
- }
-
- // get item index
- var itemIndex = __findNamedItemIndex__(this, arg.name);
- var ret = null;
-
- if (itemIndex > -1) { // found it!
- ret = this[itemIndex]; // use existing Attribute
-
- // throw Exception if DOMAttr is readonly
- if (__ownerDocument__(this).implementation.errorChecking && ret._readonly) {
- throw(new DOMException(DOMException.NO_MODIFICATION_ALLOWED_ERR));
- } else {
- this[itemIndex] = arg; // over-write existing NamedNode
- this[arg.name] = arg;
- }
- } else {
- // add new NamedNode
- Array.prototype.push.apply(this, [arg]);
- this[arg.name] = arg;
- }
-
- arg.ownerElement = this.parentNode; // update ownerElement
-
- return ret; // return old node or null
- },
- removeNamedItem : function(name) {
- var ret = null;
- // test for exceptions
- // throw Exception if DOMNamedNodeMap is readonly
- if (__ownerDocument__(this).implementation.errorChecking &&
- (this._readonly || (this.parentNode && this.parentNode._readonly))) {
- throw(new DOMException(DOMException.NO_MODIFICATION_ALLOWED_ERR));
- }
-
- // get item index
- var itemIndex = __findNamedItemIndex__(this, name);
-
- // throw Exception if there is no node named name in this map
- if (__ownerDocument__(this).implementation.errorChecking && (itemIndex < 0)) {
- throw(new DOMException(DOMException.NOT_FOUND_ERR));
- }
-
- // get Node
- var oldNode = this[itemIndex];
- //this[oldNode.name] = undefined;
-
- // throw Exception if Node is readonly
- if (__ownerDocument__(this).implementation.errorChecking && oldNode._readonly) {
- throw(new DOMException(DOMException.NO_MODIFICATION_ALLOWED_ERR));
- }
-
- // return removed node
- return __removeChild__(this, itemIndex);
- },
- getNamedItemNS : function(namespaceURI, localName) {
- var ret = null;
-
- // test that Named Node exists
- var itemIndex = __findNamedItemNSIndex__(this, namespaceURI, localName);
-
- if (itemIndex > -1) { // found it!
- ret = this[itemIndex]; // return NamedNode
- }
-
- return ret; // if node is not found, default value null is returned
- },
- setNamedItemNS : function(arg) {
- // test for exceptions
- if (__ownerDocument__(this).implementation.errorChecking) {
- // throw Exception if DOMNamedNodeMap is readonly
- if (this._readonly || (this.parentNode && this.parentNode._readonly)) {
- throw(new DOMException(DOMException.NO_MODIFICATION_ALLOWED_ERR));
- }
-
- // throw Exception if arg was not created by this Document
- if (__ownerDocument__(this) != __ownerDocument__(arg)) {
- throw(new DOMException(DOMException.WRONG_DOCUMENT_ERR));
- }
-
- // throw Exception if arg is already an attribute of another Element object
- if (arg.ownerElement && (arg.ownerElement != this.parentNode)) {
- throw(new DOMException(DOMException.INUSE_ATTRIBUTE_ERR));
- }
- }
-
- // get item index
- var itemIndex = __findNamedItemNSIndex__(this, arg.namespaceURI, arg.localName);
- var ret = null;
-
- if (itemIndex > -1) { // found it!
- ret = this[itemIndex]; // use existing Attribute
- // throw Exception if DOMAttr is readonly
- if (__ownerDocument__(this).implementation.errorChecking && ret._readonly) {
- throw(new DOMException(DOMException.NO_MODIFICATION_ALLOWED_ERR));
- } else {
- this[itemIndex] = arg; // over-write existing NamedNode
- }
- }else {
- // add new NamedNode
- Array.prototype.push.apply(this, [arg]);
- }
- arg.ownerElement = this.parentNode;
-
-
- return ret; // return old node or null
- },
- removeNamedItemNS : function(namespaceURI, localName) {
- var ret = null;
-
- // test for exceptions
- // throw Exception if DOMNamedNodeMap is readonly
- if (__ownerDocument__(this).implementation.errorChecking && (this._readonly || (this.parentNode && this.parentNode._readonly))) {
- throw(new DOMException(DOMException.NO_MODIFICATION_ALLOWED_ERR));
- }
-
- // get item index
- var itemIndex = __findNamedItemNSIndex__(this, namespaceURI, localName);
-
- // throw Exception if there is no matching node in this map
- if (__ownerDocument__(this).implementation.errorChecking && (itemIndex < 0)) {
- throw(new DOMException(DOMException.NOT_FOUND_ERR));
- }
-
- // get Node
- var oldNode = this[itemIndex];
-
- // throw Exception if Node is readonly
- if (__ownerDocument__(this).implementation.errorChecking && oldNode._readonly) {
- throw(new DOMException(DOMException.NO_MODIFICATION_ALLOWED_ERR));
- }
-
- return __removeChild__(this, itemIndex); // return removed node
- },
- get xml() {
- var ret = "";
-
- // create string containing concatenation of all (but last) Attribute string values (separated by spaces)
- for (var i=0; i < this.length -1; i++) {
- ret += this[i].xml +" ";
- }
-
- // add last Attribute to string (without trailing space)
- if (this.length > 0) {
- ret += this[this.length -1].xml;
- }
-
- return ret;
- }
-
-});
-
-/**
- * @method DOMNamedNodeMap._findNamedItemIndex - find the item index of the node with the specified name
- *
- * @author Jon van Noort (jon@webarcana.com.au)
- * @param name : string - the name of the required node
- * @param isnsmap : if its a DOMNamespaceNodeMap
- * @return : int
- */
-var __findNamedItemIndex__ = function(namednodemap, name, isnsmap) {
- var ret = -1;
-
- // loop through all nodes
- for (var i=0; i -1) { // found it!
- ret = true; // return true
- }
+ //IMPORTANT: These must come last so rhino will not iterate parent
+ // properties before child properties. (qunit.equiv issue)
- return ret; // if node is not found, default value false is returned
-}
+ // The parent of this node. All nodes, except Document, DocumentFragment,
+ // and Attr may have a parent. However, if a node has just been created
+ // and not yet added to the tree, or if it has been removed from the tree,
+ // this is null
+ this.parentNode = null;
+ // The Document object associated with this node
+ this.ownerDocument = ownerDocument;
-/**
- * @method DOMNamedNodeMap._hasAttributeNS - Returns true if specified node exists
- *
- * @author Jon van Noort (jon@webarcana.com.au)
- * @param namespaceURI : string - the namespace URI of the required node
- * @param localName : string - the local name of the required node
- * @return : boolean
- */
-var __hasAttributeNS__ = function(namednodemap, namespaceURI, localName) {
- var ret = false;
-
- // test that Named Node exists
- var itemIndex = __findNamedItemNSIndex__(namednodemap, namespaceURI, localName);
-
- if (itemIndex > -1) { // found it!
- ret = true; // return true
- }
-
- return ret; // if node is not found, default value false is returned
-}
-
-/**
- * @method DOMNamedNodeMap._cloneNodes - Returns a NamedNodeMap containing clones of the Nodes in this NamedNodeMap
- *
- * @author Jon van Noort (jon@webarcana.com.au)
- * @param parentNode : DOMNode - the new parent of the cloned NodeList
- * @param isnsmap : bool - is this a DOMNamespaceNodeMap
- * @return : DOMNamedNodeMap - NamedNodeMap containing clones of the Nodes in this DOMNamedNodeMap
- */
-var __cloneNamedNodes__ = function(namednodemap, parentNode, isnsmap) {
- var cloneNamedNodeMap = isnsmap?
- new DOMNamespaceNodeMap(namednodemap.ownerDocument, parentNode):
- new DOMNamedNodeMap(namednodemap.ownerDocument, parentNode);
-
- // create list containing clones of all children
- for (var i=0; i < namednodemap.length; i++) {
- $debug("cloning node in named node map :" + namednodemap[i]);
- __appendChild__(cloneNamedNodeMap, namednodemap[i].cloneNode(false));
- }
-
- return cloneNamedNodeMap;
-};
-
-
-/**
- * @class DOMNamespaceNodeMap - used to represent collections of namespace nodes that can be accessed by name
- * typically a set of Element attributes
- *
- * @extends DOMNamedNodeMap
- *
- * @author Jon van Noort (jon@webarcana.com.au)
- *
- * @param ownerDocument : DOMDocument - the ownerDocument
- * @param parentNode : DOMNode - the node that the DOMNamespaceNodeMap is attached to (or null)
- */
-var DOMNamespaceNodeMap = function(ownerDocument, parentNode) {
- //$log("\t\t\tcreating dom namespacednodemap");
- this.DOMNamedNodeMap = DOMNamedNodeMap;
- this.DOMNamedNodeMap(ownerDocument, parentNode);
- __setArray__(this, []);
-};
-DOMNamespaceNodeMap.prototype = new DOMNamedNodeMap;
-__extend__(DOMNamespaceNodeMap.prototype, {
- get xml() {
- var ret = "";
-
- // identify namespaces declared local to this Element (ie, not inherited)
- for (var ind = 0; ind < this.length; ind++) {
- // if namespace declaration does not exist in the containing node's, parentNode's namespaces
- var ns = null;
- try {
- var ns = this.parentNode.parentNode._namespaces.
- getNamedItem(this[ind].localName);
- }
- catch (e) {
- //breaking to prevent default namespace being inserted into return value
- break;
- }
- if (!(ns && (""+ ns.nodeValue == ""+ this[ind].nodeValue))) {
- // display the namespace declaration
- ret += this[ind].xml +" ";
- }
- }
-
- return ret;
- }
-});
-$debug("Defining Node");
-/*
-* Node - DOM Level 2
-*/
-/**
- * @class DOMNode - The Node interface is the primary datatype for the entire Document Object Model.
- * It represents a single node in the document tree.
- * @author Jon van Noort (jon@webarcana.com.au), David Joham (djoham@yahoo.com) and Scott Severtson
- * @param ownerDocument : DOMDocument - The Document object associated with this node.
- */
-var DOMNode = function(ownerDocument) {
- if (ownerDocument) {
- this._id = ownerDocument._genId(); // generate unique internal id
- }
-
- this.namespaceURI = ""; // The namespace URI of this node (Level 2)
- this.prefix = ""; // The namespace prefix of this node (Level 2)
- this.localName = ""; // The localName of this node (Level 2)
-
- this.nodeName = ""; // The name of this node
- this.nodeValue = null; // The value of this node
- this.className = ""; // The CSS class name of this node.
-
- // The parent of this node. All nodes, except Document, DocumentFragment, and Attr may have a parent.
- // However, if a node has just been created and not yet added to the tree, or if it has been removed from the tree, this is null
- this.parentNode = null;
-
- // A NodeList that contains all children of this node. If there are no children, this is a NodeList containing no nodes.
- // The content of the returned NodeList is "live" in the sense that, for instance, changes to the children of the node object
- // that it was created from are immediately reflected in the nodes returned by the NodeList accessors;
- // it is not a static snapshot of the content of the node. This is true for every NodeList, including the ones returned by the getElementsByTagName method.
- this.childNodes = new DOMNodeList(ownerDocument, this);
-
- this.firstChild = null; // The first child of this node. If there is no such node, this is null
- this.lastChild = null; // The last child of this node. If there is no such node, this is null.
- this.previousSibling = null; // The node immediately preceding this node. If there is no such node, this is null.
- this.nextSibling = null; // The node immediately following this node. If there is no such node, this is null.
-
- this.ownerDocument = ownerDocument; // The Document object associated with this node
- this.attributes = new DOMNamedNodeMap(this.ownerDocument, this);
- this._namespaces = new DOMNamespaceNodeMap(ownerDocument, this); // The namespaces in scope for this node
- this._readonly = false;
};
// nodeType constants
-DOMNode.ELEMENT_NODE = 1;
-DOMNode.ATTRIBUTE_NODE = 2;
-DOMNode.TEXT_NODE = 3;
-DOMNode.CDATA_SECTION_NODE = 4;
-DOMNode.ENTITY_REFERENCE_NODE = 5;
-DOMNode.ENTITY_NODE = 6;
-DOMNode.PROCESSING_INSTRUCTION_NODE = 7;
-DOMNode.COMMENT_NODE = 8;
-DOMNode.DOCUMENT_NODE = 9;
-DOMNode.DOCUMENT_TYPE_NODE = 10;
-DOMNode.DOCUMENT_FRAGMENT_NODE = 11;
-DOMNode.NOTATION_NODE = 12;
-DOMNode.NAMESPACE_NODE = 13;
+Node.ELEMENT_NODE = 1;
+Node.ATTRIBUTE_NODE = 2;
+Node.TEXT_NODE = 3;
+Node.CDATA_SECTION_NODE = 4;
+Node.ENTITY_REFERENCE_NODE = 5;
+Node.ENTITY_NODE = 6;
+Node.PROCESSING_INSTRUCTION_NODE = 7;
+Node.COMMENT_NODE = 8;
+Node.DOCUMENT_NODE = 9;
+Node.DOCUMENT_TYPE_NODE = 10;
+Node.DOCUMENT_FRAGMENT_NODE = 11;
+Node.NOTATION_NODE = 12;
+Node.NAMESPACE_NODE = 13;
-__extend__(DOMNode.prototype, {
+Node.DOCUMENT_POSITION_EQUAL = 0x00;
+Node.DOCUMENT_POSITION_DISCONNECTED = 0x01;
+Node.DOCUMENT_POSITION_PRECEDING = 0x02;
+Node.DOCUMENT_POSITION_FOLLOWING = 0x04;
+Node.DOCUMENT_POSITION_CONTAINS = 0x08;
+Node.DOCUMENT_POSITION_CONTAINED_BY = 0x10;
+Node.DOCUMENT_POSITION_IMPLEMENTATION_SPECIFIC = 0x20;
+
+
+__extend__(Node.prototype, {
+ get localName(){
+ return this.prefix?
+ this.nodeName.substring(this.prefix.length+1, this.nodeName.length):
+ this.nodeName;
+ },
+ get prefix(){
+ return this.nodeName.split(':').length>1?
+ this.nodeName.split(':')[0]:
+ null;
+ },
+ set prefix(value){
+ if(value === null){
+ this.nodeName = this.localName;
+ }else{
+ this.nodeName = value+':'+this.localName;
+ }
+ },
hasAttributes : function() {
if (this.attributes.length == 0) {
return false;
@@ -860,170 +1908,187 @@ __extend__(DOMNode.prototype, {
return true;
}
},
+ get textContent(){
+ return __recursivelyGatherText__(this);
+ },
+ set textContent(newText){
+ while(this.firstChild != null){
+ this.removeChild( this.firstChild );
+ }
+ var text = this.ownerDocument.createTextNode(newText);
+ this.appendChild(text);
+ },
insertBefore : function(newChild, refChild) {
var prevNode;
-
- if(newChild==null || refChild==null){
+
+ if(newChild==null){
return newChild;
}
-
+ if(refChild==null){
+ this.appendChild(newChild);
+ return this.newChild;
+ }
+
// test for exceptions
if (__ownerDocument__(this).implementation.errorChecking) {
- // throw Exception if DOMNode is readonly
+ // throw Exception if Node is readonly
if (this._readonly) {
throw(new DOMException(DOMException.NO_MODIFICATION_ALLOWED_ERR));
}
-
+
// throw Exception if newChild was not created by this Document
if (__ownerDocument__(this) != __ownerDocument__(newChild)) {
throw(new DOMException(DOMException.WRONG_DOCUMENT_ERR));
}
-
+
// throw Exception if the node is an ancestor
if (__isAncestor__(this, newChild)) {
throw(new DOMException(DOMException.HIERARCHY_REQUEST_ERR));
}
}
-
- if (refChild) { // if refChild is specified, insert before it
+
+ // if refChild is specified, insert before it
+ if (refChild) {
// find index of refChild
- var itemIndex = __findItemIndex__(this.childNodes, refChild._id);
-
+ var itemIndex = __findItemIndex__(this.childNodes, refChild);
// throw Exception if there is no child node with this id
if (__ownerDocument__(this).implementation.errorChecking && (itemIndex < 0)) {
- throw(new DOMException(DOMException.NOT_FOUND_ERR));
+ throw(new DOMException(DOMException.NOT_FOUND_ERR));
}
-
+
// if the newChild is already in the tree,
var newChildParent = newChild.parentNode;
if (newChildParent) {
- // remove it
- newChildParent.removeChild(newChild);
+ // remove it
+ newChildParent.removeChild(newChild);
}
-
+
// insert newChild into childNodes
- __insertBefore__(this.childNodes, newChild,
- __findItemIndex__(this.childNodes, refChild._id));
-
+ __insertBefore__(this.childNodes, newChild, itemIndex);
+
// do node pointer surgery
prevNode = refChild.previousSibling;
-
+
// handle DocumentFragment
- if (newChild.nodeType == DOMNode.DOCUMENT_FRAGMENT_NODE) {
- if (newChild.childNodes.length > 0) {
- // set the parentNode of DocumentFragment's children
- for (var ind = 0; ind < newChild.childNodes.length; ind++) {
- newChild.childNodes[ind].parentNode = this;
+ if (newChild.nodeType == Node.DOCUMENT_FRAGMENT_NODE) {
+ if (newChild.childNodes.length > 0) {
+ // set the parentNode of DocumentFragment's children
+ for (var ind = 0; ind < newChild.childNodes.length; ind++) {
+ newChild.childNodes[ind].parentNode = this;
+ }
+
+ // link refChild to last child of DocumentFragment
+ refChild.previousSibling = newChild.childNodes[newChild.childNodes.length-1];
}
-
- // link refChild to last child of DocumentFragment
- refChild.previousSibling = newChild.childNodes[newChild.childNodes.length-1];
- }
}else {
- newChild.parentNode = this; // set the parentNode of the newChild
- refChild.previousSibling = newChild; // link refChild to newChild
+ // set the parentNode of the newChild
+ newChild.parentNode = this;
+ // link refChild to newChild
+ refChild.previousSibling = newChild;
}
- }else { // otherwise, append to end
+
+ }else {
+ // otherwise, append to end
prevNode = this.lastChild;
this.appendChild(newChild);
}
-
- if (newChild.nodeType == DOMNode.DOCUMENT_FRAGMENT_NODE) {
+
+ if (newChild.nodeType == Node.DOCUMENT_FRAGMENT_NODE) {
// do node pointer surgery for DocumentFragment
if (newChild.childNodes.length > 0) {
- if (prevNode) {
+ if (prevNode) {
prevNode.nextSibling = newChild.childNodes[0];
- }else { // this is the first child in the list
+ }else {
+ // this is the first child in the list
this.firstChild = newChild.childNodes[0];
}
-
newChild.childNodes[0].previousSibling = prevNode;
newChild.childNodes[newChild.childNodes.length-1].nextSibling = refChild;
}
}else {
// do node pointer surgery for newChild
if (prevNode) {
- prevNode.nextSibling = newChild;
- }else { // this is the first child in the list
- this.firstChild = newChild;
+ prevNode.nextSibling = newChild;
+ }else {
+ // this is the first child in the list
+ this.firstChild = newChild;
}
-
newChild.previousSibling = prevNode;
newChild.nextSibling = refChild;
}
-
+
return newChild;
},
replaceChild : function(newChild, oldChild) {
var ret = null;
-
+
if(newChild==null || oldChild==null){
return oldChild;
}
-
+
// test for exceptions
if (__ownerDocument__(this).implementation.errorChecking) {
- // throw Exception if DOMNode is readonly
+ // throw Exception if Node is readonly
if (this._readonly) {
throw(new DOMException(DOMException.NO_MODIFICATION_ALLOWED_ERR));
}
-
+
// throw Exception if newChild was not created by this Document
if (__ownerDocument__(this) != __ownerDocument__(newChild)) {
throw(new DOMException(DOMException.WRONG_DOCUMENT_ERR));
}
-
+
// throw Exception if the node is an ancestor
if (__isAncestor__(this, newChild)) {
throw(new DOMException(DOMException.HIERARCHY_REQUEST_ERR));
}
}
-
+
// get index of oldChild
- var index = __findItemIndex__(this.childNodes, oldChild._id);
-
+ var index = __findItemIndex__(this.childNodes, oldChild);
+
// throw Exception if there is no child node with this id
if (__ownerDocument__(this).implementation.errorChecking && (index < 0)) {
throw(new DOMException(DOMException.NOT_FOUND_ERR));
}
-
+
// if the newChild is already in the tree,
var newChildParent = newChild.parentNode;
if (newChildParent) {
// remove it
newChildParent.removeChild(newChild);
}
-
+
// add newChild to childNodes
ret = __replaceChild__(this.childNodes,newChild, index);
-
-
- if (newChild.nodeType == DOMNode.DOCUMENT_FRAGMENT_NODE) {
+
+
+ if (newChild.nodeType == Node.DOCUMENT_FRAGMENT_NODE) {
// do node pointer surgery for Document Fragment
if (newChild.childNodes.length > 0) {
for (var ind = 0; ind < newChild.childNodes.length; ind++) {
newChild.childNodes[ind].parentNode = this;
}
-
+
if (oldChild.previousSibling) {
oldChild.previousSibling.nextSibling = newChild.childNodes[0];
} else {
this.firstChild = newChild.childNodes[0];
}
-
+
if (oldChild.nextSibling) {
oldChild.nextSibling.previousSibling = newChild;
} else {
this.lastChild = newChild.childNodes[newChild.childNodes.length-1];
}
-
+
newChild.childNodes[0].previousSibling = oldChild.previousSibling;
newChild.childNodes[newChild.childNodes.length-1].nextSibling = oldChild.nextSibling;
}
} else {
// do node pointer surgery for newChild
newChild.parentNode = this;
-
+
if (oldChild.previousSibling) {
oldChild.previousSibling.nextSibling = newChild;
}else{
@@ -1037,31 +2102,33 @@ __extend__(DOMNode.prototype, {
newChild.previousSibling = oldChild.previousSibling;
newChild.nextSibling = oldChild.nextSibling;
}
+
return ret;
},
removeChild : function(oldChild) {
if(!oldChild){
return null;
}
- // throw Exception if DOMNamedNodeMap is readonly
- if (__ownerDocument__(this).implementation.errorChecking && (this._readonly || oldChild._readonly)) {
+ // throw Exception if NamedNodeMap is readonly
+ if (__ownerDocument__(this).implementation.errorChecking &&
+ (this._readonly || oldChild._readonly)) {
throw(new DOMException(DOMException.NO_MODIFICATION_ALLOWED_ERR));
}
-
+
// get index of oldChild
- var itemIndex = __findItemIndex__(this.childNodes, oldChild._id);
-
+ var itemIndex = __findItemIndex__(this.childNodes, oldChild);
+
// throw Exception if there is no child node with this id
if (__ownerDocument__(this).implementation.errorChecking && (itemIndex < 0)) {
throw(new DOMException(DOMException.NOT_FOUND_ERR));
}
-
+
// remove oldChild from childNodes
__removeChild__(this.childNodes, itemIndex);
-
+
// do node pointer surgery
oldChild.parentNode = null;
-
+
if (oldChild.previousSibling) {
oldChild.previousSibling.nextSibling = oldChild.nextSibling;
}else {
@@ -1072,77 +2139,74 @@ __extend__(DOMNode.prototype, {
}else {
this.lastChild = oldChild.previousSibling;
}
-
+
oldChild.previousSibling = null;
oldChild.nextSibling = null;
-
+
return oldChild;
},
appendChild : function(newChild) {
if(!newChild){
return null;
}
- // test for exceptions
- if (__ownerDocument__(this).implementation.errorChecking) {
- // throw Exception if Node is readonly
- if (this._readonly) {
- throw(new DOMException(DOMException.NO_MODIFICATION_ALLOWED_ERR));
+ // test for exceptions
+ if (__ownerDocument__(this).implementation.errorChecking) {
+ // throw Exception if Node is readonly
+ if (this._readonly) {
+ throw(new DOMException(DOMException.NO_MODIFICATION_ALLOWED_ERR));
+ }
+
+ // throw Exception if arg was not created by this Document
+ if (__ownerDocument__(this) != __ownerDocument__(this)) {
+ throw(new DOMException(DOMException.WRONG_DOCUMENT_ERR));
+ }
+
+ // throw Exception if the node is an ancestor
+ if (__isAncestor__(this, newChild)) {
+ throw(new DOMException(DOMException.HIERARCHY_REQUEST_ERR));
+ }
}
-
- // throw Exception if arg was not created by this Document
- if (__ownerDocument__(this) != __ownerDocument__(this)) {
- throw(new DOMException(DOMException.WRONG_DOCUMENT_ERR));
+
+ // if the newChild is already in the tree,
+ var newChildParent = newChild.parentNode;
+ if (newChildParent) {
+ // remove it
+ //console.debug('removing node %s', newChild);
+ newChildParent.removeChild(newChild);
}
-
- // throw Exception if the node is an ancestor
- if (__isAncestor__(this, newChild)) {
- throw(new DOMException(DOMException.HIERARCHY_REQUEST_ERR));
- }
- }
-
- // if the newChild is already in the tree,
- var newChildParent = newChild.parentNode;
- if (newChildParent) {
- // remove it
- newChildParent.removeChild(newChild);
- }
-
- // add newChild to childNodes
- __appendChild__(this.childNodes, newChild);
-
- if (newChild.nodeType == DOMNode.DOCUMENT_FRAGMENT_NODE) {
- // do node pointer surgery for DocumentFragment
- if (newChild.childNodes.length > 0) {
- for (var ind = 0; ind < newChild.childNodes.length; ind++) {
- newChild.childNodes[ind].parentNode = this;
- }
-
- if (this.lastChild) {
- this.lastChild.nextSibling = newChild.childNodes[0];
- newChild.childNodes[0].previousSibling = this.lastChild;
- this.lastChild = newChild.childNodes[newChild.childNodes.length-1];
- }
- else {
- this.lastChild = newChild.childNodes[newChild.childNodes.length-1];
- this.firstChild = newChild.childNodes[0];
- }
- }
- }
- else {
- // do node pointer surgery for newChild
- newChild.parentNode = this;
- if (this.lastChild) {
- this.lastChild.nextSibling = newChild;
- newChild.previousSibling = this.lastChild;
- this.lastChild = newChild;
- }
- else {
- this.lastChild = newChild;
- this.firstChild = newChild;
- }
- }
-
- return newChild;
+
+ // add newChild to childNodes
+ __appendChild__(this.childNodes, newChild);
+
+ if (newChild.nodeType == Node.DOCUMENT_FRAGMENT_NODE) {
+ // do node pointer surgery for DocumentFragment
+ if (newChild.childNodes.length > 0) {
+ for (var ind = 0; ind < newChild.childNodes.length; ind++) {
+ newChild.childNodes[ind].parentNode = this;
+ }
+
+ if (this.lastChild) {
+ this.lastChild.nextSibling = newChild.childNodes[0];
+ newChild.childNodes[0].previousSibling = this.lastChild;
+ this.lastChild = newChild.childNodes[newChild.childNodes.length-1];
+ } else {
+ this.lastChild = newChild.childNodes[newChild.childNodes.length-1];
+ this.firstChild = newChild.childNodes[0];
+ }
+ }
+ } else {
+ // do node pointer surgery for newChild
+ newChild.parentNode = this;
+ if (this.lastChild) {
+ this.lastChild.nextSibling = newChild;
+ newChild.previousSibling = this.lastChild;
+ this.lastChild = newChild;
+ } else {
+ this.lastChild = newChild;
+ this.firstChild = newChild;
+ }
+ }
+ return newChild;
},
hasChildNodes : function() {
return (this.childNodes.length > 0);
@@ -1154,264 +2218,800 @@ __extend__(DOMNode.prototype, {
return __ownerDocument__(this).importNode(this, deep);
} catch (e) {
//there shouldn't be any exceptions, but if there are, return null
+ // may want to warn: $debug("could not clone node: "+e.code);
return null;
}
},
normalize : function() {
+ var i;
var inode;
- var nodesToRemove = new DOMNodeList();
-
- if (this.nodeType == DOMNode.ELEMENT_NODE || this.nodeType == DOMNode.DOCUMENT_NODE) {
+ var nodesToRemove = new NodeList();
+
+ if (this.nodeType == Node.ELEMENT_NODE || this.nodeType == Node.DOCUMENT_NODE) {
var adjacentTextNode = null;
-
+
// loop through all childNodes
- for(var i = 0; i < this.childNodes.length; i++) {
+ for(i = 0; i < this.childNodes.length; i++) {
inode = this.childNodes.item(i);
-
- if (inode.nodeType == DOMNode.TEXT_NODE) { // this node is a text node
- if (inode.length < 1) { // this text node is empty
- __appendChild__(nodesToRemove, inode); // add this node to the list of nodes to be remove
+
+ if (inode.nodeType == Node.TEXT_NODE) {
+ // this node is a text node
+ if (inode.length < 1) {
+ // this text node is empty
+ // add this node to the list of nodes to be remove
+ __appendChild__(nodesToRemove, inode);
}else {
- if (adjacentTextNode) { // if previous node was also text
- adjacentTextNode.appendData(inode.data); // merge the data in adjacent text nodes
- __appendChild__(nodesToRemove, inode); // add this node to the list of nodes to be removed
- }else {
- adjacentTextNode = inode; // remember this node for next cycle
+ if (adjacentTextNode) {
+ // previous node was also text
+ adjacentTextNode.appendData(inode.data);
+ // merge the data in adjacent text nodes
+ // add this node to the list of nodes to be removed
+ __appendChild__(nodesToRemove, inode);
+ } else {
+ // remember this node for next cycle
+ adjacentTextNode = inode;
}
}
} else {
- adjacentTextNode = null; // (soon to be) previous node is not a text node
- inode.normalize(); // normalise non Text childNodes
+ // (soon to be) previous node is not a text node
+ adjacentTextNode = null;
+ // normalize non Text childNodes
+ inode.normalize();
}
}
-
+
// remove redundant Text Nodes
- for(var i = 0; i < nodesToRemove.length; i++) {
+ for(i = 0; i < nodesToRemove.length; i++) {
inode = nodesToRemove.item(i);
inode.parentNode.removeChild(inode);
}
}
},
isSupported : function(feature, version) {
- // use Implementation.hasFeature to determin if this feature is supported
+ // use Implementation.hasFeature to determine if this feature is supported
return __ownerDocument__(this).implementation.hasFeature(feature, version);
},
getElementsByTagName : function(tagname) {
// delegate to _getElementsByTagNameRecursive
// recurse childNodes
- var nodelist = new DOMNodeList(__ownerDocument__(this));
- for(var i = 0; i < this.childNodes.length; i++) {
- nodeList = __getElementsByTagNameRecursive__(this.childNodes.item(i), tagname, nodelist);
+ var nodelist = new NodeList(__ownerDocument__(this));
+ for (var i = 0; i < this.childNodes.length; i++) {
+ __getElementsByTagNameRecursive__(this.childNodes.item(i),
+ tagname,
+ nodelist);
}
return nodelist;
},
getElementsByTagNameNS : function(namespaceURI, localName) {
// delegate to _getElementsByTagNameNSRecursive
- return __getElementsByTagNameNSRecursive__(this, namespaceURI, localName,
- new DOMNodeList(__ownerDocument__(this)));
+ return __getElementsByTagNameNSRecursive__(this, namespaceURI, localName,
+ new NodeList(__ownerDocument__(this)));
},
importNode : function(importedNode, deep) {
-
+ var i;
var importNode;
- //$debug("importing node " + importedNode.nodeName + "(?deep = "+deep+")");
+
//there is no need to perform namespace checks since everything has already gone through them
//in order to have gotten into the DOM in the first place. The following line
//turns namespace checking off in ._isValidNamespace
- __ownerDocument__(this)._performingImportNodeOperation = true;
-
- if (importedNode.nodeType == DOMNode.ELEMENT_NODE) {
- if (!__ownerDocument__(this).implementation.namespaceAware) {
- // create a local Element (with the name of the importedNode)
- importNode = __ownerDocument__(this).createElement(importedNode.tagName);
-
- // create attributes matching those of the importedNode
- for(var i = 0; i < importedNode.attributes.length; i++) {
- importNode.setAttribute(importedNode.attributes.item(i).name, importedNode.attributes.item(i).value);
- }
- }else {
- // create a local Element (with the name & namespaceURI of the importedNode)
- importNode = __ownerDocument__(this).createElementNS(importedNode.namespaceURI, importedNode.nodeName);
-
- // create attributes matching those of the importedNode
- for(var i = 0; i < importedNode.attributes.length; i++) {
- importNode.setAttributeNS(importedNode.attributes.item(i).namespaceURI,
- importedNode.attributes.item(i).name, importedNode.attributes.item(i).value);
- }
-
- // create namespace definitions matching those of the importedNode
- for(var i = 0; i < importedNode._namespaces.length; i++) {
- importNode._namespaces[i] = __ownerDocument__(this).createNamespace(importedNode._namespaces.item(i).localName);
- importNode._namespaces[i].value = importedNode._namespaces.item(i).value;
- }
+ __ownerDocument__(this).importing = true;
+
+ if (importedNode.nodeType == Node.ELEMENT_NODE) {
+ if (!__ownerDocument__(this).implementation.namespaceAware) {
+ // create a local Element (with the name of the importedNode)
+ importNode = __ownerDocument__(this).createElement(importedNode.tagName);
+
+ // create attributes matching those of the importedNode
+ for(i = 0; i < importedNode.attributes.length; i++) {
+ importNode.setAttribute(importedNode.attributes.item(i).name, importedNode.attributes.item(i).value);
}
- } else if (importedNode.nodeType == DOMNode.ATTRIBUTE_NODE) {
- if (!__ownerDocument__(this).implementation.namespaceAware) {
- // create a local Attribute (with the name of the importedAttribute)
- importNode = __ownerDocument__(this).createAttribute(importedNode.name);
- } else {
- // create a local Attribute (with the name & namespaceURI of the importedAttribute)
- importNode = __ownerDocument__(this).createAttributeNS(importedNode.namespaceURI, importedNode.nodeName);
-
- // create namespace definitions matching those of the importedAttribute
- for(var i = 0; i < importedNode._namespaces.length; i++) {
- importNode._namespaces[i] = __ownerDocument__(this).createNamespace(importedNode._namespaces.item(i).localName);
- importNode._namespaces[i].value = importedNode._namespaces.item(i).value;
- }
+ } else {
+ // create a local Element (with the name & namespaceURI of the importedNode)
+ importNode = __ownerDocument__(this).createElementNS(importedNode.namespaceURI, importedNode.nodeName);
+
+ // create attributes matching those of the importedNode
+ for(i = 0; i < importedNode.attributes.length; i++) {
+ importNode.setAttributeNS(importedNode.attributes.item(i).namespaceURI,
+ importedNode.attributes.item(i).name, importedNode.attributes.item(i).value);
}
-
- // set the value of the local Attribute to match that of the importedAttribute
- importNode.value = importedNode.value;
-
- } else if (importedNode.nodeType == DOMNode.DOCUMENT_FRAGMENT) {
- // create a local DocumentFragment
- importNode = __ownerDocument__(this).createDocumentFragment();
- } else if (importedNode.nodeType == DOMNode.NAMESPACE_NODE) {
- // create a local NamespaceNode (with the same name & value as the importedNode)
- importNode = __ownerDocument__(this).createNamespace(importedNode.nodeName);
- importNode.value = importedNode.value;
- } else if (importedNode.nodeType == DOMNode.TEXT_NODE) {
- // create a local TextNode (with the same data as the importedNode)
- importNode = __ownerDocument__(this).createTextNode(importedNode.data);
- } else if (importedNode.nodeType == DOMNode.CDATA_SECTION_NODE) {
- // create a local CDATANode (with the same data as the importedNode)
- importNode = __ownerDocument__(this).createCDATASection(importedNode.data);
- } else if (importedNode.nodeType == DOMNode.PROCESSING_INSTRUCTION_NODE) {
- // create a local ProcessingInstruction (with the same target & data as the importedNode)
- importNode = __ownerDocument__(this).createProcessingInstruction(importedNode.target, importedNode.data);
- } else if (importedNode.nodeType == DOMNode.COMMENT_NODE) {
- // create a local Comment (with the same data as the importedNode)
- importNode = __ownerDocument__(this).createComment(importedNode.data);
- } else { // throw Exception if nodeType is not supported
- throw(new DOMException(DOMException.NOT_SUPPORTED_ERR));
- }
-
- if (deep) { // recurse childNodes
- for(var i = 0; i < importedNode.childNodes.length; i++) {
- importNode.appendChild(__ownerDocument__(this).importNode(importedNode.childNodes.item(i), true));
+
+ // create namespace definitions matching those of the importedNode
+ for(i = 0; i < importedNode._namespaces.length; i++) {
+ importNode._namespaces[i] = __ownerDocument__(this).createNamespace(importedNode._namespaces.item(i).localName);
+ importNode._namespaces[i].value = importedNode._namespaces.item(i).value;
}
}
-
- //reset _performingImportNodeOperation
- __ownerDocument__(this)._performingImportNodeOperation = false;
- return importNode;
-
+ } else if (importedNode.nodeType == Node.ATTRIBUTE_NODE) {
+ if (!__ownerDocument__(this).implementation.namespaceAware) {
+ // create a local Attribute (with the name of the importedAttribute)
+ importNode = __ownerDocument__(this).createAttribute(importedNode.name);
+ } else {
+ // create a local Attribute (with the name & namespaceURI of the importedAttribute)
+ importNode = __ownerDocument__(this).createAttributeNS(importedNode.namespaceURI, importedNode.nodeName);
+
+ // create namespace definitions matching those of the importedAttribute
+ for(i = 0; i < importedNode._namespaces.length; i++) {
+ importNode._namespaces[i] = __ownerDocument__(this).createNamespace(importedNode._namespaces.item(i).localName);
+ importNode._namespaces[i].value = importedNode._namespaces.item(i).value;
+ }
+ }
+
+ // set the value of the local Attribute to match that of the importedAttribute
+ importNode.value = importedNode.value;
+
+ } else if (importedNode.nodeType == Node.DOCUMENT_FRAGMENT_NODE) {
+ // create a local DocumentFragment
+ importNode = __ownerDocument__(this).createDocumentFragment();
+ } else if (importedNode.nodeType == Node.NAMESPACE_NODE) {
+ // create a local NamespaceNode (with the same name & value as the importedNode)
+ importNode = __ownerDocument__(this).createNamespace(importedNode.nodeName);
+ importNode.value = importedNode.value;
+ } else if (importedNode.nodeType == Node.TEXT_NODE) {
+ // create a local TextNode (with the same data as the importedNode)
+ importNode = __ownerDocument__(this).createTextNode(importedNode.data);
+ } else if (importedNode.nodeType == Node.CDATA_SECTION_NODE) {
+ // create a local CDATANode (with the same data as the importedNode)
+ importNode = __ownerDocument__(this).createCDATASection(importedNode.data);
+ } else if (importedNode.nodeType == Node.PROCESSING_INSTRUCTION_NODE) {
+ // create a local ProcessingInstruction (with the same target & data as the importedNode)
+ importNode = __ownerDocument__(this).createProcessingInstruction(importedNode.target, importedNode.data);
+ } else if (importedNode.nodeType == Node.COMMENT_NODE) {
+ // create a local Comment (with the same data as the importedNode)
+ importNode = __ownerDocument__(this).createComment(importedNode.data);
+ } else { // throw Exception if nodeType is not supported
+ throw(new DOMException(DOMException.NOT_SUPPORTED_ERR));
+ }
+
+ if (deep) {
+ // recurse childNodes
+ for(i = 0; i < importedNode.childNodes.length; i++) {
+ importNode.appendChild(__ownerDocument__(this).importNode(importedNode.childNodes.item(i), true));
+ }
+ }
+
+ //reset importing
+ __ownerDocument__(this).importing = false;
+ return importNode;
+
},
contains : function(node){
- while(node && node != this ){
- node = node.parentNode;
- }
- return !!node;
+ while(node && node != this ){
+ node = node.parentNode;
+ }
+ return !!node;
},
compareDocumentPosition : function(b){
- var a = this;
- var number = (a != b && a.contains(b) && 16) + (a != b && b.contains(a) && 8);
- //find position of both
- var all = document.getElementsByTagName("*");
- var my_location = 0, node_location = 0;
- for(var i=0; i < all.length; i++){
- if(all[i] == a) my_location = i;
- if(all[i] == b) node_location = i;
- if(my_location && node_location) break;
+ //console.log("comparing document position %s %s", this, b);
+ var i,
+ length,
+ a = this,
+ parent,
+ aparents,
+ bparents;
+ //handle a couple simpler case first
+ if(a === b) {
+ return Node.DOCUMENT_POSITION_EQUAL;
}
- number += (my_location < node_location && 4)
- number += (my_location > node_location && 2)
- return number;
- }
+ if(a.ownerDocument !== b.ownerDocument) {
+ return Node.DOCUMENT_POSITION_IMPLEMENTATION_SPECIFIC|
+ Node.DOCUMENT_POSITION_FOLLOWING|
+ Node.DOCUMENT_POSITION_DISCONNECTED;
+ }
+ if(a.parentNode === b.parentNode){
+ length = a.parentNode.childNodes.length;
+ for(i=0;i aparents.length){
+ return Node.DOCUMENT_POSITION_FOLLOWING;
+ }else if(bparents.length < aparents.length){
+ return Node.DOCUMENT_POSITION_PRECEDING;
+ }else{
+ //common ancestor diverge point
+ if (i === 0) {
+ return Node.DOCUMENT_POSITION_FOLLOWING;
+ } else {
+ parent = aparents[i-1];
+ }
+ return parent.compareDocumentPosition(bparents.pop());
+ }
+ }
+ }
+
+ return Node.DOCUMENT_POSITION_IMPLEMENTATION_SPECIFIC|
+ Node.DOCUMENT_POSITION_DISCONNECTED;
+
+ },
+ toString : function() {
+ return '[object Node]';
+ }
});
+
+
/**
- * @method DOMNode._getElementsByTagNameRecursive - implements getElementsByTagName()
- * @param elem : DOMElement - The element which are checking and then recursing into
+ * @method __getElementsByTagNameRecursive__ - implements getElementsByTagName()
+ * @param elem : Element - The element which are checking and then recursing into
* @param tagname : string - The name of the tag to match on. The special value "*" matches all tags
- * @param nodeList : DOMNodeList - The accumulating list of matching nodes
+ * @param nodeList : NodeList - The accumulating list of matching nodes
*
- * @return : DOMNodeList
+ * @return : NodeList
*/
var __getElementsByTagNameRecursive__ = function (elem, tagname, nodeList) {
-
- if (elem.nodeType == DOMNode.ELEMENT_NODE || elem.nodeType == DOMNode.DOCUMENT_NODE) {
-
- if(elem.nodeType !== DOMNode.DOCUMENT_NODE &&
- ((elem.nodeName.toUpperCase() == tagname.toUpperCase()) ||
+
+ if (elem.nodeType == Node.ELEMENT_NODE || elem.nodeType == Node.DOCUMENT_NODE) {
+
+ if(elem.nodeType !== Node.DOCUMENT_NODE &&
+ ((elem.nodeName.toUpperCase() == tagname.toUpperCase()) ||
(tagname == "*")) ){
- __appendChild__(nodeList, elem); // add matching node to nodeList
+ // add matching node to nodeList
+ __appendChild__(nodeList, elem);
}
-
+
// recurse childNodes
for(var i = 0; i < elem.childNodes.length; i++) {
nodeList = __getElementsByTagNameRecursive__(elem.childNodes.item(i), tagname, nodeList);
}
}
-
+
return nodeList;
};
/**
- * @method DOMNode._getElementsByTagNameNSRecursive - implements getElementsByTagName()
+ * @method __getElementsByTagNameNSRecursive__
+ * implements getElementsByTagName()
*
- * @param elem : DOMElement - The element which are checking and then recursing into
+ * @param elem : Element - The element which are checking and then recursing into
* @param namespaceURI : string - the namespace URI of the required node
* @param localName : string - the local name of the required node
- * @param nodeList : DOMNodeList - The accumulating list of matching nodes
+ * @param nodeList : NodeList - The accumulating list of matching nodes
*
- * @return : DOMNodeList
+ * @return : NodeList
*/
var __getElementsByTagNameNSRecursive__ = function(elem, namespaceURI, localName, nodeList) {
- if (elem.nodeType == DOMNode.ELEMENT_NODE || elem.nodeType == DOMNode.DOCUMENT_NODE) {
+ if (elem.nodeType == Node.ELEMENT_NODE || elem.nodeType == Node.DOCUMENT_NODE) {
- if (((elem.namespaceURI == namespaceURI) || (namespaceURI == "*")) && ((elem.localName == localName) || (localName == "*"))) {
- __appendChild__(nodeList, elem); // add matching node to nodeList
+ if (((elem.namespaceURI == namespaceURI) || (namespaceURI == "*")) &&
+ ((elem.localName == localName) || (localName == "*"))) {
+ // add matching node to nodeList
+ __appendChild__(nodeList, elem);
+ }
+
+ // recurse childNodes
+ for(var i = 0; i < elem.childNodes.length; i++) {
+ nodeList = __getElementsByTagNameNSRecursive__(
+ elem.childNodes.item(i), namespaceURI, localName, nodeList);
+ }
}
- // recurse childNodes
- for(var i = 0; i < elem.childNodes.length; i++) {
- nodeList = __getElementsByTagNameNSRecursive__(elem.childNodes.item(i), namespaceURI, localName, nodeList);
- }
- }
-
- return nodeList;
+ return nodeList;
};
/**
- * @method DOMNode._isAncestor - returns true if node is ancestor of target
- * @param target : DOMNode - The node we are using as context
- * @param node : DOMNode - The candidate ancestor node
+ * @method __isAncestor__ - returns true if node is ancestor of target
+ * @param target : Node - The node we are using as context
+ * @param node : Node - The candidate ancestor node
* @return : boolean
*/
var __isAncestor__ = function(target, node) {
- // if this node matches, return true,
- // otherwise recurse up (if there is a parentNode)
- return ((target == node) || ((target.parentNode) && (__isAncestor__(target.parentNode, node))));
+ // if this node matches, return true,
+ // otherwise recurse up (if there is a parentNode)
+ return ((target == node) || ((target.parentNode) && (__isAncestor__(target.parentNode, node))));
};
-var __ownerDocument__ = function(node){
- return (node.nodeType == DOMNode.DOCUMENT_NODE)?node:node.ownerDocument;
-};
-$w.Node = DOMNode;
+
+var __recursivelyGatherText__ = function(aNode) {
+ var accumulateText = "",
+ idx,
+ node;
+ for (idx=0;idx < aNode.childNodes.length;idx++){
+ node = aNode.childNodes.item(idx);
+ if(node.nodeType == Node.TEXT_NODE)
+ accumulateText += node.data;
+ else
+ accumulateText += __recursivelyGatherText__(node);
+ }
+ return accumulateText;
+};
/**
- * @class DOMNamespace - The Namespace interface represents an namespace in an Element object
- *
- * @extends DOMNode
- * @author Jon van Noort (jon@webarcana.com.au)
- * @param ownerDocument : DOMDocument - The Document object associated with this node.
+ * function __escapeXML__
+ * @param str : string - The string to be escaped
+ * @return : string - The escaped string
*/
-var DOMNamespace = function(ownerDocument) {
- this.DOMNode = DOMNode;
- this.DOMNode(ownerDocument);
+var escAmpRegEx = /&(?!(amp;|lt;|gt;|quot|apos;))/g;
+var escLtRegEx = //g;
+var quotRegEx = /"/g;
+var aposRegEx = /'/g;
- this.name = ""; // the name of this attribute
+function __escapeXML__(str) {
+ str = str.replace(escAmpRegEx, "&").
+ replace(escLtRegEx, "<").
+ replace(escGtRegEx, ">").
+ replace(quotRegEx, """).
+ replace(aposRegEx, "'");
- // If this attribute was explicitly given a value in the original document, this is true; otherwise, it is false.
- // Note that the implementation is in charge of this attribute, not the user.
- // If the user changes the value of the attribute (even if it ends up having the same value as the default value)
- // then the specified flag is automatically flipped to true
- this.specified = false;
+ return str;
};
-DOMNamespace.prototype = new DOMNode;
-__extend__(DOMNamespace.prototype, {
+
+/*
+function __escapeHTML5__(str) {
+ str = str.replace(escAmpRegEx, "&").
+ replace(escLtRegEx, "<").
+ replace(escGtRegEx, ">");
+
+ return str;
+};
+function __escapeHTML5Atribute__(str) {
+ str = str.replace(escAmpRegEx, "&").
+ replace(escLtRegEx, "<").
+ replace(escGtRegEx, ">").
+ replace(quotRegEx, """).
+ replace(aposRegEx, "'");
+
+ return str;
+};
+*/
+
+/**
+ * function __unescapeXML__
+ * @param str : string - The string to be unescaped
+ * @return : string - The unescaped string
+ */
+var unescAmpRegEx = /&/g;
+var unescLtRegEx = /</g;
+var unescGtRegEx = />/g;
+var unquotRegEx = /"/g;
+var unaposRegEx = /'/g;
+function __unescapeXML__(str) {
+ str = str.replace(unescAmpRegEx, "&").
+ replace(unescLtRegEx, "<").
+ replace(unescGtRegEx, ">").
+ replace(unquotRegEx, "\"").
+ replace(unaposRegEx, "'");
+
+ return str;
+};
+
+/**
+ * @class NamedNodeMap -
+ * used to represent collections of nodes that can be accessed by name
+ * typically a set of Element attributes
+ *
+ * @extends NodeList -
+ * note W3C spec says that this is not the case, but we need an item()
+ * method identical to NodeList's, so why not?
+ * @param ownerDocument : Document - the ownerDocument
+ * @param parentNode : Node - the node that the NamedNodeMap is attached to (or null)
+ */
+NamedNodeMap = function(ownerDocument, parentNode) {
+ NodeList.apply(this, arguments);
+ __setArray__(this, []);
+};
+NamedNodeMap.prototype = new NodeList();
+__extend__(NamedNodeMap.prototype, {
+ add: function(name){
+ this[this.length] = name;
+ },
+ getNamedItem : function(name) {
+ var ret = null;
+ //console.log('NamedNodeMap getNamedItem %s', name);
+ // test that Named Node exists
+ var itemIndex = __findNamedItemIndex__(this, name);
+
+ if (itemIndex > -1) {
+ // found it!
+ ret = this[itemIndex];
+ }
+ // if node is not found, default value null is returned
+ return ret;
+ },
+ setNamedItem : function(arg) {
+ //console.log('setNamedItem %s', arg);
+ // test for exceptions
+ if (__ownerDocument__(this).implementation.errorChecking) {
+ // throw Exception if arg was not created by this Document
+ if (this.ownerDocument != arg.ownerDocument) {
+ throw(new DOMException(DOMException.WRONG_DOCUMENT_ERR));
+ }
+
+ // throw Exception if DOMNamedNodeMap is readonly
+ if (this._readonly || (this.parentNode && this.parentNode._readonly)) {
+ throw(new DOMException(DOMException.NO_MODIFICATION_ALLOWED_ERR));
+ }
+
+ // throw Exception if arg is already an attribute of another Element object
+ if (arg.ownerElement && (arg.ownerElement != this.parentNode)) {
+ throw(new DOMException(DOMException.INUSE_ATTRIBUTE_ERR));
+ }
+ }
+
+ //console.log('setNamedItem __findNamedItemIndex__ ');
+ // get item index
+ var itemIndex = __findNamedItemIndex__(this, arg.name);
+ var ret = null;
+
+ //console.log('setNamedItem __findNamedItemIndex__ %s', itemIndex);
+ if (itemIndex > -1) { // found it!
+ ret = this[itemIndex]; // use existing Attribute
+
+ // throw Exception if DOMAttr is readonly
+ if (__ownerDocument__(this).implementation.errorChecking && ret._readonly) {
+ throw(new DOMException(DOMException.NO_MODIFICATION_ALLOWED_ERR));
+ } else {
+ this[itemIndex] = arg; // over-write existing NamedNode
+ this[arg.name.toLowerCase()] = arg;
+ }
+ } else {
+ // add new NamedNode
+ //console.log('setNamedItem add new named node map (by index)');
+ Array.prototype.push.apply(this, [arg]);
+ //console.log('setNamedItem add new named node map (by name) %s %s', arg, arg.name);
+ this[arg.name] = arg;
+ //console.log('finsished setNamedItem add new named node map (by name) %s', arg.name);
+
+ }
+
+ //console.log('setNamedItem parentNode');
+ arg.ownerElement = this.parentNode; // update ownerElement
+ // return old node or new node
+ //console.log('setNamedItem exit');
+ return ret;
+ },
+ removeNamedItem : function(name) {
+ var ret = null;
+ // test for exceptions
+ // throw Exception if NamedNodeMap is readonly
+ if (__ownerDocument__(this).implementation.errorChecking &&
+ (this._readonly || (this.parentNode && this.parentNode._readonly))) {
+ throw(new DOMException(DOMException.NO_MODIFICATION_ALLOWED_ERR));
+ }
+
+ // get item index
+ var itemIndex = __findNamedItemIndex__(this, name);
+
+ // throw Exception if there is no node named name in this map
+ if (__ownerDocument__(this).implementation.errorChecking && (itemIndex < 0)) {
+ throw(new DOMException(DOMException.NOT_FOUND_ERR));
+ }
+
+ // get Node
+ var oldNode = this[itemIndex];
+ //this[oldNode.name] = undefined;
+
+ // throw Exception if Node is readonly
+ if (__ownerDocument__(this).implementation.errorChecking && oldNode._readonly) {
+ throw(new DOMException(DOMException.NO_MODIFICATION_ALLOWED_ERR));
+ }
+
+ // return removed node
+ return __removeChild__(this, itemIndex);
+ },
+ getNamedItemNS : function(namespaceURI, localName) {
+ var ret = null;
+
+ // test that Named Node exists
+ var itemIndex = __findNamedItemNSIndex__(this, namespaceURI, localName);
+
+ if (itemIndex > -1) {
+ // found it! return NamedNode
+ ret = this[itemIndex];
+ }
+ // if node is not found, default value null is returned
+ return ret;
+ },
+ setNamedItemNS : function(arg) {
+ //console.log('setNamedItemNS %s', arg);
+ // test for exceptions
+ if (__ownerDocument__(this).implementation.errorChecking) {
+ // throw Exception if NamedNodeMap is readonly
+ if (this._readonly || (this.parentNode && this.parentNode._readonly)) {
+ throw(new DOMException(DOMException.NO_MODIFICATION_ALLOWED_ERR));
+ }
+
+ // throw Exception if arg was not created by this Document
+ if (__ownerDocument__(this) != __ownerDocument__(arg)) {
+ throw(new DOMException(DOMException.WRONG_DOCUMENT_ERR));
+ }
+
+ // throw Exception if arg is already an attribute of another Element object
+ if (arg.ownerElement && (arg.ownerElement != this.parentNode)) {
+ throw(new DOMException(DOMException.INUSE_ATTRIBUTE_ERR));
+ }
+ }
+
+ // get item index
+ var itemIndex = __findNamedItemNSIndex__(this, arg.namespaceURI, arg.localName);
+ var ret = null;
+
+ if (itemIndex > -1) {
+ // found it!
+ // use existing Attribute
+ ret = this[itemIndex];
+ // throw Exception if Attr is readonly
+ if (__ownerDocument__(this).implementation.errorChecking && ret._readonly) {
+ throw(new DOMException(DOMException.NO_MODIFICATION_ALLOWED_ERR));
+ } else {
+ // over-write existing NamedNode
+ this[itemIndex] = arg;
+ }
+ }else {
+ // add new NamedNode
+ Array.prototype.push.apply(this, [arg]);
+ }
+ arg.ownerElement = this.parentNode;
+
+ // return old node or null
+ return ret;
+ //console.log('finished setNamedItemNS %s', arg);
+ },
+ removeNamedItemNS : function(namespaceURI, localName) {
+ var ret = null;
+
+ // test for exceptions
+ // throw Exception if NamedNodeMap is readonly
+ if (__ownerDocument__(this).implementation.errorChecking && (this._readonly || (this.parentNode && this.parentNode._readonly))) {
+ throw(new DOMException(DOMException.NO_MODIFICATION_ALLOWED_ERR));
+ }
+
+ // get item index
+ var itemIndex = __findNamedItemNSIndex__(this, namespaceURI, localName);
+
+ // throw Exception if there is no matching node in this map
+ if (__ownerDocument__(this).implementation.errorChecking && (itemIndex < 0)) {
+ throw(new DOMException(DOMException.NOT_FOUND_ERR));
+ }
+
+ // get Node
+ var oldNode = this[itemIndex];
+
+ // throw Exception if Node is readonly
+ if (__ownerDocument__(this).implementation.errorChecking && oldNode._readonly) {
+ throw(new DOMException(DOMException.NO_MODIFICATION_ALLOWED_ERR));
+ }
+
+ return __removeChild__(this, itemIndex); // return removed node
+ },
+ get xml() {
+ var ret = "";
+
+ // create string containing concatenation of all (but last) Attribute string values (separated by spaces)
+ for (var i=0; i < this.length -1; i++) {
+ ret += this[i].xml +" ";
+ }
+
+ // add last Attribute to string (without trailing space)
+ if (this.length > 0) {
+ ret += this[this.length -1].xml;
+ }
+
+ return ret;
+ },
+ toString : function(){
+ return "[object NamedNodeMap]";
+ }
+
+});
+
+/**
+ * @method __findNamedItemIndex__
+ * find the item index of the node with the specified name
+ *
+ * @param name : string - the name of the required node
+ * @param isnsmap : if its a NamespaceNodeMap
+ * @return : int
+ */
+var __findNamedItemIndex__ = function(namednodemap, name, isnsmap) {
+ var ret = -1;
+ // loop through all nodes
+ for (var i=0; i -1) {
+ // found it!
+ ret = true;
+ }
+ // if node is not found, default value false is returned
+ return ret;
+}
+
+/**
+ * @method __hasAttributeNS__
+ * Returns true if specified node exists
+ *
+ * @param namespaceURI : string - the namespace URI of the required node
+ * @param localName : string - the local name of the required node
+ * @return : boolean
+ */
+var __hasAttributeNS__ = function(namednodemap, namespaceURI, localName) {
+ var ret = false;
+ // test that Named Node exists
+ var itemIndex = __findNamedItemNSIndex__(namednodemap, namespaceURI, localName);
+ if (itemIndex > -1) {
+ // found it!
+ ret = true;
+ }
+ // if node is not found, default value false is returned
+ return ret;
+}
+
+/**
+ * @method __cloneNamedNodes__
+ * Returns a NamedNodeMap containing clones of the Nodes in this NamedNodeMap
+ *
+ * @param parentNode : Node - the new parent of the cloned NodeList
+ * @param isnsmap : bool - is this a NamespaceNodeMap
+ * @return NamedNodeMap containing clones of the Nodes in this NamedNodeMap
+ */
+var __cloneNamedNodes__ = function(namednodemap, parentNode, isnsmap) {
+ var cloneNamedNodeMap = isnsmap?
+ new NamespaceNodeMap(namednodemap.ownerDocument, parentNode):
+ new NamedNodeMap(namednodemap.ownerDocument, parentNode);
+
+ // create list containing clones of all children
+ for (var i=0; i < namednodemap.length; i++) {
+ __appendChild__(cloneNamedNodeMap, namednodemap[i].cloneNode(false));
+ }
+
+ return cloneNamedNodeMap;
+};
+
+
+/**
+ * @class NamespaceNodeMap -
+ * used to represent collections of namespace nodes that can be
+ * accessed by name typically a set of Element attributes
+ *
+ * @extends NamedNodeMap
+ *
+ * @param ownerDocument : Document - the ownerDocument
+ * @param parentNode : Node - the node that the NamespaceNodeMap is attached to (or null)
+ */
+var NamespaceNodeMap = function(ownerDocument, parentNode) {
+ this.NamedNodeMap = NamedNodeMap;
+ this.NamedNodeMap(ownerDocument, parentNode);
+ __setArray__(this, []);
+};
+NamespaceNodeMap.prototype = new NamedNodeMap();
+__extend__(NamespaceNodeMap.prototype, {
+ get xml() {
+ var ret = "",
+ ns,
+ ind;
+ // identify namespaces declared local to this Element (ie, not inherited)
+ for (ind = 0; ind < this.length; ind++) {
+ // if namespace declaration does not exist in the containing node's, parentNode's namespaces
+ ns = null;
+ try {
+ var ns = this.parentNode.parentNode._namespaces.
+ getNamedItem(this[ind].localName);
+ }catch (e) {
+ //breaking to prevent default namespace being inserted into return value
+ break;
+ }
+ if (!(ns && (""+ ns.nodeValue == ""+ this[ind].nodeValue))) {
+ // display the namespace declaration
+ ret += this[ind].xml +" ";
+ }
+ }
+ return ret;
+ }
+});
+
+/**
+ * @class Namespace -
+ * The Namespace interface represents an namespace in an Element object
+ *
+ * @param ownerDocument : The Document object associated with this node.
+ */
+Namespace = function(ownerDocument) {
+ Node.apply(this, arguments);
+ // the name of this attribute
+ this.name = "";
+
+ // If this attribute was explicitly given a value in the original document,
+ // this is true; otherwise, it is false.
+ // Note that the implementation is in charge of this attribute, not the user.
+ // If the user changes the value of the attribute (even if it ends up having
+ // the same value as the default value) then the specified flag is
+ // automatically flipped to true
+ this.specified = false;
+};
+Namespace.prototype = new Node();
+__extend__(Namespace.prototype, {
get value(){
// the value of the attribute is returned as a string
return this.nodeValue;
@@ -1420,7 +3020,7 @@ __extend__(DOMNamespace.prototype, {
this.nodeValue = value+'';
},
get nodeType(){
- return DOMNode.NAMESPACE_NODE;
+ return Node.NAMESPACE_NODE;
},
get xml(){
var ret = "";
@@ -1432,57 +3032,58 @@ __extend__(DOMNamespace.prototype, {
else { // handle default namespace
ret += "xmlns=\""+ __escapeXML__(this.nodeValue) +"\"";
}
-
+
return ret;
},
toString: function(){
- return "Namespace #" + this.id;
+ return '[object Namespace]';
}
});
-$debug("Defining CharacterData");
-/*
-* CharacterData - DOM Level 2
-*/
+
/**
- * @class DOMCharacterData - parent abstract class for DOMText and DOMComment
- * @extends DOMNode
- * @author Jon van Noort (jon@webarcana.com.au)
- * @param ownerDocument : DOMDocument - The Document object associated with this node.
+ * @class CharacterData - parent abstract class for Text and Comment
+ * @extends Node
+ * @param ownerDocument : The Document object associated with this node.
*/
-var DOMCharacterData = function(ownerDocument) {
- this.DOMNode = DOMNode;
- this.DOMNode(ownerDocument);
+CharacterData = function(ownerDocument) {
+ Node.apply(this, arguments);
};
-DOMCharacterData.prototype = new DOMNode;
-__extend__(DOMCharacterData.prototype,{
+CharacterData.prototype = new Node();
+__extend__(CharacterData.prototype,{
get data(){
return this.nodeValue;
},
set data(data){
this.nodeValue = data;
},
+ get textContent(){
+ return this.nodeValue;
+ },
+ set textContent(newText){
+ this.nodeValue = newText;
+ },
get length(){return this.nodeValue.length;},
appendData: function(arg){
- // throw Exception if DOMCharacterData is readonly
+ // throw Exception if CharacterData is readonly
if (__ownerDocument__(this).implementation.errorChecking && this._readonly) {
throw(new DOMException(DOMException.NO_MODIFICATION_ALLOWED_ERR));
}
// append data
this.data = "" + this.data + arg;
},
- deleteData: function(offset, count){
- // throw Exception if DOMCharacterData is readonly
+ deleteData: function(offset, count){
+ // throw Exception if CharacterData is readonly
if (__ownerDocument__(this).implementation.errorChecking && this._readonly) {
throw(new DOMException(DOMException.NO_MODIFICATION_ALLOWED_ERR));
}
if (this.data) {
// throw Exception if offset is negative or greater than the data length,
- if (__ownerDocument__(this).implementation.errorChecking &&
+ if (__ownerDocument__(this).implementation.errorChecking &&
((offset < 0) || (offset > this.data.length) || (count < 0))) {
throw(new DOMException(DOMException.INDEX_SIZE_ERR));
}
-
+
// delete data
if(!count || (offset + count) > this.data.length) {
this.data = this.data.substring(0, offset);
@@ -1493,43 +3094,43 @@ __extend__(DOMCharacterData.prototype,{
}
},
insertData: function(offset, arg){
- // throw Exception if DOMCharacterData is readonly
+ // throw Exception if CharacterData is readonly
if(__ownerDocument__(this).implementation.errorChecking && this._readonly){
throw(new DOMException(DOMException.NO_MODIFICATION_ALLOWED_ERR));
}
-
+
if(this.data){
// throw Exception if offset is negative or greater than the data length,
- if (__ownerDocument__(this).implementation.errorChecking &&
+ if (__ownerDocument__(this).implementation.errorChecking &&
((offset < 0) || (offset > this.data.length))) {
throw(new DOMException(DOMException.INDEX_SIZE_ERR));
}
-
+
// insert data
this.data = this.data.substring(0, offset).concat(arg, this.data.substring(offset));
}else {
// throw Exception if offset is negative or greater than the data length,
- if (__ownerDocument__(this).implementation.errorChecking && (offset != 0)) {
+ if (__ownerDocument__(this).implementation.errorChecking && (offset !== 0)) {
throw(new DOMException(DOMException.INDEX_SIZE_ERR));
}
-
+
// set data
this.data = arg;
}
},
replaceData: function(offset, count, arg){
- // throw Exception if DOMCharacterData is readonly
+ // throw Exception if CharacterData is readonly
if (__ownerDocument__(this).implementation.errorChecking && this._readonly) {
throw(new DOMException(DOMException.NO_MODIFICATION_ALLOWED_ERR));
}
-
+
if (this.data) {
// throw Exception if offset is negative or greater than the data length,
- if (__ownerDocument__(this).implementation.errorChecking &&
+ if (__ownerDocument__(this).implementation.errorChecking &&
((offset < 0) || (offset > this.data.length) || (count < 0))) {
throw(new DOMException(DOMException.INDEX_SIZE_ERR));
}
-
+
// replace data
this.data = this.data.substring(0, offset).
concat(arg, this.data.substring(offset + count));
@@ -1543,7 +3144,7 @@ __extend__(DOMCharacterData.prototype,{
if (this.data) {
// throw Exception if offset is negative or greater than the data length,
// or the count is negative
- if (__ownerDocument__(this).implementation.errorChecking &&
+ if (__ownerDocument__(this).implementation.errorChecking &&
((offset < 0) || (offset > this.data.length) || (count < 0))) {
throw(new DOMException(DOMException.INDEX_SIZE_ERR));
}
@@ -1555,178 +3156,182 @@ __extend__(DOMCharacterData.prototype,{
}
}
return ret;
+ },
+ toString : function(){
+ return "[object CharacterData]";
}
});
-$w.CharacterData = DOMCharacterData;$debug("Defining Text");
-/*
-* Text - DOM Level 2
-*/
/**
- * @class DOMText - The Text interface represents the textual content (termed character data in XML) of an Element or Attr.
- * If there is no markup inside an element's content, the text is contained in a single object implementing the Text interface
- * that is the only child of the element. If there is markup, it is parsed into a list of elements and Text nodes that form the
- * list of children of the element.
- * @extends DOMCharacterData
- * @author Jon van Noort (jon@webarcana.com.au) and David Joham (djoham@yahoo.com)
- * @param ownerDocument : DOMDocument - The Document object associated with this node.
+ * @class Text
+ * The Text interface represents the textual content (termed
+ * character data in XML) of an Element or Attr.
+ * If there is no markup inside an element's content, the text is
+ * contained in a single object implementing the Text interface that
+ * is the only child of the element. If there is markup, it is
+ * parsed into a list of elements and Text nodes that form the
+ * list of children of the element.
+ * @extends CharacterData
+ * @param ownerDocument The Document object associated with this node.
*/
-var DOMText = function(ownerDocument) {
- this.DOMCharacterData = DOMCharacterData;
- this.DOMCharacterData(ownerDocument);
-
- this.nodeName = "#text";
+Text = function(ownerDocument) {
+ CharacterData.apply(this, arguments);
+ this.nodeName = "#text";
};
-DOMText.prototype = new DOMCharacterData;
-__extend__(DOMText.prototype,{
- //Breaks this Text node into two Text nodes at the specified offset,
- // keeping both in the tree as siblings. This node then only contains all the content up to the offset point.
- // And a new Text node, which is inserted as the next sibling of this node, contains all the content at and after the offset point.
+Text.prototype = new CharacterData();
+__extend__(Text.prototype,{
+ get localName(){
+ return null;
+ },
+ // Breaks this Text node into two Text nodes at the specified offset,
+ // keeping both in the tree as siblings. This node then only contains
+ // all the content up to the offset point. And a new Text node, which
+ // is inserted as the next sibling of this node, contains all the
+ // content at and after the offset point.
splitText : function(offset) {
- var data, inode;
-
+ var data,
+ inode;
// test for exceptions
if (__ownerDocument__(this).implementation.errorChecking) {
// throw Exception if Node is readonly
if (this._readonly) {
throw(new DOMException(DOMException.NO_MODIFICATION_ALLOWED_ERR));
}
-
// throw Exception if offset is negative or greater than the data length,
if ((offset < 0) || (offset > this.data.length)) {
throw(new DOMException(DOMException.INDEX_SIZE_ERR));
}
}
-
if (this.parentNode) {
// get remaining string (after offset)
data = this.substringData(offset);
-
// create new TextNode with remaining string
inode = __ownerDocument__(this).createTextNode(data);
-
// attach new TextNode
if (this.nextSibling) {
this.parentNode.insertBefore(inode, this.nextSibling);
- }
- else {
+ } else {
this.parentNode.appendChild(inode);
}
-
// remove remaining string from original TextNode
this.deleteData(offset);
}
-
return inode;
},
get nodeType(){
- return DOMNode.TEXT_NODE;
+ return Node.TEXT_NODE;
},
get xml(){
return __escapeXML__(""+ this.nodeValue);
},
toString: function(){
- return "Text #" + this._id;
+ return "[object Text]";
}
});
-$w.Text = DOMText;$debug("Defining CDATASection");
-/*
-* CDATASection - DOM Level 2
-*/
/**
- * @class DOMCDATASection - CDATA sections are used to escape blocks of text containing characters that would otherwise be regarded as markup.
- * The only delimiter that is recognized in a CDATA section is the "\]\]\>" string that ends the CDATA section
- * @extends DOMCharacterData
- * @author Jon van Noort (jon@webarcana.com.au) and David Joham (djoham@yahoo.com)
- * @param ownerDocument : DOMDocument - The Document object associated with this node.
+ * @class CDATASection
+ * CDATA sections are used to escape blocks of text containing
+ * characters that would otherwise be regarded as markup.
+ * The only delimiter that is recognized in a CDATA section is
+ * the "\]\]\>" string that ends the CDATA section
+ * @extends Text
+ * @param ownerDocument : The Document object associated with this node.
*/
-var DOMCDATASection = function(ownerDocument) {
- this.DOMText = DOMText;
- this.DOMText(ownerDocument);
-
- this.nodeName = "#cdata-section";
+CDATASection = function(ownerDocument) {
+ Text.apply(this, arguments);
+ this.nodeName = '#cdata-section';
};
-DOMCDATASection.prototype = new DOMText;
-__extend__(DOMCDATASection.prototype,{
+CDATASection.prototype = new Text();
+__extend__(CDATASection.prototype,{
get nodeType(){
- return DOMNode.CDATA_SECTION_NODE;
+ return Node.CDATA_SECTION_NODE;
},
get xml(){
return "";
},
toString : function(){
- return "CDATA #"+this._id;
+ return "[object CDATASection]";
}
});
-
-$w.CDATASection = DOMCDATASection;$debug("Defining Comment");
-/*
-* Comment - DOM Level 2
-*/
/**
- * @class DOMComment - This represents the content of a comment, i.e., all the characters between the starting ''
- * @extends DOMCharacterData
- * @author Jon van Noort (jon@webarcana.com.au)
- * @param ownerDocument : DOMDocument - The Document object associated with this node.
+ * @class Comment
+ * This represents the content of a comment, i.e., all the
+ * characters between the starting ''
+ * @extends CharacterData
+ * @param ownerDocument : The Document object associated with this node.
*/
-var DOMComment = function(ownerDocument) {
- this.DOMCharacterData = DOMCharacterData;
- this.DOMCharacterData(ownerDocument);
-
- this.nodeName = "#comment";
+Comment = function(ownerDocument) {
+ CharacterData.apply(this, arguments);
+ this.nodeName = "#comment";
};
-DOMComment.prototype = new DOMCharacterData;
-__extend__(DOMComment.prototype, {
+Comment.prototype = new CharacterData();
+__extend__(Comment.prototype, {
+ get localName(){
+ return null;
+ },
get nodeType(){
- return DOMNode.COMMENT_NODE;
+ return Node.COMMENT_NODE;
},
get xml(){
return "";
},
toString : function(){
- return "Comment #"+this._id;
+ return "[object Comment]";
}
});
-$w.Comment = DOMComment;
-$debug("Defining DocumentType");
-;/*
-* DocumentType - DOM Level 2
-*/
-var DOMDocumentType = function() {
- $error("DOMDocumentType.constructor(): Not Implemented" );
-};
-$w.DocumentType = DOMDocumentType;
-$debug("Defining Attr");
-/*
-* Attr - DOM Level 2
-*/
/**
- * @class DOMAttr - The Attr interface represents an attribute in an Element object
- * @extends DOMNode
- * @author Jon van Noort (jon@webarcana.com.au)
- * @param ownerDocument : DOMDocument - The Document object associated with this node.
+ * @author envjs team
+ * @param {Document} onwnerDocument
*/
-var DOMAttr = function(ownerDocument) {
- this.DOMNode = DOMNode;
- this.DOMNode(ownerDocument);
-
- this.ownerElement = null; // set when Attr is added to NamedNodeMap
+DocumentType = function(ownerDocument) {
+ Node.apply(this, arguments);
+ this.systemId = null;
+ this.publicId = null;
};
-DOMAttr.prototype = new DOMNode;
-__extend__(DOMAttr.prototype, {
+DocumentType.prototype = new Node();
+__extend__({
+ get name(){
+ return this.nodeName;
+ },
+ get entities(){
+ return null;
+ },
+ get internalSubsets(){
+ return null;
+ },
+ get notations(){
+ return null;
+ },
+ toString : function(){
+ return "[object DocumentType]";
+ }
+});
+
+/**
+ * @class Attr
+ * The Attr interface represents an attribute in an Element object
+ * @extends Node
+ * @param ownerDocument : The Document object associated with this node.
+ */
+Attr = function(ownerDocument) {
+ Node.apply(this, arguments);
+ // set when Attr is added to NamedNodeMap
+ this.ownerElement = null;
+ //TODO: our implementation of Attr is incorrect because we don't
+ // treat the value of the attribute as a child text node.
+};
+Attr.prototype = new Node();
+__extend__(Attr.prototype, {
// the name of this attribute
get name(){
return this.nodeName;
},
- set name(name){
- this.nodeName = name;
- },
// the value of the attribute is returned as a string
get value(){
- return this.nodeValue;
+ return this.nodeValue||'';
},
set value(value){
// throw Exception if Attribute is readonly
@@ -1736,46 +3341,50 @@ __extend__(DOMAttr.prototype, {
// delegate to node
this.nodeValue = value;
},
+ get textContent(){
+ return this.nodeValue;
+ },
+ set textContent(newText){
+ this.nodeValue = newText;
+ },
get specified(){
- return (this.value.length > 0);
+ return (this !== null && this !== undefined);
},
get nodeType(){
- return DOMNode.ATTRIBUTE_NODE;
+ return Node.ATTRIBUTE_NODE;
},
- get xml(){
- return this.nodeName + '="' + __escapeXML__(this.nodeValue) + '" ';
+ get xml() {
+ if (this.nodeValue) {
+ return __escapeXML__(this.nodeValue+"");
+ } else {
+ return '';
+ }
},
- toString : function(){
- return "Attr #" + this._id + " " + this.name;
+ toString : function() {
+ return '[object Attr]';
}
});
-$w.Attr = DOMAttr;
-$debug("Defining Element");
+
/**
- * @class DOMElement - By far the vast majority of objects (apart from text) that authors encounter
- * when traversing a document are Element nodes.
- * @extends DOMNode
- * @author Jon van Noort (jon@webarcana.com.au) and David Joham (djoham@yahoo.com)
- * @param ownerDocument : DOMDocument - The Document object associated with this node.
+ * @class Element -
+ * By far the vast majority of objects (apart from text)
+ * that authors encounter when traversing a document are
+ * Element nodes.
+ * @extends Node
+ * @param ownerDocument : The Document object associated with this node.
*/
-var DOMElement = function(ownerDocument) {
- this.DOMNode = DOMNode;
- this.DOMNode(ownerDocument);
- this.id = ""; // the ID of the element
+Element = function(ownerDocument) {
+ Node.apply(this, arguments);
+ this.attributes = new NamedNodeMap(this.ownerDocument, this);
};
-DOMElement.prototype = new DOMNode;
-__extend__(DOMElement.prototype, {
+Element.prototype = new Node();
+__extend__(Element.prototype, {
// The name of the element.
get tagName(){
- return this.nodeName;
+ return this.nodeName;
},
- set tagName(name){
- this.nodeName = name;
- },
- addEventListener : function(){ window.addEventListener.apply(this, arguments) },
- removeEventListener : function(){ window.removeEventListener.apply(this, arguments) },
- dispatchEvent : function(){ window.dispatchEvent.apply(this, arguments) },
+
getAttribute: function(name) {
var ret = null;
// if attribute exists, use it
@@ -1783,51 +3392,54 @@ __extend__(DOMElement.prototype, {
if (attr) {
ret = attr.value;
}
- return ret; // if Attribute exists, return its value, otherwise, return ""
+ // if Attribute exists, return its value, otherwise, return null
+ return ret;
},
setAttribute : function (name, value) {
// if attribute exists, use it
var attr = this.attributes.getNamedItem(name);
- var value = value+'';
- //I had to add this check becuase as the script initializes
+ //console.log('attr %s', attr);
+ //I had to add this check because as the script initializes
//the id may be set in the constructor, and the html element
//overrides the id property with a getter/setter.
if(__ownerDocument__(this)){
- if (!attr) {
- attr = __ownerDocument__(this).createAttribute(name); // otherwise create it
+ if (attr===null||attr===undefined) {
+ // otherwise create it
+ attr = __ownerDocument__(this).createAttribute(name);
+ //console.log('attr %s', attr);
}
-
-
+
+
// test for exceptions
if (__ownerDocument__(this).implementation.errorChecking) {
// throw Exception if Attribute is readonly
if (attr._readonly) {
throw(new DOMException(DOMException.NO_MODIFICATION_ALLOWED_ERR));
}
-
+
// throw Exception if the value string contains an illegal character
- if (!__isValidString__(value)) {
+ if (!__isValidString__(value+'')) {
throw(new DOMException(DOMException.INVALID_CHARACTER_ERR));
}
}
-
- if (__isIdDeclaration__(name)) {
- // this.id = value; // cache ID for getElementById()
- }
-
+
// assign values to properties (and aliases)
- attr.value = value;
-
+ attr.value = value + '';
+
// add/replace Attribute in NamedNodeMap
this.attributes.setNamedItem(attr);
+ //console.log('element setNamedItem %s', attr);
+ }else{
+ console.warn('Element has no owner document '+this.tagName+
+ '\n\t cant set attribute ' + name + ' = '+value );
}
},
removeAttribute : function removeAttribute(name) {
- // delegate to DOMNamedNodeMap.removeNamedItem
+ // delegate to NamedNodeMap.removeNamedItem
return this.attributes.removeNamedItem(name);
},
getAttributeNode : function getAttributeNode(name) {
- // delegate to DOMNamedNodeMap.getNamedItem
+ // delegate to NamedNodeMap.getNamedItem
return this.attributes.getNamedItem(name);
},
setAttributeNode: function(newAttr) {
@@ -1835,7 +3447,7 @@ __extend__(DOMElement.prototype, {
if (__isIdDeclaration__(newAttr.name)) {
this.id = newAttr.value; // cache ID for getElementById()
}
- // delegate to DOMNamedNodeMap.setNamedItem
+ // delegate to NamedNodeMap.setNamedItem
return this.attributes.setNamedItem(newAttr);
},
removeAttributeNode: function(oldAttr) {
@@ -1843,20 +3455,20 @@ __extend__(DOMElement.prototype, {
if (__ownerDocument__(this).implementation.errorChecking && oldAttr._readonly) {
throw(new DOMException(DOMException.NO_MODIFICATION_ALLOWED_ERR));
}
-
+
// get item index
var itemIndex = this.attributes._findItemIndex(oldAttr._id);
-
+
// throw Exception if node does not exist in this map
if (__ownerDocument__(this).implementation.errorChecking && (itemIndex < 0)) {
throw(new DOMException(DOMException.NOT_FOUND_ERR));
}
-
+
return this.attributes._removeChild(itemIndex);
},
getAttributeNS : function(namespaceURI, localName) {
var ret = "";
- // delegate to DOMNAmedNodeMap.getNamedItemNS
+ // delegate to NAmedNodeMap.getNamedItemNS
var attr = this.attributes.getNamedItemNS(namespaceURI, localName);
if (attr) {
ret = attr.value;
@@ -1864,52 +3476,53 @@ __extend__(DOMElement.prototype, {
return ret; // if Attribute exists, return its value, otherwise return ""
},
setAttributeNS : function(namespaceURI, qualifiedName, value) {
- // call DOMNamedNodeMap.getNamedItem
+ // call NamedNodeMap.getNamedItem
+ //console.log('setAttributeNS %s %s %s', namespaceURI, qualifiedName, value);
var attr = this.attributes.getNamedItem(namespaceURI, qualifiedName);
-
+
if (!attr) { // if Attribute exists, use it
// otherwise create it
attr = __ownerDocument__(this).createAttributeNS(namespaceURI, qualifiedName);
}
-
- var value = value+'';
-
+
+ value = '' + value;
+
// test for exceptions
if (__ownerDocument__(this).implementation.errorChecking) {
// throw Exception if Attribute is readonly
if (attr._readonly) {
throw(new DOMException(DOMException.NO_MODIFICATION_ALLOWED_ERR));
}
-
+
// throw Exception if the Namespace is invalid
- if (!__isValidNamespace__(namespaceURI, qualifiedName)) {
+ if (!__isValidNamespace__(this.ownerDocument, namespaceURI, qualifiedName, true)) {
throw(new DOMException(DOMException.NAMESPACE_ERR));
}
-
+
// throw Exception if the value string contains an illegal character
if (!__isValidString__(value)) {
throw(new DOMException(DOMException.INVALID_CHARACTER_ERR));
}
}
-
+
// if this Attribute is an ID
- if (__isIdDeclaration__(name)) {
- this.id = value; // cache ID for getElementById()
- }
-
+ //if (__isIdDeclaration__(name)) {
+ // this.id = value;
+ //}
+
// assign values to properties (and aliases)
attr.value = value;
attr.nodeValue = value;
-
- // delegate to DOMNamedNodeMap.setNamedItem
+
+ // delegate to NamedNodeMap.setNamedItem
this.attributes.setNamedItemNS(attr);
},
removeAttributeNS : function(namespaceURI, localName) {
- // delegate to DOMNamedNodeMap.removeNamedItemNS
+ // delegate to NamedNodeMap.removeNamedItemNS
return this.attributes.removeNamedItemNS(namespaceURI, localName);
},
getAttributeNodeNS : function(namespaceURI, localName) {
- // delegate to DOMNamedNodeMap.getNamedItemNS
+ // delegate to NamedNodeMap.getNamedItemNS
return this.attributes.getNamedItemNS(namespaceURI, localName);
},
setAttributeNodeNS : function(newAttr) {
@@ -1917,52 +3530,74 @@ __extend__(DOMElement.prototype, {
if ((newAttr.prefix == "") && __isIdDeclaration__(newAttr.name)) {
this.id = newAttr.value+''; // cache ID for getElementById()
}
-
- // delegate to DOMNamedNodeMap.setNamedItemNS
+
+ // delegate to NamedNodeMap.setNamedItemNS
return this.attributes.setNamedItemNS(newAttr);
},
hasAttribute : function(name) {
- // delegate to DOMNamedNodeMap._hasAttribute
+ // delegate to NamedNodeMap._hasAttribute
return __hasAttribute__(this.attributes,name);
},
hasAttributeNS : function(namespaceURI, localName) {
- // delegate to DOMNamedNodeMap._hasAttributeNS
+ // delegate to NamedNodeMap._hasAttributeNS
return __hasAttributeNS__(this.attributes, namespaceURI, localName);
},
get nodeType(){
- return DOMNode.ELEMENT_NODE;
+ return Node.ELEMENT_NODE;
},
get xml() {
- var ret = "";
-
+ var ret = "",
+ ns = "",
+ attrs,
+ attrstring,
+ i;
+
// serialize namespace declarations
- var ns = this._namespaces.xml;
- if (ns.length > 0) ns = " "+ ns;
-
+ if (this.namespaceURI ){
+ if((this === this.ownerDocument.documentElement) ||
+ (!this.parentNode)||
+ (this.parentNode && (this.parentNode.namespaceURI !== this.namespaceURI))) {
+ ns = ' xmlns' + (this.prefix?(':'+this.prefix):'') +
+ '="' + this.namespaceURI + '"';
+ }
+ }
+
// serialize Attribute declarations
- var attrs = this.attributes.xml;
- if (attrs.length > 0) attrs = " "+ attrs;
-
- // serialize this Element
- ret += "<" + this.nodeName.toLowerCase() + ns + attrs +">";
- ret += this.childNodes.xml;
- ret += "" + this.nodeName.toLowerCase()+">";
-
+ attrs = this.attributes;
+ attrstring = "";
+ for(i=0;i< attrs.length;i++){
+ if(attrs[i].name.match('xmlns:')) {
+ attrstring += " "+attrs[i].name+'="'+attrs[i].xml+'"';
+ }
+ }
+ for(i=0;i< attrs.length;i++){
+ if(!attrs[i].name.match('xmlns:')) {
+ attrstring += " "+attrs[i].name+'="'+attrs[i].xml+'"';
+ }
+ }
+
+ if(this.hasChildNodes()){
+ // serialize this Element
+ ret += "<" + this.tagName + ns + attrstring +">";
+ ret += this.childNodes.xml;
+ ret += "" + this.tagName + ">";
+ }else{
+ ret += "<" + this.tagName + ns + attrstring +"/>";
+ }
+
return ret;
},
toString : function(){
- return "Element #"+this._id + " "+ this.tagName + (this.id?" => "+this.id:'');
+ return '[object Element]';
}
});
-
-$w.Element = DOMElement;
/**
* @class DOMException - raised when an operation is impossible to perform
* @author Jon van Noort (jon@webarcana.com.au)
* @param code : int - the exception code (one of the DOMException constants)
*/
-var DOMException = function(code) {
- this.code = code;
+DOMException = function(code) {
+ this.code = code;
};
// DOMException constants
@@ -1984,1267 +3619,106 @@ DOMException.SYNTAX_ERR = 12;
DOMException.INVALID_MODIFICATION_ERR = 13;
DOMException.NAMESPACE_ERR = 14;
DOMException.INVALID_ACCESS_ERR = 15;
-$debug("Defining DocumentFragment");
-/*
-* DocumentFragment - DOM Level 2
-*/
+
/**
- * @class DOMDocumentFragment - DocumentFragment is a "lightweight" or "minimal" Document object.
- * @extends DOMNode
- * @author Jon van Noort (jon@webarcana.com.au) and David Joham (djoham@yahoo.com)
- * @param ownerDocument : DOMDocument - The Document object associated with this node.
+ * @class DocumentFragment -
+ * DocumentFragment is a "lightweight" or "minimal" Document object.
+ * @extends Node
+ * @param ownerDocument : The Document object associated with this node.
*/
-var DOMDocumentFragment = function(ownerDocument) {
- this.DOMNode = DOMNode;
- this.DOMNode(ownerDocument);
- this.nodeName = "#document-fragment";
+DocumentFragment = function(ownerDocument) {
+ Node.apply(this, arguments);
+ this.nodeName = "#document-fragment";
};
-DOMDocumentFragment.prototype = new DOMNode;
-__extend__(DOMDocumentFragment.prototype,{
+DocumentFragment.prototype = new Node();
+__extend__(DocumentFragment.prototype,{
get nodeType(){
- return DOMNode.DOCUMENT_FRAGMENT_NODE;
+ return Node.DOCUMENT_FRAGMENT_NODE;
},
get xml(){
var xml = "",
- count = this.childNodes.length;
-
+ count = this.childNodes.length;
+
// create string concatenating the serialized ChildNodes
for (var i = 0; i < count; i++) {
xml += this.childNodes.item(i).xml;
}
-
+
return xml;
},
toString : function(){
- return "DocumentFragment #"+this._id;
+ return "[object DocumentFragment]";
+ },
+ get localName(){
+ return null;
}
});
-$w.DocumentFragment = DOMDocumentFragment;
-$debug("Defining ProcessingInstruction");
-/*
-* ProcessingInstruction - DOM Level 2
-*/
+
/**
- * @class DOMProcessingInstruction - The ProcessingInstruction interface represents a "processing instruction",
- * used in XML as a way to keep processor-specific information in the text of the document
- * @extends DOMNode
+ * @class ProcessingInstruction -
+ * The ProcessingInstruction interface represents a
+ * "processing instruction", used in XML as a way to
+ * keep processor-specific information in the text of
+ * the document
+ * @extends Node
* @author Jon van Noort (jon@webarcana.com.au)
- * @param ownerDocument : DOMDocument - The Document object associated with this node.
+ * @param ownerDocument : The Document object associated with this node.
*/
-var DOMProcessingInstruction = function(ownerDocument) {
- this.DOMNode = DOMNode;
- this.DOMNode(ownerDocument);
+ProcessingInstruction = function(ownerDocument) {
+ Node.apply(this, arguments);
};
-DOMProcessingInstruction.prototype = new DOMNode;
-__extend__(DOMProcessingInstruction.prototype, {
+ProcessingInstruction.prototype = new Node();
+__extend__(ProcessingInstruction.prototype, {
get data(){
return this.nodeValue;
},
set data(data){
- // throw Exception if DOMNode is readonly
+ // throw Exception if Node is readonly
if (__ownerDocument__(this).errorChecking && this._readonly) {
throw(new DOMException(DOMException.NO_MODIFICATION_ALLOWED_ERR));
}
this.nodeValue = data;
},
+ get textContent(){
+ return this.data;
+ },
+ get localName(){
+ return null;
+ },
get target(){
// The target of this processing instruction.
// XML defines this as being the first token following the markup that begins the processing instruction.
// The content of this processing instruction.
return this.nodeName;
},
+ set target(value){
+ // The target of this processing instruction.
+ // XML defines this as being the first token following the markup that begins the processing instruction.
+ // The content of this processing instruction.
+ this.nodeName = value;
+ },
get nodeType(){
- return DOMNode.PROCESSING_INSTRUCTION_NODE;
+ return Node.PROCESSING_INSTRUCTION_NODE;
},
get xml(){
- return "" + this.nodeName +" "+ this.nodeValue + " ?>";
+ return "" + this.nodeName +" "+ this.nodeValue + "?>";
},
toString : function(){
- return "ProcessingInstruction #"+this._id;
- }
-});
-
-$w.ProcessesingInstruction = DOMProcessingInstruction;
-$debug("Defining DOMParser");
-/*
-* DOMParser
-*/
-
-var DOMParser = function(){};
-__extend__(DOMParser.prototype,{
- parseFromString: function(xmlString){
- //$log("Parsing XML String: " +xmlString);
- return document.implementation.createDocument().loadXML(xmlString);
- }
-});
-
-$debug("Initializing Internal DOMParser.");
-//keep one around for internal use
-$domparser = new DOMParser();
-
-$w.DOMParser = DOMParser;
-// =========================================================================
-//
-// xmlsax.js - an XML SAX parser in JavaScript.
-//
-// version 3.1
-//
-// =========================================================================
-//
-// Copyright (C) 2001 - 2002 David Joham (djoham@yahoo.com) and Scott Severtson
-//
-// This library is free software; you can redistribute it and/or
-// modify it under the terms of the GNU Lesser General Public
-// License as published by the Free Software Foundation; either
-// version 2.1 of the License, or (at your option) any later version.
-
-// This library is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-// Lesser General Public License for more details.
-
-// You should have received a copy of the GNU Lesser General Public
-// License along with this library; if not, write to the Free Software
-// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
-//
-//
-// Visit the XML for