forked from 0x2620/oxjs
better filesystem structure for modules and themes; 'minified' ui if debug option not set; dynamially generated map markers
This commit is contained in:
parent
358ee1bc96
commit
4489e88f44
596 changed files with 115093 additions and 17682 deletions
129
source/Ox.UI/js/Core/Ox.App.js
Normal file
129
source/Ox.UI/js/Core/Ox.App.js
Normal file
|
|
@ -0,0 +1,129 @@
|
|||
// vim: et:ts=4:sw=4:sts=4:ft=js
|
||||
/*
|
||||
============================================================================
|
||||
Application
|
||||
============================================================================
|
||||
*/
|
||||
|
||||
// fixme: get rid of launch, fire load event
|
||||
|
||||
Ox.App = (function() {
|
||||
|
||||
/***
|
||||
Ox.App
|
||||
Basic application instance that communicates with a JSON API.
|
||||
The JSON API must support at least the following actions:
|
||||
api returns all api methods
|
||||
init returns data (site, user, ...)
|
||||
Options
|
||||
timeout API timeout in msec
|
||||
type 'GET' or 'POST'
|
||||
url URL of the API
|
||||
Methods
|
||||
api[action] make a request
|
||||
api.cancel cancel a request
|
||||
options get or set options
|
||||
Events
|
||||
load app loaded
|
||||
***/
|
||||
|
||||
return function(options) {
|
||||
|
||||
options = options || {};
|
||||
var self = {
|
||||
options: Ox.extend({
|
||||
timeout: 60000,
|
||||
type: 'POST',
|
||||
url: '/api/',
|
||||
}, options || {}),
|
||||
time: new Date()
|
||||
},
|
||||
that = new Ox.Element({}, self);
|
||||
|
||||
that.api = {
|
||||
api: function(callback) {
|
||||
Ox.Request.send({
|
||||
url: self.options.url,
|
||||
data: {
|
||||
action: 'api'
|
||||
},
|
||||
callback: callback
|
||||
});
|
||||
},
|
||||
cancel: function(id) {
|
||||
Ox.Request.cancel(id);
|
||||
}
|
||||
};
|
||||
|
||||
$.ajaxSetup({
|
||||
timeout: self.options.timeout,
|
||||
type: self.options.type,
|
||||
url: self.options.url
|
||||
});
|
||||
|
||||
that.api.api(function(result) {
|
||||
Ox.forEach(result.data.actions, function(val, key) {
|
||||
that.api[key] = function(data, callback) {
|
||||
if (arguments.length == 1 && Ox.isFunction(data)) {
|
||||
callback = data;
|
||||
data = {};
|
||||
}
|
||||
return Ox.Request.send($.extend({
|
||||
url: self.options.url,
|
||||
data: {
|
||||
action: key,
|
||||
data: JSON.stringify(data)
|
||||
},
|
||||
callback: callback
|
||||
}, !val.cache ? {age: 0}: {}));
|
||||
};
|
||||
});
|
||||
that.api.init(getUserData(), function(result) {
|
||||
//Ox.UI.hideLoadingScreen();
|
||||
that.triggerEvent({
|
||||
load: result.data
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
function getUserData() {
|
||||
return {
|
||||
document: {
|
||||
referrer: document.referrer
|
||||
},
|
||||
history: {
|
||||
length: history.length
|
||||
},
|
||||
navigator: {
|
||||
cookieEnabled: navigator.cookieEnabled,
|
||||
plugins: $.map(navigator.plugins, function(plugin, i) {
|
||||
return plugin.name;
|
||||
}),
|
||||
userAgent: navigator.userAgent
|
||||
},
|
||||
screen: screen,
|
||||
time: (+new Date() - self.time) / 1000,
|
||||
window: {
|
||||
innerHeight: window.innerHeight,
|
||||
innerWidth: window.innerWidth,
|
||||
outerHeight: window.outerHeight,
|
||||
outerWidth: window.outerWidth,
|
||||
screenLeft: window.screenLeft,
|
||||
screenTop: window.screenTop
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
self.change = function(key, value) {
|
||||
|
||||
};
|
||||
|
||||
that.options = function() {
|
||||
return Ox.getset(self.options, Array.prototype.slice.call(arguments), self.change, that);
|
||||
};
|
||||
|
||||
return that;
|
||||
|
||||
};
|
||||
|
||||
}());
|
||||
23
source/Ox.UI/js/Core/Ox.Clipboard.js
Normal file
23
source/Ox.UI/js/Core/Ox.Clipboard.js
Normal file
|
|
@ -0,0 +1,23 @@
|
|||
// vim: et:ts=4:sw=4:sts=4:ft=js
|
||||
Ox.Clipboard = function() {
|
||||
/***
|
||||
Ox.Clipboard
|
||||
Basic clipboard handler
|
||||
Methods
|
||||
copy(data) copy data to clipboard
|
||||
paste paste data from clipboard
|
||||
***/
|
||||
var clipboard = {};
|
||||
return {
|
||||
_print: function() {
|
||||
Ox.print(JSON.stringify(clipboard));
|
||||
},
|
||||
copy: function(data) {
|
||||
clipboard = data;
|
||||
Ox.print('copy', JSON.stringify(clipboard));
|
||||
},
|
||||
paste: function(type) {
|
||||
return clipboard;
|
||||
}
|
||||
};
|
||||
}();
|
||||
17
source/Ox.UI/js/Core/Ox.Container.js
Normal file
17
source/Ox.UI/js/Core/Ox.Container.js
Normal file
|
|
@ -0,0 +1,17 @@
|
|||
// vim: et:ts=4:sw=4:sts=4:ft=js
|
||||
// fixme: wouldn't it be better to let the elements be,
|
||||
// rather then $element, $content, and potentially others,
|
||||
// 0, 1, 2, etc, so that append would append 0, and appendTo
|
||||
// would append (length - 1)?
|
||||
|
||||
Ox.Container = function(options, self) {
|
||||
// fixme: to be deprecated
|
||||
var that = new Ox.Element('div', self)
|
||||
.options(options || {})
|
||||
.addClass('OxContainer');
|
||||
that.$content = new Ox.Element('div', self)
|
||||
.options(options || {})
|
||||
.addClass('OxContent')
|
||||
.appendTo(that);
|
||||
return that;
|
||||
};
|
||||
325
source/Ox.UI/js/Core/Ox.Element.js
Normal file
325
source/Ox.UI/js/Core/Ox.Element.js
Normal file
|
|
@ -0,0 +1,325 @@
|
|||
// vim: et:ts=4:sw=4:sts=4:ft=js
|
||||
// check out http://ejohn.org/apps/learn/#36 (-#38, making fns work w/o new)
|
||||
|
||||
Ox.Element = function() {
|
||||
|
||||
/***
|
||||
Basic element object
|
||||
***/
|
||||
|
||||
/*
|
||||
tooltip option can be any of the following:
|
||||
string
|
||||
function(e), returns string
|
||||
{mousemove: true, title: function(e)}
|
||||
*/
|
||||
|
||||
return function(options, self) {
|
||||
|
||||
if (!(this instanceof arguments.callee)) {
|
||||
return new arguments.callee(options, self);
|
||||
}
|
||||
|
||||
self = self || {};
|
||||
self.options = options || {};
|
||||
// allow for Ox.Element('tagname', self)
|
||||
if (typeof self.options == 'string') {
|
||||
self.options = {
|
||||
element: self.options
|
||||
};
|
||||
}
|
||||
if (!self.$eventHandler) {
|
||||
self.$eventHandler = $('<div>');
|
||||
}
|
||||
|
||||
var that = new Ox.JQueryElement(
|
||||
$('<' + (self.options.element || 'div') + '>')
|
||||
)
|
||||
.mousedown(mousedown);
|
||||
|
||||
/*
|
||||
self.options.tooltip && that.bind(Ox.extend({
|
||||
mouseenter: mouseenter,
|
||||
mouseleave: mouseleave
|
||||
}, self.options.tooltip.mousemove ? {
|
||||
mousemove: mousemove
|
||||
} : {}));
|
||||
*/
|
||||
|
||||
function mousedown(e) {
|
||||
/*
|
||||
better mouse events
|
||||
mousedown:
|
||||
trigger mousedown
|
||||
within 250 msec:
|
||||
mouseup: trigger anyclick ("click" would collide with click events of certain widgets)
|
||||
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 within 250 msec:
|
||||
trigger dragpause
|
||||
mouseup: trigger dragend
|
||||
*/
|
||||
var clientX, clientY,
|
||||
dragTimeout = 0,
|
||||
mouseInterval = 0;
|
||||
if (!self.mouseTimeout) {
|
||||
// first mousedown
|
||||
that.triggerEvent('mousedown', e);
|
||||
self.mouseup = false;
|
||||
self.mouseTimeout = setTimeout(function() {
|
||||
self.mouseTimeout = 0;
|
||||
if (self.mouseup) {
|
||||
// singleclick
|
||||
that.triggerEvent('singleclick', e);
|
||||
} else {
|
||||
// mouserepeat, drag
|
||||
clientX = e.clientX;
|
||||
clientY = e.clientY;
|
||||
that.triggerEvent('dragstart', e);
|
||||
mouserepeat();
|
||||
mouseInterval = setInterval(mouserepeat, 50);
|
||||
Ox.UI.$window.unbind('mouseup', mouseup)
|
||||
.mousemove(mousemove)
|
||||
.one('mouseup', function(e) {
|
||||
clearInterval(mouseInterval);
|
||||
clearTimeout(dragTimeout);
|
||||
Ox.UI.$window.unbind('mousemove', mousemove);
|
||||
that.triggerEvent('dragend', extend(e));
|
||||
});
|
||||
that.one('mouseleave', function() {
|
||||
clearInterval(mouseInterval);
|
||||
});
|
||||
}
|
||||
}, 250);
|
||||
} else {
|
||||
// second mousedown
|
||||
clearTimeout(self.mouseTimeout);
|
||||
self.mouseTimeout = 0;
|
||||
that.triggerEvent('doubleclick', e);
|
||||
}
|
||||
Ox.UI.$window.one('mouseup', mouseup);
|
||||
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() {
|
||||
that.triggerEvent('dragpause', e);
|
||||
}, 250);
|
||||
that.triggerEvent('drag', e);
|
||||
}
|
||||
function mouserepeat() {
|
||||
that.triggerEvent('mouserepeat');
|
||||
}
|
||||
function mouseup(e) {
|
||||
// only trigger on firse mouseup
|
||||
if (!self.mouseup) {
|
||||
that.triggerEvent('anyclick', e);
|
||||
self.mouseup = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
function mouseenter(e) {
|
||||
self.$tooltip = new Ox.Tooltip({
|
||||
title: Ox.isString(self.options.tooltip) ?
|
||||
self.options.tooltip : Ox.isFunction(self.options.tooltip) ?
|
||||
self.options.tooltip(e) : self.options.tooltip.title(e)
|
||||
}).show();
|
||||
}
|
||||
|
||||
function mouseleave(e) {
|
||||
self.$tooltip.hide();
|
||||
}
|
||||
|
||||
function mousemove(e) {
|
||||
self.$tooltip.options({
|
||||
title: self.options.tooltip.title(e)
|
||||
});
|
||||
}
|
||||
*/
|
||||
|
||||
self.onChange = function() {
|
||||
// self.onChange(key, value)
|
||||
// is called when an option changes
|
||||
// (to be implemented by widget)
|
||||
// fixme: rename to self.setOption
|
||||
};
|
||||
|
||||
that._leakSelf = function() { // fixme: remove
|
||||
return self;
|
||||
}
|
||||
|
||||
that.bindEvent = function() {
|
||||
/***
|
||||
binds a function to an event triggered by this object
|
||||
Usage
|
||||
bindEvent(event, fn) or bindEvent({event0: fn0, event1: fn1, ...})
|
||||
***/
|
||||
if (arguments.length == 1) {
|
||||
Ox.forEach(arguments[0], function(fn, event) {
|
||||
// Ox.print(that.id, 'bind', event);
|
||||
self.$eventHandler.bind('ox_' + event, fn);
|
||||
});
|
||||
} else {
|
||||
// Ox.print(that.id, 'bind', arguments[0]);
|
||||
self.$eventHandler.bind('ox_' + arguments[0], arguments[1]);
|
||||
}
|
||||
return that;
|
||||
}
|
||||
|
||||
that.bindEventOnce = function() {
|
||||
if (arguments.length == 1) {
|
||||
Ox.forEach(arguments[0], function(fn, event) {
|
||||
self.$eventHandler.one('ox_' + event, fn);
|
||||
});
|
||||
} else {
|
||||
self.$eventHandler.one('ox_' + arguments[0], arguments[1]);
|
||||
}
|
||||
return that;
|
||||
};
|
||||
|
||||
that.defaults = function(defaults) {
|
||||
/***
|
||||
sets the default options
|
||||
Usage
|
||||
that.defaults({key0: value0, key1: value1, ...})
|
||||
***/
|
||||
self.defaults = defaults;
|
||||
delete self.options; // fixme: hackish fix for that = Ox.Foo({...}, self).defaults({...}).options({...})
|
||||
return that;
|
||||
};
|
||||
|
||||
that.gainFocus = function() {
|
||||
/***
|
||||
make this object gain focus
|
||||
***/
|
||||
Ox.Focus.focus(that.id);
|
||||
return that;
|
||||
};
|
||||
|
||||
that.hasFocus = function() {
|
||||
/***
|
||||
returns true if this object has focus
|
||||
***/
|
||||
return Ox.Focus.focused() == that.id;
|
||||
};
|
||||
|
||||
that.loseFocus = function() {
|
||||
/***
|
||||
make this object lose focus
|
||||
***/
|
||||
Ox.Focus.blur(that.id);
|
||||
return that;
|
||||
};
|
||||
|
||||
that.options = function() { // fixme: use Ox.getset
|
||||
/***
|
||||
get or set options
|
||||
Usage
|
||||
that.options() returns self.options
|
||||
that.options('foo') returns self.options.foo
|
||||
that.options('foo', x) sets self.options.foo,
|
||||
returns that
|
||||
that.options({foo: x, bar: y}) sets self.options.foo
|
||||
and self.options.bar,
|
||||
returns that
|
||||
***/
|
||||
var args,
|
||||
length = arguments.length,
|
||||
oldOptions,
|
||||
ret;
|
||||
if (length == 0) {
|
||||
// options()
|
||||
ret = self.options;
|
||||
} else if (length == 1 && typeof arguments[0] == 'string') {
|
||||
// options(str)
|
||||
ret = self.options ? self.options[arguments[0]] : options[arguments[0]];
|
||||
} else {
|
||||
// options (str, val) or options({str: val, ...})
|
||||
// translate (str, val) to ({str: val})
|
||||
args = Ox.makeObject.apply(that, arguments || {});
|
||||
oldOptions = $.extend({}, self.options);
|
||||
// if options have not been set, extend defaults,
|
||||
// otherwise, extend options
|
||||
//self.options = $.extend(self.options, self.options ? {} : self.defaults, args);
|
||||
self.options = $.extend({}, self.defaults, self.options, args);
|
||||
//self.options = $.extend(self.options || self.defaults, args);
|
||||
Ox.forEach(args, function(val, key) {
|
||||
// key == 'id' && id && Ox.Event.changeId(id, value);
|
||||
/*!Ox.equals(value, oldOptions[key]) &&*/ self.onChange(key, val);
|
||||
});
|
||||
ret = that;
|
||||
}
|
||||
return ret;
|
||||
};
|
||||
|
||||
that.removeElement = function() {
|
||||
/***
|
||||
remove this element, including its event handler
|
||||
***/
|
||||
that.loseFocus();
|
||||
delete self.$eventHandler;
|
||||
that.remove();
|
||||
delete Ox.UI.elements[that.id];
|
||||
return that;
|
||||
};
|
||||
|
||||
that.triggerEvent = function() {
|
||||
/***
|
||||
triggers an event
|
||||
Usage
|
||||
triggerEvent(event)
|
||||
triggerEvent(event, data)
|
||||
triggerEvent({event0: data0, event1: data1, ...})
|
||||
***/
|
||||
if (Ox.isObject(arguments[0])) {
|
||||
Ox.forEach(arguments[0], function(data, event) {
|
||||
if (['mousedown', 'mouserepeat', 'anyclick', 'singleclick', 'doubleclick', 'dragstart', 'drag', 'dragpause', 'dragend', 'playing'].indexOf(event) == -1) {
|
||||
Ox.print(that.id, self.options.id, 'trigger', event, data);
|
||||
}
|
||||
self.$eventHandler.trigger('ox_' + event, data);
|
||||
});
|
||||
} else {
|
||||
if (['mousedown', 'mouserepeat', 'anyclick', 'singleclick', 'doubleclick', 'dragstart', 'drag', 'dragpause', 'dragend', 'playing'].indexOf(arguments[0]) == -1) {
|
||||
Ox.print(that.id, self.options ? self.options.id : '', 'trigger', arguments[0], arguments[1] || {});
|
||||
}
|
||||
self.$eventHandler.trigger('ox_' + arguments[0], arguments[1] || {});
|
||||
}
|
||||
return that;
|
||||
};
|
||||
|
||||
that.unbindEvent = function() {
|
||||
/***
|
||||
unbinds a function from an event triggered by this element
|
||||
Usage
|
||||
unbindEvent(event, fn)
|
||||
unbindEvent({event0: fn0, event1: fn1, ...})
|
||||
***/
|
||||
if (arguments.length == 1) {
|
||||
Ox.forEach(arguments[0], function(fn, event) {
|
||||
// Ox.print(that.id, 'unbind', arguments[0]);
|
||||
self.$eventHandler.unbind('ox_' + event, fn);
|
||||
});
|
||||
} else {
|
||||
// Ox.print(that.id, 'unbind', arguments[0]);
|
||||
self.$eventHandler.unbind('ox_' + arguments[0], arguments[1]);
|
||||
}
|
||||
return that;
|
||||
};
|
||||
|
||||
return that;
|
||||
|
||||
}
|
||||
|
||||
}();
|
||||
41
source/Ox.UI/js/Core/Ox.Focus.js
Normal file
41
source/Ox.UI/js/Core/Ox.Focus.js
Normal file
|
|
@ -0,0 +1,41 @@
|
|||
// vim: et:ts=4:sw=4:sts=4:ft=js
|
||||
Ox.Focus = function() {
|
||||
/***
|
||||
Ox.Focus
|
||||
Basic focus handler
|
||||
Methods
|
||||
blur(id) blur element
|
||||
focus(id) focus element
|
||||
focused() return id of focused element, or null
|
||||
***/
|
||||
var stack = [];
|
||||
return {
|
||||
_print: function() {
|
||||
Ox.print(stack);
|
||||
},
|
||||
blur: function(id) {
|
||||
var index = stack.indexOf(id);
|
||||
if (index > -1 && index == stack.length - 1) {
|
||||
stack.length == 1 ? stack.pop() :
|
||||
stack.splice(stack.length - 2, 0, stack.pop());
|
||||
//$elements[id].removeClass('OxFocus');
|
||||
$('.OxFocus').removeClass('OxFocus'); // fixme: the above is better, and should work
|
||||
stack.length && Ox.UI.elements[stack[stack.length - 1]].addClass('OxFocus');
|
||||
Ox.print('blur', id, stack);
|
||||
}
|
||||
},
|
||||
focus: function(id) {
|
||||
var index = stack.indexOf(id);
|
||||
if (index == -1 || index < stack.length - 1) {
|
||||
index > -1 && stack.splice(index, 1);
|
||||
stack.push(id);
|
||||
$('.OxFocus').removeClass('OxFocus'); // fixme: see above
|
||||
Ox.UI.elements[id].addClass('OxFocus');
|
||||
Ox.print('focus', id, stack);
|
||||
}
|
||||
},
|
||||
focused: function() {
|
||||
return stack.length ? stack[stack.length - 1] : null;
|
||||
}
|
||||
};
|
||||
}();
|
||||
5
source/Ox.UI/js/Core/Ox.History.js
Normal file
5
source/Ox.UI/js/Core/Ox.History.js
Normal file
|
|
@ -0,0 +1,5 @@
|
|||
// vim: et:ts=4:sw=4:sts=4:ft=js
|
||||
/***
|
||||
Ox.History
|
||||
***/
|
||||
|
||||
38
source/Ox.UI/js/Core/Ox.JQueryElement.js
Normal file
38
source/Ox.UI/js/Core/Ox.JQueryElement.js
Normal file
|
|
@ -0,0 +1,38 @@
|
|||
// vim: et:ts=4:sw=4:sts=4:ft=js
|
||||
|
||||
/***
|
||||
Basic jQuery element
|
||||
***/
|
||||
|
||||
Ox.JQueryElement = function($element) {
|
||||
var that = this;
|
||||
that.id = Ox.uid();
|
||||
that.ox = Ox.VERSION;
|
||||
that.$element = $element.data({
|
||||
oxid: that.id
|
||||
});
|
||||
Ox.UI.elements[that.id] = that;
|
||||
return that;
|
||||
};
|
||||
|
||||
Ox.forEach($('<div>'), function(val, key) {
|
||||
if (Ox.isFunction(val)) {
|
||||
Ox.JQueryElement.prototype[key] = function() {
|
||||
var args = arguments, id, ret, that = this;
|
||||
Ox.forEach(args, function(arg, i) {
|
||||
// if an ox object was passed
|
||||
// then pass its $element instead
|
||||
// so that we can do oxObj.jqFn(oxObj)
|
||||
if (arg && arg.ox) {
|
||||
args[i] = arg.$element;
|
||||
}
|
||||
});
|
||||
ret = that.$element[key].apply(that.$element, args);
|
||||
// if the $element of an ox object was returned
|
||||
// then return the ox object instead
|
||||
// so that we can do oxObj.jqFn().oxFn()
|
||||
return ret.jquery && Ox.UI.elements[id = ret.data('oxid')] ?
|
||||
Ox.UI.elements[id] : ret;
|
||||
};
|
||||
}
|
||||
});
|
||||
198
source/Ox.UI/js/Core/Ox.Keyboard.js
Normal file
198
source/Ox.UI/js/Core/Ox.Keyboard.js
Normal file
|
|
@ -0,0 +1,198 @@
|
|||
// vim: et:ts=4:sw=4:sts=4:ft=js
|
||||
/***
|
||||
Ox.Keyboard
|
||||
***/
|
||||
|
||||
(function() {
|
||||
|
||||
var buffer = '',
|
||||
bufferTime = 0,
|
||||
bufferTimeout = 1000,
|
||||
// wrapped in function so it can be collapsed in text editor
|
||||
keyNames = (function() {
|
||||
return {
|
||||
0: 'section',
|
||||
8: 'backspace',
|
||||
9: 'tab',
|
||||
12: 'clear',
|
||||
13: 'enter',
|
||||
16: 'shift',
|
||||
17: 'control',
|
||||
18: 'alt',
|
||||
20: 'capslock',
|
||||
27: 'escape',
|
||||
32: 'space',
|
||||
33: 'pageup',
|
||||
34: 'pagedown',
|
||||
35: 'end',
|
||||
36: 'home',
|
||||
37: 'left',
|
||||
38: 'up',
|
||||
39: 'right',
|
||||
40: 'down',
|
||||
45: 'insert',
|
||||
46: 'delete',
|
||||
47: 'help',
|
||||
48: '0',
|
||||
49: '1',
|
||||
50: '2',
|
||||
51: '3',
|
||||
52: '4',
|
||||
53: '5',
|
||||
54: '6',
|
||||
55: '7',
|
||||
56: '8',
|
||||
57: '9',
|
||||
65: 'a',
|
||||
66: 'b',
|
||||
67: 'c',
|
||||
68: 'd',
|
||||
69: 'e',
|
||||
70: 'f',
|
||||
71: 'g',
|
||||
72: 'h',
|
||||
73: 'i',
|
||||
74: 'j',
|
||||
75: 'k',
|
||||
76: 'l',
|
||||
77: 'm',
|
||||
78: 'n',
|
||||
79: 'o',
|
||||
80: 'p',
|
||||
81: 'q',
|
||||
82: 'r',
|
||||
83: 's',
|
||||
84: 't',
|
||||
85: 'u',
|
||||
86: 'v',
|
||||
87: 'w',
|
||||
88: 'x',
|
||||
89: 'y',
|
||||
90: 'z',
|
||||
//91: 'meta.left',
|
||||
//92: 'meta.right',
|
||||
91: 'meta',
|
||||
//92: 'meta',
|
||||
93: 'meta',
|
||||
96: '0.numpad',
|
||||
97: '1.numpad',
|
||||
98: '2.numpad',
|
||||
99: '3.numpad',
|
||||
100: '4.numpad',
|
||||
101: '5.numpad',
|
||||
102: '6.numpad',
|
||||
103: '7.numpad',
|
||||
104: '8.numpad',
|
||||
105: '9.numpad',
|
||||
106: 'asterisk.numpad',
|
||||
107: 'plus.numpad',
|
||||
109: 'minus.numpad',
|
||||
108: 'enter.numpad',
|
||||
110: 'dot.numpad',
|
||||
111: 'slash.numpad',
|
||||
112: 'f1',
|
||||
113: 'f2',
|
||||
114: 'f3',
|
||||
115: 'f4',
|
||||
116: 'f5',
|
||||
117: 'f6',
|
||||
118: 'f7',
|
||||
119: 'f8',
|
||||
120: 'f9',
|
||||
121: 'f10',
|
||||
122: 'f11',
|
||||
123: 'f12',
|
||||
124: 'f13',
|
||||
125: 'f14',
|
||||
126: 'f15',
|
||||
127: 'f16',
|
||||
144: 'numlock',
|
||||
145: 'scrolllock',
|
||||
186: 'semicolon',
|
||||
187: 'equal',
|
||||
188: 'comma',
|
||||
189: 'minus',
|
||||
190: 'dot',
|
||||
191: 'slash',
|
||||
192: 'backtick',
|
||||
219: 'openbracket',
|
||||
220: 'backslash',
|
||||
221: 'closebracket',
|
||||
222: 'quote'
|
||||
// see dojo, for ex.
|
||||
};
|
||||
})(),
|
||||
modifierNames = {
|
||||
altKey: 'alt', // mac: option
|
||||
ctrlKey: 'control',
|
||||
// metaKey: 'meta', // mac: command
|
||||
shiftKey: 'shift'
|
||||
};
|
||||
|
||||
Ox.UI.ready(function() {
|
||||
// fixme: how to do this better?
|
||||
// in firefox on mac, keypress doesn't fire for up/down
|
||||
// if the cursor is at the start/end of an input element
|
||||
// on linux, it doesn't seem to fire if the input element has focus
|
||||
if ($.browser.mozilla) {
|
||||
Ox.UI.$document.keypress(keypress);
|
||||
Ox.UI.$document.keydown(function(event) {
|
||||
var $element = $('input:focus');
|
||||
if ($element.length) {
|
||||
if (
|
||||
(
|
||||
keyNames[event.keyCode] == 'up' &&
|
||||
$element[0].selectionStart + $element[0].selectionEnd == 0
|
||||
) || (
|
||||
keyNames[event.keyCode] == 'down' &&
|
||||
$element[0].selectionStart == $element.val().length &&
|
||||
$element[0].selectionEnd == $element.val().length
|
||||
)
|
||||
) {
|
||||
keypress(event);
|
||||
}
|
||||
}
|
||||
});
|
||||
} else {
|
||||
Ox.UI.$document.keydown(keypress);
|
||||
}
|
||||
});
|
||||
|
||||
function keypress(event) {
|
||||
var focused = Ox.Focus.focused(),
|
||||
key,
|
||||
keys = [],
|
||||
//ret = true,
|
||||
time;
|
||||
Ox.forEach(modifierNames, function(v, k) {
|
||||
event[k] && keys.push(v);
|
||||
});
|
||||
// avoid pushing modifier twice
|
||||
if (keyNames[event.keyCode] && keys.indexOf(keyNames[event.keyCode]) == -1) {
|
||||
keys.push(keyNames[event.keyCode]);
|
||||
}
|
||||
key = keys.join('_');
|
||||
if (key.match(/^[\w\d\-]$|SPACE/)) {
|
||||
time = Ox.getTime();
|
||||
if (time - bufferTime > bufferTimeout) {
|
||||
buffer = '';
|
||||
}
|
||||
buffer += key == 'SPACE' ? ' ' : key;
|
||||
bufferTime = time;
|
||||
}
|
||||
focused !== null && Ox.UI.elements[focused].triggerEvent('key_' + key);
|
||||
// fixme: oxdb context browser suggests we should add left and right keys here
|
||||
if (['down', 'space', 'up'].indexOf(key) > -1 && !Ox.UI.elements[focused].hasClass('OxInput')) {
|
||||
// prevent chrome from scrolling
|
||||
return false;
|
||||
}
|
||||
/*
|
||||
stack.forEach(function(v) {
|
||||
// fixme: we dont get the return value!
|
||||
ret = Ox.event.trigger(keyboard + Ox.toCamelCase(key) + '.' + v);
|
||||
return ret;
|
||||
});
|
||||
*/
|
||||
}
|
||||
|
||||
})();
|
||||
28
source/Ox.UI/js/Core/Ox.LoadingIcon.js
Normal file
28
source/Ox.UI/js/Core/Ox.LoadingIcon.js
Normal file
|
|
@ -0,0 +1,28 @@
|
|||
// vim: et:ts=4:sw=4:sts=4:ft=js
|
||||
Ox.LoadingIcon = function(options, self) {
|
||||
var self = self || {},
|
||||
that = new Ox.Element('img', self)
|
||||
.defaults({
|
||||
size: 'medium'
|
||||
})
|
||||
.options(options || {})
|
||||
.attr({
|
||||
src: Ox.UI.getImagePath('symbolLoading.svg')
|
||||
})
|
||||
.addClass(
|
||||
'OxLoadingIcon Ox' + Ox.toTitleCase(self.options.size)
|
||||
);
|
||||
that.start = function() {
|
||||
that.animate({
|
||||
opacity: 1
|
||||
}, 250);
|
||||
return that;
|
||||
};
|
||||
that.stop = function() {
|
||||
that.animate({
|
||||
opacity: 0
|
||||
}, 250);
|
||||
return that;
|
||||
}
|
||||
return that;
|
||||
}
|
||||
5
source/Ox.UI/js/Core/Ox.Progressbar.js
Normal file
5
source/Ox.UI/js/Core/Ox.Progressbar.js
Normal file
|
|
@ -0,0 +1,5 @@
|
|||
// vim: et:ts=4:sw=4:sts=4:ft=js
|
||||
/**
|
||||
Ox.Progressbar
|
||||
*/
|
||||
|
||||
222
source/Ox.UI/js/Core/Ox.Request.js
Normal file
222
source/Ox.UI/js/Core/Ox.Request.js
Normal file
|
|
@ -0,0 +1,222 @@
|
|||
// vim: et:ts=4:sw=4:sts=4:ft=js
|
||||
Ox.Request = function(options) {
|
||||
|
||||
/***
|
||||
Ox.Request
|
||||
Basic request handler
|
||||
Options
|
||||
timeout
|
||||
Methods
|
||||
cancel() cancel request
|
||||
clearCache() clear cache
|
||||
options() get or set options
|
||||
requests() return number of active requests
|
||||
send() send request
|
||||
***/
|
||||
|
||||
var cache = {},
|
||||
//dfd = $.Deferred(),
|
||||
pending = {},
|
||||
requests = {},
|
||||
self = {
|
||||
options: $.extend({
|
||||
timeout: 60000,
|
||||
type: 'POST',
|
||||
url: '/api/'
|
||||
}, options)
|
||||
};
|
||||
|
||||
return {
|
||||
|
||||
cancel: function() {
|
||||
if (arguments.length == 0) {
|
||||
// cancel all requests
|
||||
requests = {};
|
||||
} else if (Ox.isFunction(arguments[0])) {
|
||||
// cancel with function
|
||||
Ox.forEach(requests, function(req, id) {
|
||||
if (arguments[0](req)) {
|
||||
delete requests[id];
|
||||
}
|
||||
});
|
||||
} else {
|
||||
// cancel by id
|
||||
delete requests[arguments[0]];
|
||||
}
|
||||
},
|
||||
|
||||
clearCache: function() {
|
||||
cache = {};
|
||||
},
|
||||
|
||||
options: function(options) {
|
||||
return Ox.getset(self.options, options, $.noop(), this);
|
||||
},
|
||||
|
||||
requests: function() {
|
||||
return Ox.len(requests);
|
||||
},
|
||||
|
||||
send: function(options) {
|
||||
|
||||
var options = $.extend({
|
||||
age: -1,
|
||||
callback: null,
|
||||
id: Ox.uid(),
|
||||
timeout: self.options.timeout,
|
||||
type: self.options.type,
|
||||
url: self.options.url
|
||||
}, options),
|
||||
req = JSON.stringify({
|
||||
url: options.url,
|
||||
data: options.data
|
||||
});
|
||||
|
||||
if (pending[options.id]) {
|
||||
setTimeout(function() {
|
||||
Ox.Request.send(options);
|
||||
}, 0);
|
||||
} else {
|
||||
requests[options.id] = {
|
||||
url: options.url,
|
||||
data: options.data
|
||||
};
|
||||
if (cache[req] && (options.age == -1 || options.age > Ox.getTime() - cache[req].time)) {
|
||||
setTimeout(function() {
|
||||
callback && callback(cache[req].data);
|
||||
}, 0);
|
||||
} else {
|
||||
pending[options.id] = true;
|
||||
$.ajax({
|
||||
data: options.data,
|
||||
dataType: 'json',
|
||||
error: error,
|
||||
success: success,
|
||||
timeout: options.timeout,
|
||||
type: options.type,
|
||||
url: options.url
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
function callback(data) {
|
||||
delete requests[options.id];
|
||||
//Ox.len(requests) == 0 && $body.trigger('requestStop');
|
||||
options.callback && options.callback(data);
|
||||
}
|
||||
|
||||
function debug(request) {
|
||||
var $iframe = $('<iframe>')
|
||||
.css({ // fixme: should go into a class
|
||||
width: 768,
|
||||
height: 384
|
||||
}),
|
||||
$dialog = new Ox.Dialog({
|
||||
title: 'Application Error',
|
||||
buttons: [
|
||||
new Ox.Button({
|
||||
title: 'Close'
|
||||
})
|
||||
.bindEvent({
|
||||
click: function() {
|
||||
$dialog.close();
|
||||
}
|
||||
})
|
||||
],
|
||||
content: $iframe,
|
||||
width: 800,
|
||||
height: 400
|
||||
})
|
||||
.open(),
|
||||
iframe = $iframe[0].contentDocument || $iframe[0].contentWindow.document;
|
||||
iframe.open();
|
||||
iframe.write(request.responseText);
|
||||
iframe.close();
|
||||
}
|
||||
|
||||
function error(request, status, error) {
|
||||
var data;
|
||||
if (arguments.length == 1) {
|
||||
data = arguments[0]
|
||||
} else {
|
||||
try {
|
||||
data = JSON.parse(request.responseText);
|
||||
} catch (err) {
|
||||
try {
|
||||
data = {
|
||||
status: {
|
||||
code: request.status,
|
||||
text: request.statusText
|
||||
}
|
||||
};
|
||||
} catch (err) {
|
||||
data = {
|
||||
status: {
|
||||
code: '500',
|
||||
text: 'Unknown Error'
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
if (data.status.code < 500) {
|
||||
callback(data);
|
||||
} else {
|
||||
var $dialog = new Ox.Dialog({
|
||||
title: 'Application Error',
|
||||
buttons: [
|
||||
new Ox.Button({
|
||||
id: 'details',
|
||||
title: 'Details'
|
||||
})
|
||||
.bindEvent({
|
||||
click: function() {
|
||||
$dialog.close(function() {
|
||||
debug(request);
|
||||
});
|
||||
}
|
||||
}),
|
||||
new Ox.Button({
|
||||
id: 'close',
|
||||
title: 'Close'
|
||||
})
|
||||
.bindEvent({
|
||||
click: function() {
|
||||
$dialog.close();
|
||||
}
|
||||
})
|
||||
],
|
||||
content: 'Sorry, we have encountered an application error while handling your request. To help us find out what went wrong, you may want to report this error to an administrator. Otherwise, please try again later.',
|
||||
keys: {enter: 'close', escape: 'close'},
|
||||
width: 400,
|
||||
height: 200
|
||||
})
|
||||
.open();
|
||||
// fixme: change this to Send / Don't Send
|
||||
/*Ox.print({
|
||||
request: request,
|
||||
status: status,
|
||||
error: error
|
||||
});*/
|
||||
}
|
||||
pending[options.id] = false;
|
||||
}
|
||||
|
||||
function success(data) {
|
||||
pending[options.id] = false;
|
||||
cache[req] = {
|
||||
data: data,
|
||||
time: Ox.getTime()
|
||||
};
|
||||
callback(data);
|
||||
}
|
||||
|
||||
// return dfd.promise();
|
||||
|
||||
return options.id;
|
||||
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
}();
|
||||
104
source/Ox.UI/js/Core/Ox.Theme.js
Normal file
104
source/Ox.UI/js/Core/Ox.Theme.js
Normal file
|
|
@ -0,0 +1,104 @@
|
|||
// vim: et:ts=4:sw=4:sts=4:ft=js
|
||||
// fixme: this should be Ox.Theme, and provide Ox.Theme.set(), Ox.Theme.load, etc.
|
||||
/**
|
||||
if name is given as argument, switch to this theme.
|
||||
return current theme otherwise.
|
||||
|
||||
Ox.theme()
|
||||
get theme
|
||||
Ox.theme('foo')
|
||||
set theme to 'foo'
|
||||
*/
|
||||
|
||||
Ox.Theme = function(theme) {
|
||||
|
||||
return theme ? setTheme(theme) : getTheme();
|
||||
|
||||
function getTheme() {
|
||||
var theme = '';
|
||||
Ox.forEach(Ox.UI.$body.attr('class').split(' '), function(className) {
|
||||
if (Ox.startsWith(className, 'OxTheme')) {
|
||||
theme = className.replace('OxTheme', '').toLowerCase();
|
||||
return false;
|
||||
}
|
||||
});
|
||||
Ox.print('getTheme', theme)
|
||||
return theme;
|
||||
}
|
||||
|
||||
function setTheme(theme) {
|
||||
var currentTheme = getTheme();
|
||||
if (theme != currentTheme) {
|
||||
Ox.UI.$body
|
||||
.addClass('OxTheme' + Ox.toTitleCase(theme))
|
||||
.removeClass('OxTheme' + Ox.toTitleCase(currentTheme));
|
||||
$('img').add('input[type=image]').each(function() {
|
||||
var $this = $(this);
|
||||
$this.attr({
|
||||
src: $this.attr('src').replace(
|
||||
'/Ox.UI/themes/' + currentTheme + '/',
|
||||
'/Ox.UI/themes/' + theme + '/'
|
||||
)
|
||||
});
|
||||
});
|
||||
}
|
||||
return theme;
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
/*
|
||||
Ox.UI.ready(function() {
|
||||
|
||||
Ox.theme = function() {
|
||||
var length = arguments.length,
|
||||
classes = Ox.UI.$body.attr('class').split(' '),
|
||||
arg, theme;
|
||||
Ox.forEach(classes, function(v) {
|
||||
if (Ox.startsWith(v, 'OxTheme')) {
|
||||
theme = v.replace('OxTheme', '').toLowerCase();
|
||||
if (length == 1) {
|
||||
Ox.UI.$body.removeClass(v);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
});
|
||||
if (length == 1) {
|
||||
arg = arguments[0]
|
||||
Ox.UI.$body.addClass('OxTheme' + Ox.toTitleCase(arg));
|
||||
if (theme) {
|
||||
$('img').each(function() {
|
||||
var $this = $(this);
|
||||
if (!$this.attr('src')) return; // fixme: remove, should't be neccessary
|
||||
$this.attr({
|
||||
src: $this.attr('src').replace(
|
||||
'/ox.ui.' + theme + '/', '/ox.ui.' + arg + '/'
|
||||
)
|
||||
});
|
||||
});
|
||||
$('input[type=image]').each(function() {
|
||||
var $this = $(this);
|
||||
$this.attr({
|
||||
src: $this.attr('src').replace(
|
||||
'/ox.ui.' + theme + '/', '/ox.ui.' + arg + '/'
|
||||
)
|
||||
});
|
||||
});
|
||||
$('.OxLoadingIcon').each(function() {
|
||||
var $this = $(this);
|
||||
$this.attr({
|
||||
src: $this.attr('src').replace(
|
||||
'/ox.ui.' + theme + '/', '/ox.ui.' + arg + '/'
|
||||
)
|
||||
});
|
||||
})
|
||||
}
|
||||
}
|
||||
return theme;
|
||||
};
|
||||
|
||||
Ox.theme(Ox.UI.DEFAULT_THEME);
|
||||
|
||||
|
||||
});
|
||||
*/
|
||||
5
source/Ox.UI/js/Core/Ox.URL.js
Normal file
5
source/Ox.UI/js/Core/Ox.URL.js
Normal file
|
|
@ -0,0 +1,5 @@
|
|||
// vim: et:ts=4:sw=4:sts=4:ft=js
|
||||
/***
|
||||
Ox.URL
|
||||
***/
|
||||
|
||||
Loading…
Add table
Add a link
Reference in a new issue