From 7430ef1023f5aae25f32a80ce995ff01db59e1b0 Mon Sep 17 00:00:00 2001 From: rolux Date: Sat, 23 Apr 2011 13:04:37 +0200 Subject: [PATCH] updates for loader --- .bzrignore | 1 + demos/calendar/index.html | 1 - demos/calendar/js/calendar.js | 9 +- .../css/OxUI.classic.css | 0 build/css/ox.ui.css => source/css/OxUI.css | 6 +- .../css/OxUI.future.css | 0 .../css/OxUI.modern.css | 0 source/js/Ox.js | 2 +- source/js/OxUI.js | 597 ++++++++++++------ tools/build/build.py | 5 + 10 files changed, 429 insertions(+), 192 deletions(-) rename build/css/ox.ui.classic.css => source/css/OxUI.classic.css (100%) rename build/css/ox.ui.css => source/css/OxUI.css (99%) rename build/css/ox.ui.future.css => source/css/OxUI.future.css (100%) rename build/css/ox.ui.modern.css => source/css/OxUI.modern.css (100%) diff --git a/.bzrignore b/.bzrignore index 947f0057..c24a264f 100644 --- a/.bzrignore +++ b/.bzrignore @@ -1,2 +1,3 @@ .DS_Store build/js/* +build/css diff --git a/demos/calendar/index.html b/demos/calendar/index.html index 2d3bd520..ec09a699 100644 --- a/demos/calendar/index.html +++ b/demos/calendar/index.html @@ -3,7 +3,6 @@ ox.js calendar demo - diff --git a/demos/calendar/js/calendar.js b/demos/calendar/js/calendar.js index 906c7c50..7b99d181 100644 --- a/demos/calendar/js/calendar.js +++ b/demos/calendar/js/calendar.js @@ -1,10 +1,17 @@ +console.log('calling Ox.UI()') +//console.log('Ox =', Ox) +//console.log('Ox.UI =', Ox.UI) + Ox.UI(function() { + console.log('running Ox.UI()') + //console.log('Ox =', Ox) + Ox.UI.ready(function() { Ox.theme('modern'); - Ox.print('$$$$', Ox.Calendar) + //Ox.print('$$$$', Ox.Calendar) new Ox.Calendar({ date: new Date(0), diff --git a/build/css/ox.ui.classic.css b/source/css/OxUI.classic.css similarity index 100% rename from build/css/ox.ui.classic.css rename to source/css/OxUI.classic.css diff --git a/build/css/ox.ui.css b/source/css/OxUI.css similarity index 99% rename from build/css/ox.ui.css rename to source/css/OxUI.css index 0f6d4a38..f725dd7d 100644 --- a/build/css/ox.ui.css +++ b/source/css/OxUI.css @@ -1,6 +1,6 @@ -@import url("ox.ui.classic.css"); -@import url("ox.ui.modern.css"); -@import url("ox.ui.future.css"); +@import url("OxUI.classic.css"); +@import url("OxUI.modern.css"); +@import url("OxUI.future.css"); /* ================================================================================ diff --git a/build/css/ox.ui.future.css b/source/css/OxUI.future.css similarity index 100% rename from build/css/ox.ui.future.css rename to source/css/OxUI.future.css diff --git a/build/css/ox.ui.modern.css b/source/css/OxUI.modern.css similarity index 100% rename from build/css/ox.ui.modern.css rename to source/css/OxUI.modern.css diff --git a/source/js/Ox.js b/source/js/Ox.js index 5fabf32c..51d465ff 100644 --- a/source/js/Ox.js +++ b/source/js/Ox.js @@ -926,7 +926,7 @@ Ox.getDateInWeek = function(date, weekday, utc) { return date; } -Ox.getDayOfTheYear = function(date) { +Ox.getDayOfTheYear = function(date, utc) { /* >>> Ox.getDayOfTheYear(new Date("12/31/2000")) 366 diff --git a/source/js/OxUI.js b/source/js/OxUI.js index 26617a1b..184641ba 100644 --- a/source/js/OxUI.js +++ b/source/js/OxUI.js @@ -1,208 +1,433 @@ //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 DOM is ready +*/ + (function() { - var path = Array.prototype.slice.apply( + var files = ['css/OxUI.css', 'js/Ox.js', 'js/jquery.js'], + path = Array.prototype.slice.apply( document.getElementsByTagName('script') - ).filter(function(script) { - return /OxUI\.js$/(script.src); - })[0].src.replace('OxUI.js', ''), - scripts = [ - {ready: typeof Ox != 'undefined', src: 'Ox.js'}, - {ready: typeof $ != 'undefined', src: 'jquery.js'} - ], - uiCallback, - ready = false, - readyCallbacks = []; + ).filter(function(element) { + return /OxUI\.js$/(element.src); + })[0].src.replace('js/OxUI.js', ''), + head = document.getElementsByTagName('head')[0], + oxUICallback = function() {}, + oxUIFunction = function(options, callback) { + var defaults = { + // 'classic', 'modern', 'verbose' or anything falsy + display: 'classic' + }; + oxUICallback = arguments.length == 2 ? callback : options; + oxUIOptions = arguments.length == 2 && options ? options : {}; + }, + oxUIOptions = {}, + documentReady = false, + documentReadyCallbacks = []; + + files.forEach(function(file, i) { + files[i] = { + ready: isIncluded(file), + src: file + }; + }); Ox = typeof Ox != 'undefined' ? Ox : function() {}; - Ox.UI = function(callback) { - uiCallback = callback; - }; + Ox.UI = oxUIFunction; - scripts.forEach(function(script) { - var element; - if (!script.ready) { - element = document.createElement('script'); - element.src = path + script.src; - element.type = 'text/javascript'; - element.onload = function() { - script.ready = true; + 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; + console.log(file.src, 'ready') + if (file.src == 'js/Ox.js') { + Ox.UI = oxUIFunction; + } + waitForFiles(); + } + function waitForCSS() { + try { + element.sheet.cssRule; onload(); - }; - document.getElementsByTagName('head')[0].appendChild(element); + } catch(e) { + setTimeout(waitForCSS, 25); + } } }); - onload(); + function isFileType(src, type) { + return new RegExp('\.' + type + '$')(src); + } - function onload() { - if (scripts.map(function(script) { - return script.ready; + 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 waitForDocument() { + document.addEventListener('DOMContentLoaded', onload, false); + function onload() { + console.log('DOMContentLoaded') + document.removeEventListener('DOMContentLoaded', onload, false); + bootOxUI(); + } + } + + function waitForFiles() { + files.map(function(file) { + return file.ready; }).reduce(function(pre, cur) { return pre && cur; - })) { + }) && loadOxUI(); + } - Ox.UI = {}; - Ox.UI.ready = function(callback) { - if (!ready) { - readyCallbacks.push(callback); - } else { - callback(); + function bootOxUI() { + + var body = element('body'), + css = { + position: 'absolute', + left: 0, + top: 0, + right: 0, + bottom: 0, + margin: 'auto', + MozUserSelect: 'none', + WebkitUserSelect: 'none' + }, + div = element('
') + .css({ + position: 'absolute', + left: 0, + top: 0, + right: 0, + bottom: 0, + background: 'rgb(240, 240, 240)', + opacity: 1, + zIndex: 1000 + }) + .appendTo(body), + userAgents = [ + {name: 'Chrome', url: 'http://www.google.com/chrome/'}, + {name: 'Firefox', url: 'http://www.mozilla.org/firefox/'}, + {name: 'Safari', url: 'http://www.apple.com/safari/'} + ]; + + getUserAgent() ? start() : stop(); + + function getUserAgent() { + var userAgent = ''; + userAgents.forEach(function(v) { + if (navigator.userAgent.indexOf(v.name) > -1) { + userAgent = v.name; } - }; - - $(function() { - Ox.UI.$body = $('body'); - Ox.UI.$document = $(document); - Ox.UI.$head = $('head'); - Ox.UI.$window = $(window); - ready = true; - readyCallbacks.forEach(function(callback) { - 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.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' - }; - Ox.IMAGE_CACHE = []; - $.getJSON(Ox.UI.PATH + 'json/OxUI.json', function(data) { - - function loadImage(src) { - var dfd = new $.Deferred(); - var image = new Image(); - image.onload = function() { - dfd.resolve(); - }; - image.src = Ox.UI.PATH + src; - Ox.IMAGE_CACHE.push(src); - return dfd.promise(); - } - - function loadScript(src) { - // jQuery doesn't work here, does some unwanted magic - var dfd = new $.Deferred(); - var script = document.createElement('script'); - script.onload = function() { - dfd.resolve(); - }; - script.src = Ox.UI.PATH + src; - script.type = 'text/javascript'; - document.getElementsByTagName('head')[0].appendChild(script); - return dfd.promise(); - } - - var $head = $('head'), - promises = []; - // 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) { - if (/\.js$/(src)) { - promises.push(loadScript(src)); - } else { - promises.push(loadImage(src)); - } - }); - $.when.apply(null, promises) - .done(uiCallback || []); }); - + return userAgent; } + + function element(str) { + // Generic HTML Element Object (mimics jQuery) + return { + 0: str[0] == '<' ? + document.createElement(str.substr(1, str.length - 2)) : + document.getElementsByTagName(str)[0], + addClass: function(str) { + 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 start() { + var image = new Image(), + src = path + 'svg/ox.ui.classic/symbolLoading.svg'; + image.onload = function() { + element('') + .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; + 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 && loaded(); + } + image.src = userAgent.src; + }); + function loaded() { + var box = element('
') + .css(css) + .appendTo(div); + userAgents.forEach(function(userAgent, i) { + var link = element('') + .attr({ + href: userAgents[name], + title: name + }) + .css({ + position: 'absolute', + left: (i * 72) + 'px', + width: '72px', + height: '72px', + }) + .appendTo(box); + element('') + .css(css) + .css({ + width: '64px', + height: '64px', + border: 0, + cursor: 'pointer' + }) + .mousedown(function(e) { + e.preventDefault(); + }) + .appendTo(link); + }); + } + } + + } + + function loadOxUI() { + + Ox.UI = {}; + Ox.UI.ready = function(callback) { + if (!documentReady) { + documentReadyCallbacks.push(callback); + } else { + callback(); + } + }; + + $.getJSON(path + 'json/OxUI.json', function(data) { + + var $head = $('head'), + promises = [waitForDocument()]; + // 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) + .then(function() { + var $div = Ox.UI.$body.find('div'); + Ox.UI.$body.find('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 = 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() { + Ox.UI.$body = $('body'); + Ox.UI.$document = $(document); + Ox.UI.$head = $('head'); + Ox.UI.$window = $(window); + documentReady = true; + documentReadyCallbacks.forEach(function(callback) { + callback(); + }); + dfd.resolve(); + }); + return dfd.promise(); + } + + }); + + + 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' + }; + } }()); diff --git a/tools/build/build.py b/tools/build/build.py index 96737efb..71603e45 100644 --- a/tools/build/build.py +++ b/tools/build/build.py @@ -55,6 +55,11 @@ for dirname, dirnames, filenames in os.walk(source_path + 'js/'): elif not '_' in dirname and not filename.endswith('.min.js'): files.append(os.path.join(dirname.replace(source_path , '../source/'), filename)) +for dirname, dirnames, filenames in os.walk(source_path + 'css'): + for filename in filenames: + if filename[:1] != '.': + write_link(os.path.join(dirname, filename), build_path + 'css/' + filename) + for dirname, dirnames, filenames in os.walk(build_path + 'png'): for filename in filenames: if filename[:1] != '.':