Skip to content

Commit

Permalink
Merge pull request #412 from andygup/v2.15
Browse files Browse the repository at this point in the history
v2.15
  • Loading branch information
andygup committed Sep 30, 2015
2 parents c364abc + 50187ca commit 9552ba1
Show file tree
Hide file tree
Showing 20 changed files with 1,153 additions and 107 deletions.
9 changes: 9 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,14 @@
# offline-editor-js - Changelog

## Version 2.15 - Sep. 29, 2015

No breaking changes.

**Enhancements**
* Closes #291 - OfflineTilesEnablerLayer now supports token-based authentication. Going forward, if you are using a secure tiled map service you will need to make sure that the `esri\IdentityManager` module is included in your ArcGIS API for JavaScript optimized build.
* Refactored OfflineTilesEnablerLayer to break out offline and secure service detection into more logicially seperate functions.
* Added a new spec to test token-based tile layer.

## Version 2.14.0.2 - Sep. 8, 2015

No breaking changes. Doc updates only.
Expand Down
2 changes: 1 addition & 1 deletion dist/offline-edit-min.js

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion dist/offline-edit-src.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
/*! esri-offline-maps - v2.14.0 - 2015-08-14
/*! esri-offline-maps - v2.15.0 - 2015-09-29
* Copyright (c) 2015 Environmental Systems Research Institute, Inc.
* Apache License*/
/*jshint -W030 */
Expand Down
6 changes: 3 additions & 3 deletions dist/offline-tiles-advanced-min.js

Large diffs are not rendered by default.

