completed the xml tests - and lots of them run successfully
This commit is contained in:
		
							parent
							
								
									f9542b90db
								
							
						
					
					
						commit
						f932f560bd
					
				
										
											
												File diff suppressed because one or more lines are too long
											
										
									
								
							
										
											
												File diff suppressed because one or more lines are too long
											
										
									
								
							@ -433,7 +433,8 @@ module.exports = function() {
 | 
				
			|||||||
          position: this.getPosition(),
 | 
					          position: this.getPosition(),
 | 
				
			||||||
          object: this.parent.getCustomType(),
 | 
					          object: this.parent.getCustomType(),
 | 
				
			||||||
          length: 1,
 | 
					          length: 1,
 | 
				
			||||||
          changedBy: o.uid.creator
 | 
					          changedBy: o.uid.creator,
 | 
				
			||||||
 | 
					          oldValue: this.val()
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
      ]);
 | 
					      ]);
 | 
				
			||||||
    };
 | 
					    };
 | 
				
			||||||
 | 
				
			|||||||
@ -1,50 +1,11 @@
 | 
				
			|||||||
var dont_proxy, json_types_uninitialized, proxy_token, _proxy,
 | 
					var json_types_uninitialized,
 | 
				
			||||||
  __extends = function(child, parent) { for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; },
 | 
					  __extends = function(child, parent) { for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; },
 | 
				
			||||||
  __hasProp = {}.hasOwnProperty;
 | 
					  __hasProp = {}.hasOwnProperty;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
json_types_uninitialized = require("./JsonTypes");
 | 
					json_types_uninitialized = require("./JsonTypes");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
