Add Base.splice() to handle lists of items with _index referneces and use it for paper.documents and Item#children.

This commit is contained in:
Jürg Lehni 2011-05-07 16:11:05 +01:00
parent b44e796475
commit 8c7b253bc2
4 changed files with 46 additions and 18 deletions

View file

@ -50,12 +50,12 @@ var Document = this.Document = Base.extend({
this._size = Size.read(arguments) || new Size(1024, 768);
this.canvas = CanvasProvider.getCanvas(this._size);
}
// TODO: currently we don't do anything with Document#bounds.. What
// does it mean to change the bounds of the document? (JP)
// TODO: Currently we don't do anything with Document#bounds.
// What does it mean to change the bounds of the document? (JP)
this.bounds = Rectangle.create(0, 0, this._size.width,
this._size.height);
this.context = this.canvas.getContext('2d');
paper.documents.push(this);
Base.splice(paper.documents, [this]);
this.activate();
this.layers = [];
this.activeLayer = new Layer();
@ -65,7 +65,7 @@ var Document = this.Document = Base.extend({
this.views = [this.activeView];
this._selectedItems = {};
this._selectedItemCount = 0;
// TODO: test this on IE:
// TODO: Test this on IE:
if (this.canvas.attributes.stats) {
this.stats = new Stats();
// Align top-left to the canvas
@ -102,6 +102,7 @@ var Document = this.Document = Base.extend({
},
activate: function() {
// TODO: Remove indexOf()
var index = paper.documents.indexOf(this);
if (index != -1) {
paper.document = this;

View file

@ -251,24 +251,21 @@ var Item = this.Item = Base.extend({
* The next item on the same level as this item.
*/
getNextSibling: function() {
return this.parent && this.parent.children[this.getIndex() + 1] || null;
return this.parent && this.parent.children[this._index + 1] || null;
},
/**
* The previous item on the same level as this item.
*/
getPreviousSibling: function() {
return this.parent && this.parent.children[this.getIndex() - 1] || null;
return this.parent && this.parent.children[this._index - 1] || null;
},
/**
* The index of this item within the list of it's parent's children.
*/
getIndex: function() {
// TODO: Relying on indexOf() here is slow, especially since it is
// used for getPrevious/NextSibling().
// We need linked lists instead.
return this.parent && this.parent.children.indexOf(this) || null;
return this._index !== undefined ? this._index : null;
},
/**
@ -276,8 +273,8 @@ var Item = this.Item = Base.extend({
*/
_removeFromParent: function() {
if (this.parent) {
var ok = !!this.parent.children.splice(this.getIndex(), 1).length;
// TODO: Reassign _index
var ok = !!Base.splice(this.parent.children, null,
this._index, 1).length;
this.parent = null;
return ok;
}
@ -812,8 +809,7 @@ var Item = this.Item = Base.extend({
return function(item) {
item._removeFromParent();
if (this.children) {
this.children.splice(top ? this.children.length : 0, 0, item);
// TODO: Reassign _index
Base.splice(this.children, [item], top ? undefined : 0, 0);
item.parent = this;
item._setDocument(this._document);
return true;
@ -826,9 +822,8 @@ var Item = this.Item = Base.extend({
return function(item) {
// first remove the item from its parent's children list
if (item.parent && this._removeFromParent()) {
item.parent.children.splice(item.getIndex()
+ (above ? 1 : -1), 0, this);
// TODO: Reassign _index
Base.splice(item.parent.children, [this],
item._index + (above ? 1 : -1), 0);
this.parent = item.parent;
this._setDocument(item._document);
return true;

View file

@ -79,6 +79,38 @@ Base.inject({
return res;
},
/**
* Utility function for adding and removing items from a list of which
* each entry keeps a reference to its index in the list in the private
* _index property. Used for paper.documents and Item#children.
*/
splice: function(list, items, index, remove) {
var amount = items && items.length,
append = index === undefined;
index = append ? list.length : index;
// Update _index on the items to be added first.
for (var i = 0; i < amount; i++) {
items[i]._index = index + i;
}
if (append) {
// Append them all at the end by using push
list.push.apply(list, items);
// Nothing removed, and nothing to adjust above
return [];
} else {
// Insert somewhere else and/or remove
var args = [index, remove];
if (items)
args.push.apply(args, items);
var removed = list.splice.apply(list, args);
// Adjust the indices of the items above.
for (var i = index + amount, l = list.length; i < l; i++) {
list[i]._index = i;
}
return removed;
}
},
capitalize: function(str) {
return str.replace(/\b[a-z]/g, function(match) {
return match.toUpperCase();

View file

@ -145,7 +145,7 @@ var Path = this.Path = PathItem.extend({
var segments = this._segments,
curves = this._curves,
amount = segs.length,
append = index === undefined,
append = index == null,
index = append ? segments.length : index;
// Scan through segments to add first, convert if necessary and set
// _path and _index references on them.