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