Skip to content

Commit

Permalink
Update dnd-core and misc
Browse files Browse the repository at this point in the history
  • Loading branch information
gaearon committed Apr 3, 2015
1 parent d1b68b0 commit d878e39
Show file tree
Hide file tree
Showing 6 changed files with 99 additions and 62 deletions.
1 change: 1 addition & 0 deletions TODO
Expand Up @@ -17,3 +17,4 @@
dnd-core
* smarter canDrop()
* state extractor on removed target
* OKAY we prob need this big optimization: materialized views. (stream of props) + (stream of actions)
50 changes: 25 additions & 25 deletions modules/backends/HTML5.js
Expand Up @@ -203,8 +203,8 @@ export default class HTML5Backend {
this.dragStartSourceHandles = [];
}

handleDragStart(e, sourceHandle) {
this.dragStartSourceHandles.push([sourceHandle, e.currentTarget]);
handleDragStart(e, sourceId) {
this.dragStartSourceHandles.push([sourceId, e.currentTarget]);
}

handleTopDragStart(e) {
Expand All @@ -213,15 +213,15 @@ export default class HTML5Backend {

// Try calling beginDrag() on each drag source
// until one of them agrees to to be dragged.
let sourceHandle = null;
let sourceId = null;
let node = null;
for (let i = 0; i < dragStartSourceHandles.length; i++) {
[sourceHandle, node] = dragStartSourceHandles[i];
[sourceId, node] = dragStartSourceHandles[i];
// Pass false to keep drag source unpublished.
// We will publish it in the next tick so browser
// has time to screenshot current state and doesn't
// cancel drag if the source DOM node is removed.
this.actions.beginDrag(sourceHandle, false);
this.actions.beginDrag(sourceId, false);

if (this.monitor.isDragging()) {
break;
Expand Down Expand Up @@ -277,8 +277,8 @@ export default class HTML5Backend {
this.dragOverTargetHandles = [];
}

handleDragOver(e, targetHandle) {
this.dragOverTargetHandles.unshift(targetHandle);
handleDragOver(e, targetId) {
this.dragOverTargetHandles.unshift(targetId);
}

handleTopDragOver(e) {
Expand All @@ -287,7 +287,7 @@ export default class HTML5Backend {
this.actions.hover(dragOverTargetHandles);

const canDrop = dragOverTargetHandles.some(
targetHandle => this.monitor.canDrop(targetHandle)
targetId => this.monitor.canDrop(targetId)
);

if (canDrop) {
Expand Down Expand Up @@ -319,8 +319,8 @@ export default class HTML5Backend {
}
}

handleDragEnter(e, targetHandle) {
this.dragEnterTargetHandles.unshift(targetHandle);
handleDragEnter(e, targetId) {
this.dragEnterTargetHandles.unshift(targetId);
}

handleTopDragEnter(e) {
Expand All @@ -329,7 +329,7 @@ export default class HTML5Backend {
this.actions.hover(dragEnterTargetHandles);

const canDrop = dragEnterTargetHandles.some(
targetHandle => this.monitor.canDrop(targetHandle)
targetId => this.monitor.canDrop(targetId)
);

if (canDrop) {
Expand Down Expand Up @@ -365,8 +365,8 @@ export default class HTML5Backend {
this.enterLeaveCounter.reset();
}

handleDrop(e, targetHandle) {
this.dropTargetHandles.unshift(targetHandle);
handleDrop(e, targetId) {
this.dropTargetHandles.unshift(targetId);
}

handleTopDrop() {
Expand All @@ -391,8 +391,8 @@ export default class HTML5Backend {
};
}

setSourceNode(sourceHandle, node) {
let nodeHandlers = this.nodeHandlers[sourceHandle];
setSourceNode(sourceId, node) {
let nodeHandlers = this.nodeHandlers[sourceId];
if (nodeHandlers && nodeHandlers.node === node) {
return;
}
Expand All @@ -403,20 +403,20 @@ export default class HTML5Backend {
}

if (node) {
nodeHandlers = this.nodeHandlers[sourceHandle] = {
nodeHandlers = this.nodeHandlers[sourceId] = {
node,
dragstart: (e) => this.handleDragStart(e, sourceHandle)
dragstart: (e) => this.handleDragStart(e, sourceId)
};

node.setAttribute('draggable', true);
node.addEventListener('dragstart', nodeHandlers.dragstart);
} else {
delete this.nodeHandlers[sourceHandle];
delete this.nodeHandlers[sourceId];
}
}

setTargetNode(targetHandle, node) {
let nodeHandlers = this.nodeHandlers[targetHandle];
setTargetNode(targetId, node) {
let nodeHandlers = this.nodeHandlers[targetId];
if (nodeHandlers && nodeHandlers.node === node) {
return;
}
Expand All @@ -428,18 +428,18 @@ export default class HTML5Backend {
}

if (node) {
nodeHandlers = this.nodeHandlers[targetHandle] = {
nodeHandlers = this.nodeHandlers[targetId] = {
node,
dragenter: (e) => this.handleDragEnter(e, targetHandle),
dragover: (e) => this.handleDragOver(e, targetHandle),
drop: (e) => this.handleDrop(e, targetHandle)
dragenter: (e) => this.handleDragEnter(e, targetId),
dragover: (e) => this.handleDragOver(e, targetId),
drop: (e) => this.handleDrop(e, targetId)
};

node.addEventListener('dragenter', nodeHandlers.dragenter);
node.addEventListener('dragover', nodeHandlers.dragover);
node.addEventListener('drop', nodeHandlers.drop);
} else {
delete this.nodeHandlers[targetHandle];
delete this.nodeHandlers[targetId];
}
}
}
40 changes: 20 additions & 20 deletions modules/configureDragDrop.js
@@ -1,7 +1,7 @@
import React, { Component, PropTypes, findDOMNode } from 'react';
import ComponentDragSource from './ComponentDragSource';
import ComponentDropTarget from './ComponentDropTarget';
import shallowEqual from 'react/lib/shallowEqual';
import shallowEqual from './utils/shallowEqual';
import shallowEqualScalar from './utils/shallowEqualScalar';
import assign from 'lodash/object/assign';
import memoize from 'lodash/function/memoize';
Expand All @@ -28,7 +28,7 @@ export default function configureDragDrop(InnerComponent, {
this.manager = context[managerName];
invariant(this.manager, 'Could not read manager from context.');

this.handles = {};
this.handlerIds = {};
this.handlers = {};

this.connector = this.createConnector();
Expand Down Expand Up @@ -93,7 +93,7 @@ export default function configureDragDrop(InnerComponent, {

attachHandlers(handlers) {
this.handlers = assign({}, this.handlers);
this.handles = assign({}, this.handles);
this.handlerIds = assign({}, this.handlerIds);

Object.keys(handlers).forEach(key => {
this.attachHandler(key, handlers[key]);
Expand All @@ -102,16 +102,16 @@ export default function configureDragDrop(InnerComponent, {

detachHandlers() {
this.handlers = assign({}, this.handlers);
this.handles = assign({}, this.handles);
this.handlerIds = assign({}, this.handlerIds);

Object.keys(this.handles).forEach(key => {
Object.keys(this.handlerIds).forEach(key => {
this.detachHandler(key);
});
}

receiveHandlers(nextHandlers) {
this.handlers = assign({}, this.handlers);
this.handles = assign({}, this.handles);
this.handlerIds = assign({}, this.handlerIds);

const keys = Object.keys(this.handlers);
const nextKeys = Object.keys(nextHandlers);
Expand All @@ -132,9 +132,9 @@ export default function configureDragDrop(InnerComponent, {
const registry = this.manager.getRegistry();

if (handler instanceof ComponentDragSource) {
this.handles[key] = registry.addSource(handler.type, handler);
this.handlerIds[key] = registry.addSource(handler.type, handler);
} else if (handler instanceof ComponentDropTarget) {
this.handles[key] = registry.addTarget(handler.type, handler);
this.handlerIds[key] = registry.addTarget(handler.type, handler);
} else {
invariant(false, 'Handle is neither a source nor a target.');
}
Expand All @@ -144,17 +144,17 @@ export default function configureDragDrop(InnerComponent, {

detachHandler(key) {
const registry = this.manager.getRegistry();
const handle = this.handles[key];
const handlerId = this.handlerIds[key];

if (registry.isSourceHandle(handle)) {
registry.removeSource(handle);
} else if (registry.isTargetHandle(handle)) {
registry.removeTarget(handle);
if (registry.isSourceId(handlerId)) {
registry.removeSource(handlerId);
} else if (registry.isTargetId(handlerId)) {
registry.removeTarget(handlerId);
} else {
invariant(false, 'Handle is neither a source nor a target.');
}

delete this.handles[key];
delete this.handlerIds[key];
delete this.handlers[key];
}

Expand All @@ -171,12 +171,12 @@ export default function configureDragDrop(InnerComponent, {
getCurrentState() {
const monitor = this.manager.getMonitor();

let handles = this.handles;
if (handles[DEFAULT_KEY]) {
handles = handles[DEFAULT_KEY];
let handlerIds = this.handlerIds;
if (typeof handlerIds[DEFAULT_KEY] !== 'undefined') {
handlerIds = handlerIds[DEFAULT_KEY];
}

return inject(this.connector, monitor, handles);
return inject(this.connector, monitor, handlerIds);
}

createConnector() {
Expand All @@ -185,8 +185,8 @@ export default function configureDragDrop(InnerComponent, {
const wrappedConnector = {};

Object.keys(connector).forEach(function (key) {
wrappedConnector[key] = memoize(handle => componentOrNode =>
connector[key].call(connector, handle, findDOMNode(componentOrNode))
wrappedConnector[key] = memoize(handlerId => componentOrNode =>
connector[key].call(connector, handlerId, findDOMNode(componentOrNode))
);
});

Expand Down
31 changes: 31 additions & 0 deletions modules/utils/shallowEqual.js
@@ -0,0 +1,31 @@
export default function shallowEqual(objA, objB) {
if (objA === objB) {
return true;
}

var keysA = Object.keys(objA);
var keysB = Object.keys(objB);

if (keysA.length !== keysB.length) {
return false;
}

// Test for A's keys different from B.
var hasOwn = Object.prototype.hasOwnProperty;
for (var i = 0; i < keysA.length; i++) {
if (!hasOwn.call(objB, keysA[i]) ||
objA[keysA[i]] !== objB[keysA[i]]) {

return false;
}

var valA = objA[keysA[i]];
var valB = objB[keysA[i]];

if (valA !== valB) {
return false;
}
}

return true;
}
37 changes: 21 additions & 16 deletions modules/utils/shallowEqualScalar.js
@@ -1,29 +1,34 @@
import isBoolean from 'lodash/lang/isBoolean';
import isString from 'lodash/lang/isString';
import isNumber from 'lodash/lang/isNumber';
import isFunction from 'lodash/lang/isFunction';

export default function shallowEqualScalar(objA, objB) {
if (objA === objB) {
return true;
}

var key;
for (key in objA) {
if (objA.hasOwnProperty(key) &&
(!objB.hasOwnProperty(key) ||
objA[key] !== objB[key] ||
typeof objA[key] === 'object' ||
typeof objB[key] === 'object')) {
if (typeof objA !== 'object' || objA === null ||
typeof objB !== 'object' || objB === null) {
return false;
}

var keysA = Object.keys(objA);
var keysB = Object.keys(objB);

if (keysA.length !== keysB.length) {
return false;
}

// Test for A's keys different from B.
var hasOwn = Object.prototype.hasOwnProperty;
for (var i = 0; i < keysA.length; i++) {
if (!hasOwn.call(objB, keysA[i])) {
return false;
}
}

for (key in objB) {
if (objB.hasOwnProperty(key) && !objA.hasOwnProperty(key)) {
var valA = objA[keysA[i]];
var valB = objB[keysA[i]];

if (valA !== valB || typeof valA === 'object' || typeof valB === 'object') {
return false;
}
}

return true;
}
}
2 changes: 1 addition & 1 deletion package.json
Expand Up @@ -31,7 +31,7 @@
},
"homepage": "https://github.com/gaearon/react-dnd",
"dependencies": {
"dnd-core": "^0.6.1",
"dnd-core": "~0.7.0",
"flux": "^2.0.1",
"lodash": "^3.1.0"
},
Expand Down

0 comments on commit d878e39

Please sign in to comment.