4 * Copyright 2016 RIFT.IO Inc
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
10 * http://www.apache.org/licenses/LICENSE-2.0
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.
20 * Created by onvelocity on 10/2/15.
23 import _
from 'lodash'
25 import UID
from './UniqueId'
26 import SelectionManager
from './SelectionManager'
27 import CatalogItemsActions
from '../actions/CatalogItemsActions'
28 import DescriptorModelFactory
from './model/DescriptorModelFactory'
30 import '../styles/Animations.scss'
35 function onlyUnique(value
, index
, self
) {
36 return self
.indexOf(value
) === index
;
39 function createDeleteEvent(e
, uid
, eventName
= 'cut') {
48 if (window
.CustomEvent
.prototype.initCustomEvent
) {
50 var evt
= document
.createEvent('CustomEvent');
51 evt
.initCustomEvent(eventName
, data
.bubbles
, data
.cancelable
, data
.detail
);
54 return new CustomEvent(eventName
, data
);
57 export default class DeletionManager
{
59 static onDeleteKey(event
) {
60 const target
= event
.target
;
61 if (event
.defaultPrevented
) {
64 if ((event
.which
=== DELETE
|| event
.which
=== BACKSPACE
) && /^BODY|SVG|DIV$/i.test(target
.tagName
)) {
65 event
.preventDefault();
66 DeletionManager
.deleteSelected(event
);
71 static deleteSelected(event
) {
73 // TODO refactor this to be a flux action e.g. move this code into ComposerAppActions.deleteSelected()
75 const selected
= SelectionManager
.getSelections();
77 const canvasPanelDiv
= document
.getElementById('canvasPanelDiv');
79 if (!canvasPanelDiv
) {
83 // get a valid list of items to potentially remove via the cut event handler
84 const removeElementList
= selected
.filter(d
=> d
).filter(onlyUnique
).reduce((r
, uid
) => {
85 const elements
= Array
.from(canvasPanelDiv
.querySelectorAll('[data-uid="' + uid
+ '"]'));
86 return r
.concat(elements
);
87 }, []).filter(d
=> d
);
89 if (removeElementList
.length
=== 0 && selected
.length
> 0) {
90 // something was selected but we did not find any dom elements with data-uid!
91 console
.error(`No valid DescriptorModel instance found on element. Did you forget to put data-uid={m.uid}`,
92 selected
.map(uid
=> Array
.from(canvasPanelDiv
.querySelectorAll(`[data-uid="${uid}"]`))));
95 SelectionManager
.removeOutline();
97 // now actually update the model
98 const invokedEventAlreadyMap
= {};
99 const failedToRemoveList
= removeElementList
.map(element
=> {
101 const uid
= UID
.from(element
);
103 if (invokedEventAlreadyMap
[uid
]) {
108 // https://developer.mozilla.org/en-US/docs/Web/API/EventTarget/dispatchEvent
109 // false means event.preventDefault() was called by one of the handlers
110 const deleteEvent
= createDeleteEvent(event
, uid
);
111 const preventDefault
= (false === element
.dispatchEvent(deleteEvent
));
112 if (preventDefault
) {
113 console
.log('cut event was cancelled', element
);
114 //d3.select(element).classed('-with-animations deleteItemAnimation', false).style({opacity: null});
119 console
.warn(`Exception caught dispatching 'cut' event: ${error}`,
120 selected
.map(uid
=> Array
.from(canvasPanelDiv
.querySelectorAll(`[data-uid="${uid}"]`)))
124 invokedEventAlreadyMap
[uid
] = true;
127 }).filter(d
=> d
).filter(onlyUnique
);
129 SelectionManager
.clearSelectionAndRemoveOutline();
130 failedToRemoveList
.forEach(d
=> SelectionManager
.addSelection(d
));
131 SelectionManager
.refreshOutline();
135 static addEventListeners() {
136 DeletionManager
.removeEventListeners();
137 document
.body
.addEventListener('keydown', DeletionManager
.onDeleteKey
);
140 static removeEventListeners() {
141 document
.body
.removeEventListener('keydown', DeletionManager
.onDeleteKey
);