//curtain.js // JavaScript Document //email.js // JavaScript Document function showEmailForm(){ logAction( 5, "show" ); document.getElementById('emailCurtain').className = "visible"; document.getElementById('curtainBackground').className = "visible"; document.getElementById("name").value = "" document.getElementById("email").value = "" document.getElementById("phone").value = "" document.getElementById("message").value = "" } function hideEmailForm(){ logAction( 5, "hide" ); document.getElementById('emailCurtain').className = "hidden"; document.getElementById('curtainBackground').className = "hidden"; } function submitEmailForm( formID ){ if( validateForm() ) { var uri = "/index.php?method=sendemail"; var ajaxRequest = new AjaxRequest(uri); ajaxRequest.setUsePOST(); //ajaxRequest.setPostRequest(onCF_return); ajaxRequest.setPostRequest(submitEmailFormPostback); ajaxRequest.addFormElements( formID ); ajaxRequest.sendRequest(); } return false; //kills form submission } function submitEmailFormPostback(o){ xmlhttp = o.getXMLHttpRequestObject() //if you mama smells like ass then do this shit man var message = xmlhttp.responseXML.getElementsByTagName('message')[0].firstChild.data if( message == 1 ){ hideEmailForm(); }else{ } } //coupon.js // JavaScript Document function showFullCoupon( couponID ){ logAction( 4, "show" ); document.getElementById('curtainBackground').className = "visible"; document.getElementById('couponCurtain').className = "visible"; } function hideFullCoupon(){ logAction( 4, "hide" ); document.getElementById('couponCurtain').className = "hidden"; document.getElementById('curtainBackground').className = "hidden"; } function printCoupon( couponID ){ logAction( 4, "print" ); window.print(); } //log.js // Logs user actions //Logs the action function logAction( categoryID, extra ){ var uri = "/index.php?method=jslog&categoryID=" + categoryID + "&extra=" +extra; var ajaxRequest = new AjaxRequest(uri); ajaxRequest.setUseGET(); //ajaxRequest.setPostRequest(onCF_return); ajaxRequest.sendRequest(); } //taconite-client.js /** @fileoverview This JavaScript file represents the core browser-side functionality supplied by Taconite. In general, the tools in this file wrap an instance of XMLHttpRequest object and provide utility methods for gather data from form elements to be sent to the server as par of an Ajax request. */ var taconite_client_version="2.0"; /** Constructor for the AjaxRequest class.

Example:

var ajaxRequest = new AjaxRequest("YOUR_URL"); @class The AjaxRequest object wraps an instance of XMLHttpRequest and provides facilities for setting functions that are called before a request is made and after a request returns. By default, AjaxRequest handles the server response by simply calling eval(), passing to it the responseText from the XMLHttpRequestObject, of course assuming that the response was generated by Taconite on the server side and that running eval() will update the web page.

Example Usage:

