'use strict'; Ox.load(function() { var app = { $ui: {}, animate: function() { var home = app.url.get().page == ''; app.state.animating = true; if (home) { app.$ui.logo.attr({ src: app.getSRC('logo') }); app.$ui.screen.show(); app.$ui.label.show(); app.$ui.menu.options({value: ''}).show(); } else { app.$ui.menu.options({value: app.user.page}); } app.$ui.panel.find('.OxButtonGroup').css({opacity: 0}); [ 'screen', 'logo', 'label', 'menu', 'switch' ].forEach(function(element) { app.$ui[element].stop().animate( app.getCSS(element), 1000, element == 'screen' ? function() { if (!home) { app.$ui.logo.attr({ src: app.getSRC('logo') }); app.$ui.panel.find('.OxButtonGroup').css({opacity: 1}); app.$ui.screen.hide(); app.$ui.label.hide(); app.$ui.menu.hide().options({value: ''}); } app.state.animating = false; } : void 0 ); }); }, data: { html: {}, pages: [ {id: 'about', title: 'About'}, {id: 'readme', title: 'Readme'}, {id: 'examples', title: 'Examples'}, {id: 'doc', title: 'Documentation'}, {id: 'downloads', title: 'Downloads'}, {id: 'development', title: 'Development'} ], user: { item: {doc: '', examples: '', readme: ''}, page: '', previousPage: 'about' } }, db: Ox.localStorage('OxJS'), getCSS: function(element) { var css = {}, home = app.url.get().page == '', center = Math.floor(window.innerWidth / 2), middle = Math.floor(window.innerHeight / 2); if (element == 'label') { css = home ? { top: middle + 16 + 'px', left: center - 128 + 'px', width: '242px', height: '16px', fontSize: '12px', opacity: 1, overflow: 'visible' } : { top: '35px', left: '4px', width: '40px', height: '4px', fontSize: '1px', opacity: 0 } } else if (element == 'loading') { css.top = middle + 52 + 'px' } else if (element == 'logo') { css = home || !app.state.loaded ? { left: center - 128 + 'px', top: middle - 128 + 'px', width: '256px', height: '128px', borderRadius: '32px' } : { top: '6px', left: '6px', width: '48px', height: '24px', borderRadius: '6px' }; } else if (element == 'menu') { css = home ? { top: middle + 56 + 'px', left: Math.ceil(center - app.$ui.menu.width() / 2) + 'px' } : { top: '6px', left: Math.ceil(center - app.$ui.menu.width() / 2) + 'px' }; } else if (element == 'screen') { css.opacity = home ? 1 : 0; } else if (element == 'switch') { css = home ? { top: middle + 96 + 'px', right: Math.floor(center - app.$ui.switch.width() / 2) + 'px' } : { top: '6px', right: '6px' }; } else if (element == 'warning') { css = { left: center - 128 + 'px', top: middle + 16 + 'px', }; } return css; }, getSRC: function(element) { var src, home = app.url.get().page == '', theme = app.user.theme || 'classic'; if (element == 'icon') { src = 'source/Ox.UI/themes/' + theme + '/png/icon16.png'; } else if (element == 'loading') { src = 'source/Ox.UI/themes/' + theme + '/svg/symbolLoading.svg' } else if (element == 'logo') { src = 'source/Ox.UI/themes/' + theme + '/png/logo128.png' } return src; }, html: {}, init: function() { app.loadScreen(function() { app.loadData(function() { Ox.load({UI: {theme: app.theme}}, app.load); }); }); }, load: function(browserSupported) { var url = app.url.get(); app.user = Ox.extend(app.data.user, app.db()) app.user.page = url.page; if (url.item && url.page in app.user.item) { app.user.item[url.page] = url.item; } app.db(app.user); app.$ui.panel = app.ui.panel() .select(app.user.page) .appendTo(Ox.$body); // jqueryfy so that we can animate ['screen', 'logo', 'loading'].forEach(function(element) { app.$ui[element] = $('.' + element); }); app.$ui.loading.animate({opacity: 0}, 500, function() { app.$ui.loading.remove(); }); if (!browserSupported) { app.$ui.warning = app.ui.warning() .css(app.getCSS('warning')) .appendTo(Ox.$body); app.$ui.logo .css({cursor: 'pointer'}) .one({ click: function() { app.$ui.warning.remove(); app.load(true); } }); } else if (!url.page) { app.$ui.logo .css({cursor: 'pointer'}) .on({ click: app.toggle }); ['label', 'menu', 'switch'].forEach(function(element) { app.$ui[element] = app.ui[element]() .css({opacity: 0}) .appendTo(Ox.$body); app.$ui[element] .css(app.getCSS(element)) .animate({opacity: 1}, 500); }); } else { ['label', 'menu', 'switch'].forEach(function(element) { app.$ui[element] = app.ui[element]().appendTo(Ox.$body); app.$ui[element].css(app.getCSS(element)).hide(); }); app.$ui.screen.animate({opacity: 0}, 500, function() { app.$ui.screen.hide(); }); app.$ui.logo.animate({opacity: 0}, 500, function() { app.$ui.logo .attr({src: app.getSRC('logo')}) .css(app.getCSS('logo')) .animate({opacity: 1}, 500, function() { app.$ui.logo .css({cursor: 'pointer'}) .on({ click: app.toggle }); }); app.$ui.switch.css({opacity: 0}).show().animate({ opacity: 1 }, 500); }); } Ox.$window.on({ hashchange: app.urlchange }); app.state.loaded = true; }, loadData: function(callback) { Ox.getJSON('index.json?'+Ox.random(1000), function(data) { app.data = Ox.extend(app.data, data); app.data.pages.forEach(function(page) { var id = page.id == 'doc' ? 'documentation' : page.id; Ox.get('readme/html/_' + (id) + '.html', function(html) { app.html[id] = html; Ox.len(app.html) == app.data.pages.length && callback(); }); }) }); }, loadScreen: function(callback) { app.setTheme(app.user.theme || 'classic'); app.$ui.screen = app.ui.screen(); app.$ui.loading = app.ui.loading(); app.$ui.logo = app.ui.logo() .one({ load: function() { Ox.$('body') .append(app.$ui.screen) .append(app.$ui.logo) .append(app.$ui.loading); app.rotate(); callback(); } }); Ox.$(window).on({ resize: app.resize }); }, patchButtonGroup: function($buttonGroup) { $buttonGroup.find('.OxButton').css({ height: '22px', paddingLeft: '8px', paddingRight: '8px', fontSize: '13px' }); $buttonGroup.find('.OxButton:first-child').css({ //paddingLeft: '9px', borderTopLeftRadius: '6px', borderBottomLeftRadius: '6px' }); $buttonGroup.find('.OxButton:last-child').css({ //paddingRight: '9px', borderTopRightRadius: '6px', borderBottomRightRadius: '6px' }); }, re: { code: [ new RegExp( 'Ox' + '(\\.' + 'UI)?' + '\\.' + '([\\w\\$]+)<\\/span>', 'g' ), function (str) { return '' + str + ''; } ], comment: [ /\b(Ox\.[\w\$]+)/g, '$1' ], version: [ '{version}', function() { return ( /:\/\/oxjs.org\//.test(window.location.href) ? 'The latest version is' : 'You\'re currently running version' ) + ' ' + Ox.VERSION + '.' } ] }, resize: function() { [ 'logo', 'loading', 'label', 'menu', 'switch' ].forEach(function(element) { app.$ui[element] && app.$ui[element].css(app.getCSS(element)); }); }, rotate: function() { var css, deg = 0, previousTime = +new Date(), interval = setInterval(function() { var currentTime = +new Date(), delta = (currentTime - previousTime) / 1000, loadingIcon = document.getElementById('loadingIcon'); if (loadingIcon) { previousTime = currentTime; deg = Math.round((deg + delta * 360) % 360 / 30) * 30; css = 'rotate(' + deg + 'deg)'; loadingIcon.style.MozTransform = css; loadingIcon.style.MSTransform = css; loadingIcon.style.OTransform = css; loadingIcon.style.WebkitTransform = css; } else { clearInterval(interval); } }, 83); }, setTheme: function(theme) { app.user.theme = theme; app.db(app.user); (Ox.$('#icon') || Ox.$('').attr({ id: 'icon', rel: 'shortcut icon', type: 'image/png' }).appendTo(Ox.$('head'))).attr({ href: app.getSRC('icon') }); app.$ui.logo && app.$ui.logo .attr({src: app.getSRC('logo')}) .css(app.getCSS('logo')); Ox.Theme ? Ox.Theme(theme) : Ox.$('body').addClass('OxTheme' + Ox.toTitleCase(theme) ); }, state: { animating: false, loaded: false }, toggle: function() { !app.state.animating && app.url.set( app.url.get().page ? { page: '', item: '' } : { page: app.user.previousPage, item: app.user.previousPage in app.user.item ? app.user.item[app.user.previousPage] : '' } ); }, ui: { doc: function() { return Ox.DocPanel({ element: $('
') .addClass('page') .css({ margin: '32px', width: window.innerWidth - 640 + 'px' }) .html(app.html.documentation), examples: app.data.docItems ? void 0 : app.data.examples, examplesPath: app.data.docItems ? void 0 : 'examples/', files: app.data.docItems ? void 0 : app.data.documentation, getModule: function(item) { var file = item.file.replace(/^dev\//, ''); return file.split('/')[0]; }, getSection: function(item) { var file = item.file.replace(/^dev\//, ''); return item.section || file.split('/')[2].split('.')[0]; }, items: app.data.docItems || void 0, path: 'dev/', references: /\b(Ox\.[\w\$]+)\b/g, replace: [app.re.code], results: app.data.testResults || void 0, selected: app.user.item.doc, showTests: true }) .bindEvent({ example: function(data) { app.url.set({ page: 'examples', item: {examples: data.id} }); }, select: function(data) { app.user.item.doc = data.id; app.db(app.user); app.url.set(); } }) .bindEventOnce({ load: function(data) { app.data.docItems = data.items; }, tests: function(data) { app.data.testResults = data.results; } }); }, examples: function() { return Ox.ExamplePanel({ element: $('
') .addClass('page') .css({ margin: '32px', width: window.innerWidth - 640 + 'px' }) .html(app.html.examples), examples: app.data.examples, path: 'examples/', references: /\b(Ox\.[\w\$]+)\b/g, replaceCode: [app.re.code], replaceComment: [app.re.comment], selected: app.user.item.examples }) .bindEvent({ select: function(data) { app.user.item.examples = data.id; app.db(app.user); app.url.set(); } }); }, label: function() { return Ox.Label({ textAlign: 'center', title: 'A JavaScript Library for Web Applications', width: 256 }) .addClass('label animate') .css({ paddingTop: '4px', paddingBottom: '4px', borderRadius: '6px' }) .on({ click: app.toggle }); }, loading: function() { return Ox.$('') .addClass('loading') .attr({id: 'loadingIcon', src: app.getSRC('loading')}) .css(app.getCSS('loading')); }, logo: function() { return Ox.$('') .addClass('logo animate') .attr({src: app.getSRC('logo')}) .css(app.getCSS('logo')); }, menu: function() { var $menu = Ox.ButtonGroup({ buttons: app.data.pages, min: 0, selectable: true, }) .addClass('menu animate') .bindEvent({ change: function(data) { if (data.value) { app.url.set({page: data.value}); } } }) app.patchButtonGroup($menu); return $menu; }, page: function(page, replace) { var $element = Ox.Container(); $('
') .addClass('OxSelectable page') .html(app.html[page].replace(app.re.version[0], app.re.version[1])) .appendTo($element); return $element; }, panel: function() { var $panel = Ox.TabPanel({ content: function(id) { return app.$ui[id] = app.ui[id] ? app.ui[id]() : app.ui.page(id); }, size: 36, tabs: app.data.pages }) .bindEvent({ change: function(data) { if (app.state.loaded) { app.user.page = data.selected; app.db(app.user); app.url.set(); } } }), $buttonGroup = $panel.find('.OxButtonGroup').css({ top: '6px' }); app.patchButtonGroup($buttonGroup); return $panel; }, readme: function() { var $list = Ox.Container().css({overflowY: 'scroll'}), $text = Ox.Container().addClass('OxSerif OxSelectable text'), self = {}, that = Ox.SplitPanel({ elements: [ {element: $list, size: 256}, {element: $text} ], orientation: 'horizontal' }, self) .addClass('readme'); Ox.sortBy(app.data.readme, '-date').forEach(function(item, i) { var $item = $('
') .addClass('item') .attr({id: 'readme_' + item.id}) .css({ width: 224 - Ox.UI.SCROLLBAR_SIZE + 'px' }) .on({ click: function(e) { if (!$(this).is('.selected')) { selectItem(item.id); } else if (e.metaKey) { selectItem(); } } }) .appendTo($list); $('
') .addClass('OxSerif title') .html(item.title) .appendTo($item); $('
') .addClass('OxSerif OxLight date') .html(Ox.formatDate(item.date, '%B %e, %Y', true)) .appendTo($item); }); selectItem(app.user.item.readme); function selectItem(id) { $('.readme .item.selected').removeClass('selected'); id && $('#readme_' + id).addClass('selected'); Ox.get('readme/html/' + (id || '_readme') + '.html', function(html) { $text.empty() .append( id ? html : $('
') .addClass('page') .css({ margin: '16px', width: window.innerWidth - 640 + 'px' }) .html(html) ) .find('.code').each(function() { var $this = $(this); $this.replaceWith( Ox.SyntaxHighlighter({ source: $this.text() }) .attr({id: $this.attr('id')}) ); }); }); app.user.item.readme = id; app.db(app.user); app.url.set(); } self.setOption = function(key, value) { if (key == 'selected') { selectItem(value); } } return that; }, screen: function() { return Ox.$('
').addClass('screen animate'); }, switch: function() { var $switch = Ox.ButtonGroup({ buttons: [ {id: 'classic', title: 'Light'}, {id: 'modern', title: 'Dark'} ], selectable: true, value: app.user.theme }) .addClass('switch animate') .bindEvent({ change: function(data) { app.setTheme(data.value); } }); app.patchButtonGroup($switch); return $switch; }, warning: function() { return $('
') .addClass('warning') .html( 'Aw, snap! This website requires an up-to-date, HTML5-compliant web browser. ' + 'It should work fine in current versions of ' + 'Chrome,' + 'Firefox ' + 'and Safari, ' + 'or Internet Explorer with Chrome Frame installed. ' + 'To proceed at your own risk, click on the logo above.' ); } }, url: { get: function() { var split = window.location.hash.slice(1).split('/'); return {page: split[0], item: split[1] || ''}; }, set: function(data) { data = data || app.user; window.location.hash = data.page + ( data.item && data.item[data.page] ? '/' + data.item[data.page] : '' ); return app; } }, urlchange: function() { var url = app.url.get(); app.user.previousPage = app.user.page; app.user.page = url.page; if (url.item && url.page in app.user.item) { app.user.item[url.page] = url.item; } app.db(app.user); if (app.user.page != app.user.previousPage) { app.$ui.panel.select(app.user.page); } if (url.item) { app.$ui[url.page] && app.$ui[url.page].options({selected: url.item}); } if (!app.user.page || !app.user.previousPage) { app.animate(); } }, user: {} }; app.init(); window.oxjs = app; });