1
0
mirror of https://git.tt-rss.org/git/tt-rss.git synced 2026-02-10 16:01:33 +00:00

upgrade Dojo to 1.6.1

This commit is contained in:
Andrew Dolgov
2011-11-08 20:40:44 +04:00
parent 870a70e109
commit 81bea17aef
680 changed files with 51915 additions and 74107 deletions
+98 -97
View File
@@ -1,5 +1,5 @@
/*
Copyright (c) 2004-2010, The Dojo Foundation All Rights Reserved.
Copyright (c) 2004-2011, The Dojo Foundation All Rights Reserved.
Available via Academic Free License >= 2.1 OR the modified BSD license.
see: http://dojotoolkit.org/license for details
*/
@@ -8,11 +8,11 @@
if(!dojo._hasResource["dojo.data.ItemFileReadStore"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
dojo._hasResource["dojo.data.ItemFileReadStore"] = true;
dojo.provide("dojo.data.ItemFileReadStore");
dojo.require("dojo.data.util.filter");
dojo.require("dojo.data.util.simpleFetch");
dojo.require("dojo.date.stamp");
dojo.declare("dojo.data.ItemFileReadStore", null,{
// summary:
// The ItemFileReadStore implements the dojo.data.api.Read API and reads
@@ -22,7 +22,7 @@ dojo.declare("dojo.data.ItemFileReadStore", null,{
// { name:'Fozzie Bear', wears:['hat', 'tie']},
// { name:'Miss Piggy', pets:'Foo-Foo'}
// ]}
// Note that it can also contain an 'identifer' property that specified which attribute on the items
// Note that it can also contain an 'identifer' property that specified which attribute on the items
// in the array of items that acts as the unique identifier for that item.
//
constructor: function(/* Object */ keywordParameters){
@@ -37,7 +37,7 @@ dojo.declare("dojo.data.ItemFileReadStore", null,{
// ...
// typeN: function || object
// }
// Where if it is a function, it is assumed to be an object constructor that takes the
// Where if it is a function, it is assumed to be an object constructor that takes the
// value of _value as the initialization parameters. If it is an object, then it is assumed
// to be an object of general form:
// {
@@ -103,7 +103,7 @@ dojo.declare("dojo.data.ItemFileReadStore", null,{
//all item handles will become invalid and a new fetch must be issued.
clearOnClose: false,
//Parameter to allow specifying if preventCache should be passed to the xhrGet call or not when loading data from a url.
//Parameter to allow specifying if preventCache should be passed to the xhrGet call or not when loading data from a url.
//Note this does not mean the store calls the server on each fetch, only that the data load has preventCache set as an option.
//Added for tracker: #6072
urlPreventCache: false,
@@ -111,19 +111,19 @@ dojo.declare("dojo.data.ItemFileReadStore", null,{
//Parameter for specifying that it is OK for the xhrGet call to fail silently.
failOk: false,
//Parameter to indicate to process data from the url as hierarchical
//(data items can contain other data items in js form). Default is true
//for backwards compatibility. False means only root items are processed
//as items, all child objects outside of type-mapped objects and those in
//Parameter to indicate to process data from the url as hierarchical
//(data items can contain other data items in js form). Default is true
//for backwards compatibility. False means only root items are processed
//as items, all child objects outside of type-mapped objects and those in
//specific reference format, are left straight JS data objects.
hierarchical: true,
_assertIsItem: function(/* item */ item){
// summary:
// This function tests whether the item passed in is indeed an item in the store.
// item:
// item:
// The item to test for being contained by the store.
if(!this.isItem(item)){
if(!this.isItem(item)){
throw new Error("dojo.data.ItemFileReadStore: Invalid item argument.");
}
},
@@ -131,25 +131,25 @@ dojo.declare("dojo.data.ItemFileReadStore", null,{
_assertIsAttribute: function(/* attribute-name-string */ attribute){
// summary:
// This function tests whether the item passed in is indeed a valid 'attribute' like type for the store.
// attribute:
// attribute:
// The attribute to test for being contained by the store.
if(typeof attribute !== "string"){
if(typeof attribute !== "string"){
throw new Error("dojo.data.ItemFileReadStore: Invalid attribute argument.");
}
},
getValue: function( /* item */ item,
/* attribute-name-string */ attribute,
getValue: function( /* item */ item,
/* attribute-name-string */ attribute,
/* value? */ defaultValue){
// summary:
// summary:
// See dojo.data.api.Read.getValue()
var values = this.getValues(item, attribute);
return (values.length > 0)?values[0]:defaultValue; // mixed
},
getValues: function(/* item */ item,
getValues: function(/* item */ item,
/* attribute-name-string */ attribute){
// summary:
// summary:
// See dojo.data.api.Read.getValues()
this._assertIsItem(item);
@@ -159,7 +159,7 @@ dojo.declare("dojo.data.ItemFileReadStore", null,{
},
getAttributes: function(/* item */ item){
// summary:
// summary:
// See dojo.data.api.Read.getAttributes()
this._assertIsItem(item);
var attributes = [];
@@ -174,17 +174,17 @@ dojo.declare("dojo.data.ItemFileReadStore", null,{
hasAttribute: function( /* item */ item,
/* attribute-name-string */ attribute){
// summary:
// summary:
// See dojo.data.api.Read.hasAttribute()
this._assertIsItem(item);
this._assertIsAttribute(attribute);
return (attribute in item);
},
containsValue: function(/* item */ item,
/* attribute-name-string */ attribute,
containsValue: function(/* item */ item,
/* attribute-name-string */ attribute,
/* anything */ value){
// summary:
// summary:
// See dojo.data.api.Read.containsValue()
var regexp = undefined;
if(typeof value === "string"){
@@ -193,22 +193,22 @@ dojo.declare("dojo.data.ItemFileReadStore", null,{
return this._containsValue(item, attribute, value, regexp); //boolean.
},
_containsValue: function( /* item */ item,
/* attribute-name-string */ attribute,
_containsValue: function( /* item */ item,
/* attribute-name-string */ attribute,
/* anything */ value,
/* RegExp?*/ regexp){
// summary:
// summary:
// Internal function for looking at the values contained by the item.
// description:
// Internal function for looking at the values contained by the item. This
// description:
// Internal function for looking at the values contained by the item. This
// function allows for denoting if the comparison should be case sensitive for
// strings or not (for handling filtering cases where string case should not matter)
//
//
// item:
// The data item to examine for attribute values.
// attribute:
// The attribute to inspect.
// value:
// value:
// The value to match.
// regexp:
// Optional regular expression generated off value if value was of string type to handle wildcarding.
@@ -225,7 +225,7 @@ dojo.declare("dojo.data.ItemFileReadStore", null,{
},
isItem: function(/* anything */ something){
// summary:
// summary:
// See dojo.data.api.Read.isItem()
if(something && something[this._storeRefPropName] === this){
if(this._arrayOfAllItems[something[this._itemNumPropName]] === something){
@@ -236,25 +236,25 @@ dojo.declare("dojo.data.ItemFileReadStore", null,{
},
isItemLoaded: function(/* anything */ something){
// summary:
// summary:
// See dojo.data.api.Read.isItemLoaded()
return this.isItem(something); //boolean
},
loadItem: function(/* object */ keywordArgs){
// summary:
// summary:
// See dojo.data.api.Read.loadItem()
this._assertIsItem(keywordArgs.item);
},
getFeatures: function(){
// summary:
// summary:
// See dojo.data.api.Read.getFeatures()
return this._features; //Object
},
getLabel: function(/* item */ item){
// summary:
// summary:
// See dojo.data.api.Read.getLabel()
if(this._labelAttr && this.isItem(item)){
return this.getValue(item,this._labelAttr); //String
@@ -263,7 +263,7 @@ dojo.declare("dojo.data.ItemFileReadStore", null,{
},
getLabelAttributes: function(/* item */ item){
// summary:
// summary:
// See dojo.data.api.Read.getLabelAttributes()
if(this._labelAttr){
return [this._labelAttr]; //array
@@ -271,10 +271,10 @@ dojo.declare("dojo.data.ItemFileReadStore", null,{
return null; //null
},
_fetchItems: function( /* Object */ keywordArgs,
/* Function */ findCallback,
_fetchItems: function( /* Object */ keywordArgs,
/* Function */ findCallback,
/* Function */ errorCallback){
// summary:
// summary:
// See dojo.data.util.simpleFetch.fetch()
var self = this,
filter = function(requestArgs, arrayOfItems){
@@ -314,8 +314,8 @@ dojo.declare("dojo.data.ItemFileReadStore", null,{
}
findCallback(items, requestArgs);
}else{
// We want a copy to pass back in case the parent wishes to sort the array.
// We shouldn't allow resort of the internal list, so that multiple callers
// We want a copy to pass back in case the parent wishes to sort the array.
// We shouldn't allow resort of the internal list, so that multiple callers
// can get lists and sort without affecting each other. We also need to
// filter out any null values that have been left as a result of deleteItem()
// calls in ItemFileWriteStore.
@@ -335,11 +335,11 @@ dojo.declare("dojo.data.ItemFileReadStore", null,{
//Do a check on the JsonFileUrl and crosscheck it.
//If it doesn't match the cross-check, it needs to be updated
//This allows for either url or _jsonFileUrl to he changed to
//reset the store load location. Done this way for backwards
//reset the store load location. Done this way for backwards
//compatibility. People use _jsonFileUrl (even though officially
//private.
if(this._jsonFileUrl !== this._ccUrl){
dojo.deprecated("dojo.data.ItemFileReadStore: ",
dojo.deprecated("dojo.data.ItemFileReadStore: ",
"To change the url, set the url property of the store," +
" not _jsonFileUrl. _jsonFileUrl support will be removed in 2.0");
this._ccUrl = this._jsonFileUrl;
@@ -350,21 +350,21 @@ dojo.declare("dojo.data.ItemFileReadStore", null,{
}
//See if there was any forced reset of data.
if(this.data != null && this._jsonData == null){
if(this.data != null){
this._jsonData = this.data;
this.data = null;
}
if(this._jsonFileUrl){
//If fetches come in before the loading has finished, but while
//a load is in progress, we have to defer the fetching to be
//a load is in progress, we have to defer the fetching to be
//invoked in the callback.
if(this._loadInProgress){
this._queuedFetches.push({args: keywordArgs, filter: filter});
}else{
this._loadInProgress = true;
var getArgs = {
url: self._jsonFileUrl,
url: self._jsonFileUrl,
handleAs: "json-comment-optional",
preventCache: this.urlPreventCache,
failOk: this.failOk
@@ -424,7 +424,7 @@ dojo.declare("dojo.data.ItemFileReadStore", null,{
},
_handleQueuedFetches: function(){
// summary:
// summary:
// Internal function to execute delayed request in the store.
//Execute any deferred fetches now.
if(this._queuedFetches.length > 0){
@@ -433,7 +433,7 @@ dojo.declare("dojo.data.ItemFileReadStore", null,{
delayedQuery = fData.args,
delayedFilter = fData.filter;
if(delayedFilter){
delayedFilter(delayedQuery, this._getItemsArray(delayedQuery.queryOptions));
delayedFilter(delayedQuery, this._getItemsArray(delayedQuery.queryOptions));
}else{
this.fetchItemByIdentity(delayedQuery);
}
@@ -443,31 +443,31 @@ dojo.declare("dojo.data.ItemFileReadStore", null,{
},
_getItemsArray: function(/*object?*/queryOptions){
// summary:
// summary:
// Internal function to determine which list of items to search over.
// queryOptions: The query options parameter, if any.
if(queryOptions && queryOptions.deep){
return this._arrayOfAllItems;
return this._arrayOfAllItems;
}
return this._arrayOfTopLevelItems;
},
close: function(/*dojo.data.api.Request || keywordArgs || null */ request){
// summary:
// summary:
// See dojo.data.api.Read.close()
if(this.clearOnClose &&
this._loadFinished &&
if(this.clearOnClose &&
this._loadFinished &&
!this._loadInProgress){
//Reset all internalsback to default state. This will force a reload
//on next fetch. This also checks that the data or url param was set
//on next fetch. This also checks that the data or url param was set
//so that the store knows it can get data. Without one of those being set,
//the next fetch will trigger an error.
if(((this._jsonFileUrl == "" || this._jsonFileUrl == null) &&
if(((this._jsonFileUrl == "" || this._jsonFileUrl == null) &&
(this.url == "" || this.url == null)
) && this.data == null){
console.debug("dojo.data.ItemFileReadStore: WARNING! Data reload " +
" information has not been provided." +
" information has not been provided." +
" Please set 'url' or 'data' to the appropriate value before" +
" the next fetch");
}
@@ -505,7 +505,7 @@ dojo.declare("dojo.data.ItemFileReadStore", null,{
// | false == valueIsAnItem("Kermit");
// | false == valueIsAnItem(42);
// | false == valueIsAnItem(new Date());
// | false == valueIsAnItem({_type:'Date', _value:'May 14, 1802'});
// | false == valueIsAnItem({_type:'Date', _value:'1802-05-14'});
// | false == valueIsAnItem({_reference:'Kermit'});
// | true == valueIsAnItem({name:'Kermit', color:'green'});
// | true == valueIsAnItem({iggy:'pop'});
@@ -516,8 +516,8 @@ dojo.declare("dojo.data.ItemFileReadStore", null,{
(!dojo.isArray(aValue) || addingArrays) &&
(!dojo.isFunction(aValue)) &&
(aValue.constructor == Object || dojo.isArray(aValue)) &&
(typeof aValue._reference === "undefined") &&
(typeof aValue._type === "undefined") &&
(typeof aValue._reference === "undefined") &&
(typeof aValue._type === "undefined") &&
(typeof aValue._value === "undefined") &&
self.hierarchical
);
@@ -567,13 +567,13 @@ dojo.declare("dojo.data.ItemFileReadStore", null,{
item[this._rootItemPropName]=true;
}
// Step 2: Walk through all the attribute values of all the items,
// Step 2: Walk through all the attribute values of all the items,
// and replace single values with arrays. For example, we change this:
// { name:'Miss Piggy', pets:'Foo-Foo'}
// into this:
// { name:['Miss Piggy'], pets:['Foo-Foo']}
//
// We also store the attribute names so we can validate our store
//
// We also store the attribute names so we can validate our store
// reference and item id special properties for the O(1) isItem
var allAttributeNames = {},
key;
@@ -607,9 +607,9 @@ dojo.declare("dojo.data.ItemFileReadStore", null,{
this._reverseRefMap += "_";
}
// Step 4: Some data files specify an optional 'identifier', which is
// the name of an attribute that holds the identity of each item.
// If this data file specified an identifier attribute, then build a
// Step 4: Some data files specify an optional 'identifier', which is
// the name of an attribute that holds the identity of each item.
// If this data file specified an identifier attribute, then build a
// hash table of items keyed by the identity of the items.
var arrayOfValues;
@@ -621,7 +621,7 @@ dojo.declare("dojo.data.ItemFileReadStore", null,{
item = this._arrayOfAllItems[i];
arrayOfValues = item[identifier];
var identity = arrayOfValues[0];
if(!this._itemsByIdentity[identity]){
if(!Object.hasOwnProperty.call(this._itemsByIdentity, identity)){
this._itemsByIdentity[identity] = item;
}else{
if(this._jsonFileUrl){
@@ -635,7 +635,7 @@ dojo.declare("dojo.data.ItemFileReadStore", null,{
this._features['dojo.data.api.Identity'] = Number;
}
// Step 5: Walk through all the items, and set each item's properties
// Step 5: Walk through all the items, and set each item's properties
// for _storeRefPropName and _itemNumPropName, so that store.isItem() will return true.
for(i = 0; i < this._arrayOfAllItems.length; ++i){
item = this._arrayOfAllItems[i];
@@ -649,13 +649,13 @@ dojo.declare("dojo.data.ItemFileReadStore", null,{
// We replace item-references with pointers to items. For example, we change:
// { name:['Kermit'], friends:[{_reference:{name:'Miss Piggy'}}] }
// into this:
// { name:['Kermit'], friends:[miss_piggy] }
// { name:['Kermit'], friends:[miss_piggy] }
// (where miss_piggy is the object representing the 'Miss Piggy' item).
//
// We replace type/value pairs with typed-literals. For example, we change:
// { name:['Nelson Mandela'], born:[{_type:'Date', _value:'July 18, 1918'}] }
// { name:['Nelson Mandela'], born:[{_type:'Date', _value:'1918-07-18'}] }
// into this:
// { name:['Kermit'], born:(new Date('July 18, 1918')) }
// { name:['Kermit'], born:(new Date(1918, 6, 18)) }
//
// We also generate the associate map for all items for the O(1) isItem function.
for(i = 0; i < this._arrayOfAllItems.length; ++i){
@@ -668,7 +668,7 @@ dojo.declare("dojo.data.ItemFileReadStore", null,{
if(("_type" in value) && ("_value" in value)){
var type = value._type; // examples: 'Date', 'Color', or 'ComplexNumber'
var mappingObj = this._datatypeMap[type]; // examples: Date, dojo.Color, foo.math.ComplexNumber, {type: dojo.Color, deserialize(value){ return new dojo.Color(value)}}
if(!mappingObj){
if(!mappingObj){
throw new Error("dojo.data.ItemFileReadStore: in the typeMap constructor arg, no object class was specified for the datatype '" + type + "'");
}else if(dojo.isFunction(mappingObj)){
arrayOfValues[j] = new mappingObj(value._value);
@@ -691,12 +691,12 @@ dojo.declare("dojo.data.ItemFileReadStore", null,{
var candidateItem = this._arrayOfAllItems[k],
found = true;
for(var refKey in referenceDescription){
if(candidateItem[refKey] != referenceDescription[refKey]){
found = false;
if(candidateItem[refKey] != referenceDescription[refKey]){
found = false;
}
}
if(found){
arrayOfValues[j] = candidateItem;
if(found){
arrayOfValues[j] = candidateItem;
}
}
}
@@ -707,7 +707,7 @@ dojo.declare("dojo.data.ItemFileReadStore", null,{
}
}
}else if(this.isItem(value)){
//It's a child item (not one referenced through _reference).
//It's a child item (not one referenced through _reference).
//We need to treat this as a referenced item, so it can be cleaned up
//in a write store easily.
if(this.referenceIntegrity){
@@ -736,7 +736,7 @@ dojo.declare("dojo.data.ItemFileReadStore", null,{
},
getIdentity: function(/* item */ item){
// summary:
// summary:
// See dojo.data.api.Identity.getIdentity()
var identifier = this._features['dojo.data.api.Identity'];
if(identifier === Number){
@@ -751,7 +751,7 @@ dojo.declare("dojo.data.ItemFileReadStore", null,{
},
fetchItemByIdentity: function(/* Object */ keywordArgs){
// summary:
// summary:
// See dojo.data.api.Identity.fetchItemByIdentity()
// Hasn't loaded yet, we have to trigger the load.
@@ -762,11 +762,11 @@ dojo.declare("dojo.data.ItemFileReadStore", null,{
//Do a check on the JsonFileUrl and crosscheck it.
//If it doesn't match the cross-check, it needs to be updated
//This allows for either url or _jsonFileUrl to he changed to
//reset the store load location. Done this way for backwards
//reset the store load location. Done this way for backwards
//compatibility. People use _jsonFileUrl (even though officially
//private.
if(this._jsonFileUrl !== this._ccUrl){
dojo.deprecated("dojo.data.ItemFileReadStore: ",
dojo.deprecated("dojo.data.ItemFileReadStore: ",
"To change the url, set the url property of the store," +
" not _jsonFileUrl. _jsonFileUrl support will be removed in 2.0");
this._ccUrl = this._jsonFileUrl;
@@ -789,7 +789,7 @@ dojo.declare("dojo.data.ItemFileReadStore", null,{
}else{
this._loadInProgress = true;
var getArgs = {
url: self._jsonFileUrl,
url: self._jsonFileUrl,
handleAs: "json-comment-optional",
preventCache: this.urlPreventCache,
failOk: this.failOk
@@ -832,7 +832,7 @@ dojo.declare("dojo.data.ItemFileReadStore", null,{
scope = keywordArgs.scope?keywordArgs.scope:dojo.global;
keywordArgs.onItem.call(scope, item);
}
}
}
}else{
// Already loaded. We can just look it up and call back.
item = this._getItemByIdentity(keywordArgs.identity);
@@ -847,9 +847,10 @@ dojo.declare("dojo.data.ItemFileReadStore", null,{
// summary:
// Internal function to look an item up by its identity map.
var item = null;
if(this._itemsByIdentity){
if(this._itemsByIdentity &&
Object.hasOwnProperty.call(this._itemsByIdentity, identity)){
item = this._itemsByIdentity[identity];
}else{
}else if (Object.hasOwnProperty.call(this._arrayOfAllItems, identity)){
item = this._arrayOfAllItems[identity];
}
if(item === undefined){
@@ -859,15 +860,15 @@ dojo.declare("dojo.data.ItemFileReadStore", null,{
},
getIdentityAttributes: function(/* item */ item){
// summary:
// See dojo.data.api.Identity.getIdentifierAttributes()
// summary:
// See dojo.data.api.Identity.getIdentityAttributes()
var identifier = this._features['dojo.data.api.Identity'];
if(identifier === Number){
// If (identifier === Number) it means getIdentity() just returns
// an integer item-number for each item. The dojo.data.api.Identity
// spec says we need to return null if the identity is not composed
// of attributes
// spec says we need to return null if the identity is not composed
// of attributes
return null; // null
}else{
return [identifier]; // Array
@@ -875,18 +876,18 @@ dojo.declare("dojo.data.ItemFileReadStore", null,{
},
_forceLoad: function(){
// summary:
// summary:
// Internal function to force a load of the store if it hasn't occurred yet. This is required
// for specific functions to work properly.
// for specific functions to work properly.
var self = this;
//Do a check on the JsonFileUrl and crosscheck it.
//If it doesn't match the cross-check, it needs to be updated
//This allows for either url or _jsonFileUrl to he changed to
//reset the store load location. Done this way for backwards
//reset the store load location. Done this way for backwards
//compatibility. People use _jsonFileUrl (even though officially
//private.
if(this._jsonFileUrl !== this._ccUrl){
dojo.deprecated("dojo.data.ItemFileReadStore: ",
dojo.deprecated("dojo.data.ItemFileReadStore: ",
"To change the url, set the url property of the store," +
" not _jsonFileUrl. _jsonFileUrl support will be removed in 2.0");
this._ccUrl = this._jsonFileUrl;
@@ -897,14 +898,14 @@ dojo.declare("dojo.data.ItemFileReadStore", null,{
}
//See if there was any forced reset of data.
if(this.data != null && this._jsonData == null){
if(this.data != null){
this._jsonData = this.data;
this.data = null;
}
if(this._jsonFileUrl){
var getArgs = {
url: this._jsonFileUrl,
url: this._jsonFileUrl,
handleAs: "json-comment-optional",
preventCache: this.urlPreventCache,
failOk: this.failOk,
@@ -913,7 +914,7 @@ dojo.declare("dojo.data.ItemFileReadStore", null,{
var getHandler = dojo.xhrGet(getArgs);
getHandler.addCallback(function(data){
try{
//Check to be sure there wasn't another load going on concurrently
//Check to be sure there wasn't another load going on concurrently
//So we don't clobber data that comes in on it. If there is a load going on
//then do not save this data. It will potentially clobber current data.
//We mainly wanted to sync/wait here.
@@ -926,7 +927,7 @@ dojo.declare("dojo.data.ItemFileReadStore", null,{
//Okay, we hit an error state we can't recover from. A forced load occurred
//while an async load was occurring. Since we cannot block at this point, the best
//that can be managed is to throw an error.
throw new Error("dojo.data.ItemFileReadStore: Unable to perform a synchronous load, an async load is in progress.");
throw new Error("dojo.data.ItemFileReadStore: Unable to perform a synchronous load, an async load is in progress.");
}
}catch(e){
console.log(e);
@@ -940,7 +941,7 @@ dojo.declare("dojo.data.ItemFileReadStore", null,{
self._getItemsFromLoadedData(self._jsonData);
self._jsonData = null;
self._loadFinished = true;
}
}
}
});
//Mix in the simple fetch implementation to this class.
+43 -42
View File
@@ -1,5 +1,5 @@
/*
Copyright (c) 2004-2010, The Dojo Foundation All Rights Reserved.
Copyright (c) 2004-2011, The Dojo Foundation All Rights Reserved.
Available via Academic Free License >= 2.1 OR the modified BSD license.
see: http://dojotoolkit.org/license for details
*/
@@ -10,6 +10,7 @@ dojo._hasResource["dojo.data.ItemFileWriteStore"] = true;
dojo.provide("dojo.data.ItemFileWriteStore");
dojo.require("dojo.data.ItemFileReadStore");
dojo.declare("dojo.data.ItemFileWriteStore", dojo.data.ItemFileReadStore, {
constructor: function(/* object */ keywordParameters){
// keywordParameters: {typeMap: object)
@@ -20,7 +21,7 @@ dojo.declare("dojo.data.ItemFileWriteStore", dojo.data.ItemFileReadStore, {
// ...
// typeN: function || object
// }
// Where if it is a function, it is assumed to be an object constructor that takes the
// Where if it is a function, it is assumed to be an object constructor that takes the
// value of _value as the initialization parameters. It is serialized assuming object.toString()
// serialization. If it is an object, then it is assumed
// to be an object of general form:
@@ -36,8 +37,8 @@ dojo.declare("dojo.data.ItemFileWriteStore", dojo.data.ItemFileReadStore, {
// For keeping track of changes so that we can implement isDirty and revert
this._pending = {
_newItems:{},
_modifiedItems:{},
_newItems:{},
_modifiedItems:{},
_deletedItems:{}
};
@@ -100,8 +101,8 @@ dojo.declare("dojo.data.ItemFileWriteStore", dojo.data.ItemFileReadStore, {
}
}
// make sure this identity is not already in use by another item, if identifiers were
// defined in the file. Otherwise it would be the item count,
// make sure this identity is not already in use by another item, if identifiers were
// defined in the file. Otherwise it would be the item count,
// which should always be unique in this case.
if(this._itemsByIdentity){
this._assert(typeof this._itemsByIdentity[newIdentity] === "undefined");
@@ -110,7 +111,7 @@ dojo.declare("dojo.data.ItemFileWriteStore", dojo.data.ItemFileReadStore, {
this._assert(typeof this._pending._deletedItems[newIdentity] === "undefined");
var newItem = {};
newItem[this._storeRefPropName] = this;
newItem[this._storeRefPropName] = this;
newItem[this._itemNumPropName] = this._arrayOfAllItems.length;
if(this._itemsByIdentity){
this._itemsByIdentity[newIdentity] = newItem;
@@ -163,14 +164,14 @@ dojo.declare("dojo.data.ItemFileWriteStore", dojo.data.ItemFileReadStore, {
// Bummer, the user is trying to do something like
// newItem({_S:"foo"}). Unfortunately, our superclass,
// ItemFileReadStore, is already using _S in each of our items
// to hold private info. To avoid a naming collision, we
// need to move all our private info to some other property
// to hold private info. To avoid a naming collision, we
// need to move all our private info to some other property
// of all the items/objects. So, we need to iterate over all
// the items and do something like:
// the items and do something like:
// item.__S = item._S;
// item._S = undefined;
// But first we have to make sure the new "__S" variable is
// not in use, which means we have to iterate over all the
// But first we have to make sure the new "__S" variable is
// not in use, which means we have to iterate over all the
// items checking for that.
throw new Error("encountered bug in ItemFileWriteStore.newItem");
}
@@ -207,17 +208,17 @@ dojo.declare("dojo.data.ItemFileWriteStore", dojo.data.ItemFileReadStore, {
this._assertIsItem(item);
// Remove this item from the _arrayOfAllItems, but leave a null value in place
// of the item, so as not to change the length of the array, so that in newItem()
// of the item, so as not to change the length of the array, so that in newItem()
// we can still safely do: newIdentity = this._arrayOfAllItems.length;
var indexInArrayOfAllItems = item[this._itemNumPropName];
var identity = this.getIdentity(item);
//If we have reference integrity on, we need to do reference cleanup for the deleted item
if(this.referenceIntegrity){
//First scan all the attributes of this items for references and clean them up in the map
//First scan all the attributes of this items for references and clean them up in the map
//As this item is going away, no need to track its references anymore.
//Get the attributes list before we generate the backup so it
//Get the attributes list before we generate the backup so it
//doesn't pollute the attributes list.
var attributes = this.getAttributes(item);
@@ -263,7 +264,7 @@ dojo.declare("dojo.data.ItemFileWriteStore", dojo.data.ItemFileReadStore, {
return !(this.isItem(possibleItem) && this.getIdentity(possibleItem) == identity);
}, this);
//Remove the note of the reference to the item and set the values on the modified attribute.
this._removeReferenceFromMap(item, containingItem, attribute);
this._removeReferenceFromMap(item, containingItem, attribute);
if(newValues.length < oldValues.length){
this._setValueOrValues(containingItem, attribute, newValues, true);
}
@@ -325,11 +326,11 @@ dojo.declare("dojo.data.ItemFileWriteStore", dojo.data.ItemFileReadStore, {
var identity = this.getIdentity(item);
if(!this._pending._modifiedItems[identity]){
// Before we actually change the item, we make a copy of it to
// record the original state, so that we'll be able to revert if
// Before we actually change the item, we make a copy of it to
// record the original state, so that we'll be able to revert if
// the revert method gets called. If the item has already been
// modified then there's no need to do this now, since we already
// have a record of the original state.
// have a record of the original state.
var copyOfItemState = {};
for(var key in item){
if((key === this._storeRefPropName) || (key === this._itemNumPropName) || (key === this._rootItemPropName)){
@@ -350,7 +351,7 @@ dojo.declare("dojo.data.ItemFileWriteStore", dojo.data.ItemFileReadStore, {
if(dojo.isArray(newValueOrValues) && newValueOrValues.length === 0){
// If we were passed an empty array as the value, that counts
// as "unsetting" the attribute, so we need to remove this
// as "unsetting" the attribute, so we need to remove this
// attribute from the item.
success = delete item[attribute];
newValueOrValues = undefined; // used in the onSet Notification call below
@@ -374,7 +375,7 @@ dojo.declare("dojo.data.ItemFileWriteStore", dojo.data.ItemFileReadStore, {
// Unfortunately, it's not safe to just do this:
// newValueArray = newValues;
// Instead, we need to copy the array, which slice() does very nicely.
// This is so that our internal data structure won't
// This is so that our internal data structure won't
// get corrupted if the user mucks with the values array *after*
// calling setValues().
newValueArray = newValueOrValues.slice(0, newValueOrValues.length);
@@ -382,7 +383,7 @@ dojo.declare("dojo.data.ItemFileWriteStore", dojo.data.ItemFileReadStore, {
newValueArray = [newValueOrValues];
}
//We need to handle reference integrity if this is on.
//We need to handle reference integrity if this is on.
//In the case of set, we need to see if references were added or removed
//and update the reference tracking map accordingly.
if(this.referenceIntegrity){
@@ -409,7 +410,7 @@ dojo.declare("dojo.data.ItemFileWriteStore", dojo.data.ItemFileReadStore, {
if(map[id.toString()]){
delete map[id.toString()];
}else{
this._addReferenceToMap(possibleItem, item, attribute);
this._addReferenceToMap(possibleItem, item, attribute);
}
}
}, this);
@@ -439,7 +440,7 @@ dojo.declare("dojo.data.ItemFileWriteStore", dojo.data.ItemFileReadStore, {
// Now we make the dojo.data.api.Notification call
if(callOnSet){
this.onSet(item, attribute, oldValueOrValues, newValueOrValues);
this.onSet(item, attribute, oldValueOrValues, newValueOrValues);
}
return success; // boolean
},
@@ -474,7 +475,7 @@ dojo.declare("dojo.data.ItemFileWriteStore", dojo.data.ItemFileReadStore, {
// Method to remove an reference map entry for an item and attribute.
// description:
// Method to remove an reference map entry for an item and attribute. This will
// also perform cleanup on the map such that if there are no more references at all to
// also perform cleanup on the map such that if there are no more references at all to
// the item, its reference object and entry are removed.
//
// refItem:
@@ -531,7 +532,7 @@ dojo.declare("dojo.data.ItemFileWriteStore", dojo.data.ItemFileReadStore, {
_flatten: function(/* anything */ value){
if(this.isItem(value)){
var item = value;
// Given an item, return an serializable object that provides a
// Given an item, return an serializable object that provides a
// reference to the item.
// For example, given kermit:
// var kermit = store.newItem({id:2, name:"Kermit"});
@@ -562,7 +563,7 @@ dojo.declare("dojo.data.ItemFileWriteStore", dojo.data.ItemFileReadStore, {
},
_getNewFileContentString: function(){
// summary:
// summary:
// Generate a string that can be saved to a file.
// The result should look similar to:
// http://trac.dojotoolkit.org/browser/dojo/trunk/tests/data/countries.json
@@ -603,7 +604,7 @@ dojo.declare("dojo.data.ItemFileWriteStore", dojo.data.ItemFileReadStore, {
},
_isEmpty: function(something){
// summary:
// summary:
// Function to determine if an array or object has no properties or values.
// something:
// The array or object to examine.
@@ -632,7 +633,7 @@ dojo.declare("dojo.data.ItemFileWriteStore", dojo.data.ItemFileReadStore, {
var self = this;
var saveCompleteCallback = function(){
self._pending = {
_newItems:{},
_newItems:{},
_modifiedItems:{},
_deletedItems:{}
};
@@ -681,7 +682,7 @@ dojo.declare("dojo.data.ItemFileWriteStore", dojo.data.ItemFileReadStore, {
modifiedItem = this._arrayOfAllItems[identity];
}
// Restore the original item into a full-fledged item again, we want to try to
// Restore the original item into a full-fledged item again, we want to try to
// keep the same object instance as if we don't it, causes bugs like #9022.
copyOfItemState[this._storeRefPropName] = this;
for(key in modifiedItem){
@@ -722,7 +723,7 @@ dojo.declare("dojo.data.ItemFileWriteStore", dojo.data.ItemFileReadStore, {
}
this._addReferenceToMap(refItem, deletedItem, reference.attr);
}, this);
delete deletedItem["backupRefs_" + this._reverseRefMap];
delete deletedItem["backupRefs_" + this._reverseRefMap];
}
}
@@ -741,8 +742,8 @@ dojo.declare("dojo.data.ItemFileWriteStore", dojo.data.ItemFileReadStore, {
}
this._pending = {
_newItems:{},
_modifiedItems:{},
_newItems:{},
_modifiedItems:{},
_deletedItems:{}
};
return true; // boolean
@@ -753,13 +754,13 @@ dojo.declare("dojo.data.ItemFileWriteStore", dojo.data.ItemFileReadStore, {
if(item){
// return true if the item is dirty
var identity = this.getIdentity(item);
return new Boolean(this._pending._newItems[identity] ||
return new Boolean(this._pending._newItems[identity] ||
this._pending._modifiedItems[identity] ||
this._pending._deletedItems[identity]).valueOf(); // boolean
}else{
// return true if the store is dirty -- which means return true
// if there are any new items, dirty items, or modified items
if(!this._isEmpty(this._pending._newItems) ||
if(!this._isEmpty(this._pending._newItems) ||
!this._isEmpty(this._pending._modifiedItems) ||
!this._isEmpty(this._pending._deletedItems)){
return true;
@@ -770,28 +771,28 @@ dojo.declare("dojo.data.ItemFileWriteStore", dojo.data.ItemFileReadStore, {
/* dojo.data.api.Notification */
onSet: function(/* item */ item,
/*attribute-name-string*/ attribute,
onSet: function(/* item */ item,
/*attribute-name-string*/ attribute,
/*object | array*/ oldValue,
/*object | array*/ newValue){
// summary: See dojo.data.api.Notification.onSet()
// No need to do anything. This method is here just so that the
// No need to do anything. This method is here just so that the
// client code can connect observers to it.
},
onNew: function(/* item */ newItem, /*object?*/ parentInfo){
// summary: See dojo.data.api.Notification.onNew()
// No need to do anything. This method is here just so that the
// client code can connect observers to it.
// No need to do anything. This method is here just so that the
// client code can connect observers to it.
},
onDelete: function(/* item */ deletedItem){
// summary: See dojo.data.api.Notification.onDelete()
// No need to do anything. This method is here just so that the
// client code can connect observers to it.
// No need to do anything. This method is here just so that the
// client code can connect observers to it.
},
close: function(/* object? */ request){
+487
View File
@@ -0,0 +1,487 @@
/*
Copyright (c) 2004-2011, The Dojo Foundation All Rights Reserved.
Available via Academic Free License >= 2.1 OR the modified BSD license.
see: http://dojotoolkit.org/license for details
*/
if(!dojo._hasResource["dojo.data.ObjectStore"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
dojo._hasResource["dojo.data.ObjectStore"] = true;
dojo.provide("dojo.data.ObjectStore");
dojo.require("dojo.regexp");
dojo.declare("dojo.data.ObjectStore", null,{
objectStore: null,
constructor: function(options){
// summary:
// A Dojo Data implementation that wraps Dojo object stores for backwards
// compatibility.
// options:
// The configuration information to pass into the data store.
// options.objectStore:
// The object store to use as the source provider for this data store
dojo.mixin(this, options);
},
labelProperty: "label",
getValue: function(/*Object*/ item, /*String*/property, /*value?*/defaultValue){
// summary:
// Gets the value of an item's 'property'
//
// item:
// The item to get the value from
// property:
// property to look up value for
// defaultValue:
// the default value
return typeof item.get === "function" ? item.get(property) :
property in item ?
item[property] : defaultValue;
},
getValues: function(item, property){
// summary:
// Gets the value of an item's 'property' and returns
// it. If this value is an array it is just returned,
// if not, the value is added to an array and that is returned.
//
// item: /* object */
// property: /* string */
// property to look up value for
var val = this.getValue(item,property);
return val instanceof Array ? val : val === undefined ? [] : [val];
},
getAttributes: function(item){
// summary:
// Gets the available attributes of an item's 'property' and returns
// it as an array.
//
// item: /* object */
var res = [];
for(var i in item){
if(item.hasOwnProperty(i) && !(i.charAt(0) == '_' && i.charAt(1) == '_')){
res.push(i);
}
}
return res;
},
hasAttribute: function(item,attribute){
// summary:
// Checks to see if item has attribute
//
// item: /* object */
// attribute: /* string */
return attribute in item;
},
containsValue: function(item, attribute, value){
// summary:
// Checks to see if 'item' has 'value' at 'attribute'
//
// item: /* object */
// attribute: /* string */
// value: /* anything */
return dojo.indexOf(this.getValues(item,attribute),value) > -1;
},
isItem: function(item){
// summary:
// Checks to see if the argument is an item
//
// item: /* object */
// attribute: /* string */
// we have no way of determining if it belongs, we just have object returned from
// service queries
return (typeof item == 'object') && item && !(item instanceof Date);
},
isItemLoaded: function(item){
// summary:
// Checks to see if the item is loaded.
//
// item: /* object */
return item && typeof item.load !== "function";
},
loadItem: function(args){
// summary:
// Loads an item and calls the callback handler. Note, that this will call the callback
// handler even if the item is loaded. Consequently, you can use loadItem to ensure
// that an item is loaded is situations when the item may or may not be loaded yet.
// If you access a value directly through property access, you can use this to load
// a lazy value as well (doesn't need to be an item).
//
// example:
// store.loadItem({
// item: item, // this item may or may not be loaded
// onItem: function(item){
// // do something with the item
// }
// });
var item;
if(typeof args.item.load === "function"){
dojo.when(args.item.load(), function(result){
item = result; // in synchronous mode this can allow loadItem to return the value
var func = result instanceof Error ? args.onError : args.onItem;
if(func){
func.call(args.scope, result);
}
});
}else if(args.onItem){
// even if it is already loaded, we will use call the callback, this makes it easier to
// use when it is not known if the item is loaded (you can always safely call loadItem).
args.onItem.call(args.scope, args.item);
}
return item;
},
close: function(request){
return request && request.abort && request.abort();
},
fetch: function(args){
// summary:
// See dojo.data.api.Read.fetch
//
args = args || {};
var self = this;
var scope = args.scope || self;
var query = args.query;
if(typeof query == "object"){ // can be null, but that is ignore by for-in
query = dojo.delegate(query); // don't modify the original
for(var i in query){
// find any strings and convert them to regular expressions for wildcard support
var required = query[i];
if(typeof required == "string"){
query[i] = RegExp("^" + dojo.regexp.escapeString(required, "*?").replace(/\*/g, '.*').replace(/\?/g, '.') + "$", args.queryOptions && args.queryOptions.ignoreCase ? "mi" : "m");
query[i].toString = (function(original){
return function(){
return original;
}
})(required);
}
}
}
var results = this.objectStore.query(query, args);
dojo.when(results.total, function(totalCount){
dojo.when(results, function(results){
if(args.onBegin){
args.onBegin.call(scope, totalCount || results.length, args);
}
if(args.onItem){
for(var i=0; i<results.length;i++){
args.onItem.call(scope, results[i], args);
}
}
if(args.onComplete){
args.onComplete.call(scope, args.onItem ? null : results, args);
}
return results;
}, errorHandler);
}, errorHandler);
function errorHandler(error){
if(args.onError){
args.onError.call(scope, error, args);
}
}
args.abort = function(){
// abort the request
if(results.cancel){
results.cancel();
}
};
args.store = this;
return args;
},
getFeatures: function(){
// summary:
// return the store feature set
return {
"dojo.data.api.Read": !!this.objectStore.get,
"dojo.data.api.Identity": true,
"dojo.data.api.Write": !!this.objectStore.put,
"dojo.data.api.Notification": true
};
},
getLabel: function(/* item */ item){
// summary:
// See dojo.data.api.Read.getLabel()
if(this.isItem(item)){
return this.getValue(item,this.labelProperty); //String
}
return undefined; //undefined
},
getLabelAttributes: function(/* item */ item){
// summary:
// See dojo.data.api.Read.getLabelAttributes()
return [this.labelProperty]; //array
},
//Identity API Support
getIdentity: function(item){
return item.getId ? item.getId() : item[this.objectStore.idProperty || "id"];
},
getIdentityAttributes: function(item){
// summary:
// returns the attributes which are used to make up the
// identity of an item. Basically returns this.objectStore.idProperty
return [this.objectStore.idProperty];
},
fetchItemByIdentity: function(args){
// summary:
// fetch an item by its identity, by looking in our index of what we have loaded
var item;
dojo.when(this.objectStore.get(args.identity),
function(result){
item = result;
args.onItem.call(args.scope, result);
},
function(error){
args.onError.call(args.scope, error);
}
);
return item;
},
newItem: function(data, parentInfo){
// summary:
// adds a new item to the store at the specified point.
// Takes two parameters, data, and options.
//
// data: /* object */
// The data to be added in as an item.
if(parentInfo){
// get the previous value or any empty array
var values = this.getValue(parentInfo.parent,parentInfo.attribute,[]);
// set the new value
values = values.concat([data]);
data.__parent = values;
this.setValue(parentInfo.parent, parentInfo.attribute, values);
}
this._dirtyObjects.push({object:data, save: true});
this.onNew(data);
return data;
},
deleteItem: function(item){
// summary:
// deletes item and any references to that item from the store.
//
// item:
// item to delete
//
// If the desire is to delete only one reference, unsetAttribute or
// setValue is the way to go.
this.changing(item, true);
this.onDelete(item);
},
setValue: function(item, attribute, value){
// summary:
// sets 'attribute' on 'item' to 'value'
var old = item[attribute];
this.changing(item);
item[attribute]=value;
this.onSet(item,attribute,old,value);
},
setValues: function(item, attribute, values){
// summary:
// sets 'attribute' on 'item' to 'value' value
// must be an array.
if(!dojo.isArray(values)){
throw new Error("setValues expects to be passed an Array object as its value");
}
this.setValue(item,attribute,values);
},
unsetAttribute: function(item, attribute){
// summary:
// unsets 'attribute' on 'item'
this.changing(item);
var old = item[attribute];
delete item[attribute];
this.onSet(item,attribute,old,undefined);
},
_dirtyObjects: [],
changing: function(object,_deleting){
// summary:
// adds an object to the list of dirty objects. This object
// contains a reference to the object itself as well as a
// cloned and trimmed version of old object for use with
// revert.
object.__isDirty = true;
//if an object is already in the list of dirty objects, don't add it again
//or it will overwrite the premodification data set.
for(var i=0; i<this._dirtyObjects.length; i++){
var dirty = this._dirtyObjects[i];
if(object==dirty.object){
if(_deleting){
// we are deleting, no object is an indicator of deletiong
dirty.object = false;
if(!this._saveNotNeeded){
dirty.save = true;
}
}
return;
}
}
var old = object instanceof Array ? [] : {};
for(i in object){
if(object.hasOwnProperty(i)){
old[i] = object[i];
}
}
this._dirtyObjects.push({object: !_deleting && object, old: old, save: !this._saveNotNeeded});
},
save: function(kwArgs){
// summary:
// Saves the dirty data using object store provider. See dojo.data.api.Write for API.
//
// kwArgs.global:
// This will cause the save to commit the dirty data for all
// ObjectStores as a single transaction.
//
// kwArgs.revertOnError
// This will cause the changes to be reverted if there is an
// error on the save. By default a revert is executed unless
// a value of false is provide for this parameter.
kwArgs = kwArgs || {};
var result, actions = [];
var alreadyRecorded = {};
var savingObjects = [];
var self;
var dirtyObjects = this._dirtyObjects;
var left = dirtyObjects.length;// this is how many changes are remaining to be received from the server
try{
dojo.connect(kwArgs,"onError",function(){
if(kwArgs.revertOnError !== false){
var postCommitDirtyObjects = dirtyObjects;
dirtyObjects = savingObjects;
var numDirty = 0; // make sure this does't do anything if it is called again
jr.revert(); // revert if there was an error
self._dirtyObjects = postCommitDirtyObjects;
}
else{
self._dirtyObjects = dirtyObject.concat(savingObjects);
}
});
if(this.objectStore.transaction){
var transaction = this.objectStore.transaction();
}
for(var i = 0; i < dirtyObjects.length; i++){
var dirty = dirtyObjects[i];
var object = dirty.object;
var old = dirty.old;
delete object.__isDirty;
if(object){
result = this.objectStore.put(object, {overwrite: !!old});
}
else{
result = this.objectStore.remove(this.getIdentity(old));
}
savingObjects.push(dirty);
dirtyObjects.splice(i--,1);
dojo.when(result, function(value){
if(!(--left)){
if(kwArgs.onComplete){
kwArgs.onComplete.call(kwArgs.scope, actions);
}
}
},function(value){
// on an error we want to revert, first we want to separate any changes that were made since the commit
left = -1; // first make sure that success isn't called
kwArgs.onError.call(kwArgs.scope, value);
});
}
if(transaction){
transaction.commit();
}
}catch(e){
kwArgs.onError.call(kwArgs.scope, value);
}
},
revert: function(kwArgs){
// summary
// returns any modified data to its original state prior to a save();
//
var dirtyObjects = this._dirtyObjects;
for(var i = dirtyObjects.length; i > 0;){
i--;
var dirty = dirtyObjects[i];
var object = dirty.object;
var old = dirty.old;
if(object && old){
// changed
for(var j in old){
if(old.hasOwnProperty(j) && object[j] !== old[j]){
this.onSet(object, j, object[j], old[j]);
object[j] = old[j];
}
}
for(j in object){
if(!old.hasOwnProperty(j)){
this.onSet(object, j, object[j]);
delete object[j];
}
}
}else if(!old){
// was an addition, remove it
this.onDelete(object);
}else{
// was a deletion, we will add it back
this.onNew(old);
}
delete (object || old).__isDirty;
dirtyObjects.splice(i, 1);
}
},
isDirty: function(item){
// summary
// returns true if the item is marked as dirty or true if there are any dirty items
if(!item){
return !!this._dirtyObjects.length;
}
return item.__isDirty;
},
//Notifcation Support
onSet: function(){},
onNew: function(){},
onDelete: function(){}
}
);
}
+16 -15
View File
@@ -1,5 +1,5 @@
/*
Copyright (c) 2004-2010, The Dojo Foundation All Rights Reserved.
Copyright (c) 2004-2011, The Dojo Foundation All Rights Reserved.
Available via Academic Free License >= 2.1 OR the modified BSD license.
see: http://dojotoolkit.org/license for details
*/
@@ -10,6 +10,7 @@ dojo._hasResource["dojo.data.api.Identity"] = true;
dojo.provide("dojo.data.api.Identity");
dojo.require("dojo.data.api.Read");
dojo.declare("dojo.data.api.Identity", dojo.data.api.Read, {
// summary:
// This is an abstract API that data provider implementations conform to.
@@ -17,7 +18,7 @@ dojo.declare("dojo.data.api.Identity", dojo.data.api.Read, {
// methods unimplemented.
getFeatures: function(){
// summary:
// summary:
// See dojo.data.api.Read.getFeatures()
return {
'dojo.data.api.Read': true,
@@ -45,16 +46,16 @@ dojo.declare("dojo.data.api.Identity", dojo.data.api.Read, {
getIdentityAttributes: function(/* item */ item){
// summary:
// Returns an array of attribute names that are used to generate the identity.
// Returns an array of attribute names that are used to generate the identity.
// For most stores, this is a single attribute, but for some complex stores
// such as RDB backed stores that use compound (multi-attribute) identifiers
// it can be more than one. If the identity is not composed of attributes
// on the item, it will return null. This function is intended to identify
// the attributes that comprise the identity so that so that during a render
// of all attributes, the UI can hide the the identity information if it
// of all attributes, the UI can hide the the identity information if it
// chooses.
// item:
// The item from the store from which to obtain the array of public attributes that
// The item from the store from which to obtain the array of public attributes that
// compose the identifier, if any.
// example:
// | var itemId = store.getIdentity(kermit);
@@ -67,14 +68,14 @@ dojo.declare("dojo.data.api.Identity", dojo.data.api.Read, {
fetchItemByIdentity: function(/* object */ keywordArgs){
// summary:
// Given the identity of an item, this method returns the item that has
// that identity through the onItem callback. Conforming implementations
// should return null if there is no item with the given identity.
// Implementations of fetchItemByIdentity() may sometimes return an item
// from a local cache and may sometimes fetch an item from a remote server,
// Given the identity of an item, this method returns the item that has
// that identity through the onItem callback. Conforming implementations
// should return null if there is no item with the given identity.
// Implementations of fetchItemByIdentity() may sometimes return an item
// from a local cache and may sometimes fetch an item from a remote server,
//
// keywordArgs:
// An anonymous object that defines the item to locate and callbacks to invoke when the
// An anonymous object that defines the item to locate and callbacks to invoke when the
// item has been located and load has completed. The format of the object is as follows:
// {
// identity: string|object,
@@ -84,9 +85,9 @@ dojo.declare("dojo.data.api.Identity", dojo.data.api.Read, {
// }
// The *identity* parameter.
// The identity parameter is the identity of the item you wish to locate and load
// This attribute is required. It should be a string or an object that toString()
// This attribute is required. It should be a string or an object that toString()
// can be called on.
//
//
// The *onItem* parameter.
// Function(item)
// The onItem parameter is the callback to invoke when the item has been loaded. It takes only one
@@ -98,12 +99,12 @@ dojo.declare("dojo.data.api.Identity", dojo.data.api.Read, {
// parameter, the error object
//
// The *scope* parameter.
// If a scope object is provided, all of the callback functions (onItem,
// If a scope object is provided, all of the callback functions (onItem,
// onError, etc) will be invoked in the context of the scope object.
// In the body of the callback function, the value of the "this"
// keyword will be the scope object. If no scope object is provided,
// the callback functions will be called in the context of dojo.global.
// For example, onItem.call(scope, item, request) vs.
// For example, onItem.call(scope, item, request) vs.
// onItem.call(dojo.global, item, request)
if(!this.isItemLoaded(keywordArgs.item)){
throw new Error('Unimplemented API: dojo.data.api.Identity.fetchItemByIdentity');
+17 -16
View File
@@ -1,5 +1,5 @@
/*
Copyright (c) 2004-2010, The Dojo Foundation All Rights Reserved.
Copyright (c) 2004-2011, The Dojo Foundation All Rights Reserved.
Available via Academic Free License >= 2.1 OR the modified BSD license.
see: http://dojotoolkit.org/license for details
*/
@@ -10,6 +10,7 @@ dojo._hasResource["dojo.data.api.Notification"] = true;
dojo.provide("dojo.data.api.Notification");
dojo.require("dojo.data.api.Read");
dojo.declare("dojo.data.api.Notification", dojo.data.api.Read, {
// summary:
// This is an abstract API that data provider implementations conform to.
@@ -18,12 +19,12 @@ dojo.declare("dojo.data.api.Notification", dojo.data.api.Read, {
//
// description:
// This API defines a set of APIs that all datastores that conform to the
// Notifications API must implement. In general, most stores will implement
// Notifications API must implement. In general, most stores will implement
// these APIs as no-op functions for users who wish to monitor them to be able
// to connect to then via dojo.connect(). For non-users of dojo.connect,
// to connect to then via dojo.connect(). For non-users of dojo.connect,
// they should be able to just replace the function on the store to obtain
// notifications. Both read-only and read-write stores may implement
// this feature. In the case of a read-only store, this feature makes sense if
// this feature. In the case of a read-only store, this feature makes sense if
// the store itself does internal polling to a back-end server and periodically updates
// its cache of items (deletes, adds, and updates).
//
@@ -36,7 +37,7 @@ dojo.declare("dojo.data.api.Notification", dojo.data.api.Read, {
// | dojo.connect(store, "onSet", onSet);
getFeatures: function(){
// summary:
// summary:
// See dojo.data.api.Read.getFeatures()
return {
'dojo.data.api.Read': true,
@@ -44,16 +45,16 @@ dojo.declare("dojo.data.api.Notification", dojo.data.api.Read, {
};
},
onSet: function(/* item */ item,
/* attribute-name-string */ attribute,
onSet: function(/* item */ item,
/* attribute-name-string */ attribute,
/* object | array */ oldValue,
/* object | array */ newValue){
// summary:
// This function is called any time an item is modified via setValue, setValues, unsetAttribute, etc.
// This function is called any time an item is modified via setValue, setValues, unsetAttribute, etc.
// description:
// This function is called any time an item is modified via setValue, setValues, unsetAttribute, etc.
// Its purpose is to provide a hook point for those who wish to monitor actions on items in the store
// in a simple manner. The general expected usage is to dojo.connect() to the store's
// This function is called any time an item is modified via setValue, setValues, unsetAttribute, etc.
// Its purpose is to provide a hook point for those who wish to monitor actions on items in the store
// in a simple manner. The general expected usage is to dojo.connect() to the store's
// implementation and be called after the store function is called.
//
// item:
@@ -62,11 +63,11 @@ dojo.declare("dojo.data.api.Notification", dojo.data.api.Read, {
// The attribute being changed represented as a string name.
// oldValue:
// The old value of the attribute. In the case of single value calls, such as setValue, unsetAttribute, etc,
// this value will be generally be an atomic value of some sort (string, int, etc, object). In the case of
// this value will be generally be an atomic value of some sort (string, int, etc, object). In the case of
// multi-valued attributes, it will be an array.
// newValue:
// The new value of the attribute. In the case of single value calls, such as setValue, this value will be
// generally be an atomic value of some sort (string, int, etc, object). In the case of multi-valued attributes,
// The new value of the attribute. In the case of single value calls, such as setValue, this value will be
// generally be an atomic value of some sort (string, int, etc, object). In the case of multi-valued attributes,
// it will be an array. In the case of unsetAttribute, the new value will be 'undefined'.
//
// returns:
@@ -93,12 +94,12 @@ dojo.declare("dojo.data.api.Notification", dojo.data.api.Read, {
// {
// item: someItem, //The parent item
// attribute: "attribute-name-string", //The attribute the new item was assigned to.
// oldValue: something //Whatever was the previous value for the attribute.
// oldValue: something //Whatever was the previous value for the attribute.
// //If it is a single-value attribute only, then this value will be a single value.
// //If it was a multi-valued attribute, then this will be an array of all the values minues the new one.
// newValue: something //The new value of the attribute. In the case of single value calls, such as setValue, this value will be
// //generally be an atomic value of some sort (string, int, etc, object). In the case of multi-valued attributes,
// //it will be an array.
// //it will be an array.
// }
//
// returns:
+81 -80
View File
@@ -1,5 +1,5 @@
/*
Copyright (c) 2004-2010, The Dojo Foundation All Rights Reserved.
Copyright (c) 2004-2011, The Dojo Foundation All Rights Reserved.
Available via Academic Free License >= 2.1 OR the modified BSD license.
see: http://dojotoolkit.org/license for details
*/
@@ -10,26 +10,27 @@ dojo._hasResource["dojo.data.api.Read"] = true;
dojo.provide("dojo.data.api.Read");
dojo.require("dojo.data.api.Request");
dojo.declare("dojo.data.api.Read", null, {
// summary:
// This is an abstract API that data provider implementations conform to.
// This is an abstract API that data provider implementations conform to.
// This file defines methods signatures and intentionally leaves all the
// methods unimplemented. For more information on the dojo.data APIs,
// methods unimplemented. For more information on the dojo.data APIs,
// please visit: http://www.dojotoolkit.org/node/98
getValue: function( /* item */ item,
/* attribute-name-string */ attribute,
getValue: function( /* item */ item,
/* attribute-name-string */ attribute,
/* value? */ defaultValue){
// summary:
// Returns a single attribute value.
// Returns defaultValue if and only if *item* does not have a value for *attribute*.
// Returns null if and only if null was explicitly set as the attribute value.
// Returns undefined if and only if the item does not have a value for the
// given attribute (which is the same as saying the item does not have the attribute).
// given attribute (which is the same as saying the item does not have the attribute).
// description:
// Saying that an "item x does not have a value for an attribute y"
// is identical to saying that an "item x does not have attribute y".
// It is an oxymoron to say "that attribute is present but has no values"
// is identical to saying that an "item x does not have attribute y".
// It is an oxymoron to say "that attribute is present but has no values"
// or "the item has that attribute but does not have any attribute values".
// If store.hasAttribute(item, attribute) returns false, then
// store.getValue(item, attribute) will return undefined.
@@ -112,7 +113,7 @@ dojo.declare("dojo.data.api.Read", null, {
},
containsValue: function(/* item */ item,
/* attribute-name-string */ attribute,
/* attribute-name-string */ attribute,
/* anything */ value){
// summary:
// Returns true if the given *value* is one of the values that getValues()
@@ -135,8 +136,8 @@ dojo.declare("dojo.data.api.Read", null, {
isItem: function(/* anything */ something){
// summary:
// Returns true if *something* is an item and came from the store instance.
// Returns false if *something* is a literal, an item from another store instance,
// Returns true if *something* is an item and came from the store instance.
// Returns false if *something* is a literal, an item from another store instance,
// or is any object other than an item.
//
// something:
@@ -173,9 +174,9 @@ dojo.declare("dojo.data.api.Read", null, {
// isItemLoaded() returns true before loadItem() is even called,
// then loadItem() need not do any work at all and will not even invoke
// the callback handlers. So, before invoking this method, check that
// the item has not already been loaded.
// the item has not already been loaded.
// keywordArgs:
// An anonymous object that defines the item to load and callbacks to invoke when the
// An anonymous object that defines the item to load and callbacks to invoke when the
// load has completed. The format of the object is as follows:
// {
// item: object,
@@ -198,12 +199,12 @@ dojo.declare("dojo.data.api.Read", null, {
// parameter, the error object
//
// The *scope* parameter.
// If a scope object is provided, all of the callback functions (onItem,
// If a scope object is provided, all of the callback functions (onItem,
// onError, etc) will be invoked in the context of the scope object.
// In the body of the callback function, the value of the "this"
// keyword will be the scope object. If no scope object is provided,
// the callback functions will be called in the context of dojo.global().
// For example, onItem.call(scope, item, request) vs.
// For example, onItem.call(scope, item, request) vs.
// onItem.call(dojo.global(), item, request)
if(!this.isItemLoaded(keywordArgs.item)){
throw new Error('Unimplemented API: dojo.data.api.Read.loadItem');
@@ -214,25 +215,25 @@ dojo.declare("dojo.data.api.Read", null, {
// summary:
// Given a query and set of defined options, such as a start and count of items to return,
// this method executes the query and makes the results available as data items.
// The format and expectations of stores is that they operate in a generally asynchronous
// The format and expectations of stores is that they operate in a generally asynchronous
// manner, therefore callbacks are always used to return items located by the fetch parameters.
//
// description:
// A Request object will always be returned and is returned immediately.
// The basic request is nothing more than the keyword args passed to fetch and
// an additional function attached, abort(). The returned request object may then be used
// to cancel a fetch. All data items returns are passed through the callbacks defined in the
// The basic request is nothing more than the keyword args passed to fetch and
// an additional function attached, abort(). The returned request object may then be used
// to cancel a fetch. All data items returns are passed through the callbacks defined in the
// fetch parameters and are not present on the 'request' object.
//
// This does not mean that custom stores can not add methods and properties to the request object
// returned, only that the API does not require it. For more info about the Request API,
// returned, only that the API does not require it. For more info about the Request API,
// see dojo.data.api.Request
//
// keywordArgs:
// The keywordArgs parameter may either be an instance of
// The keywordArgs parameter may either be an instance of
// conforming to dojo.data.api.Request or may be a simple anonymous object
// that may contain any of the following:
// {
// {
// query: query-object or query-string,
// queryOptions: object,
// onBegin: Function,
@@ -245,10 +246,10 @@ dojo.declare("dojo.data.api.Read", null, {
// sort: array
// }
// All implementations should accept keywordArgs objects with any of
// the 9 standard properties: query, onBegin, onItem, onComplete, onError
// scope, sort, start, and count. Some implementations may accept additional
// properties in the keywordArgs object as valid parameters, such as
// {includeOutliers:true}.
// the 9 standard properties: query, onBegin, onItem, onComplete, onError
// scope, sort, start, and count. Some implementations may accept additional
// properties in the keywordArgs object as valid parameters, such as
// {includeOutliers:true}.
//
// The *query* parameter.
// The query may be optional in some data store implementations.
@@ -256,28 +257,28 @@ dojo.declare("dojo.data.api.Read", null, {
// of the query itself -- each different data store implementation
// may have its own notion of what a query should look like.
// However, as of dojo 0.9, 1.0, and 1.1, all the provided datastores in dojo.data
// and dojox.data support an object structure query, where the object is a set of
// and dojox.data support an object structure query, where the object is a set of
// name/value parameters such as { attrFoo: valueBar, attrFoo1: valueBar1}. Most of the
// dijit widgets, such as ComboBox assume this to be the case when working with a datastore
// when they dynamically update the query. Therefore, for maximum compatibility with dijit
// dijit widgets, such as ComboBox assume this to be the case when working with a datastore
// when they dynamically update the query. Therefore, for maximum compatibility with dijit
// widgets the recommended query parameter is a key/value object. That does not mean that the
// the datastore may not take alternative query forms, such as a simple string, a Date, a number,
// or a mix of such. Ultimately, The dojo.data.api.Read API is agnostic about what the query
// format.
// Further note: In general for query objects that accept strings as attribute
// value matches, the store should also support basic filtering capability, such as *
// the datastore may not take alternative query forms, such as a simple string, a Date, a number,
// or a mix of such. Ultimately, The dojo.data.api.Read API is agnostic about what the query
// format.
// Further note: In general for query objects that accept strings as attribute
// value matches, the store should also support basic filtering capability, such as *
// (match any character) and ? (match single character). An example query that is a query object
// would be like: { attrFoo: "value*"}. Which generally means match all items where they have
// would be like: { attrFoo: "value*"}. Which generally means match all items where they have
// an attribute named attrFoo, with a value that starts with 'value'.
//
// The *queryOptions* parameter
// The queryOptions parameter is an optional parameter used to specify optiosn that may modify
// the query in some fashion, such as doing a case insensitive search, or doing a deep search
// where all items in a hierarchical representation of data are scanned instead of just the root
// where all items in a hierarchical representation of data are scanned instead of just the root
// items. It currently defines two options that all datastores should attempt to honor if possible:
// {
// ignoreCase: boolean, //Whether or not the query should match case sensitively or not. Default behaviour is false.
// deep: boolean //Whether or not a fetch should do a deep search of items and all child
// deep: boolean //Whether or not a fetch should do a deep search of items and all child
// //items instead of just root-level items in a datastore. Default is false.
// }
//
@@ -287,14 +288,14 @@ dojo.declare("dojo.data.api.Read", null, {
// will be called just once, before the first onItem callback is called.
// The onBegin callback function will be passed two arguments, the
// the total number of items identified and the Request object. If the total number is
// unknown, then size will be -1. Note that size is not necessarily the size of the
// collection of items returned from the query, as the request may have specified to return only a
// unknown, then size will be -1. Note that size is not necessarily the size of the
// collection of items returned from the query, as the request may have specified to return only a
// subset of the total set of items through the use of the start and count parameters.
//
// The *onItem* parameter.
// function(item, request);
// If an onItem callback function is provided, the callback function
// will be called as each item in the result is received. The callback
// will be called as each item in the result is received. The callback
// function will be passed two arguments: the item itself, and the
// Request object.
//
@@ -304,12 +305,12 @@ dojo.declare("dojo.data.api.Read", null, {
// If an onComplete callback function is provided, the callback function
// will be called just once, after the last onItem callback is called.
// Note that if the onItem callback is not present, then onComplete will be passed
// an array containing all items which matched the query and the request object.
// If the onItem callback is present, then onComplete is called as:
// an array containing all items which matched the query and the request object.
// If the onItem callback is present, then onComplete is called as:
// onComplete(null, request).
//
// The *onError* parameter.
// function(errorData, request);
// function(errorData, request);
// If an onError callback function is provided, the callback function
// will be called if there is any sort of error while attempting to
// execute the query.
@@ -317,29 +318,29 @@ dojo.declare("dojo.data.api.Read", null, {
// an Error object and the Request object.
//
// The *scope* parameter.
// If a scope object is provided, all of the callback functions (onItem,
// If a scope object is provided, all of the callback functions (onItem,
// onComplete, onError, etc) will be invoked in the context of the scope
// object. In the body of the callback function, the value of the "this"
// keyword will be the scope object. If no scope object is provided,
// the callback functions will be called in the context of dojo.global().
// For example, onItem.call(scope, item, request) vs.
// the callback functions will be called in the context of dojo.global().
// For example, onItem.call(scope, item, request) vs.
// onItem.call(dojo.global(), item, request)
//
// The *start* parameter.
// If a start parameter is specified, this is a indication to the datastore to
// If a start parameter is specified, this is a indication to the datastore to
// only start returning items once the start number of items have been located and
// skipped. When this parameter is paired withh 'count', the store should be able
// to page across queries with millions of hits by only returning subsets of the
// to page across queries with millions of hits by only returning subsets of the
// hits for each query
//
// The *count* parameter.
// If a count parameter is specified, this is a indication to the datastore to
// only return up to that many items. This allows a fetch call that may have
// millions of item matches to be paired down to something reasonable.
// If a count parameter is specified, this is a indication to the datastore to
// only return up to that many items. This allows a fetch call that may have
// millions of item matches to be paired down to something reasonable.
//
// The *sort* parameter.
// If a sort parameter is specified, this is a indication to the datastore to
// sort the items in some manner before returning the items. The array is an array of
// If a sort parameter is specified, this is a indication to the datastore to
// sort the items in some manner before returning the items. The array is an array of
// javascript objects that must conform to the following format to be applied to the
// fetching of items:
// {
@@ -347,18 +348,18 @@ dojo.declare("dojo.data.api.Read", null, {
// descending: true|false; // Optional. Default is false.
// }
// Note that when comparing attributes, if an item contains no value for the attribute
// (undefined), then it the default ascending sort logic should push it to the bottom
// (undefined), then it the default ascending sort logic should push it to the bottom
// of the list. In the descending order case, it such items should appear at the top of the list.
//
//
// returns:
// The fetch() method will return a javascript object conforming to the API
// defined in dojo.data.api.Request. In general, it will be the keywordArgs
// object returned with the required functions in Request.js attached.
// Its general purpose is to provide a convenient way for a caller to abort an
// ongoing fetch.
//
// ongoing fetch.
//
// The Request object may also have additional properties when it is returned
// such as request.store property, which is a pointer to the datastore object that
// such as request.store property, which is a pointer to the datastore object that
// fetch() is a method of.
//
// exceptions:
@@ -373,7 +374,7 @@ dojo.declare("dojo.data.api.Read", null, {
// | var request = store.fetch(onComplete: showEverything);
// example:
// Fetch only 10 books that match the query 'all books', starting at the fifth book found during the search.
// This demonstrates how paging can be done for specific queries.
// This demonstrates how paging can be done for specific queries.
// | var request = store.fetch({query:"all books", start: 4, count: 10, onComplete: showBooks});
// example:
// Fetch all items that match the query, calling 'callback' each time an item is located.
@@ -412,21 +413,21 @@ dojo.declare("dojo.data.api.Read", null, {
// and then when the user presses the "Next Page" button...
// | fetchArgs.start += 20;
// | store.fetch(fetchArgs); // get the next 20 items
var request = null;
var request = null;
throw new Error('Unimplemented API: dojo.data.api.Read.fetch');
return request; // an object conforming to the dojo.data.api.Request API
},
getFeatures: function(){
// summary:
// The getFeatures() method returns an simple keyword values object
// that specifies what interface features the datastore implements.
// A simple CsvStore may be read-only, and the only feature it
// The getFeatures() method returns an simple keyword values object
// that specifies what interface features the datastore implements.
// A simple CsvStore may be read-only, and the only feature it
// implements will be the 'dojo.data.api.Read' interface, so the
// getFeatures() method will return an object like this one:
// {'dojo.data.api.Read': true}.
// A more sophisticated datastore might implement a variety of
// interface features, like 'dojo.data.api.Read', 'dojo.data.api.Write',
// interface features, like 'dojo.data.api.Read', 'dojo.data.api.Write',
// 'dojo.data.api.Identity', and 'dojo.data.api.Attribution'.
return {
'dojo.data.api.Read': true
@@ -435,14 +436,14 @@ dojo.declare("dojo.data.api.Read", null, {
close: function(/*dojo.data.api.Request || keywordArgs || null */ request){
// summary:
// The close() method is intended for instructing the store to 'close' out
// The close() method is intended for instructing the store to 'close' out
// any information associated with a particular request.
//
// description:
// The close() method is intended for instructing the store to 'close' out
// The close() method is intended for instructing the store to 'close' out
// any information associated with a particular request. In general, this API
// expects to recieve as a parameter a request object returned from a fetch.
// It will then close out anything associated with that request, such as
// expects to recieve as a parameter a request object returned from a fetch.
// It will then close out anything associated with that request, such as
// clearing any internal datastore caches and closing any 'open' connections.
// For some store implementations, this call may be a no-op.
//
@@ -450,7 +451,7 @@ dojo.declare("dojo.data.api.Read", null, {
// An instance of a request for the store to use to identify what to close out.
// If no request is passed, then the store should clear all internal caches (if any)
// and close out all 'open' connections. It does not render the store unusable from
// there on, it merely cleans out any current data and resets the store to initial
// there on, it merely cleans out any current data and resets the store to initial
// state.
//
// example:
@@ -463,7 +464,7 @@ dojo.declare("dojo.data.api.Read", null, {
getLabel: function(/* item */ item){
// summary:
// Method to inspect the item and return a user-readable 'label' for the item
// that provides a general/adequate description of what the item is.
// that provides a general/adequate description of what the item is.
//
// description:
// Method to inspect the item and return a user-readable 'label' for the item
@@ -471,17 +472,17 @@ dojo.declare("dojo.data.api.Read", null, {
// most labels will be a specific attribute value or collection of the attribute
// values that combine to label the item in some manner. For example for an item
// that represents a person it may return the label as: "firstname lastlame" where
// the firstname and lastname are attributes on the item. If the store is unable
// the firstname and lastname are attributes on the item. If the store is unable
// to determine an adequate human readable label, it should return undefined. Users that wish
// to customize how a store instance labels items should replace the getLabel() function on
// their instance of the store, or extend the store and replace the function in
// to customize how a store instance labels items should replace the getLabel() function on
// their instance of the store, or extend the store and replace the function in
// the extension class.
//
// item:
// The item to return the label for.
//
// returns:
// A user-readable string representing the item or undefined if no user-readable label can
// returns:
// A user-readable string representing the item or undefined if no user-readable label can
// be generated.
throw new Error('Unimplemented API: dojo.data.api.Read.getLabel');
return undefined;
@@ -489,21 +490,21 @@ dojo.declare("dojo.data.api.Read", null, {
getLabelAttributes: function(/* item */ item){
// summary:
// Method to inspect the item and return an array of what attributes of the item were used
// Method to inspect the item and return an array of what attributes of the item were used
// to generate its label, if any.
//
// description:
// Method to inspect the item and return an array of what attributes of the item were used
// Method to inspect the item and return an array of what attributes of the item were used
// to generate its label, if any. This function is to assist UI developers in knowing what
// attributes can be ignored out of the attributes an item has when displaying it, in cases
// where the UI is using the label as an overall identifer should they wish to hide
// where the UI is using the label as an overall identifer should they wish to hide
// redundant information.
//
// item:
// The item to return the list of label attributes for.
//
// returns:
// An array of attribute names that were used to generate the label, or null if public attributes
// returns:
// An array of attribute names that were used to generate the label, or null if public attributes
// were not used to generate the label.
throw new Error('Unimplemented API: dojo.data.api.Read.getLabelAttributes');
return null;
+7 -6
View File
@@ -1,5 +1,5 @@
/*
Copyright (c) 2004-2010, The Dojo Foundation All Rights Reserved.
Copyright (c) 2004-2011, The Dojo Foundation All Rights Reserved.
Available via Academic Free License >= 2.1 OR the modified BSD license.
see: http://dojotoolkit.org/license for details
*/
@@ -9,16 +9,17 @@ if(!dojo._hasResource["dojo.data.api.Request"]){ //_hasResource checks added by
dojo._hasResource["dojo.data.api.Request"] = true;
dojo.provide("dojo.data.api.Request");
dojo.declare("dojo.data.api.Request", null, {
// summary:
// This class defines out the semantics of what a 'Request' object looks like
// when returned from a fetch() method. In general, a request object is
// nothing more than the original keywordArgs from fetch with an abort function
// attached to it to allow users to abort a particular request if they so choose.
// nothing more than the original keywordArgs from fetch with an abort function
// attached to it to allow users to abort a particular request if they so choose.
// No other functions are required on a general Request object return. That does not
// inhibit other store implementations from adding extentions to it, of course.
//
// This is an abstract API that data provider implementations conform to.
// This is an abstract API that data provider implementations conform to.
// This file defines methods signatures and intentionally leaves all the
// methods unimplemented.
//
@@ -26,10 +27,10 @@ dojo.declare("dojo.data.api.Request", null, {
abort: function(){
// summary:
// This function is a hook point for stores to provide as a way for
// This function is a hook point for stores to provide as a way for
// a fetch to be halted mid-processing.
// description:
// This function is a hook point for stores to provide as a way for
// This function is a hook point for stores to provide as a way for
// a fetch to be halted mid-processing. For more details on the fetch() api,
// please see dojo.data.api.Read.fetch().
throw new Error('Unimplemented API: dojo.data.api.Request.abort');
+21 -20
View File
@@ -1,5 +1,5 @@
/*
Copyright (c) 2004-2010, The Dojo Foundation All Rights Reserved.
Copyright (c) 2004-2011, The Dojo Foundation All Rights Reserved.
Available via Academic Free License >= 2.1 OR the modified BSD license.
see: http://dojotoolkit.org/license for details
*/
@@ -10,14 +10,15 @@ dojo._hasResource["dojo.data.api.Write"] = true;
dojo.provide("dojo.data.api.Write");
dojo.require("dojo.data.api.Read");
dojo.declare("dojo.data.api.Write", dojo.data.api.Read, {
// summary:
// This is an abstract API that data provider implementations conform to.
// This is an abstract API that data provider implementations conform to.
// This file defines function signatures and intentionally leaves all the
// functionss unimplemented.
getFeatures: function(){
// summary:
// summary:
// See dojo.data.api.Read.getFeatures()
return {
'dojo.data.api.Read': true,
@@ -31,16 +32,16 @@ dojo.declare("dojo.data.api.Write", dojo.data.api.Read, {
// item based on the *keywordArgs* provided. In general, the attribute
// names in the keywords become the attributes in the new item and as for
// the attribute values in keywordArgs, they become the values of the attributes
// in the new item. In addition, for stores that support hierarchical item
// in the new item. In addition, for stores that support hierarchical item
// creation, an optional second parameter is accepted that defines what item is the parent
// of the new item and what attribute of that item should the new item be assigned to.
// In general, this will assume that the attribute targetted is multi-valued and a new item
// is appended onto the list of values for that attribute.
// is appended onto the list of values for that attribute.
//
// keywordArgs:
// A javascript object defining the initial content of the item as a set of JavaScript 'property name: value' pairs.
// parentInfo:
// An optional javascript object defining what item is the parent of this item (in a hierarchical store. Not all stores do hierarchical items),
// An optional javascript object defining what item is the parent of this item (in a hierarchical store. Not all stores do hierarchical items),
// and what attribute of that parent to assign the new item to. If this is present, and the attribute specified
// is a multi-valued attribute, it will append this item into the array of values for that attribute. The structure
// of the object is as follows:
@@ -51,7 +52,7 @@ dojo.declare("dojo.data.api.Write", dojo.data.api.Read, {
//
// exceptions:
// Throws an exception if *keywordArgs* is a string or a number or
// anything other than a simple anonymous object.
// anything other than a simple anonymous object.
// Throws an exception if the item in parentInfo is not an item from the store
// or if the attribute isn't an attribute name string.
// example:
@@ -66,11 +67,11 @@ dojo.declare("dojo.data.api.Write", dojo.data.api.Read, {
// summary:
// Deletes an item from the store.
//
// item:
// item:
// The item to delete.
//
// exceptions:
// Throws an exception if the argument *item* is not an item
// Throws an exception if the argument *item* is not an item
// (if store.isItem(item) returns false).
// example:
// | var success = store.deleteItem(kermit);
@@ -78,7 +79,7 @@ dojo.declare("dojo.data.api.Write", dojo.data.api.Read, {
return false; // boolean
},
setValue: function( /* item */ item,
setValue: function( /* item */ item,
/* string */ attribute,
/* almost anything */ value){
// summary:
@@ -103,7 +104,7 @@ dojo.declare("dojo.data.api.Write", dojo.data.api.Read, {
},
setValues: function(/* item */ item,
/* string */ attribute,
/* string */ attribute,
/* array */ values){
// summary:
// Adds each value in the *values* array as a value of the given
@@ -130,7 +131,7 @@ dojo.declare("dojo.data.api.Write", dojo.data.api.Read, {
return false; // boolean
},
unsetAttribute: function( /* item */ item,
unsetAttribute: function( /* item */ item,
/* string */ attribute){
// summary:
// Deletes all the values of an attribute on an item.
@@ -154,9 +155,9 @@ dojo.declare("dojo.data.api.Write", dojo.data.api.Read, {
// summary:
// Saves to the server all the changes that have been made locally.
// The save operation may take some time and is generally performed
// in an asynchronous fashion. The outcome of the save action is
// in an asynchronous fashion. The outcome of the save action is
// is passed into the set of supported callbacks for the save.
//
//
// keywordArgs:
// {
// onComplete: function
@@ -172,7 +173,7 @@ dojo.declare("dojo.data.api.Write", dojo.data.api.Read, {
// are generally passed to the onComplete.
//
// The *onError* parameter.
// function(errorData);
// function(errorData);
//
// If an onError callback function is provided, the callback function
// will be called if there is any sort of error while attempting to
@@ -184,12 +185,12 @@ dojo.declare("dojo.data.api.Write", dojo.data.api.Read, {
// onComplete, onError, etc) will be invoked in the context of the scope
// object. In the body of the callback function, the value of the "this"
// keyword will be the scope object. If no scope object is provided,
// the callback functions will be called in the context of dojo.global.
// For example, onComplete.call(scope) vs.
// the callback functions will be called in the context of dojo.global.
// For example, onComplete.call(scope) vs.
// onComplete.call(dojo.global)
//
// returns:
// Nothing. Since the saves are generally asynchronous, there is
// Nothing. Since the saves are generally asynchronous, there is
// no need to return anything. All results are passed via callbacks.
// example:
// | store.save({onComplete: onSave});
@@ -211,8 +212,8 @@ dojo.declare("dojo.data.api.Write", dojo.data.api.Read, {
isDirty: function(/* item? */ item){
// summary:
// Given an item, isDirty() returns true if the item has been modified
// since the last save(). If isDirty() is called with no *item* argument,
// Given an item, isDirty() returns true if the item has been modified
// since the last save(). If isDirty() is called with no *item* argument,
// then this function returns true if any item has been modified since
// the last save().
//
+6 -4
View File
@@ -1,5 +1,5 @@
/*
Copyright (c) 2004-2010, The Dojo Foundation All Rights Reserved.
Copyright (c) 2004-2011, The Dojo Foundation All Rights Reserved.
Available via Academic Free License >= 2.1 OR the modified BSD license.
see: http://dojotoolkit.org/license for details
*/
@@ -9,12 +9,14 @@ if(!dojo._hasResource["dojo.data.util.filter"]){ //_hasResource checks added by
dojo._hasResource["dojo.data.util.filter"] = true;
dojo.provide("dojo.data.util.filter");
dojo.getObject("data.util.filter", true, dojo);
dojo.data.util.filter.patternToRegExp = function(/*String*/pattern, /*boolean?*/ ignoreCase){
// summary:
// summary:
// Helper function to convert a simple pattern to a regular expression for matching.
// description:
// Returns a regular expression object that conforms to the defined conversion rules.
// For example:
// For example:
// ca* -> /^ca.*$/
// *ca* -> /^.*ca.*$/
// *c\*a* -> /^.*c\*a.*$/
@@ -26,7 +28,7 @@ dojo.data.util.filter.patternToRegExp = function(/*String*/pattern, /*boolean?*/
// * Means match anything, so ca* means match anything starting with ca
// ? Means match single character. So, b?b will match to bob and bab, and so on.
// \ is an escape character. So for example, \* means do not treat * as a match, but literal character *.
// To use a \ as a character in the string, it must be escaped. So in the pattern it should be
// To use a \ as a character in the string, it must be escaped. So in the pattern it should be
// represented by \\ to be treated as an ordinary \ character instead of an escape.
//
// ignoreCase:
+14 -12
View File
@@ -1,5 +1,5 @@
/*
Copyright (c) 2004-2010, The Dojo Foundation All Rights Reserved.
Copyright (c) 2004-2011, The Dojo Foundation All Rights Reserved.
Available via Academic Free License >= 2.1 OR the modified BSD license.
see: http://dojotoolkit.org/license for details
*/
@@ -10,30 +10,32 @@ dojo._hasResource["dojo.data.util.simpleFetch"] = true;
dojo.provide("dojo.data.util.simpleFetch");
dojo.require("dojo.data.util.sorter");
dojo.getObject("data.util.simpleFetch", true, dojo);
dojo.data.util.simpleFetch.fetch = function(/* Object? */ request){
// summary:
// The simpleFetch mixin is designed to serve as a set of function(s) that can
// be mixed into other datastore implementations to accelerate their development.
// The simpleFetch mixin should work well for any datastore that can respond to a _fetchItems()
// be mixed into other datastore implementations to accelerate their development.
// The simpleFetch mixin should work well for any datastore that can respond to a _fetchItems()
// call by returning an array of all the found items that matched the query. The simpleFetch mixin
// is not designed to work for datastores that respond to a fetch() call by incrementally
// loading items, or sequentially loading partial batches of the result
// set. For datastores that mixin simpleFetch, simpleFetch
// set. For datastores that mixin simpleFetch, simpleFetch
// implements a fetch method that automatically handles eight of the fetch()
// arguments -- onBegin, onItem, onComplete, onError, start, count, sort and scope
// The class mixing in simpleFetch should not implement fetch(),
// but should instead implement a _fetchItems() method. The _fetchItems()
// method takes three arguments, the keywordArgs object that was passed
// but should instead implement a _fetchItems() method. The _fetchItems()
// method takes three arguments, the keywordArgs object that was passed
// to fetch(), a callback function to be called when the result array is
// available, and an error callback to be called if something goes wrong.
// The _fetchItems() method should ignore any keywordArgs parameters for
// start, count, onBegin, onItem, onComplete, onError, sort, and scope.
// start, count, onBegin, onItem, onComplete, onError, sort, and scope.
// The _fetchItems() method needs to correctly handle any other keywordArgs
// parameters, including the query parameter and any optional parameters
// (such as includeChildren). The _fetchItems() method should create an array of
// result items and pass it to the fetchHandler along with the original request object
// -- or, the _fetchItems() method may, if it wants to, create an new request object
// with other specifics about the request that are specific to the datastore and pass
// parameters, including the query parameter and any optional parameters
// (such as includeChildren). The _fetchItems() method should create an array of
// result items and pass it to the fetchHandler along with the original request object
// -- or, the _fetchItems() method may, if it wants to, create an new request object
// with other specifics about the request that are specific to the datastore and pass
// that as the request object to the handler.
//
// For more information on this specific function, see dojo.data.api.Read.fetch()
+12 -10
View File
@@ -1,5 +1,5 @@
/*
Copyright (c) 2004-2010, The Dojo Foundation All Rights Reserved.
Copyright (c) 2004-2011, The Dojo Foundation All Rights Reserved.
Available via Academic Free License >= 2.1 OR the modified BSD license.
see: http://dojotoolkit.org/license for details
*/
@@ -9,11 +9,13 @@ if(!dojo._hasResource["dojo.data.util.sorter"]){ //_hasResource checks added by
dojo._hasResource["dojo.data.util.sorter"] = true;
dojo.provide("dojo.data.util.sorter");
dojo.data.util.sorter.basicComparator = function( /*anything*/ a,
dojo.getObject("data.util.sorter", true, dojo);
dojo.data.util.sorter.basicComparator = function( /*anything*/ a,
/*anything*/ b){
// summary:
// summary:
// Basic comparision function that compares if an item is greater or less than another item
// description:
// description:
// returns 1 if a > b, -1 if a < b, 0 if equal.
// 'null' values (null, undefined) are treated as larger values so that they're pushed to the end of the list.
// And compared to each other, null is equivalent to undefined.
@@ -30,18 +32,18 @@ dojo.data.util.sorter.basicComparator = function( /*anything*/ a,
b = undefined;
}
if(a == b){
r = 0;
r = 0;
}else if(a > b || a == null){
r = 1;
r = 1;
}
return r; //int {-1,0,1}
};
dojo.data.util.sorter.createSortFunction = function( /* attributes array */sortSpec,
/*dojo.data.core.Read*/ store){
// summary:
// summary:
// Helper function to generate the sorting function based off the list of sort attributes.
// description:
// description:
// The sort function creation will look for a property on the store called 'comparatorMap'. If it exists
// it will look in the mapping for comparisons function for the attributes. If one is found, it will
// use it instead of the basic comparator, which is typically used for strings, ints, booleans, and dates.
@@ -83,7 +85,7 @@ dojo.data.util.sorter.createSortFunction = function( /* attributes array */sortS
}
comp = map[attr] || bc;
}
sortFunctions.push(createSortFunction(attr,
sortFunctions.push(createSortFunction(attr,
dir, comp, store));
}
}
@@ -95,7 +97,7 @@ dojo.data.util.sorter.createSortFunction = function( /* attributes array */sortS
return ret;//int
}
}
return 0; //int
return 0; //int
}; // Function
};