proxy_token = false;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
dont_proxy = function(f) {
 | 
					 | 
				
			||||||
  var e;
 | 
					 | 
				
			||||||
  proxy_token = true;
 | 
					 | 
				
			||||||
  try {
 | 
					 | 
				
			||||||
    f();
 | 
					 | 
				
			||||||
  } catch (_error) {
 | 
					 | 
				
			||||||
    e = _error;
 | 
					 | 
				
			||||||
    proxy_token = false;
 | 
					 | 
				
			||||||
    throw new Error(e);
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
  return proxy_token = false;
 | 
					 | 
				
			||||||
};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
_proxy = function(f_name, f) {
 | 
					 | 
				
			||||||
  var old_f;
 | 
					 | 
				
			||||||
  old_f = this[f_name];
 | 
					 | 
				
			||||||
  if (old_f != null) {
 | 
					 | 
				
			||||||
    return this[f_name] = function() {
 | 
					 | 
				
			||||||
      var args, that, _ref;
 | 
					 | 
				
			||||||
      if (!proxy_token && !((_ref = this._y) != null ? _ref.isDeleted() : void 0)) {
 | 
					 | 
				
			||||||
        that = this;
 | 
					 | 
				
			||||||
        args = arguments;
 | 
					 | 
				
			||||||
        return dont_proxy(function() {
 | 
					 | 
				
			||||||
          f.apply(that, args);
 | 
					 | 
				
			||||||
          return old_f.apply(that, args);
 | 
					 | 
				
			||||||
        });
 | 
					 | 
				
			||||||
      } else {
 | 
					 | 
				
			||||||
        return old_f.apply(this, arguments);
 | 
					 | 
				
			||||||
      }
 | 
					 | 
				
			||||||
    };
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
if (typeof Element !== "undefined" && Element !== null) {
 | 
					 | 
				
			||||||
  Element.prototype._proxy = _proxy;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
module.exports = function(HB) {
 | 
					module.exports = function(HB) {
 | 
				
			||||||
  var TextNodeType, XmlType, json_types, parser, types;
 | 
					  var XmlType, json_types, parser, types;
 | 
				
			||||||
  json_types = json_types_uninitialized(HB);
 | 
					  json_types = json_types_uninitialized(HB);
 | 
				
			||||||
  types = json_types.types;
 | 
					  types = json_types.types;
 | 
				
			||||||
  parser = json_types.parser;
 | 
					  parser = json_types.parser;
 | 
				
			||||||
@ -52,234 +13,11 @@ module.exports = function(HB) {
 | 
				
			|||||||
    __extends(XmlType, _super);
 | 
					    __extends(XmlType, _super);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    function XmlType(uid, _at_tagname, attributes, elements, _at_xml) {
 | 
					    function XmlType(uid, _at_tagname, attributes, elements, _at_xml) {
 | 
				
			||||||
      var attr, d, element, i, n, word, _i, _j, _len, _ref, _ref1, _ref2;
 | 
					 | 
				
			||||||
      this.tagname = _at_tagname;
 | 
					      this.tagname = _at_tagname;
 | 
				
			||||||
      this.xml = _at_xml;
 | 
					      this.xml = _at_xml;
 | 
				
			||||||
 | 
					 | 
				
			||||||
      /* In case you make this instanceof Insert again
 | 
					 | 
				
			||||||
      if prev? and (not next?) and prev.type?
 | 
					 | 
				
			||||||
         * adjust what you actually mean. you want to insert after prev, then
 | 
					 | 
				
			||||||
         * next is not defined. but we only insert after non-deleted elements.
 | 
					 | 
				
			||||||
         * This is also handled in TextInsert.
 | 
					 | 
				
			||||||
        while prev.isDeleted()
 | 
					 | 
				
			||||||
          prev = prev.prev_cl
 | 
					 | 
				
			||||||
        next = prev.next_cl
 | 
					 | 
				
			||||||
       */
 | 
					 | 
				
			||||||
      XmlType.__super__.constructor.call(this, uid);
 | 
					 | 
				
			||||||
      if (((_ref = this.xml) != null ? _ref._y : void 0) != null) {
 | 
					 | 
				
			||||||
        d = new types.Delete(void 0, this.xml._y);
 | 
					 | 
				
			||||||
        HB.addOperation(d).execute();
 | 
					 | 
				
			||||||
        this.xml._y = null;
 | 
					 | 
				
			||||||
      }
 | 
					 | 
				
			||||||
      if ((attributes != null) && (elements != null)) {
 | 
					 | 
				
			||||||
        this.saveOperation('attributes', attributes);
 | 
					 | 
				
			||||||
        this.saveOperation('elements', elements);
 | 
					 | 
				
			||||||
      } else if ((attributes == null) && (elements == null)) {
 | 
					 | 
				
			||||||
        this.attributes = new types.JsonType();
 | 
					 | 
				
			||||||
        this.attributes.setMutableDefault('immutable');
 | 
					 | 
				
			||||||
        HB.addOperation(this.attributes).execute();
 | 
					 | 
				
			||||||
        this.elements = new types.WordType();
 | 
					 | 
				
			||||||
        this.elements.parent = this;
 | 
					 | 
				
			||||||
        HB.addOperation(this.elements).execute();
 | 
					 | 
				
			||||||
      } else {
 | 
					 | 
				
			||||||
        throw new Error("Either define attribute and elements both, or none of them");
 | 
					 | 
				
			||||||
      }
 | 
					 | 
				
			||||||
      if (this.xml != null) {
 | 
					 | 
				
			||||||
        this.tagname = this.xml.tagName;
 | 
					 | 
				
			||||||
        for (i = _i = 0, _ref1 = this.xml.attributes.length; 0 <= _ref1 ? _i < _ref1 : _i > _ref1; i = 0 <= _ref1 ? ++_i : --_i) {
 | 
					 | 
				
			||||||
          attr = xml.attributes[i];
 | 
					 | 
				
			||||||
          this.attributes.val(attr.name, attr.value);
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
        _ref2 = this.xml.childNodes;
 | 
					 | 
				
			||||||
        for (_j = 0, _len = _ref2.length; _j < _len; _j++) {
 | 
					 | 
				
			||||||
          n = _ref2[_j];
 | 
					 | 
				
			||||||
          if (n.nodeType === n.TEXT_NODE) {
 | 
					 | 
				
			||||||
            word = new TextNodeType(void 0, n);
 | 
					 | 
				
			||||||
            HB.addOperation(word).execute();
 | 
					 | 
				
			||||||
            this.elements.push(word);
 | 
					 | 
				
			||||||
          } else if (n.nodeType === n.ELEMENT_NODE) {
 | 
					 | 
				
			||||||
            element = new XmlType(void 0, void 0, void 0, void 0, n);
 | 
					 | 
				
			||||||
            HB.addOperation(element).execute();
 | 
					 | 
				
			||||||
            this.elements.push(element);
 | 
					 | 
				
			||||||
          } else {
 | 
					 | 
				
			||||||
            throw new Error("I don't know Node-type " + n.nodeType + "!!");
 | 
					 | 
				
			||||||
          }
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
        this.setXmlProxy();
 | 
					 | 
				
			||||||
      }
 | 
					 | 
				
			||||||
      void 0;
 | 
					 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    XmlType.prototype.type = "XmlType";
 | 
					    XmlType.prototype.setXmlProxy = function() {};
 | 
				
			||||||
 | 
					 | 
				
			||||||
    XmlType.prototype.applyDelete = function(op) {
 | 
					 | 
				
			||||||
      if ((this.insert_parent != null) && !this.insert_parent.isDeleted()) {
 | 
					 | 
				
			||||||
        return this.insert_parent.applyDelete(op);
 | 
					 | 
				
			||||||
      } else {
 | 
					 | 
				
			||||||
        this.attributes.applyDelete();
 | 
					 | 
				
			||||||
        this.elements.applyDelete();
 | 
					 | 
				
			||||||
        return XmlType.__super__.applyDelete.apply(this, arguments);
 | 
					 | 
				
			||||||
      }
 | 
					 | 
				
			||||||
    };
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    XmlType.prototype.cleanup = function() {
 | 
					 | 
				
			||||||
      return XmlType.__super__.cleanup.call(this);
 | 
					 | 
				
			||||||
    };
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    XmlType.prototype.setXmlProxy = function() {
 | 
					 | 
				
			||||||
      var findNode, insertBefore, removeChild, renewClassList, that;
 | 
					 | 
				
			||||||
      this.xml._y = this;
 | 
					 | 
				
			||||||
      that = this;
 | 
					 | 
				
			||||||
      this.elements.on('insert', function(event, op) {
 | 
					 | 
				
			||||||
        var newNode, right, rightNode;
 | 
					 | 
				
			||||||
        if (op.creator !== HB.getUserId() && this === that.elements) {
 | 
					 | 
				
			||||||
          newNode = op.content.val();
 | 
					 | 
				
			||||||
          right = op.next_cl;
 | 
					 | 
				
			||||||
          while ((right != null) && right.isDeleted()) {
 | 
					 | 
				
			||||||
            right = right.next_cl;
 | 
					 | 
				
			||||||
          }
 | 
					 | 
				
			||||||
          rightNode = null;
 | 
					 | 
				
			||||||
          if (right.type !== 'Delimiter') {
 | 
					 | 
				
			||||||
            rightNode = right.val().val();
 | 
					 | 
				
			||||||
          }
 | 
					 | 
				
			||||||
          return dont_proxy(function() {
 | 
					 | 
				
			||||||
            return that.xml.insertBefore(newNode, rightNode);
 | 
					 | 
				
			||||||
          });
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
      });
 | 
					 | 
				
			||||||
      this.elements.on('delete', function(event, op) {
 | 
					 | 
				
			||||||
        var del_op, deleted;
 | 
					 | 
				
			||||||
        del_op = op.deleted_by[0];
 | 
					 | 
				
			||||||
        if ((del_op != null) && del_op.creator !== HB.getUserId() && this === that.elements) {
 | 
					 | 
				
			||||||
          deleted = op.content.val();
 | 
					 | 
				
			||||||
          return dont_proxy(function() {
 | 
					 | 
				
			||||||
            return that.xml.removeChild(deleted);
 | 
					 | 
				
			||||||
          });
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
      });
 | 
					 | 
				
			||||||
      this.attributes.on(['add', 'update'], function(event, property_name, op) {
 | 
					 | 
				
			||||||
        if (op.creator !== HB.getUserId() && this === that.attributes) {
 | 
					 | 
				
			||||||
          return dont_proxy(function() {
 | 
					 | 
				
			||||||
            var newval;
 | 
					 | 
				
			||||||
            newval = op.val().val();
 | 
					 | 
				
			||||||
            if (newval != null) {
 | 
					 | 
				
			||||||
              return that.xml.setAttribute(property_name, op.val().val());
 | 
					 | 
				
			||||||
            } else {
 | 
					 | 
				
			||||||
              return that.xml.removeAttribute(property_name);
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
          });
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
      });
 | 
					 | 
				
			||||||
      findNode = function(child) {
 | 
					 | 
				
			||||||
        var elem;
 | 
					 | 
				
			||||||
        if (child == null) {
 | 
					 | 
				
			||||||
          throw new Error("you must specify a parameter!");
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
        child = child._y;
 | 
					 | 
				
			||||||
        elem = that.elements.beginning.next_cl;
 | 
					 | 
				
			||||||
        while (elem.type !== 'Delimiter' && elem.content !== child) {
 | 
					 | 
				
			||||||
          elem = elem.next_cl;
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
        if (elem.type === 'Delimiter') {
 | 
					 | 
				
			||||||
          return false;
 | 
					 | 
				
			||||||
        } else {
 | 
					 | 
				
			||||||
          return elem;
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
      };
 | 
					 | 
				
			||||||
      insertBefore = function(insertedNode_s, adjacentNode) {
 | 
					 | 
				
			||||||
        var child, element, inserted_nodes, next, prev, _results;
 | 
					 | 
				
			||||||
        next = null;
 | 
					 | 
				
			||||||
        if (adjacentNode != null) {
 | 
					 | 
				
			||||||
          next = findNode(adjacentNode);
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
        prev = null;
 | 
					 | 
				
			||||||
        if (next) {
 | 
					 | 
				
			||||||
          prev = next.prev_cl;
 | 
					 | 
				
			||||||
        } else {
 | 
					 | 
				
			||||||
          prev = this._y.elements.end.prev_cl;
 | 
					 | 
				
			||||||
          while (prev.isDeleted()) {
 | 
					 | 
				
			||||||
            prev = prev.prev_cl;
 | 
					 | 
				
			||||||
          }
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
        inserted_nodes = null;
 | 
					 | 
				
			||||||
        if (insertedNode_s.nodeType === insertedNode_s.DOCUMENT_FRAGMENT_NODE) {
 | 
					 | 
				
			||||||
          child = insertedNode_s.lastChild;
 | 
					 | 
				
			||||||
          _results = [];
 | 
					 | 
				
			||||||
          while (child != null) {
 | 
					 | 
				
			||||||
            element = new XmlType(void 0, void 0, void 0, void 0, child);
 | 
					 | 
				
			||||||
            HB.addOperation(element).execute();
 | 
					 | 
				
			||||||
            that.elements.insertAfter(prev, element);
 | 
					 | 
				
			||||||
            _results.push(child = child.previousSibling);
 | 
					 | 
				
			||||||
          }
 | 
					 | 
				
			||||||
          return _results;
 | 
					 | 
				
			||||||
        } else {
 | 
					 | 
				
			||||||
          element = new XmlType(void 0, void 0, void 0, void 0, insertedNode_s);
 | 
					 | 
				
			||||||
          HB.addOperation(element).execute();
 | 
					 | 
				
			||||||
          return that.elements.insertAfter(prev, element);
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
      };
 | 
					 | 
				
			||||||
      this.xml._proxy('insertBefore', insertBefore);
 | 
					 | 
				
			||||||
      this.xml._proxy('appendChild', insertBefore);
 | 
					 | 
				
			||||||
      this.xml._proxy('removeAttribute', function(name) {
 | 
					 | 
				
			||||||
        return that.attributes.val(name, void 0);
 | 
					 | 
				
			||||||
      });
 | 
					 | 
				
			||||||
      this.xml._proxy('setAttribute', function(name, value) {
 | 
					 | 
				
			||||||
        return that.attributes.val(name, value);
 | 
					 | 
				
			||||||
      });
 | 
					 | 
				
			||||||
      renewClassList = function(newclass) {
 | 
					 | 
				
			||||||
        var dont_do_it, elem, value, _i, _len;
 | 
					 | 
				
			||||||
        dont_do_it = false;
 | 
					 | 
				
			||||||
        if (newclass != null) {
 | 
					 | 
				
			||||||
          for (_i = 0, _len = this.length; _i < _len; _i++) {
 | 
					 | 
				
			||||||
            elem = this[_i];
 | 
					 | 
				
			||||||
            if (newclass === elem) {
 | 
					 | 
				
			||||||
              dont_do_it = true;
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
          }
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
        value = Array.prototype.join.call(this, " ");
 | 
					 | 
				
			||||||
        if ((newclass != null) && !dont_do_it) {
 | 
					 | 
				
			||||||
          value += " " + newclass;
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
        return that.attributes.val('class', value);
 | 
					 | 
				
			||||||
      };
 | 
					 | 
				
			||||||
      _proxy.call(this.xml.classList, 'add', renewClassList);
 | 
					 | 
				
			||||||
      _proxy.call(this.xml.classList, 'remove', renewClassList);
 | 
					 | 
				
			||||||
      this.xml.__defineSetter__('className', function(val) {
 | 
					 | 
				
			||||||
        return this.setAttribute('class', val);
 | 
					 | 
				
			||||||
      });
 | 
					 | 
				
			||||||
      this.xml.__defineGetter__('className', function() {
 | 
					 | 
				
			||||||
        return that.attributes.val('class');
 | 
					 | 
				
			||||||
      });
 | 
					 | 
				
			||||||
      this.xml.__defineSetter__('textContent', function(val) {
 | 
					 | 
				
			||||||
        var elem, remove, text_node;
 | 
					 | 
				
			||||||
        elem = that.xml.firstChild;
 | 
					 | 
				
			||||||
        while (elem != null) {
 | 
					 | 
				
			||||||
          remove = elem;
 | 
					 | 
				
			||||||
          elem = elem.nextSibling;
 | 
					 | 
				
			||||||
          that.xml.removeChild(remove);
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
        if (val !== "") {
 | 
					 | 
				
			||||||
          text_node = document.createTextNode(val);
 | 
					 | 
				
			||||||
          return that.xml.appendChild(text_node);
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
      });
 | 
					 | 
				
			||||||
      removeChild = function(node) {
 | 
					 | 
				
			||||||
        var d, elem;
 | 
					 | 
				
			||||||
        elem = findNode(node);
 | 
					 | 
				
			||||||
        if (!elem) {
 | 
					 | 
				
			||||||
          throw new Error("You are only allowed to delete existing (direct) child elements!");
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
        d = new types.Delete(void 0, elem);
 | 
					 | 
				
			||||||
        HB.addOperation(d).execute();
 | 
					 | 
				
			||||||
        return node._y = null;
 | 
					 | 
				
			||||||
      };
 | 
					 | 
				
			||||||
      this.xml._proxy('removeChild', removeChild);
 | 
					 | 
				
			||||||
      return this.xml._proxy('replaceChild', function(insertedNode, replacedNode) {
 | 
					 | 
				
			||||||
        insertBefore.call(this, insertedNode, replacedNode);
 | 
					 | 
				
			||||||
        return removeChild.call(this, replacedNode);
 | 
					 | 
				
			||||||
      });
 | 
					 | 
				
			||||||
    };
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
    XmlType.prototype.val = function(enforce) {
 | 
					    XmlType.prototype.val = function(enforce) {
 | 
				
			||||||
      var a, attr, attr_name, e, n, text_node, value;
 | 
					      var a, attr, attr_name, e, n, text_node, value;
 | 
				
			||||||
@ -351,54 +89,9 @@ module.exports = function(HB) {
 | 
				
			|||||||
    return XmlType;
 | 
					    return XmlType;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  })(types.Insert);
 | 
					  })(types.Insert);
 | 
				
			||||||
  parser['XmlType'] = function(json) {
 | 
					  return parser['XmlType'] = function(json) {
 | 
				
			||||||
    var attributes, elements, tagname, uid;
 | 
					    var attributes, elements, tagname, uid;
 | 
				
			||||||
    uid = json['uid'], attributes = json['attributes'], elements = json['elements'], tagname = json['tagname'];
 | 
					    uid = json['uid'], attributes = json['attributes'], elements = json['elements'], tagname = json['tagname'];
 | 
				
			||||||
    return new XmlType(uid, tagname, attributes, elements, void 0);
 | 
					    return new XmlType(uid, tagname, attributes, elements, void 0);
 | 
				
			||||||
  };
 | 
					  };
 | 
				
			||||||
  TextNodeType = (function(_super) {
 | 
					 | 
				
			||||||
    __extends(TextNodeType, _super);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    function TextNodeType(uid, content) {
 | 
					 | 
				
			||||||
      var d;
 | 
					 | 
				
			||||||
      if (content._y != null) {
 | 
					 | 
				
			||||||
        d = new types.Delete(void 0, content._y);
 | 
					 | 
				
			||||||
        HB.addOperation(d).execute();
 | 
					 | 
				
			||||||
        content._y = null;
 | 
					 | 
				
			||||||
      }
 | 
					 | 
				
			||||||
      content._y = this;
 | 
					 | 
				
			||||||
      TextNodeType.__super__.constructor.call(this, uid, content);
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    TextNodeType.prototype.applyDelete = function(op) {
 | 
					 | 
				
			||||||
      if ((this.insert_parent != null) && !this.insert_parent.isDeleted()) {
 | 
					 | 
				
			||||||
        return this.insert_parent.applyDelete(op);
 | 
					 | 
				
			||||||
      } else {
 | 
					 | 
				
			||||||
        return TextNodeType.__super__.applyDelete.apply(this, arguments);
 | 
					 | 
				
			||||||
      }
 | 
					 | 
				
			||||||
    };
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    TextNodeType.prototype.type = "TextNodeType";
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    TextNodeType.prototype._encode = function() {
 | 
					 | 
				
			||||||
      var json;
 | 
					 | 
				
			||||||
      json = {
 | 
					 | 
				
			||||||
        'type': this.type,
 | 
					 | 
				
			||||||
        'uid': this.getUid(),
 | 
					 | 
				
			||||||
        'content': this.content.textContent
 | 
					 | 
				
			||||||
      };
 | 
					 | 
				
			||||||
      return json;
 | 
					 | 
				
			||||||
    };
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    return TextNodeType;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  })(types.ImmutableObject);
 | 
					 | 
				
			||||||
  parser['TextNodeType'] = function(json) {
 | 
					 | 
				
			||||||
    var content, textnode, uid;
 | 
					 | 
				
			||||||
    uid = json['uid'], content = json['content'];
 | 
					 | 
				
			||||||
    textnode = document.createTextNode(content);
 | 
					 | 
				
			||||||
    return new TextNodeType(uid, textnode);
 | 
					 | 
				
			||||||
  };
 | 
					 | 
				
			||||||
  types['XmlType'] = XmlType;
 | 
					 | 
				
			||||||
  return json_types;
 | 
					 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
				
			|||||||
@ -1,12 +1,17 @@
 | 
				
			|||||||
var YXml;
 | 
					var YXml, dont_proxy, initialize_proxies, proxies_are_initialized, proxy_token;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
YXml = (function() {
 | 
					YXml = (function() {
 | 
				
			||||||
  function YXml(tagname, attributes) {
 | 
					  function YXml(tag_or_dom, attributes) {
 | 
				
			||||||
    var a, a_name, c, c_name, _classes, _i, _len, _ref;
 | 
					    var a, a_name, c, c_name, tagname, _classes, _i, _len, _ref;
 | 
				
			||||||
    if (attributes == null) {
 | 
					    if (attributes == null) {
 | 
				
			||||||
      attributes = {};
 | 
					      attributes = {};
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					    if (tag_or_dom == null) {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    } else if (tag_or_dom.constructor === String) {
 | 
				
			||||||
 | 
					      tagname = tag_or_dom;
 | 
				
			||||||
      this._xml = {};
 | 
					      this._xml = {};
 | 
				
			||||||
 | 
					      this._xml.children = [];
 | 
				
			||||||
      this._xml.tagname = tagname;
 | 
					      this._xml.tagname = tagname;
 | 
				
			||||||
      if (attributes.constructor !== Object) {
 | 
					      if (attributes.constructor !== Object) {
 | 
				
			||||||
        throw new Error("The attributes must be specified as a Object");
 | 
					        throw new Error("The attributes must be specified as a Object");
 | 
				
			||||||
@ -31,48 +36,96 @@ YXml = (function() {
 | 
				
			|||||||
        }
 | 
					        }
 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
      void 0;
 | 
					      void 0;
 | 
				
			||||||
 | 
					    } else if (tag_or_dom instanceof Element) {
 | 
				
			||||||
 | 
					      this._dom = tag_or_dom;
 | 
				
			||||||
 | 
					      this._xml = {};
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  YXml.prototype._name = "Xml";
 | 
					  YXml.prototype._name = "Xml";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  YXml.prototype._getModel = function(Y, ops) {
 | 
					  YXml.prototype._getModel = function(Y, ops) {
 | 
				
			||||||
 | 
					    var attribute, c, child, _i, _j, _k, _len, _len1, _len2, _ref, _ref1, _ref2;
 | 
				
			||||||
    if (this._model == null) {
 | 
					    if (this._model == null) {
 | 
				
			||||||
 | 
					      if (this._dom != null) {
 | 
				
			||||||
 | 
					        this._xml.tagname = this._dom.tagName.toLowerCase();
 | 
				
			||||||
 | 
					        this._xml.attributes = {};
 | 
				
			||||||
 | 
					        this._xml.classes = {};
 | 
				
			||||||
 | 
					        _ref = this._dom.attributes;
 | 
				
			||||||
 | 
					        for (_i = 0, _len = _ref.length; _i < _len; _i++) {
 | 
				
			||||||
 | 
					          attribute = _ref[_i];
 | 
				
			||||||
 | 
					          if (attribute.name === "class") {
 | 
				
			||||||
 | 
					            _ref1 = attribute.value.split(" ");
 | 
				
			||||||
 | 
					            for (_j = 0, _len1 = _ref1.length; _j < _len1; _j++) {
 | 
				
			||||||
 | 
					              c = _ref1[_j];
 | 
				
			||||||
 | 
					              this._xml.classes[c] = true;
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					          } else {
 | 
				
			||||||
 | 
					            this._xml.attributes[attribute.name] = attribute.value;
 | 
				
			||||||
 | 
					          }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        this._xml.children = [];
 | 
				
			||||||
 | 
					        _ref2 = this._dom.childNodes;
 | 
				
			||||||
 | 
					        for (_k = 0, _len2 = _ref2.length; _k < _len2; _k++) {
 | 
				
			||||||
 | 
					          child = _ref2[_k];
 | 
				
			||||||
 | 
					          if (child.nodeType === child.TEXT_NODE) {
 | 
				
			||||||
 | 
					            this._xml.children.push(child.textContent);
 | 
				
			||||||
 | 
					          } else {
 | 
				
			||||||
 | 
					            this._xml.children.push(new YXml(child));
 | 
				
			||||||
 | 
					          }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
      this._model = new ops.MapManager(this).execute();
 | 
					      this._model = new ops.MapManager(this).execute();
 | 
				
			||||||
      this._model.val("attributes", new Y.Object(this._xml.attributes));
 | 
					      this._model.val("attributes", new Y.Object(this._xml.attributes));
 | 
				
			||||||
      this._model.val("classes", new Y.Object(this._xml.classes));
 | 
					      this._model.val("classes", new Y.Object(this._xml.classes));
 | 
				
			||||||
      this._model.val("tagname", this._xml.tagname);
 | 
					      this._model.val("tagname", this._xml.tagname);
 | 
				
			||||||
      this._model.val("children", new Y.List());
 | 
					      this._model.val("children", new Y.List(this._xml.children));
 | 
				
			||||||
      if (this._xml.parent != null) {
 | 
					      if (this._xml.parent != null) {
 | 
				
			||||||
        this._model.val("parent", this._xml.parent);
 | 
					        this._model.val("parent", this._xml.parent);
 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
 | 
					      if (this._dom != null) {
 | 
				
			||||||
 | 
					        this.getDom();
 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
      this._setModel(this._model);
 | 
					      this._setModel(this._model);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
    return this._model;
 | 
					    return this._model;
 | 
				
			||||||
  };
 | 
					  };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  YXml.prototype._setModel = function(_at__model) {
 | 
					  YXml.prototype._setModel = function(_at__model) {
 | 
				
			||||||
    this._model = _at__model;
 | 
					    this._model = _at__model;
 | 
				
			||||||
    delete this._xml;
 | 
					    this._model.observe(function(events) {
 | 
				
			||||||
    return this._model.observe(function(events) {
 | 
					      var c, children, event, i, parent, _i, _len, _ref, _results;
 | 
				
			||||||
      var c, children, event, i, parent, _i, _j, _len, _len1, _ref;
 | 
					      _results = [];
 | 
				
			||||||
      for (_i = 0, _len = events.length; _i < _len; _i++) {
 | 
					      for (_i = 0, _len = events.length; _i < _len; _i++) {
 | 
				
			||||||
        event = events[_i];
 | 
					        event = events[_i];
 | 
				
			||||||
        if (event.name === "parent" && event.type !== "add") {
 | 
					        if (event.name === "parent" && event.type !== "add") {
 | 
				
			||||||
          parent = event.oldValue;
 | 
					          parent = event.oldValue;
 | 
				
			||||||
          children = (_ref = parent._model.val("children")) != null ? _ref.val() : void 0;
 | 
					          children = (_ref = parent._model.val("children")) != null ? _ref.val() : void 0;
 | 
				
			||||||
          if (children != null) {
 | 
					          if (children != null) {
 | 
				
			||||||
 | 
					            _results.push((function() {
 | 
				
			||||||
 | 
					              var _j, _len1, _results1;
 | 
				
			||||||
 | 
					              _results1 = [];
 | 
				
			||||||
              for (i = _j = 0, _len1 = children.length; _j < _len1; i = ++_j) {
 | 
					              for (i = _j = 0, _len1 = children.length; _j < _len1; i = ++_j) {
 | 
				
			||||||
                c = children[i];
 | 
					                c = children[i];
 | 
				
			||||||
                if (c === this) {
 | 
					                if (c === this) {
 | 
				
			||||||
                  parent._model.val("children")["delete"](i);
 | 
					                  parent._model.val("children")["delete"](i);
 | 
				
			||||||
                  break;
 | 
					                  break;
 | 
				
			||||||
 | 
					                } else {
 | 
				
			||||||
 | 
					                  _results1.push(void 0);
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
              }
 | 
					              }
 | 
				
			||||||
 | 
					              return _results1;
 | 
				
			||||||
 | 
					            }).call(this));
 | 
				
			||||||
 | 
					          } else {
 | 
				
			||||||
 | 
					            _results.push(void 0);
 | 
				
			||||||
 | 
					          }
 | 
				
			||||||
 | 
					        } else {
 | 
				
			||||||
 | 
					          _results.push(void 0);
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
      }
 | 
					      return _results;
 | 
				
			||||||
      return void 0;
 | 
					 | 
				
			||||||
    });
 | 
					    });
 | 
				
			||||||
 | 
					    return delete this._xml;
 | 
				
			||||||
  };
 | 
					  };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  YXml.prototype._setParent = function(parent) {
 | 
					  YXml.prototype._setParent = function(parent) {
 | 
				
			||||||
@ -294,10 +347,225 @@ YXml = (function() {
 | 
				
			|||||||
    return this._model.val("children").val();
 | 
					    return this._model.val("children").val();
 | 
				
			||||||
  };
 | 
					  };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  YXml.prototype.getPosition = function() {
 | 
				
			||||||
 | 
					    var c, i, parent, _i, _len, _ref;
 | 
				
			||||||
 | 
					    parent = this._model.val("parent");
 | 
				
			||||||
 | 
					    if (parent != null) {
 | 
				
			||||||
 | 
					      _ref = parent._model.val("children").val();
 | 
				
			||||||
 | 
					      for (i = _i = 0, _len = _ref.length; _i < _len; i = ++_i) {
 | 
				
			||||||
 | 
					        c = _ref[i];
 | 
				
			||||||
 | 
					        if (c === this) {
 | 
				
			||||||
 | 
					          return i;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					      throw new Error("This is not a child of its parent (should not happen in Y.Xml!)");
 | 
				
			||||||
 | 
					    } else {
 | 
				
			||||||
 | 
					      return null;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					  };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  YXml.prototype.getDom = function() {
 | 
				
			||||||
 | 
					    var attr_name, attr_value, child, dom, i, that, _i, _len, _ref, _ref1;
 | 
				
			||||||
 | 
					    if (this._dom == null) {
 | 
				
			||||||
 | 
					      this._dom = document.createElement(this._model.val("tagname"));
 | 
				
			||||||
 | 
					      _ref = this.attr();
 | 
				
			||||||
 | 
					      for (attr_name in _ref) {
 | 
				
			||||||
 | 
					        attr_value = _ref[attr_name];
 | 
				
			||||||
 | 
					        this._dom.setAttribute(attr_name, attr_value);
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					      _ref1 = this.getChildren();
 | 
				
			||||||
 | 
					      for (i = _i = 0, _len = _ref1.length; _i < _len; i = ++_i) {
 | 
				
			||||||
 | 
					        child = _ref1[i];
 | 
				
			||||||
 | 
					        if (child.constructor === String) {
 | 
				
			||||||
 | 
					          dom = document.createTextNode(child);
 | 
				
			||||||
 | 
					        } else {
 | 
				
			||||||
 | 
					          dom = child.getDom();
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        this._dom.insertBefore(dom);
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    that = this;
 | 
				
			||||||
 | 
					    if (this._dom._y_xml == null) {
 | 
				
			||||||
 | 
					      this._dom._y_xml = this;
 | 
				
			||||||
 | 
					      initialize_proxies.call(this);
 | 
				
			||||||
 | 
					      this._model.val("children").observe(function(events) {
 | 
				
			||||||
 | 
					        var children, deleted, event, newNode, rightNode, _j, _len1, _results;
 | 
				
			||||||
 | 
					        _results = [];
 | 
				
			||||||
 | 
					        for (_j = 0, _len1 = events.length; _j < _len1; _j++) {
 | 
				
			||||||
 | 
					          event = events[_j];
 | 
				
			||||||
 | 
					          if (event.type === "insert") {
 | 
				
			||||||
 | 
					            newNode = event.value.getDom();
 | 
				
			||||||
 | 
					            children = that._dom.childNodes;
 | 
				
			||||||
 | 
					            if (children.length > 0) {
 | 
				
			||||||
 | 
					              rightNode = children[0];
 | 
				
			||||||
 | 
					            } else {
 | 
				
			||||||
 | 
					              rightNode = null;
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					            event.value._setParent(that);
 | 
				
			||||||
 | 
					            _results.push(dont_proxy(function() {
 | 
				
			||||||
 | 
					              return that._dom.insertBefore(newNode, rightNode);
 | 
				
			||||||
 | 
					            }));
 | 
				
			||||||
 | 
					          } else if (event.type === "delete") {
 | 
				
			||||||
 | 
					            deleted = event.oldValue.getDom();
 | 
				
			||||||
 | 
					            _results.push(dont_proxy(function() {
 | 
				
			||||||
 | 
					              return that._dom.removeChild(deleted);
 | 
				
			||||||
 | 
					            }));
 | 
				
			||||||
 | 
					          } else {
 | 
				
			||||||
 | 
					            _results.push(void 0);
 | 
				
			||||||
 | 
					          }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        return _results;
 | 
				
			||||||
 | 
					      });
 | 
				
			||||||
 | 
					      this._model.val("attributes").observe(function(events) {
 | 
				
			||||||
 | 
					        var event, newval, _j, _len1, _results;
 | 
				
			||||||
 | 
					        _results = [];
 | 
				
			||||||
 | 
					        for (_j = 0, _len1 = events.length; _j < _len1; _j++) {
 | 
				
			||||||
 | 
					          event = events[_j];
 | 
				
			||||||
 | 
					          if (event.type === "add" || event.type === "update") {
 | 
				
			||||||
 | 
					            newval = event.object.val(event.name);
 | 
				
			||||||
 | 
					            _results.push(dont_proxy(function() {
 | 
				
			||||||
 | 
					              return that._dom.setAttribute(event.name, newval);
 | 
				
			||||||
 | 
					            }));
 | 
				
			||||||
 | 
					          } else if (event.type === "delete") {
 | 
				
			||||||
 | 
					            _results.push(dont_proxy(function() {
 | 
				
			||||||
 | 
					              return that._dom.removeAttribute(event.name);
 | 
				
			||||||
 | 
					            }));
 | 
				
			||||||
 | 
					          } else {
 | 
				
			||||||
 | 
					            _results.push(void 0);
 | 
				
			||||||
 | 
					          }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        return _results;
 | 
				
			||||||
 | 
					      });
 | 
				
			||||||
 | 
					      this._model.val("classes").observe(function(events) {
 | 
				
			||||||
 | 
					        var event, _j, _len1, _results;
 | 
				
			||||||
 | 
					        _results = [];
 | 
				
			||||||
 | 
					        for (_j = 0, _len1 = events.length; _j < _len1; _j++) {
 | 
				
			||||||
 | 
					          event = events[_j];
 | 
				
			||||||
 | 
					          if (event.type === "add" || event.type === "update") {
 | 
				
			||||||
 | 
					            _results.push(dont_proxy(function() {
 | 
				
			||||||
 | 
					              return that._dom.classList.add(event.name);
 | 
				
			||||||
 | 
					            }));
 | 
				
			||||||
 | 
					          } else if (event.type === "delete") {
 | 
				
			||||||
 | 
					            _results.push(dont_proxy(function() {
 | 
				
			||||||
 | 
					              return that._dom.classList.remove(event.name);
 | 
				
			||||||
 | 
					            }));
 | 
				
			||||||
 | 
					          } else {
 | 
				
			||||||
 | 
					            _results.push(void 0);
 | 
				
			||||||
 | 
					          }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        return _results;
 | 
				
			||||||
 | 
					      });
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    return this._dom;
 | 
				
			||||||
 | 
					  };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  return YXml;
 | 
					  return YXml;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
})();
 | 
					})();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					proxies_are_initialized = false;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					proxy_token = false;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					dont_proxy = function(f) {
 | 
				
			||||||
 | 
					  var e;
 | 
				
			||||||
 | 
					  proxy_token = true;
 | 
				
			||||||
 | 
					  try {
 | 
				
			||||||
 | 
					    f();
 | 
				
			||||||
 | 
					  } catch (_error) {
 | 
				
			||||||
 | 
					    e = _error;
 | 
				
			||||||
 | 
					    proxy_token = false;
 | 
				
			||||||
 | 
					    throw new Error(e);
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					  return proxy_token = false;
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					initialize_proxies = function() {
 | 
				
			||||||
 | 
					  var insertBefore, removeChild, replaceChild, that, _proxy;
 | 
				
			||||||
 | 
					  _proxy = function(f_name, f, source) {
 | 
				
			||||||
 | 
					    var old_f;
 | 
				
			||||||
 | 
					    if (source == null) {
 | 
				
			||||||
 | 
					      source = Element.prototype;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    old_f = source[f_name];
 | 
				
			||||||
 | 
					    return source[f_name] = function() {
 | 
				
			||||||
 | 
					      if ((this._y_xml == null) || proxy_token) {
 | 
				
			||||||
 | 
					        return old_f.apply(this, arguments);
 | 
				
			||||||
 | 
					      } else {
 | 
				
			||||||
 | 
					        return f.apply(this._y_xml, arguments);
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					    };
 | 
				
			||||||
 | 
					  };
 | 
				
			||||||
 | 
					  that = this;
 | 
				
			||||||
 | 
					  this._dom.classList.add = function(c) {
 | 
				
			||||||
 | 
					    return that.addClass(c);
 | 
				
			||||||
 | 
					  };
 | 
				
			||||||
 | 
					  this._dom.classList.remove = function(c) {
 | 
				
			||||||
 | 
					    return that.removeClass(c);
 | 
				
			||||||
 | 
					  };
 | 
				
			||||||
 | 
					  this._dom.__defineSetter__('className', function(val) {
 | 
				
			||||||
 | 
					    return that.attr('class', val);
 | 
				
			||||||
 | 
					  });
 | 
				
			||||||
 | 
					  this._dom.__defineGetter__('className', function() {
 | 
				
			||||||
 | 
					    return that.attr('class');
 | 
				
			||||||
 | 
					  });
 | 
				
			||||||
 | 
					  this._dom.__defineSetter__('textContent', function(val) {
 | 
				
			||||||
 | 
					    that.empty();
 | 
				
			||||||
 | 
					    if (val !== "") {
 | 
				
			||||||
 | 
					      return that.append(val);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					  });
 | 
				
			||||||
 | 
					  if (proxies_are_initialized) {
 | 
				
			||||||
 | 
					    return;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					  proxies_are_initialized = true;
 | 
				
			||||||
 | 
					  insertBefore = function(insertedNode_s, adjacentNode) {
 | 
				
			||||||
 | 
					    var child, new_childs, pos;
 | 
				
			||||||
 | 
					    if (adjacentNode != null) {
 | 
				
			||||||
 | 
					      pos = adjacentNode._y_xml.getPosition();
 | 
				
			||||||
 | 
					    } else {
 | 
				
			||||||
 | 
					      pos = this.getChildren().length;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    new_childs = [];
 | 
				
			||||||
 | 
					    if (insertedNode_s.nodeType === insertedNode_s.DOCUMENT_FRAGMENT_NODE) {
 | 
				
			||||||
 | 
					      child = insertedNode_s.firstChild;
 | 
				
			||||||
 | 
					      while (child != null) {
 | 
				
			||||||
 | 
					        new_childs.push(child);
 | 
				
			||||||
 | 
					        child = child.nextSibling;
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					    } else {
 | 
				
			||||||
 | 
					      new_childs.push(insertedNode_s);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    new_childs = new_childs.map(function(child) {
 | 
				
			||||||
 | 
					      if (child._y_xml != null) {
 | 
				
			||||||
 | 
					        return child._y_xml;
 | 
				
			||||||
 | 
					      } else if (child.nodeType === child.TEXT_NODE) {
 | 
				
			||||||
 | 
					        return child.textContent;
 | 
				
			||||||
 | 
					      } else {
 | 
				
			||||||
 | 
					        return new YXml(child);
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					    });
 | 
				
			||||||
 | 
					    return this._model.val("children").insertContents(pos, new_childs);
 | 
				
			||||||
 | 
					  };
 | 
				
			||||||
 | 
					  _proxy('insertBefore', insertBefore);
 | 
				
			||||||
 | 
					  _proxy('appendChild', insertBefore);
 | 
				
			||||||
 | 
					  _proxy('removeAttribute', function(name) {
 | 
				
			||||||
 | 
					    return this.removeAttr(name);
 | 
				
			||||||
 | 
					  });
 | 
				
			||||||
 | 
					  _proxy('setAttribute', function(name, value) {
 | 
				
			||||||
 | 
					    return this.attr(name, value);
 | 
				
			||||||
 | 
					  });
 | 
				
			||||||
 | 
					  removeChild = function(node) {
 | 
				
			||||||
 | 
					    return node._y_xml.remove();
 | 
				
			||||||
 | 
					  };
 | 
				
			||||||
 | 
					  _proxy('removeChild', removeChild, this._dom);
 | 
				
			||||||
 | 
					  replaceChild = function(insertedNode, replacedNode) {
 | 
				
			||||||
 | 
					    insertBefore.call(this, insertedNode, replacedNode);
 | 
				
			||||||
 | 
					    return removeChild.call(this, replacedNode);
 | 
				
			||||||
 | 
					  };
 | 
				
			||||||
 | 
					  return _proxy('replaceChild', replaceChild, this._dom);
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
if (typeof window !== "undefined" && window !== null) {
 | 
					if (typeof window !== "undefined" && window !== null) {
 | 
				
			||||||
  if (window.Y != null) {
 | 
					  if (window.Y != null) {
 | 
				
			||||||
    window.Y.Xml = YXml;
 | 
					    window.Y.Xml = YXml;
 | 
				
			||||||
 | 
				
			|||||||
										
											
												File diff suppressed because one or more lines are too long
											
										
									
								
							
										
											
												File diff suppressed because one or more lines are too long
											
										
									
								
							
										
											
												File diff suppressed because one or more lines are too long
											
										
									
								
							@ -487,6 +487,7 @@ module.exports = ()->
 | 
				
			|||||||
        object: @parent.getCustomType() # TODO: You can combine getPosition + getParent in a more efficient manner! (only left Delimiter will hold @parent)
 | 
					        object: @parent.getCustomType() # TODO: You can combine getPosition + getParent in a more efficient manner! (only left Delimiter will hold @parent)
 | 
				
			||||||
        length: 1
 | 
					        length: 1
 | 
				
			||||||
        changedBy: o.uid.creator
 | 
					        changedBy: o.uid.creator
 | 
				
			||||||
 | 
					        oldValue: @val()
 | 
				
			||||||
      ]
 | 
					      ]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    #
 | 
					    #
 | 
				
			||||||
 | 
				
			|||||||
@ -1,34 +1,7 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
json_types_uninitialized = require "./JsonTypes"
 | 
					json_types_uninitialized = require "./JsonTypes"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
# some dom implementations may call another dom.method that simulates the behavior of another.
 | 
					 | 
				
			||||||
# For example xml.insertChild(dom) , wich inserts an element at the end, and xml.insertAfter(dom,null) wich does the same
 | 
					 | 
				
			||||||
# But Y's proxy may be called only once!
 | 
					 | 
				
			||||||
proxy_token = false
 | 
					 | 
				
			||||||
dont_proxy = (f)->
 | 
					 | 
				
			||||||
  proxy_token = true
 | 
					 | 
				
			||||||
  try
 | 
					 | 
				
			||||||
    f()
 | 
					 | 
				
			||||||
  catch e
 | 
					 | 
				
			||||||
    proxy_token = false
 | 
					 | 
				
			||||||
    throw new Error e
 | 
					 | 
				
			||||||
  proxy_token = false
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
_proxy = (f_name, f)->
 | 
					 | 
				
			||||||
  old_f = @[f_name]
 | 
					 | 
				
			||||||
  if old_f?
 | 
					 | 
				
			||||||
    @[f_name] = ()->
 | 
					 | 
				
			||||||
      if not proxy_token and not @_y?.isDeleted()
 | 
					 | 
				
			||||||
        that = this
 | 
					 | 
				
			||||||
        args = arguments
 | 
					 | 
				
			||||||
        dont_proxy ()->
 | 
					 | 
				
			||||||
          f.apply that, args
 | 
					 | 
				
			||||||
          old_f.apply that, args
 | 
					 | 
				
			||||||
      else
 | 
					 | 
				
			||||||
        old_f.apply this, arguments
 | 
					 | 
				
			||||||
  #else
 | 
					 | 
				
			||||||
  #  @[f_name] = f
 | 
					 | 
				
			||||||
Element?.prototype._proxy = _proxy
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
module.exports = (HB)->
 | 
					module.exports = (HB)->
 | 
				
			||||||
@ -46,202 +19,10 @@ module.exports = (HB)->
 | 
				
			|||||||
  class XmlType extends types.Insert
 | 
					  class XmlType extends types.Insert
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    constructor: (uid, @tagname, attributes, elements, @xml)->
 | 
					    constructor: (uid, @tagname, attributes, elements, @xml)->
 | 
				
			||||||
      ### In case you make this instanceof Insert again
 | 
					 | 
				
			||||||
      if prev? and (not next?) and prev.type?
 | 
					 | 
				
			||||||
        # adjust what you actually mean. you want to insert after prev, then
 | 
					 | 
				
			||||||
        # next is not defined. but we only insert after non-deleted elements.
 | 
					 | 
				
			||||||
        # This is also handled in TextInsert.
 | 
					 | 
				
			||||||
        while prev.isDeleted()
 | 
					 | 
				
			||||||
          prev = prev.prev_cl
 | 
					 | 
				
			||||||
        next = prev.next_cl
 | 
					 | 
				
			||||||
      ###
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
      super(uid)
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
      if @xml?._y?
 | 
					 | 
				
			||||||
        d = new types.Delete undefined, @xml._y
 | 
					 | 
				
			||||||
        HB.addOperation(d).execute()
 | 
					 | 
				
			||||||
        @xml._y = null
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
      if attributes? and elements?
 | 
					 | 
				
			||||||
        @saveOperation 'attributes', attributes
 | 
					 | 
				
			||||||
        @saveOperation 'elements', elements
 | 
					 | 
				
			||||||
      else if (not attributes?) and (not elements?)
 | 
					 | 
				
			||||||
        @attributes = new types.JsonType()
 | 
					 | 
				
			||||||
        @attributes.setMutableDefault 'immutable'
 | 
					 | 
				
			||||||
        HB.addOperation(@attributes).execute()
 | 
					 | 
				
			||||||
        @elements = new types.WordType()
 | 
					 | 
				
			||||||
        @elements.parent = @
 | 
					 | 
				
			||||||
        HB.addOperation(@elements).execute()
 | 
					 | 
				
			||||||
      else
 | 
					 | 
				
			||||||
        throw new Error "Either define attribute and elements both, or none of them"
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
      if @xml?
 | 
					 | 
				
			||||||
        @tagname = @xml.tagName
 | 
					 | 
				
			||||||
        for i in [0...@xml.attributes.length]
 | 
					 | 
				
			||||||
          attr = xml.attributes[i]
 | 
					 | 
				
			||||||
          @attributes.val(attr.name, attr.value)
 | 
					 | 
				
			||||||
        for n in @xml.childNodes
 | 
					 | 
				
			||||||
          if n.nodeType is n.TEXT_NODE
 | 
					 | 
				
			||||||
            word = new TextNodeType(undefined, n)
 | 
					 | 
				
			||||||
            HB.addOperation(word).execute()
 | 
					 | 
				
			||||||
            @elements.push word
 | 
					 | 
				
			||||||
          else if n.nodeType is n.ELEMENT_NODE
 | 
					 | 
				
			||||||
            element = new XmlType undefined, undefined, undefined, undefined, n
 | 
					 | 
				
			||||||
            HB.addOperation(element).execute()
 | 
					 | 
				
			||||||
            @elements.push element
 | 
					 | 
				
			||||||
          else
 | 
					 | 
				
			||||||
            throw new Error "I don't know Node-type #{n.nodeType}!!"
 | 
					 | 
				
			||||||
        @setXmlProxy()
 | 
					 | 
				
			||||||
      undefined
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    #
 | 
					 | 
				
			||||||
    # Identifies this class.
 | 
					 | 
				
			||||||
    # Use it in order to check whether this is an xml-type or something else.
 | 
					 | 
				
			||||||
    #
 | 
					 | 
				
			||||||
    type: "XmlType"
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    applyDelete: (op)->
 | 
					 | 
				
			||||||
      if @insert_parent? and not @insert_parent.isDeleted()
 | 
					 | 
				
			||||||
        @insert_parent.applyDelete op
 | 
					 | 
				
			||||||
      else
 | 
					 | 
				
			||||||
        @attributes.applyDelete()
 | 
					 | 
				
			||||||
        @elements.applyDelete()
 | 
					 | 
				
			||||||
        super
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    cleanup: ()->
 | 
					 | 
				
			||||||
      super()
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
    setXmlProxy: ()->
 | 
					    setXmlProxy: ()->
 | 
				
			||||||
      @xml._y = @
 | 
					 | 
				
			||||||
      that = @
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
      @elements.on 'insert', (event, op)->
 | 
					 | 
				
			||||||
        if op.creator isnt HB.getUserId() and this is that.elements
 | 
					 | 
				
			||||||
          newNode = op.content.val()
 | 
					 | 
				
			||||||
          right = op.next_cl
 | 
					 | 
				
			||||||
          while right? and right.isDeleted()
 | 
					 | 
				
			||||||
            right = right.next_cl
 | 
					 | 
				
			||||||
          rightNode = null
 | 
					 | 
				
			||||||
          if right.type isnt 'Delimiter'
 | 
					 | 
				
			||||||
            rightNode = right.val().val()
 | 
					 | 
				
			||||||
          dont_proxy ()->
 | 
					 | 
				
			||||||
            that.xml.insertBefore newNode, rightNode
 | 
					 | 
				
			||||||
      @elements.on 'delete', (event, op)->
 | 
					 | 
				
			||||||
        del_op = op.deleted_by[0]
 | 
					 | 
				
			||||||
        if del_op? and del_op.creator isnt HB.getUserId() and this is that.elements
 | 
					 | 
				
			||||||
          deleted = op.content.val()
 | 
					 | 
				
			||||||
          dont_proxy ()->
 | 
					 | 
				
			||||||
            that.xml.removeChild deleted
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
      @attributes.on ['add', 'update'], (event, property_name, op)->
 | 
					 | 
				
			||||||
        if op.creator isnt HB.getUserId() and this is that.attributes
 | 
					 | 
				
			||||||
          dont_proxy ()->
 | 
					 | 
				
			||||||
            newval = op.val().val()
 | 
					 | 
				
			||||||
            if newval?
 | 
					 | 
				
			||||||
              that.xml.setAttribute(property_name, op.val().val())
 | 
					 | 
				
			||||||
            else
 | 
					 | 
				
			||||||
              that.xml.removeAttribute(property_name)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
      ## Here are all methods that proxy the behavior of the xml
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
      # you want to find a specific child element. Since they are carried by an Insert-Type, you want to find that Insert-Operation.
 | 
					 | 
				
			||||||
      # @param child {DomElement} Dom element.
 | 
					 | 
				
			||||||
      # @return {InsertType} This carries the XmlType that represents the DomElement (child). false if i couldn't find it.
 | 
					 | 
				
			||||||
      #
 | 
					 | 
				
			||||||
      findNode = (child)->
 | 
					 | 
				
			||||||
        if not child?
 | 
					 | 
				
			||||||
          throw new Error "you must specify a parameter!"
 | 
					 | 
				
			||||||
        child = child._y
 | 
					 | 
				
			||||||
        elem = that.elements.beginning.next_cl
 | 
					 | 
				
			||||||
        while elem.type isnt 'Delimiter' and elem.content isnt child
 | 
					 | 
				
			||||||
          elem = elem.next_cl
 | 
					 | 
				
			||||||
        if elem.type is 'Delimiter'
 | 
					 | 
				
			||||||
          false
 | 
					 | 
				
			||||||
        else
 | 
					 | 
				
			||||||
          elem
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
      insertBefore = (insertedNode_s, adjacentNode)->
 | 
					 | 
				
			||||||
        next = null
 | 
					 | 
				
			||||||
        if adjacentNode?
 | 
					 | 
				
			||||||
          next = findNode adjacentNode
 | 
					 | 
				
			||||||
        prev = null
 | 
					 | 
				
			||||||
        if next
 | 
					 | 
				
			||||||
          prev = next.prev_cl
 | 
					 | 
				
			||||||
        else
 | 
					 | 
				
			||||||
          prev = @_y.elements.end.prev_cl
 | 
					 | 
				
			||||||
          while prev.isDeleted()
 | 
					 | 
				
			||||||
            prev = prev.prev_cl
 | 
					 | 
				
			||||||
        inserted_nodes = null
 | 
					 | 
				
			||||||
        if insertedNode_s.nodeType is insertedNode_s.DOCUMENT_FRAGMENT_NODE
 | 
					 | 
				
			||||||
          child = insertedNode_s.lastChild
 | 
					 | 
				
			||||||
          while child?
 | 
					 | 
				
			||||||
            element = new XmlType undefined, undefined, undefined, undefined, child
 | 
					 | 
				
			||||||
            HB.addOperation(element).execute()
 | 
					 | 
				
			||||||
            that.elements.insertAfter prev, element
 | 
					 | 
				
			||||||
            child = child.previousSibling
 | 
					 | 
				
			||||||
        else
 | 
					 | 
				
			||||||
          element = new XmlType undefined, undefined, undefined, undefined, insertedNode_s
 | 
					 | 
				
			||||||
          HB.addOperation(element).execute()
 | 
					 | 
				
			||||||
          that.elements.insertAfter prev, element
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
      @xml._proxy 'insertBefore', insertBefore
 | 
					 | 
				
			||||||
      @xml._proxy 'appendChild', insertBefore
 | 
					 | 
				
			||||||
      @xml._proxy 'removeAttribute', (name)->
 | 
					 | 
				
			||||||
        that.attributes.val(name, undefined)
 | 
					 | 
				
			||||||
      @xml._proxy 'setAttribute', (name, value)->
 | 
					 | 
				
			||||||
        that.attributes.val name, value
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
      renewClassList = (newclass)->
 | 
					 | 
				
			||||||
        dont_do_it = false
 | 
					 | 
				
			||||||
        if newclass?
 | 
					 | 
				
			||||||
          for elem in this
 | 
					 | 
				
			||||||
            if newclass is elem
 | 
					 | 
				
			||||||
              dont_do_it = true
 | 
					 | 
				
			||||||
        value = Array.prototype.join.call this, " "
 | 
					 | 
				
			||||||
        if newclass? and not dont_do_it
 | 
					 | 
				
			||||||
          value += " "+newclass
 | 
					 | 
				
			||||||
        that.attributes.val('class', value )
 | 
					 | 
				
			||||||
      _proxy.call @xml.classList, 'add', renewClassList
 | 
					 | 
				
			||||||
      _proxy.call @xml.classList, 'remove', renewClassList
 | 
					 | 
				
			||||||
      @xml.__defineSetter__ 'className', (val)->
 | 
					 | 
				
			||||||
        @setAttribute('class', val)
 | 
					 | 
				
			||||||
      @xml.__defineGetter__ 'className', ()->
 | 
					 | 
				
			||||||
        that.attributes.val('class')
 | 
					 | 
				
			||||||
      @xml.__defineSetter__ 'textContent', (val)->
 | 
					 | 
				
			||||||
        # remove all nodes
 | 
					 | 
				
			||||||
        elem = that.xml.firstChild
 | 
					 | 
				
			||||||
        while elem?
 | 
					 | 
				
			||||||
          remove = elem
 | 
					 | 
				
			||||||
          elem = elem.nextSibling
 | 
					 | 
				
			||||||
          that.xml.removeChild remove
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        # insert word content
 | 
					 | 
				
			||||||
        if val isnt ""
 | 
					 | 
				
			||||||
          text_node = document.createTextNode val
 | 
					 | 
				
			||||||
          that.xml.appendChild text_node
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
      removeChild = (node)->
 | 
					 | 
				
			||||||
        elem = findNode node
 | 
					 | 
				
			||||||
        if not elem
 | 
					 | 
				
			||||||
          throw new Error "You are only allowed to delete existing (direct) child elements!"
 | 
					 | 
				
			||||||
        d = new types.Delete undefined, elem
 | 
					 | 
				
			||||||
        HB.addOperation(d).execute()
 | 
					 | 
				
			||||||
        node._y = null
 | 
					 | 
				
			||||||
      @xml._proxy 'removeChild', removeChild
 | 
					 | 
				
			||||||
      @xml._proxy 'replaceChild', (insertedNode, replacedNode)->
 | 
					 | 
				
			||||||
        insertBefore.call this, insertedNode, replacedNode
 | 
					 | 
				
			||||||
        removeChild.call this, replacedNode
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
    val: (enforce = false)->
 | 
					    val: (enforce = false)->
 | 
				
			||||||
      if document?
 | 
					      if document?
 | 
				
			||||||
@ -314,53 +95,3 @@ module.exports = (HB)->
 | 
				
			|||||||
    } = json
 | 
					    } = json
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    new XmlType uid, tagname, attributes, elements, undefined
 | 
					    new XmlType uid, tagname, attributes, elements, undefined
 | 
				
			||||||
 | 
					 | 
				
			||||||
#
 | 
					 | 
				
			||||||
  # @nodoc
 | 
					 | 
				
			||||||
  # Defines an object that is cannot be changed. You can use this to set an immutable string, or a number.
 | 
					 | 
				
			||||||
  #
 | 
					 | 
				
			||||||
  class TextNodeType extends types.ImmutableObject
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    #
 | 
					 | 
				
			||||||
    # @param {Object} uid A unique identifier. If uid is undefined, a new uid will be created.
 | 
					 | 
				
			||||||
    # @param {Object} content
 | 
					 | 
				
			||||||
    #
 | 
					 | 
				
			||||||
    constructor: (uid, content)->
 | 
					 | 
				
			||||||
      if content._y?
 | 
					 | 
				
			||||||
        d = new types.Delete undefined, content._y
 | 
					 | 
				
			||||||
        HB.addOperation(d).execute()
 | 
					 | 
				
			||||||
        content._y = null
 | 
					 | 
				
			||||||
      content._y = @
 | 
					 | 
				
			||||||
      super uid, content
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    applyDelete: (op)->
 | 
					 | 
				
			||||||
      if @insert_parent? and not @insert_parent.isDeleted()
 | 
					 | 
				
			||||||
        @insert_parent.applyDelete op
 | 
					 | 
				
			||||||
      else
 | 
					 | 
				
			||||||
        super
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    type: "TextNodeType"
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    #
 | 
					 | 
				
			||||||
    # Encode this operation in such a way that it can be parsed by remote peers.
 | 
					 | 
				
			||||||
    #
 | 
					 | 
				
			||||||
    _encode: ()->
 | 
					 | 
				
			||||||
      json = {
 | 
					 | 
				
			||||||
        'type': @type
 | 
					 | 
				
			||||||
        'uid' : @getUid()
 | 
					 | 
				
			||||||
        'content' : @content.textContent
 | 
					 | 
				
			||||||
      }
 | 
					 | 
				
			||||||
      json
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  parser['TextNodeType'] = (json)->
 | 
					 | 
				
			||||||
    {
 | 
					 | 
				
			||||||
      'uid' : uid
 | 
					 | 
				
			||||||
      'content' : content
 | 
					 | 
				
			||||||
    } = json
 | 
					 | 
				
			||||||
    textnode = document.createTextNode content
 | 
					 | 
				
			||||||
    new TextNodeType uid, textnode
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  types['XmlType'] = XmlType
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  json_types
 | 
					 | 
				
			||||||
 | 
				
			|||||||
@ -1,7 +1,12 @@
 | 
				
			|||||||
class YXml
 | 
					class YXml
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  constructor: (tagname, attributes = {})->
 | 
					  constructor: (tag_or_dom, attributes = {})->
 | 
				
			||||||
 | 
					    if not tag_or_dom?
 | 
				
			||||||
 | 
					      # nop
 | 
				
			||||||
 | 
					    else if tag_or_dom.constructor is String
 | 
				
			||||||
 | 
					      tagname = tag_or_dom
 | 
				
			||||||
      @_xml = {}
 | 
					      @_xml = {}
 | 
				
			||||||
 | 
					      @_xml.children = []
 | 
				
			||||||
      #TODO: How to force the user to specify parameters?
 | 
					      #TODO: How to force the user to specify parameters?
 | 
				
			||||||
      #if not tagname?
 | 
					      #if not tagname?
 | 
				
			||||||
      #  throw new Error "You must specify a tagname"
 | 
					      #  throw new Error "You must specify a tagname"
 | 
				
			||||||
@ -20,23 +25,48 @@ class YXml
 | 
				
			|||||||
          if c.length > 0
 | 
					          if c.length > 0
 | 
				
			||||||
            @_xml.classes[c_name] = c
 | 
					            @_xml.classes[c_name] = c
 | 
				
			||||||
      undefined
 | 
					      undefined
 | 
				
			||||||
 | 
					    else if tag_or_dom instanceof Element
 | 
				
			||||||
 | 
					      @_dom = tag_or_dom
 | 
				
			||||||
 | 
					      @_xml = {}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  _name: "Xml"
 | 
					  _name: "Xml"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  _getModel: (Y, ops)->
 | 
					  _getModel: (Y, ops)->
 | 
				
			||||||
    if not @_model?
 | 
					    if not @_model?
 | 
				
			||||||
 | 
					      if @_dom?
 | 
				
			||||||
 | 
					        @_xml.tagname = @_dom.tagName.toLowerCase()
 | 
				
			||||||
 | 
					        @_xml.attributes = {}
 | 
				
			||||||
 | 
					        @_xml.classes = {}
 | 
				
			||||||
 | 
					        for attribute in @_dom.attributes
 | 
				
			||||||
 | 
					          if attribute.name is "class"
 | 
				
			||||||
 | 
					            for c in attribute.value.split(" ")
 | 
				
			||||||
 | 
					              @_xml.classes[c] = true
 | 
				
			||||||
 | 
					          else
 | 
				
			||||||
 | 
					            @_xml.attributes[attribute.name] = attribute.value
 | 
				
			||||||
 | 
					        @_xml.children = []
 | 
				
			||||||
 | 
					        for child in @_dom.childNodes
 | 
				
			||||||
 | 
					          if child.nodeType is child.TEXT_NODE
 | 
				
			||||||
 | 
					            @_xml.children.push child.textContent
 | 
				
			||||||
 | 
					          else
 | 
				
			||||||
 | 
					            @_xml.children.push(new YXml(child))
 | 
				
			||||||
      @_model = new ops.MapManager(@).execute()
 | 
					      @_model = new ops.MapManager(@).execute()
 | 
				
			||||||
      @_model.val("attributes", new Y.Object(@_xml.attributes))
 | 
					      @_model.val("attributes", new Y.Object(@_xml.attributes))
 | 
				
			||||||
      @_model.val("classes", new Y.Object(@_xml.classes))
 | 
					      @_model.val("classes", new Y.Object(@_xml.classes))
 | 
				
			||||||
      @_model.val("tagname", @_xml.tagname)
 | 
					      @_model.val("tagname", @_xml.tagname)
 | 
				
			||||||
      @_model.val("children", new Y.List())
 | 
					      @_model.val("children", new Y.List(@_xml.children))
 | 
				
			||||||
      if @_xml.parent?
 | 
					      if @_xml.parent?
 | 
				
			||||||
        @_model.val("parent", @_xml.parent)
 | 
					        @_model.val("parent", @_xml.parent)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      if @_dom?
 | 
				
			||||||
 | 
					        @getDom() # two way bind dom to this xml type
 | 
				
			||||||
 | 
					
 | 
				
			||||||
      @_setModel @_model
 | 
					      @_setModel @_model
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    @_model
 | 
					    @_model
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  _setModel: (@_model)->
 | 
					  _setModel: (@_model)->
 | 
				
			||||||
    delete @_xml
 | 
					 | 
				
			||||||
    @_model.observe (events)->
 | 
					    @_model.observe (events)->
 | 
				
			||||||
      for event in events
 | 
					      for event in events
 | 
				
			||||||
        if event.name is "parent" and event.type isnt "add"
 | 
					        if event.name is "parent" and event.type isnt "add"
 | 
				
			||||||
@ -47,8 +77,7 @@ class YXml
 | 
				
			|||||||
              if c is @
 | 
					              if c is @
 | 
				
			||||||
                parent._model.val("children").delete i
 | 
					                parent._model.val("children").delete i
 | 
				
			||||||
                break
 | 
					                break
 | 
				
			||||||
      undefined
 | 
					    delete @_xml
 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
  _setParent: (parent)->
 | 
					  _setParent: (parent)->
 | 
				
			||||||
    if parent instanceof YXml
 | 
					    if parent instanceof YXml
 | 
				
			||||||
@ -260,6 +289,158 @@ class YXml
 | 
				
			|||||||
  getChildren: ()->
 | 
					  getChildren: ()->
 | 
				
			||||||
    @_model.val("children").val()
 | 
					    @_model.val("children").val()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  getPosition: ()->
 | 
				
			||||||
 | 
					    parent = @_model.val("parent")
 | 
				
			||||||
 | 
					    if parent?
 | 
				
			||||||
 | 
					      for c,i in parent._model.val("children").val()
 | 
				
			||||||
 | 
					        if c is @
 | 
				
			||||||
 | 
					          return i
 | 
				
			||||||
 | 
					      throw new Error "This is not a child of its parent (should not happen in Y.Xml!)"
 | 
				
			||||||
 | 
					    else
 | 
				
			||||||
 | 
					      null
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  getDom: ()->
 | 
				
			||||||
 | 
					    if not @_dom?
 | 
				
			||||||
 | 
					      @_dom = document.createElement(@_model.val("tagname"))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      # set the attributes _and_ the classes (@see .attr())
 | 
				
			||||||
 | 
					      for attr_name, attr_value of @attr()
 | 
				
			||||||
 | 
					        @_dom.setAttribute attr_name, attr_value
 | 
				
			||||||
 | 
					      for child,i in @getChildren()
 | 
				
			||||||
 | 
					        if child.constructor is String
 | 
				
			||||||
 | 
					          dom = document.createTextNode child
 | 
				
			||||||
 | 
					        else
 | 
				
			||||||
 | 
					          dom = child.getDom()
 | 
				
			||||||
 | 
					        @_dom.insertBefore dom
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    that = @
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if (not @_dom._y_xml?)
 | 
				
			||||||
 | 
					      @_dom._y_xml = @
 | 
				
			||||||
 | 
					      initialize_proxies.call @
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      @_model.val("children").observe (events)->
 | 
				
			||||||
 | 
					        for event in events
 | 
				
			||||||
 | 
					          if event.type is "insert"
 | 
				
			||||||
 | 
					            newNode = event.value.getDom()
 | 
				
			||||||
 | 
					            children = that._dom.childNodes
 | 
				
			||||||
 | 
					            if children.length > 0
 | 
				
			||||||
 | 
					              rightNode = children[0]
 | 
				
			||||||
 | 
					            else
 | 
				
			||||||
 | 
					              rightNode = null
 | 
				
			||||||
 | 
					            event.value._setParent that
 | 
				
			||||||
 | 
					            dont_proxy ()->
 | 
				
			||||||
 | 
					              that._dom.insertBefore newNode, rightNode
 | 
				
			||||||
 | 
					          else if event.type is "delete"
 | 
				
			||||||
 | 
					            deleted = event.oldValue.getDom()
 | 
				
			||||||
 | 
					            dont_proxy ()->
 | 
				
			||||||
 | 
					              that._dom.removeChild deleted
 | 
				
			||||||
 | 
					      @_model.val("attributes").observe (events)->
 | 
				
			||||||
 | 
					        for event in events
 | 
				
			||||||
 | 
					          if event.type is "add" or event.type is "update"
 | 
				
			||||||
 | 
					            newval = event.object.val(event.name)
 | 
				
			||||||
 | 
					            dont_proxy ()->
 | 
				
			||||||
 | 
					              that._dom.setAttribute event.name, newval
 | 
				
			||||||
 | 
					          else if event.type is "delete"
 | 
				
			||||||
 | 
					            dont_proxy ()->
 | 
				
			||||||
 | 
					              that._dom.removeAttribute event.name
 | 
				
			||||||
 | 
					      @_model.val("classes").observe (events)->
 | 
				
			||||||
 | 
					        for event in events
 | 
				
			||||||
 | 
					          if event.type is "add" or event.type is "update"
 | 
				
			||||||
 | 
					            dont_proxy ()->
 | 
				
			||||||
 | 
					              that._dom.classList.add event.name # classes are stored as the keys
 | 
				
			||||||
 | 
					          else if event.type is "delete"
 | 
				
			||||||
 | 
					            dont_proxy ()->
 | 
				
			||||||
 | 
					              that._dom.classList.remove event.name
 | 
				
			||||||
 | 
					    @_dom
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					proxies_are_initialized = false
 | 
				
			||||||
 | 
					# some dom implementations may call another dom.method that simulates the behavior of another.
 | 
				
			||||||
 | 
					# For example xml.insertChild(dom) , wich inserts an element at the end, and xml.insertAfter(dom,null) wich does the same
 | 
				
			||||||
 | 
					# But Y's proxy may be called only once!
 | 
				
			||||||
 | 
					proxy_token = false
 | 
				
			||||||
 | 
					dont_proxy = (f)->
 | 
				
			||||||
 | 
					  proxy_token = true
 | 
				
			||||||
 | 
					  try
 | 
				
			||||||
 | 
					    f()
 | 
				
			||||||
 | 
					  catch e
 | 
				
			||||||
 | 
					    proxy_token = false
 | 
				
			||||||
 | 
					    throw new Error e
 | 
				
			||||||
 | 
					  proxy_token = false
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					initialize_proxies = ()->
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  _proxy = (f_name, f, source = Element.prototype)->
 | 
				
			||||||
 | 
					    old_f = source[f_name]
 | 
				
			||||||
 | 
					    source[f_name] = ()->
 | 
				
			||||||
 | 
					      if (not @_y_xml?) or proxy_token
 | 
				
			||||||
 | 
					        old_f.apply this, arguments
 | 
				
			||||||
 | 
					      else
 | 
				
			||||||
 | 
					        f.apply @_y_xml, arguments
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  that = this
 | 
				
			||||||
 | 
					  @_dom.classList.add = (c)->
 | 
				
			||||||
 | 
					    that.addClass c
 | 
				
			||||||
 | 
					  @_dom.classList.remove = (c)->
 | 
				
			||||||
 | 
					    that.removeClass c
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  @_dom.__defineSetter__ 'className', (val)->
 | 
				
			||||||
 | 
					    that.attr('class', val)
 | 
				
			||||||
 | 
					  @_dom.__defineGetter__ 'className', ()->
 | 
				
			||||||
 | 
					    that.attr('class')
 | 
				
			||||||
 | 
					  @_dom.__defineSetter__ 'textContent', (val)->
 | 
				
			||||||
 | 
					    # remove all nodes
 | 
				
			||||||
 | 
					    that.empty()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    # insert word content
 | 
				
			||||||
 | 
					    if val isnt ""
 | 
				
			||||||
 | 
					      that.append val
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  if proxies_are_initialized
 | 
				
			||||||
 | 
					    return
 | 
				
			||||||
 | 
					  proxies_are_initialized = true
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  # the following methods are initialized on prototypes and therefore they need to be written only once!
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  insertBefore = (insertedNode_s, adjacentNode)->
 | 
				
			||||||
 | 
					    if adjacentNode?
 | 
				
			||||||
 | 
					      pos = adjacentNode._y_xml.getPosition()
 | 
				
			||||||
 | 
					    else
 | 
				
			||||||
 | 
					      pos = @getChildren().length
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    new_childs = []
 | 
				
			||||||
 | 
					    if insertedNode_s.nodeType is insertedNode_s.DOCUMENT_FRAGMENT_NODE
 | 
				
			||||||
 | 
					      child = insertedNode_s.firstChild
 | 
				
			||||||
 | 
					      while child?
 | 
				
			||||||
 | 
					        new_childs.push child
 | 
				
			||||||
 | 
					        child = child.nextSibling
 | 
				
			||||||
 | 
					    else
 | 
				
			||||||
 | 
					      new_childs.push insertedNode_s
 | 
				
			||||||
 | 
					    new_childs = new_childs.map (child)->
 | 
				
			||||||
 | 
					      if child._y_xml?
 | 
				
			||||||
 | 
					        child._y_xml
 | 
				
			||||||
 | 
					      else if child.nodeType == child.TEXT_NODE
 | 
				
			||||||
 | 
					        child.textContent
 | 
				
			||||||
 | 
					      else
 | 
				
			||||||
 | 
					        new YXml(child)
 | 
				
			||||||
 | 
					    @_model.val("children").insertContents pos, new_childs
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  _proxy 'insertBefore', insertBefore
 | 
				
			||||||
 | 
					  _proxy 'appendChild', insertBefore
 | 
				
			||||||
 | 
					  _proxy 'removeAttribute', (name)->
 | 
				
			||||||
 | 
					    @removeAttr name
 | 
				
			||||||
 | 
					  _proxy 'setAttribute', (name, value)->
 | 
				
			||||||
 | 
					    @attr name, value
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  removeChild = (node)->
 | 
				
			||||||
 | 
					    node._y_xml.remove()
 | 
				
			||||||
 | 
					  _proxy 'removeChild', removeChild, @_dom
 | 
				
			||||||
 | 
					  replaceChild = (insertedNode, replacedNode)->
 | 
				
			||||||
 | 
					    insertBefore.call this, insertedNode, replacedNode
 | 
				
			||||||
 | 
					    removeChild.call this, replacedNode
 | 
				
			||||||
 | 
					  _proxy 'replaceChild', replaceChild, @_dom
 | 
				
			||||||
 | 
					
 | 
				
			||||||
if window?
 | 
					if window?
 | 
				
			||||||
  if window.Y?
 | 
					  if window.Y?
 | 
				
			||||||
 | 
				
			|||||||
@ -4,6 +4,7 @@ should    = chai.should()
 | 
				
			|||||||
sinon     = require('sinon')
 | 
					sinon     = require('sinon')
 | 
				
			||||||
sinonChai = require('sinon-chai')
 | 
					sinonChai = require('sinon-chai')
 | 
				
			||||||
_         = require("underscore")
 | 
					_         = require("underscore")
 | 
				
			||||||
 | 
					$         = require('jquery')
 | 
				
			||||||
 | 
					
 | 
				
			||||||
chai.use(sinonChai)
 | 
					chai.use(sinonChai)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -27,7 +28,7 @@ class XmlTest extends Test
 | 
				
			|||||||
    super new Y conn
 | 
					    super new Y conn
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  initUsers: (u)->
 | 
					  initUsers: (u)->
 | 
				
			||||||
    u.val("xml",new Y.Xml("root"))
 | 
					    u.val("xml",new Y.Xml("div"))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  type: "XmlTest"
 | 
					  type: "XmlTest"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -175,7 +176,7 @@ describe "Y-Xml", ->
 | 
				
			|||||||
      child2 = new Y.Xml("child2")
 | 
					      child2 = new Y.Xml("child2")
 | 
				
			||||||
      @u1.append child
 | 
					      @u1.append child
 | 
				
			||||||
      @u1.append child2
 | 
					      @u1.append child2
 | 
				
			||||||
      expect(@u1.toString()).to.equal("<root><child></child><child2></child2></root>")
 | 
					      expect(@u1.toString()).to.equal("<div><child></child><child2></child2></div>")
 | 
				
			||||||
      @yTest.compareAll()
 | 
					      @yTest.compareAll()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    it "prepend", ->
 | 
					    it "prepend", ->
 | 
				
			||||||
@ -183,31 +184,31 @@ describe "Y-Xml", ->
 | 
				
			|||||||
      child2 = new Y.Xml("child2")
 | 
					      child2 = new Y.Xml("child2")
 | 
				
			||||||
      @u1.prepend child2
 | 
					      @u1.prepend child2
 | 
				
			||||||
      @u1.prepend child
 | 
					      @u1.prepend child
 | 
				
			||||||
      expect(@u1.toString()).to.equal("<root><child></child><child2></child2></root>")
 | 
					      expect(@u1.toString()).to.equal("<div><child></child><child2></child2></div>")
 | 
				
			||||||
      @yTest.compareAll()
 | 
					      @yTest.compareAll()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    it "after", ->
 | 
					    it "after", ->
 | 
				
			||||||
      child = new Y.Xml("child")
 | 
					      child = new Y.Xml("child")
 | 
				
			||||||
      @u1.append child
 | 
					      @u1.append child
 | 
				
			||||||
      child.after new Y.Xml("right-child")
 | 
					      child.after new Y.Xml("right-child")
 | 
				
			||||||
      expect(@u1.toString()).to.equal("<root><child></child><right-child></right-child></root>")
 | 
					      expect(@u1.toString()).to.equal("<div><child></child><right-child></right-child></div>")
 | 
				
			||||||
      @yTest.compareAll()
 | 
					      @yTest.compareAll()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    it "before", ->
 | 
					    it "before", ->
 | 
				
			||||||
      child = new Y.Xml("child")
 | 
					      child = new Y.Xml("child")
 | 
				
			||||||
      @u1.append child
 | 
					      @u1.append child
 | 
				
			||||||
      child.before new Y.Xml("left-child")
 | 
					      child.before new Y.Xml("left-child")
 | 
				
			||||||
      expect(@u1.toString()).to.equal("<root><left-child></left-child><child></child></root>")
 | 
					      expect(@u1.toString()).to.equal("<div><left-child></left-child><child></child></div>")
 | 
				
			||||||
      @yTest.compareAll()
 | 
					      @yTest.compareAll()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    it "empty", ->
 | 
					    it "empty", ->
 | 
				
			||||||
      child = new Y.Xml("child")
 | 
					      child = new Y.Xml("child")
 | 
				
			||||||
      @u1.append child
 | 
					      @u1.append child
 | 
				
			||||||
      child.before new Y.Xml("left-child")
 | 
					      child.before new Y.Xml("left-child")
 | 
				
			||||||
      expect(@u1.toString()).to.equal("<root><left-child></left-child><child></child></root>")
 | 
					      expect(@u1.toString()).to.equal("<div><left-child></left-child><child></child></div>")
 | 
				
			||||||
      @yTest.compareAll()
 | 
					      @yTest.compareAll()
 | 
				
			||||||
      @u1.empty()
 | 
					      @u1.empty()
 | 
				
			||||||
      expect(@u1.toString()).to.equal("<root></root>")
 | 
					      expect(@u1.toString()).to.equal("<div></div>")
 | 
				
			||||||
      @yTest.compareAll()
 | 
					      @yTest.compareAll()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    it "remove", ->
 | 
					    it "remove", ->
 | 
				
			||||||
@ -215,10 +216,10 @@ describe "Y-Xml", ->
 | 
				
			|||||||
      child2 = new Y.Xml("child2")
 | 
					      child2 = new Y.Xml("child2")
 | 
				
			||||||
      @u1.prepend child2
 | 
					      @u1.prepend child2
 | 
				
			||||||
      @u1.prepend child
 | 
					      @u1.prepend child
 | 
				
			||||||
      expect(@u1.toString()).to.equal("<root><child></child><child2></child2></root>")
 | 
					      expect(@u1.toString()).to.equal("<div><child></child><child2></child2></div>")
 | 
				
			||||||
      @yTest.compareAll()
 | 
					      @yTest.compareAll()
 | 
				
			||||||
      child2.remove()
 | 
					      child2.remove()
 | 
				
			||||||
      expect(@u1.toString()).to.equal("<root><child></child></root>")
 | 
					      expect(@u1.toString()).to.equal("<div><child></child></div>")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    it "removeAttr", ->
 | 
					    it "removeAttr", ->
 | 
				
			||||||
      @u1.attr("dtrn", "stuff")
 | 
					      @u1.attr("dtrn", "stuff")
 | 
				
			||||||
@ -258,4 +259,216 @@ describe "Y-Xml", ->
 | 
				
			|||||||
      @u1.prepend(child)
 | 
					      @u1.prepend(child)
 | 
				
			||||||
      expect(@u1.getChildren()[0]).to.equal(child)
 | 
					      expect(@u1.getChildren()[0]).to.equal(child)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  if not window?
 | 
				
			||||||
 | 
					    describe "skip DOM tests (only in browser environment)", ->
 | 
				
			||||||
 | 
					      it "", ->
 | 
				
			||||||
 | 
					  else
 | 
				
			||||||
 | 
					    describe "DOM binding ", ->
 | 
				
			||||||
 | 
					      beforeEach (done)->
 | 
				
			||||||
 | 
					        @dom = @u1.getDom()
 | 
				
			||||||
 | 
					        @j = $(@dom)
 | 
				
			||||||
 | 
					        done()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      it "can transform to a new real Dom element", ->
 | 
				
			||||||
 | 
					        expect(@dom).to.not.be.undefined
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      it "supports dom.insertBefore", ->
 | 
				
			||||||
 | 
					        newdom = $("<p>dtrn</p>")[0]
 | 
				
			||||||
 | 
					        newdom2 = $("<p>dtrn2</p>")[0]
 | 
				
			||||||
 | 
					        @dom.insertBefore(newdom2, null)
 | 
				
			||||||
 | 
					        @dom.insertBefore(newdom, newdom2)
 | 
				
			||||||
 | 
					        expect(@u1+"").to.equal("<div><p>dtrn</p><p>dtrn2</p></div>")
 | 
				
			||||||
 | 
					        expect(@dom.outerHTML).to.equal("<div><p>dtrn</p><p>dtrn2</p></div>")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      it "supports dom.appendChild", ->
 | 
				
			||||||
 | 
					        newdom = $("<p>dtrn</p>")[0]
 | 
				
			||||||
 | 
					        @dom.appendChild(newdom)
 | 
				
			||||||
 | 
					        expect(@u1+"").to.equal("<div><p>dtrn</p></div>")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      it "supports dom.setAttribute", ->
 | 
				
			||||||
 | 
					        @dom.setAttribute("test_attribute", "newVal")
 | 
				
			||||||
 | 
					        expect(@u1.attr("test_attribute")).to.equal("newVal")
 | 
				
			||||||
 | 
					        expect(@dom.getAttribute("test_attribute")).to.equal("newVal")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      it "supports dom.removeAttribute", ->
 | 
				
			||||||
 | 
					        @dom.setAttribute("test_attribute", "newVal")
 | 
				
			||||||
 | 
					        expect(@u1.attr("test_attribute")).to.equal("newVal")
 | 
				
			||||||
 | 
					        expect(@dom.getAttribute("test_attribute")).to.equal("newVal")
 | 
				
			||||||
 | 
					        @dom.removeAttribute("test_attribute")
 | 
				
			||||||
 | 
					        expect(@u1.attr("test_attribute")).to.be.undefined
 | 
				
			||||||
 | 
					        expect(@dom.getAttribute("test_attribute")).to.be.undefined
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      it "supports dom.removeChild", ->
 | 
				
			||||||
 | 
					        newdom = $("<p>dtrn</p>")[0]
 | 
				
			||||||
 | 
					        @dom.appendChild(newdom)
 | 
				
			||||||
 | 
					        expect(@u1+"").to.equal("<div><p>dtrn</p></div>")
 | 
				
			||||||
 | 
					        expect(@dom.outerHTML).to.equal("<div><p>dtrn</p></div>")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        @dom.removeChild(newdom)
 | 
				
			||||||
 | 
					        expect(@dom.childNodes.length).to.equal(0)
 | 
				
			||||||
 | 
					        expect(@u1.getChildren().length).to.equal(0)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      it "supports dom.replaceChild", ->
 | 
				
			||||||
 | 
					        dom = $("<p>dtrn</p>")[0]
 | 
				
			||||||
 | 
					        @dom.appendChild(newdom)
 | 
				
			||||||
 | 
					        expect(@u1+"").to.equal("<div><p>dtrn</p></div>")
 | 
				
			||||||
 | 
					        expect(@dom.outerHTML).to.equal("<div><p>dtrn</p></div>")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        newdom = $("<p>replaced</p>")[0]
 | 
				
			||||||
 | 
					        @dom.replaceChild(dom,newdom)
 | 
				
			||||||
 | 
					        expect(@dom.outerHTML).to.equal("<div><p>replaced</p></div>")
 | 
				
			||||||
 | 
					        expect(@u1+"").to.equal("<div><p>replaced</p></div>")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      it "supports dom.classList.add", ->
 | 
				
			||||||
 | 
					        @dom.classList.add "classy"
 | 
				
			||||||
 | 
					        @dom.classList.add "moreclassy"
 | 
				
			||||||
 | 
					        expect(@u1.attr("class")).to.equal("classy moreclassy")
 | 
				
			||||||
 | 
					        expect(@dom.getAttribute("class")).to.equal("classy moreclassy")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      it "supports dom.textContent", ->
 | 
				
			||||||
 | 
					        dom = $("<p>dtrn</p>")[0]
 | 
				
			||||||
 | 
					        @dom.appendChild(newdom)
 | 
				
			||||||
 | 
					        expect(@u1+"").to.equal("<div><p>dtrn</p></div>")
 | 
				
			||||||
 | 
					        expect(@dom.outerHTML).to.equal("<div><p>dtrn</p></div>")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        @dom.textContent = ""
 | 
				
			||||||
 | 
					        expect(@u1+"").to.equal("<div></div>")
 | 
				
			||||||
 | 
					        expect(@dom.outerHTML).to.equal("<div></div>")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      it "suppports dom.textContent (non empty string)", ->
 | 
				
			||||||
 | 
					        dom = $("<p>dtrn</p>")[0]
 | 
				
			||||||
 | 
					        @dom.appendChild(newdom)
 | 
				
			||||||
 | 
					        expect(@u1+"").to.equal("<div><p>dtrn</p></div>")
 | 
				
			||||||
 | 
					        expect(@dom.outerHTML).to.equal("<div><p>dtrn</p></div>")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        @dom.textContent = "stuff"
 | 
				
			||||||
 | 
					        expect(@u1+"").to.equal("<div>stuff</div>")
 | 
				
			||||||
 | 
					        expect(@dom.outerHTML).to.equal("<div>stuff</div>")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      it "supports jquery.addClass", ->
 | 
				
			||||||
 | 
					        @j.addClass("testy")
 | 
				
			||||||
 | 
					        @j.addClass("testedy tested")
 | 
				
			||||||
 | 
					        expect(@dom.getAttribute("class")).to.equal("testy testedy tested")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      it "supports jquery.after", ->
 | 
				
			||||||
 | 
					        d = $("<span></span>")
 | 
				
			||||||
 | 
					        @dom.appendChild(d[0], null)
 | 
				
			||||||
 | 
					        d.after("<div>after</div>")
 | 
				
			||||||
 | 
					        expect(@dom.outerHTML).to.equal("<div><span></span><div>after</div></div>")
 | 
				
			||||||
 | 
					        expect(@u1+"").to.equal("<div><span></span><div>after</div></div>")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      it "supports jquery.append", ->
 | 
				
			||||||
 | 
					        d = $("<span></span>")[0]
 | 
				
			||||||
 | 
					        @j.append(d)
 | 
				
			||||||
 | 
					        d = $("<div></div>")[0]
 | 
				
			||||||
 | 
					        @dom.append(d)
 | 
				
			||||||
 | 
					        expect(@dom.outerHTML).to.equal("<div><span></span><div></div></div>")
 | 
				
			||||||
 | 
					        expect(@u1+"").to.equal("<div><span></span><div></div></div>")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      it "supports jquery.appendTo", ->
 | 
				
			||||||
 | 
					        $("<b>appendedTo</b>").appendTo(@dom)
 | 
				
			||||||
 | 
					        $("p").appendTo(@dom)
 | 
				
			||||||
 | 
					        expect(@dom.outerHTML).to.equal("<div><b>appendedTo</b><p></p></div>")
 | 
				
			||||||
 | 
					        expect(@u1+"").to.equal("<div><b>appendedTo</b><p></p></div>")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      it "supports jquery.before", ->
 | 
				
			||||||
 | 
					        newdom = $("p")
 | 
				
			||||||
 | 
					        $(@dom).append(newdom)
 | 
				
			||||||
 | 
					        newdom.before("<div>before</div>")
 | 
				
			||||||
 | 
					        expect(@dom.outerHTML).to.equal("<div><div>before</div><p></p></div>")
 | 
				
			||||||
 | 
					        expect(@u1+"").to.equal("<div><div>before</div><p></p></div>")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      it "supports jquery.detach", ->
 | 
				
			||||||
 | 
					        d = $("p")
 | 
				
			||||||
 | 
					        $j.append(d)
 | 
				
			||||||
 | 
					        $j.detach("p")
 | 
				
			||||||
 | 
					        expect(@dom.outerHTML).to.equal("<div></div>")
 | 
				
			||||||
 | 
					        expect(@u1+"").to.equal("<div></div>")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      it "supports jquery.empty", ->
 | 
				
			||||||
 | 
					        d = $("<p />")
 | 
				
			||||||
 | 
					        d.appendTo(@dom)
 | 
				
			||||||
 | 
					        d = $("<div />")
 | 
				
			||||||
 | 
					        d.appendTo(@dom)
 | 
				
			||||||
 | 
					        @j.empty()
 | 
				
			||||||
 | 
					        expect(@dom.outerHTML).to.equal("<div></div>")
 | 
				
			||||||
 | 
					        expect(@u1+"").to.equal("<div></div>")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      it "supports jquery.insertAfter", ->
 | 
				
			||||||
 | 
					        d = $("span")
 | 
				
			||||||
 | 
					        d.appendTo(@dom)
 | 
				
			||||||
 | 
					        $("<p>after</p>").insertAfter(d)
 | 
				
			||||||
 | 
					        expect(@dom.outerHTML).to.equal("<div><span></span><p>after</p></div>")
 | 
				
			||||||
 | 
					        expect(@u1+"").to.equal("<div><span></span><p>after</p></div>")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      it "supports jquery.insertBefore", ->
 | 
				
			||||||
 | 
					        d = $("span")
 | 
				
			||||||
 | 
					        d.appendTo(@j)
 | 
				
			||||||
 | 
					        $("<p>after</p>").insertAfter(d)
 | 
				
			||||||
 | 
					        expect(@dom.outerHTML).to.equal("<div><p>before</p><span></span></div>")
 | 
				
			||||||
 | 
					        expect(@u1+"").to.equal("<div><p>before</p><span></span></div>")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      it "supports jquery.prepend", ->
 | 
				
			||||||
 | 
					        @j.prepend("<p>prepended2</p>")
 | 
				
			||||||
 | 
					        @j.prepend("<p>prepended1</p>")
 | 
				
			||||||
 | 
					        expect(@dom.outerHTML).to.equal("<div><p>prepended1</p><p>prepended2</p></div>")
 | 
				
			||||||
 | 
					        expect(@u1+"").to.equal("<div><p>prepended1</p><p>prepended2</p></div>")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      it "supports jquery.prependTo", ->
 | 
				
			||||||
 | 
					        $("<p>prepended2</p>").prependTo(@j)
 | 
				
			||||||
 | 
					        $("<p>prepended1</p>").prependTo(@j)
 | 
				
			||||||
 | 
					        expect(@dom.outerHTML).to.equal("<div><p>prepended1</p><p>prepended2</p></div>")
 | 
				
			||||||
 | 
					        expect(@u1+"").to.equal("<div><p>prepended1</p><p>prepended2</p></div>")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      it "supports jquery.remove", ->
 | 
				
			||||||
 | 
					        d = $("<div />")
 | 
				
			||||||
 | 
					        d.prependTo(@j)
 | 
				
			||||||
 | 
					        d.remove()
 | 
				
			||||||
 | 
					        expect(@dom.outerHTML).to.equal("<div></div>")
 | 
				
			||||||
 | 
					        expect(@u1+"").to.equal("<div></div>")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      it "supports jquery.removeAttr", ->
 | 
				
			||||||
 | 
					        @dom.setAttribute("test_attribute", "newVal")
 | 
				
			||||||
 | 
					        expect(@u1.attr("test_attribute")).to.equal("newVal")
 | 
				
			||||||
 | 
					        expect(@dom.getAttribute("test_attribute")).to.equal("newVal")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        @j.removeAttr("test_attribute")
 | 
				
			||||||
 | 
					        expect(@u1.attr("test_attribute")).to.be.undefined
 | 
				
			||||||
 | 
					        expect(@j.attr("test_attribute")).to.be.undefined
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      it "supports jquery.removeClass", ->
 | 
				
			||||||
 | 
					        @j.addClass("testy")
 | 
				
			||||||
 | 
					        @j.addClass("testedy tested")
 | 
				
			||||||
 | 
					        expect(@dom.getAttribute("class")).to.equal("testy testedy tested")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        @j.removeClass("testedy")
 | 
				
			||||||
 | 
					        expect(@dom.getAttribute("class")).to.equal("testy tested")
 | 
				
			||||||
 | 
					        expect(@u1.hasClass("testedy")).to.be.false
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      it "supports jquery.attr", ->
 | 
				
			||||||
 | 
					        @j.attr("atone", "yeah")
 | 
				
			||||||
 | 
					        expect(@u1.attr("atone")).to.equal("yeah")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      it "supports jquery.replaceAll", ->
 | 
				
			||||||
 | 
					        $("<span>New span content </span>").replaceAll("#test_dom div")
 | 
				
			||||||
 | 
					        @check()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      it "supports jquery.replaceWith", ->
 | 
				
			||||||
 | 
					        d = $("span")
 | 
				
			||||||
 | 
					        @j.prepend(d)
 | 
				
			||||||
 | 
					        d = $("span")
 | 
				
			||||||
 | 
					        @j.prepend(d)
 | 
				
			||||||
 | 
					        d = $("span")
 | 
				
			||||||
 | 
					        @j.prepend(d)
 | 
				
			||||||
 | 
					        d = @j.getElementsByTagName("span")
 | 
				
			||||||
 | 
					        d.replaceWith("<div></div>")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        expect(@dom.outerHTML).to.equal("<div><div></div><div></div><div></div></div>")
 | 
				
			||||||
 | 
					        expect(@u1+"").to.equal("<div><div></div><div></div><div></div></div>")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
										
											
												File diff suppressed because one or more lines are too long
											
										
									
								
							
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user