178 changes: 143 additions & 35 deletions dist/offline-tiles-advanced-src.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
/*! esri-offline-maps - v2.14.0 - 2015-08-14
/*! esri-offline-maps - v2.15.0 - 2015-09-29
* Copyright (c) 2015 Environmental Systems Research Institute, Inc.
* Apache License*/
define([
Expand All @@ -23,13 +23,17 @@ define([
_minZoom: null,
_maxZoom: null,
_tilesCore:null,
_secure:false, //is this a secured service

constructor:function(url,callback,/* boolean */ state,/* Object */ dbConfig){

if(this._isLocalStorage() === false){
alert("OfflineTiles Library not supported on this browser.");
callback(false);
}
else {
window.localStorage.offline_id_manager = ""; //this is where we will store secure service info
}

if( dbConfig === undefined || dbConfig === null){
// Database properties
Expand Down Expand Up @@ -86,36 +90,11 @@ define([
this.offline.store.objectStoreName = this.DB_OBJECTSTORE_NAME;
this.offline.store.init(function(success){
if(success){
this._getTileInfoPrivate(url,function(result){

// Store the layerInfo locally so we have it when browser restarts or is reloaded.
// We need this info in order to properly rebuild the layer.
if(localStorage.__offlineTileInfo === undefined && result !== false){
localStorage.__offlineTileInfo = result;
}

// If library is offline then attempt to get layerInfo from localStorage.
if(this.offline.online === false && result === false && localStorage.__offlineTileInfo !== undefined){
result = localStorage.__offlineTileInfo;
}
else if(this.offline.online === false && result === false && localStorage.__offlineTileInfo === undefined){
alert("There was a problem retrieving tiled map info in OfflineTilesEnablerLayer.");
}

this._tilesCore._parseGetTileInfo(result,function(tileResult){
this.layerInfos = tileResult.resultObj.layers;
this.minScale = tileResult.resultObj.minScale;
this.maxScale = tileResult.resultObj.maxScale;
this.tileInfo = tileResult.tileInfo;
this._imageType = this.tileInfo.format.toLowerCase();
this.fullExtent = tileResult.fullExtent;
this.spatialReference = this.tileInfo.spatialReference;
this.initialExtent = tileResult.initExtent;
this.loaded = true;
this.onLoad(this);
callback(true);
}.bind(this._self));
}.bind(this._self));
// Configure the layer
this._getTileInfoPrivate(url,function(result){
callback(result);
});
}
}.bind(this._self));
}
Expand Down Expand Up @@ -143,8 +122,30 @@ define([

this._level = level;

var url = this.url + "/tile/" + level + "/" + row + "/" + col;
var self = this;

// Verify if user has logged in. If they haven't and we've gotten this far in the
// code then there will be a problem because the library won't be able to retrieve
// secure tiles without appending the token to the URL
var token;
var secureInfo = window.localStorage.offline_id_manager;

if(secureInfo === undefined || secureInfo === ""){
token = "";
}
else {
var parsed = JSON.parse(secureInfo);

parsed.credentials.forEach(function(result) {
if(self.url.indexOf(result.server) !== -1) {
token = "?token=" + result.token;
}
});
}

var url = this.url + "/tile/" + level + "/" + row + "/" + col + token;
console.log("LIBRARY ONLINE " + this.offline.online);

if( this.offline.online )
{
console.log("fetching url online: ", url);
Expand Down Expand Up @@ -447,20 +448,106 @@ define([
}
},

/**
* Assign various properties to the layer
* @param result
* @param context
* @param callback
* @private
*/
_parseTileInfo: function(result, context, callback) {
// If library is offline then attempt to get layerInfo from localStorage.
if(context.offline.online === false && result === false && localStorage.__offlineTileInfo !== undefined){
result = localStorage.__offlineTileInfo;
}
else if(context.offline.online === false && result === false && localStorage.__offlineTileInfo === undefined){
alert("There was a problem retrieving tiled map info in OfflineTilesEnablerLayer.");
}

context._tilesCore._parseGetTileInfo(result,function(tileResult){
context.layerInfos = tileResult.resultObj.layers;
context.minScale = tileResult.resultObj.minScale;
context.maxScale = tileResult.resultObj.maxScale;
context.tileInfo = tileResult.tileInfo;
context._imageType = context.tileInfo.format.toLowerCase();
context.fullExtent = tileResult.fullExtent;
context.spatialReference = context.tileInfo.spatialReference;
context.initialExtent = tileResult.initExtent;
context.loaded = true;
context.onLoad(context);
callback(true);
});
},

/**
* Attempts an http request to verify if app is online or offline.
* Use this in conjunction with the offline checker library: offline.min.js
*
* More info on accessing ArcGIS Online services: https://developers.arcgis.com/authentication/accessing-arcgis-online-services/
* @param callback
*/
_getTileInfoPrivate: function(url, callback){
var self = this;
var req = new XMLHttpRequest();
var finalUrl = this.offline.proxyPath != null? this.offline.proxyPath + "?" + url + "?f=pjson" : url + "?f=pjson";
var token;
var secureInfo = window.localStorage.offline_id_manager;

if(secureInfo === undefined || secureInfo === ""){
token = "";
}
else {
var parsed = JSON.parse(secureInfo);

parsed.credentials.forEach(function(result) {
if(url.indexOf(result.server) !== -1) {
token = "&token=" + result.token;
}
});
}

var finalUrl = self.offline.proxyPath != null? self.offline.proxyPath + "?" + url + "?f=pjson" + token : url + "?f=pjson" + token;

req.open("GET", finalUrl, true);
req.onload = function()
{
if( req.status === 200 && req.responseText !== "")
{
callback(this.response);
var staticResponse = this.response;
var fixedResponse = this.response.replace(/\\'/g, "'");
var resultObj = JSON.parse(fixedResponse);

if("error" in resultObj) {
if("code" in resultObj.error) {
if(resultObj.error.code == 499 || resultObj.error.code == 498) {
console.log("Unable to log-in to tiled map service");

require([
"esri/IdentityManager"
],function(esriId) {

var cred = esriId.findCredential(url);

if (cred === undefined) {
//https://developers.arcgis.com/javascript/jssamples/widget_identitymanager_client_side.html
esriId.getCredential(url).then(function () {
self._secure = true;
window.localStorage.offline_id_manager = JSON.stringify(esriId.toJson());
self._getTileInfoPrivate(url, callback);
});
}
else {
// Run it again to see if the credentials are successful.
self._getTileInfoPrivate(url, callback);
}
});
}
}
}
else {
self._parseTileInfo(staticResponse, self, callback);
}

//callback(this.response);
}
else
{
Expand Down Expand Up @@ -991,7 +1078,27 @@ O.esri.Tiles.TilesCore = function(){
{
if(lastTileUrl)
{
var url = proxyPath? proxyPath + "?" + lastTileUrl : lastTileUrl;

// Verify if user has logged in. If they haven't and we've gotten this far in the
// code then there will be a problem because the library won't be able to retrieve
// secure tiles without appending the token to the URL
var token;
var secureInfo = window.localStorage.offline_id_manager;

if(secureInfo === undefined || secureInfo === ""){
token = "";
}
else {
var parsed = JSON.parse(secureInfo);

parsed.credentials.forEach(function(result) {
if(lastTileUrl.indexOf(result.server) !== -1) {
token = "?token=" + result.token;
}
});
}

var url = proxyPath? proxyPath + "?" + lastTileUrl + token : lastTileUrl + token;
request.get(url,{
handleAs: "text/plain; charset=x-user-defined",
headers: {
Expand Down Expand Up @@ -1132,7 +1239,8 @@ O.esri.Tiles.TilesCore = function(){
"esri/layers/LOD",
"esri/geometry/Extent",
"esri/layers/TileInfo",
"esri/geometry/Point"],function(SpatialReference,LOD,Extent,TileInfo,Point){
"esri/geometry/Point"
],function(SpatialReference,LOD,Extent,TileInfo,Point){

var spatialRef = new SpatialReference({wkid:resultObj.spatialReference.wkid});

Expand Down
4 changes: 2 additions & 2 deletions dist/offline-tiles-basic-min.js

Large diffs are not rendered by default.

27 changes: 24 additions & 3 deletions dist/offline-tiles-basic-src.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
/*! esri-offline-maps - v2.14.0 - 2015-08-14
/*! esri-offline-maps - v2.15.0 - 2015-09-29
* Copyright (c) 2015 Environmental Systems Research Institute, Inc.
* Apache License*/
define([
Expand Down Expand Up @@ -909,7 +909,27 @@ O.esri.Tiles.TilesCore = function(){
{
if(lastTileUrl)
{
var url = proxyPath? proxyPath + "?" + lastTileUrl : lastTileUrl;

// Verify if user has logged in. If they haven't and we've gotten this far in the
// code then there will be a problem because the library won't be able to retrieve
// secure tiles without appending the token to the URL
var token;
var secureInfo = window.localStorage.offline_id_manager;

if(secureInfo === undefined || secureInfo === ""){
token = "";
}
else {
var parsed = JSON.parse(secureInfo);

parsed.credentials.forEach(function(result) {
if(lastTileUrl.indexOf(result.server) !== -1) {
token = "?token=" + result.token;
}
});
}

var url = proxyPath? proxyPath + "?" + lastTileUrl + token : lastTileUrl + token;
request.get(url,{
handleAs: "text/plain; charset=x-user-defined",
headers: {
Expand Down Expand Up @@ -1050,7 +1070,8 @@ O.esri.Tiles.TilesCore = function(){
"esri/layers/LOD",
"esri/geometry/Extent",
"esri/layers/TileInfo",
"esri/geometry/Point"],function(SpatialReference,LOD,Extent,TileInfo,Point){
"esri/geometry/Point"
],function(SpatialReference,LOD,Extent,TileInfo,Point){

var spatialRef = new SpatialReference({wkid:resultObj.spatialReference.wkid});

Expand Down
2 changes: 1 addition & 1 deletion dist/offline-tpk-min.js

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion dist/offline-tpk-src.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
/*! esri-offline-maps - v2.14.0 - 2015-08-14
/*! esri-offline-maps - v2.15.0 - 2015-09-29
* Copyright (c) 2015 Environmental Systems Research Institute, Inc.
* Apache License*/
/**
Expand Down
8 changes: 8 additions & 0 deletions doc/howtousetiles.md
Original file line number Diff line number Diff line change
Expand Up @@ -232,6 +232,14 @@ For offlineTilesEnablerLayer use this pattern in the constructor:
In the constructor for `offlineTilesEnablerLayer` and in the `extend()` method for `offlineTilesEnabler` is a `state` property. This always defaults to `true`. It's important because it allows you to tell the library at runtime whether the application is online (true) or offline (false) so that the library initializes correctly.
## Working with secure tile services
If you are using a secure tiled map service then you'll need to use the `offlineTilesEnablerLayer` library. There isn't anything special you need to do, the library should automatically recognize you are using a secure service and it will trigger `esri/IdentityManager` if it cannot find valid credentials.
The library manually stores credential information using the following localStorage pattern: `window.localStorage.offline_id_manager`.
If you are using an optimized version of the ArcGIS API for JavaScript make sure you include the `esri/IdentityManager` module.
## Browser storage limitations
Our general guideline for the amount of total storage you can use on a device is be between 50MBs and 100MBs. If you need greater storage than that you'll need to either switch to a hybrid model (e.g. PhoneGap) or use one of our native ArcGIS Runtime SDKs. The Runtime SDKs have fully supported and robust offline capabilities that go beyond what JavaScript is currently capable of.
Expand Down
2 changes: 2 additions & 0 deletions doc/offlinetilesenablerlayer.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@ There are two different libraries for taking tiles offline: `offline-tiles-basic

If you have a requirement for restarting or reloading the app while offline then you should use the advanced library. The `offline-tiles-advanced-min.js` library lets you create a custom basemap layer that extends TiledMapServiceLayer.

If you have a requirement for using token-based security on your tiled map service then you'll need to use this library.

##O.esri.Tiles.OfflineTileEnablerLayer
The `offline-tiles-advanced-min.js` library provides the following tools for working with tiled map services. This library is designed for both partial and full offline use cases, and it will work if you have a requirement for browser reloads or restarts while offline.

Expand Down
Loading

0 comments on commit 9552ba1

Please sign in to comment.