diff --git a/CHANGELOG.md b/CHANGELOG.md index 6b397a57..48e7d953 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,14 @@ # offline-editor-js - Changelog +## Version 3.0.6 - March 3, 2016 + +No breaking changes + +**Bug Fixes** + +* Closes #448 - OfflineEditAdvanced - after multiple offline restarts, UID begins at -1 again for Adds. + + ## Version 3.0.5 - Feb 2, 2016 No breaking changes. Documentation updates only. @@ -541,4 +550,4 @@ Deprecations: ## Version 1 - Sep 19. 2013 -- Initial commit. \ No newline at end of file +- Initial commit. diff --git a/Gruntfile.js b/Gruntfile.js index c906e075..4fc765f8 100644 --- a/Gruntfile.js +++ b/Gruntfile.js @@ -117,7 +117,7 @@ module.exports = function(grunt) { beautify: { semicolons: false //Required: prevents dojo parser errors w/ minified files in this project }, - preserveComments: 'some', + // preserveComments: 'some', wrap: false // mangle: { // except: ['O'] diff --git a/dist/offline-edit-advanced-min.js b/dist/offline-edit-advanced-min.js index 68baa293..deb2fa7b 100644 --- a/dist/offline-edit-advanced-min.js +++ b/dist/offline-edit-advanced-min.js @@ -1,6 +1,3 @@ -/*! esri-offline-maps - v3.0.3 - 2015-11-30 -* Copyright (c) 2015 Environmental Systems Research Institute, Inc. -* Apache License*/ Offline.options={checks:{image:{url:function(){return"http://esri.github.io/offline-editor-js/tiny-image.png?_="+Math.floor(1e9*Math.random())}},active:"image"}},define(["dojo/Evented","dojo/_base/Deferred","dojo/promise/all","dojo/_base/declare","dojo/_base/array","dojo/dom-attr","dojo/dom-style","dojo/query","esri/config","esri/layers/GraphicsLayer","esri/graphic","esri/request","esri/symbols/SimpleMarkerSymbol","esri/symbols/SimpleLineSymbol","esri/symbols/SimpleFillSymbol","esri/urlUtils"],function(a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p){"use strict" return d("O.esri.Edit.OfflineEditAdvanced",[a],{_onlineStatus:"online",_featureLayers:{},_featureCollectionUsageFlag:!1,_editStore:new O.esri.Edit.EditStore,_defaultXhrTimeout:15e3,ONLINE:"online",OFFLINE:"offline",RECONNECTING:"reconnecting",attachmentsStore:null,proxyPath:null,ENABLE_FEATURECOLLECTION:!1,DB_NAME:"features_store",DB_OBJECTSTORE_NAME:"features",DB_UID:"objectid",ATTACHMENTS_DB_NAME:"attachments_store",ATTACHMENTS_DB_OBJECTSTORE_NAME:"attachments",events:{EDITS_SENT:"edits-sent",EDITS_ENQUEUED:"edits-enqueued",EDITS_ENQUEUED_ERROR:"edits-enqueued-error",EDITS_SENT_ERROR:"edits-sent-error",ALL_EDITS_SENT:"all-edits-sent",ATTACHMENT_ENQUEUED:"attachment-enqueued",ATTACHMENTS_SENT:"attachments-sent"},initAttachments:function(a){if(a=a||function(a){},!this._checkFileAPIs())return a(!1,"File APIs not supported") try{if(this.attachmentsStore=new O.esri.Edit.AttachmentsStore,this.attachmentsStore.dbName=this.ATTACHMENTS_DB_NAME,this.attachmentsStore.objectStoreName=this.ATTACHMENTS_DB_OBJECTSTORE_NAME,!this.attachmentsStore.isSupported())return a(!1,"indexedDB not supported") @@ -82,7 +79,7 @@ return n._editStore.deletePhantomGraphic(h,function(b){b?a.resolve(!0):a.resolve c([f(),g()]).then(function(a){e(a)})},a._getFilesFromForm=function(a){var b=[],c=e.filter(a.elements,function(a){return"file"===a.type}) return c.forEach(function(a){b.push.apply(b,a.files)},this),b},a._replaceFeatureIds=function(a,b,c){a.length||c(0) var d,e=a.length,f=e,g=0 -for(d=0;e>d;d++)n.attachmentsStore.replaceFeatureId(this.url,a[d],b[d],function(a){--f,g+=a?1:0,0===f&&c(g)}.bind(this))},a._nextTempId=-1,a._getNextTempId=function(){return this._nextTempId--},l(),c(m).then(function(b){0===b.length&&o?this.ENABLE_FEATURECOLLECTION?a._pushFeatureCollections(function(a){a?d(!0,null):d(!1,null)}):d(!0,null):b[0].success&&!o?this._editStore.getFeatureLayerJSON(function(b,c){b?(this._featureLayers[c.__featureLayerURL]=a,a.url=c.__featureLayerURL,this.ENABLE_FEATURECOLLECTION?a._pushFeatureCollections(function(a){a?d(!0,null):d(!1,null)}):d(!0,null)):d(!1,c)}.bind(this)):b[0].success&&(this.ENABLE_FEATURECOLLECTION?a._pushFeatureCollections(function(a){a?d(!0,null):d(!1,null)}):d(!0,null))}.bind(this))},goOffline:function(){this._onlineStatus=this.OFFLINE},goOnline:function(a){this._onlineStatus=this.RECONNECTING,this._replayStoredEdits(function(b,c){var d={success:b,responses:c} +for(d=0;e>d;d++)n.attachmentsStore.replaceFeatureId(this.url,a[d],b[d],function(a){--f,g+=a?1:0,0===f&&c(g)}.bind(this))},this._editStore.getNextLowestTempId(a,function(b,c){"success"===c?a._nextTempId=b:a._nextTempId=-1}),a._getNextTempId=function(){return this._nextTempId--},l(),c(m).then(function(b){0===b.length&&o?this.ENABLE_FEATURECOLLECTION?a._pushFeatureCollections(function(a){a?d(!0,null):d(!1,null)}):d(!0,null):b[0].success&&!o?this._editStore.getFeatureLayerJSON(function(b,c){b?(this._featureLayers[c.__featureLayerURL]=a,a.url=c.__featureLayerURL,this.ENABLE_FEATURECOLLECTION?a._pushFeatureCollections(function(a){a?d(!0,null):d(!1,null)}):d(!0,null)):d(!1,c)}.bind(this)):b[0].success&&(this.ENABLE_FEATURECOLLECTION?a._pushFeatureCollections(function(a){a?d(!0,null):d(!1,null)}):d(!0,null))}.bind(this))},goOffline:function(){this._onlineStatus=this.OFFLINE},goOnline:function(a){this._onlineStatus=this.RECONNECTING,this._replayStoredEdits(function(b,c){var d={success:b,responses:c} this._onlineStatus=this.ONLINE,null!=this.attachmentsStore?this._sendStoredAttachments(function(b,c,e){d.attachments={success:b,responses:c,dbResponses:e},a&&a(d)}.bind(this)):a&&a(d)}.bind(this))},getOnlineStatus:function(){return this._onlineStatus},serializeFeatureGraphicsArray:function(a,b){for(var c=a.length,d=[],e=0;c>e;e++){var f=a[e].toJson() if(d.push(f),e==c-1){var g=JSON.stringify(d) b(g) @@ -131,7 +128,7 @@ n.open("POST",a.url+"/applyEdits",!0),n.setRequestHeader("Content-type","applica f(a.addResults,a.updateResults,a.deleteResults)}catch(b){g("Unable to parse xhr response",n)}},n.onerror=function(a){g(a)},n.ontimeout=function(){g("xhr timeout error")},n.timeout=this._defaultXhrTimeout,n.send(m)},_parseResponsesArray:function(a){var c=new b,d=0 for(var e in a)a.hasOwnProperty(e)&&(a[e].addResults.map(function(a){a.success||d++}),a[e].updateResults.map(function(a){a.success||d++}),a[e].deleteResults.map(function(a){a.success||d++})) return d>0?c.resolve(!1):c.resolve(!0),c.promise}})}),"undefined"!=typeof O?O.esri.Edit={}:(O={},O.esri={Edit:{}}),O.esri.Edit.EditStore=function(){"use strict" -this._db=null,this._isDBInit=!1,this.dbName="features_store",this.objectStoreName="features",this.objectId="objectid",this.ADD="add",this.UPDATE="update",this.DELETE="delete",this.FEATURE_LAYER_JSON_ID="feature-layer-object-1001",this.FEATURE_COLLECTION_ID="feature-collection-object-1001",this.PHANTOM_GRAPHIC_PREFIX="phantom-layer",this._PHANTOM_PREFIX_TOKEN="|@|",this.isSupported=function(){return window.indexedDB?!0:!1},this.pushEdit=function(a,b,c,d){var e={id:b+"/"+c.attributes[this.objectId],operation:a,layer:b,type:c.geometry.type,graphic:c.toJson()} +this._db=null,this._isDBInit=!1,this.dbName="features_store",this.objectStoreName="features",this.objectId="objectid",this.ADD="add",this.UPDATE="update",this.DELETE="delete",this.FEATURE_LAYER_JSON_ID="feature-layer-object-1001",this.FEATURE_COLLECTION_ID="feature-collection-object-1001",this.PHANTOM_GRAPHIC_PREFIX="phantom-layer",this._PHANTOM_PREFIX_TOKEN="|@|",this.isSupported=function(){return!!window.indexedDB},this.pushEdit=function(a,b,c,d){var e={id:b+"/"+c.attributes[this.objectId],operation:a,layer:b,type:c.geometry.type,graphic:c.toJson()} if("undefined"==typeof c.attributes[this.objectId])d(!1,"editsStore.pushEdit() - failed to insert undefined objectId into database. Did you set offlineEdit.DB_UID? "+JSON.stringify(c.attributes)) else{var f=this._db.transaction([this.objectStoreName],"readwrite") f.oncomplete=function(a){d(!0)},f.onerror=function(a){d(!1,a.target.error.message)} @@ -169,7 +166,13 @@ var d=c.get(a) d.onsuccess=function(){var c=d.result c&&c.id==a?b(!0,c):b(!1,"Id not found")},d.onerror=function(a){b(!1,a)}},this.getAllEdits=function(a){if(null!==this._db){var b=this.FEATURE_LAYER_JSON_ID,c=this.FEATURE_COLLECTION_ID,d=this.PHANTOM_GRAPHIC_PREFIX,e=this._db.transaction([this.objectStoreName]).objectStore(this.objectStoreName).openCursor() e.onsuccess=function(e){var f=e.target.result -f&&f.hasOwnProperty("value")&&f.value.hasOwnProperty("id")?(f.value.id!==b&&f.value.id!==c&&-1==f.value.id.indexOf(d)&&a(f.value,null),f["continue"]()):a(null,"end")}.bind(this),e.onerror=function(b){a(null,b)}}else a(null,"no db")},this.getAllEditsArray=function(a){var b=[] +f&&f.hasOwnProperty("value")&&f.value.hasOwnProperty("id")?(f.value.id!==b&&f.value.id!==c&&-1==f.value.id.indexOf(d)&&a(f.value,null),f["continue"]()):a(null,"end")}.bind(this),e.onerror=function(b){a(null,b)}}else a(null,"no db")},this.getNextLowestTempId=function(a,b){var c=[],d=this +if(null!==this._db){var e=this.FEATURE_LAYER_JSON_ID,f=this.FEATURE_COLLECTION_ID,g=this.PHANTOM_GRAPHIC_PREFIX,h=this._db.transaction([this.objectStoreName]).objectStore(this.objectStoreName).openCursor() +h.onsuccess=function(h){var i=h.target.result +if(i&&i.value&&i.value.id)i.value.id!==e&&i.value.id!==f&&-1==i.value.id.indexOf(g)&&i.value.layer===a.url&&"add"===i.value.operation&&c.push(i.value.graphic.attributes[d.objectId]),i["continue"]() +else if(0===c.length)b(-1,"success") +else{var j=c.filter(function(a){return!isNaN(a)}),k=Math.min.apply(Math,j) +b(k--,"success")}}.bind(this),h.onerror=function(a){b(null,a)}}else b(null,"no db")},this.getAllEditsArray=function(a){var b=[] if(null!==this._db){var c=this.FEATURE_LAYER_JSON_ID,d=this.FEATURE_COLLECTION_ID,e=this.PHANTOM_GRAPHIC_PREFIX,f=this._db.transaction([this.objectStoreName]).objectStore(this.objectStoreName).openCursor() f.onsuccess=function(f){var g=f.target.result g&&g.value&&g.value.id?(g.value.id!==c&&g.value.id!==d&&-1==g.value.id.indexOf(e)&&b.push(g.value),g["continue"]()):a(b,"end")}.bind(this),f.onerror=function(b){a(null,b)}}else a(null,"no db")},this.updateExistingEdit=function(a,b,c,d){var e=this._db.transaction([this.objectStoreName],"readwrite").objectStore(this.objectStoreName),f=e.get(c.attributes[this.objectId]) @@ -196,7 +199,7 @@ c.onsuccess=function(){var b=c.result "undefined"!=typeof b?a(!0,b):a(!1,null)},c.onerror=function(b){a(!1,b)}},this.init=function(a){var b=indexedDB.open(this.dbName,11) a=a||function(a){}.bind(this),b.onerror=function(b){a(!1,b.target.errorCode)}.bind(this),b.onupgradeneeded=function(a){var b=a.target.result b.objectStoreNames.contains(this.objectStoreName)&&b.deleteObjectStore(this.objectStoreName),b.createObjectStore(this.objectStoreName,{keyPath:"id"})}.bind(this),b.onsuccess=function(b){this._db=b.target.result,this._isDBInit=!0,a(!0,null)}.bind(this)}},O.esri.Edit.AttachmentsStore=function(){"use strict" -this._db=null,this.dbName="attachments_store",this.objectStoreName="attachments",this.TYPE={ADD:"add",UPDATE:"update",DELETE:"delete"},this.isSupported=function(){return window.indexedDB?!0:!1},this.store=function(a,b,c,d,e,f){try{e==this.TYPE.ADD||e==this.TYPE.UPDATE||e==this.TYPE.DELETE?this._readFile(d,function(g,h){if(g){var i={id:b,objectId:c,type:e,featureId:a+"/"+c,contentType:d.type,name:d.name,size:d.size,featureLayerUrl:a,content:h,file:d},j=this._db.transaction([this.objectStoreName],"readwrite") +this._db=null,this.dbName="attachments_store",this.objectStoreName="attachments",this.TYPE={ADD:"add",UPDATE:"update",DELETE:"delete"},this.isSupported=function(){return!!window.indexedDB},this.store=function(a,b,c,d,e,f){try{e==this.TYPE.ADD||e==this.TYPE.UPDATE||e==this.TYPE.DELETE?this._readFile(d,function(g,h){if(g){var i={id:b,objectId:c,type:e,featureId:a+"/"+c,contentType:d.type,name:d.name,size:d.size,featureLayerUrl:a,content:h,file:d},j=this._db.transaction([this.objectStoreName],"readwrite") j.oncomplete=function(a){f(!0,i)},j.onerror=function(a){f(!1,a.target.error.message)} try{j.objectStore(this.objectStoreName).put(i)}catch(k){f(!1,k)}}else f(!1,h)}.bind(this)):f(!1,"attachmentsStore.store() Invalid type in the constructor!")}catch(g){f(!1,g.stack)}},this.retrieve=function(a,b){var c=this._db.transaction([this.objectStoreName]).objectStore(this.objectStoreName),d=c.get(a) d.onsuccess=function(a){var c=a.target.result diff --git a/dist/offline-edit-advanced-src.js b/dist/offline-edit-advanced-src.js index db393422..2b0b47fb 100644 --- a/dist/offline-edit-advanced-src.js +++ b/dist/offline-edit-advanced-src.js @@ -1,5 +1,5 @@ -/*! esri-offline-maps - v3.0.3 - 2015-11-30 -* Copyright (c) 2015 Environmental Systems Research Institute, Inc. +/*! esri-offline-maps - v3.0.6 - 2016-03-03 +* Copyright (c) 2016 Environmental Systems Research Institute, Inc. * Apache License*/ // Configure offline/online detection // Requires: http://github.hubspot.com/offline/docs/welcome/ @@ -1166,7 +1166,19 @@ define([ // we need to identify ADDs before sending them to the server // we assign temporary ids (using negative numbers to distinguish them from real ids) - layer._nextTempId = -1; + // query the database first to find any existing offline adds, and find the next lowest integer to start with. + this._editStore.getNextLowestTempId(layer, function(value, status){ + if(status === "success"){ + console.log("_nextTempId:", value); + layer._nextTempId = value; + } + else{ + console.log("_nextTempId, not success:", value); + layer._nextTempId = -1; + console.debug(layer._nextTempId); + } + }); + layer._getNextTempId = function () { return this._nextTempId--; }; @@ -2673,6 +2685,58 @@ O.esri.Edit.EditStore = function () { } }; + /* + * Query the database, looking for any existing Add temporary OIDs, and return the nextTempId to be used. + * @param feature - extended layer from offline edit advanced + * @param callback {int, messageString} or {null, messageString} + */ + this.getNextLowestTempId = function (feature, callback) { + var addOIDsArray = [], + self = this; + + if (this._db !== null) { + + var fLayerJSONId = this.FEATURE_LAYER_JSON_ID; + var fCollectionId = this.FEATURE_COLLECTION_ID; + var phantomGraphicPrefix = this.PHANTOM_GRAPHIC_PREFIX; + + var transaction = this._db.transaction([this.objectStoreName]) + .objectStore(this.objectStoreName) + .openCursor(); + + transaction.onsuccess = function (event) { + var cursor = event.target.result; + if (cursor && cursor.value && cursor.value.id) { + // Make sure we are not return FeatureLayer JSON data or a Phantom Graphic + if (cursor.value.id !== fLayerJSONId && cursor.value.id !== fCollectionId && cursor.value.id.indexOf(phantomGraphicPrefix) == -1) { + if(cursor.value.layer === feature.url && cursor.value.operation === "add"){ // check to make sure the edit is for the feature we are looking for, and that the operation is an add. + addOIDsArray.push(cursor.value.graphic.attributes[self.objectId]); // add the temporary OID to the array + } + } + cursor.continue(); + } + else { + if(addOIDsArray.length === 0){ // if we didn't find anything, + callback(-1, "success"); // we'll start with -1 + } + else{ + var filteredOIDsArray = addOIDsArray.filter(function(val){ // filter out any non numbers from the array... + return !isNaN(val); // .. should anything have snuck in or returned a NaN + }); + var lowestTempId = Math.min.apply(Math, filteredOIDsArray); // then find the lowest number from the array + callback(lowestTempId--, "success"); // and we'll start with one less than tat. + } + } + }.bind(this); + transaction.onerror = function (err) { + callback(null, err); + }; + } + else { + callback(null, "no db"); + } + }, + /** * Returns all the edits as a single Array via the callback * @param callback {array, messageString} or {null, messageString} diff --git a/dist/offline-edit-basic-min.js b/dist/offline-edit-basic-min.js index 1a134316..764596be 100644 --- a/dist/offline-edit-basic-min.js +++ b/dist/offline-edit-basic-min.js @@ -1,6 +1,3 @@ -/*! esri-offline-maps - v3.0.3 - 2015-11-30 -* Copyright (c) 2015 Environmental Systems Research Institute, Inc. -* Apache License*/ Offline.options={checks:{image:{url:function(){return"http://esri.github.io/offline-editor-js/tiny-image.png?_="+Math.floor(1e9*Math.random())}},active:"image"}},define(["dojo/Evented","dojo/_base/Deferred","dojo/promise/all","dojo/_base/declare","dojo/_base/array","dojo/dom-attr","dojo/dom-style","dojo/query","dojo/on","esri/config","esri/layers/GraphicsLayer","esri/layers/FeatureLayer","esri/graphic"],function(a,b,c,d,e,f,g,h,i,j,k,l,m){"use strict" return d("O.esri.Edit.OfflineEditBasic",[a],{_onlineStatus:"online",_featureLayers:{},_editStore:new O.esri.Edit.EditStorePOLS,_defaultXhrTimeout:15e3,_autoOfflineDetect:!0,ONLINE:"online",OFFLINE:"offline",RECONNECTING:"reconnecting",proxyPath:null,DB_NAME:"features_store",DB_OBJECTSTORE_NAME:"features",DB_UID:"objectid",events:{EDITS_SENT:"edits-sent",EDITS_ENQUEUED:"edits-enqueued",EDITS_ENQUEUED_ERROR:"edits-enqueued-error"},constructor:function(a){a&&a.hasOwnProperty("autoDetect")&&(this._autoOfflineDetect=a.autoDetect)},extend:function(a,d){var f=[],g=this a.offlineExtended=!0,!a.loaded||null===a._url,a.objectIdField=this.DB_UID @@ -33,7 +30,7 @@ case g._editStore.UPDATE:d.operation==g._editStore.ADD&&(c.operation=g._editStor break case g._editStore.DELETE:var h=!0 d.operation==g._editStore.ADD&&a._deleteTemporaryFeature(c,function(a,b){a||(h=!1)}),f.resolve({success:h,graphic:c,operation:e})}else"Id not found"==d?f.resolve({success:!0,graphic:c,operation:e}):f.reject(c)}),f},a._deleteTemporaryFeature=function(b,c){g._editStore["delete"](a.url,b,function(a,b){c(a,b)})},a._getFilesFromForm=function(a){var b=[],c=e.filter(a.elements,function(a){return"file"===a.type}) -return c.forEach(function(a){b.push.apply(b,a.files)},this),b},a._nextTempId=-1,a._getNextTempId=function(){return this._nextTempId--},c(f).then(function(a){g._autoOfflineDetect&&(Offline.on("up",function(){g.goOnline(function(a,b){})}),Offline.on("down",function(){g.goOffline()})),d(!0,null)})},goOffline:function(){this._onlineStatus=this.OFFLINE},goOnline:function(a){this._onlineStatus=this.RECONNECTING,this._replayStoredEdits(function(b,c){this._onlineStatus=this.ONLINE,a&&a(b,c)}.bind(this))},getOnlineStatus:function(){return this._onlineStatus},_initializeDB:function(a){var c=new b,d=this._editStore +return c.forEach(function(a){b.push.apply(b,a.files)},this),b},this._editStore.getNextLowestTempId(a,function(b,c){"success"===c?a._nextTempId=b:a._nextTempId=-1}),a._getNextTempId=function(){return this._nextTempId--},c(f).then(function(a){g._autoOfflineDetect&&(Offline.on("up",function(){g.goOnline(function(a,b){})}),Offline.on("down",function(){g.goOffline()})),d(!0,null)})},goOffline:function(){this._onlineStatus=this.OFFLINE},goOnline:function(a){this._onlineStatus=this.RECONNECTING,this._replayStoredEdits(function(b,c){this._onlineStatus=this.ONLINE,a&&a(b,c)}.bind(this))},getOnlineStatus:function(){return this._onlineStatus},_initializeDB:function(a){var c=new b,d=this._editStore return d.dbName=this.DB_NAME,d.objectStoreName=this.DB_OBJECTSTORE_NAME,d.objectId=this.DB_UID,d.init(function(a,b){a?c.resolve({success:!0,error:null}):c.reject({success:!1,error:null})}),c},_replayStoredEdits:function(a){var b,d={},e=this,f=[],g=[],h=[],i=[],j=[],k=this._featureLayers,l=this._editStore this._editStore.getAllEditsArray(function(n,o){if(n.length>0){j=n for(var p=j.length,q=0;p>q;q++){b=k[j[q].layer],b.__onEditsComplete=b.onEditsComplete,b.onEditsComplete=function(){},f=[],g=[],h=[],i=[] @@ -63,8 +60,8 @@ var n=new XMLHttpRequest n.open("POST",a.url+"/applyEdits",!0),n.setRequestHeader("Content-type","application/x-www-form-urlencoded"),n.onload=function(){if(200===n.status&&""!==n.responseText)try{var a=JSON.parse(this.response) f(a.addResults,a.updateResults,a.deleteResults)}catch(b){g("Unable to parse xhr response",n)}},n.onerror=function(a){g(a)},n.ontimeout=function(){g("xhr timeout error")},n.timeout=this._defaultXhrTimeout,n.send(m)},_parseResponsesArray:function(a,b){var c=0 for(var d in a)a.hasOwnProperty(d)&&(a[d].addResults.forEach(function(a){a.success||c++}),a[d].updateResults.forEach(function(a){a.success||c++}),a[d].deleteResults.forEach(function(a){a.success||c++})) -b(c>0?!1:!0)}})}),"undefined"!=typeof O?O.esri.Edit={}:(O={},O.esri={Edit:{}}),O.esri.Edit.EditStorePOLS=function(){"use strict" -this._db=null,this._isDBInit=!1,this.dbName="features_store",this.objectStoreName="features",this.objectId="objectid",this.ADD="add",this.UPDATE="update",this.DELETE="delete",this.FEATURE_LAYER_JSON_ID="feature-layer-object-1001",this.FEATURE_COLLECTION_ID="feature-collection-object-1001",this.isSupported=function(){return window.indexedDB?!0:!1},this.pushEdit=function(a,b,c,d){var e={id:b+"/"+c.attributes[this.objectId],operation:a,layer:b,type:c.geometry.type,graphic:c.toJson()} +b(!(c>0))}})}),"undefined"!=typeof O?O.esri.Edit={}:(O={},O.esri={Edit:{}}),O.esri.Edit.EditStorePOLS=function(){"use strict" +this._db=null,this._isDBInit=!1,this.dbName="features_store",this.objectStoreName="features",this.objectId="objectid",this.ADD="add",this.UPDATE="update",this.DELETE="delete",this.FEATURE_LAYER_JSON_ID="feature-layer-object-1001",this.FEATURE_COLLECTION_ID="feature-collection-object-1001",this.isSupported=function(){return!!window.indexedDB},this.pushEdit=function(a,b,c,d){var e={id:b+"/"+c.attributes[this.objectId],operation:a,layer:b,type:c.geometry.type,graphic:c.toJson()} if("undefined"==typeof c.attributes[this.objectId])d(!1,"editsStore.pushEdit() - failed to insert undefined objectId into database. Did you set offlineEdit.DB_UID? "+JSON.stringify(c.attributes)) else{var f=this._db.transaction([this.objectStoreName],"readwrite") f.oncomplete=function(a){d(!0)},f.onerror=function(a){d(!1,a.target.error.message)} diff --git a/dist/offline-edit-basic-src.js b/dist/offline-edit-basic-src.js index ab98a754..280b72e5 100644 --- a/dist/offline-edit-basic-src.js +++ b/dist/offline-edit-basic-src.js @@ -1,5 +1,5 @@ -/*! esri-offline-maps - v3.0.3 - 2015-11-30 -* Copyright (c) 2015 Environmental Systems Research Institute, Inc. +/*! esri-offline-maps - v3.0.6 - 2016-03-03 +* Copyright (c) 2016 Environmental Systems Research Institute, Inc. * Apache License*/ // Configure offline/online detection // Requires: http://github.hubspot.com/offline/docs/welcome/ @@ -504,7 +504,19 @@ define([ // we need to identify ADDs before sending them to the server // we assign temporary ids (using negative numbers to distinguish them from real ids) - layer._nextTempId = -1; + // query the database first to find any existing offline adds, and find the next lowest integer to start with. + this._editStore.getNextLowestTempId(layer, function(value, status){ + if(status === "success"){ + console.log("_nextTempId:", value); + layer._nextTempId = value; + } + else{ + console.log("_nextTempId, not success:", value); + layer._nextTempId = -1; + console.debug(layer._nextTempId); + } + }); + layer._getNextTempId = function () { return this._nextTempId--; }; diff --git a/dist/offline-tiles-advanced-min.js b/dist/offline-tiles-advanced-min.js index 35aa0183..22306d7a 100644 --- a/dist/offline-tiles-advanced-min.js +++ b/dist/offline-tiles-advanced-min.js @@ -1,10 +1,7 @@ -/*! esri-offline-maps - v3.0.3 - 2015-11-30 -* Copyright (c) 2015 Environmental Systems Research Institute, Inc. -* Apache License*/ define(["dojo/query","dojo/request","dojo/_base/declare","esri/layers/LOD","esri/geometry/Point","esri/geometry/Extent","esri/layers/TileInfo","esri/SpatialReference","esri/geometry/Polygon","esri/layers/TiledMapServiceLayer"],function(a,b,c,d,e,f,g,h,i,j){"use strict" return c("O.esri.Tiles.OfflineTilesAdvanced",[j],{tileInfo:null,_imageType:"",_level:null,_minZoom:null,_maxZoom:null,_tilesCore:null,_secure:!1,constructor:function(a,b,c,d){this._isLocalStorage()===!1?(alert("OfflineTiles Library not supported on this browser."),b(!1)):window.localStorage.offline_id_manager="",void 0===d||null===d?(this.DB_NAME="offline_tile_store",this.DB_OBJECTSTORE_NAME="tilepath"):(this.DB_NAME=d.dbName,this.DB_OBJECTSTORE_NAME=d.objectStoreName),this._tilesCore=new O.esri.Tiles.TilesCore,Array.prototype.sortNumber=function(){return this.sort(function(a,b){return a-b})},this._self=this,this._lastTileUrl="",this._imageType="",this._getTileUrl=this.getTileUrl var e=!0 -return("undefined"!=typeof c||null!=c)&&(e=c),this.showBlankTiles=!0,this.offline={online:e,store:new O.esri.Tiles.TilesStore,proxyPath:null},this.offline.store.isSupported()?(this.offline.store.dbName=this.DB_NAME,this.offline.store.objectStoreName=this.DB_OBJECTSTORE_NAME,this.offline.store.init(function(c){c&&this._getTileInfoPrivate(a,function(a){b(a)})}.bind(this._self)),void 0):b(!1,"indexedDB not supported")},getTileUrl:function(b,c,d){this._level=b +return"undefined"==typeof c&&null==c||(e=c),this.showBlankTiles=!0,this.offline={online:e,store:new O.esri.Tiles.TilesStore,proxyPath:null},this.offline.store.isSupported()?(this.offline.store.dbName=this.DB_NAME,this.offline.store.objectStoreName=this.DB_OBJECTSTORE_NAME,this.offline.store.init(function(c){c&&this._getTileInfoPrivate(a,function(a){b(a)})}.bind(this._self)),void 0):b(!1,"indexedDB not supported")},getTileUrl:function(b,c,d){this._level=b var e,f=this,g=window.localStorage.offline_id_manager if(void 0===g||""===g)e="" else{var h=JSON.parse(g) @@ -27,19 +24,18 @@ if(void 0===f||""===f)c="" else{var g=JSON.parse(f) g.credentials.forEach(function(b){-1!==a.indexOf(b.server)&&(c="&token="+b.token)})}var h=null!=d.offline.proxyPath?d.offline.proxyPath+"?"+a+"?f=pjson"+c:a+"?f=pjson"+c e.open("GET",h,!0),e.onload=function(){if(200===e.status&&""!==e.responseText){var c=this.response,f=this.response.replace(/\\'/g,"'"),g=JSON.parse(f) -"error"in g?"code"in g.error&&(499==g.error.code||498==g.error.code)&&require(["esri/IdentityManager"],function(c){var e=c.findCredential(a) -void 0===e?c.getCredential(a).then(function(){d._secure=!0,window.localStorage.offline_id_manager=JSON.stringify(c.toJson()),d._getTileInfoPrivate(a,b)}):d._getTileInfoPrivate(a,b)}):d._parseTileInfo(c,d,b)}else b(!1)},e.onerror=function(a){b(!1)},e.send(null)}})}),"undefined"!=typeof O?O.esri.Tiles={}:(O={},O.esri={Tiles:{}}),O.esri.Tiles.Base64Utils={},O.esri.Tiles.Base64Utils.outputTypes={Base64:0,Hex:1,String:2,Raw:3},O.esri.Tiles.Base64Utils.addWords=function(a,b){var c=(65535&a)+(65535&b),d=(a>>16)+(b>>16)+(c>>16) +"error"in g?"code"in g.error&&(499!=g.error.code&&498!=g.error.code||require(["esri/IdentityManager"],function(c){var e=c.findCredential(a) +void 0===e?c.getCredential(a).then(function(){d._secure=!0,window.localStorage.offline_id_manager=JSON.stringify(c.toJson()),d._getTileInfoPrivate(a,b)}):d._getTileInfoPrivate(a,b)})):d._parseTileInfo(c,d,b)}else b(!1)},e.onerror=function(a){b(!1)},e.send(null)}})}),"undefined"!=typeof O?O.esri.Tiles={}:(O={},O.esri={Tiles:{}}),O.esri.Tiles.Base64Utils={},O.esri.Tiles.Base64Utils.outputTypes={Base64:0,Hex:1,String:2,Raw:3},O.esri.Tiles.Base64Utils.addWords=function(a,b){var c=(65535&a)+(65535&b),d=(a>>16)+(b>>16)+(c>>16) return d<<16|65535&c},O.esri.Tiles.Base64Utils.stringToWord=function(a){for(var b=8,c=(1<e;e+=b)d[e>>5]|=(a.charCodeAt(e/b)&c)<e;e+=b)d.push(String.fromCharCode(a[e>>5]>>>e%32&c)) return d.join("")},O.esri.Tiles.Base64Utils.wordToHex=function(a){for(var b="0123456789abcdef",c=[],d=0,e=4*a.length;e>d;d++)c.push(b.charAt(a[d>>2]>>d%4*8+4&15)+b.charAt(a[d>>2]>>d%4*8&15)) return c.join("")},O.esri.Tiles.Base64Utils.wordToBase64=function(a){for(var b="=",c="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/",d=[],e=0,f=4*a.length;f>e;e+=3)for(var g=(a[e>>2]>>8*(e%4)&255)<<16|(a[e+1>>2]>>8*((e+1)%4)&255)<<8|a[e+2>>2]>>8*((e+2)%4)&255,h=0;4>h;h++)8*e+6*h>32*a.length?d.push(b):d.push(c.charAt(g>>6*(3-h)&63)) -return d.join("")},/*! @source http://purl.eligrey.com/github/FileSaver.js/blob/master/FileSaver.js */ -O.esri.Tiles.saveAs=function(a){"use strict" +return d.join("")},O.esri.Tiles.saveAs=function(a){"use strict" var b=a.document,c=function(){return a.URL||a.webkitURL||a},d=a.URL||a.webkitURL||a,e=b.createElementNS("http://www.w3.org/1999/xhtml","a"),f=!a.externalHost&&"download"in e,g=a.webkitRequestFileSystem,h=a.requestFileSystem||g||a.mozRequestFileSystem,i=function(b){(a.setImmediate||a.setTimeout)(function(){throw b},0)},j="application/octet-stream",k=0,l=[],m=function(){for(var a=l.length;a--;){var b=l[a] "string"==typeof b?d.revokeObjectURL(b):b.remove()}l.length=0},n=function(a,b,c){b=[].concat(b) for(var d=b.length;d--;){var e=a["on"+b[d]] if("function"==typeof e)try{e.call(a,c||a)}catch(f){i(f)}}},o=function(d,i){var m,o,p,q=this,r=d.type,s=!1,t=function(){var a=c().createObjectURL(d) -return l.push(a),a},u=function(){n(q,"writestart progress write writeend".split(" "))},v=function(){(s||!m)&&(m=t(d)),o?o.location.href=m:window.open(m,"_blank"),q.readyState=q.DONE,u()},w=function(a){return function(){return q.readyState!==q.DONE?a.apply(this,arguments):void 0}},x={create:!0,exclusive:!1} +return l.push(a),a},u=function(){n(q,"writestart progress write writeend".split(" "))},v=function(){!s&&m||(m=t(d)),o?o.location.href=m:window.open(m,"_blank"),q.readyState=q.DONE,u()},w=function(a){return function(){return q.readyState!==q.DONE?a.apply(this,arguments):void 0}},x={create:!0,exclusive:!1} if(q.readyState=q.INIT,i||(i="download"),f){m=t(d),b=a.document,e=b.createElementNS("http://www.w3.org/1999/xhtml","a"),e.href=m,e.download=i var y=b.createEvent("MouseEvents") return y.initMouseEvent("click",!0,!1,a,0,0,0,0,0,!1,!1,!1,!1,0,null),e.dispatchEvent(y),q.readyState=q.DONE,void u()}return a.chrome&&r&&r!==j&&(p=d.slice||d.webkitSlice,d=p.call(d,0,d.size,j),s=!0),g&&"download"!==i&&(i+=".download"),(r===j||g)&&(o=a),h?(k+=d.size,void h(a.TEMPORARY,k,w(function(a){a.root.getDirectory("saved",x,w(function(a){var b=function(){a.getFile(i,x,w(function(a){a.createWriter(w(function(b){b.onwriteend=function(b){o.location.href=a.toURL(),l.push(a),q.readyState=q.DONE,n(q,"writeend",b)},b.onerror=function(){var a=b.error @@ -70,7 +66,7 @@ JSON.parse(a,function(a,b){if("number"!=typeof a&&a%1!==0||"object"!=typeof b)re var c=new e return c.level=b.level,c.resolution=b.resolution,c.scale=b.scale,b.hasOwnProperty("level")&&j.push(c),b}) var k=new f(parseFloat(d.initialExtent.xmin),parseFloat(d.initialExtent.ymin),parseFloat(d.initialExtent.xmax),parseFloat(d.initialExtent.ymax),i),l=new f(parseFloat(d.fullExtent.xmin),parseFloat(d.fullExtent.ymin),parseFloat(d.fullExtent.xmax),parseFloat(d.fullExtent.ymax),i),m=new g(d.tileInfo),n=new h(m.origin.x,m.origin.y,i) -m.origin=n,m.lods=j,b({initExtent:k,fullExtent:l,tileInfo:m,resultObj:d})})}},O.esri.Tiles.TilesStore=function(){this._db=null,this.dbName="offline_tile_store",this.objectStoreName="tilepath",this.isSupported=function(){return window.indexedDB||window.openDatabase?!0:!1},this.store=function(a,b){try{var c=this._db.transaction([this.objectStoreName],"readwrite") +m.origin=n,m.lods=j,b({initExtent:k,fullExtent:l,tileInfo:m,resultObj:d})})}},O.esri.Tiles.TilesStore=function(){this._db=null,this.dbName="offline_tile_store",this.objectStoreName="tilepath",this.isSupported=function(){return!(!window.indexedDB&&!window.openDatabase)},this.store=function(a,b){try{var c=this._db.transaction([this.objectStoreName],"readwrite") c.oncomplete=function(){b(!0)},c.onerror=function(a){b(!1,a.target.error.message)} var d=c.objectStore(this.objectStoreName),e=d.put(a) e.onsuccess=function(){}}catch(f){b(!1,f.stack)}},this.retrieve=function(a,b){if(null!==this._db){var c=this._db.transaction([this.objectStoreName]).objectStore(this.objectStoreName),d=c.get(a) diff --git a/dist/offline-tiles-advanced-src.js b/dist/offline-tiles-advanced-src.js index f0309347..b6737edb 100644 --- a/dist/offline-tiles-advanced-src.js +++ b/dist/offline-tiles-advanced-src.js @@ -1,6 +1,6 @@ -/*! esri-offline-maps - v3.0.3 - 2015-11-30 -* Copyright (c) 2015 Environmental Systems Research Institute, Inc. -* Apache License*/ +/*! esri-offline-maps - v3.0.6 - 2016-03-03 +* Copyright (c) 2016 Environmental Systems Research Institute, Inc. +* Apache License*/ define([ "dojo/query", "dojo/request", @@ -562,7 +562,7 @@ define([ req.send(null); } }); // declare -}); // define +}); // define /** * Creates a namespace for the non-AMD libraries in this directory */ @@ -577,7 +577,7 @@ else{ }; } -//"use strict"; +//"use strict"; /*jslint bitwise: true */ O.esri.Tiles.Base64Utils={}; @@ -659,7 +659,7 @@ O.esri.Tiles.Base64Utils.wordToBase64=function(/* word[] */wa){ return s.join(""); // string }; -/*jslint bitwise: false */ +/*jslint bitwise: false */ /* FileSaver.js * A saveAs() FileSaver implementation. * 2013-10-21 @@ -896,7 +896,7 @@ O.esri.Tiles.saveAs = //if (typeof module !== 'undefined') module.exports = saveAs; - + /** * This library contains common core code between OfflineTilesBasic.js * and OfflineTilesAdvanced.js @@ -1289,7 +1289,7 @@ O.esri.Tiles.TilesCore = function(){ }; - + /*global indexedDB */ /** @@ -1551,7 +1551,7 @@ O.esri.Tiles.TilesStore = function(){ }; }; - + O.esri.Tiles.TilingScheme = function (layer) { this.tileInfo = layer.tileInfo; }; diff --git a/dist/offline-tiles-basic-min.js b/dist/offline-tiles-basic-min.js index 09cf47e0..dcf7ea4d 100644 --- a/dist/offline-tiles-basic-min.js +++ b/dist/offline-tiles-basic-min.js @@ -1,6 +1,3 @@ -/*! esri-offline-maps - v3.0.3 - 2015-11-30 -* Copyright (c) 2015 Environmental Systems Research Institute, Inc. -* Apache License*/ define(["dojo/query","dojo/request","esri/geometry/Polygon","dojo/_base/declare"],function(a,b,c,d){"use strict" return d("O.esri.Tiles.OfflineTilesBasic",[],{getBasemapLayer:function(a){var b=a.layerIds[0] return a.getLayer(b)},extend:function(c,d,e,f){c._tilesCore=new O.esri.Tiles.TilesCore,c._lastTileUrl="",c._imageType="",c._minZoom=null,c._maxZoom=null,void 0===f||null===f?(c.DB_NAME="offline_tile_store",c.DB_OBJECTSTORE_NAME="tilepath"):(c.DB_NAME=f.dbName,c.DB_OBJECTSTORE_NAME=f.objectStoreName),c._getTileUrl=c.getTileUrl @@ -22,13 +19,12 @@ return d<<16|65535&c},O.esri.Tiles.Base64Utils.stringToWord=function(a){for(var return d},O.esri.Tiles.Base64Utils.wordToString=function(a){for(var b=8,c=(1<e;e+=b)d.push(String.fromCharCode(a[e>>5]>>>e%32&c)) return d.join("")},O.esri.Tiles.Base64Utils.wordToHex=function(a){for(var b="0123456789abcdef",c=[],d=0,e=4*a.length;e>d;d++)c.push(b.charAt(a[d>>2]>>d%4*8+4&15)+b.charAt(a[d>>2]>>d%4*8&15)) return c.join("")},O.esri.Tiles.Base64Utils.wordToBase64=function(a){for(var b="=",c="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/",d=[],e=0,f=4*a.length;f>e;e+=3)for(var g=(a[e>>2]>>8*(e%4)&255)<<16|(a[e+1>>2]>>8*((e+1)%4)&255)<<8|a[e+2>>2]>>8*((e+2)%4)&255,h=0;4>h;h++)8*e+6*h>32*a.length?d.push(b):d.push(c.charAt(g>>6*(3-h)&63)) -return d.join("")},/*! @source http://purl.eligrey.com/github/FileSaver.js/blob/master/FileSaver.js */ -O.esri.Tiles.saveAs=function(a){"use strict" +return d.join("")},O.esri.Tiles.saveAs=function(a){"use strict" var b=a.document,c=function(){return a.URL||a.webkitURL||a},d=a.URL||a.webkitURL||a,e=b.createElementNS("http://www.w3.org/1999/xhtml","a"),f=!a.externalHost&&"download"in e,g=a.webkitRequestFileSystem,h=a.requestFileSystem||g||a.mozRequestFileSystem,i=function(b){(a.setImmediate||a.setTimeout)(function(){throw b},0)},j="application/octet-stream",k=0,l=[],m=function(){for(var a=l.length;a--;){var b=l[a] "string"==typeof b?d.revokeObjectURL(b):b.remove()}l.length=0},n=function(a,b,c){b=[].concat(b) for(var d=b.length;d--;){var e=a["on"+b[d]] if("function"==typeof e)try{e.call(a,c||a)}catch(f){i(f)}}},o=function(d,i){var m,o,p,q=this,r=d.type,s=!1,t=function(){var a=c().createObjectURL(d) -return l.push(a),a},u=function(){n(q,"writestart progress write writeend".split(" "))},v=function(){(s||!m)&&(m=t(d)),o?o.location.href=m:window.open(m,"_blank"),q.readyState=q.DONE,u()},w=function(a){return function(){return q.readyState!==q.DONE?a.apply(this,arguments):void 0}},x={create:!0,exclusive:!1} +return l.push(a),a},u=function(){n(q,"writestart progress write writeend".split(" "))},v=function(){!s&&m||(m=t(d)),o?o.location.href=m:window.open(m,"_blank"),q.readyState=q.DONE,u()},w=function(a){return function(){return q.readyState!==q.DONE?a.apply(this,arguments):void 0}},x={create:!0,exclusive:!1} if(q.readyState=q.INIT,i||(i="download"),f){m=t(d),b=a.document,e=b.createElementNS("http://www.w3.org/1999/xhtml","a"),e.href=m,e.download=i var y=b.createEvent("MouseEvents") return y.initMouseEvent("click",!0,!1,a,0,0,0,0,0,!1,!1,!1,!1,0,null),e.dispatchEvent(y),q.readyState=q.DONE,void u()}return a.chrome&&r&&r!==j&&(p=d.slice||d.webkitSlice,d=p.call(d,0,d.size,j),s=!0),g&&"download"!==i&&(i+=".download"),(r===j||g)&&(o=a),h?(k+=d.size,void h(a.TEMPORARY,k,w(function(a){a.root.getDirectory("saved",x,w(function(a){var b=function(){a.getFile(i,x,w(function(a){a.createWriter(w(function(b){b.onwriteend=function(b){o.location.href=a.toURL(),l.push(a),q.readyState=q.DONE,n(q,"writeend",b)},b.onerror=function(){var a=b.error @@ -59,7 +55,7 @@ JSON.parse(a,function(a,b){if("number"!=typeof a&&a%1!==0||"object"!=typeof b)re var c=new e return c.level=b.level,c.resolution=b.resolution,c.scale=b.scale,b.hasOwnProperty("level")&&j.push(c),b}) var k=new f(parseFloat(d.initialExtent.xmin),parseFloat(d.initialExtent.ymin),parseFloat(d.initialExtent.xmax),parseFloat(d.initialExtent.ymax),i),l=new f(parseFloat(d.fullExtent.xmin),parseFloat(d.fullExtent.ymin),parseFloat(d.fullExtent.xmax),parseFloat(d.fullExtent.ymax),i),m=new g(d.tileInfo),n=new h(m.origin.x,m.origin.y,i) -m.origin=n,m.lods=j,b({initExtent:k,fullExtent:l,tileInfo:m,resultObj:d})})}},O.esri.Tiles.TilesStore=function(){this._db=null,this.dbName="offline_tile_store",this.objectStoreName="tilepath",this.isSupported=function(){return window.indexedDB||window.openDatabase?!0:!1},this.store=function(a,b){try{var c=this._db.transaction([this.objectStoreName],"readwrite") +m.origin=n,m.lods=j,b({initExtent:k,fullExtent:l,tileInfo:m,resultObj:d})})}},O.esri.Tiles.TilesStore=function(){this._db=null,this.dbName="offline_tile_store",this.objectStoreName="tilepath",this.isSupported=function(){return!(!window.indexedDB&&!window.openDatabase)},this.store=function(a,b){try{var c=this._db.transaction([this.objectStoreName],"readwrite") c.oncomplete=function(){b(!0)},c.onerror=function(a){b(!1,a.target.error.message)} var d=c.objectStore(this.objectStoreName),e=d.put(a) e.onsuccess=function(){}}catch(f){b(!1,f.stack)}},this.retrieve=function(a,b){if(null!==this._db){var c=this._db.transaction([this.objectStoreName]).objectStore(this.objectStoreName),d=c.get(a) diff --git a/dist/offline-tiles-basic-src.js b/dist/offline-tiles-basic-src.js index f79f7920..94e885f8 100644 --- a/dist/offline-tiles-basic-src.js +++ b/dist/offline-tiles-basic-src.js @@ -1,6 +1,6 @@ -/*! esri-offline-maps - v3.0.3 - 2015-11-30 -* Copyright (c) 2015 Environmental Systems Research Institute, Inc. -* Apache License*/ +/*! esri-offline-maps - v3.0.6 - 2016-03-03 +* Copyright (c) 2016 Environmental Systems Research Institute, Inc. +* Apache License*/ define([ "dojo/query", "dojo/request", @@ -394,7 +394,7 @@ define([ }); // declare }); // define - + /** * Creates a namespace for the non-AMD libraries in this directory */ @@ -409,7 +409,7 @@ else{ }; } -//"use strict"; +//"use strict"; /*jslint bitwise: true */ O.esri.Tiles.Base64Utils={}; @@ -491,7 +491,7 @@ O.esri.Tiles.Base64Utils.wordToBase64=function(/* word[] */wa){ return s.join(""); // string }; -/*jslint bitwise: false */ +/*jslint bitwise: false */ /* FileSaver.js * A saveAs() FileSaver implementation. * 2013-10-21 @@ -728,7 +728,7 @@ O.esri.Tiles.saveAs = //if (typeof module !== 'undefined') module.exports = saveAs; - + /** * This library contains common core code between OfflineTilesBasic.js * and OfflineTilesAdvanced.js @@ -1121,7 +1121,7 @@ O.esri.Tiles.TilesCore = function(){ }; - + /*global indexedDB */ /** @@ -1383,7 +1383,7 @@ O.esri.Tiles.TilesStore = function(){ }; }; - + O.esri.Tiles.TilingScheme = function (layer) { this.tileInfo = layer.tileInfo; }; diff --git a/dist/offline-tpk-min.js b/dist/offline-tpk-min.js index bb1b401a..ae7c08a5 100644 --- a/dist/offline-tpk-min.js +++ b/dist/offline-tpk-min.js @@ -1,6 +1,3 @@ -/*! esri-offline-maps - v3.0.3 - 2015-11-30 -* Copyright (c) 2015 Environmental Systems Research Institute, Inc. -* Apache License*/ define(["dojo/_base/declare","esri/geometry/Extent","dojo/query","esri/SpatialReference","esri/layers/TileInfo","esri/layers/TiledMapServiceLayer","dojo/Deferred","dojo/promise/all","dojo/Evented"],function(a,b,c,d,e,f,g,h,i){return a("O.esri.TPK.TPKLayer",[f,i],{map:null,store:null,MAX_DB_SIZE:75,TILE_PATH:"",RECENTER_DELAY:350,PARSING_ERROR:"parsingError",DB_INIT_ERROR:"dbInitError",DB_FULL_ERROR:"dbFullError",NO_SUPPORT_ERROR:"libNotSupportedError",PROGRESS_START:"start",PROGRESS_END:"end",WINDOW_VALIDATED:"windowValidated",DB_VALIDATED:"dbValidated",DATABASE_ERROR_EVENT:"databaseErrorEvent",VALIDATION_EVENT:"validationEvent",PROGRESS_EVENT:"progress",_maxDBSize:75,_isDBWriteable:!0,_isDBValid:!1,_autoCenter:null,_fileEntriesLength:0,_inMemTilesObject:null,_inMemTilesObjectLength:0,_zeroLengthFileCounter:0,constructor:function(){this._self=this,this._inMemTilesIndex=[],this._inMemTilesObject={},this.store=new O.esri.Tiles.TilesStore,this._validate()},extend:function(a){this._fileEntriesLength=a.length,this.emit(this.PROGRESS_EVENT,this.PROGRESS_START),this._parseInMemFiles(a,function(){this._parseConfCdi(function(a){this.initialExtent=this.fullExtent=a,this._parseConfXml(function(a){this.tileInfo=new e(a),this.spatialReference=new d({wkid:this.tileInfo.spatialReference.wkid}),this.loaded=!0,this.onLoad(this),this.emit(this.PROGRESS_EVENT,this.PROGRESS_END)}.bind(this._self))}.bind(this._self))}.bind(this._self))},getTileUrl:function(a,b,d){this.emit(this.PROGRESS_EVENT,this.PROGRESS_START) var e=this._self.TILE_PATH+"_alllayers",f=this._getCacheFilePath(e,a,b,d) if(this._inMemTilesObject!={}){var g="void:/"+a+"/"+b+"/"+d @@ -52,7 +49,7 @@ return 1==k?(f=i[l],b=(252&f)>>2,c=(3&f)<<4,g+=h[b]+h[c]+"=="):2==k&&(f=i[l]<<8| c(g)},_int2HexString:function(a){var b=a.toString(16).toUpperCase() return 1===b.length?"000"+b:2===b.length?"00"+b:3===b.length?"0"+b:b.substr(0,b.length)},_getOffset:function(a,b,c,d,e){var f=128*(c-e)+(b-d) return 16+5*f},_getCacheFilePath:function(a,b,c,d){var e=[] -return e.push(a),e.push("/"),e.push("L"),e.push(10>b?"0"+b:b),e.push("/"),e.push("R"),e.push(this._int2HexString(c)),e.push("C"),e.push(this._int2HexString(d)),e.join("")},_bytes2MBs:function(a){return(a>>>20)+"."+(2046&a)}})}),"undefined"!=typeof O?O.esri.TPK={}:(O={},O.esri={TPK:{},Tiles:{}}),O.esri.Tiles.TilesStore=function(){this._db=null,this.dbName="offline_tile_store",this.objectStoreName="tilepath",this.isSupported=function(){return window.indexedDB||window.openDatabase?!0:!1},this.store=function(a,b){try{var c=this._db.transaction([this.objectStoreName],"readwrite") +return e.push(a),e.push("/"),e.push("L"),e.push(10>b?"0"+b:b),e.push("/"),e.push("R"),e.push(this._int2HexString(c)),e.push("C"),e.push(this._int2HexString(d)),e.join("")},_bytes2MBs:function(a){return(a>>>20)+"."+(2046&a)}})}),"undefined"!=typeof O?O.esri.TPK={}:(O={},O.esri={TPK:{},Tiles:{}}),O.esri.Tiles.TilesStore=function(){this._db=null,this.dbName="offline_tile_store",this.objectStoreName="tilepath",this.isSupported=function(){return!(!window.indexedDB&&!window.openDatabase)},this.store=function(a,b){try{var c=this._db.transaction([this.objectStoreName],"readwrite") c.oncomplete=function(){b(!0)},c.onerror=function(a){b(!1,a.target.error.message)} var d=c.objectStore(this.objectStoreName),e=d.put(a) e.onsuccess=function(){}}catch(f){b(!1,f.stack)}},this.retrieve=function(a,b){if(null!==this._db){var c=this._db.transaction([this.objectStoreName]).objectStore(this.objectStoreName),d=c.get(a) @@ -149,7 +146,7 @@ for(b=0;B+1>b;b++)e[b]=0 for(b=0;3>b;b++)f[b]=0 g.set(e.subarray(0,B),0),h.set(e.subarray(0,B+1),0)}var c,d,e,f,g,h,j=this j.inflate_trees_bits=function(e,f,g,h,i){var j -return b(19),c[0]=0,j=a(e,0,19,19,null,null,g,f,h,c,d),j==m?i.msg="oversubscribed dynamic bit lengths tree":(j==o||0===f[0])&&(i.msg="incomplete dynamic bit lengths tree",j=m),j},j.inflate_trees_dynamic=function(e,f,g,h,j,k,l,p,q){var r +return b(19),c[0]=0,j=a(e,0,19,19,null,null,g,f,h,c,d),j==m?i.msg="oversubscribed dynamic bit lengths tree":j!=o&&0!==f[0]||(i.msg="incomplete dynamic bit lengths tree",j=m),j},j.inflate_trees_dynamic=function(e,f,g,h,j,k,l,p,q){var r return b(288),c[0]=0,r=a(g,0,e,257,x,y,k,h,p,c,d),r!=i||0===h[0]?(r==m?q.msg="oversubscribed literal/length tree":r!=n&&(q.msg="incomplete literal/length tree",r=m),r):(b(288),r=a(g,e,f,0,z,A,l,j,p,c,d),r!=i||0===j[0]&&e>257?(r==m?q.msg="oversubscribed distance tree":r==o?(q.msg="incomplete distance tree",r=m):r!=n&&(q.msg="empty distance tree with lengths",r=m),r):i)}}function c(){function a(a,b,c,d,e,f,g,h){var k,l,n,o,q,r,s,t,u,v,w,x,y,z,A,B s=h.next_in_index,t=h.avail_in,q=g.bitb,r=g.bitk,u=g.write,v=ur;)t--,q|=(255&h.read_byte(s++))</g,">").replace(/"/g,""").replace(/'/g,"'").replace(/\//g,"/"):a}function g(a){return a.replace(/&/g,"&").replace(/</g,"<").replace(/>/g,">").replace(/"/g,'"').replace(/'/g,"'").replace(///g,"/")}function h(b,c,d){switch(a.arrayAccessForm){case"property":b[c]instanceof Array?b[c+"_asArray"]=b[c]:b[c+"_asArray"]=[b[c]]}if(!(b[c]instanceof Array)&&a.arrayAccessFormPaths.length>0){for(var e=0;e/g,">").replace(/"/g,""").replace(/'/g,"'").replace(/\//g,"/"):a}function g(a){return a.replace(/&/g,"&").replace(/</g,"<").replace(/>/g,">").replace(/"/g,'"').replace(/'/g,"'").replace(///g,"/")}function h(b,c,d){switch(a.arrayAccessForm){case"property":b[c]instanceof Array?b[c+"_asArray"]=b[c]:b[c+"_asArray"]=[b[c]]}if(!(b[c]instanceof Array)&&a.arrayAccessFormPaths.length>0){for(var e=0;e1&&c.setMilliseconds(d[1]),b[6]&&b[7]){var e=60*b[6]+Number(b[7]),f=/\d\d-\d\d:\d\d$/.test(a)?"-":"+" e=0+("-"==f?-1*e:e),c.setMinutes(c.getMinutes()-e-c.getTimezoneOffset())}else-1!==a.indexOf("Z",a.length-1)&&(c=new Date(Date.UTC(c.getFullYear(),c.getMonth(),c.getDate(),c.getHours(),c.getMinutes(),c.getSeconds(),c.getMilliseconds()))) @@ -314,7 +311,7 @@ m.nodeType!=w.COMMENT_NODE&&(f.__cnt++,null==f[n]?(f[n]=k(m,c+"."+n),h(f,n,c+"." f.__cnt++,f[a.attributePrefix+p.name]=p.value}var q=e(b) return null!=q&&""!=q&&(f.__cnt++,f.__prefix=q),null!=f["#text"]&&(f.__text=f["#text"],f.__text instanceof Array&&(f.__text=f.__text.join("\n")),a.escapeMode&&(f.__text=g(f.__text)),a.stripWhitespaces&&(f.__text=f.__text.trim()),delete f["#text"],"property"==a.arrayAccessForm&&delete f["#text_asArray"],f.__text=j(f.__text,n,c+"."+n)),null!=f["#cdata-section"]&&(f.__cdata=f["#cdata-section"],delete f["#cdata-section"],"property"==a.arrayAccessForm&&delete f["#cdata-section_asArray"]),1==f.__cnt&&null!=f.__text?f=f.__text:0==f.__cnt&&"text"==a.emptyNodeForm?f="":f.__cnt>1&&null!=f.__text&&a.skipEmptyTextNodesForObj&&(a.stripWhitespaces&&""==f.__text||""==f.__text.trim())&&delete f.__text,delete f.__cnt,!a.enableToStringFunc||null==f.__text&&null==f.__cdata||(f.toString=function(){return(null!=this.__text?this.__text:"")+(null!=this.__cdata?this.__cdata:"")}),f}return b.nodeType==w.TEXT_NODE||b.nodeType==w.CDATA_SECTION_NODE?b.nodeValue:void 0}function l(b,c,d,e){var g="<"+(null!=b&&null!=b.__prefix?b.__prefix+":":"")+c if(null!=d)for(var h=0;h":">"}function m(a,b){return""}function n(a,b){return-1!==a.indexOf(b,a.length-b.length)}function o(b,c){return"property"==a.arrayAccessForm&&n(c.toString(),"_asArray")||0==c.toString().indexOf(a.attributePrefix)||0==c.toString().indexOf("__")||b[c]instanceof Function?!0:!1}function p(a){var b=0 +a.escapeMode&&(j=f(j)),g+=" "+i.substr(a.attributePrefix.length)+"='"+j+"'"}return g+=e?"/>":">"}function m(a,b){return""}function n(a,b){return-1!==a.indexOf(b,a.length-b.length)}function o(b,c){return!!("property"==a.arrayAccessForm&&n(c.toString(),"_asArray")||0==c.toString().indexOf(a.attributePrefix)||0==c.toString().indexOf("__")||b[c]instanceof Function)}function p(a){var b=0 if(a instanceof Object)for(var c in a)o(a,c)||b++ return b}function q(b){var c=[] if(b instanceof Object)for(var d in b)-1==d.toString().indexOf("__")&&0==d.toString().indexOf(a.attributePrefix)&&c.push(d) diff --git a/dist/offline-tpk-src.js b/dist/offline-tpk-src.js index 3d27b4c2..428d40ce 100644 --- a/dist/offline-tpk-src.js +++ b/dist/offline-tpk-src.js @@ -1,6 +1,6 @@ -/*! esri-offline-maps - v3.0.3 - 2015-11-30 -* Copyright (c) 2015 Environmental Systems Research Institute, Inc. -* Apache License*/ +/*! esri-offline-maps - v3.0.6 - 2016-03-03 +* Copyright (c) 2016 Environmental Systems Research Institute, Inc. +* Apache License*/ /** * Library for reading an ArcGIS Tile Package (.tpk) file and displaying the tiles * as a map that can be used both online and offline. @@ -720,7 +720,7 @@ define([ } }); } -); +); /** * Creates a namespace for the non-AMD libraries in this directory */ @@ -738,7 +738,7 @@ else{ } //"use strict"; - + /*global indexedDB */ /** @@ -1000,7 +1000,7 @@ O.esri.Tiles.TilesStore = function(){ }; }; - + //https://github.com/gildas-lormeau/zip.js/blob/master/WebContent/zip.js /* Copyright (c) 2013 Gildas Lormeau. All rights reserved. @@ -1807,7 +1807,7 @@ O.esri.Tiles.TilesStore = function(){ useWebWorkers : true }; -}(O.esri)); +}(O.esri)); /** * This library assists with autoCenter the map upon orientation change * IMPORTANT: There are Esri dependencies in this library including @@ -1941,7 +1941,7 @@ O.esri.TPK.autoCenterMap = function(/* Map */ map,/* int */ delay){ var centerPt = map.extent.getCenter(); _setCenterPt(centerPt.x,centerPt.y,map.spatialReference.wkid); }; -}; +}; /* Copyright (c) 2013 Gildas Lormeau. All rights reserved. @@ -4120,7 +4120,7 @@ O.esri.TPK.___blobURL = URL.createObjectURL( ) O.esri.zip.workerScriptsPath = O.esri.TPK.___blobURL; - + //https://github.com/abdmob/x2js/blob/master/xml2json.js /* Copyright 2011-2013 Abdulla Abdurakhmanov diff --git a/lib/edit/OfflineEditAdvanced.js b/lib/edit/OfflineEditAdvanced.js index 67ec436f..99529c25 100644 --- a/lib/edit/OfflineEditAdvanced.js +++ b/lib/edit/OfflineEditAdvanced.js @@ -1150,7 +1150,19 @@ define([ // we need to identify ADDs before sending them to the server // we assign temporary ids (using negative numbers to distinguish them from real ids) - layer._nextTempId = -1; + // query the database first to find any existing offline adds, and find the next lowest integer to start with. + this._editStore.getNextLowestTempId(layer, function(value, status){ + if(status === "success"){ + console.log("_nextTempId:", value); + layer._nextTempId = value; + } + else{ + console.log("_nextTempId, not success:", value); + layer._nextTempId = -1; + console.debug(layer._nextTempId); + } + }); + layer._getNextTempId = function () { return this._nextTempId--; }; diff --git a/lib/edit/OfflineEditBasic.js b/lib/edit/OfflineEditBasic.js index a12d801f..b264dc27 100644 --- a/lib/edit/OfflineEditBasic.js +++ b/lib/edit/OfflineEditBasic.js @@ -488,7 +488,19 @@ define([ // we need to identify ADDs before sending them to the server // we assign temporary ids (using negative numbers to distinguish them from real ids) - layer._nextTempId = -1; + // query the database first to find any existing offline adds, and find the next lowest integer to start with. + this._editStore.getNextLowestTempId(layer, function(value, status){ + if(status === "success"){ + console.log("_nextTempId:", value); + layer._nextTempId = value; + } + else{ + console.log("_nextTempId, not success:", value); + layer._nextTempId = -1; + console.debug(layer._nextTempId); + } + }); + layer._getNextTempId = function () { return this._nextTempId--; }; diff --git a/lib/edit/editsStore.js b/lib/edit/editsStore.js index 888106bd..19c53bde 100644 --- a/lib/edit/editsStore.js +++ b/lib/edit/editsStore.js @@ -540,6 +540,58 @@ O.esri.Edit.EditStore = function () { } }; + /* + * Query the database, looking for any existing Add temporary OIDs, and return the nextTempId to be used. + * @param feature - extended layer from offline edit advanced + * @param callback {int, messageString} or {null, messageString} + */ + this.getNextLowestTempId = function (feature, callback) { + var addOIDsArray = [], + self = this; + + if (this._db !== null) { + + var fLayerJSONId = this.FEATURE_LAYER_JSON_ID; + var fCollectionId = this.FEATURE_COLLECTION_ID; + var phantomGraphicPrefix = this.PHANTOM_GRAPHIC_PREFIX; + + var transaction = this._db.transaction([this.objectStoreName]) + .objectStore(this.objectStoreName) + .openCursor(); + + transaction.onsuccess = function (event) { + var cursor = event.target.result; + if (cursor && cursor.value && cursor.value.id) { + // Make sure we are not return FeatureLayer JSON data or a Phantom Graphic + if (cursor.value.id !== fLayerJSONId && cursor.value.id !== fCollectionId && cursor.value.id.indexOf(phantomGraphicPrefix) == -1) { + if(cursor.value.layer === feature.url && cursor.value.operation === "add"){ // check to make sure the edit is for the feature we are looking for, and that the operation is an add. + addOIDsArray.push(cursor.value.graphic.attributes[self.objectId]); // add the temporary OID to the array + } + } + cursor.continue(); + } + else { + if(addOIDsArray.length === 0){ // if we didn't find anything, + callback(-1, "success"); // we'll start with -1 + } + else{ + var filteredOIDsArray = addOIDsArray.filter(function(val){ // filter out any non numbers from the array... + return !isNaN(val); // .. should anything have snuck in or returned a NaN + }); + var lowestTempId = Math.min.apply(Math, filteredOIDsArray); // then find the lowest number from the array + callback(lowestTempId--, "success"); // and we'll start with one less than tat. + } + } + }.bind(this); + transaction.onerror = function (err) { + callback(null, err); + }; + } + else { + callback(null, "no db"); + } + }, + /** * Returns all the edits as a single Array via the callback * @param callback {array, messageString} or {null, messageString} diff --git a/package.json b/package.json index f4b00309..ff58f6a2 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "esri-offline-maps", - "version": "3.0.5", + "version": "3.0.6", "description": "Lightweight set of libraries for working offline with map tiles and editing with ArcGIS feature services", "author": "Andy Gup (http://blog.andygup.net)", "license": "Apache 2.0",