// ==UserScript==
// @id iitc-plugin-bookmarkUnderDraw
// @name IITC plugin: Bookmark portals under draw or search result.
// @author Jormund
// @category Controls
// @version 1.0.0.20221113.2221
// @description [2022-11-13-2221] Bookmark portals under draw or search result.
// @updateURL https://raw.githubusercontent.com/Jormund/bookmark_under_draw/master/bookmark_under_draw.meta.js
// @downloadURL https://raw.githubusercontent.com/Jormund/bookmark_under_draw/master/bookmark_under_draw.user.js
// @match https://intel.ingress.com/*
// @match https://intel-x.ingress.com/*
// @match https://*.ingress.com/intel*
// @grant none
// ==/UserScript==
//Changelog
//1.0.0: Activate on intel-x.ingress.com
//0.2.0: Fix error with IITC-CE, MultiPolygon doesn't exist in Leaflet 1.4
//0.1.15: activate on intel.ingress.com, changed download url to github
//0.1.14: remove bookmarks under draw or search
//0.1.13: sort by name
//0.1.12: buttons to clear draw and bookmarks
//0.1.11: sort new bookmarks
//0.1.10: preference dialog now opens with the star button (removed from portal detail)
//0.1.9: handle holes (can happen in search result)
//0.1.8: use same algorithm as layer-count (better approximation of "curved" edges), still not an exact solution for GeodesicPolygons
//0.1.7: handle ingress.com and www.ingress.com
//0.1.6: dropdownlist to choose folder
function wrapper(plugin_info) {
if (typeof window.plugin !== 'function') window.plugin = function () { };
// PLUGIN START ////////////////////////////////////////////////////////
window.plugin.bookmarkUnderDraw = function () { };
window.plugin.bookmarkUnderDraw.work = {};
window.plugin.bookmarkUnderDraw.KEY_STORAGE = 'bookmarkUnderDraw-storage';
window.plugin.bookmarkUnderDraw.DRAW_TOOLS_KEY_STORAGE = 'plugin-draw-tools-layer';
window.plugin.bookmarkUnderDraw.actions = { ADD: 'ADD', REMOVE: 'REMOVE' };
window.plugin.bookmarkUnderDraw.DEFAULT_FOLDER_ID = 'idOthers'; //using string constant because bookmark plugin might not be loaded yet
window.plugin.bookmarkUnderDraw.DEFAULT_NOT_LOADED_PORTAL_NAME = 'UNKNOWN PORTAL NAME';
window.plugin.bookmarkUnderDraw.DEFAULT_BOOKMARK_UNKNOWN_PORTAL = false;
window.plugin.bookmarkUnderDraw.DEFAULT_BOOKMARK_HIDDEN_PORTAL = true;
window.plugin.bookmarkUnderDraw.sorts = {
NONE: {
code: "NONE", name: "No sort", compareFunction: function (a, b) { return 0 }
},
EAST_TO_WEST: {
code: "EAST_TO_WEST", name: "East to west",
compareFunction: function (a, b) {
if (a.lng > b.lng) return -1;
if (a.lng < b.lng) return 1;
//when lng are equal, sort SOUTH_TO_NORTH to make the sort stable
if (a.lat > b.lat) return 1;
if (a.lat < b.lat) return -1;
return 0;
}
},
WEST_TO_EAST: {
code: "WEST_TO_EAST", name: "West to east",
compareFunction: function (a, b) {
if (a.lng > b.lng) return 1;
if (a.lng < b.lng) return -1;
//when lng are equal, sort SOUTH_TO_NORTH to make the sort stable
if (a.lat > b.lat) return 1;
if (a.lat < b.lat) return -1;
return 0;
}
},
NORTH_TO_SOUTH: {
code: "NORTH_TO_SOUTH", name: "North to south",
compareFunction: function (a, b) {
if (a.lat > b.lat) return -1;
if (a.lat < b.lat) return 1;
//when lat are equal, sort WEST_TO_EAST to make the sort stable
if (a.lng > b.lng) return 1;
if (a.lng < b.lng) return -1;
return 0;
}
},
SOUTH_TO_NORTH: {
code: "SOUTH_TO_NORTH", name: "South to north",
compareFunction: function (a, b) {
if (a.lat > b.lat) return 1;
if (a.lat < b.lat) return -1;
//when lat are equal, sort WEST_TO_EAST to make the sort stable
if (a.lng > b.lng) return 1;
if (a.lng < b.lng) return -1;
return 0;
}
},
PORTAL_NAME: {
code: "PORTAL_NAME", name: "Portal name",
compareFunction: function (a, b) {
var comp = a.label.localeCompare(b.label, "en-GB"); //TODO:let user choose locale ?
if (comp != 0) return comp;
//if (a.label > b.label) return 1;
//if (a.label < b.label) return -1;
//when equal, use lat&lng to make the sort stable
//WEST_TO_EAST
if (a.lng > b.lng) return 1;
if (a.lng < b.lng) return -1;
//SOUTH_TO_NORTH
if (a.lat > b.lat) return 1;
if (a.lat < b.lat) return -1;
return 0;
}
}
};
window.plugin.bookmarkUnderDraw.sortedSorts = [
window.plugin.bookmarkUnderDraw.sorts.NONE,
window.plugin.bookmarkUnderDraw.sorts.WEST_TO_EAST,
window.plugin.bookmarkUnderDraw.sorts.EAST_TO_WEST,
window.plugin.bookmarkUnderDraw.sorts.NORTH_TO_SOUTH,
window.plugin.bookmarkUnderDraw.sorts.SOUTH_TO_NORTH,
window.plugin.bookmarkUnderDraw.sorts.PORTAL_NAME
];
//window.plugin.bookmarkUnderDraw.DEFAULT_SORT = window.plugin.bookmarkUnderDraw.sorts.NONE;
window.plugin.bookmarkUnderDraw.DEFAULT_SORT_CODE = window.plugin.bookmarkUnderDraw.sorts.NONE.code;
window.plugin.bookmarkUnderDraw.storage = {
folderId: window.plugin.bookmarkUnderDraw.DEFAULT_FOLDER_ID,
sortCode: window.plugin.bookmarkUnderDraw.DEFAULT_SORT_CODE,
notLoadedPortalName: window.plugin.bookmarkUnderDraw.DEFAULT_NOT_LOADED_PORTAL_NAME,
bookmarkUnknownPortal: window.plugin.bookmarkUnderDraw.DEFAULT_BOOKMARK_UNKNOWN_PORTAL,
bookmarkHiddenPortal: window.plugin.bookmarkUnderDraw.DEFAULT_BOOKMARK_HIDDEN_PORTAL
};
//star icon
// window.plugin.bookmarkUnderDraw.ico = 'data:image/svg+xml;utf8,';//utf-8 svg not working for reason unknown, using base64 instead
window.plugin.bookmarkUnderDraw.bookmarkIcon = "data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIzMCIgaGVpZ2h0PSIzMCI+DQoJPGcgc3R5bGU9ImZpbGw6ICNGQUNBMDA7IGZpbGwtb3BhY2l0eTogMTsgc3Ryb2tlOiBub25lOyI+DQogICAgPHBhdGggZD0iTSAxNSwxIDE4LDEyIDI5LDEyIDIwLDE4IDI0LDI4IDE1LDIxIDYsMjggMTAsMTggMSwxMiAxMiwxMiBaIiAvPg0KCTwvZz4NCjwvc3ZnPg==";
// STORAGE //////////////////////////////////////////////////////////
// update the localStorage with preferences
window.plugin.bookmarkUnderDraw.saveStorage = function () {
localStorage[window.plugin.bookmarkUnderDraw.KEY_STORAGE] = JSON.stringify(window.plugin.bookmarkUnderDraw.storage);
};
// load the localStorage datas
window.plugin.bookmarkUnderDraw.loadStorage = function () {
if (typeof localStorage[window.plugin.bookmarkUnderDraw.KEY_STORAGE] != "undefined") {
window.plugin.bookmarkUnderDraw.storage = JSON.parse(localStorage[window.plugin.bookmarkUnderDraw.KEY_STORAGE]);
}
//ensure default values are always set
if (typeof window.plugin.bookmarkUnderDraw.storage.folderId == "undefined") {
window.plugin.bookmarkUnderDraw.storage.folderId = window.plugin.bookmarkUnderDraw.DEFAULT_FOLDER_ID;
}
if (typeof window.plugin.bookmarkUnderDraw.storage.sortCode == "undefined") {
window.plugin.bookmarkUnderDraw.storage.sortCode = window.plugin.bookmarkUnderDraw.DEFAULT_SORT_CODE;
}
if (typeof window.plugin.bookmarkUnderDraw.storage.notLoadedPortalName == "undefined") {
window.plugin.bookmarkUnderDraw.storage.notLoadedPortalName = window.plugin.bookmarkUnderDraw.DEFAULT_NOT_LOADED_PORTAL_NAME;
}
if (typeof window.plugin.bookmarkUnderDraw.storage.bookmarkUnknownPortal == "undefined") {
window.plugin.bookmarkUnderDraw.storage.bookmarkUnknownPortal = window.plugin.bookmarkUnderDraw.DEFAULT_BOOKMARK_UNKNOWN_PORTAL;
}
if (typeof window.plugin.bookmarkUnderDraw.storage.bookmarkHiddenPortal == "undefined") {
window.plugin.bookmarkUnderDraw.storage.bookmarkHiddenPortal = window.plugin.bookmarkUnderDraw.DEFAULT_BOOKMARK_HIDDEN_PORTAL;
}
};
// FUNCTIONS ////////////////////////////////////////////////////////
/*
pnpoly Copyright (c) 1970-2003, Wm. Randolph Franklin
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated
documentation files (the "Software"), to deal in the Software without restriction, including without limitation the
rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit
persons to whom the Software is furnished to do so, subject to the following conditions:
1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following
disclaimers.
2. Redistributions in binary form must reproduce the above copyright notice in the documentation and/or other
materials provided with the distribution.
3. The name of W. Randolph Franklin may not be used to endorse or promote products derived from this Software without
specific prior written permission.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
window.plugin.bookmarkUnderDraw.pnpoly = function (latlngs, point) {
var length = latlngs.length, c = false;
for (var i = 0, j = length - 1; i < length; j = i++) {
if (((latlngs[i].lat > point.lat) != (latlngs[j].lat > point.lat)) &&
(point.lng < latlngs[i].lng + (latlngs[j].lng - latlngs[i].lng) * (point.lat - latlngs[i].lat) / (latlngs[j].lat - latlngs[i].lat))) {
c = !c;
}
}
return c;
}
window.plugin.bookmarkUnderDraw.circleToSearchCircle = function (drawnItem) {
var circleCenter = drawnItem.getLatLng();
var result = { type: 'circle', radius: drawnItem.getRadius(), center: new L.LatLng(circleCenter.lat, circleCenter.lng) };
return result;
};
//drawnItem can be multipolygon or polygon
window.plugin.bookmarkUnderDraw.multiPolygonToSearchPolygons = function (drawnItem) {
var result = [];
var polygonArr = [];
if (drawnItem instanceof L.GeodesicPolygon) {
//_latlngs contains the Polygon path used to approximate the GeodesicPolygon
//we use this because the pnpoly algorithm is not suited for GeodesicPolygon and the approximation works better
if (typeof drawnItem._latlngs != "undefined" && drawnItem._latlngs.length > 0) {
if (typeof drawnItem._latlngs[0].lng == "number") {
polygonArr = drawnItem._latlngs.map(function (item) { return [item.lng, item.lat] });
polygonArr = [polygonArr]; //handle simple polygon like a multipolygon of one polygon only
} else if (typeof drawnItem._latlngs[0][0].lng == "number") {
$.each(drawnItem._latlngs, function (i, latLngs) {//each latLngs is a polygon of a multipolygon
var innerPolygonArr = latLngs.map(function (item) { return [item.lng, item.lat] });
polygonArr.push(innerPolygonArr);
});
}
}
}
else {
//console.log("Not a GeodesicPolygon");
polygonArr = drawnItem.toGeoJSON().geometry.coordinates;
if (polygonArr[0].length == 2 && typeof polygonArr[0][0] == "number") {
//console.log("Not a MultiPolygon");
polygonArr = [polygonArr]; //handle simple polygon like a multipolygon of one polygon only
}
}
//console.log("polygonArr:"+polygonArr.length);
$.each(polygonArr, function (i, polygonCoords) {//each polygonCoords is a polygon of a multipolygon
var searchPolygon = {
type: 'polygon',
outerRing: [],
holes: []
};
if (polygonCoords[0].length == 2 && typeof polygonCoords[0][0] == "number") {
//polygon has no hole, we wrap it in an array
polygonCoords = [polygonCoords];
}
//console.log(i+" polygonCoords:"+polygonCoords.length);
$.each(polygonCoords, function (j, linearRing) {//in a polygon, the first set of coords is the outside bound, the others are holes
var latLngArr = [];
//console.log(j+" linearRing:"+linearRing.length);
$.each(linearRing, function (k, latlng) {
var obj = { lng: latlng[0], lat: latlng[1] };
latLngArr.push(obj);
//console.log(k+" latLngArr:" + latLngArr.length);
});
if (j == 0) {
searchPolygon.outerRing = latLngArr;
}
else {
searchPolygon.holes.push(latLngArr);
}
//console.log("searchPolygon.outerRing:"+searchPolygon.outerRing.length);
//console.log("searchPolygon.holes:"+searchPolygon.holes.length);
});
result.push(searchPolygon);
//console.log("result:"+result.length);
});
return result;
};
window.plugin.bookmarkUnderDraw.doTheJob = function (options) {
if (!window.plugin.bookmarks) {
console.log('Bookmarks Under Draw ERROR : Bookmark plugin required');
alert('Bookmarks plugin required');
return false;
}
window.plugin.bookmarkUnderDraw.work.searchItems = [];
if (!!window.plugin.drawTools && !!window.plugin.drawTools.drawnItems) {
window.plugin.drawTools.drawnItems.eachLayer(function (drawnItem) {
if (drawnItem instanceof L.GeodesicCircle) {//must be tested first because GeodesicCircle inherit from Polygon
var searchCircle = window.plugin.bookmarkUnderDraw.circleToSearchCircle(drawnItem);
window.plugin.bookmarkUnderDraw.work.searchItems.push(searchCircle);
}
else if (drawnItem instanceof L.GeodesicPolygon) {
var searchPolygons = window.plugin.bookmarkUnderDraw.multiPolygonToSearchPolygons(drawnItem);
//console.log("searchPolygons:"+searchPolygons.length);
$.each(searchPolygons, function (index, searchItem) {
window.plugin.bookmarkUnderDraw.work.searchItems.push(searchItem);
});
}
else if (drawnItem instanceof L.GeodesicPolyline || drawnItem instanceof L.Marker) {
//ignored, nothing to do
}
else {
//should not happen
console.log('Bookmark Under Draw : unknown drawn item type');
}
});
}
//if search, add it to job
if (window.search.lastSearch &&
window.search.lastSearch.selectedResult &&
window.search.lastSearch.selectedResult.layer) {
window.search.lastSearch.selectedResult.layer.eachLayer(function (drawnItem) {
if (drawnItem instanceof L.Polygon || (typeof L.MultiPolygon == "function" && drawnItem instanceof L.MultiPolygon)) {
var searchPolygons = window.plugin.bookmarkUnderDraw.multiPolygonToSearchPolygons(drawnItem);
$.each(searchPolygons, function (index, searchItem) {
window.plugin.bookmarkUnderDraw.work.searchItems.push(searchItem);
});
}
});
}
if (window.plugin.bookmarkUnderDraw.work.searchItems.length == 0) {
//warning icon
var img = '';
alert(img + ' A polygon or circle must be drawn or a search result selected');
return false;
}
else {
console.log('Bookmark Under Draw :' + window.plugin.bookmarkUnderDraw.work.searchItems.length + ' shapes found');
}
var bookmarkUnderDraw = function (options) {
if (typeof options == 'undefined') options = {};
if (typeof options.folderId == 'undefined') options.folderId = window.plugin.bookmarkUnderDraw.DEFAULT_FOLDER_ID;
if (typeof options.notLoadedPortalName == 'undefined') options.notLoadedPortalName = window.plugin.bookmarkUnderDraw.DEFAULT_NOT_LOADED_PORTAL_NAME;
if (typeof options.bookmarkUnknownPortal == 'undefined') options.bookmarkUnknownPortal = window.plugin.bookmarkUnderDraw.DEFAULT_BOOKMARK_UNKNOWN_PORTAL;
if (typeof options.bookmarkHiddenPortal == 'undefined') options.bookmarkHiddenPortal = window.plugin.bookmarkUnderDraw.DEFAULT_BOOKMARK_HIDDEN_PORTAL;
if (typeof options.sort == 'undefined' || typeof options.sortCode == 'undefined') {
options.sortCode = window.plugin.bookmarkUnderDraw.DEFAULT_SORT_CODE;
options.sort = window.plugin.bookmarkUnderDraw.sorts[options.sortCode];
}
var t = this;
this._w_ = {}; //work variables
this.bookmarkedPortals = {}; //bookmarks guids
this.distinctPortalUnderDrawCount = 0;
this.bookmarkAddCount = 0;
this.bookmarkRemoveCount = 0;
this.wrongDataCount = 0;
this.alreadyExistCount = 0;
//this.foundTwiceCount = 0;//obsolete
this.options = options;
return t;
};
bookmarkUnderDraw.prototype.initialize = function (searchItems) {
var t = this;
//t._w_ = window.plugin.bookmarkUnderDraw.work;
t._w_.searchItems = searchItems;
t._w_.portalsUnderDraw = []; //guids of portals under draw
};
bookmarkUnderDraw.prototype.run = function () {
var t = this;
var input = window.portals;
//when removing bookmarks, we can restrict ourselves to bookmarks
if (t.options.action == window.plugin.bookmarkUnderDraw.actions.REMOVE) {
input = {};
var list = window.plugin.bookmarks.bkmrksObj['portals'];
for (var idFolders in list) {
for (var idBkmrk in list[idFolders]['bkmrk']) {
var portalGuid = list[idFolders]['bkmrk'][idBkmrk]['guid'];
var portal = window.portals[portalGuid];
if (portal) {
input[portalGuid] = portal;
}
}
}
}
console.log("portals:" + input.length);
$.each(input, function (guid, portal) {
var point = portal.getLatLng();
var found = false;
$.each(t._w_.searchItems, function (index, searchItem) {
switch (searchItem.type) {
case 'circle':
if (t.pointIsInCircle(point, searchItem)) {
found = true;
console.log("in circle:" + point.lat + "," + point.lng);
return false; //breaks the $.each
}
break;
case 'polygon':
if (t.pointIsInPolygon(point, searchItem)) {
found = true;
console.log("in polygon:" + point.lat + "," + point.lng);
return false; //breaks the $.each
}
break;
default:
console.log('Bookmark Under Draw ERROR : invalid draw type (' + searchItem.type + ')');
return true; //continue the $.each
break;
};
});
//console.log("found"+found);
if (found) {
t._w_.portalsUnderDraw.push(guid);
}
});
if (t.options.action == window.plugin.bookmarkUnderDraw.actions.ADD) {
t.bookmarkPortals();
}
else if (t.options.action == window.plugin.bookmarkUnderDraw.actions.REMOVE) {
t.removeBookmarks();
}
else {
//should not happen
}
t.render();
};
bookmarkUnderDraw.prototype.pointIsInPolygon = function (point, searchItem) {
var nodeIn = window.plugin.bookmarkUnderDraw.pnpoly(searchItem.outerRing, point);
$.each(searchItem.holes, function (index, hole) {
var inHole = window.plugin.bookmarkUnderDraw.pnpoly(hole, point);
if (inHole) {
nodeIn = false; //portal is in the hole so not in the polygon
return false; //breaks the loop
}
});
return nodeIn;
};
bookmarkUnderDraw.prototype.pointIsInCircle = function (point, searchItem) {
//var t = this;
var found = false;
if (searchItem.center.distanceTo(point) <= searchItem.radius) {
found = true;
}
return found;
};
bookmarkUnderDraw.prototype.removeBookmarks = function () {
var t = this;
$.each(t._w_.portalsUnderDraw, function (index, guid) {
var list = window.plugin.bookmarks.bkmrksObj['portals'];
var bkmrkData = window.plugin.bookmarks.findByGuid(guid);
if (bkmrkData) {
//bookmark exists
t.bookmarkRemoveCount++;
delete list[bkmrkData['id_folder']]['bkmrk'][bkmrkData['id_bookmark']]; //inspired by window.plugin.bookmarks.switchStarPortal
//$('.bkmrk#' + bkmrkData['id_bookmark'] + '').remove();//handled by the refresh below
}
else {
//do nothing
}
});
window.plugin.bookmarks.saveStorage();
window.plugin.bookmarks.refreshBkmrks();
window.runHooks('pluginBkmrksEdit', { "target": "all", "action": "import" });
console.log('bookmarkUnderDraw: refreshed bookmarks');
}
//used instead of bookmark plugin because the original code makes only 99 different IDs in the same millisecond
bookmarkUnderDraw.prototype.generateID = function () {
var d = new Date();
var ID = Math.floor(Math.random() * 1e10) + 1;
//var ID = d.getTime()+(Math.floor(Math.random()*99)+1);//id1 472 936 881 241
ID = 'id' + ID.toString();
return ID;
}
bookmarkUnderDraw.prototype.bookmarkPortals = function () {
var t = this;
var folderBkmrks = window.plugin.bookmarks.bkmrksObj['portals'][t.options.folderId]['bkmrk'];
var newBookmarks = [];
$.each(t._w_.portalsUnderDraw, function (index, guid) {
//if (typeof t.bookmarkedPortals[guid] == 'undefined') {//we check if portal was added by our loop, can happen if draws overlap//28/05/2018: cannot happen since we loop on portals only once
var bkmrkData = window.plugin.bookmarks.findByGuid(guid);
if (bkmrkData) {
//bookmark exists
t.alreadyExistCount++;
}
else {
var portal = window.portals[guid];
var portalName = portal.options.data.title;
if (typeof portalName == 'string' || t.options.bookmarkUnknownPortal) {//add portal only if name is loaded or override is chosen
if (t.options.bookmarkHiddenPortal || window.map.hasLayer(portal)) {//add portal only if it is not filtered out or override is chosen
var ll = portal.getLatLng();
//window.plugin.bookmarks.addPortalBookmark(guid, ll.lat + ',' + ll.lng, portalName); //actually bookmarks the portal
//02/09/2016: only add the bookmark to JS obj to make it faster
var bookmarkID = t.generateID();
// Add bookmark in the localStorage
var latlng = ll.lat + ',' + ll.lng;
var label = portalName || t.options.notLoadedPortalName;
var newBookmark = {
"guid": guid, "latlng": latlng, "label": label,
"id": bookmarkID, lat: ll.lat, lng: ll.lng //used for sort, will be deleted before adding to the bookmark plugin
};
newBookmarks.push(newBookmark);
//console.log('bookmarkUnderDraw: added portal ' + ID);
//window.runHooks('pluginBkmrksEdit', { "target": "portal", "action": "add", "id": ID, "guid": guid });//02/09/2016: only refresh once
t.bookmarkAddCount++;
}
}
else {
t.wrongDataCount++;
}
}
t.bookmarkedPortals[guid] = {}; //keep result for the count and the next checks
t.distinctPortalUnderDrawCount++;
// }
// else {
// //bookmark exists
// t.foundTwiceCount++;
// }
});
//sort result if a sort is selected
if (t.options.sort.code != window.plugin.bookmarkUnderDraw.sorts.NONE.code) {
newBookmarks.sort(t.options.sort.compareFunction);
}
//create the bookmarks
$.each(newBookmarks, function (index, newBookmark) {
var bookmarkID = newBookmark.id;
delete newBookmark.id;
delete newBookmark.lat;
delete newBookmark.lng;
folderBkmrks[bookmarkID] = newBookmark;
});
//02/09/2016: only refresh once
window.plugin.bookmarks.saveStorage();
window.plugin.bookmarks.refreshBkmrks();
window.runHooks('pluginBkmrksEdit', { "target": "all", "action": "import" });
console.log('bookmarkUnderDraw: refreshed bookmarks');
};
bookmarkUnderDraw.prototype.setMessage = function (message, makeVisible) {
if (makeVisible) {
setTimeout(function () {
window.plugin.bookmarkUnderDraw.button.classList.add("active");
}, 1);
}
setTimeout(function () {
window.plugin.bookmarkUnderDraw.messageBox.innerHTML = message;
}, 1);
};
bookmarkUnderDraw.prototype.render = function () {
var t = this;
var message = '';
if (t.options.action == window.plugin.bookmarkUnderDraw.actions.ADD) {
var bookmarkedPortalCount = t.bookmarkAddCount; // Object.keys(t.bookmarkedPortals).length;
var totalPortalCount = t.distinctPortalUnderDrawCount;
if (totalPortalCount > 0) {
if (totalPortalCount == 1)
message += totalPortalCount + ' portal found';
else
message += totalPortalCount + ' portals found';
}
else {
message += 'No portal found';
}
message += ', ' + bookmarkedPortalCount + ' new';
if (t.alreadyExistCount > 0)
message += ', ' + t.alreadyExistCount + ' old';
if (t.wrongDataCount > 0)
message += ', ' + t.wrongDataCount + ' not loaded';
} else if (t.options.action == window.plugin.bookmarkUnderDraw.actions.REMOVE) {
if (t.bookmarkRemoveCount > 0) {
if (t.bookmarkRemoveCount == 1)
message += t.bookmarkRemoveCount + ' bookmark removed';
else
message += t.bookmarkRemoveCount + ' bookmarks removed';
}
else {
message += 'No bookmark removed';
}
}
var zoomLevel = $('#loadlevel').html();
if (zoomLevel != 'all') {
message += ' Portals might be missing. Zoom level :' + zoomLevel + '';
}
t.setMessage(message, true); //setTimeout copied from layer-count, don't know why
};
//doTheJob
//var options = window.plugin.bookmarkUnderDraw.storage;
var worker = new bookmarkUnderDraw(options);
window.plugin.bookmarkUnderDraw.work.lastWorker = worker; //debug
worker.initialize(window.plugin.bookmarkUnderDraw.work.searchItems);
worker.run();
};
window.plugin.bookmarkUnderDraw.messageBoxClicked = function (evt) {
//console.log('window.plugin.bookmarkUnderDraw.messageBoxClicked');
var btn = window.plugin.bookmarkUnderDraw.button;
var messageBox = window.plugin.bookmarkUnderDraw.messageBox;
btn.classList.remove("active");
messageBox.textContent = "";
evt.stopPropagation();
};
//inspired by window.plugin.drawTools.optReset
window.plugin.bookmarkUnderDraw.resetDraw = function () {
if (window.plugin.drawTools) {
delete localStorage[window.plugin.bookmarkUnderDraw.DRAW_TOOLS_KEY_STORAGE];
window.plugin.drawTools.drawnItems.clearLayers();
window.plugin.drawTools.load();
runHooks('pluginDrawTools', { event: 'clear' });
}
};
//inspired by window.plugin.bookmarks.optReset
window.plugin.bookmarkUnderDraw.resetBookmarks = function () {
delete localStorage[window.plugin.bookmarks.KEY_STORAGE];
window.plugin.bookmarks.createStorage();
window.plugin.bookmarks.loadStorage();
window.plugin.bookmarks.refreshBkmrks();
window.runHooks('pluginBkmrksEdit', { "target": "all", "action": "reset" });
};
window.plugin.bookmarkUnderDraw.resetOpt = function () {
window.plugin.bookmarkUnderDraw.storage.folderId = window.plugin.bookmarkUnderDraw.DEFAULT_FOLDER_ID;
window.plugin.bookmarkUnderDraw.storage.sortCode = window.plugin.bookmarkUnderDraw.DEFAULT_SORT_CODE;
window.plugin.bookmarkUnderDraw.storage.notLoadedPortalName = window.plugin.bookmarkUnderDraw.DEFAULT_NOT_LOADED_PORTAL_NAME;
window.plugin.bookmarkUnderDraw.storage.bookmarkUnknownPortal = window.plugin.bookmarkUnderDraw.DEFAULT_BOOKMARK_UNKNOWN_PORTAL;
window.plugin.bookmarkUnderDraw.storage.bookmarkHiddenPortal = window.plugin.bookmarkUnderDraw.DEFAULT_BOOKMARK_HIDDEN_PORTAL;
window.plugin.bookmarkUnderDraw.saveStorage();
window.plugin.bookmarkUnderDraw.openOptDialog();
}
window.plugin.bookmarkUnderDraw.saveOpt = function () {
var options = {};
options.folderId = $('#bookmarkUnderDraw-folderId').val();
options.notLoadedPortalName = $('#bookmarkUnderDraw-notLoadedPortalName').val();
options.bookmarkUnknownPortal = $('#bookmarkUnderDraw-bookmarkUnknownPortal').is(":checked");
options.bookmarkHiddenPortal = $('#bookmarkUnderDraw-bookmarkHiddenPortal').is(":checked");
options.sortCode = $('#bookmarkUnderDraw-sortCode').val();
var sort = window.plugin.bookmarkUnderDraw.sorts[options.sortCode];
if (typeof sort == 'undefined') {
options.sortCode = window.plugin.bookmarkUnderDraw.DEFAULT_SORT_CODE;
sort = window.plugin.bookmarkUnderDraw.sorts[options.sortCode];
}
options.sort = sort;
window.plugin.bookmarkUnderDraw.storage.folderId = options.folderId;
window.plugin.bookmarkUnderDraw.storage.sortCode = options.sortCode;
window.plugin.bookmarkUnderDraw.storage.notLoadedPortalName = options.notLoadedPortalName;
window.plugin.bookmarkUnderDraw.storage.bookmarkUnknownPortal = options.bookmarkUnknownPortal;
window.plugin.bookmarkUnderDraw.storage.bookmarkHiddenPortal = options.bookmarkHiddenPortal;
window.plugin.bookmarkUnderDraw.saveStorage();
return options;
}
window.plugin.bookmarkUnderDraw.saveOptAndRemoveBookmarks = function () {
var options = window.plugin.bookmarkUnderDraw.saveOpt();
options.action = window.plugin.bookmarkUnderDraw.actions.REMOVE;
window.plugin.bookmarkUnderDraw.doTheJob(options);
}
window.plugin.bookmarkUnderDraw.saveOptAndBookmarkPortals = function () {
var options = window.plugin.bookmarkUnderDraw.saveOpt();
options.action = window.plugin.bookmarkUnderDraw.actions.ADD;
window.plugin.bookmarkUnderDraw.doTheJob(options);
}
window.plugin.bookmarkUnderDraw.openOptDialog = function () {
var html =
'
| ' + 'Send alert even if portal name is not loaded' + ' | ' + '' + '' + ' | ' + '
| ' + 'Send alert even if portal is hidden' + ' | ' + '' + '' + ' | ' + '
| ' + 'Folder :' + ' | ' + ''; html += ''; html += ' | ' + '
| ' + 'Sort :' + ' | ' + ''; html += ''; html += ' | ' + '
| ' + 'Missing portal name :' + ' | ' + '' + '' + ' | ' + '