update Ox.URL, add Ox.Event

This commit is contained in:
rlx 2011-09-23 10:43:57 +00:00
parent 738f734bde
commit f2c8644001
6 changed files with 166 additions and 33 deletions

View file

@ -1,5 +1,4 @@
// vim: et:ts=4:sw=4:sts=4:ft=javascript // vim: et:ts=4:sw=4:sts=4:ft=javascript
// check out http://ejohn.org/apps/learn/#36 (-#38, making fns work w/o new)
/*@ /*@
Ox.Element <function:Ox.JQueryElement> Basic UI element object Ox.Element <function:Ox.JQueryElement> Basic UI element object
@ -99,9 +98,9 @@ Ox.Element = function(options, self) {
}); });
} }
function bind(action, event, fn) { function bind(action, event, callback) {
self.$eventHandler[action]('ox_' + event, function(event, data) { self.$eventHandler[action]('ox_' + event, function(event, data) {
fn(Ox.extend({ callback(Ox.extend({
_element: that.$element, _element: that.$element,
_event: event _event: event
}, data)); }, data));
@ -236,11 +235,10 @@ Ox.Element = function(options, self) {
data <o> event data (key/value pairs) data <o> event data (key/value pairs)
event <s> Event name event <s> Event name
Event names can be namespaced, like <code>'click.foo'</code> Event names can be namespaced, like <code>'click.foo'</code>
@*/ @*/
that.bindEvent = function() { that.bindEvent = function() {
Ox.forEach(Ox.makeObject(arguments), function(fn, event) { Ox.forEach(Ox.makeObject(arguments), function(callback, event) {
bind('bind', event, fn); bind('bind', event, callback);
}); });
return that; return that;
} }
@ -255,8 +253,8 @@ Ox.Element = function(options, self) {
Event names can be namespaced, like <code>'click.foo'</code> Event names can be namespaced, like <code>'click.foo'</code>
@*/ @*/
that.bindEventOnce = function() { that.bindEventOnce = function() {
Ox.forEach(Ox.makeObject(arguments), function(fn, event) { Ox.forEach(Ox.makeObject(arguments), function(callback, event) {
bind('one', event, fn); bind('one', event, callback);
}); });
return that; return that;
}; };

View file

@ -0,0 +1,91 @@
/*@
Ox.Event <o> Basic event handler
@*/
Ox.Event = (function() {
var self = {}, that = {};
self.$eventHandler = $('<div>');
/*@
bind <f> Binds a callback to an event
(event, callback) -> <o> The event handler
({event: callback, ...}) -> <o> The event handler
callback <f> Callback function
data <*> Event data
event <s> Event name
Event names can be namespaced, like <code>'click.foo'</code>
@*/
that.bind = function() {
Ox.forEach(Ox.makeObject(arguments), function(callback, event) {
self.$eventHandler.bind('ox_' + event, function(event, data) {
callback(data.value);
});
});
return that;
};
/*@
bindOnce <f> Binds a callback to an event, once
(event, callback) -> <o> The event handler
({event: callback, ...}) -> <o> The event handler
callback <f> Callback function
data <*> Event data
event <s> Event name
Event names can be namespaced, like <code>'click.foo'</code>
@*/
that.bindOnce = function() {
Ox.forEach(Ox.makeObject(arguments), function(callback, event) {
self.$eventHandler.one('ox_' + event, function(event, data) {
callback(data.value);
});
});
return that;
};
/*@
trigger <function> Triggers an event
(event) -> <o> The event handler
(event, data) -> <o> The event handler
({event: data, ...}) -> <o> The event handler
event <s> Event name
data <*> Event data
@*/
that.trigger = function() {
Ox.forEach(Ox.makeObject(arguments), function(data, event) {
Ox.print('Ox.Event.trigger', event, data)
self.$eventHandler.trigger('ox_' + event, {value: data});
});
return that;
};
/*@
unbind <f> Unbinds all callbacks from an event
To unbind a specific handler, use namespaced events, like
<code>bind('click.foo', callback)</code>, and then
<code>unbind('click.foo')</code>.
() -> <o> The event handler
Unbinds all events
(event) -> <o> The event handler
Unbinds one event
(event, event, ...) -> <o> The event handler
Unbinds multiple events
([event, event, ...]) -> <o> The event handler
Unbinds multiple events
event <s> Event name
@*/
that.unbind = function() {
if (arguments.length == 0) {
self.$eventHandler.unbind();
} else {
Ox.makeArray(arguments).forEach(function(event) {
self.$eventHandler.unbind('ox_' + event);
});
}
return that;
};
return that;
}());

View file

@ -157,6 +157,8 @@ Ox.URL = function(options) {
Ox.print('Ox.URL options', self.options) Ox.print('Ox.URL options', self.options)
self.previousURL = '';
function constructCondition(condition) { function constructCondition(condition) {
var key = condition.key == '*' ? '' : condition.key, var key = condition.key == '*' ? '' : condition.key,
operator = condition.operator, operator = condition.operator,
@ -200,13 +202,15 @@ Ox.URL = function(options) {
} }
function constructSort(sort, state) { function constructSort(sort, state) {
var sortKeys = self.options.sortKeys[state.type][
!state.item ? 'list' : 'item'
][state.view];
return sort.map(function(sort) { return sort.map(function(sort) {
return ( return (
sort.operator == Ox.getObjectById(self.options.sortKeys[state.type][ Ox.getObjectById(sortKeys, sort.key).operator == sort.operator
!state.item ? 'list' : 'item' ? '' : sort.operator
][state.view], sort.key).operator ? '' : sort.operator
) + sort.key; ) + sort.key;
}).join(',') }).join(',');
} }
function constructSpan(span, state) { function constructSpan(span, state) {
@ -233,7 +237,7 @@ Ox.URL = function(options) {
if (state.item) { if (state.item) {
parts.push(state.item); parts.push(state.item);
} }
if (self.options.views[state.type][ if (state.type && self.options.views[state.type][
state.item ? 'item' : 'list' state.item ? 'item' : 'list'
].indexOf(state.view) > -1) { ].indexOf(state.view) > -1) {
parts.push(state.view); parts.push(state.view);
@ -256,7 +260,8 @@ Ox.URL = function(options) {
} }
function encodeValue(str) { function encodeValue(str) {
var chars = '/&|()=*:'; // var chars = '/&|()=*:';
var chars = '&|()=*';
ret = ''; ret = '';
str.split('').forEach(function(char) { str.split('').forEach(function(char) {
var index = chars.indexOf(char); var index = chars.indexOf(char);
@ -320,7 +325,7 @@ Ox.URL = function(options) {
} }
} }
if (condition.value.indexOf(':') > -1) { if (condition.value.indexOf(':') > -1) {
condition.value = condition.value.split(':').map(decodeValue); condition.value = condition.value.split(':').map(decodeValue).join(':');
} else { } else {
condition.value = decodeValue(condition.value); condition.value = decodeValue(condition.value);
} }
@ -410,12 +415,14 @@ Ox.URL = function(options) {
} }
function parseURL(str, callback) { function parseURL(str, callback) {
Ox.print('pU', str)
var parts = str.substr(1).split('/'), var parts = str.substr(1).split('/'),
state = {}; state = {};
if (parts.length == 0) { if (parts[0] == '') {
state.page = ''; // empty URL
callback(state); callback(state);
} else if (self.options.pages.indexOf(parts[0]) > -1) { } else if (self.options.pages.indexOf(parts[0]) > -1) {
// page
state.page = parts[0]; state.page = parts[0];
callback(state); callback(state);
} else { } else {
@ -428,6 +435,7 @@ Ox.URL = function(options) {
state.type = self.options.types[0]; state.type = self.options.types[0];
} }
if (parts.length) { if (parts.length) {
Ox.print('ST', state.type, self.options.views)
if (self.options.views[state.type].list.indexOf(parts[0]) > -1) { if (self.options.views[state.type].list.indexOf(parts[0]) > -1) {
// list view // list view
state.item = ''; state.item = '';
@ -561,6 +569,12 @@ Ox.URL = function(options) {
} }
} }
function saveURL() {
self.previousURL = document.location.pathname
+ document.location.search
+ document.location.hash;
}
that._construct = function(state) { that._construct = function(state) {
return constructURL(state); return constructURL(state);
}; };
@ -571,25 +585,50 @@ Ox.URL = function(options) {
+ document.location.search + document.location.search
+ document.location.hash, + document.location.hash,
callback = arguments[arguments.length - 1]; callback = arguments[arguments.length - 1];
Ox.print(str, callback) parseURL(str, function(state) {
parseURL(str, callback); that.replace(constructURL(state));
callback(state);
});
return that;
} }
/*@
pop <f> Sets the URL to the previous URL
@*/
that.pop = function() { that.pop = function() {
history.pushState(self.previousURL);
return that;
}; };
that.push = function(url) { /*@
push <f> Pushes a new URL
(url, callback) -> <o> URL controller
(state) -> <o> URL controller
url <s> New URL
callback <f> callback function
state <o> New state
state <o> State to construct the new URL from
@*/
that.push = function(url, callback) {
url = callback ? url : constructURL(url);
saveURL();
Ox.print('PUSH', url);
history.pushState({}, '', url);
callback && parseURL(url, callback);
return that;
}; };
that.replace = function(url) { that.replace = function(url) {
saveURL();
history.replaceState({}, '', url);
return that;
}; };
that.update = function(state) { that.update = function(state) {
// pushes a new URL, constructed from state // pushes a new URL, constructed from state
// state can have type, item, view, span, sort, find // state can have type, item, view, span, sort, find
that.push(constructURL(state));
return that;
}; };
return that; return that;

View file

@ -1,12 +1,12 @@
// vim: et:ts=4:sw=4:sts=4:ft=javascript // vim: et:ts=4:sw=4:sts=4:ft=javascript
/*@ /*@
Ox.Filter <f:Ox.Element> Filter Element Ox.Filter <o> Filter Object
() -> <f> Filter Element () -> <f> Filter Object
(options) -> <f> Filter Element (options) -> <f> Filter Object
(options, self) -> <f> Filter Element (options, self) -> <f> Filter Object
options <o> Options object options <o> Options object
findKeys <a|[]> keys findKeys <[]|[]> keys
list <o> list object list <o> list object
sort <s> List sort sort <s> List sort
view <s> List view view <s> List view
@ -69,8 +69,8 @@ Ox.Filter = function(options, self) {
{id: '!<', title: 'is not less than'}, {id: '!<', title: 'is not less than'},
{id: '>', title: 'is greater than'}, {id: '>', title: 'is greater than'},
{id: '!>', title: 'is not greater than'}, {id: '!>', title: 'is not greater than'},
{id: '-', title: 'is between'}, {id: '=:', title: 'is between'},
{id: '!-', title: 'is not between'}/*, {id: '!=:', title: 'is not between'}/*,
{id: '^', title: 'starts with'}, {id: '^', title: 'starts with'},
{id: '!^', title: 'does not start with'}, {id: '!^', title: 'does not start with'},
{id: '$', title: 'ends with'}, {id: '$', title: 'ends with'},
@ -318,13 +318,15 @@ Ox.Filter = function(options, self) {
var condition = subpos == -1 var condition = subpos == -1
? self.options.query.conditions[pos] ? self.options.query.conditions[pos]
: self.options.query.conditions[pos].conditions[subpos], : self.options.query.conditions[pos].conditions[subpos],
isBetween = operator.indexOf('-') > -1,
oldOperator = condition.operator, oldOperator = condition.operator,
wasBetween = oldOperator.indexOf('-') > -1,
wasUselessCondition = isUselessCondition(pos, subpos); wasUselessCondition = isUselessCondition(pos, subpos);
condition.operator = operator; condition.operator = operator;
if (oldOperator.indexOf('-') == -1 && operator.indexOf('-') > -1) { if (isBetween && !wasBetween) {
condition.value = [condition.value, condition.value] condition.value = [condition.value, condition.value]
renderConditions(); renderConditions();
} else if (oldOperator.indexOf('-') > -1 && operator.indexOf('-') == -1) { } else if (!isBetween && wasBetween) {
condition.value = condition.value[0] condition.value = condition.value[0]
renderConditions(); renderConditions();
} }

View file

@ -23,6 +23,7 @@ Ox.Select <f:Ox.Element> Select Object
Ox.Select = function(options, self) { Ox.Select = function(options, self) {
// fixme: make selected a separate option
// fixme: selected item needs attribute "checked", not "selected" ... that's strange // fixme: selected item needs attribute "checked", not "selected" ... that's strange
self = self || {}; self = self || {};
var that = Ox.Element({ var that = Ox.Element({
@ -176,7 +177,7 @@ Ox.Select = function(options, self) {
}; };
/*@ /*@
selectItem <f> select item in group selected <f> gets selected item
() -> <o> returns object of selected items with id, title () -> <o> returns object of selected items with id, title
@*/ @*/
that.selected = function() { that.selected = function() {

View file

@ -119,8 +119,10 @@ Ox.VideoPreview = function(options, self) {
self.setOption = function(key, value) { self.setOption = function(key, value) {
if (key == 'height') { if (key == 'height') {
that.css({height: value + 'px'});
self.$frame.css(getFrameCSS()); self.$frame.css(getFrameCSS());
} else if (key == 'width') { } else if (key == 'width') {
that.css({width: value + 'px'});
self.$frame.attr({src: self.options.getFrame()}) self.$frame.attr({src: self.options.getFrame()})
.css(getFrameCSS()); .css(getFrameCSS());
self.$timeline.css({width: value + 'px'}); self.$timeline.css({width: value + 'px'});