RIFT-15726 - optimize download size -> lodash usage in UI
[osm/UI.git] / skyquake / plugins / composer / src / src / libraries / DeletionManager.js
1
2 /*
3 *
4 * Copyright 2016 RIFT.IO Inc
5 *
6 * Licensed under the Apache License, Version 2.0 (the "License");
7 * you may not use this file except in compliance with the License.
8 * You may obtain a copy of the License at
9 *
10 * http://www.apache.org/licenses/LICENSE-2.0
11 *
12 * Unless required by applicable law or agreed to in writing, software
13 * distributed under the License is distributed on an "AS IS" BASIS,
14 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 * See the License for the specific language governing permissions and
16 * limitations under the License.
17 *
18 */
19 /**
20 * Created by onvelocity on 10/2/15.
21 */
22
23 import d3 from 'd3'
24 import UID from './UniqueId'
25 import SelectionManager from './SelectionManager'
26 import CatalogItemsActions from '../actions/CatalogItemsActions'
27 import DescriptorModelFactory from './model/DescriptorModelFactory'
28
29 import '../styles/Animations.scss'
30
31 const DELETE = 26;
32 const BACKSPACE = 8;
33
34 function onlyUnique(value, index, self) {
35 return self.indexOf(value) === index;
36 }
37
38 function createDeleteEvent(e, uid, eventName = 'cut') {
39 const data = {
40 bubbles: true,
41 cancelable: true,
42 detail: {
43 uid: uid,
44 originalEvent: e
45 }
46 };
47 if (window.CustomEvent.prototype.initCustomEvent) {
48 // support IE
49 var evt = document.createEvent('CustomEvent');
50 evt.initCustomEvent(eventName, data.bubbles, data.cancelable, data.detail);
51 return evt;
52 }
53 return new CustomEvent(eventName, data);
54 }
55
56 export default class DeletionManager {
57
58 static onDeleteKey(event) {
59 const target = event.target;
60 if (event.defaultPrevented) {
61 return
62 }
63 if ((event.which === DELETE || event.which === BACKSPACE) && /^BODY|SVG|DIV$/i.test(target.tagName)) {
64 event.preventDefault();
65 DeletionManager.deleteSelected(event);
66 return false;
67 }
68 }
69
70 static deleteSelected(event) {
71
72 // TODO refactor this to be a flux action e.g. move this code into ComposerAppActions.deleteSelected()
73
74 const selected = SelectionManager.getSelections();
75
76 const canvasPanelDiv = document.getElementById('canvasPanelDiv');
77
78 if (!canvasPanelDiv) {
79 return
80 }
81
82 // get a valid list of items to potentially remove via the cut event handler
83 const removeElementList = selected.filter(d => d).filter(onlyUnique).reduce((r, uid) => {
84 const elements = Array.from(canvasPanelDiv.querySelectorAll('[data-uid="' + uid + '"]'));
85 return r.concat(elements);
86 }, []).filter(d => d);
87
88 if (removeElementList.length === 0 && selected.length > 0) {
89 // something was selected but we did not find any dom elements with data-uid!
90 console.error(`No valid DescriptorModel instance found on element. Did you forget to put data-uid={m.uid}`,
91 selected.map(uid => Array.from(canvasPanelDiv.querySelectorAll(`[data-uid="${uid}"]`))));
92 }
93
94 SelectionManager.removeOutline();
95
96 // now actually update the model
97 const invokedEventAlreadyMap = {};
98 const failedToRemoveList = removeElementList.map(element => {
99
100 const uid = UID.from(element);
101
102 if (invokedEventAlreadyMap[uid]) {
103 return
104 }
105
106 try {
107 // https://developer.mozilla.org/en-US/docs/Web/API/EventTarget/dispatchEvent
108 // false means event.preventDefault() was called by one of the handlers
109 const deleteEvent = createDeleteEvent(event, uid);
110 const preventDefault = (false === element.dispatchEvent(deleteEvent));
111 if (preventDefault) {
112 console.log('cut event was cancelled', element);
113 //d3.select(element).classed('-with-animations deleteItemAnimation', false).style({opacity: null});
114 return element;
115 }
116
117 } catch (error) {
118 console.warn(`Exception caught dispatching 'cut' event: ${error}`,
119 selected.map(uid => Array.from(canvasPanelDiv.querySelectorAll(`[data-uid="${uid}"]`)))
120 );
121 return element;
122 } finally {
123 invokedEventAlreadyMap[uid] = true;
124 }
125
126 }).filter(d => d).filter(onlyUnique);
127
128 SelectionManager.clearSelectionAndRemoveOutline();
129 failedToRemoveList.forEach(d => SelectionManager.addSelection(d));
130 SelectionManager.refreshOutline();
131
132 }
133
134 static addEventListeners() {
135 DeletionManager.removeEventListeners();
136 document.body.addEventListener('keydown', DeletionManager.onDeleteKey);
137 }
138
139 static removeEventListeners() {
140 document.body.removeEventListener('keydown', DeletionManager.onDeleteKey);
141 }
142
143 }