/* Copyright (c) 2004-2006, The Dojo Foundation All Rights Reserved. Licensed under the Academic Free License version 2.1 or above OR the modified BSD license. For more information on Dojo licensing, see: http://dojotoolkit.org/community/licensing.shtml */ dojo.provide("dojo.data.OpmlStore"); dojo.require("dojo.data.core.Read"); dojo.require("dojo.data.core.Result"); dojo.require("dojo.lang.assert"); dojo.require("dojo.json"); dojo.require("dojo.experimental"); dojo.experimental("dojo.data.OpmlStore"); // FIXME: The OpmlStore works in Firefox but does not yet work in IE. dojo.declare("dojo.data.OpmlStore", dojo.data.core.Read, { /* summary: * The OpmlStore implements the dojo.data.core.Read API. */ /* examples: * var opmlStore = new dojo.data.OpmlStore({url:"geography.opml"}); * var opmlStore = new dojo.data.OpmlStore({url:"http://example.com/geography.opml"}); */ initializer: function(/* object */ keywordParameters) { // keywordParameters: {url: String} this._arrayOfTopLevelItems = []; this._metadataNodes = null; this._loadFinished = false; this._opmlFileUrl = keywordParameters["url"]; }, _assertIsItem: function(/* item */ item) { if (!this.isItem(item)) { throw new Error("dojo.data.OpmlStore: a function was passed an item argument that was not an item"); } }, _removeChildNodesThatAreNotElementNodes: function(/* node */ node, /* boolean */ recursive) { var childNodes = node.childNodes; if (childNodes.length == 0) { return; } var nodesToRemove = []; var i, childNode; for (i = 0; i < childNodes.length; ++i) { childNode = childNodes[i]; if (childNode.nodeType != Node.ELEMENT_NODE) { nodesToRemove.push(childNode); } }; // dojo.debug('trim: ' + childNodes.length + ' total, ' + nodesToRemove.length + ' junk'); for (i = 0; i < nodesToRemove.length; ++i) { childNode = nodesToRemove[i]; node.removeChild(childNode); } // dojo.debug('trim: ' + childNodes.length + ' remaining'); if (recursive) { for (i = 0; i < childNodes.length; ++i) { childNode = childNodes[i]; this._removeChildNodesThatAreNotElementNodes(childNode, recursive); } } }, _processRawXmlTree: function(/* xmlDoc */ rawXmlTree) { var headNodes = rawXmlTree.getElementsByTagName('head'); var headNode = headNodes[0]; this._removeChildNodesThatAreNotElementNodes(headNode); this._metadataNodes = headNode.childNodes; var bodyNodes = rawXmlTree.getElementsByTagName('body'); var bodyNode = bodyNodes[0]; this._removeChildNodesThatAreNotElementNodes(bodyNode, true); var bodyChildNodes = bodyNodes[0].childNodes; for (var i = 0; i < bodyChildNodes.length; ++i) { var node = bodyChildNodes[i]; if (node.tagName == 'outline') { this._arrayOfTopLevelItems.push(node); } } }, get: function(/* item */ item, /* attribute || attribute-name-string */ attribute, /* value? */ defaultValue) { // summary: See dojo.data.core.Read.get() this._assertIsItem(item); if (attribute == 'children') { return (item.firstChild || defaultValue); } else { var value = item.getAttribute(attribute); value = (value != undefined) ? value : defaultValue; return value; } }, getValues: function(/* item */ item, /* attribute || attribute-name-string */ attribute) { // summary: See dojo.data.core.Read.getValues() this._assertIsItem(item); if (attribute == 'children') { var array = []; for (var i = 0; i < item.childNodes.length; ++i) { array.push(item.childNodes[i]); } return array; // Array // return item.childNodes; // FIXME: this isn't really an Array } else { return [item.getAttribute(attribute)]; // Array } }, getAttributes: function(/* item */ item) { // summary: See dojo.data.core.Read.getAttributes() this._assertIsItem(item); var attributes = []; var xmlNode = item; var xmlAttributes = xmlNode.attributes; for (var i = 0; i < xmlAttributes.length; ++i) { var xmlAttribute = xmlAttributes.item(i); attributes.push(xmlAttribute.nodeName); } if (xmlNode.childNodes.length > 0) { attributes.push('children'); } return attributes; // array }, hasAttribute: function(/* item */ item, /* attribute || attribute-name-string */ attribute) { // summary: See dojo.data.core.Read.hasAttribute() return (this.getValues(item, attribute).length > 0); }, containsValue: function(/* item */ item, /* attribute || attribute-name-string */ attribute, /* anything */ value) { // summary: See dojo.data.core.Read.containsValue() var values = this.getValues(item, attribute); for (var i = 0; i < values.length; ++i) { var possibleValue = values[i]; if (value == possibleValue) { return true; } } return false; // boolean }, isItem: function(/* anything */ something) { return (something && something.nodeType == Node.ELEMENT_NODE && something.tagName == 'outline'); // boolean }, isItemAvailable: function(/* anything */ something) { return this.isItem(something); }, find: function(/* object? || dojo.data.core.Result */ keywordArgs) { // summary: See dojo.data.core.Read.find() var result = null; if (keywordArgs instanceof dojo.data.core.Result) { result = keywordArgs; result.store = this; } else { result = new dojo.data.core.Result(keywordArgs, this); } var self = this; var bindHandler = function(type, data, evt) { var scope = result.scope || dj_global; if (type == "load") { self._processRawXmlTree(data); if (result.saveResult) { result.items = self._arrayOfTopLevelItems; } if (result.onbegin) { result.onbegin.call(scope, result); } for (var i=0; i < self._arrayOfTopLevelItems.length; i++) { var item = self._arrayOfTopLevelItems[i]; if (result.onnext && !result._aborted) { result.onnext.call(scope, item, result); } } if (result.oncompleted && !result._aborted) { result.oncompleted.call(scope, result); } } else if(type == "error" || type == 'timeout') { // todo: how to handle timeout? var errorObject = data; // dojo.debug("error in dojo.data.OpmlStore.find(): " + dojo.json.serialize(errorObject)); if (result.onerror) { result.onerror.call(scope, data); } } }; if (!this._loadFinished) { if (this._opmlFileUrl) { var bindRequest = dojo.io.bind({ url: this._opmlFileUrl, // "playlist.opml", handle: bindHandler, mimetype: "text/xml", sync: (result.sync || false) }); result._abortFunc = bindRequest.abort; } } return result; // dojo.data.csv.Result }, getIdentity: function(/* item */ item) { // summary: See dojo.data.core.Read.getIdentity() dojo.unimplemented('dojo.data.OpmlStore.getIdentity()'); return null; }, findByIdentity: function(/* string */ identity) { // summary: See dojo.data.core.Read.findByIdentity() dojo.unimplemented('dojo.data.OpmlStore.findByIdentity()'); return null; } });