diff --git a/demos/objectmodel/index.html b/demos/objectmodel/index.html
new file mode 100644
index 0000000..d45c5fc
--- /dev/null
+++ b/demos/objectmodel/index.html
@@ -0,0 +1,9 @@
+
+
+
+Object Model
+
+
+
+
+
\ No newline at end of file
diff --git a/demos/objectmodel/objectmodel.js b/demos/objectmodel/objectmodel.js
new file mode 100644
index 0000000..72e9539
--- /dev/null
+++ b/demos/objectmodel/objectmodel.js
@@ -0,0 +1,93 @@
+require('../mode');
+var ART = require('../../art');
+
+var art = ART.Surface(1000, 600);
+
+var group = ART.Group()
+ .inject(art);
+
+var text = ART.Text('DOM', 'bold 60px "Arial"')
+ .move(0, 0)
+ .fill('red')
+ .inject(group);
+
+var green = ART.Rectangle(100, 100)
+ .move(10, 10)
+ .fill('green')
+ .inject(group);
+
+var group2 = ART.Group()
+ .move(10,10)
+ .rotate(5)
+ .inject(group);
+
+var blue = ART.Rectangle(100, 100)
+ .move(10,10)
+ .rotate(-5)
+ .fill('blue')
+ .inject(group2);
+
+function eq(){
+ var a = arguments[0];
+ for (var i = 1; i < arguments.length; i++){
+ var b = arguments[i];
+ if (a !== b){ debugger; throw new Error('Assertion failed'); }
+ }
+}
+
+function verifyState(){
+ // art
+ // group
+ // text
+ // green
+ // group2
+ // blue
+
+ eq(art.firstChild, art.lastChild, group);
+ eq(group.nextSibling, group.previousSibling, null);
+
+ eq(group.firstChild, text);
+ eq(group.lastChild, group2);
+
+ eq(text.previousSibling, group2.nextSibling, null);
+
+ eq(text.nextSibling, green);
+ eq(green.previousSibling, text);
+
+ eq(green.nextSibling, group2);
+ eq(group2.previousSibling, green);
+
+ eq(group2.firstChild, group2.lastChild, blue);
+ eq(blue.nextSibling, blue.previousSibling, null);
+
+ eq(blue.parentNode, group2);
+ eq(text.parentNode, green.parentNode, group2.parentNode, group);
+ eq(group.parentNode, art);
+}
+
+verifyState();
+
+var alt = true;
+
+var timer = setInterval(function(){
+ alt = !alt;
+ if (alt)
+ green.eject();
+ else {
+ green.injectBefore(group2);
+ console.log('injecting' + green.parentNode);
+ verifyState();
+ //green.injectBefore(group2);
+ //group2.injectBefore(green);
+ }
+ group2.rotate(1, 50, 50);
+}, 500);
+
+group2.subscribe('click', function(){
+ clearInterval(timer);
+ group.empty();
+ art.empty();
+ blue.inject(art);
+});
+
+art.inject(document.body);
diff --git a/src/core/container.js b/src/core/container.js
deleted file mode 100644
index a7734f5..0000000
--- a/src/core/container.js
+++ /dev/null
@@ -1,10 +0,0 @@
-var Class = require('./class');
-
-module.exports = Class({
-
- grab: function(){
- for (var i = 0; i < arguments.length; i++) arguments[i].inject(this);
- return this;
- }
-
-});
\ No newline at end of file
diff --git a/src/dom/container.js b/src/dom/container.js
new file mode 100644
index 0000000..9d5b83b
--- /dev/null
+++ b/src/dom/container.js
@@ -0,0 +1,16 @@
+var Class = require('../core/class');
+
+module.exports = Class({
+
+ grab: function(){
+ for (var i = 0; i < arguments.length; i++) arguments[i].inject(this);
+ return this;
+ },
+
+ empty: function(){
+ var node;
+ while (node = this.firstChild) node.eject();
+ return this;
+ }
+
+});
\ No newline at end of file
diff --git a/src/dom/dummy.js b/src/dom/dummy.js
new file mode 100644
index 0000000..3131241
--- /dev/null
+++ b/src/dom/dummy.js
@@ -0,0 +1,116 @@
+var Class = require('../core/class');
+
+module.exports = Class({
+
+ // placement
+
+ _resetPlacement: function(){
+ var container = this.parentNode;
+ if (container){
+ var previous = this.previousSibling, next = this.nextSibling;
+ if (previous){
+ previous.nextSibling = next;
+ } else {
+ container.firstChild = next;
+ }
+ if (next){
+ next.previousSibling = previous;
+ } else {
+ container.lastChild = this.previousSibling;
+ }
+ }
+ this.previousSibling = null;
+ this.nextSibling = null;
+ this.parentNode = null;
+ return this;
+ },
+
+ inject: function(container){
+ this._resetPlacement();
+ var last = container.lastChild;
+ if (last){
+ last.nextSibling = this;
+ this.previousSibling = last;
+ } else {
+ container.firstChild = this;
+ }
+ container.lastChild = this;
+ this.parentNode = container;
+ this._place();
+ return this;
+ },
+
+ injectBefore: function(sibling){
+ this._resetPlacement();
+ var container = sibling.parentNode;
+ if (!container) return this;
+ var previous = sibling.previousSibling;
+ if (previous){
+ previous.nextSibling = this;
+ this.previousSibling = previous;
+ } else {
+ container.firstChild = this;
+ }
+ sibling.previousSibling = this;
+ this.nextSibling = sibling;
+ this.parentNode = container;
+ this._place();
+ return this;
+ },
+
+ eject: function(){
+ this._resetPlacement();
+ this._place();
+ return this;
+ },
+
+ _place: function(){},
+
+ // events
+
+ dispatch: function(event){
+ var events = this._events,
+ listeners = events && events[event.type];
+ if (listeners){
+ listeners = listeners.slice(0);
+ for (var i = 0, l = listeners.length; i < l; i++){
+ var fn = listeners[i], result;
+ if (typeof fn == 'function')
+ result = fn.call(this, event);
+ else
+ result = fn.handleEvent(event);
+ if (result === false) event.preventDefault();
+ }
+ }
+ if (this.parentNode && this.parentNode.dispatch){
+ this.parentNode.dispatch(event);
+ }
+ },
+
+ subscribe: function(type, fn, bind){
+ if (typeof type != 'string'){ // listen type / fn with object
+ var subscriptions = [];
+ for (var t in type) subscriptions.push(this.subscribe(t, type[t]));
+ return function(){ // unsubscribe
+ for (var i = 0, l = subscriptions.length; i < l; i++)
+ subscriptions[i]();
+ return this;
+ };
+ } else { // listen to one
+ var bound = typeof fn === 'function' ? fn.bind(bind || this) : fn,
+ events = this._events || (this._events = {}),
+ listeners = events[type] || (events[type] = []);
+ listeners.push(bound);
+ return function(){
+ // unsubscribe
+ for (var i = 0, l = listeners.length; i < l; i++){
+ if (listeners[i] === bound){
+ listeners.splice(i, 1);
+ break;
+ }
+ }
+ }
+ }
+ }
+
+});
diff --git a/src/dom/element.js b/src/dom/native.js
similarity index 57%
rename from src/dom/element.js
rename to src/dom/native.js
index 4971bee..4365e87 100644
--- a/src/dom/element.js
+++ b/src/dom/native.js
@@ -1,12 +1,34 @@
var Class = require('../core/class');
+function elementFrom(node){
+ if (node.toElement) return node.toElement();
+ if (node.getDOMNode) return node.getDOMNode();
+ return node;
+}
+
module.exports = Class({
- // dom
+ // conventions
+
+ toElement: function(){
+ return this.element;
+ },
+
+ getDOMNode: function(){
+ return this.toElement();
+ },
+
+ // placement
- inject: function(element){
- if (element.element) element = element.element;
- element.appendChild(this.element);
+ inject: function(container){
+ (container.containerElement || elementFrom(container))
+ .appendChild(this.element);
+ return this;
+ },
+
+ injectBefore: function(sibling){
+ var element = elementFrom(sibling);
+ element.parentNode.insertBefore(this.element, element);
return this;
},
@@ -28,7 +50,14 @@ module.exports = Class({
return this;
};
} else { // listen to one
- var bound = typeof fn === 'function' ? fn.bind(bind || this) : fn;
+ if (!bind) bind = this;
+ var bound;
+ if (typeof fn === 'function'){
+ bound = fn.bind ? fn.bind(bind)
+ : function(){ return fn.apply(bind, arguments); };
+ } else {
+ bound = fn;
+ }
var element = this.element;
if (element.addEventListener){
element.addEventListener(type, bound, false);
diff --git a/src/dom/shadow.js b/src/dom/shadow.js
new file mode 100644
index 0000000..cfc7c72
--- /dev/null
+++ b/src/dom/shadow.js
@@ -0,0 +1,32 @@
+var Class = require('../core/class');
+var Dummy = require('./dummy');
+var Native = require('./native');
+
+module.exports = Class(Dummy, Native, {
+
+ dummy_inject: Dummy.prototype.inject,
+ dummy_injectBefore: Dummy.prototype.injectBefore,
+ dummy_eject: Dummy.prototype.eject,
+ native_inject: Native.prototype.inject,
+ native_injectBefore: Native.prototype.injectBefore,
+ native_eject: Native.prototype.eject,
+
+ inject: function(container){
+ this.dummy_inject(container);
+ this.native_inject(container);
+ return this;
+ },
+
+ injectBefore: function(sibling){
+ this.dummy_injectBefore(sibling);
+ this.native_injectBefore(sibling);
+ return this;
+ },
+
+ eject: function(){
+ this.dummy_eject();
+ this.native_eject();
+ return this;
+ }
+
+});
diff --git a/src/modes/canvas/group.js b/src/modes/canvas/group.js
index f703329..6352805 100644
--- a/src/modes/canvas/group.js
+++ b/src/modes/canvas/group.js
@@ -1,5 +1,5 @@
var Class = require('../../core/class');
-var Container = require('../../core/container');
+var Container = require('../../dom/container');
var Node = require('./node');
module.exports = Class(Node, Container, {
@@ -7,14 +7,16 @@ module.exports = Class(Node, Container, {
initialize: function(width, height){
this.width = width;
this.height = height;
- this.children = [];
},
localHitTest: function(x, y){
- var children = this.children, i = children.length;
- while (i--){
- var hit = children[i].hitTest(x, y);
+ var i = 0;
+ var node = this.lastChild;
+ while (node){
+ var hit = node.hitTest(x, y);
if (hit) return hit;
+ node = node.previousSibling;
+ if (i++ > 100){ debugger; throw new Error('recursion'); }
}
return null;
},
@@ -32,9 +34,12 @@ module.exports = Class(Node, Container, {
yx = t * this.xx + yy * this.yx;
yy = t * this.xy + yy * this.yy;
- var children = this.children;
- for (var i = 0, l = children.length; i < l; i++){
- children[i].renderTo(context, xx, yx, xy, yy, x, y);
+ var i = 0;
+ var node = this.firstChild;
+ while (node){
+ node.renderTo(context, xx, yx, xy, yy, x, y);
+ node = node.nextSibling;
+ if (i++ > 100){ debugger; throw new Error('recursion'); }
}
}
diff --git a/src/modes/canvas/node.js b/src/modes/canvas/node.js
index 1f12fae..9aa7da7 100644
--- a/src/modes/canvas/node.js
+++ b/src/modes/canvas/node.js
@@ -1,36 +1,18 @@
var Class = require('../../core/class');
var Transform = require('../../core/transform');
+var Element = require('../../dom/dummy');
-var CanvasNode = Class(Transform, {
-
- inject: function(container){
- this.eject();
- this.container = container;
- container.children.push(this);
- return this.invalidate();
- },
-
- eject: function(){
- var container = this.container;
- if (container){
- var siblings = container.children,
- i = siblings.length;
- while (i--)
- if (siblings[i] === this)
- siblings.splice(i, 1);
- }
- this.invalidate();
- this.container = null;
- return this;
- },
+var CanvasNode = Class(Transform, Element, {
invalidate: function(){
- if (this.container) this.container.invalidate();
+ if (this.parentNode) this.parentNode.invalidate();
if (this._layer) this._layerCache = null;
return this;
},
-
- // transforms
+
+ _place: function(){
+ this.invalidate();
+ },
_transform: function(){
this.invalidate();
@@ -39,7 +21,7 @@ var CanvasNode = Class(Transform, {
blend: function(opacity){
if (opacity >= 1 && this._layer) this._layer = null;
this._opacity = opacity;
- if (this.container) this.container.invalidate();
+ if (this.parentNode) this.parentNode.invalidate();
return this;
},
@@ -47,13 +29,13 @@ var CanvasNode = Class(Transform, {
hide: function(){
this._invisible = true;
- if (this.container) this.container.invalidate();
+ if (this.parentNode) this.parentNode.invalidate();
return this;
},
show: function(){
this._invisible = false;
- if (this.container) this.container.invalidate();
+ if (this.parentNode) this.parentNode.invalidate();
return this;
},
@@ -72,53 +54,6 @@ var CanvasNode = Class(Transform, {
return this.localHitTest(point.x, point.y);
},
- // events
-
- dispatch: function(event){
- var events = this._events,
- listeners = events && events[event.type];
- if (listeners){
- listeners = listeners.slice(0);
- for (var i = 0, l = listeners.length; i < l; i++){
- var fn = listeners[i], result;
- if (typeof fn == 'function')
- result = fn.call(this, event);
- else
- result = fn.handleEvent(event);
- if (result === false) event.preventDefault();
- }
- }
- if (this.container && this.container.dispatch){
- this.container.dispatch(event);
- }
- },
-
- subscribe: function(type, fn, bind){
- if (typeof type != 'string'){ // listen type / fn with object
- var subscriptions = [];
- for (var t in type) subscriptions.push(this.subscribe(t, type[t]));
- return function(){ // unsubscribe
- for (var i = 0, l = subscriptions.length; i < l; i++)
- subscriptions[i]();
- return this;
- };
- } else { // listen to one
- var bound = typeof fn === 'function' ? fn.bind(bind || this) : fn,
- events = this._events || (this._events = {}),
- listeners = events[type] || (events[type] = []);
- listeners.push(bound);
- return function(){
- // unsubscribe
- for (var i = 0, l = listeners.length; i < l; i++){
- if (listeners[i] === bound){
- listeners.splice(i, 1);
- break;
- }
- }
- }
- }
- },
-
// rendering
renderTo: function(context, xx, yx, xy, yy, x, y){
diff --git a/src/modes/canvas/surface.js b/src/modes/canvas/surface.js
index 0e86508..28515d4 100644
--- a/src/modes/canvas/surface.js
+++ b/src/modes/canvas/surface.js
@@ -1,6 +1,6 @@
var Class = require('../../core/class');
-var Container = require('../../core/container');
-var Element = require('../../dom/element');
+var Container = require('../../dom/container');
+var Element = require('../../dom/native');
var fps = 1000 / 60, invalids = [], renderTimer, renderInvalids = function(){
clearTimeout(renderTimer);
@@ -21,7 +21,6 @@ var CanvasSurface = Class(Element, Container, {
initialize: function(width, height){
var element = this.element = document.createElement('canvas');
var context = this.context = element.getContext('2d');
- this.children = [];
this._valid = true;
if (width != null && height != null) this.resize(width, height);
@@ -78,7 +77,7 @@ var CanvasSurface = Class(Element, Container, {
hitTooltip = hit._tooltip;
if (hitCursor) break;
}
- hit = hit.container;
+ hit = hit.parentNode;
}
// TODO: No way to set cursor/title on the surface
this.element.style.cursor = hitCursor;
@@ -94,10 +93,6 @@ var CanvasSurface = Class(Element, Container, {
return this;
},
- toElement: function(){
- return this.element;
- },
-
invalidate: function(left, top, width, height){
if (this._valid){
this._valid = false;
@@ -111,24 +106,31 @@ var CanvasSurface = Class(Element, Container, {
}
}
}
+ return this;
},
hitTest: function(x, y){
if (x < 0 || y < 0 || x > this.width || y > this.height) return null;
- var children = this.children, i = children.length;
- while (i--){
- var hit = children[i].hitTest(x, y);
+ var i = 0;
+ var node = this.lastChild;
+ while (node){
+ var hit = node.hitTest(x, y);
if (hit) return hit;
+ node = node.previousSibling;
+ if (i++ > 100){ debugger; throw new Error('recursion'); }
}
return null;
},
render: function(){
- var children = this.children, context = this.context;
+ var node = this.firstChild, context = this.context;
context.setTransform(1, 0, 0, 1, 0, 0);
context.clearRect(0, 0, this.width, this.height);
- for (var i = 0, l = children.length; i < l; i++){
- children[i].renderTo(context, 1, 0, 0, 1, 0, 0);
+ var i = 0;
+ while (node){
+ node.renderTo(context, 1, 0, 0, 1, 0, 0);
+ node = node.nextSibling;
+ if (i++ > 100){ debugger; throw new Error('recursion'); }
}
this.refreshCursor();
}
diff --git a/src/modes/fast.js b/src/modes/fast.js
index 5654865..9c1879f 100644
--- a/src/modes/fast.js
+++ b/src/modes/fast.js
@@ -1,6 +1,6 @@
-var DOM = require('./dom');
+var VML = require('./vml');
var Canvas = require('./canvas');
-//var Flash = require('./flash/index');
+//var Flash = require('./flash');
var hasCanvas = function(){
@@ -20,7 +20,7 @@ var hasFlash = function(){
};
*/
-var MODE = hasCanvas() ? Canvas : /*hasFlash() ? ART.Flash :*/ DOM;
+var MODE = hasCanvas() ? Canvas : /*hasFlash() ? Flash :*/ VML;
exports.Surface = MODE.Surface;
exports.Path = MODE.Path;
diff --git a/src/modes/script/group.js b/src/modes/script/group.js
index 01d0996..b1b7f9e 100644
--- a/src/modes/script/group.js
+++ b/src/modes/script/group.js
@@ -1,5 +1,5 @@
var Class = require('../../core/class');
-var Container = require('../../core/container');
+var Container = require('../../dom/container');
var Node = require('./node');
module.exports = Class(Node, Container, {
@@ -8,15 +8,18 @@ module.exports = Class(Node, Container, {
initialize: function(){
this.element_initialize();
- this.children = [];
},
element_toExpression: Node.prototype.toExpression,
toExpression: function(){
var artGroup = this.artVar.property('Group'),
- grab = artGroup.construct().property('grab'),
- children = this.children.map(function(child){ return child.toExpression(); });
+ grab = artGroup.construct().property('grab');
+ var children = [], node = this.firstChild;
+ while (node){
+ children.push(node.toExpression());
+ node = node.nextSibling;
+ }
return this.element_toExpression(grab.call.apply(grab, children));
}
diff --git a/src/modes/script/node.js b/src/modes/script/node.js
index 19e52bd..5dc2d7a 100644
--- a/src/modes/script/node.js
+++ b/src/modes/script/node.js
@@ -1,8 +1,9 @@
var Class = require('../../core/class');
var Transform = require('../../core/transform');
var Modulizer = require('./modulizer');
+var Element = require('../../dom/dummy');
-module.exports = Class(Modulizer, Transform, {
+module.exports = Class(Modulizer, Transform, Element, {
initialize: function(){
this._calls = [];
@@ -36,21 +37,6 @@ module.exports = Class(Modulizer, Transform, {
return expr;
},
- // insertions
-
- inject: function(container){
- this.eject();
- if (container.children) container.children.push(this);
- this.container = container;
- return this;
- },
-
- eject: function(){
- if (this.container && this.container.children) this.container.children.erase(this);
- this.container = null;
- return this;
- },
-
// transforms
blend: function(opacity){ return this._addCall('blend', arguments); },
diff --git a/src/modes/script/surface.js b/src/modes/script/surface.js
index 7b245d7..8291dc0 100644
--- a/src/modes/script/surface.js
+++ b/src/modes/script/surface.js
@@ -1,12 +1,11 @@
var Class = require('../../core/class');
-var Container = require('../../core/container');
+var Container = require('../../dom/container');
var Modulizer = require('./modulizer');
module.exports = Class(Container, Modulizer, {
initialize: function(width, height){
this.resize(width, height);
- this.children = [];
},
resize: function(width, height){
@@ -17,9 +16,14 @@ module.exports = Class(Container, Modulizer, {
toExpression: function(){
var expr = this.artVar.property('Surface').construct(this.width, this.height);
- if (!this.children.length) return expr;
+ if (!this.firstChild) return expr;
+ var children = [], node = this.firstChild;
+ while (node){
+ children.push(node);
+ node = node.nextSibling;
+ }
var grab = expr.property('grab');
- return grab.call.apply(grab, this.children);
+ return grab.call.apply(grab, children);
},
// ignore
diff --git a/src/modes/svg/base.js b/src/modes/svg/base.js
index d003f34..34d7495 100644
--- a/src/modes/svg/base.js
+++ b/src/modes/svg/base.js
@@ -10,47 +10,33 @@ module.exports = Class(Node, {
initialize: function(tag){
this.element_initialize(tag);
+ this.brushes = {};
this.fill();
this.stroke();
},
- /* insertions */
-
- element_inject: Node.prototype.inject,
-
- inject: function(container){
- this.eject();
- this.container = container;
- this._injectBrush('fill');
- this._injectBrush('stroke');
- this.element_inject(container);
- return this;
- },
-
- element_eject: Node.prototype.eject,
-
- eject: function(){
- if (this.container){
- this.element_eject();
+ _place: function(){
+ if (this.parentNode){
+ this._injectBrush('fill');
+ this._injectBrush('stroke');
+ } else {
this._ejectBrush('fill');
this._ejectBrush('stroke');
- this.container = null;
}
return this;
},
_injectBrush: function(type){
- if (!this.container) return;
+ if (!this.parentNode) return;
var brush = type == 'fill' ? this.fillBrush : this.strokeBrush;
- if (brush) this.container.defs.appendChild(brush);
+ if (brush) this.parentNode.defs.appendChild(brush);
},
_ejectBrush: function(type){
- if (!this.container) return;
var brush = this[type + 'Brush'];
- if (brush) this.container.defs.removeChild(brush);
+ if (brush && brush.parentNode) brush.parentNode.removeChild(brush);
},
-
+
/* styles */
_createBrush: function(type, tag){
diff --git a/src/modes/svg/group.js b/src/modes/svg/group.js
index 67b5c21..db5bb1f 100644
--- a/src/modes/svg/group.js
+++ b/src/modes/svg/group.js
@@ -1,5 +1,5 @@
var Class = require('../../core/class');
-var Container = require('../../core/container');
+var Container = require('../../dom/container');
var Node = require('./node');
var DOM = require('./dom');
@@ -14,5 +14,5 @@ module.exports = Class(Node, Container, {
this.defs = DOM.createElement('defs');
this.element.appendChild(this.defs);
}
-
+
});
diff --git a/src/modes/svg/node.js b/src/modes/svg/node.js
index a6c04fe..1685339 100644
--- a/src/modes/svg/node.js
+++ b/src/modes/svg/node.js
@@ -1,6 +1,6 @@
var Class = require('../../core/class');
var Transform = require('../../core/transform');
-var Element = require('../../dom/element');
+var Element = require('../../dom/shadow');
var DOM = require('./dom');
module.exports = Class(Element, Transform, {
@@ -11,8 +11,8 @@ module.exports = Class(Element, Transform, {
element.setAttribute('id', 'e' + this.uid);
},
- /* transforms */
-
+ // transforms
+
_transform: function(){
var m = this;
this.element.setAttribute('transform', 'matrix(' + [m.xx, m.yx, m.xy, m.yy, m.x, m.y] + ')');
diff --git a/src/modes/svg/surface.js b/src/modes/svg/surface.js
index aff2405..9f8897d 100644
--- a/src/modes/svg/surface.js
+++ b/src/modes/svg/surface.js
@@ -1,6 +1,6 @@
var Class = require('../../core/class');
-var Container = require('../../core/container');
-var Element = require('../../dom/element');
+var Container = require('../../dom/container');
+var Element = require('../../dom/native');
var DOM = require('./dom');
module.exports = Class(Element, Container, {
@@ -21,10 +21,6 @@ module.exports = Class(Element, Container, {
this.width = width;
this.height = height;
return this;
- },
-
- toElement: function(){
- return this.element;
}
});
diff --git a/src/modes/svg/text.js b/src/modes/svg/text.js
index 70e031b..94ffc68 100644
--- a/src/modes/svg/text.js
+++ b/src/modes/svg/text.js
@@ -110,39 +110,33 @@ module.exports = Class(Base, {
// TODO: Unify path injection with gradients and imagefills
- base_inject: Base.prototype.inject,
+ base_place: Base.prototype._place,
- inject: function(container){
- this.base_inject(container);
- this._injectPaths();
- return this;
- },
-
- base_eject: Base.prototype.eject,
-
- eject: function(){
- if (this.container){
+ _place: function(){
+ if (this.parentNode){
+ this._injectPaths();
+ } else {
this._ejectPaths();
- this.base_eject();
- this.container = null;
}
- return this;
+ return this.base_place();
},
_injectPaths: function(){
var paths = this.pathElements;
- if (!this.container || !paths) return;
- var defs = this.container.defs;
+ if (!this.parentNode || !paths) return;
+ var defs = this.parentNode.defs;
for (var i = 0, l = paths.length; i < l; i++)
defs.appendChild(paths[i]);
},
_ejectPaths: function(){
var paths = this.pathElements;
- if (!this.container || !paths) return;
- var defs = this.container.defs;
- for (var i = 0, l = paths; i < l; i++)
- defs.removeChild(paths[i]);
+ if (!paths) return;
+ for (var i = 0, l = paths; i < l; i++){
+ var path = paths[i];
+ if (path.parentNode)
+ path.parentNode.removeChild(paths[i]);
+ }
},
_createPaths: function(path){
@@ -168,7 +162,7 @@ module.exports = Class(Base, {
_whileInDocument: function(fn, bind){
// Temporarily inject into the document
var element = this.element,
- container = this.container,
+ container = this.parentNode,
parent = element.parentNode,
sibling = element.nextSibling,
body = element.ownerDocument.body,
diff --git a/src/modes/vml/base.js b/src/modes/vml/base.js
index 00a01a7..a1277de 100644
--- a/src/modes/vml/base.js
+++ b/src/modes/vml/base.js
@@ -32,7 +32,7 @@ module.exports = Class(Node, {
/* transform */
_transform: function(){
- var container = this.container;
+ var container = this.parentNode;
// Active Transformation Matrix
var m = container ? new Transform(container._activeTransform).transform(this) : this;
diff --git a/src/modes/vml/group.js b/src/modes/vml/group.js
index 45ecdfb..12e6e02 100644
--- a/src/modes/vml/group.js
+++ b/src/modes/vml/group.js
@@ -1,6 +1,6 @@
var Class = require('../../core/class');
var Transform = require('../../core/transform');
-var Container = require('../../core/container');
+var Container = require('../../dom/container');
var Node = require('./node');
module.exports = Class(Node, Container, {
@@ -11,24 +11,8 @@ module.exports = Class(Node, Container, {
this.element_initialize('group');
this.width = width;
this.height = height;
- this.children = [];
- },
-
- element_inject: Node.prototype.inject,
-
- inject: function(container){
- this.element_inject(container);
- this._transform();
- return this;
},
- element_eject: Node.prototype.eject,
-
- eject: function(){
- this.element_eject();
- return this;
- },
-
_transform: function(){
var element = this.element;
element.coordorigin = '0,0';
@@ -39,11 +23,13 @@ module.exports = Class(Node, Container, {
element.style.height = 1000;
element.style.rotation = 0;
- var container = this.container;
+ var container = this.parentNode;
this._activeTransform = container ? new Transform(container._activeTransform).transform(this) : this;
- var children = this.children;
- for (var i = 0, l = children.length; i < l; i++)
- children[i]._transform();
+ var node = this.firstChild;
+ while (node){
+ node._transform();
+ node = node.nextSibling;
+ }
}
});
\ No newline at end of file
diff --git a/src/modes/vml/node.js b/src/modes/vml/node.js
index 01ab01c..c782c8a 100644
--- a/src/modes/vml/node.js
+++ b/src/modes/vml/node.js
@@ -1,6 +1,6 @@
var Class = require('../../core/class');
var Transform = require('../../core/transform');
-var Element = require('../../dom/element');
+var Element = require('../../dom/shadow');
var DOM = require('./dom');
module.exports = Class(Element, Transform, {
@@ -10,36 +10,17 @@ module.exports = Class(Element, Transform, {
var element = this.element = DOM.createElement(tag);
//element.setAttribute('id', 'e' + this.uid);
},
-
- /* dom */
-
- art_element_inject: Element.prototype.inject,
-
- inject: function(container){
- this.eject();
- this.container = container;
- container.children.push(this);
- this._transform();
- this.art_element_inject(container);
-
- return this;
- },
- art_element_eject: Element.prototype.eject,
-
- eject: function(){
- if (this.container){
- var siblings = this.container.children,
- i = siblings.length;
- while (i--)
- if (siblings[i] === this)
- siblings.splice(i, 1);
- this.container = null;
- this.art_element_eject();
+ _place: function(){
+ if (this.parentNode){
+ console.log('transforming');
+ this._transform();
+ var t = this._activeTransform;
+ if (t)
+ console.log([t.xx, t.xy, t.x].join(', '));
}
- return this;
},
-
+
// visibility
hide: function(){
diff --git a/src/modes/vml/surface.js b/src/modes/vml/surface.js
index 84eeb56..f8828d8 100644
--- a/src/modes/vml/surface.js
+++ b/src/modes/vml/surface.js
@@ -1,6 +1,6 @@
var Class = require('../../core/class');
-var Container = require('../../core/container');
-var Element = require('../../dom/element');
+var Container = require('../../dom/container');
+var Element = require('../../dom/native');
var DOM = require('./dom');
var precision = 100;
@@ -8,47 +8,30 @@ var precision = 100;
module.exports = Class(Element, Container, {
initialize: function VMLSurface(width, height){
- this.vml = document.createElement('vml');
- this.element = DOM.createElement('group');
- this.vml.appendChild(this.element);
- this.children = [];
+ this.element = document.createElement('vml');
+ this.containerElement = DOM.createElement('group');
+ this.element.appendChild(this.containerElement);
if (width != null && height != null) this.resize(width, height);
},
- eject: function(){
- var element = this.vml, parent = element.parentNode;
- if (parent) parent.removeChild(element);
- return this;
- },
-
- inject: function(element){
- if (element.element) element = element.element;
- element.appendChild(this.vml);
- return this;
- },
-
resize: function(width, height){
this.width = width;
this.height = height;
- var style = this.vml.style;
+ var style = this.element.style;
style.pixelWidth = width;
style.pixelHeight = height;
- style = this.element.style;
+ style = this.containerElement.style;
style.width = width;
style.height = height;
var halfPixel = (0.5 * precision);
- this.element.coordorigin = halfPixel + ',' + halfPixel;
- this.element.coordsize = (width * precision) + ',' + (height * precision);
+ this.containerElement.coordorigin = halfPixel + ',' + halfPixel;
+ this.containerElement.coordsize = (width * precision) + ',' + (height * precision);
return this;
- },
-
- toElement: function(){
- return this.vml;
}
});