diff --git a/.gitmodules b/.gitmodules
index 9059e8a..7d99113 100644
--- a/.gitmodules
+++ b/.gitmodules
@@ -7,3 +7,6 @@
[submodule "vendor/IndexedDBShim"]
path = vendor/IndexedDBShim
url = https://github.com/axemclion/IndexedDBShim
+[submodule "vendor/jasmine.async"]
+ path = vendor/jasmine.async
+ url = https://github.com/derickbailey/jasmine.async.git
diff --git a/test/jasmine/SpecRunner.html b/test/jasmine/SpecRunner.html
index 25d3261..ea45da3 100755
--- a/test/jasmine/SpecRunner.html
+++ b/test/jasmine/SpecRunner.html
@@ -4,10 +4,10 @@
Jasmine Spec Runner
-
-
-
-
+
+
+
+
diff --git a/test/jasmine/SpecRunner.tiles.html b/test/jasmine/SpecRunner.tiles.html
new file mode 100755
index 0000000..bdb7fd7
--- /dev/null
+++ b/test/jasmine/SpecRunner.tiles.html
@@ -0,0 +1,95 @@
+
+
+
+ Jasmine Spec Runner - Tiles
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/test/jasmine/spec/offlineEnablerSpec.js b/test/jasmine/spec/offlineEnablerSpec.js
new file mode 100644
index 0000000..e1995e1
--- /dev/null
+++ b/test/jasmine/spec/offlineEnablerSpec.js
@@ -0,0 +1,155 @@
+"use strict"
+
+describe("offline enabler library", function()
+{
+ var async = new AsyncSpec(this);
+
+ async.it("validate map", function(done)
+ {
+ expect(g_map).toEqual(jasmine.any(Object));
+ expect(g_map.id).toEqual("map");
+ done();
+ });
+
+ async.it("validate tiled layer", function(done)
+ {
+ expect(g_basemapLayer).toEqual(jasmine.any(Object));
+ expect(g_basemapLayer.tileInfo).toEqual(jasmine.any(Object));
+ done();
+ });
+
+ async.it("extends the tiled layer object", function(done)
+ {
+ expect(g_basemapLayer.goOffline).toBeUndefined();
+ g_offlineEnabler.extend(g_basemapLayer,function(success)
+ {
+ expect(success).toEqual(true);
+ expect(g_basemapLayer.goOffline).toEqual(jasmine.any(Function));
+ expect(g_basemapLayer.goOnline).toEqual(jasmine.any(Function));
+ expect(g_basemapLayer.getTileUrl).toEqual(jasmine.any(Function));
+ expect(g_basemapLayer._getTileUrl).toEqual(jasmine.any(Function));
+ expect(g_basemapLayer.prepareForOffline).toEqual(jasmine.any(Function));
+ expect(g_basemapLayer.storeTile).toEqual(jasmine.any(Function));
+ expect(g_basemapLayer.deleteAllTiles).toEqual(jasmine.any(Function));
+ expect(g_basemapLayer.offline).toEqual(jasmine.any(Object));
+ expect(g_basemapLayer.offline.store).toEqual(jasmine.any(Object));
+
+ g_basemapLayer.offline.proxyPath = "../../tiles/proxy.php";
+ done();
+ });
+ });
+
+ async.it("can go offline", function(done)
+ {
+ expect(g_basemapLayer.goOffline).toEqual(jasmine.any(Function));
+ expect(g_basemapLayer.offline.online).toEqual(true);
+ g_basemapLayer.goOffline();
+ expect(g_basemapLayer.offline.online).toEqual(false);
+ done();
+ });
+
+ async.it("can go online", function(done)
+ {
+ expect(g_basemapLayer.goOffline).toEqual(jasmine.any(Function));
+ expect(g_basemapLayer.offline.online).toEqual(false);
+ g_basemapLayer.goOnline();
+ expect(g_basemapLayer.offline.online).toEqual(true);
+ done();
+ })
+
+ async.it("delete all tiles", function(done)
+ {
+ g_basemapLayer.deleteAllTiles(function(success)
+ {
+ expect(success).toEqual(true);
+ setTimeout(function()
+ {
+ g_basemapLayer.getOfflineUsage(function(usage)
+ {
+ expect(usage.tileCount).toEqual(0);
+ done();
+ });
+ },1);
+ });
+ });
+
+ async.it("stores one tile", function(done)
+ {
+ g_basemapLayer.getOfflineUsage(function(usage)
+ {
+ expect(usage.tileCount).toEqual(0);
+ g_basemapLayer.storeTile(14,6177,8023, function(success)
+ {
+ expect(success).toEqual(true);
+ g_basemapLayer.getOfflineUsage(function(usage)
+ {
+ expect(usage.tileCount).toEqual(1);
+ done();
+ });
+ });
+ });
+ });
+
+ async.it("gets level estimation", function(done)
+ {
+ require(["esri/geometry/Extent"],function(Extent)
+ {
+ var extent = new Extent({"xmin":-822542.2830377579,"ymin":4580841.761960262,"xmax":94702.05638410954,"ymax":5131188.365613382,"spatialReference":{"wkid":102100}});
+ var tileSize = g_basemapLayer.estimateTileSize();
+ var estimation = g_basemapLayer.getLevelEstimation(extent,10);
+ expect(estimation.tileCount).toEqual(375);
+ expect(estimation.sizeBytes).toEqual(estimation.tileCount * tileSize);
+ var estimation = g_basemapLayer.getLevelEstimation(extent,8);
+ expect(estimation.tileCount).toEqual(28);
+ expect(estimation.sizeBytes).toEqual(estimation.tileCount * tileSize);
+ var estimation = g_basemapLayer.getLevelEstimation(extent,2);
+ expect(estimation.tileCount).toEqual(2);
+ expect(estimation.sizeBytes).toEqual(estimation.tileCount * tileSize);
+ done();
+ });
+ });
+
+ async.it("prepares the layer for offline usage", function(done)
+ {
+ require(["esri/geometry/Extent"], function(Extent)
+ {
+ g_basemapLayer.deleteAllTiles(function(success)
+ {
+ var extent = new Extent({"xmin":-822542.2830377579,"ymin":4580841.761960262,"xmax":94702.05638410954,"ymax":5131188.365613382,"spatialReference":{"wkid":102100}});
+ var reportProgress = jasmine.createSpy();
+ var finishedDownloading = function(err)
+ {
+ expect(err).not.toBeTruthy();
+ expect(reportProgress).toHaveBeenCalled();
+ expect(reportProgress.callCount).toEqual(28);
+
+ g_basemapLayer.getOfflineUsage(function(usage)
+ {
+ expect(usage.tileCount).toEqual(28);
+ done();
+ });
+ }
+
+ g_basemapLayer.prepareForOffline(8,8,extent,reportProgress, finishedDownloading);
+ });
+ });
+ });
+
+ async.it("returns placeholder urls when offline", function(done)
+ {
+ require(["dojo/dom"], function(dom)
+ {
+ var fakeTile = dom.byId('fakeTile');
+
+ g_basemapLayer.goOnline();
+ var onlineUrl = g_basemapLayer.getTileUrl(14,6178,8023);
+ expect(onlineUrl).toEqual('http://services.arcgisonline.com/ArcGIS/rest/services/Canvas/World_Light_Gray_Base/MapServer/tile/14/6178/8023');
+
+ g_basemapLayer.goOffline();
+ var offlineUrl = fakeTile.src = g_basemapLayer.getTileUrl(14,6178,8023);
+ expect(offlineUrl).toEqual('void:14-6178-8023');
+ done();
+ })
+ });
+
+});
\ No newline at end of file
diff --git a/tiles/ISSUES.md b/tiles/ISSUES.md
index dece3ba..f846bb6 100644
--- a/tiles/ISSUES.md
+++ b/tiles/ISSUES.md
@@ -16,9 +16,12 @@
+ better dependency management
- [x] remove unused files (ioWorker, OfflineTileStore)
- [x] test iPad/iPhone **DONE**, it works!
+- [x] unit testing
-- [ ] unit testing
+- [ ] update README.md
- [ ] better tile estimation and limits
+- [ ] keep on downloading tiles even if one of them fails
+- [ ] add message telling that something failed while initing the indexedDB
- [ ] allow naming caches?
- [ ] more general proxy.php
diff --git a/tiles/index.html b/tiles/index.html
index b700e59..4e06bd7 100644
--- a/tiles/index.html
+++ b/tiles/index.html
@@ -56,6 +56,7 @@
@@ -134,6 +135,13 @@
+
+
+
diff --git a/tiles/main.js b/tiles/main.js
index 3c9ba65..286d85a 100644
--- a/tiles/main.js
+++ b/tiles/main.js
@@ -12,7 +12,7 @@ require(["esri/map",
"dojo/dom", "dojo/on", "dojo/query",
"../vendor/bootstrap-map-js/src/js/bootstrapmap.js",
"esri/urlUtils", "esri/geometry/webMercatorUtils",
- "/offline/tiles/src/offlineEnabler.js",
+ "tiles/offlineEnabler",
"dojo/dom-construct", "dojo/domReady!"],
function(Map,
GraphicsLayer, Graphic, SimpleFillSymbol,
@@ -36,8 +36,7 @@ require(["esri/map",
function loadWebmap(webmapid)
{
- //webmapid = webmapid || "1d2a47c27ffc433fa4a278841544f427"; //for testing only
- webmapid = webmapid || "f58996878ac24702afef792e52a07e55";
+ webmapid = webmapid || "bbc1a04a3eca4430be144d7a08b43a17";
// Get new webmap and extract map and map parts
var mapDeferred = esriUtils.createMap(webmapid, "mapDiv", {
mapOptions: {
@@ -54,8 +53,9 @@ require(["esri/map",
// Bind to map
BootstrapMap.bindTo(map);
- // Add title
+ // Add title and description
dom.byId("mapTitle").innerHTML = response.itemInfo.item.title;
+ dom.byId("mapDescription").innerHTML = response.itemInfo.item.snippet;
if(map.loaded)
{
@@ -136,6 +136,11 @@ require(["esri/map",
else
{
dojo.byId('prepare-for-offline-btn').disabled = true;
+ dojo.byId('delete-all-tiles-btn').disabled = true;
+ dojo.byId('go-offline-btn').disabled = true;
+ dojo.byId('go-online-btn').disabled = true;
+ dojo.byId('update-offline-usage').disabled = true;
+ dojo.byId('show-stored-tiles').disabled = true;
esri.hide(dojo.byId('downloading-ui'));
/* JAMI: TODO add message telling that something failed while initing the indexedDB */
}
diff --git a/tiles/proxy.php b/tiles/proxy.php
index 3ebc95b..45c05b9 100755
--- a/tiles/proxy.php
+++ b/tiles/proxy.php
@@ -42,9 +42,10 @@
array( 'url' => 'http://tiles4.arcgis.com/tiles/', 'matchAll' => true, 'token' => '' ),
array( 'url' => 'http://www.mapabase.es/ArcGIS/', 'matchAll' => true, 'token' => '' ),
array( 'url' => 'http://server.arcgisonline.com/ArcGIS/rest/services/', 'matchAll' => true, 'token' => '' ),
- array( 'url' => 'http://sampleserver1.arcgisonline.com/ArcGIS/rest/services/', 'matchAll' => true, 'token' => '' ),
array( 'url' => 'http://services.arcgisonline.com/ArcGIS/rest/services/', 'matchAll' => true, 'token' => '' ),
+ array( 'url' => 'http://sampleserver1.arcgisonline.com/ArcGIS/rest/services/', 'matchAll' => true, 'token' => '' ),
array( 'url' => 'http://sampleserver2.arcgisonline.com/ArcGIS/rest/services/', 'matchAll' => true, 'token' => '' ),
+ array( 'url' => 'http://sampleserver5.arcgisonline.com/ArcGIS/rest/services/', 'matchAll' => true, 'token' => '' ),
array( 'url' => 'http://sampleserver1a.arcgisonline.com/arcgisoutput/', 'matchAll' => true, 'token' => '' ),
array( 'url' => 'http://sampleserver1b.arcgisonline.com/arcgisoutput/', 'matchAll' => true, 'token' => '' ),
array( 'url' => 'http://sampleserver1c.arcgisonline.com/arcgisoutput/', 'matchAll' => true, 'token' => '' )
diff --git a/tiles/src/Blob.js b/tiles/tiles/Blob.js
similarity index 100%
rename from tiles/src/Blob.js
rename to tiles/tiles/Blob.js
diff --git a/tiles/src/FileSaver.js b/tiles/tiles/FileSaver.js
similarity index 100%
rename from tiles/src/FileSaver.js
rename to tiles/tiles/FileSaver.js
diff --git a/tiles/src/base64utils.js b/tiles/tiles/base64utils.js
similarity index 100%
rename from tiles/src/base64utils.js
rename to tiles/tiles/base64utils.js
diff --git a/tiles/src/dbStore.js b/tiles/tiles/dbStore.js
similarity index 97%
rename from tiles/src/dbStore.js
rename to tiles/tiles/dbStore.js
index 2217d6d..9606eff 100644
--- a/tiles/src/dbStore.js
+++ b/tiles/tiles/dbStore.js
@@ -6,7 +6,7 @@
* Author: Andy Gup (@agup)
* Contributor: Javier Abadia (@javierabadia)
*/
-define(["/offline/tiles/src/phoneGapConnector.js"],function(phonegap)
+define(["tiles/phoneGapConnector"],function(phonegap)
{
var DbStore = function()
{
@@ -37,7 +37,6 @@ define(["/offline/tiles/src/phoneGapConnector.js"],function(phonegap)
* @returns {boolean}
*/
this.isSupported = function(){
- window.indexedDB = window.indexedDB || window.mozIndexedDB || window.webkitIndexedDB || window.msIndexedDB;
if(!window.indexedDB){
return false;
diff --git a/tiles/src/offlineEnabler.js b/tiles/tiles/offlineEnabler.js
similarity index 96%
rename from tiles/src/offlineEnabler.js
rename to tiles/tiles/offlineEnabler.js
index 83960cf..0fe87a2 100644
--- a/tiles/src/offlineEnabler.js
+++ b/tiles/tiles/offlineEnabler.js
@@ -3,9 +3,9 @@
define([
"dojo/query",
"esri/geometry",
- "/offline//tiles/src/base64utils.js",
- "/offline/tiles/src/dbStore.js",
- "/offline/tiles/src/tilingScheme.js"
+ "tiles/base64utils",
+ "tiles/dbStore",
+ "tiles/tilingScheme"
], function(query, geometry,Base64Utils,DbStore,TilingScheme)
{
return {
@@ -34,10 +34,11 @@ define([
layer._getTileUrl = layer.getTileUrl;
layer.offline = {
online: true,
- store: new DbStore()
+ store: new DbStore(),
+ proxyPath: "proxy.php"
};
- if( layer.offline.store.isSupported() )
+ if( /*false &&*/ layer.offline.store.isSupported() )
layer.offline.store.init(callback);
else
return callback(false, "indexedDB not supported");
@@ -178,7 +179,7 @@ define([
url = url.split('?')[0];
/* download the tile */
- var imgurl = "../tiles/proxy.php?" + url;
+ var imgurl = this.offline.proxyPath + "?" + url;
var req = new XMLHttpRequest();
req.open("GET", imgurl, true);
req.overrideMimeType("text/plain; charset=x-user-defined"); // https://developer.mozilla.org/en-US/docs/Web/API/XMLHttpRequest/Using_XMLHttpRequest?redirectlocale=en-US&redirectslug=DOM%2FXMLHttpRequest%2FUsing_XMLHttpRequest#Handling_binary_data
diff --git a/tiles/src/phoneGapConnector.js b/tiles/tiles/phoneGapConnector.js
similarity index 100%
rename from tiles/src/phoneGapConnector.js
rename to tiles/tiles/phoneGapConnector.js
diff --git a/tiles/src/tilingScheme.js b/tiles/tiles/tilingScheme.js
similarity index 100%
rename from tiles/src/tilingScheme.js
rename to tiles/tiles/tilingScheme.js
diff --git a/test/jasmine/lib/jasmine-1.3.1/MIT.LICENSE b/vendor/jasmine-1.3.1/MIT.LICENSE
similarity index 100%
rename from test/jasmine/lib/jasmine-1.3.1/MIT.LICENSE
rename to vendor/jasmine-1.3.1/MIT.LICENSE
diff --git a/test/jasmine/lib/jasmine-1.3.1/jasmine-html.js b/vendor/jasmine-1.3.1/jasmine-html.js
similarity index 100%
rename from test/jasmine/lib/jasmine-1.3.1/jasmine-html.js
rename to vendor/jasmine-1.3.1/jasmine-html.js
diff --git a/test/jasmine/lib/jasmine-1.3.1/jasmine.css b/vendor/jasmine-1.3.1/jasmine.css
similarity index 100%
rename from test/jasmine/lib/jasmine-1.3.1/jasmine.css
rename to vendor/jasmine-1.3.1/jasmine.css
diff --git a/test/jasmine/lib/jasmine-1.3.1/jasmine.js b/vendor/jasmine-1.3.1/jasmine.js
similarity index 100%
rename from test/jasmine/lib/jasmine-1.3.1/jasmine.js
rename to vendor/jasmine-1.3.1/jasmine.js
diff --git a/vendor/jasmine.async b/vendor/jasmine.async
new file mode 160000
index 0000000..f6f159d
--- /dev/null
+++ b/vendor/jasmine.async
@@ -0,0 +1 @@
+Subproject commit f6f159d49415442b7bdff06c912e53ed4320bb94