[Hw4mdl-svn] SF.net SVN: hw4mdl: [92] trunk/moodle/mod/liveclassroom
Brought to you by:
jhlinder,
trollinger
From: <sh...@us...> - 2006-10-20 13:55:38
|
Revision: 92 http://svn.sourceforge.net/hw4mdl/?rev=92&view=rev Author: shazan Date: 2006-10-20 06:55:25 -0700 (Fri, 20 Oct 2006) Log Message: ----------- Added Paths: ----------- trunk/moodle/mod/liveclassroom/css/ trunk/moodle/mod/liveclassroom/css/StyleSheet.css trunk/moodle/mod/liveclassroom/js/ trunk/moodle/mod/liveclassroom/js/xmldom.js Added: trunk/moodle/mod/liveclassroom/css/StyleSheet.css =================================================================== --- trunk/moodle/mod/liveclassroom/css/StyleSheet.css (rev 0) +++ trunk/moodle/mod/liveclassroom/css/StyleSheet.css 2006-10-20 13:55:25 UTC (rev 92) @@ -0,0 +1,241 @@ +body +{ background-color:#ffffff; + margin-top:0px; + margin-bottom:0px; + margin-right:0px; + margin-left:0px; + font-family: Verdana,Arial,Helvetica,sans-serif; + font-size:70%; +} +/* size remaining text relative to baseline */ +/* some indiv classes and elements have different sizes, later in doc */ +body a, +body table, body td, body th, +body p, body div, body li, body li li, +body input, body textarea, body select, body option ,td textarea +{font-size:100%;} + + + + +.page_title +{ +font-family: Verdana, Arial, Helvetica, sans-serif; +font-size:14px; +font-weight:bold; +color:#3c4b5b; +vertical-align: middle; +} +.area_title +{ +font-family: Verdana, Arial, Helvetica, sans-serif; +font-size:12px; +font-weight:bold; +color:#3c4b5b; +vertical-align: middle; +background-color:#c4cedc; + +padding-left:2px; +vertical-align:middle; +} + +table.tab +{ + margin-top:10px; + margin-left:20px; + width:100%; +} + +span.tab +{ + position: relative; + display: none; + height:190px +} +span.current_tab +{ + position: relative; + display: block; + height:190px +} +td.tab_Select +{ +background-image:url(pictures/tab_Select.gif); + background-repeat: no-repeat; + width: 78px; + font-size: 10pt; + font-family: Verdana; + } +h2 +{ + font-family: Verdana, Arial, Helvetica, sans-serif; + font-size:13px; + font-weight:bold; + color:#3c4b5b; + vertical-align: middle; +} + +tr.headcell td, tr.headcell th, .headcell { + border-left:1px solid #fff !important; + border-top:1px solid #fff !important; + color:#394859 !important; + background-color:#c4cedc !important; + font-weight:bold !important; + text-decoration:none !important; + text-align:left; + font-size:10px; +} + +/* color: fixed? */ +tr.subcell td, tr.subcell th, .subcell { + border-left:1px solid #ffffff; + border-top:1px solid #ffffff; + background-color:#e4eaef; + font-weight:normal; + color:black; + text-decoration:none; +} + +/* color: fixed? */ +tr.subcell2 td, tr.subcell2 th, .subcell2 { + border-left:1px solid #ffffff; + border-top:1px solid #ffffff; + background-color:#e4eaef; + font-weight:normal; + color:black; + text-decoration:none; +} +.datatable { + background-color:#ffffff; + border-left:1px solid #999; + border-top:1px solid #999; + border-right:2px solid #888; + border-bottom:2px solid #888; +} + + +/* color: white (fixed) */ +tr.oddRow td, tr.oddRow th, .oddRow { + border-left:1px solid #ffffff; + background-color:#fff; + font-weight:normal; + color:black; + text-decoration:none +} + +/* color: gray (fixed?) */ +tr.evenRow td, tr.evenRow th, .evenRow { + border-left:1px solid #ffffff; + background-color:#f0f0f0; + font-weight:normal; + color:black; + text-decoration:none +} +/* color: fixed */ +tr.divider td, tr.divider th, td.divider, th.divider, .divider { + border-bottom:1px solid #797979; +} +tr.divider2 td, tr.divider2 th, td.divider2, th.divider2, .divider2 { + border-bottom:1px solid #d9d9d9; +} +.clear,table.clear td,tr.clear,tr.clear td,table.clear { + border:none !important; +} + +a { +text-decoration:none; + color:Black; } + +a:hover { + text-decoration:none; + color:Black; } + +td.action,input.action{ + background-image:url(../pictures/general-empty.png); + background-repeat :no-repeat; + background-position:center; + text-decoration:none; + color:Black; +} +td.action:hover,input.action:hover{ + background-image:url(../pictures/general-empty-over.png); + background-repeat :no-repeat; + background-position:center; + text-decoration:none; + color:Black; +} +.alert +{ + color:Red; +} + + + +a.room { color:#889EB3; + +text-decoration:none; +display:block; +width:100%; + +} + +a.room:hover {color:#889EB3; + + + text-decoration:none; + border: none; + + background-position: 3px 4px; + +} + + +.info a{ + position:relative; /*this is the key*/ + z-index:24; + color:#000; + text-decoration:none} + +.info a:hover{z-index:25;text-decoration:underline;} + +.info a span{display: none;font-size:8pt;} + +.info a:hover span{ /*the span will display just on :hover state*/ + font-size:8pt; + display:block; + position:absolute; + top:1.5em; left:5em; width:28em; + border:1px solid #FFF99F; + background-color:#FFF99F; color:#000; + text-align: center} + + + +.button_disabled a{ color:#666666; + + text-decoration:none; + font-size: 9px; + +} +.button_disabled a:hover{ color:#666666; + + text-decoration:none; + font-size: 9px; + + +} + +.button_enabled a{ color:black; + + text-decoration:none; + font-size: 9px; + +} +.button_enabled a:hover{ color:black; + + text-decoration:none; + font-size: 9px; + display:block; + background-color:#d7d8d9; + cursor:hand; +} \ No newline at end of file Property changes on: trunk/moodle/mod/liveclassroom/css/StyleSheet.css ___________________________________________________________________ Name: svn:mime-type + text/css Name: svn:keywords + Date Revision Author Id Name: svn:eol-style + native Added: trunk/moodle/mod/liveclassroom/js/xmldom.js =================================================================== --- trunk/moodle/mod/liveclassroom/js/xmldom.js (rev 0) +++ trunk/moodle/mod/liveclassroom/js/xmldom.js 2006-10-20 13:55:25 UTC (rev 92) @@ -0,0 +1,1524 @@ +// ========================================================================= +// +// xmldom.js - an XML DOM parser in JavaScript. +// +// This is the classic DOM that has shipped with XML for <SCRIPT> +// since the beginning. For a more standards-compliant DOM, you may +// wish to use the standards-compliant W3C DOM that is included +// with XML for <SCRIPT> versions 3.0 and above +// +// version 3.1 +// +// ========================================================================= +// +// Copyright (C) 2000 - 2002, 2003 Michael Houghton (mi...@id...), Raymond Irving and David Joham (dj...@ya...) +// +// 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 <SCRIPT> home page at http://xmljs.sourceforge.net +// + + +// ========================================================================= +// ========================================================================= +// ========================================================================= + +// CONSTANTS + +// ========================================================================= +// ========================================================================= +// ========================================================================= + +//define the characters which constitute whitespace, and quotes +var whitespace = "\n\r\t "; +var quotes = "\"'"; + + +// ========================================================================= +// ========================================================================= +// ========================================================================= + +// CONVENIENCE FUNCTIONS + +// ========================================================================= +// ========================================================================= +// ========================================================================= + + +function convertEscapes(str) { + /******************************************************************************************************************* + function: convertEscapes + + Author: David Joham <dj...@ya...> + + Description: + Characters such as less-than signs, greater-than signs and ampersands are + illegal in XML syntax and must be escaped before being inserted into the DOM. + This function is a convience function to take those escaped characters and + return them to their original values for processing outside the parser + + This XML Parser automagically converts the content of the XML elements to + their non-escaped values when xmlNode.getText() is called for every element + except CDATA. + + EXAMPLES: + + & == & + < == < + > == > + + *********************************************************************************************************************/ + // not all Konqueror installations have regex support for some reason. Here's the original code using regexes + // that is probably a little more efficient if it matters to you + /* + var escAmpRegEx = /&/g; + var escLtRegEx = /</g; + var escGtRegEx = />/g; + + str = str.replace(escAmpRegEx, "&"); + str = str.replace(escLtRegEx, "<"); + str = str.replace(escGtRegEx, ">"); + */ + var gt; + + //< + gt = -1; + while (str.indexOf("<", gt + 1) > -1) { + var gt = str.indexOf("<", gt + 1); + var newStr = str.substr(0, gt); + newStr += "<"; + newStr = newStr + str.substr(gt + 4, str.length); + str = newStr; + } + + //> + gt = -1; + while (str.indexOf(">", gt + 1) > -1) { + var gt = str.indexOf(">", gt + 1); + var newStr = str.substr(0, gt); + newStr += ">"; + newStr = newStr + str.substr(gt + 4, str.length); + str = newStr; + } + + //& + gt = -1; + while (str.indexOf("&", gt + 1) > -1) { + var gt = str.indexOf("&", gt + 1); + var newStr = str.substr(0, gt); + newStr += "&"; + newStr = newStr + str.substr(gt + 5, str.length); + str = newStr; + } + + return str; +} // end function convertEscapes + + +function convertToEscapes(str) { + /******************************************************************************************************************* + function: convertToEscapes + + Author: David Joham dj...@ya... + + Description: + Characters such as less-than signs, greater-than signs and ampersands are + illegal in XML syntax. This function is a convience function to escape those + characters out to there legal values. + + EXAMPLES: + + < == < + > == > + & == & + *********************************************************************************************************************/ + // not all Konqueror installations have regex support for some reason. Here's the original code using regexes + // that is probably a little more efficient if it matters to you + /* + var escAmpRegEx = /&/g; + var escLtRegEx = /</g; + var escGtRegEx = />/g; + str = str.replace(escAmpRegEx, "&"); + str = str.replace(escLtRegEx, "<"); + str = str.replace(escGtRegEx, ">"); + */ + + // start with & + var gt = -1; + while (str.indexOf("&", gt + 1) > -1) { + gt = str.indexOf("&", gt + 1); + var newStr = str.substr(0, gt); + newStr += "&"; + newStr = newStr + str.substr(gt + 1, str.length); + str = newStr; + } + + // now < + gt = -1; + while (str.indexOf("<", gt + 1) > -1) { + var gt = str.indexOf("<", gt + 1); + var newStr = str.substr(0, gt); + newStr += "<"; + newStr = newStr + str.substr(gt + 1, str.length); + str = newStr; + } + + //now > + gt = -1; + while (str.indexOf(">", gt + 1) > -1) { + var gt = str.indexOf(">", gt + 1); + var newStr = str.substr(0, gt); + newStr += ">"; + newStr = newStr + str.substr(gt + 1, str.length); + str = newStr; + } + + + return str; +} // end function convertToEscapes + + +function _displayElement(domElement, strRet) { + /******************************************************************************************************************* + function: _displayElement + + Author: dj...@ya... + + Description: + returns the XML string associated with the DOM element passed in + recursively calls itself if child elements are found + + *********************************************************************************************************************/ + if(domElement==null) { + return; + } + if(!(domElement.nodeType=='ELEMENT')) { + return; + } + + var tagName = domElement.tagName; + var tagInfo = ""; + tagInfo = "<" + tagName; + + // attributes + var attributeList = domElement.getAttributeNames(); + + for(var intLoop = 0; intLoop < attributeList.length; intLoop++) { + var attribute = attributeList[intLoop]; + tagInfo = tagInfo + " " + attribute + "="; + tagInfo = tagInfo + "\"" + domElement.getAttribute(attribute) + "\""; + } + + //close the element name + tagInfo = tagInfo + ">"; + + strRet=strRet+tagInfo; + + // children + if(domElement.children!=null) { + var domElements = domElement.children; + for(var intLoop = 0; intLoop < domElements.length; intLoop++) { + var childNode = domElements[intLoop]; + if(childNode.nodeType=='COMMENT') { + strRet = strRet + "<!--" + childNode.content + "-->"; + } + + else if(childNode.nodeType=='TEXT') { + var cont = trim(childNode.content,true,true); + strRet = strRet + childNode.content; + } + + else if (childNode.nodeType=='CDATA') { + var cont = trim(childNode.content,true,true); + strRet = strRet + "<![CDATA[" + cont + "]]>"; + } + + else { + strRet = _displayElement(childNode, strRet); + } + } // end looping through the DOM elements + } // end checking for domElements.children = null + + //ending tag + strRet = strRet + "</" + tagName + ">"; + return strRet; +} // end function displayElement + + +function firstWhiteChar(str,pos) { + /******************************************************************************************************************* + function: firstWhiteChar + + Author: ma...@ps... ? + + Description: + return the position of the first whitespace character in str after position pos + + *********************************************************************************************************************/ + if (isEmpty(str)) { + return -1; + } + + while(pos < str.length) { + if (whitespace.indexOf(str.charAt(pos))!=-1) { + return pos; + } + else { + pos++; + } + } + return str.length; +} // end function firstWhiteChar + + +function isEmpty(str) { + /******************************************************************************************************************* + function: isEmpty + + Author: mi...@id... + + Description: + convenience function to identify an empty string + + *********************************************************************************************************************/ + return (str==null) || (str.length==0); + +} // end function isEmpty + +function trim(trimString, leftTrim, rightTrim) { + /******************************************************************************************************************* + function: trim + + Author: ma...@ps... + + Description: + helper function to trip a string (trimString) of leading (leftTrim) + and trailing (rightTrim) whitespace + + *********************************************************************************************************************/ + if (isEmpty(trimString)) { + return ""; + } + + // the general focus here is on minimal method calls - hence only one + // substring is done to complete the trim. + + if (leftTrim == null) { + leftTrim = true; + } + + if (rightTrim == null) { + rightTrim = true; + } + + var left=0; + var right=0; + var i=0; + var k=0; + + // modified to properly handle strings that are all whitespace + if (leftTrim == true) { + while ((i<trimString.length) && (whitespace.indexOf(trimString.charAt(i++))!=-1)) { + left++; + } + } + if (rightTrim == true) { + k=trimString.length-1; + while((k>=left) && (whitespace.indexOf(trimString.charAt(k--))!=-1)) { + right++; + } + } + return trimString.substring(left, trimString.length - right); +} // end function trim + + + + + + + + + +// ========================================================================= +// ========================================================================= +// ========================================================================= +// XML DOC FUNCTIONS +// ========================================================================= +// ========================================================================= +// ========================================================================= + +function XMLDoc(source, errFn) { + /******************************************************************************************************************* + function: XMLDoc + + Author: mi...@id... + + Description: + a constructor for an XML document + source: the string containing the document + errFn: the (optional) function used to log errors + *********************************************************************************************************************/ + // stack for document construction + + this.topNode=null; + + // set up the properties and methods for this object + + this.errFn = errFn; // user defined error functions + + this.createXMLNode = _XMLDoc_createXMLNode; + this.error = _XMLDoc_error; + this.getUnderlyingXMLText = _XMLDoc_getUnderlyingXMLText; + this.handleNode = _XMLDoc_handleNode; + this.hasErrors = false; // were errors found during the parse? + this.insertNodeAfter = _XMLDoc_insertNodeAfter; + this.insertNodeInto = _XMLDoc_insertNodeInto; + this.loadXML = _XMLDoc_loadXML; + this.parse = _XMLDoc_parse; + this.parseAttribute = _XMLDoc_parseAttribute; + this.parseDTD = _XMLDoc_parseDTD; + this.parsePI = _XMLDoc_parsePI; + this.parseTag = _XMLDoc_parseTag; + this.removeNodeFromTree = _XMLDoc_removeNodeFromTree; + this.replaceNodeContents = _XMLDoc_replaceNodeContents; + this.selectNode = _XMLDoc_selectNode; + this.selectNodeText = _XMLDoc_selectNodeText; + this.source = source; // the string source of the document + + // parse the document + + if (this.parse()) { + // we've run out of markup - check the stack is now empty + if (this.topNode!=null) { + return this.error("expected close " + this.topNode.tagName); + } + else { + return true; + } + } +} // end function XMLDoc + + +function _XMLDoc_createXMLNode(strXML) { + /******************************************************************************************************************* + function: _XMLDoc_createXMLNode + + Author: dj...@ya... + + Description: + convienience function to create a new node that inherits + the properties of the document object + *********************************************************************************************************************/ + return new XMLDoc(strXML, this.errFn).docNode; + +} // end function _XMLDoc_createXMLNode + + +function _XMLDoc_error(str) { + /******************************************************************************************************************* + function: _XMLDoc_error + + Author: mi...@id... + + Description: + used to log an error in parsing or validating + *********************************************************************************************************************/ + + this.hasErrors=true; + if(this.errFn){ + this.errFn("ERROR: " + str); + }else if(this.onerror){ + this.onerror("ERROR: " + str); + } + return 0; + +} // end function _XMLDoc_error + + +function _XMLDoc_getTagNameParams(tag,obj){ + /******************************************************************************************************************* + function: _XMLDoc_getTagNameParams + + Author: xw...@ya... + + Description: + convienience function for the nodeSearch routines + *********************************************************************************************************************/ + var elm=-1,e,s=tag.indexOf('['); + var attr=[]; + if(s>=0){ + e=tag.indexOf(']'); + if(e>=0)elm=tag.substr(s+1,(e-s)-1); + else obj.error('expected ] near '+tag); + tag=tag.substr(0,s); + if(isNaN(elm) && elm!='*'){ + attr=elm.substr(1,elm.length-1); // remove @ + attr=attr.split('='); + if(attr[1]) { //remove " + s=attr[1].indexOf('"'); + attr[1]=attr[1].substr(s+1,attr[1].length-1); + e=attr[1].indexOf('"'); + if(e>=0) attr[1]=attr[1].substr(0,e); + else obj.error('expected " near '+tag) + };elm=-1; + }else if(elm=='*') elm=-1; + } + return [tag,elm,attr[0],attr[1]] +} // end function _XMLDoc_getTagNameParams + + +function _XMLDoc_getUnderlyingXMLText() { + /******************************************************************************************************************* + function: _XMLDoc_getUnderlyingXMLText + + Author: dj...@ya... + + Description: + kicks off the process that returns the XML text representation of the XML + document inclusive of any changes made by the manipulation of the DOM + *********************************************************************************************************************/ + var strRet = ""; + //for now, hardcode the xml version 1 information. When we handle Processing Instructions later, this + //should be looked at again + strRet = strRet + "<?xml version=\"1.0\"?>"; + if (this.docNode==null) { + return; + } + + strRet = _displayElement(this.docNode, strRet); + return strRet; + +} // end function _XMLDoc_getCurrentXMLText + + + +function _XMLDoc_handleNode(current) { + /******************************************************************************************************************* + function: _XMLDoc_handleNode + + Author: mi...@id... + + Description: + adds a markup element to the document + *********************************************************************************************************************/ + + if ((current.nodeType=='COMMENT') && (this.topNode!=null)) { + return this.topNode.addElement(current); + } + else if ((current.nodeType=='TEXT') || (current.nodeType=='CDATA')) { + + // if the current node is a text node: + + + // if the stack is empty, and this text node isn't just whitespace, we have + // a problem (we're not in a document element) + + if(this.topNode==null) { + if (trim(current.content,true,false)=="") { + return true; + } + else { + return this.error("expected document node, found: " + current); + } + } + else { + // otherwise, append this as child to the element at the top of the stack + return this.topNode.addElement(current); + } + + + } + else if ((current.nodeType=='OPEN') || (current.nodeType=='SINGLE')) { + // if we find an element tag (open or empty) + var success = false; + + // if the stack is empty, this node becomes the document node + + if(this.topNode==null) { + this.docNode = current; + current.parent = null; + success = true; + } + else { + // otherwise, append this as child to the element at the top of the stack + success = this.topNode.addElement(current); + } + + + if (success && (current.nodeType!='SINGLE')) { + this.topNode = current; + } + + // rename it as an element node + + current.nodeType = "ELEMENT"; + + return success; + } + + // if it's a close tag, check the nesting + + else if (current.nodeType=='CLOSE') { + + // if the stack is empty, it's certainly an error + + if (this.topNode==null) { + return this.error("close tag without open: " + current.toString()); + } + else { + + // otherwise, check that this node matches the one on the top of the stack + + if (current.tagName!=this.topNode.tagName) { + return this.error("expected closing " + this.topNode.tagName + ", found closing " + current.tagName); + } + else { + // if it does, pop the element off the top of the stack + this.topNode = this.topNode.getParent(); + } + } + } + return true; +} // end function _XMLDoc_handleNode + + + +function _XMLDoc_insertNodeAfter (referenceNode, newNode) { + /******************************************************************************************************************* + function: _XMLDoc_insertNodeAfter + + Author: dj...@ya... + + Description: + inserts a new XML node after the reference node; + + for example, if we insert the node <tag2>hello</tag2> + after tag1 in the xml <rootnode><tag1></tag1></rootnode> + we will end up with <rootnode><tag1></tag1><tag2>hello</tag2></rootnode> + + NOTE: the return value of this function is a new XMLDoc object!!!! + + *********************************************************************************************************************/ + + var parentXMLText = this.getUnderlyingXMLText(); + var selectedNodeXMLText = referenceNode.getUnderlyingXMLText(); + var originalNodePos = parentXMLText.indexOf(selectedNodeXMLText) + selectedNodeXMLText.length; + var newXML = parentXMLText.substr(0,originalNodePos); + newXML += newNode.getUnderlyingXMLText(); + newXML += parentXMLText.substr(originalNodePos); + var newDoc = new XMLDoc(newXML, this.errFn); + return newDoc; + +} // end function _XMLDoc_insertNodeAfter + + + +function _XMLDoc_insertNodeInto (referenceNode, insertNode) { + /******************************************************************************************************************* + function: _XMLDoc_insertNodeInto + + Author: mi...@id... + + Description: + inserts a new XML node into the reference node; + + for example, if we insert the node <tag2>hello</tag2> + into tag1 in the xml <rootnode><tag1><tag3>foo</tag3></tag1></rootnode> + we will end up with <rootnode><tag1><tag2>hello</tag2><tag3>foo</tag3></tag1></rootnode> + + NOTE: the return value of this function is a new XMLDoc object!!!! + *********************************************************************************************************************/ + + var parentXMLText = this.getUnderlyingXMLText(); + var selectedNodeXMLText = referenceNode.getUnderlyingXMLText(); + var endFirstTag = selectedNodeXMLText.indexOf(">") + 1; + var originalNodePos = parentXMLText.indexOf(selectedNodeXMLText) + endFirstTag; + var newXML = parentXMLText.substr(0,originalNodePos); + newXML += insertNode.getUnderlyingXMLText(); + newXML += parentXMLText.substr(originalNodePos); + var newDoc = new XMLDoc(newXML, this.errFn); + return newDoc; + + +} // end function _XMLDoc_insertNodeInto + +function _XMLDoc_loadXML(source){ + /******************************************************************************************************************* + function: _XMLDoc_insertNodeInto + + Author: xw...@ya... + + Description: + allows an already existing XMLDoc object to load XML + *********************************************************************************************************************/ + this.topNode=null; + this.hasErrors = false; + this.source=source; + // parse the document + return this.parse(); + +} // end function _XMLDoc_loadXML + +function _XMLDoc_parse() { + /******************************************************************************************************************* + function: _XMLDoc_parse + + Author: mi...@id... + + Description: + scans through the source for opening and closing tags + checks that the tags open and close in a sensible order + *********************************************************************************************************************/ + + var pos = 0; + + // set up the arrays used to store positions of < and > characters + + err = false; + + while(!err) { + var closing_tag_prefix = ''; + var chpos = this.source.indexOf('<',pos); + var open_length = 1; + + var open; + var close; + + if (chpos ==-1) { + break; + } + + open = chpos; + + // create a text node + + var str = this.source.substring(pos, open); + + if (str.length!=0) { + err = !this.handleNode(new XMLNode('TEXT',this, str)); + } + + // handle Programming Instructions - they can't reliably be handled as tags + + if (chpos == this.source.indexOf("<?",pos)) { + pos = this.parsePI(this.source, pos + 2); + if (pos==0) { + err=true; + } + continue; + } + + // nobble the document type definition + + if (chpos == this.source.indexOf("<!DOCTYPE",pos)) { + pos = this.parseDTD(this.source, chpos+ 9); + if (pos==0) { + err=true; + } + continue; + } + + // if we found an open comment, we need to ignore angle brackets + // until we find a close comment + + if(chpos == this.source.indexOf('<!--',pos)) { + open_length = 4; + closing_tag_prefix = '--'; + } + + // similarly, if we find an open CDATA, we need to ignore all angle + // brackets until a close CDATA sequence is found + + if (chpos == this.source.indexOf('<![CDATA[',pos)) { + open_length = 9; + closing_tag_prefix = ']]'; + } + + // look for the closing sequence + + chpos = this.source.indexOf(closing_tag_prefix + '>',chpos); + if (chpos ==-1) { + return this.error("expected closing tag sequence: " + closing_tag_prefix + '>'); + } + + close = chpos + closing_tag_prefix.length; + + // create a tag node + + str = this.source.substring(open+1, close); + + var n = this.parseTag(str); + if (n) { + err = !this.handleNode(n); + } + + pos = close +1; + + // and loop + + } + return !err; + +} // end function _XMLDoc_parse + + + +function _XMLDoc_parseAttribute(src,pos,node) { + /******************************************************************************************************************* + function: _XMLDoc_parseAttribute + + Author: mi...@id... + + Description: + parse an attribute out of a tag string + + *********************************************************************************************************************/ + + // chew up the whitespace, if any + + while ((pos<src.length) && (whitespace.indexOf(src.charAt(pos))!=-1)) { + pos++; + } + + // if there's nothing else, we have no (more) attributes - just break out + + if (pos >= src.length) { + return pos; + } + + var p1 = pos; + + while ((pos < src.length) && (src.charAt(pos)!='=')) { + pos++; + } + + var msg = "attributes must have values"; + + // parameters without values aren't allowed. + + if(pos >= src.length) { + return this.error(msg); + } + + // extract the parameter name + + var paramname = trim(src.substring(p1,pos++),false,true); + + // chew up whitespace + + while ((pos < src.length) && (whitespace.indexOf(src.charAt(pos))!=-1)) { + pos++; + } + + // throw an error if we've run out of string + + if (pos >= src.length) { + return this.error(msg); + } + + msg = "attribute values must be in quotes"; + + // check for a quote mark to identify the beginning of the attribute value + + var quote = src.charAt(pos++); + + // throw an error if we didn't find one + + if (quotes.indexOf(quote)==-1) { + return this.error(msg); + } + + p1 = pos; + + while ((pos < src.length) && (src.charAt(pos)!=quote)) { + pos++; + } + + // throw an error if we found no closing quote + + if (pos >= src.length) { + return this.error(msg); + } + + // store the parameter + + if (!node.addAttribute(paramname,trim(src.substring(p1,pos++),false,true))) { + return 0; + } + + return pos; + +} //end function _XMLDoc_parseAttribute + + + +function _XMLDoc_parseDTD(str,pos) { + /******************************************************************************************************************* + function: _XMLDoc_parseDTD + + Author: mi...@id... + + Description: + parse a document type declaration + + NOTE: we're just going to discard the DTD + + *********************************************************************************************************************/ + // we're just going to discard the DTD + + var firstClose = str.indexOf('>',pos); + + if (firstClose==-1) { + return this.error("error in DTD: expected '>'"); + } + + var closing_tag_prefix = ''; + + var firstOpenSquare = str.indexOf('[',pos); + + if ((firstOpenSquare!=-1) && (firstOpenSquare < firstClose)) { + closing_tag_prefix = ']'; + } + + while(true) { + var closepos = str.indexOf(closing_tag_prefix + '>',pos); + + if (closepos ==-1) { + return this.error("expected closing tag sequence: " + closing_tag_prefix + '>'); + } + + pos = closepos + closing_tag_prefix.length +1; + + if (str.substring(closepos-1,closepos+2) != ']]>') { + break; + } + } + return pos; + +} // end function _XMLDoc_ParseDTD + + +function _XMLDoc_parsePI(str,pos) { + /******************************************************************************************************************* + function: _XMLDoc_parsePI + + Author: mi...@id... + + Description: + parse a processing instruction + + NOTE: we just swallow them up at the moment + + *********************************************************************************************************************/ + // we just swallow them up + + var closepos = str.indexOf('?>',pos); + return closepos + 2; + +} // end function _XMLDoc_parsePI + + + +function _XMLDoc_parseTag(src) { + /******************************************************************************************************************* + function: _XMLDoc_parseTag + + Author: mi...@id... + + Description: + parse out a non-text element (incl. CDATA, comments) + handles the parsing of attributes + *********************************************************************************************************************/ + + // if it's a comment, strip off the packaging, mark it a comment node + // and return it + + if (src.indexOf('!--')==0) { + return new XMLNode('COMMENT', this, src.substring(3,src.length-2)); + } + + // if it's CDATA, do similar + + if (src.indexOf('![CDATA[')==0) { + return new XMLNode('CDATA', this, src.substring(8,src.length-2)); + } + + var n = new XMLNode(); + n.doc = this; + + + if (src.charAt(0)=='/') { + n.nodeType = 'CLOSE'; + src = src.substring(1); + } + else { + // otherwise it's an open tag (possibly an empty element) + n.nodeType = 'OPEN'; + } + + // if the last character is a /, check it's not a CLOSE tag + + if (src.charAt(src.length-1)=='/') { + if (n.nodeType=='CLOSE') { + return this.error("singleton close tag"); + } + else { + n.nodeType = 'SINGLE'; + } + + // strip off the last character + + src = src.substring(0,src.length-1); + } + + // set up the properties as appropriate + + if (n.nodeType!='CLOSE') { + n.attributes = new Array(); + } + + if (n.nodeType=='OPEN') { + n.children = new Array(); + } + + // trim the whitespace off the remaining content + + src = trim(src,true,true); + + // chuck out an error if there's nothing left + + if (src.length==0) { + return this.error("empty tag"); + } + + // scan forward until a space... + + var endOfName = firstWhiteChar(src,0); + + // if there is no space, this is just a name (e.g. (<tag>, <tag/> or </tag> + + if (endOfName==-1) { + n.tagName = src; + return n; + } + + // otherwise, we should expect attributes - but store the tag name first + + n.tagName = src.substring(0,endOfName); + + // start from after the tag name + + var pos = endOfName; + + // now we loop: + + while(pos< src.length) { + pos = this.parseAttribute(src, pos, n); + if (this.pos==0) { + return null; + } + + // and loop + + } + return n; + +} // end function _XMLDoc_parseTag + + + +function _XMLDoc_removeNodeFromTree(node) { + /******************************************************************************************************************* + function: _XMLDoc_removeNodeFromTree + + Author: dj...@ya... + + Description: + removes the specified node from the tree + + NOTE: the return value of this function is a new XMLDoc object + + *********************************************************************************************************************/ + + var parentXMLText = this.getUnderlyingXMLText(); + var selectedNodeXMLText = node.getUnderlyingXMLText(); + var originalNodePos = parentXMLText.indexOf(selectedNodeXMLText); + var newXML = parentXMLText.substr(0,originalNodePos); + newXML += parentXMLText.substr(originalNodePos + selectedNodeXMLText.length); + var newDoc = new XMLDoc(newXML, this.errFn); + return newDoc; +} // end function _XMLDoc_removeNodeFromTree + + + +function _XMLDoc_replaceNodeContents(referenceNode, newContents) { + /******************************************************************************************************************* + function: _XMLDoc_replaceNodeContents + + Author: dj...@ya... + + Description: + + make a node object out of the newContents text + coming in ---- + + The "X" node will be thrown away and only the children + used to replace the contents of the reference node + + NOTE: the return value of this function is a new XMLDoc object + + *********************************************************************************************************************/ + + var newNode = this.createXMLNode("<X>" + newContents + "</X>"); + referenceNode.children = newNode.children; + return this; +} // end function _XMLDoc_replaceNodeContents + + +function _XMLDoc_selectNode(tagpath){ + /******************************************************************************************************************* + function: _XMLDoc_selectNode + + Author: xw...@ya... + + Description: + selects a single node using the nodes tag path. + examples: /node1/node2 or /taga/tag1[0]/tag2 + *********************************************************************************************************************/ + + tagpath = trim(tagpath, true, true); + + var srcnode,node,tag,params,elm,rg; + var tags,attrName,attrValue,ok; + srcnode=node=((this.source)?this.docNode:this); + if (!tagpath) return node; + if(tagpath.indexOf('/')==0)tagpath=tagpath.substr(1); + tagpath=tagpath.replace(tag,''); + tags=tagpath.split('/'); + tag=tags[0]; + if(tag){ + if(tagpath.indexOf('/')==0)tagpath=tagpath.substr(1); + tagpath=tagpath.replace(tag,''); + params=_XMLDoc_getTagNameParams(tag,this); + tag=params[0];elm=params[1]; + attrName=params[2];attrValue=params[3]; + node=(tag=='*')? node.getElements():node.getElements(tag); + if (node.length) { + if(elm<0){ + srcnode=node;var i=0; + while(i<srcnode.length){ + if(attrName){ + if (srcnode[i].getAttribute(attrName)!=attrValue) ok=false; + else ok=true; + }else ok=true; + if(ok){ + node=srcnode[i].selectNode(tagpath); + if(node) return node; + } + i++; + } + }else if (elm<node.length){ + node=node[elm].selectNode(tagpath); + if(node) return node; + } + } + } +} // end function _XMLDoc_selectNode + +function _XMLDoc_selectNodeText(tagpath){ + /******************************************************************************************************************* + function: _XMLDoc_selectNodeText + + Author: xw...@ya... + + Description: + selects a single node using the nodes tag path and then returns the node text. + *********************************************************************************************************************/ + + var node=this.selectNode(tagpath); + if (node != null) { + return node.getText(); + } + else { + return null; + } +} // end function _XMLDoc_selectNodeText + + + + + + + + +// ========================================================================= +// ========================================================================= +// ========================================================================= +// XML NODE FUNCTIONS +// ========================================================================= +// ========================================================================= +// ========================================================================= + + +function XMLNode(nodeType,doc, str) { + /******************************************************************************************************************* + function: xmlNode + + Author: mi...@id... + + Description: + + XMLNode() is a constructor for a node of XML (text, comment, cdata, tag, etc) + + nodeType = indicates the node type of the node + doc == contains a reference to the XMLDoc object describing the document + str == contains the text for the tag or text entity + + *********************************************************************************************************************/ + + + // the content of text (also CDATA and COMMENT) nodes + if (nodeType=='TEXT' || nodeType=='CDATA' || nodeType=='COMMENT' ) { + this.content = str; + } + else { + this.content = null; + } + + this.attributes = null; // an array of attributes (used as a hash table) + this.children = null; // an array (list) of the children of this node + this.doc = doc; // a reference to the document + this.nodeType = nodeType; // the type of the node + this.parent = ""; + this.tagName = ""; // the name of the tag (if a tag node) + + // configure the methods + this.addAttribute = _XMLNode_addAttribute; + this.addElement = _XMLNode_addElement; + this.getAttribute = _XMLNode_getAttribute; + this.getAttributeNames = _XMLNode_getAttributeNames; + this.getElementById = _XMLNode_getElementById; + this.getElements = _XMLNode_getElements; + this.getText = _XMLNode_getText; + this.getParent = _XMLNode_getParent; + this.getUnderlyingXMLText = _XMLNode_getUnderlyingXMLText; + this.removeAttribute = _XMLNode_removeAttribute; + this.selectNode = _XMLDoc_selectNode; + this.selectNodeText = _XMLDoc_selectNodeText; + this.toString = _XMLNode_toString; + +} // end function XMLNode + + +function _XMLNode_addAttribute(attributeName,attributeValue) { + /******************************************************************************************************************* + function: _XMLNode_addAttribute + + Author: mi...@id... + + Description: + add an attribute to a node + *********************************************************************************************************************/ + + //if the name is found, the old value is overwritten by the new value + this.attributes['_' + attributeName] = attributeValue; + return true; + +} // end function _XMLNode_addAttribute + + + +function _XMLNode_addElement(node) { + /******************************************************************************************************************* + function: _XMLNode_addElement + + Author: mi...@id... + + Description: + add an element child to a node + *********************************************************************************************************************/ + node.parent = this; + this.children[this.children.length] = node; + return true; + +} // end function _XMLNode_addElement + + +function _XMLNode_getAttribute(name) { + /******************************************************************************************************************* + function: _XMLNode_getAttribute + + Author: mi...@id... + + Description: + get the value of a named attribute from an element node + + NOTE: we prefix with "_" because of the weird 'length' meta-property + + *********************************************************************************************************************/ + if (this.attributes == null) { + return null; + } + return this.attributes['_' + name]; +} // end function _XMLNode_getAttribute + + + +function _XMLNode_getAttributeNames() { + /******************************************************************************************************************* + function: _XMLNode_getAttributeNames + + Author: mi...@id... + + Description: + get a list of attribute names for the node + + NOTE: we prefix with "_" because of the weird 'length' meta-property + + NOTE: Version 1.0 of getAttributeNames breaks backwards compatibility. Previous to 1.0 + getAttributeNames would return null if there were no attributes. 1.0 now returns an + array of length 0. + + + *********************************************************************************************************************/ + if (this.attributes == null) { + var ret = new Array(); + return ret; + } + + var attlist = new Array(); + + for (var a in this.attributes) { + attlist[attlist.length] = a.substring(1); + } + return attlist; +} // end function _XMLNode_getAttributeNames + +function _XMLNode_getElementById(id) { + + /*********************************************************************************** + Function: getElementById + + Author: dj...@ya... + + Description: + Brute force searches through the XML DOM tree + to find the node with the unique ID passed in + + ************************************************************************************/ + var node = this; + var ret; + + //alert("tag name=" + node.tagName); + //alert("id=" + node.getAttribute("id")); + if (node.getAttribute("id") == id) { + return node; + } + else{ + var elements = node.getElements(); + //alert("length=" + rugrats.length); + var intLoop = 0; + //do NOT use a for loop here. For some reason + //it kills some browsers!!! + while (intLoop < elements.length) { + //alert("intLoop=" + intLoop); + var element = elements[intLoop]; + //alert("recursion"); + ret = element.getElementById(id); + if (ret != null) { + //alert("breaking"); + break; + } + intLoop++; + } + } + return ret; +} // end function _XMLNode_getElementById + + +function _XMLNode_getElements(byName) { + /******************************************************************************************************************* + function: _XMLNode_getElements + + Author: mi...@id... + + Description: + get an array of element children of a node + with an optional filter by name + + NOTE: Version 1.0 of getElements breaks backwards compatibility. Previous to 1.0 + getElements would return null if there were no attributes. 1.0 now returns an + array of length 0. + + + *********************************************************************************************************************/ + if (this.children==null) { + var ret = new Array(); + return ret; + } + + var elements = new Array(); + for (var i=0; i<this.children.length; i++) { + if ((this.children[i].nodeType=='ELEMENT') && ((byName==null) || (this.children[i].tagName == byName))) { + elements[elements.length] = this.children[i]; + } + } + return elements; +} // end function _XMLNode_getElements + + + +function _XMLNode_getText() { + /******************************************************************************************************************* + function: _XMLNode_getText + + Author: mi...@id... + + Description: + a method to get the text of a given node (recursively, if it's an element) + *********************************************************************************************************************/ + + if (this.nodeType=='ELEMENT') { + if (this.children==null) { + return null; + } + var str = ""; + for (var i=0; i < this.children.length; i++) { + var t = this.children[i].getText(); + str += (t == null ? "" : t); + } + return str; + } + else if (this.nodeType=='TEXT') { + return convertEscapes(this.content); + } + else { + return this.content; + } +} // end function _XMLNode_getText + + + +function _XMLNode_getParent() { + /******************************************************************************************************************* + function: _XMLNode_getParent + + Author: mi...@id... + + Description: + get the parent of this node + *********************************************************************************************************************/ + return this.parent; + +} // end function _XMLNode_getParent + + +function _XMLNode_getUnderlyingXMLText() { + /******************************************************************************************************************* + function: David Joham + + Author: dj...@ya... + + Description: + returns the underlying XML text for the node + by calling the _displayElement function + *********************************************************************************************************************/ + + var strRet = ""; + strRet = _displayElement(this, strRet); + return strRet; + +} // end function _XMLNode_getUnderlyingXMLText + + + +function _XMLNode_removeAttribute(attributeName) { + /******************************************************************************************************************* + function: _XMLNode_removeAttribute + + Author: dj...@ya... + + Description: + remove an attribute from a node + *********************************************************************************************************************/ + if(attributeName == null) { + return this.doc.error("You must pass an attribute name into the removeAttribute function"); + } + + //now remove the attribute from the list. + // I want to keep the logic for adding attribtues in one place. I'm + // going to get a temp array of attributes and values here and then + // use the addAttribute function to re-add the attributes + var attributes = this.getAttributeNames(); + var intCount = attributes.length; + var tmpAttributeValues = new Array(); + for ( intLoop = 0; intLoop < intCount; intLoop++) { + tmpAttributeValues[intLoop] = this.getAttribute(attributes[intLoop]); + } + + // now blow away the old attribute list + this.attributes = new Array(); + + //now add the attributes back to the array - leaving out the one we're removing + for (intLoop = 0; intLoop < intCount; intLoop++) { + if ( attributes[intLoop] != attributeName) { + this.addAttribute(attributes[intLoop], tmpAttributeValues[intLoop]); + } + } + +return true; + +} // end function _XMLNode_removeAttribute + + + +function _XMLNode_toString() { + /******************************************************************************************************************* + function: _XMLNode_toString + + Author: mi...@id... + + Description: + produces a diagnostic string description of a node + *********************************************************************************************************************/ + return "" + this.nodeType + ":" + (this.nodeType=='TEXT' || this.nodeType=='CDATA' || this.nodeType=='COMMENT' ? this.content : this.tagName); + +} // end function _XMLNode_toString + + + + + + + + + + + + + + + + + + + + + + + + + Property changes on: trunk/moodle/mod/liveclassroom/js/xmldom.js ___________________________________________________________________ Name: svn:mime-type + text/plain Name: svn:keywords + Date Revision Author Id Name: svn:eol-style + native This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |