Skip to content

Ability to reorder layer in control panel, reflect changes in DOM and map #249

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 12 commits into from
Jan 21, 2021
2 changes: 2 additions & 0 deletions src/layer.js
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,7 @@ export class MapLayer extends HTMLElement {
// this is moved up here so that the layer control doesn't respond
// to the layer being removed with the _onLayerChange execution
// that is set up in _attached:
if(this.hasAttribute("moving")) return;
this._removeEvents();
if (this._layer._map) {
this._layer._map.removeLayer(this._layer);
Expand All @@ -83,6 +84,7 @@ export class MapLayer extends HTMLElement {
connectedCallback() {
//creates listener that waits for createmap event, this allows for delayed builds of maps
//this allows a safeguard for the case where loading a custom TCRS takes longer than loading mapml-viewer.js/web-map.js
if(this.hasAttribute("moving")) return;
this.parentNode.addEventListener('createmap', ()=>{
this._ready();
// if the map has been attached, set this layer up wrt Leaflet map
Expand Down
14 changes: 8 additions & 6 deletions src/mapml.css
Original file line number Diff line number Diff line change
Expand Up @@ -138,6 +138,7 @@
border: none;
margin: 0;
padding: 0;
cursor: grab;
}

.leaflet-control-layers-overlays > fieldset > .mapml-control-layers > summary,
Expand Down Expand Up @@ -278,12 +279,6 @@
* User interaction.
*/

/* Disable dragging of controls. */
.leaflet-control :not([draggable="true"]),
.mapml-contextmenu :not([draggable="true"]) {
-webkit-user-drag: none;
}

/* Disable text selection in controls. */
.leaflet-control,
.mapml-contextmenu,
Expand Down Expand Up @@ -354,3 +349,10 @@ summary {
.leaflet-container .leaflet-control-container {
visibility: unset!important;
}

.drag-active {
opacity: 0;
cursor: grabbing;
cursor: -moz-grabbing;
cursor: -webkit-grabbing;
}
63 changes: 49 additions & 14 deletions src/mapml/layers/MapLayer.js
Original file line number Diff line number Diff line change
Expand Up @@ -487,12 +487,12 @@ export var MapMLLayer = L.Layer.extend({
opacity = document.createElement('input'),
opacityControl = document.createElement('details'),
opacityControlSummary = document.createElement('summary'),
opacityControlSummaryLabel = document.createElement('label');
opacityControlSummaryLabel = document.createElement('label'),
root = this._layerEl.parentElement.shadowRoot, map = this._map, viewer = this._layerEl.parentNode;

input.defaultChecked = this._map ? true: false;
input.type = 'checkbox';
input.className = 'leaflet-control-layers-selector';
name.draggable = true;
name.layer = this;

if (this._legendUrl) {
Expand Down Expand Up @@ -521,19 +521,54 @@ export var MapMLLayer = L.Layer.extend({
opacity.setAttribute('step','0.1');
opacity.value = this._container.style.opacity || '1.0';

L.DomEvent.on(opacity,'change', this._changeOpacity, this);
L.DomEvent.on(name,'dragstart', function(event) {
// will have to figure out how to drag and drop a whole element
// with its contents in the case where the <layer->content</layer->
// has no src but does have inline content.
// Should be do-able, I think.
if (this._href) {
event.dataTransfer.setData("text/uri-list",this._href);
// Why use a second .setData("text/plain"...) ? This is very important:
// See https://developer.mozilla.org/en-US/docs/Web/API/HTML_Drag_and_Drop_API/Recommended_drag_types#link
event.dataTransfer.setData("text/plain", this._href);
fieldset.setAttribute("aria-grabbed", "false");
fieldset.draggable = true;

fieldset.onmousedown = (e) => {
e.target.closest("fieldset").draggable = e.target.tagName.toLowerCase() !== "input";
};

fieldset.onmouseup = (e) => {
e.target.closest("fieldset").draggable = true;
};

fieldset.ondrag = (e) => {
let control = e.target,
controls = e.target.parentNode,
x = e.clientX, y = e.clientY,
elementAt = root.elementFromPoint(x, y),
swapControl = !elementAt || !elementAt.closest("fieldset") || elementAt.closest("fieldset").draggable === false ? control : elementAt.closest("fieldset");
control.classList.add("drag-active");
control.setAttribute("aria-grabbed", 'true');
control.setAttribute("aria-dropeffect", "move");
if(swapControl && controls === swapControl.parentNode){
swapControl = swapControl !== control.nextSibling? swapControl : swapControl.nextSibling;
controls.insertBefore(control, swapControl);
}
};
fieldset.ondragend = (e) => {
e.target.classList.remove("drag-active");
e.target.setAttribute("aria-grabbed", "false");
e.target.removeAttribute("aria-dropeffect");
let controls = e.target.parentNode.children,
layers = map.getPane("overlayPane").children,
zIndex = 1;
for(let control of controls){
let layerEl = control.querySelector("span").layer._layerEl;
layerEl.setAttribute("moving","");
viewer.insertAdjacentElement("beforeend", layerEl);
layerEl.removeAttribute("moving");

for (let layer of layers){
if(control.querySelector("span").layer._container == layer){
layer.style["z-index"] = zIndex;
zIndex++;
}
}
}, this);
}
};

L.DomEvent.on(opacity,'change', this._changeOpacity, this);

fieldset.appendChild(details);
details.appendChild(summary);
Expand Down