536 lines
18 KiB
JavaScript
536 lines
18 KiB
JavaScript
//vim: et:ts=4:sw=4:sts=4:ft=js
|
|
|
|
/*
|
|
OxUI Loader
|
|
|
|
Provides function Ox.UI([options], callback) that fires when
|
|
OxUI.css, Ox.js und jquery.js have loaded
|
|
all images have loaded
|
|
the document is ready
|
|
*/
|
|
|
|
(function() {
|
|
|
|
var files = ['css/OxUI.css', 'js/Ox.js', 'js/jquery.js'],
|
|
path = Array.prototype.slice.apply(
|
|
document.getElementsByTagName('script')
|
|
).filter(function(element) {
|
|
return /OxUI\.js$/.test(element.src);
|
|
})[0].src.replace('js/OxUI.js', ''),
|
|
documentReady = false,
|
|
documentReadyCallbacks = [],
|
|
head = document.getElementsByTagName('head')[0],
|
|
logs = [],
|
|
oxUICallback = function() {},
|
|
oxUIDefaults = {
|
|
// 'classic', 'modern', 'console' or 'none'
|
|
display: 'classic'
|
|
},
|
|
oxUIFunction = function(options, callback) {
|
|
oxUICallback = arguments.length == 2 ? callback : options;
|
|
oxUIOptions = arguments.length == 2 && options ? options : oxUIDefaults;
|
|
};
|
|
|
|
files.forEach(function(file, i) {
|
|
files[i] = {
|
|
ready: isIncluded(file),
|
|
src: file
|
|
};
|
|
});
|
|
|
|
Ox = typeof Ox != 'undefined' ? Ox : function() {};
|
|
Ox.UI = oxUIFunction;
|
|
|
|
log('Loading essential scripts and stylesheets...')
|
|
waitForDocument();
|
|
waitForFiles();
|
|
|
|
files.forEach(function(file) {
|
|
var element,
|
|
isCSS = isFileType(file.src, 'css');
|
|
if (!file.ready) {
|
|
element = document.createElement(isCSS ? 'link' : 'script');
|
|
element[isCSS ? 'href' : 'src'] = path + file.src;
|
|
element.type = isCSS ? 'text/css' : 'text/javascript';
|
|
if (isCSS) {
|
|
element.rel = 'stylesheet';
|
|
waitForCSS();
|
|
} else {
|
|
element.onload = onload;
|
|
}
|
|
head.appendChild(element);
|
|
}
|
|
function onload() {
|
|
file.ready = true;
|
|
log(file.src.split('/').pop() + ' loaded.')
|
|
if (file.src == 'js/Ox.js') {
|
|
Ox.UI = oxUIFunction;
|
|
}
|
|
waitForFiles();
|
|
}
|
|
function waitForCSS() {
|
|
try {
|
|
element.sheet.cssRule;
|
|
onload();
|
|
} catch(e) {
|
|
setTimeout(waitForCSS, 25);
|
|
}
|
|
}
|
|
});
|
|
|
|
function getElement(str) {
|
|
// Generic HTML Element Object (mimics jQuery)
|
|
return {
|
|
0: str[0] == '<' ? document.createElement(str.substr(1, str.length - 2)) :
|
|
str[0] == '.' ? document.getElementsByClassName(str.substr(1))[0] :
|
|
str[0] == '#' ? document.getElementById(str.substr(1)) :
|
|
document.getElementsByTagName(str)[0],
|
|
addClass: function(str) {
|
|
this[0].className += (this[0].className ? ' ' : '') + str;
|
|
return this;
|
|
},
|
|
append: function(element) {
|
|
this[0].appendChild(element[0]);
|
|
return this;
|
|
},
|
|
appendTo: function(element) {
|
|
element[0].appendChild(this[0]);
|
|
return this;
|
|
},
|
|
attr: function(obj) {
|
|
for (var key in obj) {
|
|
this[0].setAttribute(key, obj[key]);
|
|
}
|
|
return this;
|
|
},
|
|
css: function(obj) {
|
|
for (var key in obj) {
|
|
this[0].style[key] = obj[key];
|
|
}
|
|
return this;
|
|
},
|
|
html: function(str) {
|
|
this[0].innerHTML = str;
|
|
return this;
|
|
},
|
|
mousedown: function(fn) {
|
|
this[0].onmousedown = fn;
|
|
return this;
|
|
}
|
|
};
|
|
}
|
|
|
|
function isFileType(src, type) {
|
|
return new RegExp('\.' + type + '$').test(src);
|
|
}
|
|
|
|
function isIncluded(src) {
|
|
var isCSS = isFileType(src);
|
|
return Array.prototype.slice.apply(
|
|
document.getElementsByTagName(isCSS ? 'link' : 'script')
|
|
).map(function(element) {
|
|
return element[isCSS ? 'href' : 'src'] == path + src;
|
|
}).reduce(function(prev, curr) {
|
|
return prev || curr;
|
|
}, false);
|
|
}
|
|
|
|
function log(str) {
|
|
var date = new Date(),
|
|
element = getElement('.console'),
|
|
str = [
|
|
date.getHours(), date.getMinutes(), date.getSeconds()
|
|
].map(function(num) {
|
|
return pad(num, 2)
|
|
}).join(':') + '.' + pad(date.getTime() % 1000, 3) + ' ' + str;
|
|
logs.push(str);
|
|
if (element[0]) {
|
|
logs.forEach(function(str) {
|
|
getElement('<div>')
|
|
.css({
|
|
height: '16px',
|
|
fontFamily: [
|
|
'Menlo', 'Monaco',
|
|
'DejaVu Sans Mono', 'Bitstream Vera Sans Mono',
|
|
'Consolas', 'Lucida Console'
|
|
].join(', '),
|
|
fontSize: '12px',
|
|
color: 'rgb(240, 240, 240)'
|
|
})
|
|
.html(str)
|
|
.appendTo(element);
|
|
element[0].scrollTop = 1000000;
|
|
});
|
|
logs = [];
|
|
}
|
|
function pad(num, len) {
|
|
var str = num.toString();
|
|
while (str.length < len) {
|
|
str = '0' + str;
|
|
}
|
|
return str;
|
|
}
|
|
console.log(str);
|
|
}
|
|
|
|
function waitForDocument() {
|
|
document.addEventListener('DOMContentLoaded', onload, false);
|
|
function onload() {
|
|
log('Document ready.')
|
|
document.removeEventListener('DOMContentLoaded', onload, false);
|
|
documentReady = true;
|
|
bootOxUI();
|
|
}
|
|
}
|
|
|
|
function waitForFiles() {
|
|
files.map(function(file) {
|
|
return file.ready;
|
|
}).reduce(function(pre, cur) {
|
|
return pre && cur;
|
|
}) && loadOxUI();
|
|
}
|
|
|
|
function bootOxUI() {
|
|
|
|
// runs when the document is ready
|
|
|
|
var body, css, div,
|
|
browsers = [
|
|
{name: 'Chrome', url: 'http://www.google.com/chrome/', version: 10},
|
|
{name: 'Firefox', url: 'http://www.mozilla.org/firefox/', version: 4},
|
|
{name: 'Safari', url: 'http://www.apple.com/safari/', version: 5}
|
|
],
|
|
options = oxUIOptions || oxUIDefaults;
|
|
|
|
if (options.display != 'none') {
|
|
body = getElement('body');
|
|
css = {
|
|
position: 'absolute',
|
|
left: 0,
|
|
top: 0,
|
|
right: 0,
|
|
bottom: 0,
|
|
margin: 'auto',
|
|
MozUserSelect: 'none',
|
|
WebkitUserSelect: 'none'
|
|
};
|
|
div = getElement('<div>')
|
|
.addClass(options.display == 'console' ? 'console' : '')
|
|
.css({
|
|
position: 'absolute',
|
|
left: 0,
|
|
top: 0,
|
|
right: 0,
|
|
bottom: 0,
|
|
padding: '4px',
|
|
background: 'rgb(' + (
|
|
options.display == 'classic' ? '240, 240, 240' : '16, 16, 16')
|
|
+ ')',
|
|
opacity: 1,
|
|
overflow: options.display == 'console' ? 'auto' : 'hidden',
|
|
zIndex: 1000
|
|
})
|
|
.appendTo(body);
|
|
}
|
|
|
|
checkBrowser() ? start() : stop();
|
|
|
|
function checkBrowser() {
|
|
var i, isSupported = false;
|
|
for (i in browsers) {
|
|
var browser = browsers[i],
|
|
version;
|
|
if (navigator.userAgent.indexOf(browser.name) > -1) {
|
|
if (new RegExp((
|
|
browser.name == 'Safari' ? 'Version' : browser.name
|
|
) + '\\/(\\d+)\\.')(navigator.userAgent)[1] >= browser.version) {
|
|
isSupported = true;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
return isSupported;
|
|
}
|
|
|
|
function start() {
|
|
var image, src;
|
|
if (options.display == 'console') {
|
|
log('Loading additional scripts and images...')
|
|
} else {
|
|
image = new Image(),
|
|
src = path + 'svg/ox.ui.' + options.display + '/symbolLoading.svg';
|
|
image.onload = function() {
|
|
getElement('<img>')
|
|
.attr({
|
|
src: src,
|
|
})
|
|
.css(css)
|
|
.css({
|
|
width: '32px',
|
|
height: '32px'
|
|
})
|
|
.mousedown(function(e) {
|
|
e.preventDefault()
|
|
})
|
|
.appendTo(div);
|
|
};
|
|
image.src = src;
|
|
}
|
|
}
|
|
|
|
function stop() {
|
|
var counter = 0,
|
|
message = 'Browser not supported, use ' + userAgents.map(function(userAgent, i) {
|
|
return userAgent.name + (
|
|
i == userAgents.length - 1 ? '.' :
|
|
i == userAgents.length - 2 ? ' or' : ','
|
|
);
|
|
}).join(' ');
|
|
if (options.display == 'none') {
|
|
throw new Error(message);
|
|
} else {
|
|
div.addClass('error');
|
|
if (options.display == 'console') {
|
|
log(message);
|
|
log = function() {};
|
|
} else {
|
|
userAgents.forEach(function(userAgent) {
|
|
var image = new Image();
|
|
userAgent.src = path + 'png/ox.ui/browser' + userAgent.name + '128.png';
|
|
image.onload = function() {
|
|
++counter == userAgents.length && showImages();
|
|
}
|
|
image.src = userAgent.src;
|
|
});
|
|
}
|
|
}
|
|
function showImages() {
|
|
var box = getElement('<div>')
|
|
.css(css)
|
|
.css({
|
|
width: (userAgents.length * 72) + 'px',
|
|
height: '72px'
|
|
})
|
|
.appendTo(div);
|
|
userAgents.forEach(function(userAgent, i) {
|
|
var link = getElement('<a>')
|
|
.attr({
|
|
href: userAgent.url,
|
|
title: userAgent.name
|
|
})
|
|
.css({
|
|
position: 'absolute',
|
|
left: (i * 72) + 'px',
|
|
width: '72px',
|
|
height: '72px',
|
|
})
|
|
.appendTo(box);
|
|
getElement('<img>')
|
|
.attr({
|
|
src: userAgent.src
|
|
})
|
|
.css(css)
|
|
.css({
|
|
width: '64px',
|
|
height: '64px',
|
|
border: 0,
|
|
cursor: 'pointer'
|
|
})
|
|
.mousedown(function(e) {
|
|
e.preventDefault();
|
|
})
|
|
.appendTo(link);
|
|
});
|
|
}
|
|
}
|
|
|
|
}
|
|
|
|
function loadOxUI() {
|
|
|
|
// runs when css and js files have loaded
|
|
|
|
documentReady && initDocument();
|
|
|
|
$.getJSON(path + 'json/OxUI.json', function(data) {
|
|
|
|
var $head = $('head'),
|
|
promises = documentReady ? [] : [waitForDocument()];
|
|
|
|
log('OxUI.json loaded.')
|
|
|
|
// fixme: find a better way to not wait for flags
|
|
data = data.filter(function(image) {
|
|
return !Ox.startsWith(image, 'svg/ox.map/');
|
|
});
|
|
data.forEach(function(src) {
|
|
promises.push(loadFile(src));
|
|
});
|
|
|
|
$.when.apply(null, promises)
|
|
.done(function() {
|
|
var $div, error = $('.error').length;
|
|
if (!error) {
|
|
$div = $('div');
|
|
$('img').remove();
|
|
$div.animate({
|
|
opacity: 0
|
|
}, 1000, function() {
|
|
$div.remove();
|
|
});
|
|
}
|
|
oxUICallback();
|
|
})
|
|
.fail(function() {
|
|
throw new Error('File not found.');
|
|
});
|
|
|
|
function loadFile(src) {
|
|
var dfd = new $.Deferred(),
|
|
isJS = isFileType(src, 'js'),
|
|
element = isJS ? document.createElement('script') : new Image();
|
|
element.onload = function() {
|
|
log(src.split('/').pop() + ' loaded.');
|
|
dfd.resolve();
|
|
}
|
|
element.src = path + src;
|
|
if (isJS) {
|
|
element.type = 'text/javascript';
|
|
head.appendChild(element)
|
|
} else {
|
|
// need to keep a reference to keep image in cache
|
|
Ox.UI.IMAGE_CACHE.push(src);
|
|
}
|
|
return dfd.promise();
|
|
}
|
|
|
|
function waitForDocument() {
|
|
var dfd = new $.Deferred();
|
|
$(function() {
|
|
initDocument();
|
|
dfd.resolve();
|
|
});
|
|
return dfd.promise();
|
|
}
|
|
|
|
});
|
|
|
|
function initDocument() {
|
|
Ox.UI.$body = $('body');
|
|
Ox.UI.$document = $(document);
|
|
Ox.UI.$head = $('head');
|
|
Ox.UI.$window = $(window);
|
|
documentReadyCallbacks.forEach(function(callback) {
|
|
callback();
|
|
});
|
|
}
|
|
|
|
Ox.UI.ready = function(callback) {
|
|
if (!Ox.UI.$window) {
|
|
documentReadyCallbacks.push(callback);
|
|
} else {
|
|
callback();
|
|
}
|
|
};
|
|
|
|
Ox.UI.elements = {};
|
|
Ox.UI.DEFAULT_THEME = 'classic';
|
|
Ox.UI.DIMENSIONS = {
|
|
horizontal: ['width', 'height'],
|
|
vertical: ['height', 'width']
|
|
};
|
|
Ox.UI.EDGES = {
|
|
horizontal: ['left', 'right', 'top', 'bottom'],
|
|
vertical: ['top', 'bottom', 'left', 'right']
|
|
};
|
|
Ox.UI.getImagePath = function(filename) {
|
|
// fixme: not the best idea to do this here
|
|
if (filename == 'symbolPlay.svg') {
|
|
filename = 'symbolRight.svg';
|
|
}
|
|
return Ox.UI.PATH + filename.split('.').pop() +
|
|
'/ox.ui.' + Ox.UI.theme() + '/' + filename;
|
|
};
|
|
Ox.UI.IMAGE_CACHE = [];
|
|
Ox.UI.PATH = $('script[src*="OxUI.js"]')
|
|
.attr('src').replace('js/OxUI.js', '');
|
|
Ox.UI.SCROLLBAR_SIZE = $.browser.mozilla ? 16 : 12;
|
|
// fixme: the follwing should be deprecated
|
|
Ox.UI.theme = function() {
|
|
var theme;
|
|
Ox.forEach(Ox.UI.$body.attr('class').split(' '), function(v) {
|
|
if (Ox.startsWith(v, 'OxTheme')) {
|
|
theme = v.replace('OxTheme', '').toLowerCase();
|
|
return false;
|
|
}
|
|
});
|
|
return theme || Ox.UI.DEFAULT_THEME; // fixme: shouldn't be neccessary
|
|
};
|
|
Ox.UI.getBarSize = function(size) {
|
|
var sizes = {
|
|
small: 20,
|
|
medium: 24,
|
|
large: 28
|
|
};
|
|
return sizes[size];
|
|
};
|
|
Ox.UI.symbols = {
|
|
alt: '\u2325',
|
|
apple: '\uF8FF',
|
|
arrow_down: '\u2193',
|
|
arrow_left: '\u2190',
|
|
arrow_right: '\u2192',
|
|
arrow_up: '\u2191',
|
|
backspace: '\u232B',
|
|
backup: '\u2707',
|
|
ballot: '\u2717',
|
|
black_star: '\u2605',
|
|
burn: '\u2622',
|
|
caps_lock: '\u21EA',
|
|
check: '\u2713',
|
|
//clear: '\u2327',
|
|
clear: '\u00D7',
|
|
click: '\uF803',
|
|
close: '\u2715',
|
|
command: '\u2318',
|
|
control: '\u2303',
|
|
cut: '\u2702',
|
|
'delete': '\u2326',
|
|
diamond: '\u25C6',
|
|
edit: '\uF802',
|
|
eject: '\u23CF',
|
|
escape: '\u238B',
|
|
end: '\u2198',
|
|
enter: '\u2324',
|
|
fly: '\u2708',
|
|
gear: '\u2699',
|
|
home: '\u2196',
|
|
info: '\u24D8',
|
|
navigate: '\u2388',
|
|
option: '\u2387',
|
|
page_up: '\u21DE',
|
|
page_down: '\u21DF',
|
|
redo: '\u21BA',
|
|
'return': '\u21A9',
|
|
//select: '\u21D5',
|
|
select: '\u25BE',
|
|
shift: '\u21E7',
|
|
sound: '\u266B',
|
|
space: '\u2423',
|
|
tab: '\u21E5',
|
|
trash: '\u267A',
|
|
triangle_down: '\u25BC',
|
|
triangle_left: '\u25C0',
|
|
triangle_right: '\u25BA',
|
|
triangle_up: '\u25B2',
|
|
undo: '\u21BB',
|
|
voltage: '\u26A1',
|
|
warning: '\u26A0',
|
|
white_star: '\u2606'
|
|
};
|
|
|
|
}
|
|
|
|
}());
|
|
|