diff --git a/crosslinks-enhancements.user.js b/crosslinks-enhancements.user.js index 5bc850a..550e3fb 100644 --- a/crosslinks-enhancements.user.js +++ b/crosslinks-enhancements.user.js @@ -1,3 +1,22 @@ +// ==UserScript== +// @id crosslinks-enhancements +// @name Crosslinks Enhancements +// @description Adds options to limit cross links detection by drawn items color and to cross links inside a polygon +// @category Misc +// @version 1.0 +// @author MarcioPG +// @website https://github.com/manierim/crosslinks-enhancements +// @updateURL https://github.com/manierim/crosslinks-enhancements/raw/master/crosslinks-enhancements.meta.js +// @downloadURL https://github.com/manierim/crosslinks-enhancements/raw/master/crosslinks-enhancements.user.js +// @namespace https://github.com/manierim +// @include *://*.ingress.com/intel* +// @include *://intel.ingress.com/* +// @match *://*.ingress.com/intel* +// @match *://intel.ingress.com/* +// @grant none +// @require https://cdn.rawgit.com/hayeswise/Leaflet.PointInPolygon/v1.0.0/wise-leaflet-pip.js +// ==/UserScript== + // MarcioPG WRAPPER v1.0 START ///////////////////////////////////////////// function wrapper() { @@ -8,13 +27,12 @@ function wrapper() { // PLUGIN START //////////////////////////////////////////////////////// window.plugin.crossLinksEnhancements = function () { }; - $plugin = window.plugin.crossLinksEnhancements; + var $plugin = window.plugin.crossLinksEnhancements; //------------------------------------------------------------- // Init & Setup //------------------------------------------------------------- - $plugin.initDone = false; $plugin.init = function () { @@ -28,9 +46,10 @@ function wrapper() { return; } + $plugin.opts.init(); $plugin.crossLinks.init(); - $plugin.ui.init(); + $plugin.draw.init(); } @@ -46,110 +65,332 @@ function wrapper() { } //------------------------------------------------------------- - // Filtering + // Storage //------------------------------------------------------------- + $plugin.storage = {}; + + $plugin.storage.prefix = 'plugin-crosslinks-enhancements.'; + + $plugin.storage.put = function (key, object) { + + if (object.polygon) { + object.polygon = JSON.stringify(object.polygon.getLatLngs()); + } + + localStorage.setItem($plugin.storage.prefix + key, JSON.stringify(object)); + } + + $plugin.storage.get = function (key) { - $plugin.selectedColors = []; - $plugin.drawcolors = []; + if (string = localStorage.getItem($plugin.storage.prefix + key)) { + object = JSON.parse(string); + if (object.polygon) { - $plugin.polygons = []; + var saved = object.polygon; + object.polygon = null; - $plugin.ShouldCheckDrawnItem = function (drawItem, closed) { + var colorsAndPolygons = $plugin.draw.colorsAndPolygons(); - if ($plugin.drawcolors.indexOf(drawItem.options.color) === -1) { - $plugin.drawcolors.push(drawItem.options.color); + colorsAndPolygons.polygons.forEach(function (poly) { + if (JSON.stringify(poly.getLatLngs()) === saved) { + object.polygon = poly; + } + }); + + } + return object; } - if (closed !== undefined && closed - && $plugin.polygons.indexOf(drawItem._leaflet_id) === -1 + return null; + } + + + //------------------------------------------------------------- + // Options + //------------------------------------------------------------- + $plugin.opts = {}; + + $plugin.opts.refreshed = function () { + $plugin.crossLinks.refresh(); + $plugin.destroyedLinks.refresh(); + } + + $plugin.opts.init = function () { + if (opts = $plugin.storage.get('opts')) { + $plugin.opts.set(opts, true); + } + } + + $plugin.opts.set = function (opts, firstload) { + + if (firstload == undefined) { + firstload = false; + } + + var mustRefresh = $plugin.filters.colors.set(opts.colors); + + if ($plugin.filters.polygon.set(opts.polygon)) { + mustRefresh = true; + } + + if (mustRefresh && !firstload) { + $plugin.opts.refreshed(); + } + + if (!firstload) { + $plugin.storage.put('opts', opts); + } + + } + + //------------------------------------------------------------- + // Draw + //------------------------------------------------------------- + $plugin.draw = {}; + + $plugin.draw.event = function (e) { + + var refresh = false; + + if (e.event === 'layersDeleted' + && $plugin.filters.polygon.selected + && plugin.drawTools.drawnItems._layers[$plugin.filters.polygon.selected._leaflet_id] === undefined ) { - /** @todo - * must save the stringified drawItem.getLatLngs() - * to find the new _leaflet_id upon reload! - */ + // è stato cancellato il poligono selezionato! + refresh = $plugin.filters.polygon.set(null); + } + else if (e.event == 'layersEdited' + && $plugin.filters.polygon.selected + ) { + var newJson = JSON.stringify($plugin.filters.polygon.selected.getLatLngs()); + if (string = localStorage.getItem($plugin.storage.prefix + 'opts')) { + object = JSON.parse(string); + if (object.polygon) { + + var oldJson = object.polygon; + if (oldJson != newJson) { + $plugin.filters.polygon._cachedlinkGuids = {}; + refresh = true; + } + } + } + } + + if (refresh) { + $plugin.opts.refreshed(); + $plugin.storage.put('opts', opts); + } + } + + $plugin.draw.init = function () { + addHook('pluginDrawTools', $plugin.draw.event); + }; + + $plugin.draw.colorsAndPolygons = function () { + + colorsAndPolygons = { + colors: [], + polygons: [], + }; + + for (var i in plugin.drawTools.drawnItems._layers) { // leaflet don't support breaking out of the loop + + var layer = plugin.drawTools.drawnItems._layers[i]; + + var color = layer.options.color; + + if (colorsAndPolygons.colors.indexOf(color) === -1) { + colorsAndPolygons.colors.push(color); + } + + if (layer instanceof L.GeodesicPolygon) { + colorsAndPolygons.polygons.push(layer) + } + }; + + return colorsAndPolygons; + }; - $plugin.polygons.push(drawItem._leaflet_id); + //------------------------------------------------------------- + // Filtering + //------------------------------------------------------------- + + $plugin.filters = {}; + + //------------------------------------------------------------- + // Filtering - Colors + //------------------------------------------------------------- + + $plugin.filters.colors = {}; + + $plugin.filters.colors.modes = { + ONLY_SELECTED: 'ONLY_SELECTED', + EXCLUDE_SELECTED: 'EXCLUDE_SELECTED' + }; + $plugin.filters.colors.mode = $plugin.filters.colors.modes.EXCLUDE_SELECTED; + + $plugin.filters.colors.selected = []; - if (drawItem._leaflet_id === $plugin.onlyForPolygonWithLeafletId) { - $plugin.onlyForPolygon = drawItem; + $plugin.filters.colors.set = function (opts) { + + var mustRefresh = true; + + var delta = opts.selected.filter(function (newcolor) { + return $plugin.filters.colors.selected.indexOf(newcolor) === -1 + }); + + if (!delta.length) { + + delta = $plugin.filters.colors.selected.filter(function (oldcolor) { + return opts.selected.indexOf(oldcolor) === -1 + }); + + if (!delta.length) { + mustRefresh = false; } } - if ($plugin.selectedColors.indexOf(drawItem.options.color) === -1) { + if (mustRefresh) { + $plugin.filters.colors.selected = opts.selected; + } + + if ($plugin.filters.colors.mode != $plugin.filters.colors.modes[opts.mode]) { + $plugin.filters.colors.mode = $plugin.filters.colors.modes[opts.mode]; + if ( + $plugin.filters.colors.selected.length + ) { + mustRefresh = true; + } + } + + return mustRefresh; + + } + + $plugin.filters.colors.shouldCheckDrawnItem = function (drawItem, closed) { + + // drawn item color filter + if ( + $plugin.filters.colors.selected.length + && ( + ( + $plugin.filters.colors.mode === $plugin.filters.colors.modes.EXCLUDE_SELECTED + && $plugin.filters.colors.selected.indexOf(drawItem.options.color) !== -1 + ) + || ( + $plugin.filters.colors.mode === $plugin.filters.colors.modes.ONLY_SELECTED + && $plugin.filters.colors.selected.indexOf(drawItem.options.color) === -1 + ) + ) + ) { return false; } + return true; } - $plugin.onlyForPolygonWithLeafletId = 170; - $plugin.onlyForPolygon = null; - $plugin.linkLeafletGuidsChecked = {}; + //------------------------------------------------------------- + // Filtering - polygon + //------------------------------------------------------------- + + $plugin.filters.polygon = {}; + + $plugin.filters.polygon.selected = null; + $plugin.filters.polygon._cachedlinkGuids = {}; - $plugin.ShouldCheckLink = function (link) { + $plugin.filters.polygon.set = function (polygon) { + + var changed = false; + if (polygon) { + if ( + (!$plugin.filters.polygon.selected) + || $plugin.filters.polygon.selected !== polygon + ) { + $plugin.filters.polygon.selected = polygon; + changed = true; + } + } + else if ($plugin.filters.polygon.selected) { + $plugin.filters.polygon.selected = null; + changed = true; + } + + if (changed) { + $plugin.filters.polygon._cachedlinkGuids = {}; + } + return changed; + } + + $plugin.filters.polygon.ShouldCheckLink = function (link) { var shouldCheckLink = true; - if ($plugin.onlyForPolygon) { + if ($plugin.filters.polygon.selected) { - if ($plugin.linkLeafletGuidsChecked[link.options.guid] === undefined) { + if ($plugin.filters.polygon._cachedlinkGuids[link.options.guid] === undefined) { var linkLatLongs = link.getLatLngs(); if ( - $plugin.onlyForPolygon.contains(linkLatLongs[0]) - || $plugin.onlyForPolygon.contains(linkLatLongs[1]) + $plugin.filters.polygon.selected.contains(linkLatLongs[0]) + || $plugin.filters.polygon.selected.contains(linkLatLongs[1]) ) { - $plugin.linkLeafletGuidsChecked[link.options.guid] = true; + $plugin.filters.polygon._cachedlinkGuids[link.options.guid] = true; } else { - $plugin.linkLeafletGuidsChecked[link.options.guid] = $plugin.crossLinks.overridenFunctions.testPolyLine($plugin.onlyForPolygon, link, true); - + $plugin.filters.polygon._cachedlinkGuids[link.options.guid] + = $plugin.crossLinks.overridenFunctions.testPolyLine($plugin.filters.polygon.selected, link, true); } } - shouldCheckLink = $plugin.linkLeafletGuidsChecked[link.options.guid]; + shouldCheckLink = $plugin.filters.polygon._cachedlinkGuids[link.options.guid]; } return shouldCheckLink; } + //------------------------------------------------------------- + // Destroyed Links Simulator integration + //------------------------------------------------------------- + $plugin.destroyedLinks = {}; + + $plugin.destroyedLinks.refresh = function () { + if (window.plugin.destroyedLinks !== undefined) { + window.plugin.destroyedLinks.cross.removeCrossAll(); + } + } + //------------------------------------------------------------- // Crosslinks integration //------------------------------------------------------------- $plugin.crossLinks = {}; + $plugin.crossLinks.refresh = function () { + window.plugin.crossLinks.checkAllLinks(); + } + $plugin.crossLinks.overridenFunctions = {}; // Main override for drawn item against link $plugin.crossLinks.testPolyLine = function (drawItem, link, closed) { - if (!$plugin.ShouldCheckDrawnItem(drawItem, closed)) { + if (!$plugin.filters.colors.shouldCheckDrawnItem(drawItem, closed)) { return false; } - if (!$plugin.ShouldCheckLink(link)) { + if (!$plugin.filters.polygon.ShouldCheckLink(link)) { return false; } return $plugin.crossLinks.overridenFunctions.testPolyLine(drawItem, link, closed); } - // We just reset the draw colors and polygons tables - $plugin.crossLinks.checkAllLinks = function () { - $plugin.drawcolors = []; - $plugin.polygons = []; - $plugin.crossLinks.overridenFunctions.checkAllLinks(); - } - $plugin.crossLinks.init = function () { $plugin.crossLinks.overridenFunctions.testPolyLine = window.plugin.crossLinks.testPolyLine; window.plugin.crossLinks.testPolyLine = $plugin.crossLinks.testPolyLine; - $plugin.crossLinks.overridenFunctions.checkAllLinks = window.plugin.crossLinks.checkAllLinks; - window.plugin.crossLinks.checkAllLinks = $plugin.crossLinks.checkAllLinks; - // Recolor Drawn Items fix: color changes do not trigger crosslink updates map.on('draw:recolored', function (e) { - window.plugin.crossLinks.checkAllLinks(); + $plugin.opts.refreshed(); }); } @@ -161,59 +402,223 @@ function wrapper() { $plugin.ui = {}; $plugin.ui.init = function () { - $('#toolbox').append('Cross Links Enhancements'); + + $('#toolbox') + .append( + '' + + 'Cross Links Opts' + + '' + ); } $plugin.ui.setOptions = function () { - $plugin.selectedColors = []; + $plugin.ui.resetPolys(); + + var opts = { + colors: {} + }; + + opts.colors.selected = []; $("#dialog-crossLinksEnhancementsOptions input[type=checkbox][name=crossLinkColors]").each(function (i, input) { + + if (input.checked) { + opts.colors.selected.push(input.value); + } + }); + + opts.colors.mode = null; + + $("#dialog-crossLinksEnhancementsOptions input[type=radio][name=crossLinkColorsMode]").each(function (i, input) { + if (input.checked) { - $plugin.selectedColors.push(input.value); + opts.colors.mode = input.value; } + }); + + opts.polygon = null; + + input = $("#dialog-crossLinksEnhancementsOptions select[name=crossLinkPolygon]"); + if (input.length && input[0].value !== '') { + opts.polygon = plugin.drawTools.drawnItems._layers[parseInt(input[0].value)]; + if (opts.polygon === undefined) { + opts.polygon = null; + } + } + + $plugin.opts.set(opts); + } + + + $plugin.ui.stylesCache = []; + + $plugin.ui.resetPolys = function ($exclude_leaflet_id) { + + for (leaflet_id in $plugin.ui.stylesCache) { + if ($exclude_leaflet_id !== leaflet_id) { + window.plugin.drawTools.drawnItems._layers[leaflet_id].setStyle($plugin.ui.stylesCache[leaflet_id]); + delete $plugin.ui.stylesCache[leaflet_id]; + } + } + + } + + $plugin.ui.previewPoligon = function (leaflet_id) { + + $plugin.ui.resetPolys(leaflet_id); + + if (leaflet_id != '') { + var poly = window.plugin.drawTools.drawnItems._layers[leaflet_id]; + $plugin.ui.stylesCache[leaflet_id] = { + 'fill': poly.options.fill, + 'fillColor': poly.options.fillColor, + 'fillOpacity': poly.options.fillOpacity, + }; + poly.setStyle({ + 'fill': true, + 'fillColor': '#ff0000', + 'fillOpacity': 0.6, + }) + } - }) } $plugin.ui.showOptions = function () { - var html = [] + + var html = []; + var colorsAndPolygons = $plugin.draw.colorsAndPolygons(); + html.push('
'); + /** + * ------------------------------------------------------------- + * Colors Filter + * ------------------------------------------------------------- + */ html.push('
'); - html.push('Draw items colors:'); + html.push('Drawn items color:'); - if ($plugin.drawcolors.length) { - $plugin.drawcolors.forEach(function (color) { + // Colors selection + + if (colorsAndPolygons.colors.length) { + colorsAndPolygons.colors.forEach(function (color) { var domId = "crossLinkColors_" + color; - var handler = "return window.plugin.crossLinksEnhancements.ui.clickColor('" + color + "');" html.push(''); html.push(''); html.push('    '); - }) + }); + html.push('
'); + + // Colors mode selection + + html.push('
'); + html.push('For above selected colors:'); + + // Colors mode EXCLUDE_SELECTED + var domId = "crossLinkColorMode_EXCLUDE_SELECTED"; + html.push(''); + html.push(''); + + + // Colors mode ONLY_SELECTED + var domId = "crossLinkColorMode_ONLY_SELECTED"; + html.push('
'); + html.push(''); + html.push(''); + + } else { html.push('Load a draw or wait first map update!'); } - html.push('
'); - html.push('
'); + if (colorsAndPolygons.colors.length) { + /** + * ------------------------------------------------------------- + * Polygon Filter + * ------------------------------------------------------------- + */ + html.push('
'); + html.push('Drawn polygon:'); + + // Polygon selection + if (colorsAndPolygons.polygons.length) { + + html.push(''); + + } else { + html.push('Draw does not contain polygons'); + } + + html.push('
'); + } + + + + html.push(''); dialog({ html: html.join(''), title: 'Cross Links Options', id: 'crossLinksEnhancementsOptions', - closeCallback: function () {window.plugin.crossLinksEnhancements.ui.setOptions(); } + closeCallback: function () { window.plugin.crossLinksEnhancements.ui.setOptions(); } }); - } // PLUGIN END ////////////////////////////////////////////////////////// @@ -223,8 +628,8 @@ function wrapper() { window.bootPlugins.push(setup); // if IITC has already booted, immediately run the 'setup' function if (window.iitcLoaded && typeof setup === 'function') setup(); -} +} // WRAPPER END ///////////////////////////////////////////////////////////// // inject code into site context /////////////////////////////////////////// diff --git a/readme.md b/readme.md index 75021f0..b3f13da 100644 --- a/readme.md +++ b/readme.md @@ -10,6 +10,7 @@ This plugin allows to: - choose drawn items colors to be included or excluded from cross links detection; - choose a polygon to limit cross links detection to links contained or intersecting it +![Crosslinks Enhancements](screenshots/overview-v1.0.gif) ## Installation [Click here](https://github.com/manierim/crosslinks-enhancements/raw/master/crosslinks-enhancements.user.js) and your userscript manager should do it. @@ -21,15 +22,35 @@ This plugin allows to: ## Usage -@todo +Use the toolbox link "Cross Links Opts" to access the options dialogs. + +All colors used by "crossable" drawn items are visually listed. Select one or more colors. + +Then select if you want drawn items of the selected color(s) to be ignored from detection or if instead you want only drawn item of the selected color(s) to have cross links detected for. + +The drawn polygon select box will list all polygons available in the draw, each with its hex color code and number of vertexes. + +Each time you select an item from the list the corresponding polygon in the map will be highlighted on the map. + +Press OK to apply your selections. + +**The selections are saved in the browser local storage so they will persist across reload and sessions.** +Please note that settings are not currently saved "per draw/project". If you change your draw, your settings will need to be reviewed. ## Compatibility -The plugin has been tested with the following versions (current at the time of writing): +The plugin has been tested with the following versions (current at the time of writing) **on IITC desktop**: - cross links version 1.1.2.20181031.195523 - draw tools version 0.7.0.20181031.195523 +- Destroyed Links Simulator version 0.0.7.20180217.123738 + +Modifications of above plugins might work as long as they do not change the original behavior too much. + + + +## Credits -Modifications of both plugins might work as long as they do not change the original plugin behavior too much. +Point in Polygon function by [hayeswise/Leaflet.PointInPolygon](https://github.com/hayeswise/Leaflet.PointInPolygon) ## Changelog diff --git a/screenshots/overview-v1.0.gif b/screenshots/overview-v1.0.gif new file mode 100644 index 0000000..0242b36 Binary files /dev/null and b/screenshots/overview-v1.0.gif differ