Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

leaflet-editable

Package Overview
Dependencies
Maintainers
1
Versions
15
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

leaflet-editable - npm Package Compare versions

Comparing version 0.7.0-beta.1 to 1.0.0-rc.1

test/CircleEditor.js

4

bower.json
{
"name": "leaflet.editable",
"version": "0.6.0",
"homepage": "https://github.com/yohanboniface/Leaflet.Editable",
"homepage": "https://github.com/Leaflet/Leaflet.Editable",
"authors": [
"Yohan Boniface <yb@enix.org>"
"Yohan Boniface <ybon@openstreetmap.fr>"
],

@@ -8,0 +8,0 @@ "description": "Make geometries editable in Leaflet.",

# CHANGELOG
# dev
# 1.0.0-rc.1
- hide middle markers if there is not enough space
- make possible to add new vertex on top of other
paths vertex
- make possible to add new vertex on top of other paths vertex
- leaflet 1.0 support

@@ -12,4 +11,5 @@ - make editable:drawing:click and editable:vertex:click cancellable

- AMD/UMD compliancy
- fix middleMarker still trigering some events while not being visible
- add map option editToolsClass, that allow to override L.Editable class to be used
- fix middleMarker still triggering some events while not being visible
- add map option editToolsClass, that allow to override L.Editable class to be
used
- added deleteShapeAt method

@@ -21,6 +21,12 @@ - added events editable:shape:delete and editable:shape:deleted

- added Vertex.continue, as a shortcut to continueBackward / continueForward
- removed newClickHandler, now relying only on mousedown/mouseup event (simpler touch support)
- removed newClickHandler, now relying only on mousedown/mouseup event (simpler
touch support)
- added editable:drawing:move
- added drawingCursor option to L.Editable
- added editable:vertex:metakeyclick event
- reenable edit if the layer was active when removed from the map
- only add created feature to the map at first user click (instead of adding it
at startMarker/startPolygon call)
- added editable:drawing:mousedown and editable:drawing:mouseup events
- added support for L.Rectangle and L.Circle drawing and editing

@@ -27,0 +33,0 @@ ## 0.5.0

{
"name": "leaflet-editable",
"version": "0.7.0-beta.1",
"version": "1.0.0-rc.1",
"description": "Make geometries editable in Leaflet",

@@ -23,11 +23,11 @@ "main": "src/Leaflet.Editable.js",

"type": "git",
"url": "git://github.com/yohanboniface/Leaflet.Editable.git"
"url": "git://github.com/Leaflet/Leaflet.Editable.git"
},
"bugs": {
"url": "https://github.com/yohanboniface/Leaflet.Editable/issues"
"url": "https://github.com/Leaflet/Leaflet.Editable/issues"
},
"homepage": "https://github.com/yohanboniface/Leaflet.Editable/",
"dependencies": {
"leaflet": "1.0.0-beta.2"
"homepage": "https://github.com/Leaflet/Leaflet.Editable/",
"peerDependencies": {
"leaflet": "rc"
}
}

@@ -1,2 +0,2 @@

[![Build Status](https://travis-ci.org/yohanboniface/Leaflet.Editable.svg)](https://travis-ci.org/yohanboniface/Leaflet.Editable)
[![Build Status](https://travis-ci.org/Leaflet/Leaflet.Editable.svg)](https://travis-ci.org/Leaflet/Leaflet.Editable)
# Leaflet.Editable

@@ -14,3 +14,3 @@

See the [demo UI](http://yohanboniface.github.io/Leaflet.Editable/example/index.html), an more [examples below](#examples).
See the [demo UI](http://Leaflet.github.io/Leaflet.Editable/example/index.html), an more [examples below](#examples).
This is also the drawing engine behind [uMap](http://wiki.openstreetmap.org/wiki/UMap).

@@ -29,5 +29,2 @@

Note: only [geojson](http://geojson.org/) features are supported for now:
Marker, Polyline, Polygon, and MultiPolygon/MultiPolylines (no Rectangle, Circle…)
## Install

@@ -62,10 +59,11 @@

- [Basic controls](http://yohanboniface.github.io/Leaflet.Editable/example/index.html)
- [Continue line by ctrl-clicking on first/last point](http://yohanboniface.github.io/Leaflet.Editable/example/continue-line.html)
- [Create hole in a polygon by ctrl-clicking on it](http://yohanboniface.github.io/Leaflet.Editable/example/create-hole-on-click.html)
- [Change line colour on editing](http://yohanboniface.github.io/Leaflet.Editable/example/change-line-colour-on-editing.html)
- [Display a tooltip near cursor while drawing](http://yohanboniface.github.io/Leaflet.Editable/example/tooltip-when-drawing.html)
- [Basic demo of undo/redo](http://yohanboniface.github.io/Leaflet.Editable/example/undo-redo.html) (Use ctrl-Z to undo and ctrl-shift-Z to redo)
- [Multipolygon example](http://yohanboniface.github.io/Leaflet.Editable/example/multipolygon.html)
- Example of [Leaflet.Snap](https://github.com/makinacorpus/Leaflet.Snap/) integration [to enable snapping](http://yohanboniface.github.io/Leaflet.Editable/example/snapping.html)
- [Basic controls](http://Leaflet.github.io/Leaflet.Editable/example/index.html)
- [Continue line by ctrl/command-clicking on first/last point](http://Leaflet.github.io/Leaflet.Editable/example/continue-line.html)
- [Create hole in a polygon by ctrl-clicking on it](http://Leaflet.github.io/Leaflet.Editable/example/create-hole-on-click.html)
- [Change line colour on editing](http://Leaflet.github.io/Leaflet.Editable/example/change-line-colour-on-editing.html)
- [Display a tooltip near cursor while drawing](http://Leaflet.github.io/Leaflet.Editable/example/tooltip-when-drawing.html)
- [Basic demo of undo/redo](http://Leaflet.github.io/Leaflet.Editable/example/undo-redo.html) (Use ctrl-Z to undo and ctrl-shift-Z to redo)
- [Deleting shapes by ctrl/command clicking on it](http://Leaflet.github.io/Leaflet.Editable/example/delete-shape.html)
- [Multipolygon example](http://Leaflet.github.io/Leaflet.Editable/example/multipolygon.html)
- Example of [Leaflet.Snap](https://github.com/makinacorpus/Leaflet.Snap/) integration [to enable snapping](http://Leaflet.github.io/Leaflet.Editable/example/snapping.html)

@@ -102,2 +100,4 @@

| editable:drawing:commit | layer | false | Fired when user finish drawing a feature |
| editable:drawing:mousedown | layer | false | Fired when user mousedown while drawing |
| editable:drawing:mouseup | layer | false | Fired when user mouseup while drawing |
| editable:drawing:click | layer | true | Fired when user click while drawing, before any internal action is being processed |

@@ -253,3 +253,11 @@ | editable:drawing:clicked | layer | false | Fired when user click while drawing, after all internal actions |

### L.Editable.RectangleEditor
Inherit from `L.Editable.PathEditor`.
### L.Editable.CircleEditor
Inherit from `L.Editable.PathEditor`.
### EditableMixin

@@ -256,0 +264,0 @@

@@ -33,2 +33,4 @@ 'use strict';

markerClass: L.Marker,
rectangleClass: L.Rectangle,
circleClass: L.Circle,
drawingCSSClass: 'leaflet-editable-drawing',

@@ -56,3 +58,3 @@ drawingCursor: 'crosshair'

createLineGuide: function () {
var options = L.extend({dashArray: '5,10', weight: 1}, this.options.lineGuideOptions);
var options = L.extend({dashArray: '5,10', weight: 1, interactive: false}, this.options.lineGuideOptions);
return L.polyline([], options);

@@ -110,3 +112,3 @@ },

detachForwardLineGuide: function () {
this.forwardLineGuide._latlngs = [];
this.forwardLineGuide.setLatLngs([]);
this.editLayer.removeLayer(this.forwardLineGuide);

@@ -116,9 +118,26 @@ },

detachBackwardLineGuide: function () {
this.backwardLineGuide._latlngs = [];
this.backwardLineGuide.setLatLngs([]);
this.editLayer.removeLayer(this.backwardLineGuide);
},
blockEvents: function () {
// Hack: force map not to listen to other layers events while drawing.
if (!this._oldTargets) {
this._oldTargets = this.map._targets;
this.map._targets = {};
}
},
unblockEvents: function () {
if (this._oldTargets) {
// Reset, but keep targets created while drawing.
this.map._targets = L.extend(this.map._targets, this._oldTargets);
delete this._oldTargets;
}
},
registerForDrawing: function (editor) {
this.map.on('mousemove touchmove', editor.onMouseMove, editor);
if (this._drawingEditor) this.unregisterForDrawing(this._drawingEditor);
this.map.on('mousemove touchmove', editor.onDrawingMouseMove, editor);
this.blockEvents();
this._drawingEditor = editor;

@@ -133,2 +152,3 @@ this.map.on('mousedown', this.onMousedown, this);

unregisterForDrawing: function (editor) {
this.unblockEvents();
L.DomUtil.removeClass(this.map._container, this.options.drawingCSSClass);

@@ -138,3 +158,3 @@ this.map._container.style.cursor = this.defaultMapCursor;

if (!editor) return;
this.map.off('mousemove touchmove', editor.onMouseMove, editor);
this.map.off('mousemove touchmove', editor.onDrawingMouseMove, editor);
this.map.off('mousedown', this.onMousedown, this);

@@ -149,2 +169,3 @@ this.map.off('mouseup', this.onMouseup, this);

this._mouseDown = e;
this._drawingEditor.onDrawingMouseDown(e);
},

@@ -155,7 +176,5 @@

var origin = L.point(this._mouseDown.originalEvent.clientX, this._mouseDown.originalEvent.clientY);
var distance = L.point(e.originalEvent.clientX, e.originalEvent.clientY)
.distanceTo(origin);
if (Math.abs(distance) < 9 * (window.devicePixelRatio || 1)) {
this._drawingEditor.onDrawingClick(e);
}
var distance = L.point(e.originalEvent.clientX, e.originalEvent.clientY).distanceTo(origin);
if (Math.abs(distance) < 9 * (window.devicePixelRatio || 1)) this._drawingEditor.onDrawingClick(e);
else this._drawingEditor.onDrawingMouseUp(e);
}

@@ -184,4 +203,3 @@ this._mouseDown = null;

var line = this.createPolyline([], options);
this.connectCreatedToMap(line);
line.enableEdit().newShape(latlng);
line.enableEdit(this.map).newShape(latlng);
return line;

@@ -192,4 +210,3 @@ },

var polygon = this.createPolygon([], options);
this.connectCreatedToMap(polygon);
polygon.enableEdit().newShape(latlng);
polygon.enableEdit(this.map).newShape(latlng);
return polygon;

@@ -199,10 +216,23 @@ },

startMarker: function (latlng, options) {
latlng = latlng || this.map.getCenter();
latlng = latlng || this.map.getCenter().clone();
var marker = this.createMarker(latlng, options);
this.connectCreatedToMap(marker);
var editor = marker.enableEdit();
editor.startDrawing();
marker.enableEdit(this.map).startDrawing();
return marker;
},
startRectangle: function(latlng, options) {
var corner = latlng || L.latLng([0, 0]);
var bounds = new L.LatLngBounds(corner, corner);
var rectangle = this.createRectangle(bounds, options);
rectangle.enableEdit(this.map).startDrawing();
return rectangle;
},
startCircle: function (latlng, options) {
latlng = latlng || this.map.getCenter().clone();
var circle = this.createCircle(latlng, options);
circle.enableEdit(this.map).startDrawing();
return circle;
},
startHole: function (editor, latlng) {

@@ -212,21 +242,27 @@ editor.newHole(latlng);

createPolyline: function (latlngs, options) {
createLayer: function (klass, latlngs, options) {
options = L.Util.extend({editOptions: {editTools: this}}, options);
var line = new this.options.polylineClass(latlngs, options);
this.fireAndForward('editable:created', {layer: line});
return line;
var layer = new klass(latlngs, options);
this.fireAndForward('editable:created', {layer: layer});
return layer;
},
createPolyline: function (latlngs, options) {
return this.createLayer(options && options.polylineClass || this.options.polylineClass, latlngs, options);
},
createPolygon: function (latlngs, options) {
options = L.Util.extend({editOptions: {editTools: this}}, options);
var polygon = new this.options.polygonClass(latlngs, options);
this.fireAndForward('editable:created', {layer: polygon});
return polygon;
return this.createLayer(options && options.polygonClass || this.options.polygonClass, latlngs, options);
},
createMarker: function (latlng, options) {
options = L.Util.extend({editOptions: {editTools: this}}, options);
var marker = new this.options.markerClass(latlng, options);
this.fireAndForward('editable:created', {layer: marker});
return marker;
return this.createLayer(options && options.markerClass || this.options.markerClass, latlng, options);
},
createRectangle: function (bounds, options) {
return this.createLayer(options && options.rectangleClass || this.options.rectangleClass, bounds, options);
},
createCircle: function (latlng, options) {
return this.createLayer(options && options.circleClass || this.options.circleClass, latlng, options);
}

@@ -285,2 +321,4 @@

initialize: function (latlng, latlngs, editor, options) {
// We don't use this._latlng, because on drag Leaflet replace it while
// we want to keep reference.
this.latlng = latlng;

@@ -326,4 +364,4 @@ this.latlngs = latlngs;

latlng = this._map.layerPointToLatLng(iconPos);
this.latlng.lat = latlng.lat;
this.latlng.lng = latlng.lng;
this.latlng.update(latlng);
this._latlng = this.latlng; // Push back to Leaflet our reference.
this.editor.refresh();

@@ -372,3 +410,3 @@ if (this.middleMarker) {

var next = this.getNext(); // Compute before changing latlng
this.latlngs.splice(this.latlngs.indexOf(this.latlng), 1);
this.latlngs.splice(this.getIndex(), 1);
this.editor.editLayer.removeLayer(this);

@@ -408,3 +446,3 @@ this.editor.onVertexDeleted({latlng: this.latlng, vertex: this});

addMiddleMarker: function (previous) {
if (this.editor.tools.options.skipMiddleMarkers) return;
if (!this.editor.hasMiddleMarkers()) return;
previous = previous || this.getPrevious();

@@ -415,3 +453,3 @@ if (previous && !this.middleMarker) this.middleMarker = this.editor.addMiddleMarker(previous, this, this.latlngs, this.editor);

addMiddleMarkers: function () {
if (this.editor.tools.options.skipMiddleMarkers) return;
if (!this.editor.hasMiddleMarkers()) return;
var previous = this.getPrevious();

@@ -572,3 +610,3 @@ if (previous) {

if (this._enabled) return this;
this.tools.editLayer.addLayer(this.editLayer);
if (this.isConnected()) this.tools.editLayer.addLayer(this.editLayer);
this.onEnable();

@@ -594,2 +632,6 @@ this._enabled = true;

hasMiddleMarkers: function () {
return !this.options.skipMiddleMarkers && !this.tools.options.skipMiddleMarkers;
},
fireAndForward: function (type, e) {

@@ -630,2 +672,10 @@ e = e || {};

onDrawingMouseDown: function (e) {
this.fireAndForward('editable:drawing:mousedown', e);
},
onDrawingMouseUp: function (e) {
this.fireAndForward('editable:drawing:mouseup', e);
},
startDrawing: function () {

@@ -658,5 +708,15 @@ if (!this._drawing) this._drawing = L.Editable.FORWARD;

if (e._cancelled) return;
if (!this.isConnected()) this.connect(e);
this.processDrawingClick(e);
},
isConnected: function () {
return this.map.hasLayer(this.feature);
},
connect: function (e) {
this.tools.connectCreatedToMap(this.feature);
this.tools.editLayer.addLayer(this.editLayer);
},
onMove: function (e) {

@@ -666,3 +726,3 @@ this.fireAndForward('editable:drawing:move', e);

onMouseMove: function (e) {
onDrawingMouseMove: function (e) {
this.onMove(e);

@@ -678,3 +738,4 @@ }

L.Editable.BaseEditor.prototype.enable.call(this);
this.feature.dragging.enable();
if (this.isConnected()) this.enableDragging();
else this.feature.on('add', this.enableDragging, this);
this.feature.on('dragstart', this.onEditing, this);

@@ -687,3 +748,3 @@ this.feature.on('drag', this.onMove, this);

L.Editable.BaseEditor.prototype.disable.call(this);
this.feature.dragging.disable();
if (this.feature.dragging) this.feature.dragging.disable();
this.feature.off('dragstart', this.onEditing, this);

@@ -694,12 +755,21 @@ this.feature.off('drag', this.onMove, this);

onMouseMove: function (e) {
L.Editable.BaseEditor.prototype.onMouseMove.call(this, e);
if (this._drawing) {
this.feature.setLatLng(e.latlng);
}
enableDragging: function () {
this.feature.dragging.enable();
},
onDrawingMouseMove: function (e) {
L.Editable.BaseEditor.prototype.onDrawingMouseMove.call(this, e);
if (this._drawing) this.feature.setLatLng(e.latlng);
},
processDrawingClick: function (e) {
this.fireAndForward('editable:drawing:clicked', e);
this.commitDrawing(e);
},
connect: function (e) {
// On touch, the latlng has not been updated because there is
// no mousemove.
if (e) this.feature._latlng = e.latlng;
L.Editable.BaseEditor.prototype.connect.call(this, e);
}

@@ -729,9 +799,4 @@

latlngs = latlngs || this.getLatLngs();
if (L.Polyline._flat(latlngs)) {
this.addVertexMarkers(latlngs);
} else {
for (var i = 0; i < latlngs.length; i++) {
this.initVertexMarkers(latlngs[i]);
}
}
if (L.Polyline._flat(latlngs)) this.addVertexMarkers(latlngs);
else for (var i = 0; i < latlngs.length; i++) this.initVertexMarkers(latlngs[i]);
},

@@ -758,2 +823,9 @@

refreshVertexMarkers: function (latlngs) {
latlngs = latlngs || this.getDefaultLatLngs();
for (var i = 0; i < latlngs.length; i++) {
latlngs[i].__vertex.update();
}
},
addMiddleMarker: function (left, right, latlngs) {

@@ -835,3 +907,3 @@ return new this.tools.options.middleMarkerClass(left, right, latlngs, this);

this.onMove(e);
this.feature._bounds.extend(e.vertex._latlng);
if (this.feature._bounds) this.extendBounds(e);
this.fireAndForward('editable:vertex:drag', e);

@@ -920,4 +992,4 @@ },

onMouseMove: function (e) {
L.Editable.BaseEditor.prototype.onMouseMove.call(this, e);
onDrawingMouseMove: function (e) {
L.Editable.BaseEditor.prototype.onDrawingMouseMove.call(this, e);
if (this._drawing) {

@@ -944,5 +1016,19 @@ this.tools.moveForwardLineGuide(e.latlng);

deleteShape: function (shape, latlngs) {
var e = {shape: shape};
L.Editable.makeCancellable(e);
this.fireAndForward('editable:shape:delete', e);
if (e._cancelled) return;
shape = this._deleteShape(shape, latlngs);
if (this.ensureNotFlat) this.ensureNotFlat(); // Polygon.
this.feature.setLatLngs(this.getLatLngs()); // Force bounds reset.
this.refresh();
this.reset();
this.fireAndForward('editable:shape:deleted', {shape: shape});
return shape;
},
_deleteShape: function (shape, latlngs) {
latlngs = latlngs || this.getLatLngs();
if (!latlngs.length) return;
var e, self = this,
var self = this,
inplaceDelete = function (latlngs, shape) {

@@ -956,20 +1042,9 @@ // Called when deleting a flat latlngs

latlngs.splice(latlngs.indexOf(shape), 1);
if (!latlngs.length) self._deleteShape(latlngs);
return shape;
},
doDelete = function (callback, shape) {
e = {shape: shape};
L.Editable.makeCancellable(e);
self.fireAndForward('editable:shape:delete', e);
if (e._cancelled) return;
shape = callback(latlngs, shape);
if (self.ensureNotFlat) self.ensureNotFlat(); // Polygon
self.refresh();
self.reset();
self.fireAndForward('editable:shape:deleted', {shape: shape});
return shape;
};
if (latlngs === shape) return doDelete(inplaceDelete, shape);
if (latlngs === shape) return inplaceDelete(latlngs, shape);
for (var i = 0; i < latlngs.length; i++) {
if (latlngs[i] === shape) return doDelete(spliceDelete, shape);
else if (L.Util.indexOf(latlngs[i], shape) !== -1) return doDelete(spliceDelete, latlngs[i]);
if (latlngs[i] === shape) return spliceDelete(latlngs, shape);
else if (latlngs[i].indexOf(shape) !== -1) return spliceDelete(latlngs[i], shape);
}

@@ -998,2 +1073,6 @@ },

if (this._enabled) this.reset();
},
extendBounds: function (e) {
this.feature._bounds.extend(e.vertex.latlng);
}

@@ -1012,2 +1091,3 @@

continueBackward: function (latlngs) {
if (this.drawing()) return;
latlngs = latlngs || this.getDefaultLatLngs();

@@ -1020,2 +1100,3 @@ this.setDrawnLatLngs(latlngs);

continueForward: function (latlngs) {
if (this.drawing()) return;
latlngs = latlngs || this.getDefaultLatLngs();

@@ -1118,4 +1199,6 @@ this.setDrawnLatLngs(latlngs);

vertexCanBeDeleted: function (vertex) {
if (vertex.latlngs === this.getLatLngs()) return L.Editable.PathEditor.prototype.vertexCanBeDeleted.call(this, vertex);
else return true; // Holes can be totally deleted without removing the layer itself
var parent = this.feature.parentShape(vertex.latlngs),
idx = L.Util.indexOf(parent, vertex.latlngs);
if (idx > 0) return true; // Holes can be totally deleted without removing the layer itself.
return L.Editable.PathEditor.prototype.vertexCanBeDeleted.call(this, vertex);
},

@@ -1138,3 +1221,120 @@

L.Editable.RectangleEditor = L.Editable.PathEditor.extend({
CLOSED: true,
MIN_VERTEX: 4,
options: {
skipMiddleMarkers: true
},
extendBounds: function (e) {
var index = e.vertex.getIndex(),
oppositeIndex = (index + 2) % 4,
opposite = e.vertex.latlngs[oppositeIndex],
bounds = new L.LatLngBounds(e.latlng, opposite);
this.updateBounds(bounds);
this.refreshVertexMarkers();
},
onDrawingMouseDown: function (e) {
L.Editable.PathEditor.prototype.onDrawingMouseDown.call(this, e);
this.connect();
var latlngs = this.getDefaultLatLngs();
// L.Polygon._convertLatLngs removes last latlng if it equals first point,
// which is the case here as all latlngs are [0, 0]
if (latlngs.length === 3) latlngs.push(e.latlng);
var bounds = new L.LatLngBounds(e.latlng, e.latlng);
this.updateBounds(bounds);
this.refresh();
this.reset();
this.commitDrawing(e);
// Stop dragging map.
this.map.dragging._draggable._onUp(e.originalEvent);
// Now transfer ongoing drag action to the bottom right corner.
// Should we refine which corne will handle the drag according to
// drag direction?
latlngs[3].__vertex.dragging._draggable._onDown(e.originalEvent);
},
getDefaultLatLngs: function (latlngs) {
return latlngs || this.feature._latlngs[0];
},
updateBounds: function (bounds) {
this.feature._bounds = bounds;
var latlngs = this.getDefaultLatLngs(),
newLatlngs = this.feature._boundsToLatLngs(bounds);
// Keep references.
for (var i = 0; i < latlngs.length; i++) {
latlngs[i].update(newLatlngs[i]);
};
}
});
L.Editable.CircleEditor = L.Editable.PathEditor.extend({
MIN_VERTEX: 2,
options: {
skipMiddleMarkers: true
},
initialize: function (map, feature, options) {
L.Editable.PathEditor.prototype.initialize.call(this, map, feature, options);
this._resizeLatLng = this.computeResizeLatLng();
},
computeResizeLatLng: function () {
// While circle is not added to the map, _radius is not set.
var delta = (this.feature._radius || this.feature._mRadius) * Math.cos(Math.PI / 4),
point = this.map.project(this.feature._latlng);
return this.map.unproject([point.x + delta, point.y - delta]);
},
updateResizeLatLng: function () {
this._resizeLatLng.update(this.computeResizeLatLng());
this._resizeLatLng.__vertex.update();
},
getLatLngs: function () {
return [this.feature._latlng, this._resizeLatLng];
},
getDefaultLatLngs: function () {
return this.getLatLngs();
},
onVertexMarkerDrag: function (e) {
if (e.vertex.getIndex() === 1) this.resize(e);
else this.updateResizeLatLng(e);
L.Editable.PathEditor.prototype.onVertexMarkerDrag.call(this, e);
},
resize: function (e) {
var radius = this.feature._latlng.distanceTo(e.latlng)
this.feature.setRadius(radius);
},
onDrawingMouseDown: function (e) {
L.Editable.PathEditor.prototype.onDrawingMouseDown.call(this, e);
this._resizeLatLng.update(e.latlng);
this.feature._latlng.update(e.latlng);
this.connect();
this.commitDrawing(e);
// Stop dragging map.
this.map.dragging._draggable._onUp(e.originalEvent);
// Now transfer ongoing drag action to the radius handler.
this._resizeLatLng.__vertex.dragging._draggable._onDown(e.originalEvent);
},
onDrawingMouseMove: function (e) {
L.Editable.BaseEditor.prototype.onDrawingMouseMove.call(this, e);
this.feature._latlng.update(e.latlng);
this.feature._latlng.__vertex.update();
}
});
var EditableMixin = {

@@ -1148,4 +1348,4 @@

enableEdit: function () {
if (!this.editor) this.createEditor();
enableEdit: function (map) {
if (!this.editor) this.createEditor(map);
return this.editor.enable();

@@ -1171,2 +1371,6 @@ },

}
},
_onEditableAdd: function () {
if (this.editor) this.enableEdit();
}

@@ -1179,2 +1383,4 @@

L.Marker.include(EditableMixin);
L.Rectangle.include(EditableMixin);
L.Circle.include(EditableMixin);

@@ -1203,3 +1409,3 @@ L.Polyline.include({

w = this._clickTolerance();
this._projectLatlngs(latlngs, part);
this._projectLatlngs(latlngs, part, this._pxBounds);
part = part[0];

@@ -1254,2 +1460,13 @@ p = this._map.latLngToLayerPoint(l);

return inside;
},
parentShape: function (shape, latlngs) {
latlngs = latlngs || this._latlngs;
if (!latlngs) return;
var idx = L.Util.indexOf(latlngs, shape);
if (idx !== -1) return latlngs;
for (var i = 0; i < latlngs.length; i++) {
idx = L.Util.indexOf(latlngs[i], shape);
if (idx !== -1) return latlngs[i];
}
}

@@ -1267,2 +1484,30 @@

L.Rectangle.include({
getEditorClass: function (map) {
return (map && map.options.rectangleEditorClass) ? map.options.rectangleEditorClass : L.Editable.RectangleEditor;
}
});
L.Circle.include({
getEditorClass: function (map) {
return (map && map.options.circleEditorClass) ? map.options.circleEditorClass : L.Editable.CircleEditor;
}
});
var keepEditable = function () {
// Make sure you can remove/readd an editable layer.
this.on('add', this._onEditableAdd);
};
L.Marker.addInitHook(keepEditable);
L.Polyline.addInitHook(keepEditable);
L.LatLng.prototype.update = function (latlng) {
this.lat = latlng.lat;
this.lng = latlng.lng;
}
}, window));

@@ -41,1 +41,7 @@ var qs = function (selector) {return document.querySelector(selector);};

};
chai.Assertion.addMethod('nearLatLng', function (expected, delta) {
delta = delta || 1e-4;
expect(this._obj.lat).to.be.within(expected.lat - delta, expected.lat + delta);
expect(this._obj.lng).to.be.within(expected.lng - delta, expected.lng + delta);
return this;
});

@@ -0,1 +1,2 @@

'use strict';
describe('L.Editable', function () {

@@ -6,3 +7,7 @@

});
after(function () {
afterEach(function () {
this.map.editTools.editLayer.eachLayer(function (layer) {
assert.fail(layer, null, 'no layer expected but one found');
});
});

@@ -17,2 +22,3 @@

});
describe('#drawing on top of other elements', function () {

@@ -34,4 +40,4 @@

assert.equal(line1._latlngs.length, 2);
this.map.removeLayer(line1);
this.map.removeLayer(line2);
line1.remove();
line2.remove();
});

@@ -115,3 +121,3 @@

assert.ok(this.map.editTools.drawing());
layer.remove();
layer.editor.disable();
});

@@ -118,0 +124,0 @@

'use strict';
describe('L.MarkerEditor', function() {
var marker, p2ll;
var p2ll;

@@ -12,8 +12,10 @@ before(function () {

});
after(function () {
if (marker) marker.remove();
});
describe('#startNewMarker()', function() {
var marker;
after(function () {
marker.remove();
});
it('should create feature and editor', function() {

@@ -43,11 +45,11 @@ marker = this.map.editTools.startMarker();

assert.equal(other.options.title, title);
this.map.removeLayer(other);
other.remove();
});
});
describe('#disable()', function () {
it('should stop editing on disable() call', function () {
marker.disableEdit();
assert.notOk(marker.editor);
it('should update latlng on marker drag', function (done) {
var before = marker._latlng.lat;
happen.drag(300, 299, 350, 350, function () {
assert.notEqual(before, marker._latlng.lat);
done();
});
});

@@ -60,2 +62,3 @@

it('should start editing on enable() call', function () {
var marker = L.marker([0, 0]).addTo(this.map);
marker.enableEdit();

@@ -67,15 +70,33 @@ assert.ok(marker.editor);

describe('#drag()', function () {
describe('#disable()', function () {
it('should update latlng on marker drag', function (done) {
var before = marker._latlng.lat;
happen.drag(300, 299, 350, 350, function () {
assert.notEqual(before, marker._latlng.lat);
done();
});
it('should stop editing on disable() call', function () {
var marker = L.marker([0, 0]).addTo(this.map);
marker.enableEdit();
assert.ok(marker.editEnabled());
marker.disableEdit();
assert.notOk(marker.editor);
});
it('should be reenabled after remove if active', function () {
var marker = L.marker([0, 0]).addTo(this.map);
marker.enableEdit();
this.map.removeLayer(marker);
assert.notOk(marker.editEnabled());
this.map.addLayer(marker);
assert.ok(marker.editEnabled());
});
it('should not be reenabled after remove if not active', function () {
var marker = L.marker([0, 0]).addTo(this.map);
marker.enableEdit();
marker.disableEdit();
this.map.removeLayer(marker);
assert.notOk(marker.editEnabled());
this.map.addLayer(marker);
assert.notOk(marker.editEnabled());
});
});
describe('#events', function () {

@@ -90,3 +111,3 @@

this.map.off('editable:drawing:start', call);
other.remove();
other.editor.disable();
assert.notOk(this.map.editTools._drawingEditor);

@@ -93,0 +114,0 @@ });

@@ -0,1 +1,2 @@

'use strict';
describe('L.MiddleMarker', function () {

@@ -7,3 +8,7 @@ var mouse, polyline;

});
after(function () {
afterEach(function () {
this.map.editTools.editLayer.eachLayer(function (layer) {
assert.fail(layer, null, 'no layer expected but one found');
});
});

@@ -15,3 +20,3 @@

afterEach(function () {
this.map.removeLayer(line);
line.remove();
});

@@ -18,0 +23,0 @@

@@ -0,1 +1,2 @@

'use strict';
describe('L.PolygonEditor', function() {

@@ -53,3 +54,3 @@ var p2ll, polygon;

assert.equal(other._latlngs[0].length, 3);
this.map.removeLayer(other);
other.remove();
});

@@ -61,3 +62,3 @@

assert.equal(other.options.className, className);
this.map.removeLayer(other);
other.editor.disable();
});

@@ -73,2 +74,18 @@ });

it('should be reenabled after remove if active', function () {
polygon.enableEdit();
this.map.removeLayer(polygon);
assert.notOk(polygon.editEnabled());
this.map.addLayer(polygon);
assert.ok(polygon.editEnabled());
});
it('should not be reenabled after remove if not active', function () {
polygon.disableEdit();
this.map.removeLayer(polygon);
assert.notOk(polygon.editEnabled());
this.map.addLayer(polygon);
assert.notOk(polygon.editEnabled());
});
});

@@ -104,2 +121,33 @@

it('should not delete last latlng on vertex click if only three vertices', function () {
var latlngs = [p2ll(100, 150), p2ll(150, 200), p2ll(200, 100)],
layer = L.polygon(latlngs).addTo(this.map);
assert.equal(layer._latlngs[0].length, 3);
layer.enableEdit();
happen.at('click', 200, 100);
assert.equal(layer._latlngs[0].length, 3);
layer.remove();
});
it('should delete multi polygon hole shape at last vertex delete', function () {
var latlngs = [
[
[p2ll(100, 150), p2ll(150, 200), p2ll(200, 100)],
[p2ll(120, 160), p2ll(150, 170), p2ll(180, 120)]
],
[[p2ll(300, 350), p2ll(350, 400), p2ll(400, 300)]]
],
layer = L.polygon(latlngs).addTo(this.map);
layer.enableEdit();
assert.equal(layer._latlngs[0][1].length, 3);
happen.at('click', 120, 160);
happen.at('click', 150, 170);
happen.at('click', 180, 120);
assert.notOk(layer._latlngs[0][1]);
assert.ok(layer._latlngs[0]);
assert.ok(layer._latlngs[1]);
assert.ok(this.map.hasLayer(layer));
layer.remove();
});
});

@@ -166,2 +214,5 @@

assert.notOk(polygon._latlngs[1]);
assert.ok(polygon._latlngs[0]);
assert.ok(polygon._latlngs);
assert.ok(this.map.hasLayer(polygon));
polygon.remove();

@@ -185,3 +236,3 @@ });

assert.ok(layer.editor.drawing());
layer.remove();
layer.editor.disable();
});

@@ -205,3 +256,3 @@

assert.notInclude(layer._latlngs[0], last);
this.map.removeLayer(layer);
layer.remove();
});

@@ -224,3 +275,3 @@

assert.equal(layer._latlngs[0].length, 3);
this.map.removeLayer(layer);
layer.remove();
});

@@ -273,4 +324,47 @@

describe('#parentShape()', function () {
it('should find parent shape on simple polygon', function () {
var latlngs = [p2ll(100, 150), p2ll(150, 200), p2ll(200, 100)],
layer = L.polygon(latlngs).addTo(this.map);
assert.equal(layer.parentShape(layer._latlngs[0]), layer._latlngs);
layer.remove();
});
it('should find parent shape on multi polygon', function () {
var latlngs = [
[[p2ll(100, 150), p2ll(150, 200), p2ll(200, 100)]],
[[p2ll(300, 350), p2ll(350, 400), p2ll(400, 300)]]
],
layer = L.polygon(latlngs).addTo(this.map);
assert.equal(layer.parentShape(layer._latlngs[0][0]), layer._latlngs[0]);
assert.equal(layer.parentShape(layer._latlngs[1][0]), layer._latlngs[1]);
layer.remove();
});
it('should find parent shape on multi polygon with hole', function () {
var latlngs = [
[
[p2ll(100, 150), p2ll(150, 200), p2ll(200, 100)],
[p2ll(120, 160), p2ll(150, 170), p2ll(180, 120)]
],
[[p2ll(300, 350), p2ll(350, 400), p2ll(400, 300)]]
],
layer = L.polygon(latlngs).addTo(this.map);
assert.equal(layer.parentShape(layer._latlngs[0][0]), layer._latlngs[0]);
assert.equal(layer.parentShape(layer._latlngs[0][1]), layer._latlngs[0]);
assert.equal(layer.parentShape(layer._latlngs[1][0]), layer._latlngs[1]);
layer.remove();
});
});
describe('Events', function () {
afterEach(function () {
this.map.editTools.editLayer.eachLayer(function (layer) {
assert.fail(layer, null, 'no layer expected but one found');
});
});
it('should fire editable:drawing:start on startPolygon call', function () {

@@ -283,3 +377,3 @@ var called = 0,

this.map.off('editable:drawing:start', call);
layer.remove();
layer.editor.disable();
assert.notOk(this.map.editTools._drawingEditor);

@@ -340,3 +434,3 @@ });

this.map.off('editable:drawing:end', call);
layer.remove();
layer.editor.disable();
assert.equal(called, 1);

@@ -353,3 +447,3 @@ });

this.map.off('editable:drawing:commit', call);
layer.remove();
layer.editor.disable();
assert.equal(called, 0);

@@ -442,3 +536,3 @@ });

this.map.off('editable:drawing:click', call);
polygon.remove();
polygon.editor.disable();
});

@@ -506,3 +600,3 @@

this.map.editTools.editLayer.eachLayer(function (layer) {
assert.fail(layer, null, "no layer expected but one found");
assert.fail(layer, null, 'no layer expected but one found');
});

@@ -509,0 +603,0 @@ });

'use strict';
describe('L.PolylineEditor', function() {
var polyline, p2ll;
var p2ll;

@@ -13,3 +13,8 @@ before(function () {

describe('#startNewLine()', function() {
var polyline;
after(function () {
polyline.remove();
})
it('should create feature and editor', function() {

@@ -42,2 +47,3 @@ polyline = this.map.editTools.startPolyline();

happen.drawingClick(300, 250);
happen.at('click', 300, 250);
assert.equal(polyline._latlngs.length, 3);

@@ -48,77 +54,94 @@ });

var className = 'my-class';
var other = this.map.editTools.startPolyline(null, {className:className});
var other = this.map.editTools.startPolyline(null, {className: className});
assert.equal(other.options.className, className);
this.map.removeLayer(other);
other.disableEdit();
});
});
describe('#disable()', function () {
describe('#dragVertex()', function () {
it('should stop editing on disable() call', function () {
polyline.disableEdit();
assert.notOk(polyline.editor);
it('should update latlng on vertex drag', function (done) {
var before = polyline._latlngs[1].lat,
self = this;
happen.drag(200, 350, 220, 360, function () {
assert.notEqual(before, polyline._latlngs[1].lat);
done();
});
});
});
});
describe('#deleteVertex()', function () {
describe('#enable()', function () {
it('should delete latlng on vertex click', function () {
happen.drawingClick(300, 250);
happen.at('click', 300, 250);
assert.equal(polyline._latlngs.length, 2);
});
it('should start editing on enableEdit() call', function () {
polyline.enableEdit();
assert.ok(polyline.editor._enabled);
});
it('should not reset editor when calling enableEdit() twice', function () {
var editor = polyline.editor;
polyline.enableEdit();
assert.equal(editor, polyline.editor);
describe('#continueForward()', function () {
it('should add new latlng on map click', function () {
polyline.editor.continueForward();
happen.drawingClick(400, 400);
assert.equal(polyline._latlngs.length, 3);
happen.at('click', 400, 400); // Finish shape
happen.at('click', 450, 450); // Click elsewhere on the map
assert.equal(polyline._latlngs.length, 3);
});
});
});
describe('#continueBackward()', function () {
describe('#dragVertex()', function () {
it('should add new latlng on map click', function () {
polyline.editor.continueBackward();
happen.drawingClick(400, 100);
assert.equal(polyline._latlngs.length, 4);
happen.at('click', 400, 100); // Finish shape
happen.at('click', 450, 450); // Click elsewhere on the map
assert.equal(polyline._latlngs.length, 4);
});
it('should update latlng on vertex drag', function (done) {
var before = polyline._latlngs[1].lat,
self = this;
happen.drag(200, 350, 220, 360, function () {
assert.notEqual(before, polyline._latlngs[1].lat);
done();
});
});
});
describe('#dragMiddleMarker()', function () {
describe('#deleteVertex()', function () {
it('should insert new latlng on middle marker click', function (done) {
var last = polyline._latlngs[3],
third = polyline._latlngs[2],
fromX = (400 + 220) / 2,
fromY = (400 + 360) / 2;
happen.drag(fromX, fromY, 300, 440, function () {
assert.equal(polyline._latlngs.length, 5);
// New should have been inserted between third and last latlng,
// so third and last should not have changed
assert.equal(last, polyline._latlngs[4]);
assert.equal(third, polyline._latlngs[2]);
done();
});
});
it('should delete latlng on vertex click', function () {
happen.drawingClick(300, 250);
happen.at('click', 300, 250);
assert.equal(polyline._latlngs.length, 2);
});
});
describe('#continueForward()', function () {
describe('#removeVertex', function () {
it('should add new latlng on map click', function () {
polyline.editor.continueForward();
happen.drawingClick(400, 400);
assert.equal(polyline._latlngs.length, 3);
happen.at('click', 400, 400); // Finish shape
happen.at('click', 450, 450); // Click elsewhere on the map
assert.equal(polyline._latlngs.length, 3);
});
it('should remove vertex on click', function () {
happen.at('click', 400, 400);
assert.equal(polyline._latlngs.length, 4);
happen.at('click', 100, 150);
assert.equal(polyline._latlngs.length, 3);
happen.at('click', 400, 100);
assert.equal(polyline._latlngs.length, 2);
});
});
it('should not remove last two vertex', function () {
happen.at('click', 220, 360);
assert.equal(polyline._latlngs.length, 2);
happen.at('click', 300, 440);
assert.equal(polyline._latlngs.length, 2);
});
describe('#continueBackward()', function () {
it('should add new latlng on map click', function () {
polyline.editor.continueBackward();
happen.drawingClick(400, 100);
assert.equal(polyline._latlngs.length, 4);
happen.at('click', 400, 100); // Finish shape
happen.at('click', 450, 450); // Click elsewhere on the map
assert.equal(polyline._latlngs.length, 4);
});

@@ -128,38 +151,60 @@

describe('#dragMiddleMarker()', function () {
describe('#disableEdit()', function () {
it('should insert new latlng on middle marker click', function (done) {
var last = polyline._latlngs[3],
third = polyline._latlngs[2],
fromX = (400 + 220) / 2,
fromY = (400 + 360) / 2;
happen.drag(fromX, fromY, 300, 440, function () {
assert.equal(polyline._latlngs.length, 5);
// New should have been inserted between third and last latlng,
// so third and last should not have changed
assert.equal(last, polyline._latlngs[4]);
assert.equal(third, polyline._latlngs[2]);
done();
afterEach(function () {
this.map.editTools.editLayer.eachLayer(function (layer) {
assert.fail(layer, null, 'no layer expected but one found');
});
})
it('should stop editing on disableEdit() call', function () {
var layer = this.map.editTools.startPolyline();
layer.disableEdit();
assert.notOk(layer.editor);
});
it('should be reenabled after remove if active', function () {
var layer = L.polyline([]).addTo(this.map);
layer.enableEdit();
this.map.removeLayer(layer);
assert.notOk(layer.editEnabled());
this.map.addLayer(layer);
assert.ok(layer.editEnabled());
layer.remove();
});
it('should not be reenabled after remove if not active', function () {
var layer = L.polyline([]).addTo(this.map);
layer.enableEdit();
layer.disableEdit();
this.map.removeLayer(layer);
assert.notOk(layer.editEnabled());
this.map.addLayer(layer);
assert.notOk(layer.editEnabled());
});
});
describe('#enable()', function () {
describe('#removeVertex', function () {
afterEach(function () {
this.map.editTools.editLayer.eachLayer(function (layer) {
assert.fail(layer, null, 'no layer expected but one found');
});
})
it('should remove vertex on click', function () {
happen.at('click', 400, 400);
assert.equal(polyline._latlngs.length, 4);
happen.at('click', 100, 150);
assert.equal(polyline._latlngs.length, 3);
happen.at('click', 400, 100);
assert.equal(polyline._latlngs.length, 2);
it('should start editing on enableEdit() call', function () {
var layer = L.polyline([]).addTo(this.map);
layer.enableEdit();
assert.ok(layer.editEnabled());
layer.remove();
});
it('should not remove last two vertex', function () {
happen.at('click', 220, 360);
assert.equal(polyline._latlngs.length, 2);
happen.at('click', 300, 440);
assert.equal(polyline._latlngs.length, 2);
it('should not reset editor when calling enableEdit() twice', function () {
var layer = L.polyline([]).addTo(this.map);
layer.enableEdit();
var editor = layer.editor;
layer.enableEdit();
assert.equal(editor, layer.editor);
layer.remove();
});

@@ -169,9 +214,14 @@

describe('#onRemove', function () {
describe('#onRemove', function () {
it('should remove every edit related layer on remove', function () {
polyline.remove();
this.map.editTools.editLayer.eachLayer(function (layer) {
assert.fail(layer, null, 'no layer expected but one found');
assert.fail(layer, null, 'no layer expected but one found before');
});
var layer = L.polyline([p2ll(100, 150), p2ll(150, 200)]).addTo(this.map);
layer.enableEdit();
layer.remove();
this.map.editTools.editLayer.eachLayer(function (layer) {
assert.fail(layer, null, 'no layer expected but one found after');
});
});

@@ -277,2 +327,8 @@

afterEach(function () {
this.map.editTools.editLayer.eachLayer(function (layer) {
assert.fail(layer, null, 'no layer expected but one found');
});
})
it('should remove shape if not enough latlngs', function () {

@@ -321,2 +377,8 @@ var layer = this.map.editTools.startPolyline();

afterEach(function () {
this.map.editTools.editLayer.eachLayer(function (layer) {
assert.fail(layer, null, 'no layer expected but one found');
});
})
it('should fire editable:drawing:start on startPolyline call', function () {

@@ -329,3 +391,3 @@ var called = 0,

this.map.off('editable:drawing:start', call);
this.map.removeLayer(other);
other.editor.disable(); // Not added to the map, just disable ongoing drawing.
assert.notOk(this.map.editTools._drawingEditor);

@@ -432,3 +494,3 @@ });

this.map.off('editable:drawing:click', call);
layer.remove();
layer.editor.disable();
});

@@ -445,3 +507,3 @@

this.map.off('editable:drawing:move', call);
layer.remove();
layer.editor.disable();
});

@@ -478,2 +540,3 @@

assert.ok(line._latlngs.length);
assert.ok(this.map.hasLayer(line));
this.map.off('editable:editing', call);

@@ -480,0 +543,0 @@ line.remove();

@@ -0,1 +1,2 @@

'use strict';
describe('L.Editable.VertexMarker', function() {

@@ -11,2 +12,8 @@ var polyline, p2ll;

afterEach(function () {
this.map.editTools.editLayer.eachLayer(function (layer) {
assert.fail(layer, null, 'no layer expected but one found');
});
});
describe('#split', function () {

@@ -13,0 +20,0 @@

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc