2011-11-05 16:46:53 +00:00
|
|
|
'use strict';
|
|
|
|
|
2014-09-22 14:56:54 +00:00
|
|
|
(function(_) {
|
2013-02-24 10:57:37 +00:00
|
|
|
|
2014-09-22 14:56:54 +00:00
|
|
|
/*@
|
|
|
|
Ox.Element <f> Basic UI element object
|
|
|
|
# Arguments -----------------------------------------------------------
|
|
|
|
options <o|s> Options of the element, or just the `element` option
|
|
|
|
element <s> Tagname or CSS selector
|
|
|
|
tooltip <s|f> Tooltip title, or a function that returns one
|
|
|
|
(e) -> <s> Tooltip title
|
|
|
|
e <o> Mouse event
|
|
|
|
self <o> Shared private variable
|
|
|
|
# Usage ---------------------------------------------------------------
|
2014-09-22 15:04:42 +00:00
|
|
|
([options[, self]]) -> <o> Element object
|
2014-09-22 14:56:54 +00:00
|
|
|
# Events ----------------------------------------------------------
|
|
|
|
anyclick <!> anyclick
|
|
|
|
Fires on mouseup, but not on any subsequent mouseup within 250
|
|
|
|
ms (this is useful if one wants to listen for singleclicks, but
|
|
|
|
not doubleclicks, since it will fire immediately, and won't
|
|
|
|
fire again in case of a doubleclick)
|
|
|
|
* <*> Original event properties
|
|
|
|
doubleclick <!> doubleclick
|
|
|
|
Fires on the second mousedown within 250 ms (this is useful if
|
|
|
|
one wants to listen for both singleclicks and doubleclicks,
|
|
|
|
since it will not trigger a singleclick event)
|
|
|
|
* <*> Original event properties
|
|
|
|
drag <!> drag
|
|
|
|
Fires on mousemove after dragstart, stops firing on mouseup
|
|
|
|
clientDX <n> Horizontal drag delta in px
|
|
|
|
clientDY <n> Vertical drag delta in px
|
|
|
|
* <*> Original event properties
|
|
|
|
dragend <!> dragpause
|
|
|
|
Fires on mouseup after dragstart
|
|
|
|
clientDX <n> Horizontal drag delta in px
|
|
|
|
clientDY <n> Vertical drag delta in px
|
|
|
|
* <*> Original event properties
|
|
|
|
dragenter <!> dragenter
|
|
|
|
Fires when entering an element during drag (this fires on the
|
|
|
|
element being dragged -- the target element is the event's
|
|
|
|
target property)
|
|
|
|
clientDX <n> Horizontal drag delta in px
|
|
|
|
clientDY <n> Vertical drag delta in px
|
|
|
|
* <*> Original event properties
|
|
|
|
dragleave <!> dragleave
|
|
|
|
Fires when leaving an element during drag (this fires on the
|
|
|
|
element being dragged -- the target element is the event's
|
|
|
|
target property)
|
|
|
|
clientDX <n> Horizontal drag delta in px
|
|
|
|
clientDY <n> Vertical drag delta in px
|
|
|
|
* <*> Original event properties
|
|
|
|
dragpause <!> dragpause
|
|
|
|
Fires once when the mouse doesn't move for 250 ms during drag
|
|
|
|
(this is useful in order to execute operations that are too
|
|
|
|
expensive to be attached to the drag event)
|
|
|
|
clientDX <n> Horizontal drag delta in px
|
|
|
|
clientDY <n> Vertical drag delta in px
|
|
|
|
* <*> Original event properties
|
|
|
|
dragstart <!> dragstart
|
|
|
|
Fires when the mouse is down for 250 ms
|
|
|
|
* <*> Original event properties
|
|
|
|
mousedown <!> mousedown
|
|
|
|
Fires on mousedown (this is useful if one wants to listen for
|
|
|
|
singleclicks, but not doubleclicks or drag events, and wants
|
|
|
|
the event to fire as early as possible)
|
|
|
|
* <*> Original event properties
|
|
|
|
mouserepeat <!> mouserepeat
|
|
|
|
Fires every 50 ms after the mouse was down for 250 ms, stops
|
|
|
|
firing on mouseleave or mouseup (this fires like a key that is
|
|
|
|
being pressed and held, and is useful for buttons like
|
|
|
|
scrollbar arrows that need to react to both clicking and
|
|
|
|
holding)
|
|
|
|
mousewheel <!> mousewheel
|
|
|
|
Fires on mousewheel scroll or trackpad swipe
|
|
|
|
deltaFactor <n> Original delta = normalized delta * delta factor
|
|
|
|
deltaX <n> Normalized horizontal scroll delta in px
|
|
|
|
deltaY <n> Normalized vertical scroll delta in px
|
|
|
|
* <*> Original event properties
|
|
|
|
singleclick <!> singleclick
|
|
|
|
Fires 250 ms after mouseup, if there was no subsequent
|
|
|
|
mousedown (this is useful if one wants to listen for both
|
|
|
|
singleclicks and doubleclicks, since it will not fire for
|
|
|
|
doubleclicks)
|
|
|
|
* <*> Original event properties
|
|
|
|
*/
|
2011-04-29 22:07:23 +00:00
|
|
|
|
2014-09-22 14:56:54 +00:00
|
|
|
Ox.Element = function Element(options, self) {
|
|
|
|
|
|
|
|
// create private object
|
|
|
|
self = self || {};
|
|
|
|
// create defaults and options objects
|
|
|
|
self.defaults = {};
|
|
|
|
// 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.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) {
|
|
|
|
// break if the callback returns false
|
|
|
|
return self.updateCallbacks[index](key, value) !== false;
|
|
|
|
});
|
|
|
|
};
|
|
|
|
|
|
|
|
// create public object
|
|
|
|
var that = Object.create(Ox.Element.prototype);
|
|
|
|
that.oxid = Ox.uid();
|
|
|
|
that.$element = $(self.options.element || '<div>')
|
|
|
|
.addClass('OxElement')
|
|
|
|
.data({oxid: that.oxid})
|
|
|
|
.on({
|
|
|
|
mousedown: onMousedown,
|
|
|
|
mousewheel: onMousewheel
|
|
|
|
});
|
|
|
|
that[0] = that.$element[0];
|
|
|
|
that.length = 1;
|
2014-09-22 15:10:43 +00:00
|
|
|
that.self = function() {
|
|
|
|
return arguments[0] === _ ? self : {};
|
|
|
|
};
|
2014-09-22 14:56:54 +00:00
|
|
|
Ox.elements[that.oxid] = that;
|
2014-02-02 11:05:41 +00:00
|
|
|
|
2014-09-22 14:56:54 +00:00
|
|
|
if (self.options.element == '<iframe>') {
|
|
|
|
// FIXME: update later
|
|
|
|
that.on({
|
|
|
|
load: function() {
|
|
|
|
Ox.Message.post(that, 'init', {id: that.oxid});
|
2011-04-22 22:03:10 +00:00
|
|
|
}
|
2014-09-22 14:56:54 +00:00
|
|
|
});
|
2011-10-01 02:21:55 +00:00
|
|
|
}
|
2014-09-22 14:56:54 +00:00
|
|
|
|
|
|
|
setTooltip();
|
|
|
|
|
|
|
|
function bindTooltipEvents(events) {
|
|
|
|
that.off(Ox.filter(self.boundTooltipEvents, function(value, key) {
|
|
|
|
return !events[key];
|
|
|
|
})).on(self.boundTooltipEvents = Ox.filter(events, function(value, key) {
|
|
|
|
return !self.boundTooltipEvents[key];
|
|
|
|
}));
|
2011-04-22 22:03:10 +00:00
|
|
|
}
|
2014-09-22 14:56:54 +00:00
|
|
|
|
|
|
|
function onMousedown(e) {
|
|
|
|
/*
|
|
|
|
better mouse events
|
|
|
|
mousedown:
|
|
|
|
trigger mousedown
|
|
|
|
within 250 msec:
|
|
|
|
mouseup: trigger anyclick
|
|
|
|
mouseup + mousedown: trigger doubleclick
|
|
|
|
after 250 msec:
|
|
|
|
mouseup + no mousedown within 250 msec: trigger singleclick
|
|
|
|
no mouseup within 250 msec:
|
|
|
|
trigger mouserepeat every 50 msec
|
|
|
|
trigger dragstart
|
|
|
|
mousemove: trigger drag
|
|
|
|
no mousemove for 250 msec:
|
|
|
|
trigger dragpause
|
|
|
|
mouseup: trigger dragend
|
|
|
|
"anyclick" is not called "click" since this would collide with the click
|
|
|
|
events of some widgets
|
|
|
|
*/
|
|
|
|
var clientX, clientY,
|
|
|
|
dragTimeout = 0,
|
|
|
|
mouseInterval = 0;
|
|
|
|
that.triggerEvent('mousedown', e);
|
|
|
|
if (!self._mouseTimeout) {
|
|
|
|
// first mousedown
|
|
|
|
self._drag = false;
|
|
|
|
self._mouseup = false;
|
|
|
|
self._mouseTimeout = setTimeout(function() {
|
|
|
|
// 250 ms later, no subsequent click
|
|
|
|
self._mouseTimeout = 0;
|
|
|
|
if (self._mouseup) {
|
|
|
|
// mouse went up, trigger singleclick
|
|
|
|
that.triggerEvent('singleclick', e);
|
|
|
|
} else {
|
|
|
|
// mouse is still down, trigger mouserepeat
|
|
|
|
// every 50 ms until mouseleave or mouseup
|
|
|
|
mouserepeat();
|
|
|
|
mouseInterval = setInterval(mouserepeat, 50);
|
|
|
|
that.one('mouseleave', function() {
|
|
|
|
clearInterval(mouseInterval);
|
|
|
|
});
|
|
|
|
// trigger dragstart, set up drag events
|
|
|
|
that.triggerEvent('dragstart', e);
|
|
|
|
$('.OxElement').live({
|
|
|
|
mouseenter: dragenter,
|
|
|
|
mouseleave: dragleave
|
|
|
|
});
|
|
|
|
clientX = e.clientX;
|
|
|
|
clientY = e.clientY;
|
|
|
|
Ox.UI.$window
|
|
|
|
.off('mouseup', mouseup)
|
|
|
|
.on({mousemove: mousemove})
|
|
|
|
.one('mouseup', function(e) {
|
|
|
|
// stop checking for mouserepeat
|
|
|
|
clearInterval(mouseInterval);
|
|
|
|
// stop checking for dragpause
|
|
|
|
clearTimeout(dragTimeout);
|
|
|
|
// stop checking for drag
|
|
|
|
Ox.UI.$window.off({mousemove: mousemove});
|
|
|
|
// stop checking for dragenter and dragleave
|
|
|
|
$('.OxElement').off({
|
|
|
|
mouseenter: dragenter,
|
|
|
|
mouseleave: dragleave
|
|
|
|
});
|
|
|
|
// trigger dragend
|
|
|
|
that.triggerEvent('dragend', extend(e));
|
|
|
|
});
|
|
|
|
self._drag = true;
|
|
|
|
}
|
|
|
|
}, 250);
|
|
|
|
} else {
|
|
|
|
// second mousedown within 250 ms, trigger doubleclick
|
|
|
|
clearTimeout(self._mouseTimeout);
|
|
|
|
self._mouseTimeout = 0;
|
|
|
|
that.triggerEvent('doubleclick', e);
|
|
|
|
}
|
|
|
|
Ox.UI.$window.one({mouseup: mouseup});
|
|
|
|
function dragenter(e) {
|
|
|
|
that.triggerEvent('dragenter', extend(e));
|
|
|
|
}
|
|
|
|
function dragleave(e) {
|
|
|
|
that.triggerEvent('dragleave', extend(e));
|
|
|
|
}
|
|
|
|
function extend(e) {
|
|
|
|
return Ox.extend({
|
|
|
|
clientDX: e.clientX - clientX,
|
|
|
|
clientDY: e.clientY - clientY
|
|
|
|
}, e);
|
|
|
|
}
|
|
|
|
function mousemove(e) {
|
|
|
|
e = extend(e);
|
|
|
|
clearTimeout(dragTimeout);
|
|
|
|
dragTimeout = setTimeout(function() {
|
|
|
|
// mouse did not move for 250 ms, trigger dragpause
|
|
|
|
that.triggerEvent('dragpause', e);
|
|
|
|
}, 250);
|
|
|
|
that.triggerEvent('drag', e);
|
|
|
|
}
|
|
|
|
function mouserepeat(e) {
|
|
|
|
that.triggerEvent('mouserepeat', e);
|
|
|
|
}
|
|
|
|
function mouseup(e) {
|
|
|
|
if (!self._mouseup && !self._drag) {
|
|
|
|
// mouse went up for the first time, trigger anyclick
|
|
|
|
that.triggerEvent('anyclick', e);
|
|
|
|
self._mouseup = true;
|
|
|
|
}
|
2011-10-01 02:21:55 +00:00
|
|
|
}
|
|
|
|
}
|
2011-04-22 22:03:10 +00:00
|
|
|
|
2014-09-22 14:56:54 +00:00
|
|
|
function onMouseenter(e) {
|
|
|
|
if (!that.$tooltip) {
|
|
|
|
that.$tooltip = Ox.Tooltip({title: self.options.tooltip});
|
|
|
|
}
|
|
|
|
that.$tooltip.show(e);
|
2014-02-02 11:05:41 +00:00
|
|
|
}
|
2011-04-22 22:03:10 +00:00
|
|
|
|
2014-09-22 14:56:54 +00:00
|
|
|
function onMouseleave(e) {
|
|
|
|
that.$tooltip && that.$tooltip.hide();
|
|
|
|
}
|
2011-04-22 22:03:10 +00:00
|
|
|
|
2014-09-22 14:56:54 +00:00
|
|
|
function onMousemove(e) {
|
|
|
|
that.$tooltip.options({title: self.options.tooltip(e)}).show(e);
|
2013-12-04 22:44:07 +00:00
|
|
|
}
|
2014-09-22 14:56:54 +00:00
|
|
|
|
|
|
|
function onMousewheel(e) {
|
|
|
|
// see https://github.com/brandonaaron/jquery-mousewheel/blob/master/jquery.mousewheel.js
|
2014-09-22 15:12:17 +00:00
|
|
|
e = e.originalEvent;
|
2014-09-22 14:56:54 +00:00
|
|
|
var absDelta,
|
|
|
|
deltaX = 'deltaX' in e ? e.deltaX
|
|
|
|
: 'wheelDeltaX' in e ? -e.wheelDeltaX
|
|
|
|
: 0,
|
|
|
|
deltaY = 'deltaY' in e ? -e.deltaY
|
|
|
|
: 'wheelDeltaY' in e ? e.wheelDeltaY
|
|
|
|
: 'wheelDelta' in e ? e.wheelDelta
|
|
|
|
: 0;
|
|
|
|
// Firefox < 17
|
|
|
|
if ('axis' in e && e.axis === e.HORIZONTAL_AXIS) {
|
|
|
|
deltaX = -deltaY;
|
|
|
|
deltaY = 0;
|
|
|
|
}
|
|
|
|
if (deltaX || deltaY) {
|
|
|
|
absDelta = Math.max(Math.abs(deltaY), Math.abs(deltaX));
|
|
|
|
if (!self._deltaFactor || self._deltaFactor > absDelta) {
|
|
|
|
self._deltaFactor = absDelta;
|
|
|
|
}
|
|
|
|
that.triggerEvent('mousewheel', Ox.extend(e, {
|
|
|
|
deltaFactor: self._deltaFactor,
|
|
|
|
deltaX: Ox.trunc(deltaX / self._deltaFactor),
|
|
|
|
deltaY: Ox.trunc(deltaY / self._deltaFactor)
|
|
|
|
}));
|
|
|
|
clearTimeout(self._deltaTimeout)
|
|
|
|
self._deltaTimeout = setTimeout(function() {
|
|
|
|
self._deltaFactor = null;
|
|
|
|
}, 200);
|
2013-12-04 22:44:07 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-09-22 14:56:54 +00:00
|
|
|
// TODO: in other widgets, use this,
|
|
|
|
// rather than some self.$tooltip that
|
|
|
|
// will not get garbage collected
|
|
|
|
function setTooltip() {
|
|
|
|
if (self.options.tooltip) {
|
|
|
|
if (Ox.isString(self.options.tooltip)) {
|
|
|
|
bindTooltipEvents({
|
|
|
|
mouseenter: onMouseenter,
|
|
|
|
mouseleave: onMouseleave
|
|
|
|
});
|
|
|
|
that.$tooltip && that.$tooltip.options({
|
|
|
|
title: self.options.tooltip,
|
|
|
|
animate: true
|
|
|
|
});
|
|
|
|
} else {
|
|
|
|
that.$tooltip = Ox.Tooltip({animate: false});
|
|
|
|
bindTooltipEvents({
|
|
|
|
mousemove: onMousemove,
|
|
|
|
mouseleave: onMouseleave
|
|
|
|
});
|
|
|
|
}
|
2011-11-04 22:14:30 +00:00
|
|
|
} else {
|
2014-09-22 14:56:54 +00:00
|
|
|
if (that.$tooltip) {
|
|
|
|
that.$tooltip.remove();
|
|
|
|
}
|
|
|
|
bindTooltipEvents({});
|
2011-11-05 14:29:31 +00:00
|
|
|
}
|
2011-11-04 22:14:30 +00:00
|
|
|
}
|
|
|
|
|
2014-09-22 14:56:54 +00:00
|
|
|
that.update({tooltip: setTooltip});
|
|
|
|
|
|
|
|
return that;
|
|
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
// 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
|
|
|
|
),
|
|
|
|
oxid;
|
2014-09-22 15:38:37 +00:00
|
|
|
// If exactly one $element of an Ox Element was returned, then
|
|
|
|
// return the Ox Element instead, so that we can do
|
|
|
|
// oxObj.jqFn().oxFn()
|
2014-09-22 14:56:54 +00:00
|
|
|
return $element && $element.jquery && $element.length == 1
|
|
|
|
&& Ox.elements[oxid = $element.data('oxid')]
|
|
|
|
? Ox.elements[oxid] : $element;
|
|
|
|
};
|
|
|
|
});
|
2011-04-22 22:03:10 +00:00
|
|
|
|
2011-10-01 02:21:55 +00:00
|
|
|
/*@
|
2012-06-30 10:29:06 +00:00
|
|
|
bindEvent <f> Adds event handler(s)
|
|
|
|
(callback) -> <o> This element
|
|
|
|
Adds a catch-all handler
|
|
|
|
(event, callback) -> <o> This element
|
|
|
|
Adds a handler for a single event
|
2011-10-01 02:21:55 +00:00
|
|
|
({event: callback, ...}) -> <o> This element
|
2013-12-07 14:49:41 +00:00
|
|
|
Adds handlers for one or more events
|
2011-10-01 02:21:55 +00:00
|
|
|
callback <f> Callback function
|
|
|
|
data <o> event data (key/value pairs)
|
|
|
|
event <s> Event name
|
2012-06-02 11:06:44 +00:00
|
|
|
Event names can be namespaced, like `'click.foo'`
|
2011-10-01 02:21:55 +00:00
|
|
|
@*/
|
2014-09-22 14:56:54 +00:00
|
|
|
Ox.Element.prototype.bindEvent = function bindEvent() {
|
|
|
|
var self = this.self(_);
|
2012-06-30 09:24:38 +00:00
|
|
|
Ox.Event.bind.apply(null, [self].concat(Ox.slice(arguments)));
|
2014-09-22 14:56:54 +00:00
|
|
|
return this;
|
2012-01-19 12:29:29 +00:00
|
|
|
};
|
2011-04-22 22:03:10 +00:00
|
|
|
|
2011-10-01 02:21:55 +00:00
|
|
|
/*@
|
2012-06-30 10:29:06 +00:00
|
|
|
bindEventOnce <f> Adds event handler(s) that run(s) only once
|
|
|
|
(callback) -> <o> This element
|
|
|
|
Adds a catch-all handler
|
|
|
|
(event, callback) -> <o> This element
|
|
|
|
Adds a handler for a single event
|
|
|
|
({event: callback, ...}) -> <o> This element
|
2013-12-07 14:49:41 +00:00
|
|
|
Adds handlers for one or more events
|
2011-10-01 02:21:55 +00:00
|
|
|
callback <f> Callback function
|
|
|
|
data <o> event data (key/value pairs)
|
|
|
|
event <s> Event name
|
2012-06-02 11:06:44 +00:00
|
|
|
Event names can be namespaced, like `'click.foo'`
|
2011-10-01 02:21:55 +00:00
|
|
|
@*/
|
2014-09-22 14:56:54 +00:00
|
|
|
Ox.Element.prototype.bindEventOnce = function bindEventOnce() {
|
|
|
|
var self = this.self(_);
|
2012-06-30 09:24:38 +00:00
|
|
|
Ox.Event.bindOnce.apply(null, [self].concat(Ox.slice(arguments)));
|
2014-09-22 14:56:54 +00:00
|
|
|
return this;
|
2011-10-01 02:21:55 +00:00
|
|
|
};
|
2011-04-22 22:03:10 +00:00
|
|
|
|
2013-12-07 14:49:41 +00:00
|
|
|
/*@
|
|
|
|
bindMessage <f> Adds message handlers (if the element is an iframe)
|
|
|
|
(callback) -> <o> This element
|
|
|
|
Adds a catch-all handler
|
|
|
|
(event, callback) -> <o> This element
|
|
|
|
Adds a handler for a single event
|
|
|
|
({event: callback, ...}) -> <o> This element
|
|
|
|
Adds handlers for on or more events
|
|
|
|
callback <f> Callback function
|
|
|
|
data <o> event data (key/value pairs)
|
|
|
|
event <s> Event name
|
|
|
|
@*/
|
2014-09-22 14:56:54 +00:00
|
|
|
Ox.Element.prototype.bindMessage = Ox.Element.prototype.onMessage = function bindMessage() {
|
|
|
|
var self = this.self(_);
|
|
|
|
var that = this;
|
2013-12-07 14:49:41 +00:00
|
|
|
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 || {});
|
|
|
|
}
|
|
|
|
});
|
|
|
|
}
|
|
|
|
}
|
2014-09-22 14:56:54 +00:00
|
|
|
return this;
|
2013-12-07 14:49:41 +00:00
|
|
|
};
|
|
|
|
|
2014-09-22 14:56:54 +00:00
|
|
|
Ox.Element.prototype.bindMessageOnce = function bindMessageOnce() {
|
|
|
|
|
2013-12-07 14:49:41 +00:00
|
|
|
};
|
|
|
|
|
2012-05-21 10:38:18 +00:00
|
|
|
/*@
|
|
|
|
bindKeyboard <f> bind keyboard
|
|
|
|
() -> <o> object
|
|
|
|
@*/
|
2014-09-22 14:56:54 +00:00
|
|
|
Ox.Element.prototype.bindKeyboard = function bindKeyboard() {
|
|
|
|
Ox.Keyboard.bind(this.oxid);
|
|
|
|
return this;
|
2011-11-01 11:49:46 +00:00
|
|
|
};
|
|
|
|
|
2014-09-22 14:56:54 +00:00
|
|
|
Ox.Element.prototype.childrenElements = function childrenElements() {
|
|
|
|
return this.children().filter(Ox.UI.isOxElement).map(Ox.UI.getOxElement);
|
2013-12-06 19:51:59 +00:00
|
|
|
};
|
|
|
|
|
2011-10-01 02:21:55 +00:00
|
|
|
/*@
|
2011-12-21 13:42:47 +00:00
|
|
|
defaults <function> Gets or sets the default options for an element object
|
2012-06-22 23:54:33 +00:00
|
|
|
({key: value, ...}) -> <obj> This element object
|
|
|
|
key <str> The name of the default option
|
|
|
|
value <*> The value of the default option
|
2011-10-01 02:21:55 +00:00
|
|
|
@*/
|
2014-09-22 14:56:54 +00:00
|
|
|
Ox.Element.prototype.defaults = function defaults() {
|
|
|
|
var self = this.self(_);
|
2011-12-21 13:42:47 +00:00
|
|
|
var ret;
|
|
|
|
if (arguments.length == 0) {
|
|
|
|
ret = self.defaults;
|
|
|
|
} else if (Ox.isString(arguments[0])) {
|
|
|
|
ret = self.defaults[arguments[0]];
|
|
|
|
} else {
|
|
|
|
self.defaults = arguments[0];
|
|
|
|
self.options = Ox.clone(self.defaults);
|
2014-09-22 14:56:54 +00:00
|
|
|
ret = this;
|
2011-12-21 13:42:47 +00:00
|
|
|
}
|
|
|
|
return ret;
|
2011-10-01 02:21:55 +00:00
|
|
|
};
|
2011-05-05 18:02:56 +00:00
|
|
|
|
2014-09-22 14:56:54 +00:00
|
|
|
Ox.Element.prototype.findElements = function findElements() {
|
|
|
|
return Ox.map(this.find('.OxElement'), Ox.UI.getOxElement);
|
2013-12-06 19:51:59 +00:00
|
|
|
};
|
|
|
|
|
2014-09-22 14:56:54 +00:00
|
|
|
/*
|
|
|
|
Ox.Element.prototype.forEach = function forEach() {
|
|
|
|
// TODO
|
2014-08-21 15:13:05 +00:00
|
|
|
};
|
2014-09-22 14:56:54 +00:00
|
|
|
*/
|
2014-08-21 15:13:05 +00:00
|
|
|
|
2011-10-01 02:21:55 +00:00
|
|
|
/*@
|
|
|
|
gainFocus <function> Makes an element object gain focus
|
|
|
|
() -> <obj> This element object
|
|
|
|
@*/
|
2014-09-22 14:56:54 +00:00
|
|
|
Ox.Element.prototype.gainFocus = function gainFocus() {
|
|
|
|
Ox.Focus.focus(this.oxid);
|
|
|
|
return this;
|
2011-10-01 02:21:55 +00:00
|
|
|
};
|
2011-04-22 22:03:10 +00:00
|
|
|
|
2011-10-01 02:21:55 +00:00
|
|
|
/*@
|
|
|
|
hasFocus <function> Returns true if an element object has focus
|
|
|
|
() -> <boolean> True if the element has focus
|
|
|
|
@*/
|
2014-09-22 14:56:54 +00:00
|
|
|
Ox.Element.prototype.hasFocus = function hasFocus() {
|
|
|
|
return Ox.Focus.focused() == this.oxid;
|
2011-10-01 02:21:55 +00:00
|
|
|
};
|
2011-05-05 18:02:56 +00:00
|
|
|
|
2011-10-01 02:21:55 +00:00
|
|
|
/*@
|
|
|
|
loseFocus <function> Makes an element object lose focus
|
|
|
|
() -> <object> This element object
|
|
|
|
@*/
|
2014-09-22 14:56:54 +00:00
|
|
|
Ox.Element.prototype.loseFocus = function loseFocus() {
|
|
|
|
Ox.Focus.blur(this.oxid);
|
|
|
|
return this;
|
2011-10-01 02:21:55 +00:00
|
|
|
};
|
2011-04-22 22:03:10 +00:00
|
|
|
|
2014-09-22 14:56:54 +00:00
|
|
|
Ox.Element.prototype.nextElement = function nextElement() {
|
|
|
|
return this.nextElements()[0];
|
2013-12-06 19:51:59 +00:00
|
|
|
};
|
|
|
|
|
2014-09-22 14:56:54 +00:00
|
|
|
Ox.Element.prototype.nextElements = function nextElements() {
|
|
|
|
return this.nextAll().filter(Ox.UI.isOxElement).map(Ox.UI.getOxElement);
|
2013-12-06 19:51:59 +00:00
|
|
|
};
|
|
|
|
|
2011-10-01 02:21:55 +00:00
|
|
|
/*@
|
2012-06-02 10:37:19 +00:00
|
|
|
options <f> Gets or sets the options of an element object
|
2012-07-02 11:28:42 +00:00
|
|
|
() -> <o> All options
|
|
|
|
(key) -> <*> The value of option[key]
|
|
|
|
(key, value) -> <o> This element
|
2012-05-28 19:35:41 +00:00
|
|
|
Sets options[key] to value and calls update(key, value)
|
2011-10-01 02:21:55 +00:00
|
|
|
if the key/value pair was added or modified
|
2012-07-02 11:28:42 +00:00
|
|
|
({key: value, ...}) -> <o> This element
|
2013-12-07 14:49:41 +00:00
|
|
|
Sets one or more options and calls update(key, value)
|
2011-10-01 02:21:55 +00:00
|
|
|
for every key/value pair that was added or modified
|
2012-07-02 11:28:42 +00:00
|
|
|
key <s> The name of the option
|
|
|
|
value <*> The value of the option
|
2011-10-01 02:21:55 +00:00
|
|
|
@*/
|
2014-09-22 14:56:54 +00:00
|
|
|
Ox.Element.prototype.options = function options() {
|
|
|
|
var self = this.self(_);
|
|
|
|
return Ox.getset(self.options, arguments, self.update, this);
|
2011-10-01 02:21:55 +00:00
|
|
|
};
|
|
|
|
|
2014-09-22 14:56:54 +00:00
|
|
|
Ox.Element.prototype.parentElement = function parentElement() {
|
|
|
|
return Ox.last(this.parentElements());
|
2013-12-06 19:51:59 +00:00
|
|
|
};
|
|
|
|
|
2014-09-22 14:56:54 +00:00
|
|
|
Ox.Element.prototype.parentElements = function parentElements() {
|
|
|
|
return this.parents().filter(Ox.UI.isOxElement).map(Ox.UI.getOxElement);
|
2013-12-06 19:51:59 +00:00
|
|
|
};
|
|
|
|
|
2013-02-24 10:57:37 +00:00
|
|
|
/*@
|
|
|
|
postMessage <f> Sends a message (if the element is an iframe)
|
|
|
|
(event, data) -> This element
|
|
|
|
event <s> Event name
|
|
|
|
data <o> Event data
|
|
|
|
@*/
|
2014-09-22 14:56:54 +00:00
|
|
|
Ox.Element.prototype.postMessage = function postMessage(event, data) {
|
|
|
|
var self = this.self(_);
|
2013-02-24 10:57:37 +00:00
|
|
|
if (self.options.element == '<iframe>') {
|
2014-09-22 14:56:54 +00:00
|
|
|
Ox.Message.post(this, event, data);
|
2013-02-24 10:57:37 +00:00
|
|
|
}
|
2014-09-22 14:56:54 +00:00
|
|
|
return this;
|
2013-02-24 10:57:37 +00:00
|
|
|
};
|
|
|
|
|
2014-09-22 14:56:54 +00:00
|
|
|
Ox.Element.prototype.prevElement = function prevElement() {
|
|
|
|
return Ox.last(this.prevElements());
|
2013-12-06 19:51:59 +00:00
|
|
|
};
|
|
|
|
|
2014-09-22 14:56:54 +00:00
|
|
|
Ox.Element.prototype.prevElements = function prevElements() {
|
|
|
|
return this.prevAll().filter(Ox.UI.isOxElement).map(Ox.UI.getOxElement);
|
2013-12-06 19:51:59 +00:00
|
|
|
};
|
|
|
|
|
2011-10-01 02:21:55 +00:00
|
|
|
/*@
|
2013-12-06 19:51:59 +00:00
|
|
|
remove <f> Removes an element object and its event handler
|
2012-06-02 10:37:19 +00:00
|
|
|
() -> <o> This element
|
2011-10-01 02:21:55 +00:00
|
|
|
@*/
|
2014-09-22 14:56:54 +00:00
|
|
|
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;
|
2011-10-01 02:21:55 +00:00
|
|
|
};
|
|
|
|
|
2013-12-06 19:51:59 +00:00
|
|
|
/*
|
2014-09-22 14:56:54 +00:00
|
|
|
Ox.Element.prototype.remove = function() {
|
2013-12-06 19:51:59 +00:00
|
|
|
[that].concat(that.find('.OxElement'))
|
|
|
|
.map(Ox.UI.getOxElement).forEach(function($element) {
|
|
|
|
$element.removeElement();
|
|
|
|
});
|
|
|
|
that[0].parentNode.removeChild(this[0]);
|
|
|
|
return that;
|
|
|
|
}
|
|
|
|
|
2014-09-22 14:56:54 +00:00
|
|
|
Ox.Element.prototype.removeElement = function() {
|
2013-12-06 19:51:59 +00:00
|
|
|
delete Ox.$elements[that.oxid];
|
|
|
|
Ox.Focus.remove(that);
|
|
|
|
self.unbindKeyboard();
|
|
|
|
return that;
|
|
|
|
};
|
|
|
|
*/
|
|
|
|
|
2012-05-21 10:38:18 +00:00
|
|
|
/*@
|
|
|
|
setElement <f> set $element
|
2012-06-02 10:00:52 +00:00
|
|
|
($element) -> <o> This element
|
2012-05-21 10:38:18 +00:00
|
|
|
@*/
|
2014-09-22 14:56:54 +00:00
|
|
|
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]];
|
|
|
|
return this;
|
2011-12-21 13:42:47 +00:00
|
|
|
};
|
|
|
|
|
2012-05-21 10:38:18 +00:00
|
|
|
/*@
|
2012-06-02 10:00:52 +00:00
|
|
|
toggleOption <f> Toggle boolean option(s)
|
|
|
|
(key[, key[, ...]]) -> <o> This element
|
2012-05-21 10:38:18 +00:00
|
|
|
@*/
|
2014-09-22 14:56:54 +00:00
|
|
|
Ox.Element.prototype.toggleOption = function toggleOption() {
|
|
|
|
var self = this.self(_);
|
2011-12-21 13:42:47 +00:00
|
|
|
var options = {};
|
2013-12-01 13:57:52 +00:00
|
|
|
Ox.slice(arguments).forEach(function(key) {
|
2011-12-21 13:42:47 +00:00
|
|
|
options[key] == !self.options[key];
|
|
|
|
});
|
2014-09-22 14:56:54 +00:00
|
|
|
this.options(options);
|
|
|
|
return this;
|
2011-12-21 13:42:47 +00:00
|
|
|
};
|
|
|
|
|
2011-10-01 02:21:55 +00:00
|
|
|
/*@
|
2012-06-30 10:29:06 +00:00
|
|
|
triggerEvent <f> Triggers one or more events
|
|
|
|
(event) -> <o> This element object
|
|
|
|
Triggers an event
|
|
|
|
(event, data) -> <o> This element object
|
|
|
|
Triggers an event with data
|
|
|
|
({event: data, ...}) -> <o> This element object
|
2013-12-07 14:49:41 +00:00
|
|
|
Triggers one or more events with data
|
2011-10-01 02:21:55 +00:00
|
|
|
event <string> Event name
|
|
|
|
data <object> Event data (key/value pairs)
|
|
|
|
@*/
|
2014-09-22 14:56:54 +00:00
|
|
|
Ox.Element.prototype.triggerEvent = function triggerEvent() {
|
|
|
|
var self = this.self(_);
|
|
|
|
Ox.Event.trigger.apply(this, [self].concat(Ox.slice(arguments)));
|
|
|
|
return this;
|
2011-10-01 02:21:55 +00:00
|
|
|
};
|
2011-04-22 22:03:10 +00:00
|
|
|
|
2014-09-22 14:56:54 +00:00
|
|
|
Ox.Element.prototype.triggerMessage = function triggerMessage() {
|
|
|
|
|
2013-12-07 14:49:41 +00:00
|
|
|
};
|
|
|
|
|
2011-10-01 02:21:55 +00:00
|
|
|
/*@
|
2012-06-30 10:29:06 +00:00
|
|
|
unbindEvent <f> Removes event handler(s)
|
|
|
|
() -> <o> This element
|
|
|
|
Removes all handlers.
|
2012-05-28 14:02:25 +00:00
|
|
|
(callback) -> <o> This element
|
2012-06-30 10:29:06 +00:00
|
|
|
Removes a specific catch-all handler
|
2012-05-28 14:02:25 +00:00
|
|
|
(event) -> <o> This element
|
2012-06-30 10:29:06 +00:00
|
|
|
Removes all handlers for a single event (to remove all catch-all
|
|
|
|
handlers, pass '*' as event)
|
2012-05-28 14:02:25 +00:00
|
|
|
(event, callback) -> <o> This element
|
2012-06-30 10:29:06 +00:00
|
|
|
Removes a specific handler for a single event
|
2012-05-28 14:02:25 +00:00
|
|
|
({event: callback}, ...) -> <o> This element
|
2013-12-07 14:49:41 +00:00
|
|
|
Removes specific handlers for one or more events
|
2011-10-01 02:21:55 +00:00
|
|
|
event <string> Event name
|
|
|
|
@*/
|
2014-09-22 14:56:54 +00:00
|
|
|
Ox.Element.prototype.unbindEvent = function unbindEvent() {
|
|
|
|
var self = this.self(_);
|
2012-06-30 09:24:38 +00:00
|
|
|
Ox.Event.unbind.apply(null, [self].concat(Ox.slice(arguments)));
|
2014-09-22 14:56:54 +00:00
|
|
|
return this;
|
2011-10-01 02:21:55 +00:00
|
|
|
};
|
|
|
|
|
2014-09-22 14:56:54 +00:00
|
|
|
Ox.Element.prototype.unbindMessage = function unbindMessage() {
|
|
|
|
|
2013-12-07 14:49:41 +00:00
|
|
|
};
|
|
|
|
|
2012-05-21 10:38:18 +00:00
|
|
|
/*@
|
|
|
|
unbindKeyboard <f> unbind keyboard
|
|
|
|
() -> <o> object
|
|
|
|
@*/
|
2014-09-22 14:56:54 +00:00
|
|
|
Ox.Element.prototype.unbindKeyboard = function unbindKeyboard() {
|
|
|
|
Ox.Keyboard.unbind(this.oxid);
|
|
|
|
return this;
|
2011-11-01 11:49:46 +00:00
|
|
|
};
|
|
|
|
|
2012-05-28 16:16:23 +00:00
|
|
|
/*@
|
|
|
|
update <f> Adds one or more handlers for options updates
|
|
|
|
(callback) -> <o> that
|
|
|
|
(key, callback) -> <o> that
|
|
|
|
({key: callback, ...}) -> <o> that
|
|
|
|
@*/
|
2014-09-22 14:56:54 +00:00
|
|
|
Ox.Element.prototype.update = function update() {
|
|
|
|
var self = this.self(_);
|
2012-05-28 16:16:23 +00:00
|
|
|
var callbacks;
|
2012-06-25 14:32:16 +00:00
|
|
|
if (Ox.isFunction(arguments[0])) {
|
2012-05-28 16:16:23 +00:00
|
|
|
self.updateCallbacks.push(arguments[0]);
|
|
|
|
} else {
|
|
|
|
callbacks = Ox.makeObject(arguments);
|
|
|
|
self.updateCallbacks.push(function(key) {
|
|
|
|
if (callbacks[key]) {
|
|
|
|
return callbacks[key]();
|
|
|
|
}
|
|
|
|
});
|
|
|
|
}
|
2014-09-22 14:56:54 +00:00
|
|
|
return this;
|
2012-05-28 16:16:23 +00:00
|
|
|
};
|
|
|
|
|
2011-12-21 15:33:52 +00:00
|
|
|
/*@
|
|
|
|
value <f> Shortcut to get or set self.options.value
|
|
|
|
@*/
|
2014-09-22 14:56:54 +00:00
|
|
|
Ox.Element.prototype.value = function value() {
|
|
|
|
return this.options(
|
2011-12-21 15:33:52 +00:00
|
|
|
arguments.length == 0 ? 'value' : {value: arguments[0]}
|
|
|
|
);
|
|
|
|
};
|
|
|
|
|
2014-09-22 14:56:54 +00:00
|
|
|
}({}));
|
2011-04-22 22:03:10 +00:00
|
|
|
|