adapt Ox.Element

This commit is contained in:
rlx 2014-09-23 21:16:25 +02:00
parent a90cc87234
commit aedcb524b5

View file

@ -88,16 +88,18 @@
// create private object // create private object
self = self || {}; self = self || {};
// create defaults and options objects self.boundTooltipEvents = {}; // FIXME?
self.defaults = {}; self.defaults = {};
self.eventCallbacks = self.eventCallbacks || {};
// allow for Ox.Element('<tagname>') or Ox.Element('cssSelector') // allow for Ox.Element('<tagname>') or Ox.Element('cssSelector')
self.options = Ox.isString(options) ? {element: options} : options || {}; self.options = Ox.isString(options) ? {element: options} : options || {};
// stack of callbacks bound to option updates self.unbindKeyboard = function unbindKeyboard() {
self.updateCallbacks = self.updateCallbacks || []; Object.keys(self.eventCallbacks).filter(function(event) {
return /^key([\._][\w\.]+)?$/.test(event);
self.boundTooltipEvents = {}; // FIXME? }).forEach(function(event) {
self.data = {}; that.unbindEvent(event);
});
};
self.update = function update(key, value) { self.update = function update(key, value) {
// update is called whenever an option is modified or added // update is called whenever an option is modified or added
Ox.loop(self.updateCallbacks.length - 1, -1, -1, function(index) { Ox.loop(self.updateCallbacks.length - 1, -1, -1, function(index) {
@ -105,6 +107,7 @@
return self.updateCallbacks[index](key, value) !== false; return self.updateCallbacks[index](key, value) !== false;
}); });
}; };
self.updateCallbacks = self.updateCallbacks || [];
// create public object // create public object
var that = Object.create(Ox.Element.prototype); var that = Object.create(Ox.Element.prototype);
@ -118,16 +121,23 @@
}); });
that[0] = that.$element[0]; that[0] = that.$element[0];
that.length = 1; that.length = 1;
that.self = function() { that.self = function _self() {
return arguments[0] === _ ? self : {}; return arguments[0] === _ ? self : {};
}; };
Ox.elements[that.oxid] = that; Ox.elements[that.oxid] = that;
if (self.options.element == '<iframe>') { if (self.options.element == '<iframe>') {
// FIXME: update later self.messageCallbacks = self.messageCallbacks || {};
that.on({ that.on({
load: function() { load: function init() {
Ox.Message.post(that, 'init', {id: that.oxid}); // send oxid to iframe
that.postMessage({init: {oxid: that.oxid}});
self.initTimeout = setTimeout(init, 25);
}
}).bindEvent({
init: function() {
// iframe has received oxid
clearTimeout(self.initTimeout);
} }
}); });
} }
@ -192,7 +202,7 @@
}); });
clientX = e.clientX; clientX = e.clientX;
clientY = e.clientY; clientY = e.clientY;
Ox.UI.$window Ox.$window
.off('mouseup', mouseup) .off('mouseup', mouseup)
.on({mousemove: mousemove}) .on({mousemove: mousemove})
.one('mouseup', function(e) { .one('mouseup', function(e) {
@ -201,7 +211,7 @@
// stop checking for dragpause // stop checking for dragpause
clearTimeout(dragTimeout); clearTimeout(dragTimeout);
// stop checking for drag // stop checking for drag
Ox.UI.$window.off({mousemove: mousemove}); Ox.$window.off({mousemove: mousemove});
// stop checking for dragenter and dragleave // stop checking for dragenter and dragleave
$('.OxElement').off({ $('.OxElement').off({
mouseenter: dragenter, mouseenter: dragenter,
@ -219,7 +229,7 @@
self._mouseTimeout = 0; self._mouseTimeout = 0;
that.triggerEvent('doubleclick', e); that.triggerEvent('doubleclick', e);
} }
Ox.UI.$window.one({mouseup: mouseup}); Ox.$window.one({mouseup: mouseup});
function dragenter(e) { function dragenter(e) {
that.triggerEvent('dragenter', extend(e)); that.triggerEvent('dragenter', extend(e));
} }
@ -339,16 +349,14 @@
// add all jQuery methods to the prototype of Ox.Element // add all jQuery methods to the prototype of Ox.Element
Ox.methods($('<div>'), true).forEach(function(method) { Ox.methods($('<div>'), true).forEach(function(method) {
Ox.Element.prototype[method] = function() { Ox.Element.prototype[method] = function() {
var $element = this.$element[method].apply( var ret = this.$element[method].apply(this.$element, arguments),
this.$element, arguments
),
oxid; oxid;
// If exactly one $element of an Ox Element was returned, then // If exactly one $element of an Ox Element was returned, then
// return the Ox Element instead, so that we can do // return the Ox Element instead, so that we can do
// oxObj.jqFn().oxFn() // oxObj.jqFn().oxFn()
return $element && $element.jquery && $element.length == 1 return ret && ret.jquery && ret.length == 1
&& Ox.elements[oxid = $element.data('oxid')] && Ox.elements[oxid = ret.data('oxid')]
? Ox.elements[oxid] : $element; ? Ox.elements[oxid] : ret;
}; };
}); });
@ -366,8 +374,7 @@
Event names can be namespaced, like `'click.foo'` Event names can be namespaced, like `'click.foo'`
@*/ @*/
Ox.Element.prototype.bindEvent = function bindEvent() { Ox.Element.prototype.bindEvent = function bindEvent() {
var self = this.self(_); Ox.Event.bind.apply(this, [this.self(_)].concat(Ox.slice(arguments)));
Ox.Event.bind.apply(null, [self].concat(Ox.slice(arguments)));
return this; return this;
}; };
@ -385,8 +392,9 @@
Event names can be namespaced, like `'click.foo'` Event names can be namespaced, like `'click.foo'`
@*/ @*/
Ox.Element.prototype.bindEventOnce = function bindEventOnce() { Ox.Element.prototype.bindEventOnce = function bindEventOnce() {
var self = this.self(_); Ox.Event.bindOnce.apply(
Ox.Event.bindOnce.apply(null, [self].concat(Ox.slice(arguments))); this, [this.self(_)].concat(Ox.slice(arguments))
);
return this; return this;
}; };
@ -404,44 +412,26 @@
@*/ @*/
Ox.Element.prototype.bindMessage = Ox.Element.prototype.onMessage = function bindMessage() { Ox.Element.prototype.bindMessage = Ox.Element.prototype.onMessage = function bindMessage() {
var self = this.self(_); var self = this.self(_);
var that = this;
var callback;
if (self.options.element == '<iframe>') { if (self.options.element == '<iframe>') {
if (Ox.isObject(arguments[0])) { Ox.Message.bind.apply(this, [self].concat(Ox.slice(arguments)));
Ox.forEach(arguments[0], function(callback, event) {
Ox.Message.bind(arguments[0], function(event_, data, oxid) {
if (event_ == event && oxid == that.oxid) {
callback(data || {});
}
});
});
} else {
callback = arguments[0];
Ox.Message.bind(function(event, data, oxid) {
if (that.oxid == oxid) {
callback(event, data || {});
}
});
}
} }
return this; return this;
}; };
Ox.Element.prototype.bindMessageOnce = function bindMessageOnce() { Ox.Element.prototype.bindMessageOnce = Ox.Element.prototype.onMessageOnce = function bindMessageOnce() {
var self = this.self(_);
}; if (self.options.element == '<iframe>') {
Ox.Message.bindOnce.apply(
/*@ this, [self].concat(Ox.slice(arguments))
bindKeyboard <f> bind keyboard );
() -> <o> object }
@*/
Ox.Element.prototype.bindKeyboard = function bindKeyboard() {
Ox.Keyboard.bind(this.oxid);
return this; return this;
}; };
Ox.Element.prototype.childrenElements = function childrenElements() { Ox.Element.prototype.childrenElements = function childrenElements() {
return this.children().filter(Ox.UI.isOxElement).map(Ox.UI.getOxElement); return Ox.slice(this.children())
.filter(Ox.isOxElement)
.map(Ox.getOxElement);
}; };
/*@ /*@
@ -458,29 +448,31 @@
} else if (Ox.isString(arguments[0])) { } else if (Ox.isString(arguments[0])) {
ret = self.defaults[arguments[0]]; ret = self.defaults[arguments[0]];
} else { } else {
self.defaults = arguments[0]; self.defaults = Ox.makeObject(arguments);
self.options = Ox.clone(self.defaults); self.options = Ox.clone(self.defaults);
ret = this; ret = this;
} }
return ret; return ret;
}; };
Ox.Element.prototype.findElements = function findElements() { Ox.Element.prototype.empty = function empty() {
return Ox.map(this.find('.OxElement'), Ox.UI.getOxElement); this.childrenElements().forEach(function($element) {
$element.removeElement();
});
this.$element.empty.apply(this, arguments);
return this;
}; };
/* Ox.Element.prototype.findElements = function findElements() {
Ox.Element.prototype.forEach = function forEach() { return Ox.map(this.find('.OxElement'), Ox.getOxElement);
// TODO
}; };
*/
/*@ /*@
gainFocus <function> Makes an element object gain focus gainFocus <function> Makes an element object gain focus
() -> <obj> This element object () -> <obj> This element object
@*/ @*/
Ox.Element.prototype.gainFocus = function gainFocus() { Ox.Element.prototype.gainFocus = function gainFocus() {
Ox.Focus.focus(this.oxid); Ox.Focus.gainFocus(this);
return this; return this;
}; };
@ -489,7 +481,16 @@
() -> <boolean> True if the element has focus () -> <boolean> True if the element has focus
@*/ @*/
Ox.Element.prototype.hasFocus = function hasFocus() { Ox.Element.prototype.hasFocus = function hasFocus() {
return Ox.Focus.focused() == this.oxid; return Ox.Focus.focusedElement() === this;
};
Ox.Element.prototype.html = function html() {
var ret;
this.childrenElements().forEach(function($element) {
$element.removeElement();
});
ret = this.$element.html.apply(this, arguments);
return arguments.length == 0 ? ret : this;
}; };
/*@ /*@
@ -497,7 +498,7 @@
() -> <object> This element object () -> <object> This element object
@*/ @*/
Ox.Element.prototype.loseFocus = function loseFocus() { Ox.Element.prototype.loseFocus = function loseFocus() {
Ox.Focus.blur(this.oxid); Ox.Focus.loseFocus(this);
return this; return this;
}; };
@ -506,7 +507,7 @@
}; };
Ox.Element.prototype.nextElements = function nextElements() { Ox.Element.prototype.nextElements = function nextElements() {
return this.nextAll().filter(Ox.UI.isOxElement).map(Ox.UI.getOxElement); return this.nextAll().filter(Ox.isOxElement).map(Ox.getOxElement);
}; };
/*@ /*@
@ -532,7 +533,9 @@
}; };
Ox.Element.prototype.parentElements = function parentElements() { Ox.Element.prototype.parentElements = function parentElements() {
return this.parents().filter(Ox.UI.isOxElement).map(Ox.UI.getOxElement); return Ox.slice(this.parents())
.filter(Ox.isOxElement)
.map(Ox.getOxElement);
}; };
/*@ /*@
@ -542,9 +545,8 @@
data <o> Event data data <o> Event data
@*/ @*/
Ox.Element.prototype.postMessage = function postMessage(event, data) { Ox.Element.prototype.postMessage = function postMessage(event, data) {
var self = this.self(_); if (this.self(_).options.element == '<iframe>') {
if (self.options.element == '<iframe>') { Ox.Message.post.apply(this, Ox.slice(arguments));
Ox.Message.post(this, event, data);
} }
return this; return this;
}; };
@ -554,72 +556,82 @@
}; };
Ox.Element.prototype.prevElements = function prevElements() { Ox.Element.prototype.prevElements = function prevElements() {
return this.prevAll().filter(Ox.UI.isOxElement).map(Ox.UI.getOxElement); return this.prevAll().filter(Ox.isOxElement).map(Ox.getOxElement);
}; };
/*@ Ox.Element.prototype.remove = function remove() {
remove <f> Removes an element object and its event handler var parent = this[0].parentNode;
() -> <o> This element this.removeElement();
@*/ parent && parent.removeChild(this[0]);
Ox.Element.prototype.remove = function remove(remove) {
if (remove !== false) {
this.find('.OxElement').each(function() {
var $element = Ox.elements[$(this).data('oxid')];
$element && $element.remove(false);
});
}
Ox.Focus.remove(this.oxid);
Ox.Keyboard.unbind(this.oxid);
delete Ox.elements[this.oxid];
this.$tooltip && this.$tooltip.remove();
remove !== false && this.$element.remove();
return this; return this;
}; };
/* Ox.Element.prototype.removeElement = function removeElement(includeChildren) {
Ox.Element.prototype.remove = function() { if (includeChildren !== false) {
[that].concat(that.find('.OxElement')) this.find('.OxElement').each(function() {
.map(Ox.UI.getOxElement).forEach(function($element) { var $element = Ox.getElement(this);
$element.removeElement(); $element && $element.removeElement(false);
}); });
that[0].parentNode.removeChild(this[0]); }
return that; Ox.Focus.removeElement(this.oxid);
} this.self(_).unbindKeyboard();
this.$tooltip && this.$tooltip.remove();
Ox.Element.prototype.removeElement = function() { delete Ox.elements[this.oxid];
delete Ox.$elements[that.oxid]; // If setElement($element) was used, delete $element too
Ox.Focus.remove(that); delete Ox.elements[this.$element.oxid];
self.unbindKeyboard(); return this;
return that; };
Ox.Element.prototype.replace = function replace() {
arguments[0].removeElement();
this.$element.replace.apply(this.$element, arguments);
return this;
};
Ox.Element.prototype.replaceWith = function replaceWith() {
this.removeElement();
this.$element.replaceWith.apply(this.$element, arguments);
return this;
}; };
*/
/*@ /*@
setElement <f> set $element setElement <f> set $element
($element) -> <o> This element ($element) -> <o> This element
@*/ @*/
Ox.Element.prototype.setElement = function setElement($element) { Ox.Element.prototype.setElement = function setElement($element) {
// FIXME: get rid of this.$element
$element.addClass('OxElement').data({oxid: this.oxid}); $element.addClass('OxElement').data({oxid: this.oxid});
this.replaceWith($element); this.replaceWith($element);
this.$element = $element; this.$element = $element;
this[0] = $element[0]; this[0] = $element[0];
this.elements = [this[0]]; Ox.elements[this.oxid] = this;
return this; return this;
}; };
Ox.Element.prototype.siblingElements = function siblingElements() {
return Ox.slice(this.siblings())
.filter(Ox.isOxElement)
.map(Ox.getOxElement);
};
Ox.Element.prototype.text = function text() {
var ret;
this.childrenElements().forEach(function($element) {
$element.removeElement();
});
ret = this.$element.text.apply(this, arguments);
return arguments.length == 0 ? ret : this;
};
/*@ /*@
toggleOption <f> Toggle boolean option(s) toggleOption <f> Toggle boolean option(s)
(key[, key[, ...]]) -> <o> This element (key[, key[, ...]]) -> <o> This element
@*/ @*/
Ox.Element.prototype.toggleOption = function toggleOption() { Ox.Element.prototype.toggleOption = function toggleOption() {
var self = this.self(_); var options = {}, self = this.self(_);
var options = {};
Ox.slice(arguments).forEach(function(key) { Ox.slice(arguments).forEach(function(key) {
options[key] == !self.options[key]; options[key] == !self.options[key];
}); });
this.options(options); return this.options(options);
return this;
}; };
/*@ /*@
@ -634,13 +646,18 @@
data <object> Event data (key/value pairs) data <object> Event data (key/value pairs)
@*/ @*/
Ox.Element.prototype.triggerEvent = function triggerEvent() { Ox.Element.prototype.triggerEvent = function triggerEvent() {
var self = this.self(_); Ox.Event.trigger.apply(
Ox.Event.trigger.apply(this, [self].concat(Ox.slice(arguments))); this, [this.self(_)].concat(Ox.slice(arguments))
);
return this; return this;
}; };
Ox.Element.prototype.triggerMessage = function triggerMessage() { Ox.Element.prototype.triggerMessage = function triggerMessage() {
var self = this.self(_);
if (self.options.element == '<iframe>') {
Ox.Message.trigger.apply(this, [self].concat(Ox.slice(arguments)));
}
return this;
}; };
/*@ /*@
@ -659,21 +676,15 @@
event <string> Event name event <string> Event name
@*/ @*/
Ox.Element.prototype.unbindEvent = function unbindEvent() { Ox.Element.prototype.unbindEvent = function unbindEvent() {
var self = this.self(_); Ox.Event.unbind.apply(this, [this.self(_)].concat(Ox.slice(arguments)));
Ox.Event.unbind.apply(null, [self].concat(Ox.slice(arguments)));
return this; return this;
}; };
Ox.Element.prototype.unbindMessage = function unbindMessage() { Ox.Element.prototype.unbindMessage = function unbindMessage() {
var self = this.self(_);
}; if (self.options.element == '<iframe>') {
Ox.Message.unbind.apply(this, [self].concat(Ox.slice(arguments)));
/*@ }
unbindKeyboard <f> unbind keyboard
() -> <o> object
@*/
Ox.Element.prototype.unbindKeyboard = function unbindKeyboard() {
Ox.Keyboard.unbind(this.oxid);
return this; return this;
}; };
@ -684,15 +695,14 @@
({key: callback, ...}) -> <o> that ({key: callback, ...}) -> <o> that
@*/ @*/
Ox.Element.prototype.update = function update() { Ox.Element.prototype.update = function update() {
var self = this.self(_); var callbacks, self = this.self(_);
var callbacks;
if (Ox.isFunction(arguments[0])) { if (Ox.isFunction(arguments[0])) {
self.updateCallbacks.push(arguments[0]); self.updateCallbacks.push(arguments[0]);
} else { } else {
callbacks = Ox.makeObject(arguments); callbacks = Ox.makeObject(arguments);
self.updateCallbacks.push(function(key) { self.updateCallbacks.push(function(key, value) {
if (callbacks[key]) { if (callbacks[key]) {
return callbacks[key](); return callbacks[key](value);
} }
}); });
} }