var ajaxRequest = new AjaxRequest("YOUR_URL");
ajaxRequest.addFormElements("form_element_id_attribute_value-or-form_dom_element");
ajaxRequest.sendRequest(); @constructor @param {String} a String repesenting the URL to which the Ajax request will be sent. */ function AjaxRequest(url) { /** @private */ var self = this; /** @private */ var xmlHttp = createXMLHttpRequest(); /** @private */ var queryString = ""; /** @private */ var requestURL = url; /** @private */ var method = "GET"; /** @private */ var preRequest = null; /** @private */ var postRequest = null; /** @private */ var debugResponse = false; /** @private */ var async = true; /** @private errorHandler*/ var errorHandler = null; /** Return the instance of the XMLHttpRequest object wrapped by this object. @return XMLHttpRequest */ this.getXMLHttpRequestObject = function() { return xmlHttp; } /** Set the pre-request function. This function will be called prior to sending the Ajax request. The pre-request function is passed a reference to this object. @param {Function} The function to be called prior to sending the Ajax request. The function is passed a refernce of this object. */ this.setPreRequest = function(func) { preRequest = func; } /** Set the post-request function. This function will be called after the response has been received and after eval() has been called using the XMLHttpRequest object's responseText. The post-request function is passed a reference to this object. @param {Function} The function to be called after receiving the Ajax response. The function is passed a refernce of this object. */ this.setPostRequest = function(func) { postRequest = func; } /** Return the post request function. */ this.getPostRequest = function() { return postRequest; } /** Send the Ajax request using the POST method. Use with caution -- some browsers do not support the POST method with the XMLHttpRequest object. */ this.setUsePOST = function() { method = "POST"; } /** Send the Ajax request using the GET method, where parameters are sent as a query string appended to the URL. This is the default behavior. */ this.setUseGET = function() { method = "GET"; } /** Enable client-side debugging. The server's response will be written to a text area appended to the bottom of the page. If parsing is performed on the client side, then the results of the parsing operations are shown in their own text areas. */ this.setEchoDebugInfo = function() { debugResponse = true; } /** Indicate if debugging is enabled. @return boolean */ this.isEchoDebugInfo = function() { return debugResponse; } /** Set the query string that will be sent to the server. For GET requests, the query string is appended to the URL. For POST requests, the query string is sent in the request body. This method is useful, for example, if you want to send an XML string or JSON string to the server. @param {String} qa, the new query string value. */ this.setQueryString = function(qs) { queryString = qs; } /** Return the query string. @return The query string. */ this.getQueryString = function() { return queryString; } /** @param {Boolean} asyncBoolean, set to true if asynchronous request, false synchronous request. */ this.setAsync = function(asyncBoolean){ async = asyncBoolean; } /** @param {Function} Set the error handler function that is called if the server's HTTP response code is something other than 200. */ this.setErrorHandler = function(func){ errorHandler = func; } /** Add all of the form elements under the specified form to the query string to be sent to the server as part of the Ajax request. The values are automatically encoded. @param form, A form DOM element, or the id attribute of the form element from which you wish to accumulate the form values. */ this.addFormElements = function(form) { var formElements = new Array(); if (form != null) { if (typeof form == "string") { var el = document.getElementById(form); if (el != null) { formElements = el.elements; } } else { formElements = form.elements; } } var values = toQueryString(formElements); accumulateQueryString(values); } /** Add the name/value pair to the query string. @param {String} name @param {String} value */ this.addNameValuePair = function(name, value) { var nameValuePair = name + "=" + encodeURIComponent(value); accumulateQueryString(nameValuePair); } /** Same as addNamedFormElements, except it will filter form elements by form's id. For example, these are all valid uses:

ajaxRequest.addNamedFormElements("form-id""element-name-1");
ajaxRequest.addNamedFormElements("form-id","element-name-1", "element-name-2", "element-name-3"); */ this.addNamedFormElementsByFormID = function() { var elementName = ""; var namedElements = null; for(var i = 1; i < arguments.length; i++) { elementName = arguments[i]; namedElements = document.getElementsByName(elementName); var arNamedElements = new Array(); for(j = 0; j < namedElements.length; j++) { if(namedElements[j].form && namedElements[j].form.getAttribute("id") == arguments[0]){ arNamedElements.push(namedElements[j]); } } if(arNamedElements.length > 0){ elementValues = toQueryString(arNamedElements); accumulateQueryString(elementValues); } } } /** Add the values of the named form elements to the query string to be sent to the server as part of the Ajax request. This method takes any number of Strings representing the form elements for wish you wish to accumulate the values. The Strings must be the value of the element's name attribute.

For example, these are all valid uses:

ajaxRequest.addNamedFormElements("element-name-1");
ajaxRequest.addNamedFormElements("element-name-1", "element-name-2", "element-name-3"); */ this.addNamedFormElements = function() { var elementName = ""; var namedElements = null; for(var i = 0; i < arguments.length; i++) { elementName = arguments[i]; namedElements = document.getElementsByName(elementName); elementValues = toQueryString(namedElements); accumulateQueryString(elementValues); } } /** Add the values of the id'd form elements to the query string to be sent to the server as part of the Ajax request. This method takes any number of Strings representing the ids of the form elements for wish you wish to accumulate the values. The Strings must be the value of the element's name attribute.

For example, these are all valid uses:

ajaxRequest.addFormElementsById("element-id-1");
ajaxRequest.addFormElementsById("element-id-1", "element-id-2", "element-id-3"); */ this.addFormElementsById = function() { var id = ""; var element = null; var elements = new Array(); for(var h = 0; h < arguments.length; h++) { element = document.getElementById(arguments[h]); if(element != null) { elements[h] = element; } } elementValues = toQueryString(elements); accumulateQueryString(elementValues); } /** Send the Ajax request. */ this.sendRequest = function() { if(preRequest) { preRequest(self); } var obj = this; if(async) xmlHttp.onreadystatechange = function () { handleStateChange(self) }; if(requestURL.indexOf("?") > 0) { requestURL = requestURL + "&ts=" + new Date().getTime(); } else { requestURL = requestURL + "?ts=" + new Date().getTime(); } try { if(method == "GET") { if(queryString.length > 0) { requestURL = requestURL + "&" + queryString; } xmlHttp.open(method, requestURL, async); xmlHttp.send(null); } else { xmlHttp.open(method, requestURL, async); //Fix a bug in Firefox when posting try { if (xmlHttp.overrideMimeType) { xmlHttp.setRequestHeader("Connection", "close");//set header after open } } catch(e) { // Do nothing } xmlHttp.setRequestHeader("Content-Type", "application/x-www-form-urlencoded"); xmlHttp.send(queryString); } } catch(exception) { if(errorHandler) { errorHandler(self, exception); } else { throw exception; } } if(!async) { //synchronous request, handle the state change handleStateChange(self); } if(self.isEchoDebugInfo()) { echoRequestParams(); } } /** @private */ handleStateChange = function(ajaxRequest) { if(ajaxRequest.getXMLHttpRequestObject().readyState != 4) { return; } if(ajaxRequest.getXMLHttpRequestObject().status != 200) { errorHandler(self); return; } try { var debug = ajaxRequest.isEchoDebugInfo(); if(debug) { echoResponse(ajaxRequest); } //handle null responseXML var nodes = null; if (ajaxRequest.getXMLHttpRequestObject().responseXML != null) { nodes = ajaxRequest.getXMLHttpRequestObject().responseXML.documentElement.childNodes; } else { nodes = new Array(); } var parser = new XhtmlToDOMParser(); var parseInBrowser = ""; for(var i = 0; i < nodes.length; i++) { if(nodes[i].nodeType != 1 || !isTaconiteTag(nodes[i])) { continue; } parser.parseXhtml(nodes[i]); } } catch(exception) { if(errorHandler) { errorHandler(self, exception); } else { throw exception; } } finally { try { if(ajaxRequest.getPostRequest()) { var f = ajaxRequest.getPostRequest(); f(ajaxRequest); } } catch(exception) { if(errorHandler) { errorHandler(self, exception); } } } } /** Create an instance of the XMLHttpRequest object, using the appropriate method for the type of browser in which this script is running. For Internet Explorer, it's an ActiveX object, for all others it's a native JavaScript object. @return an instance of the XMLHttpRequest object. @private */ function createXMLHttpRequest() { var req = false; if (window.XMLHttpRequest) { req = new XMLHttpRequest(); } else if (window.ActiveXObject) { try { req = new ActiveXObject("Msxml2.XMLHTTP"); } catch(e) { try { req = new ActiveXObject("Microsoft.XMLHTTP"); } catch(e) { req = false; } } } return req; } /** @private */ function accumulateQueryString(newValues) { if(queryString == "") { queryString = newValues; } else { queryString = queryString + "&" + newValues; } } /** @private */ function isTaconiteTag(node) { return node.tagName.substring(0, 9) == "taconite-"; } /** @private */ function toQueryString(elements) { var node = null; var qs = ""; var name = ""; var tempString = ""; for(var i = 0; i < elements.length; i++) { tempString = ""; node = elements[i]; name = node.getAttribute("name"); //use id if name is null if (!name) { name = node.getAttribute("id"); } name = encodeURIComponent(name); if(node.tagName.toLowerCase() == "input") { if(node.type.toLowerCase() == "radio" || node.type.toLowerCase() == "checkbox") { if(node.checked) { tempString = name + "=" + encodeURIComponent(node.value); } } if(node.type.toLowerCase() == "text" || node.type.toLowerCase() == "hidden" || node.type.toLowerCase() == "password") { tempString = name + "=" + encodeURIComponent(node.value); } } else if(node.tagName.toLowerCase() == "select") { tempString = getSelectedOptions(node); } else if(node.tagName.toLowerCase() == "textarea") { tempString = name + "=" + encodeURIComponent(node.value); } if(tempString != "") { if(qs == "") { qs = tempString; } else { qs = qs + "&" + tempString; } } } return qs; } /** @private */ function getSelectedOptions(select) { var options = select.options; var option = null; var qs = ""; var tempString = ""; for(var x = 0; x < options.length; x++) { tempString = ""; option = options[x]; if(option.selected) { tempString = encodeURIComponent(select.name) + "=" + encodeURIComponent(option.value); } if(tempString != "") { if(qs == "") { qs = tempString; } else { qs = qs + "&" + tempString; } } } return qs; } /** @private */ function echoResponse(ajaxRequest) { var echoTextArea = document.getElementById("debugResponse"); if(echoTextArea == null) { echoTextArea = createDebugTextArea("Server Response:", "debugResponse"); } var debugText = ajaxRequest.getXMLHttpRequestObject().status + " " + ajaxRequest.getXMLHttpRequestObject().statusText + "\n\n\n"; echoTextArea.value = debugText + ajaxRequest.getXMLHttpRequestObject().responseText; } /** @private */ function echoParsedJavaScript(js) { var echoTextArea = document.getElementById("debugParsedJavaScript"); if(echoTextArea == null) { var echoTextArea = createDebugTextArea("Parsed JavaScript (by JavaScript Parser):", "debugParsedJavaScript"); } echoTextArea.value = js; } /** @private */ function createDebugTextArea(label, id) { echoTextArea = document.createElement("textarea"); echoTextArea.setAttribute("id", id); echoTextArea.setAttribute("rows", "15"); echoTextArea.setAttribute("style", "width:100%"); echoTextArea.style.cssText = "width:100%"; document.getElementsByTagName("body")[0].appendChild(document.createTextNode(label)); document.getElementsByTagName("body")[0].appendChild(echoTextArea); return echoTextArea; } /** @private */ function echoRequestParams() { var qsTextBox = document.getElementById("qsTextBox"); if(qsTextBox == null) { qsTextBox = createDebugTextBox("Query String:", "qsTextBox"); } qsTextBox.value = queryString; var urlTextBox = document.getElementById("urlTextBox"); if(urlTextBox == null) { urlTextBox = createDebugTextBox("URL (Includes query string if GET request):", "urlTextBox"); } urlTextBox.value = requestURL; } /** @private */ function createDebugTextBox(label, id) { textBox = document.createElement("input"); textBox.setAttribute("type", "text"); textBox.setAttribute("id", id); textBox.setAttribute("style", "width:100%"); textBox.style.cssText = "width:100%"; document.getElementsByTagName("body")[0].appendChild(document.createTextNode(label)); document.getElementsByTagName("body")[0].appendChild(textBox); return textBox; } }; //taconite-parser.js /** @fileoverview This JavaScript file represents the JavaScript parser used by Taconite for converting Xhtml documents sent by the server into actions acting on the Javascript DOM. Copyright notes: The DOMSelector is based on document.getElementsBySelector(selector) method, Copyright (C) Simon Willison 2004. */ var taconite_parser_version ="2.0"; var isIE=document.uniqueID; var TaconiteDOMUtils = { getAllSubElements : function(element) { // Returns all sub elements. Workaround required for IE5/Windows. return element.all ? element.all : element.getElementsByTagName('*'); }, setMultipleSelectOptions : function(selectNodeId) { var selectNode = document.getElementById(selectNodeId); var options = document.getElementById(selectNodeId).getElementsByTagName("option"); var option; for(var i = 0; i < options.length; i++) { option = options[i]; if (typeof(option.taconiteOptionSelected) != "undefined") { option.selected = true; } else { option.selected = false; } } } }; function XhtmlToDOMParser(){ this.parseXhtml = function(xml){ var xmlTagName=xml.tagName.toLowerCase(); if (requiresContextNode(xmlTagName)) { var contextNodes = getContextNodes(xml); if(contextNodes == null || contextNodes.length == 0) { return false; } else { // Remove no more necessary attributes: xml.removeAttribute("contextNodeID"); xml.removeAttribute("contextNodeSelector"); xml.removeAttribute("matchMode"); xml.removeAttribute("parseInBrowser"); // switch (xmlTagName) { case "taconite-append-as-children": for (var i = 0; i < contextNodes.length; i++) { var contextNode = contextNodes[i]; getReplaceChildren(contextNode,xml,false); } break; case "taconite-delete": for (var i = 0; i < contextNodes.length; i++) { var contextNode = contextNodes[i]; getDelete(contextNode,xml); } break; case "taconite-append-as-first-child": for (var i = 0; i < contextNodes.length; i++) { var contextNode = contextNodes[i]; getAppendAsFirstChild(contextNode,xml); } break; case "taconite-insert-after": for (var i = 0; i < contextNodes.length; i++) { var contextNode = contextNodes[i]; getInsertAfter(contextNode,xml); } break; case "taconite-insert-before": for (var i = 0; i < contextNodes.length; i++) { var contextNode = contextNodes[i]; getInsertBefore(contextNode,xml); } break; case "taconite-replace-children": for (var i = 0; i < contextNodes.length; i++) { var contextNode = contextNodes[i]; getReplaceChildren(contextNode,xml,true); } break; case "taconite-replace": for (var i = 0; i < contextNodes.length; i++) { var contextNode = contextNodes[i]; getReplace(contextNode,xml); } break; case "taconite-set-attributes": for (var i = 0; i < contextNodes.length; i++) { var contextNode = contextNodes[i]; handleAttributes(contextNode,xml); } break; } return true; } } else { switch (xmlTagName) { case "taconite-redirect": handleRedirect(xml); break; case "taconite-execute-javascript": executeJavascript(xml); break; } return true; } } function requiresContextNode(xmlTagName) { return !(xmlTagName == "taconite-execute-javascript" || xmlTagName == "taconite-redirect"); } function getContextNodes(xml) { var matchMode = xml.getAttribute("matchMode"); var contextNodes = new Array(); if (matchMode != null) { switch(matchMode) { case "plain" : contextNodes = getContextNodesByPlainMatch(xml); break; case "wildcard" : contextNodes = getContextNodesByWildcardMatch(xml); break; case "selector" : contextNodes = getContextNodesBySelectorMatch(xml); break; } } else { contextNodes = getContextNodesByPlainMatch(xml); } return contextNodes; } function getContextNodesByPlainMatch(xml) { var contextNodeID = xml.getAttribute("contextNodeID"); var contextIDs = contextNodeID.split(','); var contextNodes = new Array(); for (var i = 0, k = 0; i < contextIDs.length; i++) { var tmp = document.getElementById(contextIDs[i].trim()); if (tmp != null) { contextNodes[k] = tmp; k++; } } return contextNodes; } function getContextNodesByWildcardMatch(xml) { var contextNodeID = xml.getAttribute("contextNodeID"); var contextIDs = contextNodeID.split(','); var contextNodes = new Array(); for (var i = 0; i < contextIDs.length; i++) { contextNodes = contextNodes.concat(document.getElementsByMatchingId(contextIDs[i].trim())); } return contextNodes; } function getContextNodesBySelectorMatch(xml) { var selector = new DOMSelector(); var contextNodeSelector = xml.getAttribute("contextNodeSelector"); var contextSelectors = contextNodeSelector.split(','); var contextNodes = new Array(); for (var i = 0; i < contextSelectors.length; i++) { contextNodes = contextNodes.concat(selector.select(contextSelectors[i].trim())); } return contextNodes; } function isInlineMode(node) { var lowerCaseTag = node.tagName.toLowerCase(); if(lowerCaseTag == "button") { return true; } var attrType = node.getAttribute("type"); if(lowerCaseTag == "input" && (attrType == "radio" || attrType == "checkbox")) { return true; } return false; } function handleNode(xmlNode){ var nodeType = xmlNode.nodeType; switch(nodeType) { case 1: //ELEMENT_NODE return handleElement(xmlNode); case 3: //TEXT_NODE case 4: //CDATA_SECTION_NODE var textNode = document.createTextNode(xmlNode.nodeValue); if(isIE) { textNode.nodeValue = textNode.nodeValue.replace(/\n/g, '\r'); } return textNode; } return null; } function handleElement(xmlNode){ var domElemNode = null; var xmlNodeTagName = xmlNode.tagName.toLowerCase(); if(isIE){ if(isInlineMode(xmlNode)) { return document.createElement("<" + xmlNodeTagName + " " + handleAttributes(domElemNode, xmlNode, true) + ">"); } if(xmlNodeTagName == "style"){ //In internet explorer, we have to use styleSheets array. var text,rulesArray,styleSheetPtr; var regExp = /\s+/g; text=xmlNode.text.replace(regExp, " "); rulesArray=text.split("}"); domElemNode=document.createElement("style"); styleSheetPtr=document.styleSheets[document.styleSheets.length-1]; for(var i=0;i 0){ domElemNode.text=xmlNode.text; } } else{ for(var z = 0; z < xmlNode.childNodes.length; z++) { var domChildNode=handleNode(xmlNode.childNodes[z]); if(domChildNode!=null) { domElemNode.appendChild(domChildNode); } } } } return domElemNode; } function useIEFormElementCreationStrategy(xmlNodeTagName) { var useIEStrategy = false; var nodeName = xmlNodeTagName.toLowerCase(); if (isIE && (nodeName == "form" || nodeName == "input" || nodeName == "textarea" || nodeName == "select" || nodeName == "a" || nodeName == "applet" || nodeName == "button" || nodeName == "img" || nodeName == "link" || nodeName == "map" || nodeName == "object")) { useIEStrategy = true; } return useIEStrategy; } function createFormElementsForIEStrategy(xmlNode) { var attr = null; var name = ""; var value = ""; for (var x = 0; x < xmlNode.attributes.length; x++) { attr = xmlNode.attributes[x]; name = attr.name.trim(); if (name == "name") { value = attr.value.trim(); } } domElemNode = document.createElement("<" + xmlNode.tagName + " name='" + value + "' />"); // e.g. document.createElement(""); return domElemNode; } function handleAttributes(domNode, xmlNode) { var attr = null; var attrString = ""; var name = ""; var value = ""; var returnAsText = false; if(arguments.length == 3) { returnAsText = true; } for(var x = 0; x < xmlNode.attributes.length; x++) { attr = xmlNode.attributes[x]; name = cleanAttributeName(attr.name.trim()); value = attr.value.trim(); if(!returnAsText){ if(name == "style") { /* IE workaround */ domNode.style.cssText = value; /* Standards compliant */ domNode.setAttribute(name, value); } else if(name.trim().toLowerCase().substring(0, 2) == "on") { /* IE workaround for event handlers */ if(isIE) { eval("domNode." + name.trim().toLowerCase() + "=function(){" + value + "}"); } else { domNode.setAttribute(name,value); } } else if(name == "value") { /* IE workaround for the value attribute -- makes form elements selectable/editable */ domNode.value = value; } else if(useIEFormElementCreationStrategy(xmlNode.tagName) && name == "name") { //Do nothing, as the "name" attribute was handled in the createFormElementsForIEStrategy function continue; } else { /* Standards compliant */ domNode.setAttribute(name,value); } /* class attribute workaround for IE */ if(name == "class") { domNode.setAttribute("className",value); } /* This is a workaround for a bug in IE where select elemnts with multiple don't have all the appropriate options selected. Only one is selected. Appears fixed in IE7. */ if(isIE) { if(name == "multiple" && domNode.id != "") { setTimeout("TaconiteDOMUtils.setMultipleSelectOptions('" + domNode.id + "');", 100); } if(name == "selected") { domNode.taconiteOptionSelected = true; } } } else{ attrString = attrString + name + "=\"" + value + "\" " ; } } return attrString; } function getAppendAsFirstChild(domNode,xml){ var firstNode=null; if(domNode.childNodes.length > 0) { firstNode=domNode.childNodes[0]; } for(var i=0;i0){ domNode.removeChild(domNode.childNodes[0]); } } for(var i=0;i combinator selector = selector.replace(/\s*(?=>)/g, ''); selector = selector.replace(/>\s*/g, '>'); // + combinator selector = selector.replace(/\s*(?=\+)/g, ''); selector = selector.replace(/\+\s*/g, '+'); // ~ combinator selector = selector.replace(/\s*(?=~)/g, ''); selector = selector.replace(/~\s*/g, '~'); // Split selector into tokens var splitter = /\s|>|\+|~/g; var combinators = selector.match(splitter); var tokens = selector.split(splitter); var currentContext = new Array(rootContext); // Prepare regular expressions that will be used later: var attributesRegexp = /^(\w*)\[(\w+)([=~\|\^\$\*]?)=?"?([^\]"]*)"?\]$/; var pseudoClassesRegexp = /^(\w*)\:(\w+-?\w+)/; var regexpResult = null; // Go! for (var i = 0; i < tokens.length; i++) { var combinator = i == 0 ? " " : combinators[i - 1]; var token = tokens[i].trim(); if (token.indexOf('#') > -1) { // Token is an ID selector var tagName = token.substring(0, token.indexOf('#')); var id = token.substring(token.indexOf('#') + 1, token.length); var filterFunction = function(e) { return (e.id == id); }; var found = new Array(); for (var h = 0; h < currentContext.length; h++) { found = selectByFilter(combinator, currentContext[h], tagName, filterFunction); if (found && found.length == 1) { break; } } // Set currentContext to contain just this element currentContext = found; // Skip to next token continue; } else if ((regexpResult = attributesRegexp.exec(token))) { // Token contains attribute selectors var tagName = regexpResult[1]; var attrName = regexpResult[2]; var attrOperator = regexpResult[3]; var attrValue = regexpResult[4]; // Attribute filtering functions: var filterFunction = null; // This function will be used to filter the elements switch (attrOperator) { case '=': // Equality filterFunction = function(e) { return (e.getAttribute(attrName) && e.getAttribute(attrName) == attrValue); }; break; case '~': // Match one of space seperated words filterFunction = function(e) { return (e.getAttribute(attrName) && e.getAttribute(attrName).match(new RegExp('(\\s|^)' + attrValue + '(\\s|$)'))); }; break; case '|': // Match start with value followed by optional hyphen filterFunction = function(e) { return (e.getAttribute(attrName) && e.getAttribute(attrName).match(new RegExp('^' + attrValue + '-?'))); }; break; case '^': // Match starts with value filterFunction = function(e) { return (e.getAttribute(attrName) && e.getAttribute(attrName).indexOf(attrValue) == 0); }; break; case '$': // Match ends with value - fails with "Warning" in Opera 7 filterFunction = function(e) { return (e.getAttribute(attrName) && (e.getAttribute(attrName).lastIndexOf(attrValue) == e.getAttribute(attrName).length - attrValue.length)); }; break; case '*': // Match contains value filterFunction = function(e) { return (e.getAttribute(attrName) && e.getAttribute(attrName).indexOf(attrValue) > -1); }; break; default : // Just test for existence of attribute filterFunction = function(e) { return e.getAttribute(attrName); }; } var found = new Array(); var counter = 0; for (var h = 0; h < currentContext.length; h++) { var elements = selectByFilter(combinator, currentContext[h], tagName, filterFunction); for (var j = 0; j < elements.length; j++) { found[counter++] = elements[j]; } } currentContext = found; // Skip to next token continue; } else if ((regexpResult = pseudoClassesRegexp.exec(token))) { // Token contains pseudo-class selectors var tagName = regexpResult[1]; var pseudoClass = regexpResult[2]; // Pseudo class filtering functions: var filterFunction = null; // This function will be used to filter the elements switch (pseudoClass) { case 'first-child': filterFunction = function(e) { var parent = e.parentNode; var i = 0; while (parent.childNodes[i] && parent.childNodes[i].nodeType != 1) i++; return (parent.childNodes[i] == e); }; break; case 'last-child': filterFunction = function(e) { var parent = e.parentNode; var i = parent.childNodes.length - 1; while (parent.childNodes[i] && parent.childNodes[i].nodeType != 1) i--; return (parent.childNodes[i] == e); }; break; case 'empty': filterFunction = function(e) { return (e.childNodes.length == 0); }; break; default : filterFunction = function(e) { return false; }; } var found = new Array(); var counter = 0; for (var h = 0; h < currentContext.length; h++) { var elements = selectByFilter(combinator, currentContext[h], tagName, filterFunction); for (var j = 0; j < elements.length; j++) { found[counter++] = elements[j]; } } currentContext = found; // Skip to next token continue; } else if (token.indexOf('.') > -1) { // Token contains a class selector var tagName = token.substring(0, token.indexOf('.')); var className = token.substring(token.indexOf('.') + 1, token.length); var regexp = new RegExp('(\\s|^)' + className + '(\\s|$)'); var filterFunction = function(e) { return (e.className && e.className.match(regexp)); }; var found = new Array(); var counter = 0; for (var h = 0; h < currentContext.length; h++) { var elements = selectByFilter(combinator, currentContext[h], tagName, filterFunction); for (var j = 0; j < elements.length; j++) { found[counter++] = elements[j]; } } currentContext = found; // Skip to next token continue; } else { // If we get here, token is just an element (not a class or ID selector) tagName = token; var filterFunction = function(e) { return true; }; var found = new Array(); var counter = 0; for (var h = 0; h < currentContext.length; h++) { var elements = selectByFilter(combinator, currentContext[h], tagName, filterFunction); for (var j = 0; j < elements.length; j++) { found[counter++] = elements[j]; } } currentContext = found; } } return currentContext; } function selectByFilter(combinator, context, tagName, filterFunction) { var result = new Array(); var elements = new Array(); // Get elements to filter depending on the combinator: if (combinator == " ") { elements = TaconiteDOMUtils.getAllSubElements(context); } else if (combinator == ">") { elements = context.childNodes; } else if (combinator == "+") { var sibling = context.nextSibling; while (sibling && sibling.nodeType != 1) { sibling = sibling.nextSibling; } if (sibling) elements = new Array(sibling); else elements = new Array(); } else if (combinator == "~") { var sibling = context.nextSibling; var counter = 0; while (sibling) { if (sibling.nodeType == 1) { elements[counter] = sibling; counter++; } sibling = sibling.nextSibling; } } // Actually filter elements by tag name and filter function: var counter = 0; if (!tagName || tagName == '*') { for (var k = 0; k < elements.length; k++) { if (elements[k].nodeType == 1 && filterFunction(elements[k])) { result[counter] = elements[k]; counter++; } } } else { for (var k = 0; k < elements.length; k++) { if (elements[k].nodeType == 1 && elements[k].nodeName.toLowerCase() == tagName.toLowerCase() && filterFunction(elements[k])) { result[counter] = elements[k]; counter++; } } } return result; } }; String.prototype.trim = function() { //skip leading and trailing whitespace //and return everything in between var x=this; x=x.replace(/^\s*(.*)/, "$1"); x=x.replace(/(.*?)\s*$/, "$1"); return x; }; document.getElementsByMatchingId = function(matchingId) { var allElements = TaconiteDOMUtils.getAllSubElements(document); var matchingElements = new Array(); for (var i = 0; i < allElements.length; i++) { var currentElement = allElements[i]; if (currentElement.nodeType == 1) { var id = currentElement.getAttribute("id"); if (id != null && id != "") { if (id.indexOf("_") == (id.length - 1)) { var pattern = "^" + id.replace(/_$/, ".*"); var rexp = new RegExp(pattern); if (rexp.test(matchingId)) { matchingElements.push(currentElement); } } else if (id == matchingId) { matchingElements.push(currentElement); } } } } return matchingElements; }; //taconite-parser-min.js var taconite_parser_version="2.0";var isIE=document.uniqueID;var TaconiteDOMUtils={getAllSubElements:function(element){return element.all?element.all:element.getElementsByTagName('*');},setMultipleSelectOptions:function(selectNodeId){var selectNode=document.getElementById(selectNodeId);var options=document.getElementById(selectNodeId).getElementsByTagName("option");var option;for(var i=0;i");} if(xmlNodeTagName=="style"){var text,rulesArray,styleSheetPtr;var regExp=/\s+/g;text=xmlNode.text.replace(regExp," ");rulesArray=text.split("}");domElemNode=document.createElement("style");styleSheetPtr=document.styleSheets[document.styleSheets.length-1];for(var i=0;i0){domElemNode.text=xmlNode.text;}} else{for(var z=0;z");return domElemNode;} function handleAttributes(domNode,xmlNode){var attr=null;var attrString="";var name="";var value="";var returnAsText=false;if(arguments.length==3){returnAsText=true;} for(var x=0;x0){firstNode=domNode.childNodes[0];} for(var i=0;i0){domNode.removeChild(domNode.childNodes[0]);}} for(var i=0;i)/g,'');selector=selector.replace(/>\s*/g,'>');selector=selector.replace(/\s*(?=\+)/g,'');selector=selector.replace(/\+\s*/g,'+');selector=selector.replace(/\s*(?=~)/g,'');selector=selector.replace(/~\s*/g,'~');var splitter=/\s|>|\+|~/g;var combinators=selector.match(splitter);var tokens=selector.split(splitter);var currentContext=new Array(rootContext);var attributesRegexp=/^(\w*)\[(\w+)([=~\|\^\$\*]?)=?"?([^\]"]*)"?\]$/;var pseudoClassesRegexp=/^(\w*)\:(\w+-?\w+)/;var regexpResult=null;for(var i=0;i-1){var tagName=token.substring(0,token.indexOf('#'));var id=token.substring(token.indexOf('#')+1,token.length);var filterFunction=function(e){return(e.id==id);};var found=new Array();for(var h=0;h-1);};break;default:filterFunction=function(e){return e.getAttribute(attrName);};} var found=new Array();var counter=0;for(var h=0;h-1){var tagName=token.substring(0,token.indexOf('.'));var className=token.substring(token.indexOf('.')+1,token.length);var regexp=new RegExp('(\\s|^)'+className+'(\\s|$)');var filterFunction=function(e){return(e.className&&e.className.match(regexp));};var found=new Array();var counter=0;for(var h=0;h"){elements=context.childNodes;}else if(combinator=="+"){var sibling=context.nextSibling;while(sibling&&sibling.nodeType!=1){sibling=sibling.nextSibling;} if(sibling)elements=new Array(sibling);else elements=new Array();}else if(combinator=="~"){var sibling=context.nextSibling;var counter=0;while(sibling){if(sibling.nodeType==1){elements[counter]=sibling;counter++;} sibling=sibling.nextSibling;}} var counter=0;if(!tagName||tagName=='*'){for(var k=0;k0){elementValues=toQueryString(arNamedElements);accumulateQueryString(elementValues);}}} this.addNamedFormElements=function(){var elementName="";var namedElements=null;for(var i=0;i0){requestURL=requestURL+"&ts="+new Date().getTime();} else{requestURL=requestURL+"?ts="+new Date().getTime();} try{if(method=="GET"){if(queryString.length>0){requestURL=requestURL+"&"+queryString;} xmlHttp.open(method,requestURL,async);xmlHttp.send(null);} else{xmlHttp.open(method,requestURL,async);try{if(xmlHttp.overrideMimeType){xmlHttp.setRequestHeader("Connection","close");}} catch(e){} xmlHttp.setRequestHeader("Content-Type","application/x-www-form-urlencoded");xmlHttp.send(queryString);}} catch(exception){if(errorHandler){errorHandler(self,exception);} else{throw exception;}} if(!async){handleStateChange(self);} if(self.isEchoDebugInfo()){echoRequestParams();}} handleStateChange=function(ajaxRequest){if(ajaxRequest.getXMLHttpRequestObject().readyState!=4){return;} if(ajaxRequest.getXMLHttpRequestObject().status!=200){errorHandler(self);return;} try{var debug=ajaxRequest.isEchoDebugInfo();if(debug){echoResponse(ajaxRequest);} var nodes=null;if(ajaxRequest.getXMLHttpRequestObject().responseXML!=null){nodes=ajaxRequest.getXMLHttpRequestObject().responseXML.documentElement.childNodes;} else{nodes=new Array();} var parser=new XhtmlToDOMParser();var parseInBrowser="";for(var i=0;i 0 && charpos >= 0) { if(!strError || strError.length ==0) { strError = objValue.name+": Only alpha-numeric characters allowed "; }//if alert(strError + "\n [Error character position " + eval(charpos+1)+"]"); return false; }//if break; }//case alphanumeric case "num": case "numeric": { var charpos = objValue.value.search("[^0-9]"); if(objValue.value.length > 0 && charpos >= 0) { if(!strError || strError.length ==0) { strError = objValue.name+": Only digits allowed "; }//if alert(strError + "\n [Error character position " + eval(charpos+1)+"]"); return false; }//if break; }//numeric case "alphabetic": case "alpha": { var charpos = objValue.value.search("[^A-Za-z]"); */ function hasInvalidChars( searchSet, allowedChar ){ var charpos = searchSet.search( "[^"+allowedChar+"]" ); if(searchSet.length > 0 && charpos >= 0) { return true; } return false } function preventCharacter( searchSet, disallowedChar ){ var charpos = searchSet.search( "["+disallowedChar+"]" ); if(searchSet.length > 0 && charpos >= 0) { return true; } return false } function isNull(a){ return typeof a == 'object' && !a; } function readLayer(ID,parentID) { if (document.layers) { var oLayer; if(parentID){ oLayer = eval('document.' + parentID + '.document.' + ID + '.document'); }else{ oLayer = document.layers[ID].document; } oLayer.open(); sText = oLayer.read(); oLayer.close(); } else if (parseInt(navigator.appVersion)>=5&&navigator.appName=="Netscape") { sText = document.getElementById(ID).innerHTML; }else if (document.all){ sText = document.all[ID].innerHTML ; } return sText; } //js_config.php //cms_form.js // JavaScript Document function createPanel( panel, elements ) { var cpc = $(panel); var arr = elements.split(","); arr.each( function(i) { var td = $( i + "_formline"); cpc.appendChild(td); }); } //prototype.js /* Prototype JavaScript framework, version 1.6.0 * (c) 2005-2007 Sam Stephenson * * Prototype is freely distributable under the terms of an MIT-style license. * For details, see the Prototype web site: http://www.prototypejs.org/ * *--------------------------------------------------------------------------*/ var Prototype = { Version: '1.6.0', Browser: { IE: !!(window.attachEvent && !window.opera), Opera: !!window.opera, WebKit: navigator.userAgent.indexOf('AppleWebKit/') > -1, Gecko: navigator.userAgent.indexOf('Gecko') > -1 && navigator.userAgent.indexOf('KHTML') == -1, MobileSafari: !!navigator.userAgent.match(/Apple.*Mobile.*Safari/) }, BrowserFeatures: { XPath: !!document.evaluate, ElementExtensions: !!window.HTMLElement, SpecificElementExtensions: document.createElement('div').__proto__ && document.createElement('div').__proto__ !== document.createElement('form').__proto__ }, ScriptFragment: ']*>([\\S\\s]*?)<\/script>', JSONFilter: /^\/\*-secure-([\s\S]*)\*\/\s*$/, emptyFunction: function() { }, K: function(x) { return x } }; if (Prototype.Browser.MobileSafari) Prototype.BrowserFeatures.SpecificElementExtensions = false; if (Prototype.Browser.WebKit) Prototype.BrowserFeatures.XPath = false; /* Based on Alex Arnell's inheritance implementation. */ var Class = { create: function() { var parent = null, properties = $A(arguments); if (Object.isFunction(properties[0])) parent = properties.shift(); function klass() { this.initialize.apply(this, arguments); } Object.extend(klass, Class.Methods); klass.superclass = parent; klass.subclasses = []; if (parent) { var subclass = function() { }; subclass.prototype = parent.prototype; klass.prototype = new subclass; parent.subclasses.push(klass); } for (var i = 0; i < properties.length; i++) klass.addMethods(properties[i]); if (!klass.prototype.initialize) klass.prototype.initialize = Prototype.emptyFunction; klass.prototype.constructor = klass; return klass; } }; Class.Methods = { addMethods: function(source) { var ancestor = this.superclass && this.superclass.prototype; var properties = Object.keys(source); if (!Object.keys({ toString: true }).length) properties.push("toString", "valueOf"); for (var i = 0, length = properties.length; i < length; i++) { var property = properties[i], value = source[property]; if (ancestor && Object.isFunction(value) && value.argumentNames().first() == "$super") { var method = value, value = Object.extend((function(m) { return function() { return ancestor[m].apply(this, arguments) }; })(property).wrap(method), { valueOf: function() { return method }, toString: function() { return method.toString() } }); } this.prototype[property] = value; } return this; } }; var Abstract = { }; Object.extend = function(destination, source) { for (var property in source) destination[property] = source[property]; return destination; }; Object.extend(Object, { inspect: function(object) { try { if (object === undefined) return 'undefined'; if (object === null) return 'null'; return object.inspect ? object.inspect() : object.toString(); } catch (e) { if (e instanceof RangeError) return '...'; throw e; } }, toJSON: function(object) { var type = typeof object; switch (type) { case 'undefined': case 'function': case 'unknown': return; case 'boolean': return object.toString(); } if (object === null) return 'null'; if (object.toJSON) return object.toJSON(); if (Object.isElement(object)) return; var results = []; for (var property in object) { var value = Object.toJSON(object[property]); if (value !== undefined) results.push(property.toJSON() + ': ' + value); } return '{' + results.join(', ') + '}'; }, toQueryString: function(object) { return $H(object).toQueryString(); }, toHTML: function(object) { return object && object.toHTML ? object.toHTML() : String.interpret(object); }, keys: function(object) { var keys = []; for (var property in object) keys.push(property); return keys; }, values: function(object) { var values = []; for (var property in object) values.push(object[property]); return values; }, clone: function(object) { return Object.extend({ }, object); }, isElement: function(object) { return object && object.nodeType == 1; }, isArray: function(object) { return object && object.constructor === Array; }, isHash: function(object) { return object instanceof Hash; }, isFunction: function(object) { return typeof object == "function"; }, isString: function(object) { return typeof object == "string"; }, isNumber: function(object) { return typeof object == "number"; }, isUndefined: function(object) { return typeof object == "undefined"; } }); Object.extend(Function.prototype, { argumentNames: function() { var names = this.toString().match(/^[\s\(]*function[^(]*\((.*?)\)/)[1].split(",").invoke("strip"); return names.length == 1 && !names[0] ? [] : names; }, bind: function() { if (arguments.length < 2 && arguments[0] === undefined) return this; var __method = this, args = $A(arguments), object = args.shift(); return function() { return __method.apply(object, args.concat($A(arguments))); } }, bindAsEventListener: function() { var __method = this, args = $A(arguments), object = args.shift(); return function(event) { return __method.apply(object, [event || window.event].concat(args)); } }, curry: function() { if (!arguments.length) return this; var __method = this, args = $A(arguments); return function() { return __method.apply(this, args.concat($A(arguments))); } }, delay: function() { var __method = this, args = $A(arguments), timeout = args.shift() * 1000; return window.setTimeout(function() { return __method.apply(__method, args); }, timeout); }, wrap: function(wrapper) { var __method = this; return function() { return wrapper.apply(this, [__method.bind(this)].concat($A(arguments))); } }, methodize: function() { if (this._methodized) return this._methodized; var __method = this; return this._methodized = function() { return __method.apply(null, [this].concat($A(arguments))); }; } }); Function.prototype.defer = Function.prototype.delay.curry(0.01); Date.prototype.toJSON = function() { return '"' + this.getUTCFullYear() + '-' + (this.getUTCMonth() + 1).toPaddedString(2) + '-' + this.getUTCDate().toPaddedString(2) + 'T' + this.getUTCHours().toPaddedString(2) + ':' + this.getUTCMinutes().toPaddedString(2) + ':' + this.getUTCSeconds().toPaddedString(2) + 'Z"'; }; var Try = { these: function() { var returnValue; for (var i = 0, length = arguments.length; i < length; i++) { var lambda = arguments[i]; try { returnValue = lambda(); break; } catch (e) { } } return returnValue; } }; RegExp.prototype.match = RegExp.prototype.test; RegExp.escape = function(str) { return String(str).replace(/([.*+?^=!:${}()|[\]\/\\])/g, '\\$1'); }; /*--------------------------------------------------------------------------*/ var PeriodicalExecuter = Class.create({ initialize: function(callback, frequency) { this.callback = callback; this.frequency = frequency; this.currentlyExecuting = false; this.registerCallback(); }, registerCallback: function() { this.timer = setInterval(this.onTimerEvent.bind(this), this.frequency * 1000); }, execute: function() { this.callback(this); }, stop: function() { if (!this.timer) return; clearInterval(this.timer); this.timer = null; }, onTimerEvent: function() { if (!this.currentlyExecuting) { try { this.currentlyExecuting = true; this.execute(); } finally { this.currentlyExecuting = false; } } } }); Object.extend(String, { interpret: function(value) { return value == null ? '' : String(value); }, specialChar: { '\b': '\\b', '\t': '\\t', '\n': '\\n', '\f': '\\f', '\r': '\\r', '\\': '\\\\' } }); Object.extend(String.prototype, { gsub: function(pattern, replacement) { var result = '', source = this, match; replacement = arguments.callee.prepareReplacement(replacement); while (source.length > 0) { if (match = source.match(pattern)) { result += source.slice(0, match.index); result += String.interpret(replacement(match)); source = source.slice(match.index + match[0].length); } else { result += source, source = ''; } } return result; }, sub: function(pattern, replacement, count) { replacement = this.gsub.prepareReplacement(replacement); count = count === undefined ? 1 : count; return this.gsub(pattern, function(match) { if (--count < 0) return match[0]; return replacement(match); }); }, scan: function(pattern, iterator) { this.gsub(pattern, iterator); return String(this); }, truncate: function(length, truncation) { length = length || 30; truncation = truncation === undefined ? '...' : truncation; return this.length > length ? this.slice(0, length - truncation.length) + truncation : String(this); }, strip: function() { return this.replace(/^\s+/, '').replace(/\s+$/, ''); }, stripTags: function() { return this.replace(/<\/?[^>]+>/gi, ''); }, stripScripts: function() { return this.replace(new RegExp(Prototype.ScriptFragment, 'img'), ''); }, extractScripts: function() { var matchAll = new RegExp(Prototype.ScriptFragment, 'img'); var matchOne = new RegExp(Prototype.ScriptFragment, 'im'); return (this.match(matchAll) || []).map(function(scriptTag) { return (scriptTag.match(matchOne) || ['', ''])[1]; }); }, evalScripts: function() { return this.extractScripts().map(function(script) { return eval(script) }); }, escapeHTML: function() { var self = arguments.callee; self.text.data = this; return self.div.innerHTML; }, unescapeHTML: function() { var div = new Element('div'); div.innerHTML = this.stripTags(); return div.childNodes[0] ? (div.childNodes.length > 1 ? $A(div.childNodes).inject('', function(memo, node) { return memo+node.nodeValue }) : div.childNodes[0].nodeValue) : ''; }, toQueryParams: function(separator) { var match = this.strip().match(/([^?#]*)(#.*)?$/); if (!match) return { }; return match[1].split(separator || '&').inject({ }, function(hash, pair) { if ((pair = pair.split('='))[0]) { var key = decodeURIComponent(pair.shift()); var value = pair.length > 1 ? pair.join('=') : pair[0]; if (value != undefined) value = decodeURIComponent(value); if (key in hash) { if (!Object.isArray(hash[key])) hash[key] = [hash[key]]; hash[key].push(value); } else hash[key] = value; } return hash; }); }, toArray: function() { return this.split(''); }, succ: function() { return this.slice(0, this.length - 1) + String.fromCharCode(this.charCodeAt(this.length - 1) + 1); }, times: function(count) { return count < 1 ? '' : new Array(count + 1).join(this); }, camelize: function() { var parts = this.split('-'), len = parts.length; if (len == 1) return parts[0]; var camelized = this.charAt(0) == '-' ? parts[0].charAt(0).toUpperCase() + parts[0].substring(1) : parts[0]; for (var i = 1; i < len; i++) camelized += parts[i].charAt(0).toUpperCase() + parts[i].substring(1); return camelized; }, capitalize: function() { return this.charAt(0).toUpperCase() + this.substring(1).toLowerCase(); }, underscore: function() { return this.gsub(/::/, '/').gsub(/([A-Z]+)([A-Z][a-z])/,'#{1}_#{2}').gsub(/([a-z\d])([A-Z])/,'#{1}_#{2}').gsub(/-/,'_').toLowerCase(); }, dasherize: function() { return this.gsub(/_/,'-'); }, inspect: function(useDoubleQuotes) { var escapedString = this.gsub(/[\x00-\x1f\\]/, function(match) { var character = String.specialChar[match[0]]; return character ? character : '\\u00' + match[0].charCodeAt().toPaddedString(2, 16); }); if (useDoubleQuotes) return '"' + escapedString.replace(/"/g, '\\"') + '"'; return "'" + escapedString.replace(/'/g, '\\\'') + "'"; }, toJSON: function() { return this.inspect(true); }, unfilterJSON: function(filter) { return this.sub(filter || Prototype.JSONFilter, '#{1}'); }, isJSON: function() { var str = this.replace(/\\./g, '@').replace(/"[^"\\\n\r]*"/g, ''); return (/^[,:{}\[\]0-9.\-+Eaeflnr-u \n\r\t]*$/).test(str); }, evalJSON: function(sanitize) { var json = this.unfilterJSON(); try { if (!sanitize || json.isJSON()) return eval('(' + json + ')'); } catch (e) { } throw new SyntaxError('Badly formed JSON string: ' + this.inspect()); }, include: function(pattern) { return this.indexOf(pattern) > -1; }, startsWith: function(pattern) { return this.indexOf(pattern) === 0; }, endsWith: function(pattern) { var d = this.length - pattern.length; return d >= 0 && this.lastIndexOf(pattern) === d; }, empty: function() { return this == ''; }, blank: function() { return /^\s*$/.test(this); }, interpolate: function(object, pattern) { return new Template(this, pattern).evaluate(object); } }); if (Prototype.Browser.WebKit || Prototype.Browser.IE) Object.extend(String.prototype, { escapeHTML: function() { return this.replace(/&/g,'&').replace(//g,'>'); }, unescapeHTML: function() { return this.replace(/&/g,'&').replace(/</g,'<').replace(/>/g,'>'); } }); String.prototype.gsub.prepareReplacement = function(replacement) { if (Object.isFunction(replacement)) return replacement; var template = new Template(replacement); return function(match) { return template.evaluate(match) }; }; String.prototype.parseQuery = String.prototype.toQueryParams; Object.extend(String.prototype.escapeHTML, { div: document.createElement('div'), text: document.createTextNode('') }); with (String.prototype.escapeHTML) div.appendChild(text); var Template = Class.create({ initialize: function(template, pattern) { this.template = template.toString(); this.pattern = pattern || Template.Pattern; }, evaluate: function(object) { if (Object.isFunction(object.toTemplateReplacements)) object = object.toTemplateReplacements(); return this.template.gsub(this.pattern, function(match) { if (object == null) return ''; var before = match[1] || ''; if (before == '\\') return match[2]; var ctx = object, expr = match[3]; var pattern = /^([^.[]+|\[((?:.*?[^\\])?)\])(\.|\[|$)/, match = pattern.exec(expr); if (match == null) return before; while (match != null) { var comp = match[1].startsWith('[') ? match[2].gsub('\\\\]', ']') : match[1]; ctx = ctx[comp]; if (null == ctx || '' == match[3]) break; expr = expr.substring('[' == match[3] ? match[1].length : match[0].length); match = pattern.exec(expr); } return before + String.interpret(ctx); }.bind(this)); } }); Template.Pattern = /(^|.|\r|\n)(#\{(.*?)\})/; var $break = { }; var Enumerable = { each: function(iterator, context) { var index = 0; iterator = iterator.bind(context); try { this._each(function(value) { iterator(value, index++); }); } catch (e) { if (e != $break) throw e; } return this; }, eachSlice: function(number, iterator, context) { iterator = iterator ? iterator.bind(context) : Prototype.K; var index = -number, slices = [], array = this.toArray(); while ((index += number) < array.length) slices.push(array.slice(index, index+number)); return slices.collect(iterator, context); }, all: function(iterator, context) { iterator = iterator ? iterator.bind(context) : Prototype.K; var result = true; this.each(function(value, index) { result = result && !!iterator(value, index); if (!result) throw $break; }); return result; }, any: function(iterator, context) { iterator = iterator ? iterator.bind(context) : Prototype.K; var result = false; this.each(function(value, index) { if (result = !!iterator(value, index)) throw $break; }); return result; }, collect: function(iterator, context) { iterator = iterator ? iterator.bind(context) : Prototype.K; var results = []; this.each(function(value, index) { results.push(iterator(value, index)); }); return results; }, detect: function(iterator, context) { iterator = iterator.bind(context); var result; this.each(function(value, index) { if (iterator(value, index)) { result = value; throw $break; } }); return result; }, findAll: function(iterator, context) { iterator = iterator.bind(context); var results = []; this.each(function(value, index) { if (iterator(value, index)) results.push(value); }); return results; }, grep: function(filter, iterator, context) { iterator = iterator ? iterator.bind(context) : Prototype.K; var results = []; if (Object.isString(filter)) filter = new RegExp(filter); this.each(function(value, index) { if (filter.match(value)) results.push(iterator(value, index)); }); return results; }, include: function(object) { if (Object.isFunction(this.indexOf)) if (this.indexOf(object) != -1) return true; var found = false; this.each(function(value) { if (value == object) { found = true; throw $break; } }); return found; }, inGroupsOf: function(number, fillWith) { fillWith = fillWith === undefined ? null : fillWith; return this.eachSlice(number, function(slice) { while(slice.length < number) slice.push(fillWith); return slice; }); }, inject: function(memo, iterator, context) { iterator = iterator.bind(context); this.each(function(value, index) { memo = iterator(memo, value, index); }); return memo; }, invoke: function(method) { var args = $A(arguments).slice(1); return this.map(function(value) { return value[method].apply(value, args); }); }, max: function(iterator, context) { iterator = iterator ? iterator.bind(context) : Prototype.K; var result; this.each(function(value, index) { value = iterator(value, index); if (result == undefined || value >= result) result = value; }); return result; }, min: function(iterator, context) { iterator = iterator ? iterator.bind(context) : Prototype.K; var result; this.each(function(value, index) { value = iterator(value, index); if (result == undefined || value < result) result = value; }); return result; }, partition: function(iterator, context) { iterator = iterator ? iterator.bind(context) : Prototype.K; var trues = [], falses = []; this.each(function(value, index) { (iterator(value, index) ? trues : falses).push(value); }); return [trues, falses]; }, pluck: function(property) { var results = []; this.each(function(value) { results.push(value[property]); }); return results; }, reject: function(iterator, context) { iterator = iterator.bind(context); var results = []; this.each(function(value, index) { if (!iterator(value, index)) results.push(value); }); return results; }, sortBy: function(iterator, context) { iterator = iterator.bind(context); return this.map(function(value, index) { return {value: value, criteria: iterator(value, index)}; }).sort(function(left, right) { var a = left.criteria, b = right.criteria; return a < b ? -1 : a > b ? 1 : 0; }).pluck('value'); }, toArray: function() { return this.map(); }, zip: function() { var iterator = Prototype.K, args = $A(arguments); if (Object.isFunction(args.last())) iterator = args.pop(); var collections = [this].concat(args).map($A); return this.map(function(value, index) { return iterator(collections.pluck(index)); }); }, size: function() { return this.toArray().length; }, inspect: function() { return '#'; } }; Object.extend(Enumerable, { map: Enumerable.collect, find: Enumerable.detect, select: Enumerable.findAll, filter: Enumerable.findAll, member: Enumerable.include, entries: Enumerable.toArray, every: Enumerable.all, some: Enumerable.any }); function $A(iterable) { if (!iterable) return []; if (iterable.toArray) return iterable.toArray(); var length = iterable.length, results = new Array(length); while (length--) results[length] = iterable[length]; return results; } if (Prototype.Browser.WebKit) { function $A(iterable) { if (!iterable) return []; if (!(Object.isFunction(iterable) && iterable == '[object NodeList]') && iterable.toArray) return iterable.toArray(); var length = iterable.length, results = new Array(length); while (length--) results[length] = iterable[length]; return results; } } Array.from = $A; Object.extend(Array.prototype, Enumerable); if (!Array.prototype._reverse) Array.prototype._reverse = Array.prototype.reverse; Object.extend(Array.prototype, { _each: function(iterator) { for (var i = 0, length = this.length; i < length; i++) iterator(this[i]); }, clear: function() { this.length = 0; return this; }, first: function() { return this[0]; }, last: function() { return this[this.length - 1]; }, compact: function() { return this.select(function(value) { return value != null; }); }, flatten: function() { return this.inject([], function(array, value) { return array.concat(Object.isArray(value) ? value.flatten() : [value]); }); }, without: function() { var values = $A(arguments); return this.select(function(value) { return !values.include(value); }); }, reverse: function(inline) { return (inline !== false ? this : this.toArray())._reverse(); }, reduce: function() { return this.length > 1 ? this : this[0]; }, uniq: function(sorted) { return this.inject([], function(array, value, index) { if (0 == index || (sorted ? array.last() != value : !array.include(value))) array.push(value); return array; }); }, intersect: function(array) { return this.uniq().findAll(function(item) { return array.detect(function(value) { return item === value }); }); }, clone: function() { return [].concat(this); }, size: function() { return this.length; }, inspect: function() { return '[' + this.map(Object.inspect).join(', ') + ']'; }, toJSON: function() { var results = []; this.each(function(object) { var value = Object.toJSON(object); if (value !== undefined) results.push(value); }); return '[' + results.join(', ') + ']'; } }); // use native browser JS 1.6 implementation if available if (Object.isFunction(Array.prototype.forEach)) Array.prototype._each = Array.prototype.forEach; if (!Array.prototype.indexOf) Array.prototype.indexOf = function(item, i) { i || (i = 0); var length = this.length; if (i < 0) i = length + i; for (; i < length; i++) if (this[i] === item) return i; return -1; }; if (!Array.prototype.lastIndexOf) Array.prototype.lastIndexOf = function(item, i) { i = isNaN(i) ? this.length : (i < 0 ? this.length + i : i) + 1; var n = this.slice(0, i).reverse().indexOf(item); return (n < 0) ? n : i - n - 1; }; Array.prototype.toArray = Array.prototype.clone; function $w(string) { if (!Object.isString(string)) return []; string = string.strip(); return string ? string.split(/\s+/) : []; } if (Prototype.Browser.Opera){ Array.prototype.concat = function() { var array = []; for (var i = 0, length = this.length; i < length; i++) array.push(this[i]); for (var i = 0, length = arguments.length; i < length; i++) { if (Object.isArray(arguments[i])) { for (var j = 0, arrayLength = arguments[i].length; j < arrayLength; j++) array.push(arguments[i][j]); } else { array.push(arguments[i]); } } return array; }; } Object.extend(Number.prototype, { toColorPart: function() { return this.toPaddedString(2, 16); }, succ: function() { return this + 1; }, times: function(iterator) { $R(0, this, true).each(iterator); return this; }, toPaddedString: function(length, radix) { var string = this.toString(radix || 10); return '0'.times(length - string.length) + string; }, toJSON: function() { return isFinite(this) ? this.toString() : 'null'; } }); $w('abs round ceil floor').each(function(method){ Number.prototype[method] = Math[method].methodize(); }); function $H(object) { return new Hash(object); }; var Hash = Class.create(Enumerable, (function() { if (function() { var i = 0, Test = function(value) { this.key = value }; Test.prototype.key = 'foo'; for (var property in new Test('bar')) i++; return i > 1; }()) { function each(iterator) { var cache = []; for (var key in this._object) { var value = this._object[key]; if (cache.include(key)) continue; cache.push(key); var pair = [key, value]; pair.key = key; pair.value = value; iterator(pair); } } } else { function each(iterator) { for (var key in this._object) { var value = this._object[key], pair = [key, value]; pair.key = key; pair.value = value; iterator(pair); } } } function toQueryPair(key, value) { if (Object.isUndefined(value)) return key; return key + '=' + encodeURIComponent(String.interpret(value)); } return { initialize: function(object) { this._object = Object.isHash(object) ? object.toObject() : Object.clone(object); }, _each: each, set: function(key, value) { return this._object[key] = value; }, get: function(key) { return this._object[key]; }, unset: function(key) { var value = this._object[key]; delete this._object[key]; return value; }, toObject: function() { return Object.clone(this._object); }, keys: function() { return this.pluck('key'); }, values: function() { return this.pluck('value'); }, index: function(value) { var match = this.detect(function(pair) { return pair.value === value; }); return match && match.key; }, merge: function(object) { return this.clone().update(object); }, update: function(object) { return new Hash(object).inject(this, function(result, pair) { result.set(pair.key, pair.value); return result; }); }, toQueryString: function() { return this.map(function(pair) { var key = encodeURIComponent(pair.key), values = pair.value; if (values && typeof values == 'object') { if (Object.isArray(values)) return values.map(toQueryPair.curry(key)).join('&'); } return toQueryPair(key, values); }).join('&'); }, inspect: function() { return '#'; }, toJSON: function() { return Object.toJSON(this.toObject()); }, clone: function() { return new Hash(this); } } })()); Hash.prototype.toTemplateReplacements = Hash.prototype.toObject; Hash.from = $H; var ObjectRange = Class.create(Enumerable, { initialize: function(start, end, exclusive) { this.start = start; this.end = end; this.exclusive = exclusive; }, _each: function(iterator) { var value = this.start; while (this.include(value)) { iterator(value); value = value.succ(); } }, include: function(value) { if (value < this.start) return false; if (this.exclusive) return value < this.end; return value <= this.end; } }); var $R = function(start, end, exclusive) { return new ObjectRange(start, end, exclusive); }; var Ajax = { getTransport: function() { return Try.these( function() {return new XMLHttpRequest()}, function() {return new ActiveXObject('Msxml2.XMLHTTP')}, function() {return new ActiveXObject('Microsoft.XMLHTTP')} ) || false; }, activeRequestCount: 0 }; Ajax.Responders = { responders: [], _each: function(iterator) { this.responders._each(iterator); }, register: function(responder) { if (!this.include(responder)) this.responders.push(responder); }, unregister: function(responder) { this.responders = this.responders.without(responder); }, dispatch: function(callback, request, transport, json) { this.each(function(responder) { if (Object.isFunction(responder[callback])) { try { responder[callback].apply(responder, [request, transport, json]); } catch (e) { } } }); } }; Object.extend(Ajax.Responders, Enumerable); Ajax.Responders.register({ onCreate: function() { Ajax.activeRequestCount++ }, onComplete: function() { Ajax.activeRequestCount-- } }); Ajax.Base = Class.create({ initialize: function(options) { this.options = { method: 'post', asynchronous: true, contentType: 'application/x-www-form-urlencoded', encoding: 'UTF-8', parameters: '', evalJSON: true, evalJS: true }; Object.extend(this.options, options || { }); this.options.method = this.options.method.toLowerCase(); if (Object.isString(this.options.parameters)) this.options.parameters = this.options.parameters.toQueryParams(); } }); Ajax.Request = Class.create(Ajax.Base, { _complete: false, initialize: function($super, url, options) { $super(options); this.transport = Ajax.getTransport(); this.request(url); }, request: function(url) { this.url = url; this.method = this.options.method; var params = Object.clone(this.options.parameters); if (!['get', 'post'].include(this.method)) { // simulate other verbs over post params['_method'] = this.method; this.method = 'post'; } this.parameters = params; if (params = Object.toQueryString(params)) { // when GET, append parameters to URL if (this.method == 'get') this.url += (this.url.include('?') ? '&' : '?') + params; else if (/Konqueror|Safari|KHTML/.test(navigator.userAgent)) params += '&_='; } try { var response = new Ajax.Response(this); if (this.options.onCreate) this.options.onCreate(response); Ajax.Responders.dispatch('onCreate', this, response); this.transport.open(this.method.toUpperCase(), this.url, this.options.asynchronous); if (this.options.asynchronous) this.respondToReadyState.bind(this).defer(1); this.transport.onreadystatechange = this.onStateChange.bind(this); this.setRequestHeaders(); this.body = this.method == 'post' ? (this.options.postBody || params) : null; this.transport.send(this.body); /* Force Firefox to handle ready state 4 for synchronous requests */ if (!this.options.asynchronous && this.transport.overrideMimeType) this.onStateChange(); } catch (e) { this.dispatchException(e); } }, onStateChange: function() { var readyState = this.transport.readyState; if (readyState > 1 && !((readyState == 4) && this._complete)) this.respondToReadyState(this.transport.readyState); }, setRequestHeaders: function() { var headers = { 'X-Requested-With': 'XMLHttpRequest', 'X-Prototype-Version': Prototype.Version, 'Accept': 'text/javascript, text/html, application/xml, text/xml, */*' }; if (this.method == 'post') { headers['Content-type'] = this.options.contentType + (this.options.encoding ? '; charset=' + this.options.encoding : ''); /* Force "Connection: close" for older Mozilla browsers to work * around a bug where XMLHttpRequest sends an incorrect * Content-length header. See Mozilla Bugzilla #246651. */ if (this.transport.overrideMimeType && (navigator.userAgent.match(/Gecko\/(\d{4})/) || [0,2005])[1] < 2005) headers['Connection'] = 'close'; } // user-defined headers if (typeof this.options.requestHeaders == 'object') { var extras = this.options.requestHeaders; if (Object.isFunction(extras.push)) for (var i = 0, length = extras.length; i < length; i += 2) headers[extras[i]] = extras[i+1]; else $H(extras).each(function(pair) { headers[pair.key] = pair.value }); } for (var name in headers) this.transport.setRequestHeader(name, headers[name]); }, success: function() { var status = this.getStatus(); return !status || (status >= 200 && status < 300); }, getStatus: function() { try { return this.transport.status || 0; } catch (e) { return 0 } }, respondToReadyState: function(readyState) { var state = Ajax.Request.Events[readyState], response = new Ajax.Response(this); if (state == 'Complete') { try { this._complete = true; (this.options['on' + response.status] || this.options['on' + (this.success() ? 'Success' : 'Failure')] || Prototype.emptyFunction)(response, response.headerJSON); } catch (e) { this.dispatchException(e); } var contentType = response.getHeader('Content-type'); if (this.options.evalJS == 'force' || (this.options.evalJS && contentType && contentType.match(/^\s*(text|application)\/(x-)?(java|ecma)script(;.*)?\s*$/i))) this.evalResponse(); } try { (this.options['on' + state] || Prototype.emptyFunction)(response, response.headerJSON); Ajax.Responders.dispatch('on' + state, this, response, response.headerJSON); } catch (e) { this.dispatchException(e); } if (state == 'Complete') { // avoid memory leak in MSIE: clean up this.transport.onreadystatechange = Prototype.emptyFunction; } }, getHeader: function(name) { try { return this.transport.getResponseHeader(name); } catch (e) { return null } }, evalResponse: function() { try { return eval((this.transport.responseText || '').unfilterJSON()); } catch (e) { this.dispatchException(e); } }, dispatchException: function(exception) { (this.options.onException || Prototype.emptyFunction)(this, exception); Ajax.Responders.dispatch('onException', this, exception); } }); Ajax.Request.Events = ['Uninitialized', 'Loading', 'Loaded', 'Interactive', 'Complete']; Ajax.Response = Class.create({ initialize: function(request){ this.request = request; var transport = this.transport = request.transport, readyState = this.readyState = transport.readyState; if((readyState > 2 && !Prototype.Browser.IE) || readyState == 4) { this.status = this.getStatus(); this.statusText = this.getStatusText(); this.responseText = String.interpret(transport.responseText); this.headerJSON = this._getHeaderJSON(); } if(readyState == 4) { var xml = transport.responseXML; this.responseXML = xml === undefined ? null : xml; this.responseJSON = this._getResponseJSON(); } }, status: 0, statusText: '', getStatus: Ajax.Request.prototype.getStatus, getStatusText: function() { try { return this.transport.statusText || ''; } catch (e) { return '' } }, getHeader: Ajax.Request.prototype.getHeader, getAllHeaders: function() { try { return this.getAllResponseHeaders(); } catch (e) { return null } }, getResponseHeader: function(name) { return this.transport.getResponseHeader(name); }, getAllResponseHeaders: function() { return this.transport.getAllResponseHeaders(); }, _getHeaderJSON: function() { var json = this.getHeader('X-JSON'); if (!json) return null; json = decodeURIComponent(escape(json)); try { return json.evalJSON(this.request.options.sanitizeJSON); } catch (e) { this.request.dispatchException(e); } }, _getResponseJSON: function() { var options = this.request.options; if (!options.evalJSON || (options.evalJSON != 'force' && !(this.getHeader('Content-type') || '').include('application/json'))) return null; try { return this.transport.responseText.evalJSON(options.sanitizeJSON); } catch (e) { this.request.dispatchException(e); } } }); Ajax.Updater = Class.create(Ajax.Request, { initialize: function($super, container, url, options) { this.container = { success: (container.success || container), failure: (container.failure || (container.success ? null : container)) }; options = options || { }; var onComplete = options.onComplete; options.onComplete = (function(response, param) { this.updateContent(response.responseText); if (Object.isFunction(onComplete)) onComplete(response, param); }).bind(this); $super(url, options); }, updateContent: function(responseText) { var receiver = this.container[this.success() ? 'success' : 'failure'], options = this.options; if (!options.evalScripts) responseText = responseText.stripScripts(); if (receiver = $(receiver)) { if (options.insertion) { if (Object.isString(options.insertion)) { var insertion = { }; insertion[options.insertion] = responseText; receiver.insert(insertion); } else options.insertion(receiver, responseText); } else receiver.update(responseText); } if (this.success()) { if (this.onComplete) this.onComplete.bind(this).defer(); } } }); Ajax.PeriodicalUpdater = Class.create(Ajax.Base, { initialize: function($super, container, url, options) { $super(options); this.onComplete = this.options.onComplete; this.frequency = (this.options.frequency || 2); this.decay = (this.options.decay || 1); this.updater = { }; this.container = container; this.url = url; this.start(); }, start: function() { this.options.onComplete = this.updateComplete.bind(this); this.onTimerEvent(); }, stop: function() { this.updater.options.onComplete = undefined; clearTimeout(this.timer); (this.onComplete || Prototype.emptyFunction).apply(this, arguments); }, updateComplete: function(response) { if (this.options.decay) { this.decay = (response.responseText == this.lastText ? this.decay * this.options.decay : 1); this.lastText = response.responseText; } this.timer = this.onTimerEvent.bind(this).delay(this.decay * this.frequency); }, onTimerEvent: function() { this.updater = new Ajax.Updater(this.container, this.url, this.options); } }); function $(element) { if (arguments.length > 1) { for (var i = 0, elements = [], length = arguments.length; i < length; i++) elements.push($(arguments[i])); return elements; } if (Object.isString(element)) element = document.getElementById(element); return Element.extend(element); } if (Prototype.BrowserFeatures.XPath) { document._getElementsByXPath = function(expression, parentElement) { var results = []; var query = document.evaluate(expression, $(parentElement) || document, null, XPathResult.ORDERED_NODE_SNAPSHOT_TYPE, null); for (var i = 0, length = query.snapshotLength; i < length; i++) results.push(Element.extend(query.snapshotItem(i))); return results; }; } /*--------------------------------------------------------------------------*/ if (!window.Node) var Node = { }; if (!Node.ELEMENT_NODE) { // DOM level 2 ECMAScript Language Binding Object.extend(Node, { ELEMENT_NODE: 1, ATTRIBUTE_NODE: 2, TEXT_NODE: 3, CDATA_SECTION_NODE: 4, ENTITY_REFERENCE_NODE: 5, ENTITY_NODE: 6, PROCESSING_INSTRUCTION_NODE: 7, COMMENT_NODE: 8, DOCUMENT_NODE: 9, DOCUMENT_TYPE_NODE: 10, DOCUMENT_FRAGMENT_NODE: 11, NOTATION_NODE: 12 }); } (function() { var element = this.Element; this.Element = function(tagName, attributes) { attributes = attributes || { }; tagName = tagName.toLowerCase(); var cache = Element.cache; if (Prototype.Browser.IE && attributes.name) { tagName = '<' + tagName + ' name="' + attributes.name + '">'; delete attributes.name; return Element.writeAttribute(document.createElement(tagName), attributes); } if (!cache[tagName]) cache[tagName] = Element.extend(document.createElement(tagName)); return Element.writeAttribute(cache[tagName].cloneNode(false), attributes); }; Object.extend(this.Element, element || { }); }).call(window); Element.cache = { }; Element.Methods = { visible: function(element) { return $(element).style.display != 'none'; }, toggle: function(element) { element = $(element); Element[Element.visible(element) ? 'hide' : 'show'](element); return element; }, hide: function(element) { $(element).style.display = 'none'; return element; }, show: function(element) { $(element).style.display = ''; return element; }, remove: function(element) { element = $(element); element.parentNode.removeChild(element); return element; }, update: function(element, content) { element = $(element); if (content && content.toElement) content = content.toElement(); if (Object.isElement(content)) return element.update().insert(content); content = Object.toHTML(content); element.innerHTML = content.stripScripts(); content.evalScripts.bind(content).defer(); return element; }, replace: function(element, c