function RemoGeoLocation() {
|
this._remoteSvrUrl = "https://webapi.amap.com/html/geolocate.html";
|
|
this._callbackList = [];
|
|
this._seqBase = 1;
|
|
this._frameReady = 0;
|
|
this._watchIdMap = {};
|
}
|
|
RemoGeoLocation.prototype = {
|
_getSeq: function () {
|
return this._seqBase++;
|
},
|
_onRrameReady: function (callback) {
|
if (this._frameReady === 0) {
|
if (!this._frameReadyList) {
|
this._frameReadyList = [];
|
}
|
|
this._frameReadyList.push(callback);
|
|
this._prepareIframe();
|
|
return;
|
}
|
|
callback.call(this);
|
},
|
_prepareIframe: function () {
|
if (this._iframeWin) {
|
return;
|
}
|
|
var ifrm = document.createElement("iframe");
|
|
ifrm.src =
|
this._remoteSvrUrl + (this._remoteSvrUrl.indexOf("?") > 0 ? "&" : "?");
|
|
ifrm.width = "0px";
|
ifrm.height = "0px";
|
ifrm.style.position = "absolute";
|
ifrm.style.display = "none";
|
|
var self = this;
|
|
var timeoutId = setTimeout(function () {
|
self._frameReady = false;
|
|
self._callbackFrameReadyList();
|
}, 5000);
|
|
ifrm.onload = function () {
|
clearTimeout(timeoutId);
|
|
self._frameReady = true;
|
|
self._callbackFrameReadyList();
|
|
ifrm.onload = null;
|
};
|
|
document.body.appendChild(ifrm);
|
|
this._iframeWin = ifrm.contentWindow;
|
|
window.addEventListener(
|
"message",
|
function (e) {
|
if (self._remoteSvrUrl.indexOf(e["origin"]) !== 0) {
|
return;
|
}
|
|
self._handleRemoteMsg(e["data"]);
|
},
|
false
|
);
|
},
|
_callbackFrameReadyList: function () {
|
if (this._frameReadyList) {
|
var list = this._frameReadyList;
|
this._frameReadyList = null;
|
|
for (var i = 0, len = list.length; i < len; i++) {
|
list[i].call(this, this._frameReady);
|
}
|
}
|
},
|
_pickCallback: function (seqNum, keepInList) {
|
var callbackList = this._callbackList;
|
|
for (var i = 0, len = callbackList.length; i < len; i++) {
|
var cbkInfo = callbackList[i];
|
|
if (seqNum === cbkInfo.seq) {
|
if (!keepInList) {
|
callbackList.splice(i, 1);
|
}
|
|
return cbkInfo;
|
}
|
}
|
},
|
_handleRemoteMsg: function (msg) {
|
var seqNum = msg["seq"];
|
|
var cbkInfo = this._pickCallback(seqNum, !!msg["notify"]);
|
|
if (cbkInfo) {
|
cbkInfo.cbk.call(null, msg["error"], msg["result"]);
|
} else {
|
console.warn("Receive remote msg: ", msg);
|
}
|
},
|
_postMessage: function (cmd, args, callback, seq) {
|
this._prepareIframe();
|
|
var msg = {
|
cmd: cmd,
|
args: args,
|
seq: seq || this._getSeq(),
|
};
|
|
this._callbackList.push({
|
cbk: callback,
|
seq: msg["seq"],
|
});
|
|
this._onRrameReady(function () {
|
if (this._frameReady === true) {
|
try {
|
this._iframeWin.postMessage(msg, "*");
|
} catch (e) {
|
this._pickCallback(msg["seq"]);
|
|
callback(e);
|
}
|
} else {
|
this._pickCallback(msg["seq"]);
|
|
callback({
|
message: "iFrame load failed!",
|
});
|
}
|
});
|
},
|
getCurrentPosition: function (succHandler, errHandler, options) {
|
this._postMessage("getCurrentPosition", [options], function (err, result) {
|
if (err) {
|
if (errHandler) {
|
errHandler(err);
|
}
|
return;
|
}
|
if (succHandler) {
|
succHandler(result);
|
}
|
});
|
},
|
watchPosition: function (succHandler, errHandler, options) {
|
var watchKey = "wk" + this._getSeq(),
|
cmdSeq = this._getSeq();
|
|
this._watchIdMap[watchKey] = {
|
stat: 0,
|
seq: cmdSeq,
|
};
|
|
var self = this;
|
|
this._postMessage(
|
"watchPosition",
|
[options],
|
function (err, result) {
|
var id = null;
|
|
if (result) {
|
id = result["id"];
|
}
|
|
var watchInfo = self._watchIdMap[watchKey];
|
|
watchInfo.id = id;
|
watchInfo.stat = 1;
|
|
if (watchInfo.callbackList) {
|
var list = watchInfo.callbackList;
|
watchInfo.callbackList = null;
|
|
for (var i = 0, len = list.length; i < len; i++) {
|
list[i].call(self, id);
|
}
|
}
|
|
if (err) {
|
if (errHandler) {
|
errHandler(err);
|
}
|
return;
|
}
|
|
if (succHandler) {
|
succHandler(result["pos"]);
|
}
|
},
|
cmdSeq
|
);
|
|
return watchKey;
|
},
|
clearWatch: function (watchKey, callback) {
|
if (!this._watchIdMap[watchKey]) {
|
callback("Id not exists: " + watchKey);
|
return;
|
}
|
|
var watchInfo = this._watchIdMap[watchKey];
|
|
var self = this;
|
|
function clearId(id) {
|
self._postMessage("clearWatch", [id], function (err, result) {
|
if (!err) {
|
self._pickCallback(watchInfo.seq);
|
|
delete self._watchIdMap[watchKey];
|
}
|
|
if (callback) {
|
callback(err, result);
|
}
|
});
|
}
|
|
if (watchInfo.stat < 1) {
|
if (!watchInfo.callbackList) {
|
watchInfo.callbackList = [];
|
}
|
|
watchInfo.callbackList.push(function (id) {
|
clearId(id);
|
});
|
} else {
|
clearId(watchInfo.id);
|
}
|
},
|
};
|
|
export default RemoGeoLocation;
|