Skip to content

Commit 3c04033

Browse files
committed
Fix component selection boundaries in case when there is multiple component instances with the same key.
1 parent 53d53da commit 3c04033

3 files changed

Lines changed: 72 additions & 30 deletions

File tree

src/framework/components/PageComposer/ComponentWrapper.js

Lines changed: 29 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import isEqual from 'lodash/isEqual';
22
import React, {Component} from 'react';
33
import ReactDOM from 'react-dom';
4+
import { isVisible } from './utilities';
45

56
const style = {
67
width: '100%',
@@ -66,16 +67,10 @@ class ComponentWrapper extends Component {
6667
this.handleDragEnter = this.handleDragEnter.bind(this);
6768
this.handleDragLeave = this.handleDragLeave.bind(this);
6869
this.handleDrop = this.handleDrop.bind(this);
69-
70-
const { elementKey, onComponentInstanceInitialize } = this.props;
71-
if (onComponentInstanceInitialize) {
72-
onComponentInstanceInitialize(elementKey, this);
73-
}
74-
7570
}
7671

7772
initDOMNode() {
78-
this.$DOMNode = this.$DOMNode || ReactDOM.findDOMNode(this);
73+
this.$DOMNode = ReactDOM.findDOMNode(this);
7974
if (this.$DOMNode) {
8075
this.$DOMNode.addEventListener('mousedown', this.handleMouseDown, false);
8176
this.$DOMNode.addEventListener('mouseover', this.handleMouseOver, false);
@@ -87,8 +82,25 @@ class ComponentWrapper extends Component {
8782
}
8883
}
8984

85+
clearDOMNode() {
86+
if (this.$DOMNode) {
87+
this.$DOMNode.removeEventListener('mousedown', this.handleMouseDown);
88+
this.$DOMNode.removeEventListener('mouseover', this.handleMouseOver);
89+
this.$DOMNode.removeEventListener('mouseout', this.handleMouseOut);
90+
this.$DOMNode.removeEventListener('click', this.handleNoop);
91+
this.$DOMNode.removeEventListener('doubleclick', this.handleNoop);
92+
this.$DOMNode.removeEventListener('mouseup', this.handleNoop);
93+
this.$DOMNode.removeEventListener('contextmenu', this.handleContextMenu);
94+
}
95+
this.$DOMNode = undefined;
96+
}
97+
9098
componentDidMount() {
9199
this.initDOMNode();
100+
const { elementKey, onComponentInstanceInitialize } = this.props;
101+
if (onComponentInstanceInitialize) {
102+
onComponentInstanceInitialize(elementKey, this);
103+
}
92104
}
93105

94106
componentDidUpdate(prevProps, prevState, snapshot) {
@@ -122,30 +134,23 @@ class ComponentWrapper extends Component {
122134
}
123135

124136
componentWillUnmount() {
125-
if (this.$DOMNode) {
126-
this.$DOMNode.removeEventListener('mousedown', this.handleMouseDown);
127-
this.$DOMNode.removeEventListener('mouseover', this.handleMouseOver);
128-
this.$DOMNode.removeEventListener('mouseout', this.handleMouseOut);
129-
this.$DOMNode.removeEventListener('click', this.handleNoop);
130-
this.$DOMNode.removeEventListener('doubleclick', this.handleNoop);
131-
this.$DOMNode.removeEventListener('mouseup', this.handleNoop);
132-
this.$DOMNode.removeEventListener('contextmenu', this.handleContextMenu);
133-
}
134-
this.$DOMNode = undefined;
137+
this.clearDOMNode();
135138
const { elementKey, onComponentInstanceDestroy } = this.props;
136139
if (onComponentInstanceDestroy) {
137-
onComponentInstanceDestroy(elementKey);
140+
onComponentInstanceDestroy(elementKey, this);
138141
}
139142
}
140143

141144
selectComponent () {
142145
const {elementKey} = this.props;
143-
window.dispatchEvent(new CustomEvent('selectComponentWrapper', {
144-
detail: {
145-
elementKey,
146-
domNode: this.$DOMNode
147-
}
148-
}));
146+
if (isVisible(this.$DOMNode)) {
147+
window.dispatchEvent(new CustomEvent('selectComponentWrapper', {
148+
detail: {
149+
elementKey,
150+
domNode: this.$DOMNode
151+
}
152+
}));
153+
}
149154
};
150155

151156
handleMouseDown(e) {

src/framework/components/PageComposer/PageComposer.js

Lines changed: 22 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -243,9 +243,13 @@ class PageComposer extends React.Component {
243243
traverseComponentInstances() {
244244
if (selectedKeys && selectedKeys.length > 0) {
245245
selectedKeys.forEach(selectedKeyItem => {
246-
const componentInstance = this.componentInstancesMap[selectedKeyItem];
247-
if (componentInstance && componentInstance.selectComponent) {
248-
componentInstance.selectComponent();
246+
const componentRefs = this.componentInstancesMap[selectedKeyItem];
247+
if (componentRefs && componentRefs.length > 0) {
248+
componentRefs.forEach(componentInstance => {
249+
if (componentInstance && componentInstance.selectComponent) {
250+
componentInstance.selectComponent();
251+
}
252+
});
249253
}
250254
});
251255
} else {
@@ -258,11 +262,23 @@ class PageComposer extends React.Component {
258262
}
259263

260264
handleComponentInstanceInitialize(elementKey, componentRef) {
261-
this.componentInstancesMap[elementKey] = componentRef;
265+
this.componentInstancesMap[elementKey] = this.componentInstancesMap[elementKey] || [];
266+
this.componentInstancesMap[elementKey].push(componentRef);
262267
}
263268

264-
handleComponentInstanceDestroy(elementKey) {
265-
delete this.componentInstancesMap[elementKey];
269+
handleComponentInstanceDestroy(elementKey, componentRef) {
270+
const componentRefs = this.componentInstancesMap[elementKey];
271+
if (componentRefs) {
272+
if (componentRefs.length === 1) {
273+
delete this.componentInstancesMap[elementKey];
274+
} else if (componentRefs.length > 1) {
275+
const foundIndex = componentRefs.findIndex(i => i === componentRef);
276+
if (foundIndex >= 0) {
277+
componentRefs.splice(foundIndex, 1);
278+
this.componentInstancesMap[elementKey] = componentRefs;
279+
}
280+
}
281+
}
266282
}
267283

268284
handleReceiveMessage(event) {

src/framework/components/PageComposer/utilities.js

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,27 @@ export function offsetInViewPort(el) {
66
return getPosition(el);
77
}
88

9+
export function isVisible(el) {
10+
if (el) {
11+
let styleDisplay = el.style.display;
12+
let styleVisibility = el.style.visibility;
13+
if (styleDisplay === 'none' || styleVisibility === 'hidden') {
14+
return false;
15+
} else {
16+
const computedStyle = window.getComputedStyle(el, null);
17+
if (computedStyle) {
18+
styleDisplay = computedStyle.getPropertyValue('display');
19+
styleVisibility = computedStyle.getPropertyValue('visibility');
20+
if (styleDisplay === 'none' || styleVisibility === 'hidden') {
21+
return false;
22+
}
23+
}
24+
}
25+
return true;
26+
}
27+
return false;
28+
}
29+
930
function getPosition1(el) {
1031
let xPos = 0;
1132
let yPos = 0;

0 commit comments

Comments
 (0)