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
// check out http://ejohn.org/apps/learn/#36 (-#38, making fns work w/o new)
/*@
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) {
fn(Ox.extend({
callback(Ox.extend({
_element: that.$element,
_event: event
}, data));
@ -236,11 +235,10 @@ Ox.Element = function(options, self) {
data <o> event data (key/value pairs)
event <s> Event name
Event names can be namespaced, like <code>'click.foo'</code>
@*/
that.bindEvent = function() {
Ox.forEach(Ox.makeObject(arguments), function(fn, event) {
bind('bind', event, fn);
Ox.forEach(Ox.makeObject(arguments), function(callback, event) {
bind('bind', event, callback);
});
return that;
}
@ -255,8 +253,8 @@ Ox.Element = function(options, self) {
Event names can be namespaced, like <code>'click.foo'</code>
@*/
that.bindEventOnce = function() {
Ox.forEach(Ox.makeObject(arguments), function(fn, event) {
bind('one', event, fn);
Ox.forEach(Ox.makeObject(arguments), function(callback, event) {
bind('one', event, callback);
});
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)
self.previousURL = '';
function constructCondition(condition) {
var key = condition.key == '*' ? '' : condition.key,
operator = condition.operator,
@ -200,13 +202,15 @@ Ox.URL = function(options) {
}
function constructSort(sort, state) {
var sortKeys = self.options.sortKeys[state.type][
!state.item ? 'list' : 'item'
][state.view];
return sort.map(function(sort) {
return (
sort.operator == Ox.getObjectById(self.options.sortKeys[state.type][
!state.item ? 'list' : 'item'
][state.view], sort.key).operator ? '' : sort.operator
Ox.getObjectById(sortKeys, sort.key).operator == sort.operator
? '' : sort.operator
) + sort.key;
}).join(',')
}).join(',');
}
function constructSpan(span, state) {
@ -233,7 +237,7 @@ Ox.URL = function(options) {
if (state.item) {
parts.push(state.item);
}
if (self.options.views[state.type][
if (state.type && self.options.views[state.type][
state.item ? 'item' : 'list'
].indexOf(state.view) > -1) {
parts.push(state.view);
@ -256,7 +260,8 @@ Ox.URL = function(options) {
}
function encodeValue(str) {
var chars = '/&|()=*:';
// var chars = '/&|()=*:';
var chars = '&|()=*';
ret = '';
str.split('').forEach(function(char) {
var index = chars.indexOf(char);
@ -320,7 +325,7 @@ Ox.URL = function(options) {
}
}
if (condition.value.indexOf(':') > -1) {
condition.value = condition.value.split(':').map(decodeValue);
condition.value = condition.value.split(':').map(decodeValue).join(':');
} else {
condition.value = decodeValue(condition.value);
}
@ -410,12 +415,14 @@ Ox.URL = function(options) {
}
function parseURL(str, callback) {
Ox.print('pU', str)
var parts = str.substr(1).split('/'),
state = {};
if (parts.length == 0) {
state.page = '';
if (parts[0] == '') {
// empty URL
callback(state);
} else if (self.options.pages.indexOf(parts[0]) > -1) {
// page
state.page = parts[0];
callback(state);
} else {
@ -428,6 +435,7 @@ Ox.URL = function(options) {
state.type = self.options.types[0];
}
if (parts.length) {
Ox.print('ST', state.type, self.options.views)
if (self.options.views[state.type].list.indexOf(parts[0]) > -1) {
// list view
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) {
return constructURL(state);
};
@ -571,25 +585,50 @@ Ox.URL = function(options) {
+ document.location.search
+ document.location.hash,
callback = arguments[arguments.length - 1];
Ox.print(str, callback)
parseURL(str, callback);
parseURL(str, function(state) {
that.replace(constructURL(state));
callback(state);
});
return that;
}
/*@
pop <f> Sets the URL to the previous URL
@*/
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) {
saveURL();
history.replaceState({}, '', url);
return that;
};
that.update = function(state) {
// pushes a new URL, constructed from state
// state can have type, item, view, span, sort, find
that.push(constructURL(state));
return that;
};
return that;

View file

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

View file

@ -23,6 +23,7 @@ Ox.Select <f:Ox.Element> Select Object
Ox.Select = function(options, self) {
// fixme: make selected a separate option
// fixme: selected item needs attribute "checked", not "selected" ... that's strange
self = self || {};
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
@*/
that.selected = function() {

View file

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