mirror of
https://github.com/scratchfoundation/paper.js.git
synced 2025-01-03 19:45:44 -05:00
Implement ChangeFlag.INSERTION notification to know when an item was inserted in a new parent inside the DOM.
This commit is contained in:
parent
946e0d5b2c
commit
aeeba4d58d
3 changed files with 43 additions and 21 deletions
|
@ -14,25 +14,27 @@ var ChangeFlag = {
|
|||
// Anything affecting the appearance of an item, including GEOMETRY,
|
||||
// STROKE, STYLE and ATTRIBUTE (except for the invisible ones: locked, name)
|
||||
APPEARANCE: 0x1,
|
||||
// Change in item hierarchy
|
||||
// A change in the item's children
|
||||
CHILDREN: 0x2,
|
||||
// A change in the item's place in the DOM (removed, inserted, moved).
|
||||
INSERTION: 0x4,
|
||||
// Item geometry (path, bounds)
|
||||
GEOMETRY: 0x4,
|
||||
// Only segment(s) have changed, and affected curves have alredy been
|
||||
GEOMETRY: 0x8,
|
||||
// Only segment(s) have changed, and affected curves have already been
|
||||
// notified. This is to implement an optimization in _changed() calls.
|
||||
SEGMENTS: 0x8,
|
||||
SEGMENTS: 0x10,
|
||||
// Stroke geometry (excluding color)
|
||||
STROKE: 0x10,
|
||||
STROKE: 0x20,
|
||||
// Fill style or stroke color / dash
|
||||
STYLE: 0x20,
|
||||
STYLE: 0x40,
|
||||
// Item attributes: visible, blendMode, locked, name, opacity, clipMask ...
|
||||
ATTRIBUTE: 0x40,
|
||||
ATTRIBUTE: 0x80,
|
||||
// Text content
|
||||
CONTENT: 0x80,
|
||||
CONTENT: 0x100,
|
||||
// Raster pixels
|
||||
PIXELS: 0x100,
|
||||
PIXELS: 0x200,
|
||||
// Clipping in one of the child items
|
||||
CLIPPING: 0x200
|
||||
CLIPPING: 0x400
|
||||
};
|
||||
|
||||
// Shortcuts to often used ChangeFlag values including APPEARANCE
|
||||
|
@ -40,6 +42,8 @@ var Change = {
|
|||
// CHILDREN also changes GEOMETRY, since removing children from groups
|
||||
// changes bounds.
|
||||
CHILDREN: ChangeFlag.CHILDREN | ChangeFlag.GEOMETRY | ChangeFlag.APPEARANCE,
|
||||
// Changing the insertion can change the appearance through parent's matrix.
|
||||
INSERTION: ChangeFlag.INSERTION | ChangeFlag.APPEARANCE,
|
||||
GEOMETRY: ChangeFlag.GEOMETRY | ChangeFlag.APPEARANCE,
|
||||
SEGMENTS: ChangeFlag.SEGMENTS | ChangeFlag.GEOMETRY | ChangeFlag.APPEARANCE,
|
||||
STROKE: ChangeFlag.STROKE | ChangeFlag.STYLE | ChangeFlag.APPEARANCE,
|
||||
|
|
|
@ -2006,10 +2006,15 @@ var Item = Base.extend(Callback, /** @lends Item# */{
|
|||
if (_proto && !(item instanceof _proto)) {
|
||||
items.splice(i, 1);
|
||||
} else {
|
||||
item._remove(true);
|
||||
// Notify parent of change. Don't notify item itself yet,
|
||||
// as we're doing so when adding it to the new parent below.
|
||||
item._remove(false, true);
|
||||
}
|
||||
}
|
||||
Base.splice(children, items, index, 0);
|
||||
var project = this._project,
|
||||
// See #_remove() for an explanation of this:
|
||||
notifySelf = project && project._changes;
|
||||
for (var i = 0, l = items.length; i < l; i++) {
|
||||
var item = items[i];
|
||||
item._parent = this;
|
||||
|
@ -2018,6 +2023,8 @@ var Item = Base.extend(Callback, /** @lends Item# */{
|
|||
// are kept in sync.
|
||||
if (item._name)
|
||||
item.setName(item._name);
|
||||
if (notifySelf)
|
||||
this._changed(/*#=*/ Change.INSERTION);
|
||||
}
|
||||
this._changed(/*#=*/ Change.CHILDREN);
|
||||
} else {
|
||||
|
@ -2164,16 +2171,24 @@ var Item = Base.extend(Callback, /** @lends Item# */{
|
|||
/**
|
||||
* Removes the item from its parent's children list.
|
||||
*/
|
||||
_remove: function(notify) {
|
||||
if (this._parent) {
|
||||
_remove: function(notifySelf, notifyParent) {
|
||||
var parent = this._parent;
|
||||
if (parent) {
|
||||
if (this._name)
|
||||
this._removeNamed();
|
||||
if (this._index != null)
|
||||
Base.splice(this._parent._children, null, this._index, 1);
|
||||
Base.splice(parent._children, null, this._index, 1);
|
||||
this._installEvents(false);
|
||||
// Notify parent of changed hierarchy
|
||||
if (notify)
|
||||
this._parent._changed(/*#=*/ Change.CHILDREN);
|
||||
// Notify self of the insertion change. We only need this
|
||||
// notification if we're tracking changes for now.
|
||||
if (notifySelf) {
|
||||
var project = this._project;
|
||||
if (project && project._changes)
|
||||
this._changed(/*#=*/ Change.INSERTION);
|
||||
}
|
||||
// Notify parent of changed children
|
||||
if (notifyParent)
|
||||
parent._changed(/*#=*/ Change.CHILDREN);
|
||||
this._parent = null;
|
||||
return true;
|
||||
}
|
||||
|
@ -2187,7 +2202,8 @@ var Item = Base.extend(Callback, /** @lends Item# */{
|
|||
* @return {Boolean} {@true if the item was removed}
|
||||
*/
|
||||
remove: function() {
|
||||
return this._remove(true);
|
||||
// Notify self and parent of change:
|
||||
return this._remove(true, true);
|
||||
},
|
||||
|
||||
/**
|
||||
|
@ -2217,8 +2233,10 @@ var Item = Base.extend(Callback, /** @lends Item# */{
|
|||
// deletes it for the removed items. Calling #_remove() afterwards is
|
||||
// fine, since it only calls Base.splice() if #_index is set.
|
||||
var removed = Base.splice(this._children, null, from, to - from);
|
||||
for (var i = removed.length - 1; i >= 0; i--)
|
||||
removed[i]._remove(false);
|
||||
for (var i = removed.length - 1; i >= 0; i--) {
|
||||
// Don't notify parent each time, notify it separately after.
|
||||
removed[i]._remove(true, false);
|
||||
}
|
||||
if (removed.length > 0)
|
||||
this._changed(/*#=*/ Change.CHILDREN);
|
||||
return removed;
|
||||
|
|
|
@ -131,7 +131,7 @@ var Layer = Group.extend(/** @lends Layer# */{
|
|||
// If the item is a layer and contained within Project#layers, use
|
||||
// our own version of move().
|
||||
if (item instanceof Layer && !item._parent) {
|
||||
this._remove(true);
|
||||
this._remove(true, true);
|
||||
Base.splice(item._project.layers, [this],
|
||||
item._index + (above ? 1 : 0), 0);
|
||||
this._setProject(item._project, true);
|
||||
|
|
Loading…
Reference in a new issue