diff options
Diffstat (limited to 'includes/js/dojox/data/XmlStore.js')
-rw-r--r-- | includes/js/dojox/data/XmlStore.js | 1141 |
1 files changed, 0 insertions, 1141 deletions
diff --git a/includes/js/dojox/data/XmlStore.js b/includes/js/dojox/data/XmlStore.js deleted file mode 100644 index 90b26a9..0000000 --- a/includes/js/dojox/data/XmlStore.js +++ /dev/null @@ -1,1141 +0,0 @@ -if(!dojo._hasResource["dojox.data.XmlStore"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code. -dojo._hasResource["dojox.data.XmlStore"] = true; -dojo.provide("dojox.data.XmlStore"); -dojo.provide("dojox.data.XmlItem"); - -dojo.require("dojo.data.util.simpleFetch"); -dojo.require("dojo.data.util.filter"); -dojo.require("dojox.data.dom"); - -dojo.declare("dojox.data.XmlStore", null, { - // summary: - // A data store for XML based services or documents - // description: - // A data store for XML based services or documents - - constructor: function(/* object */ args) { - // summary: - // Constructor for the XML store. - // args: - // An anonymous object to initialize properties. It expects the following values: - // url: The url to a service or an XML document that represents the store - // rootItem: A tag name for root items - // keyAttribute: An attribute name for a key or an indentify - // attributeMap: An anonymous object contains properties for attribute mapping, - // {"tag_name.item_attribute_name": "@xml_attribute_name", ...} - // sendQuery: A boolean indicate to add a query string to the service URL - console.log("XmlStore()"); - if(args){ - this.url = args.url; - this.rootItem = (args.rootItem || args.rootitem || this.rootItem); - this.keyAttribute = (args.keyAttribute || args.keyattribute || this.keyAttribute); - this._attributeMap = (args.attributeMap || args.attributemap); - this.label = args.label || this.label; - this.sendQuery = (args.sendQuery || args.sendquery || this.sendQuery); - } - this._newItems = []; - this._deletedItems = []; - this._modifiedItems = []; - }, - - //Values that may be set by the parser. - //Ergo, have to be instantiated to something - //So the parser knows how to set them. - url: "", - - rootItem: "", - - keyAttribute: "", - - label: "", - - sendQuery: false, - -/* dojo.data.api.Read */ - - getValue: function(/* item */ item, /* attribute || attribute-name-string */ attribute, /* value? */ defaultValue){ - // summary: - // Return an attribute value - // description: - // 'item' must be an instance of a dojox.data.XmlItem from the store instance. - // If 'attribute' specifies "tagName", the tag name of the element is - // returned. - // If 'attribute' specifies "childNodes", the first element child is - // returned. - // If 'attribute' specifies "text()", the value of the first text - // child is returned. - // For generic attributes, if '_attributeMap' is specified, - // an actual attribute name is looked up with the tag name of - // the element and 'attribute' (concatenated with '.'). - // Then, if 'attribute' starts with "@", the value of the XML - // attribute is returned. - // Otherwise, the first child element of the tag name specified with - // 'attribute' is returned. - // item: - // An XML element that holds the attribute - // attribute: - // A tag name of a child element, An XML attribute name or one of - // special names - // defaultValue: - // A default value - // returns: - // An attribute value found, otherwise 'defaultValue' - var element = item.element; - if(attribute === "tagName"){ - return element.nodeName; - }else if (attribute === "childNodes"){ - for (var i = 0; i < element.childNodes.length; i++) { - var node = element.childNodes[i]; - if (node.nodeType === 1 /*ELEMENT_NODE*/) { - return this._getItem(node); //object - } - } - return defaultValue; - }else if(attribute === "text()"){ - for(var i = 0; i < element.childNodes.length; i++){ - var node = element.childNodes[i]; - if(node.nodeType === 3 /*TEXT_NODE*/ || - node.nodeType === 4 /*CDATA_SECTION_NODE*/){ - return node.nodeValue; //string - } - } - return defaultValue; - }else{ - attribute = this._getAttribute(element.nodeName, attribute); - if(attribute.charAt(0) === '@'){ - var name = attribute.substring(1); - var value = element.getAttribute(name); - return (value !== undefined) ? value : defaultValue; //object - }else{ - for(var i = 0; i < element.childNodes.length; i++){ - var node = element.childNodes[i]; - if( node.nodeType === 1 /*ELEMENT_NODE*/ && - node.nodeName === attribute){ - return this._getItem(node); //object - } - } - return defaultValue; //object - } - } - }, - - getValues: function(/* item */ item, /* attribute || attribute-name-string */ attribute){ - // summary: - // Return an array of attribute values - // description: - // 'item' must be an instance of a dojox.data.XmlItem from the store instance. - // If 'attribute' specifies "tagName", the tag name of the element is - // returned. - // If 'attribute' specifies "childNodes", child elements are returned. - // If 'attribute' specifies "text()", the values of child text nodes - // are returned. - // For generic attributes, if '_attributeMap' is specified, - // an actual attribute name is looked up with the tag name of - // the element and 'attribute' (concatenated with '.'). - // Then, if 'attribute' starts with "@", the value of the XML - // attribute is returned. - // Otherwise, child elements of the tag name specified with - // 'attribute' are returned. - // item: - // An XML element that holds the attribute - // attribute: - // A tag name of child elements, An XML attribute name or one of - // special names - // returns: - // An array of attribute values found, otherwise an empty array - var element = item.element; - if(attribute === "tagName"){ - return [element.nodeName]; - }else if(attribute === "childNodes"){ - var values = []; - for(var i = 0; i < element.childNodes.length; i++){ - var node = element.childNodes[i]; - if(node.nodeType === 1 /*ELEMENT_NODE*/){ - values.push(this._getItem(node)); - } - } - return values; //array - }else if(attribute === "text()"){ - var values = []; - for(var i = 0; i < element.childNodes.length; i++){ - var node = childNodes[i]; - if(node.nodeType === 3){ - values.push(node.nodeValue); - } - } - return values; //array - }else{ - attribute = this._getAttribute(element.nodeName, attribute); - if(attribute.charAt(0) === '@'){ - var name = attribute.substring(1); - var value = element.getAttribute(name); - return (value !== undefined) ? [value] : []; //array - }else{ - var values = []; - for(var i = 0; i < element.childNodes.length; i++){ - var node = element.childNodes[i]; - if( node.nodeType === 1 /*ELEMENT_NODE*/ && - node.nodeName === attribute){ - values.push(this._getItem(node)); - } - } - return values; //array - } - } - }, - - getAttributes: function(/* item */ item) { - // summary: - // Return an array of attribute names - // description: - // 'item' must be an instance of a dojox.data.XmlItem from the store instance. - // tag names of child elements and XML attribute names of attributes - // specified to the element are returned along with special attribute - // names applicable to the element including "tagName", "childNodes" - // if the element has child elements, "text()" if the element has - // child text nodes, and attribute names in '_attributeMap' that match - // the tag name of the element. - // item: - // An XML element - // returns: - // An array of attributes found - var element = item.element; - var attributes = []; - attributes.push("tagName"); - if(element.childNodes.length > 0){ - var names = {}; - var childNodes = true; - var text = false; - for(var i = 0; i < element.childNodes.length; i++){ - var node = element.childNodes[i]; - if (node.nodeType === 1 /*ELEMENT_NODE*/) { - var name = node.nodeName; - if(!names[name]){ - attributes.push(name); - names[name] = name; - } - childNodes = true; - }else if(node.nodeType === 3){ - text = true; - } - } - if(childNodes){ - attributes.push("childNodes"); - } - if(text){ - attributes.push("text()"); - } - } - for(var i = 0; i < element.attributes.length; i++){ - attributes.push("@" + element.attributes[i].nodeName); - } - if(this._attributeMap){ - for (var key in this._attributeMap){ - var i = key.indexOf('.'); - if(i > 0){ - var tagName = key.substring(0, i); - if (tagName === element.nodeName){ - attributes.push(key.substring(i + 1)); - } - }else{ // global attribute - attributes.push(key); - } - } - } - return attributes; //array - }, - - hasAttribute: function(/* item */ item, /* attribute || attribute-name-string */ attribute){ - // summary: - // Check whether an element has the attribute - // item: - // 'item' must be an instance of a dojox.data.XmlItem from the store instance. - // attribute: - // A tag name of a child element, An XML attribute name or one of - // special names - // returns: - // True if the element has the attribute, otherwise false - return (this.getValue(item, attribute) !== undefined); //boolean - }, - - containsValue: function(/* item */ item, /* attribute || attribute-name-string */ attribute, /* anything */ value){ - // summary: - // Check whether the attribute values contain the value - // item: - // 'item' must be an instance of a dojox.data.XmlItem from the store instance. - // attribute: - // A tag name of a child element, An XML attribute name or one of - // special names - // returns: - // True if the attribute values contain the value, otherwise false - var values = this.getValues(item, attribute); - for(var i = 0; i < values.length; i++){ - if((typeof value === "string")){ - if(values[i].toString && values[i].toString() === value){ - return true; - } - }else if (values[i] === value){ - return true; //boolean - } - } - return false;//boolean - }, - - isItem: function(/* anything */ something){ - // summary: - // Check whether the object is an item (XML element) - // item: - // An object to check - // returns: - // True if the object is an XML element, otherwise false - if(something && something.element && something.store && something.store === this){ - return true; //boolean - } - return false; //boolran - }, - - isItemLoaded: function(/* anything */ something){ - // summary: - // Check whether the object is an item (XML element) and loaded - // item: - // An object to check - // returns: - // True if the object is an XML element, otherwise false - return this.isItem(something); //boolean - }, - - loadItem: function(/* object */ keywordArgs){ - // summary: - // Load an item (XML element) - // keywordArgs: - // object containing the args for loadItem. See dojo.data.api.Read.loadItem() - }, - - getFeatures: function() { - // summary: - // Return supported data APIs - // returns: - // "dojo.data.api.Read" and "dojo.data.api.Write" - var features = { - "dojo.data.api.Read": true, - "dojo.data.api.Write": true - }; - return features; //array - }, - - getLabel: function(/* item */ item){ - // summary: - // See dojo.data.api.Read.getLabel() - if((this.label !== "") && this.isItem(item)){ - var label = this.getValue(item,this.label); - if(label){ - return label.toString(); - } - } - return undefined; //undefined - }, - - getLabelAttributes: function(/* item */ item){ - // summary: - // See dojo.data.api.Read.getLabelAttributes() - if(this.label !== ""){ - return [this.label]; //array - } - return null; //null - }, - - _fetchItems: function(request, fetchHandler, errorHandler) { - // summary: - // Fetch items (XML elements) that match to a query - // description: - // If 'sendQuery' is true, an XML document is loaded from - // 'url' with a query string. - // Otherwise, an XML document is loaded and list XML elements that - // match to a query (set of element names and their text attribute - // values that the items to contain). - // A wildcard, "*" can be used to query values to match all - // occurrences. - // If 'rootItem' is specified, it is used to fetch items. - // request: - // A request object - // fetchHandler: - // A function to call for fetched items - // errorHandler: - // A function to call on error - var url = this._getFetchUrl(request); - console.log("XmlStore._fetchItems(): url=" + url); - if(!url){ - errorHandler(new Error("No URL specified.")); - return; - } - var localRequest = (!this.sendQuery ? request : null); // use request for _getItems() - - var self = this; - var getArgs = { - url: url, - handleAs: "xml", - preventCache: true - }; - var getHandler = dojo.xhrGet(getArgs); - getHandler.addCallback(function(data){ - var items = self._getItems(data, localRequest); - console.log("XmlStore._fetchItems(): length=" + (items ? items.length : 0)); - if (items && items.length > 0) { - fetchHandler(items, request); - } - else { - fetchHandler([], request); - } - }); - getHandler.addErrback(function(data){ - errorHandler(data, request); - }); - }, - - _getFetchUrl: function(request){ - // summary: - // Generate a URL for fetch - // description: - // This default implementation generates a query string in the form of - // "?name1=value1&name2=value2..." off properties of 'query' object - // specified in 'request' and appends it to 'url', if 'sendQuery' - // is set to false. - // Otherwise, 'url' is returned as is. - // Sub-classes may override this method for the custom URL generation. - // request: - // A request object - // returns: - // A fetch URL - if(!this.sendQuery){ - return this.url; - } - var query = request.query; - if(!query){ - return this.url; - } - if(dojo.isString(query)){ - return this.url + query; - } - var queryString = ""; - for(var name in query){ - var value = query[name]; - if(value){ - if(queryString){ - queryString += "&"; - } - queryString += (name + "=" + value); - } - } - if(!queryString){ - return this.url; - } - //Check to see if the URL already has query params or not. - var fullUrl = this.url; - if(fullUrl.indexOf("?") < 0){ - fullUrl += "?"; - }else{ - fullUrl += "&"; - } - return fullUrl + queryString; - }, - - _getItems: function(document, request) { - // summary: - // Fetch items (XML elements) in an XML document based on a request - // description: - // This default implementation walks through child elements of - // the document element to see if all properties of 'query' object - // match corresponding attributes of the element (item). - // If 'request' is not specified, all child elements are returned. - // Sub-classes may override this method for the custom search in - // an XML document. - // document: - // An XML document - // request: - // A request object - // returns: - // An array of items - var query = null; - if(request){ - query = request.query; - } - var items = []; - var nodes = null; - - console.log("Looking up root item: " + this.rootItem); - if(this.rootItem !== ""){ - - nodes = document.getElementsByTagName(this.rootItem); - } - else{ - nodes = document.documentElement.childNodes; - } - for(var i = 0; i < nodes.length; i++){ - var node = nodes[i]; - if(node.nodeType != 1 /*ELEMENT_NODE*/){ - continue; - } - var item = this._getItem(node); - if(query){ - var found = true; - var ignoreCase = request.queryOptions ? request.queryOptions.ignoreCase : false; - - //See if there are any string values that can be regexp parsed first to avoid multiple regexp gens on the - //same value for each item examined. Much more efficient. - var regexpList = {}; - for(var key in query){ - var value = query[key]; - if(typeof value === "string"){ - regexpList[key] = dojo.data.util.filter.patternToRegExp(value, ignoreCase); - } - } - - for(var attribute in query){ - var value = this.getValue(item, attribute); - if(value){ - var queryValue = query[attribute]; - if ((typeof value) === "string" && - (regexpList[attribute])){ - if((value.match(regexpList[attribute])) !== null){ - continue; - } - }else if((typeof value) === "object"){ - if( value.toString && - (regexpList[attribute])){ - var stringValue = value.toString(); - if((stringValue.match(regexpList[attribute])) !== null){ - continue; - } - }else{ - if(queryValue === "*" || queryValue === value){ - continue; - } - } - } - } - found = false; - break; - } - if(!found){ - continue; - } - } - items.push(item); - } - dojo.forEach(items,function(item){ - item.element.parentNode.removeChild(item.element); // make it root - },this); - return items; - }, - - close: function(/*dojo.data.api.Request || keywordArgs || null */ request){ - // summary: - // See dojo.data.api.Read.close() - }, - -/* dojo.data.api.Write */ - - newItem: function(/* object? */ keywordArgs){ - // summary: - // Return a new dojox.data.XmlItem - // description: - // At least, 'keywordArgs' must contain "tagName" to be used for - // the new element. - // Other attributes in 'keywordArgs' are set to the new element, - // including "text()", but excluding "childNodes". - // keywordArgs: - // An object containing initial attributes - // returns: - // An XML element - console.log("XmlStore.newItem()"); - keywordArgs = (keywordArgs || {}); - var tagName = keywordArgs.tagName; - if(!tagName){ - tagName = this.rootItem; - if(tagName === ""){ - return null; - } - } - - var document = this._getDocument(); - var element = document.createElement(tagName); - for(var attribute in keywordArgs){ - if(attribute === "tagName"){ - continue; - }else if(attribute === "text()"){ - var text = document.createTextNode(keywordArgs[attribute]); - element.appendChild(text); - }else{ - attribute = this._getAttribute(tagName, attribute); - if(attribute.charAt(0) === '@'){ - var name = attribute.substring(1); - element.setAttribute(name, keywordArgs[attribute]); - }else{ - var child = document.createElement(attribute); - var text = document.createTextNode(keywordArgs[attribute]); - child.appendChild(text); - element.appendChild(child); - } - } - } - - var item = this._getItem(element); - this._newItems.push(item); - return item; //object - }, - - deleteItem: function(/* item */ item){ - // summary: - // Delete an dojox.data.XmlItem (wrapper to a XML element). - // item: - // An XML element to delete - // returns: - // True - console.log("XmlStore.deleteItem()"); - var element = item.element; - if(element.parentNode){ - this._backupItem(item); - element.parentNode.removeChild(element); - return true; - } - this._forgetItem(item); - this._deletedItems.push(item); - return true; //boolean - }, - - setValue: function(/* item */ item, /* attribute || string */ attribute, /* almost anything */ value){ - // summary: - // Set an attribute value - // description: - // 'item' must be an instance of a dojox.data.XmlItem from the store instance. - // If 'attribute' specifies "tagName", nothing is set and false is - // returned. - // If 'attribute' specifies "childNodes", the value (XML element) is - // added to the element. - // If 'attribute' specifies "text()", a text node is created with - // the value and set it to the element as a child. - // For generic attributes, if '_attributeMap' is specified, - // an actual attribute name is looked up with the tag name of - // the element and 'attribute' (concatenated with '.'). - // Then, if 'attribute' starts with "@", the value is set to the XML - // attribute. - // Otherwise, a text node is created with the value and set it to - // the first child element of the tag name specified with 'attribute'. - // If the child element does not exist, it is created. - // item: - // An XML element that holds the attribute - // attribute: - // A tag name of a child element, An XML attribute name or one of - // special names - // value: - // A attribute value to set - // returns: - // False for "tagName", otherwise true - if(attribute === "tagName"){ - return false; //boolean - } - - this._backupItem(item); - - var element = item.element; - if(attribute === "childNodes"){ - var child = value.element; - element.appendChild(child); - }else if(attribute === "text()"){ - while (element.firstChild){ - element.removeChild(element.firstChild); - } - var text = this._getDocument(element).createTextNode(value); - element.appendChild(text); - }else{ - attribute = this._getAttribute(element.nodeName, attribute); - if(attribute.charAt(0) === '@'){ - var name = attribute.substring(1); - element.setAttribute(name, value); - }else{ - var child = null; - for(var i = 0; i < element.childNodes.length; i++){ - var node = element.childNodes[i]; - if( node.nodeType === 1 /*ELEMENT_NODE*/&& - node.nodeName === attribute){ - child = node; - break; - } - } - var document = this._getDocument(element); - if(child){ - while(child.firstChild){ - child.removeChild(child.firstChild); - } - }else{ - child = document.createElement(attribute); - element.appendChild(child); - } - var text = document.createTextNode(value); - child.appendChild(text); - } - } - return true; //boolean - }, - - setValues: function(/* item */ item, /* attribute || string */ attribute, /* array */ values){ - // summary: - // Set attribute values - // description: - // 'item' must be an instance of a dojox.data.XmlItem from the store instance. - // If 'attribute' specifies "tagName", nothing is set and false is - // returned. - // If 'attribute' specifies "childNodes", the value (array of XML - // elements) is set to the element's childNodes. - // If 'attribute' specifies "text()", a text node is created with - // the values and set it to the element as a child. - // For generic attributes, if '_attributeMap' is specified, - // an actual attribute name is looked up with the tag name of - // the element and 'attribute' (concatenated with '.'). - // Then, if 'attribute' starts with "@", the first value is set to - // the XML attribute. - // Otherwise, child elements of the tag name specified with - // 'attribute' are replaced with new child elements and their - // child text nodes of values. - // item: - // An XML element that holds the attribute - // attribute: - // A tag name of child elements, an XML attribute name or one of - // special names - // value: - // A attribute value to set - // returns: - // False for "tagName", otherwise true - if(attribute === "tagName"){ - return false; //boolean - } - - this._backupItem(item); - - var element = item.element; - if(attribute === "childNodes"){ - while(element.firstChild){ - element.removeChild(element.firstChild); - } - for(var i = 0; i < values.length; i++){ - var child = values[i].element; - element.appendChild(child); - } - }else if(attribute === "text()"){ - while (element.firstChild){ - element.removeChild(element.firstChild); - } - var value = ""; - for(var i = 0; i < values.length; i++){ - value += values[i]; - } - var text = this._getDocument(element).createTextNode(value); - element.appendChild(text); - }else{ - attribute = this._getAttribute(element.nodeName, attribute); - if(attribute.charAt(0) === '@'){ - var name = attribute.substring(1); - element.setAttribute(name, values[0]); - }else{ - for(var i = element.childNodes.length - 1; i >= 0; i--){ - var node = element.childNodes[i]; - if( node.nodeType === 1 /*ELEMENT_NODE*/ && - node.nodeName === attribute){ - element.removeChild(node); - } - } - var document = this._getDocument(element); - for(var i = 0; i < values.length; i++){ - var child = document.createElement(attribute); - var text = document.createTextNode(values[i]); - child.appendChild(text); - element.appendChild(child); - } - } - } - return true; //boolean - }, - - unsetAttribute: function(/* item */ item, /* attribute || string */ attribute){ - // summary: - // Remove an attribute - // description: - // 'item' must be an instance of a dojox.data.XmlItem from the store instance. - // 'attribute' can be an XML attribute name of the element or one of - // special names described below. - // If 'attribute' specifies "tagName", nothing is removed and false is - // returned. - // If 'attribute' specifies "childNodes" or "text()", all child nodes - // are removed. - // For generic attributes, if '_attributeMap' is specified, - // an actual attribute name is looked up with the tag name of - // the element and 'attribute' (concatenated with '.'). - // Then, if 'attribute' starts with "@", the XML attribute is removed. - // Otherwise, child elements of the tag name specified with - // 'attribute' are removed. - // item: - // An XML element that holds the attribute - // attribute: - // A tag name of child elements, an XML attribute name or one of - // special names - // returns: - // False for "tagName", otherwise true - if(attribute === "tagName"){ - return false; //boolean - } - - this._backupItem(item); - - var element = item.element; - if(attribute === "childNodes" || attribute === "text()"){ - while(element.firstChild){ - element.removeChild(element.firstChild); - } - }else{ - attribute = this._getAttribute(element.nodeName, attribute); - if(attribute.charAt(0) === '@'){ - var name = attribute.substring(1); - element.removeAttribute(name); - }else{ - for(var i = element.childNodes.length - 1; i >= 0; i--){ - var node = element.childNodes[i]; - if( node.nodeType === 1 /*ELEMENT_NODE*/ && - node.nodeName === attribute){ - element.removeChild(node); - } - } - } - } - return true; //boolean - }, - - save: function(/* object */ keywordArgs){ - // summary: - // Save new and/or modified items (XML elements) - // description: - // 'url' is used to save XML documents for new, modified and/or - // deleted XML elements. - // keywordArgs: - // An object for callbacks - if(!keywordArgs){ - keywordArgs = {}; - } - for(var i = 0; i < this._modifiedItems.length; i++){ - this._saveItem(this._modifiedItems[i], keywordArgs, "PUT"); - } - for(var i = 0; i < this._newItems.length; i++){ - var item = this._newItems[i]; - if(item.element.parentNode){ // reparented - this._newItems.splice(i, 1); - i--; - continue; - } - this._saveItem(this._newItems[i], keywordArgs, "POST"); - } - for(var i = 0; i < this._deletedItems.length; i++){ - this._saveItem(this._deletedItems[i], keywordArgs, "DELETE"); - } - }, - - revert: function(){ - // summary: - // Invalidate changes (new and/or modified elements) - // returns: - // True - console.log("XmlStore.revert() _newItems=" + this._newItems.length); - console.log("XmlStore.revert() _deletedItems=" + this._deletedItems.length); - console.log("XmlStore.revert() _modifiedItems=" + this._modifiedItems.length); - this._newItems = []; - this._restoreItems(this._deletedItems); - this._deletedItems = []; - this._restoreItems(this._modifiedItems); - this._modifiedItems = []; - return true; //boolean - }, - - isDirty: function(/* item? */ item){ - // summary: - // Check whether an item is new, modified or deleted - // description: - // If 'item' is specified, true is returned if the item is new, - // modified or deleted. - // Otherwise, true is returned if there are any new, modified - // or deleted items. - // item: - // An item (XML element) to check - // returns: - // True if an item or items are new, modified or deleted, otherwise - // false - if (item) { - var element = this._getRootElement(item.element); - return (this._getItemIndex(this._newItems, element) >= 0 || - this._getItemIndex(this._deletedItems, element) >= 0 || - this._getItemIndex(this._modifiedItems, element) >= 0); //boolean - } - else { - return (this._newItems.length > 0 || - this._deletedItems.length > 0 || - this._modifiedItems.length > 0); //boolean - } - }, - - _saveItem: function(item, keywordArgs, method){ - if(method === "PUT"){ - url = this._getPutUrl(item); - }else if(method === "DELETE"){ - url = this._getDeleteUrl(item); - }else{ // POST - url = this._getPostUrl(item); - } - if(!url){ - if(keywordArgs.onError){ - keywordArgs.onError.call(scope, new Error("No URL for saving content: " + postContent)); - } - return; - } - - var saveArgs = { - url: url, - method: (method || "POST"), - contentType: "text/xml", - handleAs: "xml" - }; - var saveHander; - if(method === "PUT"){ - saveArgs.putData = this._getPutContent(item); - saveHandler = dojo.rawXhrPut(saveArgs); - }else if(method === "DELETE"){ - saveHandler = dojo.xhrDelete(saveArgs); - }else{ // POST - saveArgs.postData = this._getPostContent(item); - saveHandler = dojo.rawXhrPost(saveArgs); - } - var scope = (keywordArgs.scope || dojo.global); - var self = this; - saveHandler.addCallback(function(data){ - self._forgetItem(item); - if(keywordArgs.onComplete){ - keywordArgs.onComplete.call(scope); - } - }); - saveHandler.addErrback(function(error){ - if(keywordArgs.onError){ - keywordArgs.onError.call(scope, error); - } - }); - }, - - _getPostUrl: function(item){ - // summary: - // Generate a URL for post - // description: - // This default implementation just returns 'url'. - // Sub-classes may override this method for the custom URL. - // item: - // An item to save - // returns: - // A post URL - return this.url; //string - }, - - _getPutUrl: function(item){ - // summary: - // Generate a URL for put - // description: - // This default implementation just returns 'url'. - // Sub-classes may override this method for the custom URL. - // item: - // An item to save - // returns: - // A put URL - return this.url; //string - }, - - _getDeleteUrl: function(item){ - // summary: - // Generate a URL for delete - // description: - // This default implementation returns 'url' with 'keyAttribute' - // as a query string. - // Sub-classes may override this method for the custom URL based on - // changes (new, deleted, or modified). - // item: - // An item to delete - // returns: - // A delete URL - var url = this.url; - if (item && this.keyAttribute !== "") { - var value = this.getValue(item, this.keyAttribute); - if (value) { - var key = this.keyAttribute.charAt(0) ==='@' ? this.keyAttribute.substring(1): this.keyAttribute; - url += url.indexOf('?') < 0 ? '?' : '&'; - url += key + '=' + value; - } - } - return url; //string - }, - - _getPostContent: function(item){ - // summary: - // Generate a content to post - // description: - // This default implementation generates an XML document for one - // (the first only) new or modified element. - // Sub-classes may override this method for the custom post content - // generation. - // item: - // An item to save - // returns: - // A post content - var element = item.element; - var declaration = "<?xml version=\"1.0\"?>"; // FIXME: encoding? - return declaration + dojox.data.dom.innerXML(element); //XML string - }, - - _getPutContent: function(item){ - // summary: - // Generate a content to put - // description: - // This default implementation generates an XML document for one - // (the first only) new or modified element. - // Sub-classes may override this method for the custom put content - // generation. - // item: - // An item to save - // returns: - // A post content - var element = item.element; - var declaration = "<?xml version=\"1.0\"?>"; // FIXME: encoding? - return declaration + dojox.data.dom.innerXML(element); //XML string - }, - -/* internal API */ - - _getAttribute: function(tagName, attribute){ - if(this._attributeMap){ - var key = tagName + "." + attribute; - var value = this._attributeMap[key]; - if(value){ - attribute = value; - }else{ // look for global attribute - value = this._attributeMap[attribute]; - if(value){ - attribute = value; - } - } - } - return attribute; //object - }, - - _getItem: function(element){ - return new dojox.data.XmlItem(element, this); //object - }, - - _getItemIndex: function(items, element){ - for(var i = 0; i < items.length; i++){ - if(items[i].element === element){ - return i; //int - } - } - return -1; //int - }, - - _backupItem: function(item){ - var element = this._getRootElement(item.element); - if( this._getItemIndex(this._newItems, element) >= 0 || - this._getItemIndex(this._modifiedItems, element) >= 0){ - return; // new or already modified - } - if(element != item.element){ - item = this._getItem(element); - } - item._backup = element.cloneNode(true); - this._modifiedItems.push(item); - }, - - _restoreItems: function(items){ - - dojo.forEach(items,function(item){ - if(item._backup){ - item.element = item._backup; - item._backup = null; - } - },this); - }, - - _forgetItem: function(item){ - var element = item.element; - var index = this._getItemIndex(this._newItems, element); - if(index >= 0){ - this._newItems.splice(index, 1); - } - index = this._getItemIndex(this._deletedItems, element); - if(index >= 0){ - this._deletedItems.splice(index, 1); - } - index = this._getItemIndex(this._modifiedItems, element); - if(index >= 0){ - this._modifiedItems.splice(index, 1); - } - }, - - _getDocument: function(element){ - if(element){ - return element.ownerDocument; //DOMDocument - }else if(!this._document){ - return dojox.data.dom.createDocument(); // DOMDocument - } - }, - - _getRootElement: function(element){ - while(element.parentNode){ - element = element.parentNode; - } - return element; //DOMElement - } - -}); - -//FIXME: Is a full class here really needed for containment of the item or would -//an anon object work fine? -dojo.declare("dojox.data.XmlItem", null, { - constructor: function(element, store) { - // summary: - // Initialize with an XML element - // element: - // An XML element - // store: - // The containing store, if any. - this.element = element; - this.store = store; - }, - // summary: - // A data item of 'XmlStore' - // description: - // This class represents an item of 'XmlStore' holding an XML element. - // 'element' - // element: - // An XML element - - toString: function() { - // summary: - // Return a value of the first text child of the element - // returns: - // a value of the first text child of the element - var str = ""; - if (this.element) { - for (var i = 0; i < this.element.childNodes.length; i++) { - var node = this.element.childNodes[i]; - if (node.nodeType === 3) { - str = node.nodeValue; - break; - } - } - } - return str; //String - } - -}); -dojo.extend(dojox.data.XmlStore,dojo.data.util.simpleFetch); - -} |