diff --git a/sites/all/modules/gui/materiobasemod/materio_user.module b/sites/all/modules/gui/materiobasemod/materio_user.module index 7beaace2..863a4c7a 100755 --- a/sites/all/modules/gui/materiobasemod/materio_user.module +++ b/sites/all/modules/gui/materiobasemod/materio_user.module @@ -146,7 +146,7 @@ function materio_user_block_view($delta = '') { break; case 'front_link': $block['subject'] = ''; - $block['content'] = l(''.t('home').'', '', array('html'=>true)); + $block['content'] = l(''.t('home').'', '', array('html'=>true)); break; } return $block; diff --git a/sites/all/themes/gui/materiobasetheme/.sass-cache/717d9e279c4e218b7de53140fde49b287dcd16a4/layout.scssc b/sites/all/themes/gui/materiobasetheme/.sass-cache/717d9e279c4e218b7de53140fde49b287dcd16a4/layout.scssc index 4c75ffe3..aeefbf83 100644 Binary files a/sites/all/themes/gui/materiobasetheme/.sass-cache/717d9e279c4e218b7de53140fde49b287dcd16a4/layout.scssc and b/sites/all/themes/gui/materiobasetheme/.sass-cache/717d9e279c4e218b7de53140fde49b287dcd16a4/layout.scssc differ diff --git a/sites/all/themes/gui/materiobasetheme/.sass-cache/717d9e279c4e218b7de53140fde49b287dcd16a4/misc.scssc b/sites/all/themes/gui/materiobasetheme/.sass-cache/717d9e279c4e218b7de53140fde49b287dcd16a4/misc.scssc index 79b081a5..900582ff 100644 Binary files a/sites/all/themes/gui/materiobasetheme/.sass-cache/717d9e279c4e218b7de53140fde49b287dcd16a4/misc.scssc and b/sites/all/themes/gui/materiobasetheme/.sass-cache/717d9e279c4e218b7de53140fde49b287dcd16a4/misc.scssc differ diff --git a/sites/all/themes/gui/materiobasetheme/.sass-cache/717d9e279c4e218b7de53140fde49b287dcd16a4/styles.scssc b/sites/all/themes/gui/materiobasetheme/.sass-cache/717d9e279c4e218b7de53140fde49b287dcd16a4/styles.scssc index 59a5c5e8..8bfe666a 100644 Binary files a/sites/all/themes/gui/materiobasetheme/.sass-cache/717d9e279c4e218b7de53140fde49b287dcd16a4/styles.scssc and b/sites/all/themes/gui/materiobasetheme/.sass-cache/717d9e279c4e218b7de53140fde49b287dcd16a4/styles.scssc differ diff --git a/sites/all/themes/gui/materiobasetheme/bower.json b/sites/all/themes/gui/materiobasetheme/bower.json new file mode 100644 index 00000000..4c0445d5 --- /dev/null +++ b/sites/all/themes/gui/materiobasetheme/bower.json @@ -0,0 +1,23 @@ +{ + "name": "materiobasetheme", + "version": "1.0.0", + "authors": [ + "sarah garcin " + ], + "license": "MIT", + "homepage": "http://materio.com", + "ignore": [ + "**/.*", + "node_modules", + "bower_components", + "test", + "tests" + ], + "dependencies": { + "foundation": "~5.5.1", + "history.js": "~1.8.0", + "jquery.columnizer": "~1.6.2", + "jquery.hotkeys": "jeresig/jquery.hotkeys#~0.2.0", + "jquery.lazyload": "~1.9.5" + } +} diff --git a/sites/all/themes/gui/materiobasetheme/bower_components/history.js/.bower.json b/sites/all/themes/gui/materiobasetheme/bower_components/history.js/.bower.json new file mode 100644 index 00000000..18fdc9da --- /dev/null +++ b/sites/all/themes/gui/materiobasetheme/bower_components/history.js/.bower.json @@ -0,0 +1,15 @@ +{ + "name": "history.js", + "version": "1.8.0", + "homepage": "https://github.com/browserstate/history.js", + "_release": "1.8.0", + "_resolution": { + "type": "version", + "tag": "1.8.0", + "commit": "6c6c8b951b03fa725adb11b1087d73b0b6f0ac82" + }, + "_source": "git://github.com/browserstate/history.js.git", + "_target": "~1.8.0", + "_originalSource": "history.js", + "_direct": true +} \ No newline at end of file diff --git a/sites/all/themes/gui/materiobasetheme/bower_components/history.js/.gitignore b/sites/all/themes/gui/materiobasetheme/bower_components/history.js/.gitignore new file mode 100644 index 00000000..ebb24a33 --- /dev/null +++ b/sites/all/themes/gui/materiobasetheme/bower_components/history.js/.gitignore @@ -0,0 +1,4 @@ +.build +/node_modules +/.idea +npm-debug.log diff --git a/sites/all/themes/gui/materiobasetheme/bower_components/history.js/History.md b/sites/all/themes/gui/materiobasetheme/bower_components/history.js/History.md new file mode 100644 index 00000000..8b1d44b4 --- /dev/null +++ b/sites/all/themes/gui/materiobasetheme/bower_components/history.js/History.md @@ -0,0 +1,141 @@ +## History + +- v1.8b2 - June 22 2013 + - Introduced uncompressed bundled files #287 + - Copied component.json to bower.json #291 and used right tag #286 + - Fixed wrong argument passed to History.getHash() #305, #297, #292 (@Izkata) + +- v1.8b1 - May 31 2013 + - Fixed "encoded string automatically unencoded on html5 browsers" #282, #236, #272 + +- v1.8a4 - February 13 2013 + - Fixed coffee script warnings (ExtJS & Dojo adapter, IE 6 iFrame) + - Updated qUnit to release 1.11.0, jQuery to release 1.9.1 + +- v1.8a3 - February 5 2013 + - Added tests for Dojo and ExtJS + - Changed setting of title and url + - Testing status + - All HTML5 Native Adapter fail in all browsers on Test 10 + - All other HTML5 tests work fine + - All other HTML4 tests fail in Test 4 (in IE) + +- v1.8a2 - January 21 2013 + - Fixed hashchange / statechange triggers: e.g. if a user in a HTML5 browser clicks a link, statechange is fired, in a HTML4 browser only hashchange, but state has also changed + - UTF8 / url encoding / decoding tested and so resolved: #64, #107, #108, #162, #177, #187, #205, #207, #210, #228, #251 + - Fixed #244 + +- v1.8a1 - January 19 2013 + - Pass options to `init()` as json is now supported + - Added unicode demo + - Introduced `getCurrentIndex()`, so you can get previous state by `History.getStateByIndex(getCurrentIndex()-1)` + - Fixed HTML4 endless loop when url starts with a slash (e.g. /welcome/hello) #239, #232, #185 + - Bundled and compressed all scripts + - Responsed (and therefore solved) or old issues from balupton repository: #250, #242, #238, #234, #224, #213, #206, #195, #183, #181, #180, #179, #175, #168 + - Fixed (or merged and therefore fixed) old issues from balupton repository: #248, #239, #236, #235, #229, #221, #220, #218, #215, #214, #212, #203, #191, #189, #172, #171, #166 + - Feedback for UTF8 / url encode issues necessary, related problems (thanks to riyad) + - #64, #107, #108, #162, #177, #187, #205, #207, #210, #228 + +- v1.7.2 - January 18 2013 + - Updated project README + - Integrated ExtJS Adapter (thanks to @seanadkinson!) + - Merged from forks + - added option to force no suid (@hrunting, @sbearcsiro) + - provide a consistent URI-encoded document.location.href (@hrunting, @sbearcsiro) + - Change History.getHash to return consistent hash, ala History.getLocationHref (@sbearcsiro) + - Fix an issue where HTML4 replaceState wasn't firing when SUIDs were disabled and the url didn't change (@sbearcsiro) + - Make extractId ignore the fragment if one is present (normally the hash is passed without an fragment) (@sbearcsiro) + - Remove all encoding / decoding of URLs except when creating or extracting a fragment, based on the assumption that all inputs to replaceState / pushState are appropriately encoded (@sbearcsiro) + - Change escapeHash/unescapeHash methods to use encodeURI/decodeURI instead of window.escape/unescape (@sbearcsiro) + - Fixed issue #158 (@sbearcsiro) + - isEmptyObject should use hasOwnProperty: prevents from always returning true if the Object.prototype is extended (@Alexander Johansson) + - Add potential fix for IE8 not returning full hashed url from getLocationHref when hash contains encoded characters (@sbearcsiro) + - Match current W3C popState event semantics for HTML4 (@STRML) + - Added History.options.html4Mode for easier debugging (@gigafied) + - Added History.options.delayInit (Boolean). (@gigafied) + - Added error testing and quota relief for sessionStorage.setItem (@jamie-pate) + - Fix IE 6 HTTPS warning (@Daniel15) + - Fixed bug in html4 pushState function which left History in a busy state (@joelarson4) + - Disable session storage if it's present but not working, thanks to @paulschreiber (@sbearcsiro) + - Add Lakin Wecker's dojo adapter (@sbearcsiro) + - Add dojo 1.8 tests (@sbearcsiro) + - Change dojo adapter to not use dojo events, it seems to break other parts of dojo (@sbearcsiro) + - Removes stray spaces so that the build script can run. (@billmag) + - fixed an issue in Safari's Private Browsing mode where setItem throws an exception (@billmag) + - Adds better error handling for the quota exceeded problem seen with the iPad. (@billmag) + - Consolidated var in sessionStorage to the top of the function. Re-build compressed and bundled. (@billmag) + +- v1.7.1 - October 4 2011 + - Added a new native adapter which is framework agnostic (can be used with, or without any framework) + - Provided bundled files + - Added RightJS adapter + - Updated supported browser listing + - Added sessionStorage support in core instead of optional Amplify.js Store support + - Fixed issue with state id generation growing slower over time + - Closes #104, #95, #102, #92, #81, #90, #94, #93, #91, #67, #83, #54, #45 + +- v1.7.0 - April 1 2011 + - Added `History.enabled` property (refer to usage section). This reflects whether or not History.js is enabled for our particular browser. For instance, if we have not included support for a HTML4 browser and we are accessing through a HTML4 browser then `History.enabled` will be `false`. + - Added (optional but recommended) Data Persistance and Synchronisation Support thanks to [AppendTo's](http://appendto.com/) [Amplify.js](http://amplifyjs.com/) (refer to installation and compatibility sections for details) + - Made HTML5 SUIDs more transparent - [Reported](https://github.com/balupton/history.js/issues#issue/34) by [azago](https://github.com/azago) and [Mark Jaquith](http://markjaquith.com/) + - Fixed Session Storage Issue - Reported by a whole bunch of different people; [one](https://github.com/balupton/history.js/issues#issue/36), [two](https://github.com/balupton/history.js/issues#issue/37), [three](http://getsatisfaction.com/balupton/topics/history_js_1_6_losing_state_after_manual_page_reload) + - Fixed URL Encoding Issue - [Reported](https://github.com/balupton/history.js/issues/#issue/33) by [Rob Madole](http://robmadole.com/) + - Disabled support for IE6,7,8 when using the Prototype Adapter (there is nothing we can do about this, it is due to a bug in the prototype library) - [Reported](https://github.com/balupton/history.js/issues#issue/39) by [Sindre Wimberger](http://sindre.at/) + - URLs in the State Hashes for HTML4 Browsers are now even shorter - [Discussion](https://github.com/balupton/history.js/issues#issue/28) + - Fixed a issue with the MooTools Adapter and JSON with IE7 and IE8 + +- v1.6.0 - March 22 2011 + - Added Zepto adapter thanks to [Matt Garrett](http://twitter.com/#!/matthewgarrett) + - The readme now references the supported versions of the libraries we use + - Updated vendors to the most recent versions. jQuery 1.5.1 and Mootools 1.3.1 + - Reverted versions of Safari iOS prior to version 4.3 to be HTML4 browsers, Safari iOS 4.3 is a HTML5 browser + - Refined code in History.js and its adapters + - Fixed issue with extra state being inserted on Safari 5 requiring an extra click on the back button to go home - [Reported](https://github.com/balupton/history.js/issues#issue/17) by [Rob Madole](http://robmadole.com/) + - Fixed issue with Safari 5 and Safari iOS 4 sometimes failing to apply the state change under busy conditions - Solution conceived with [Matt Garrett](http://twitter.com/matthewgarrett) + - Fixed issue with HTML4 browsers requiring a query-string in the urls of states - [Reported](https://github.com/balupton/history.js/issues#issue/26) by [azago](https://github.com/azago) + - Fixed issue with HTML4 browsers requiring title in the states in order to use state data - [Reported](https://github.com/balupton/history.js/issues#issue/25) by [Jonathan McLaughlin](http://system-werks.com/) + - Fixed issue with HTML4 browsers failing is a state is pushed/replaced twice in a row - [Reported](https://github.com/balupton/history.js/issues#issue/17) by [Joey Baker](http://byjoeybaker.com/) + - **B/C BREAK:** The `statechange` event now only fires if the state has changed; it no longer fires on page initialisation. This is following the [Firefox 4 History API Changes](http://hacks.mozilla.org/2011/03/history-api-changes-in-firefox-4/) which we agree with - this breaks standard, but makes more sense. + +- v1.5.0 - February 12 2011 + - Moved to UglifyJS instead of Google Closure + - Split HTML4 functionality from HTML5 functionality + - Installation details have changed (the filenames are different) + +- v1.4.1 - February 10 2011 + - Added HTML History API Support for Safari 5 and Safari iOS 4.2.1 + - Cleaned code a bit (mostly with unit tests) + +- v1.4.0 - February 10 2011 + - Unit Testing now uses [QUnit](http://docs.jquery.com/Qunit) + - Corrected Safari 5 Support + - Now uses queues instead of timeouts + - This means the API works exactly as expected, no more need to wrap calls in timeouts + - Included a Subscribe Form in the Demo for Version Updates via Email + - Small updates to Documentation + +- v1.3.1 - February 4 2011 + - Improved Documentation + +- v1.3.0 - January 31 2011 + - Support for cleaner HTML4 States + +- v1.2.1 - January 30 2011 + - Fixed History.log always being called - [reported by dlee](https://github.com/balupton/history.js/issues/#issue/2) + - Re-Added `History.go(index)` support + +- v1.2.0 - January 25 2011 + - Support for HTML4 States in HTML5 Browsers (added test) + - Updates of Documentation + +- v1.1.0 - January 24 2011 + - Developed a series of automated test cases + - Fixed issue with traditional anchors + - Fixed issue with differing replaceState functionality in HTML4 Browsers + - Fixed issue with Google Chrome artefacts being carried over to the initial state + - Provided `onstatechange` and `onanchorchange` events + +- v1.0.0 - January 22 2011 + - Supported `History.pushState` and `History.replaceState` degradation + - Supported jQuery, MooTools and Prototype Frameworks + diff --git a/sites/all/themes/gui/materiobasetheme/bower_components/history.js/README.md b/sites/all/themes/gui/materiobasetheme/bower_components/history.js/README.md new file mode 100644 index 00000000..260b06a5 --- /dev/null +++ b/sites/all/themes/gui/materiobasetheme/bower_components/history.js/README.md @@ -0,0 +1,292 @@ +Welcome to History.js
v1.8b2, June 22 2013 +================== + +[![Flattr this project](http://api.flattr.com/button/flattr-badge-large.png)](https://flattr.com/submit/auto?user_id=balupton&url=https://github.com/browserstate/history.js&title=History.js&language=&tags=github&category=software) + +## News +- 22/06/2013: Beta 2 of v1.8 is released. Fixes and uncompressed bundled files. +- 31/05/2013: Beta 1 of v1.8 is released. Fixes. +- 14/02/2013: Alpha 4 of v1.8 is released. Fixes. +- 05/02/2013: Alpha 3 of v1.8 is released. Tests updated. +- 21/01/2013: Alpha 2 of v1.8 is released. Correct statechange behaviour. +- 19/01/2013: Alpha 1 of v1.8 is released. Started to categorize old balupton's issues. + +### History + +See the [`History.md`](https://github.com/browserstate/history.js/blob/master/History.md#files) file for a detailed list of features, changes, solved issues and bugs + +### Involve + +Please create an issue if something doesn't work or if there is a browser specific bug. I'll try to fix it as soon as possible. Please send me your Pull requests if you have a nice solution! I'm also going to review old issues in balupton's repository and try to solve them too. + +## Aims + +- Follow the [HTML5 History API](https://developer.mozilla.org/en/DOM/Manipulating_the_browser_history) as much as possible +- Provide a cross-compatible experience for all HTML5 Browsers (they all implement the HTML5 History API a little bit differently causing different behaviours and sometimes bugs - History.js fixes this ensuring the experience is as expected / the same / great throughout the HTML5 browsers) +- Provide a backwards-compatible experience for all HTML4 Browsers using a hash-fallback (including continued support for the HTML5 History API's `data`, `title`, `pushState` and `replaceState`) with the option to [remove HTML4 support if it is not right for your application](https://github.com/browserstate/history.js/wiki/Intelligent-State-Handling) +- Provide a forwards-compatible experience for HTML4 States to HTML5 States (so if a hash-fallbacked url is accessed by a HTML5 browser it is naturally transformed into its non-hashed url equivalent) +- Provide support for as many javascript frameworks as possible via adapters; especially [Dojo](http://dojotoolkit.org/), [ExtJS](http://www.sencha.com/), [jQuery](http://jquery.com/), [MooTools](http://mootools.net/), [Right.js](http://rightjs.org/) and [Zepto](http://zeptojs.com/). + +## Usage + +### Instant + +To ajaxify your entire website with the HTML5 History API, History.js and jQuery the [Ajaxify Script](https://github.com/browserstate/ajaxify) is all you need. It's that easy. + +### Ruby On Rails + +If you are using Rails, then the easiest way for you to try History.js would be to use [Wiselinks](https://github.com/igor-alexandrov/wiselinks) gem. Wiselinks integrates into Rails application and allows you to start using History.js with three lines of code. + +### Working with History.js directly + +``` javascript +(function(window,undefined){ + + // Bind to StateChange Event + History.Adapter.bind(window,'statechange',function(){ // Note: We are using statechange instead of popstate + var State = History.getState(); // Note: We are using History.getState() instead of event.state + }); + + // Change our States + History.pushState({state:1}, "State 1", "?state=1"); // logs {state:1}, "State 1", "?state=1" + History.pushState({state:2}, "State 2", "?state=2"); // logs {state:2}, "State 2", "?state=2" + History.replaceState({state:3}, "State 3", "?state=3"); // logs {state:3}, "State 3", "?state=3" + History.pushState(null, null, "?state=4"); // logs {}, '', "?state=4" + History.back(); // logs {state:3}, "State 3", "?state=3" + History.back(); // logs {state:1}, "State 1", "?state=1" + History.back(); // logs {}, "Home Page", "?" + History.go(2); // logs {state:3}, "State 3", "?state=3" + +})(window); +``` + +### How would the above operations look in a HTML5 Browser? + +1. www.mysite.com +1. www.mysite.com/?state=1 +1. www.mysite.com/?state=2 +1. www.mysite.com/?state=3 +1. www.mysite.com/?state=4 +1. www.mysite.com/?state=3 +1. www.mysite.com/?state=1 +1. www.mysite.com +1. www.mysite.com/?state=3 + +> Note: These urls also work in HTML4 browsers and Search Engines. So no need for the hashbang (`#!`) fragment-identifier that google ["recommends"](https://github.com/browserstate/history.js/wiki/Intelligent-State-Handling). + +### How would they look in a HTML4 Browser? + +1. www.mysite.com +1. www.mysite.com/#?state=1&_suid=1 +1. www.mysite.com/#?state=2&_suid=2 +1. www.mysite.com/#?state=3&_suid=3 +1. www.mysite.com/#?state=4 +1. www.mysite.com/#?state=3&_suid=3 +1. www.mysite.com/#?state=1&_suid=1 +1. www.mysite.com +1. www.mysite.com/#?state=3&_suid=3 + +> Note 1: These urls also work in HTML5 browsers - we use `replaceState` to transform these HTML4 states into their HTML5 equivalents so the user won't even notice :-) +> +> Note 2: These urls will be automatically url-encoded in IE6 to prevent certain browser-specific bugs. +> +> Note 3: Support for HTML4 browsers (this hash fallback) is optional [- why supporting HTML4 browsers could be either good or bad based on my app's use cases](https://github.com/browserstate/history.js/wiki/Intelligent-State-Handling) + +### What's the deal with the SUIDs used in the HTML4 States? + +- SUIDs (State Unique Identifiers) are used when we utilise a `title` and/or `data` in our state. Adding a SUID allows us to associate particular states with data and titles while keeping the urls as simple as possible (don't worry it's all tested, working and a lot smarter than I'm making it out to be). +- If you aren't utilising `title` or `data` then we don't even include a SUID (as there is no need for it) - as seen by State 4 above :-) +- We also shrink the urls to make sure that the smallest url will be used. For instance we will adjust `http://www.mysite.com/#http://www.mysite.com/projects/History.js` to become `http://www.mysite.com/#/projects/History.js` automatically. (again tested, working, and smarter). +- It works with domains, subdomains, subdirectories, whatever - doesn't matter where you put it. It's smart. +- Safari 5 will also have a SUID appended to the URL, it is entirely transparent but just a visible side-effect. It is required to fix a bug with Safari 5. + +### Is there a working demo? + +- Sure is, give it a download and navigate to the demo directory in your browser :-) +- If you are after something a bit more adventurous than a end-user demo, open up the tests directory in your browser and editor - it'll rock your world and show all the vast use cases that History.js supports. + +## Download & Installation + +- Download History.js and upload it to your webserver. Download links: [tar.gz](https://github.com/browserstate/history.js/tarball/master) or [zip](https://github.com/browserstate/history.js/zipball/master) + +- Include History.js + + - For [Dojo](http://dojotoolkit.org/) v1.8+ + + ``` html + + ``` + + - For [ExtJs](http://www.sencha.com/) v1.8+ + + ``` html + + ``` + + - For [jQuery](http://jquery.com/) v1.3+ + + ``` html + + ``` + + - For [Mootools](http://mootools.net/) v1.3+ + + ``` html + + ``` + + - For [Right.js](http://rightjs.org/) v2.2+ + + ``` html + + ``` + + - For [Zepto](http://zeptojs.com/) v0.5+ + + ``` html + + ``` + + - For everything else + + ``` html + + ``` + +> Note: If you want to only support HTML5 Browsers and not HTML4 Browsers (so no hash fallback support) then just change the `/html4+html5/` part in the urls to just `/html5/`. See [Why supporting HTML4 browsers could be either good or bad based on my app's use cases](https://github.com/browserstate/history.js/wiki/Intelligent-State-Handling) + + +## Get Updates + +- For Commit RSS/Atom Updates: + - You can subscribe via the [GitHub Commit Atom Feed](http://feeds.feedburner.com/historyjs) +- For GitHub News Feed Updates: + - You can click the "watch" button up the top right of History.js's [GitHub Project Page](https://github.com/browserstate/history.js) + + +## Get Support + +- History.js is maintained by people like you. If you find a bug, report it to the [GitHub Issue Tracker](https://github.com/browserstate/history.js/issues). If you've fixed a bug submit a [Pull Request](https://github.com/browserstate/history.js/pulls) and add your fork to the [Network Wiki Page](https://github.com/browserstate/history.js/wiki/Network). + +- If you would like paid support and trainings, or have job offers, then refer to the [Network Wiki Page](https://github.com/browserstate/history.js/wiki/Network). If you are qualified with History.js, then be sure to add your details to that page too. + +- If your company uses History.js on your projects, and would like to see it grow and prosper (better documentation, bugfixes, upgrades, maintenance, etc.) and would love to become a corporate sponsor then do email sponsor@bevry.me + +- If you would like free support for History.js, then [post your question](http://stackoverflow.com/questions/ask) on [Stackoverflow](http://stackoverflow.com/about) and be sure to use the `history.js` tag when asking your question. + +- If you've created a website that uses History.js, or know of one, be sure to add it to the [Showcase Wiki Page](https://github.com/browserstate/history.js/wiki/Showcase). + +- If you'd love to +1 or like this project, then be sure to tweet about it and click the "watch" button up the top of its [Project Page](https://github.com/browserstate/history.js). + +- For anything else, refer to the [History.js GitHub Wiki Site](https://github.com/browserstate/history.js/wiki). + +Thanks! every bit of help really does make a difference! + + +## Browsers: Tested and Working In + +### HTML5 Browsers + +- Firefox 4+ +- Chrome 8+ +- Opera 11.5+ +- Safari 5.0+ +- Safari iOS 4.3+ + +### HTML4 Browsers + +- IE 6, 7, 8, 9, (10) +- Firefox 3 +- Opera 10, 11.0 +- Safari 4 +- Safari iOS 4.2, 4.1, 4.0, 3.2 + + +## Exposed API + +### Functions + +#### States +- `History.pushState(data,title,url)`
Pushes a new state to the browser; `data` can be null or an object, `title` can be null or a string, `url` must be a string +- `History.replaceState(data,title,url)`
Replaces the existing state with a new state to the browser; `data` can be null or an object, `title` can be null or a string, `url` must be a string +- `History.getState()`
Gets the current state of the browser, returns an object with `data`, `title` and `url` +- `History.getStateByIndex`
Gets a state by the index +- `History.getCurrentIndex`
Gets the current index +- `History.getHash()`
Gets the current hash of the browser + +#### Adapter +- `History.Adapter.bind(element,event,callback)`
A framework independent event binder, you may either use this or your framework's native event binder. +- `History.Adapter.trigger(element,event)`
A framework independent event trigger, you may either use this or your framework's native event trigger. +- `History.Adapter.onDomLoad(callback)`
A framework independent onDomLoad binder, you may either use this or your framework's native onDomLoad binder. + +#### Navigation +- `History.back()`
Go back once through the history (same as hitting the browser's back button) +- `History.forward()`
Go forward once through the history (same as hitting the browser's forward button) +- `History.go(X)`
If X is negative go back through history X times, if X is positive go forwards through history X times + +#### Debug +- `History.log(...)`
Logs messages to the console, the log element, and fallbacks to alert if neither of those two exist +- `History.debug(...)`
Same as `History.log` but only runs if `History.debug.enable === true` + + + +### Options + +- `History.options.hashChangeInterval`
How long should the interval be before hashchange checks +- `History.options.safariPollInterval`
How long should the interval be before safari poll checks +- `History.options.doubleCheckInterval`
How long should the interval be before we perform a double check +- `History.options.disableSuid`
Force History not to append suid +- `History.options.storeInterval`
How long should we wait between store calls +- `History.options.busyDelay`
How long should we wait between busy events +- `History.options.debug`
If true will enable debug messages to be logged +- `History.options.initialTitle`
What is the title of the initial state +- `History.options.html4Mode`
If true, will force HTMl4 mode (hashtags) +- `History.options.delayInit`
Want to override default options and call init manually. + +### Events + +- `window.onstatechange`
Fired when the state of the page changes (does not include hash changes) +- `window.onanchorchange`
Fired when the anchor of the page changes (does not include state hashes) + + +## Known Issues +- Opera 11 fails to create history entries when under stressful loads (events fire perfectly, just the history events fail) - there is nothing we can do about this +- Mercury iOS fails to apply url changes (hashes and HTML5 History API states) - there is nothing we can do about this + + +## Notes on Compatibility + +- History.js **solves** the following browser bugs: + - HTML5 Browsers + - Chrome 8 sometimes does not contain the correct state data when traversing back to the initial state + - Safari 5, Safari iOS 4 and Firefox 3 and 4 do not fire the `onhashchange` event when the page is loaded with a hash + - Safari 5 and Safari iOS 4 do not fire the `onpopstate` event when the hash has changed unlike the other browsers + - Safari 5 and Safari iOS 4 fail to return to the correct state once a hash is replaced by a `replaceState` call / [bug report](https://bugs.webkit.org/show_bug.cgi?id=56249) + - Safari 5 and Safari iOS 4 sometimes fail to apply the state change under busy conditions / [bug report](https://bugs.webkit.org/show_bug.cgi?id=42940) + - Google Chrome 8,9,10 and Firefox 4 prior to the RC will always fire `onpopstate` once the page has loaded / [change recommendation](http://hacks.mozilla.org/2011/03/history-api-changes-in-firefox-4/) + - Safari iOS 4.0, 4.1, 4.2 have a working HTML5 History API - although the actual back buttons of the browsers do not work, therefore we treat them as HTML4 browsers + - None of the HTML5 browsers actually utilise the `title` argument to the `pushState` and `replaceState` calls + - HTML4 Browsers + - Old browsers like MSIE 6,7 and Firefox 2 do not have a `onhashchange` event + - MSIE 6 and 7 sometimes do not apply a hash even it was told to (requiring a second call to the apply function) + - Non-Opera HTML4 browsers sometimes do not apply the hash when the hash is not `urlencoded` + - All Browsers + - State data and titles do not persist once the site is left and then returned (includes page refreshes) + - State titles are never applied to the `document.title` +- ReplaceState functionality is emulated in HTML4 browsers by discarding the replaced state, so when the discarded state is accessed it is skipped using the appropriate `History.back()` / `History.forward()` call +- Data persistance and synchronisation works like so: Every second or so, the SUIDs and URLs of the states will synchronise between the store and the local session. When a new session opens a familiar state (via the SUID or the URL) and it is not found locally then it will attempt to load the last known stored state with that information. +- URLs will be unescaped to the maximum, so for instance the URL `?key=a%20b%252c` will become `?key=a b c`. This is to ensure consistency between browser url encodings. +- Changing the hash of the page causes `onpopstate` to fire (this is expected/standard functionality). To ensure correct compatibility between HTML5 and HTML4 browsers the following events have been created: + - `window.onstatechange`: this is the same as the `onpopstate` event except it does not fire for traditional anchors + - `window.onanchorchange`: this is the same as the `onhashchange` event except it does not fire for states + + +## History + +You can discover the history inside the [History.md](https://github.com/browserstate/history.js/blob/master/History.md#files) file + + +## License + +Licensed under the [New BSD License](http://opensource.org/licenses/BSD-3-Clause) +
Copyright © 2011+ [Benjamin Arthur Lupton](http://balupton.com) diff --git a/sites/all/themes/gui/materiobasetheme/bower_components/history.js/bower.json b/sites/all/themes/gui/materiobasetheme/bower_components/history.js/bower.json new file mode 100644 index 00000000..fbe41338 --- /dev/null +++ b/sites/all/themes/gui/materiobasetheme/bower_components/history.js/bower.json @@ -0,0 +1,4 @@ +{ + "name": "history.js", + "version": "1.8.0" +} diff --git a/sites/all/themes/gui/materiobasetheme/bower_components/history.js/buildr-uncompressed.coffee b/sites/all/themes/gui/materiobasetheme/bower_components/history.js/buildr-uncompressed.coffee new file mode 100644 index 00000000..99cc0f40 --- /dev/null +++ b/sites/all/themes/gui/materiobasetheme/bower_components/history.js/buildr-uncompressed.coffee @@ -0,0 +1,372 @@ +# Requires +buildr = require 'buildr' +util = require 'util' + +# Options +options = + watch: false + compress: false + +# Configs +configs = + standard: + # Options + name: 'standard' + watch: options.watch + + # Paths + srcPath: __dirname+'/scripts/uncompressed' + + # Checking + checkScripts: true + jshintOptions: + browser: true + laxbreak: true + boss: true + undef: true + onevar: true + strict: true + noarg: true + + # Compression (without outPath only the generated bundle files are compressed) + compressScripts: options.compress # Array or true or false + + other: [ + + # ----------------------------- + # Dojo Toolkit + + { + # Options + name: 'html4+html5+dojo' + watch: options.watch + + # Paths + srcPath: __dirname+'/scripts/uncompressed' + + # Compression (without outPath only the generated bundle files are compressed) + compressScripts: options.compress # Array or true or false + + # Order + scriptsOrder: [ + 'json2.js' + 'history.adapter.dojo.js' + 'history.html4.js' + 'history.js' + ] + + # Bundling + bundleScriptPath: __dirname+'/scripts/bundled-uncompressed/html4+html5/dojo.history.js' + } + { + # Options + name: 'html5+dojo' + watch: options.watch + + # Paths + srcPath: __dirname+'/scripts/uncompressed' + + # Compression (without outPath only the generated bundle files are compressed) + compressScripts: options.compress # Array or true or false + + # Order + scriptsOrder: [ + 'history.adapter.dojo.js' + 'history.js' + ] + + # Bundling + bundleScriptPath: __dirname+'/scripts/bundled-uncompressed/html5/dojo.history.js' + } + + # ----------------------------- + # ExtJS + + { + # Options + name: 'html4+html5+extjs' + watch: options.watch + + # Paths + srcPath: __dirname+'/scripts/uncompressed' + + # Compression (without outPath only the generated bundle files are compressed) + compressScripts: options.compress # Array or true or false + + # Order + scriptsOrder: [ + 'json2.js' + 'history.adapter.extjs.js' + 'history.html4.js' + 'history.js' + ] + + # Bundling + bundleScriptPath: __dirname+'/scripts/bundled-uncompressed/html4+html5/extjs.history.js' + } + { + # Options + name: 'html5+extjs' + watch: options.watch + + # Paths + srcPath: __dirname+'/scripts/uncompressed' + + # Compression (without outPath only the generated bundle files are compressed) + compressScripts: options.compress # Array or true or false + + # Order + scriptsOrder: [ + 'history.adapter.extjs.js' + 'history.js' + ] + + # Bundling + bundleScriptPath: __dirname+'/scripts/bundled-uncompressed/html5/extjs.history.js' + } + + # ----------------------------- + # JQUERY + + { + # Options + name: 'html4+html5+jquery' + watch: options.watch + + # Paths + srcPath: __dirname+'/scripts/uncompressed' + + # Compression (without outPath only the generated bundle files are compressed) + compressScripts: options.compress # Array or true or false + + # Order + scriptsOrder: [ + 'json2.js' + 'history.adapter.jquery.js' + 'history.html4.js' + 'history.js' + ] + + # Bundling + bundleScriptPath: __dirname+'/scripts/bundled-uncompressed/html4+html5/jquery.history.js' + } + { + # Options + name: 'html5+jquery' + watch: options.watch + + # Paths + srcPath: __dirname+'/scripts/uncompressed' + + # Compression (without outPath only the generated bundle files are compressed) + compressScripts: options.compress # Array or true or false + + # Order + scriptsOrder: [ + 'history.adapter.jquery.js' + 'history.js' + ] + + # Bundling + bundleScriptPath: __dirname+'/scripts/bundled-uncompressed/html5/jquery.history.js' + } + + + # ----------------------------- + # MOOTOOLS + + { + # Options + name: 'html4+html5+mootools' + watch: options.watch + + # Paths + srcPath: __dirname+'/scripts/uncompressed' + + # Compression (without outPath only the generated bundle files are compressed) + compressScripts: options.compress # Array or true or false + + # Order + scriptsOrder: [ + 'json2.js' + 'history.adapter.mootools.js' + 'history.html4.js' + 'history.js' + ] + + # Bundling + bundleScriptPath: __dirname+'/scripts/bundled-uncompressed/html4+html5/mootools.history.js' + } + { + # Options + name: 'html5+mootools' + watch: options.watch + + # Paths + srcPath: __dirname+'/scripts/uncompressed' + + # Compression (without outPath only the generated bundle files are compressed) + compressScripts: options.compress # Array or true or false + + # Order + scriptsOrder: [ + 'history.adapter.mootools.js' + 'history.js' + ] + + # Bundling + bundleScriptPath: __dirname+'/scripts/bundled-uncompressed/html5/mootools.history.js' + } + + + # ----------------------------- + # NATIVE + + { + # Options + name: 'html4+html5+native' + watch: options.watch + + # Paths + srcPath: __dirname+'/scripts/uncompressed' + + # Compression (without outPath only the generated bundle files are compressed) + compressScripts: options.compress # Array or true or false + + # Order + scriptsOrder: [ + 'json2.js' + 'history.adapter.native.js' + 'history.html4.js' + 'history.js' + ] + + # Bundling + bundleScriptPath: __dirname+'/scripts/bundled-uncompressed/html4+html5/native.history.js' + } + { + # Options + name: 'html5+native' + watch: options.watch + + # Paths + srcPath: __dirname+'/scripts/uncompressed' + + # Compression (without outPath only the generated bundle files are compressed) + compressScripts: options.compress # Array or true or false + + # Order + scriptsOrder: [ + 'history.adapter.native.js' + 'history.js' + ] + + # Bundling + bundleScriptPath: __dirname+'/scripts/bundled-uncompressed/html5/native.history.js' + } + + + # ----------------------------- + # RIGHT.JS + + { + # Options + name: 'html4+html5+right' + watch: options.watch + + # Paths + srcPath: __dirname+'/scripts/uncompressed' + + # Compression (without outPath only the generated bundle files are compressed) + compressScripts: options.compress # Array or true or false + + # Order + scriptsOrder: [ + 'json2.js' + 'history.adapter.right.js' + 'history.html4.js' + 'history.js' + ] + + # Bundling + bundleScriptPath: __dirname+'/scripts/bundled-uncompressed/html4+html5/right.history.js' + } + { + # Options + name: 'html5+right' + watch: options.watch + + # Paths + srcPath: __dirname+'/scripts/uncompressed' + + # Compression (without outPath only the generated bundle files are compressed) + compressScripts: options.compress # Array or true or false + + # Order + scriptsOrder: [ + 'history.adapter.right.js' + 'history.js' + ] + + # Bundling + bundleScriptPath: __dirname+'/scripts/bundled-uncompressed/html5/right.history.js' + } + + + # ----------------------------- + # ZEPTO + + { + # Options + name: 'html4+html5+zepto' + watch: options.watch + + # Paths + srcPath: __dirname+'/scripts/uncompressed' + + # Compression (without outPath only the generated bundle files are compressed) + compressScripts: options.compress # Array or true or false + + # Order + scriptsOrder: [ + 'json2.js' + 'history.adapter.zepto.js' + 'history.html4.js' + 'history.js' + ] + + # Bundling + bundleScriptPath: __dirname+'/scripts/bundled-uncompressed/html4+html5/zepto.history.js' + } + { + # Options + name: 'html5+zepto' + watch: options.watch + + # Paths + srcPath: __dirname+'/scripts/uncompressed' + + # Compression (without outPath only the generated bundle files are compressed) + compressScripts: options.compress # Array or true or false + + # Order + scriptsOrder: [ + 'history.adapter.zepto.js' + 'history.js' + ] + + # Bundling + bundleScriptPath: __dirname+'/scripts/bundled-uncompressed/html5/zepto.history.js' + } + ] + +# Standard +standardConfig = configs.standard +standardConfig.successHandler = -> + for config in configs.other + buildrInstance = buildr.createInstance config + buildrInstance.process() + +# Process +standardBuildr = buildr.createInstance configs.standard +standardBuildr.process() diff --git a/sites/all/themes/gui/materiobasetheme/bower_components/history.js/buildr.coffee b/sites/all/themes/gui/materiobasetheme/bower_components/history.js/buildr.coffee new file mode 100644 index 00000000..08da95c9 --- /dev/null +++ b/sites/all/themes/gui/materiobasetheme/bower_components/history.js/buildr.coffee @@ -0,0 +1,373 @@ +# Requires +buildr = require 'buildr' +util = require 'util' + +# Options +options = + watch: false + compress: true + +# Configs +configs = + standard: + # Options + name: 'standard' + watch: options.watch + + # Paths + srcPath: __dirname+'/scripts/uncompressed' + outPath: __dirname+'/scripts/compressed' + + # Checking + checkScripts: true + jshintOptions: + browser: true + laxbreak: true + boss: true + undef: true + onevar: true + strict: true + noarg: true + + # Compression (without outPath only the generated bundle files are compressed) + compressScripts: options.compress # Array or true or false + + other: [ + + # ----------------------------- + # Dojo Toolkit + + { + # Options + name: 'html4+html5+dojo' + watch: options.watch + + # Paths + srcPath: __dirname+'/scripts/uncompressed' + + # Compression (without outPath only the generated bundle files are compressed) + compressScripts: options.compress # Array or true or false + + # Order + scriptsOrder: [ + 'json2.js' + 'history.adapter.dojo.js' + 'history.html4.js' + 'history.js' + ] + + # Bundling + bundleScriptPath: __dirname+'/scripts/bundled/html4+html5/dojo.history.js' + } + { + # Options + name: 'html5+dojo' + watch: options.watch + + # Paths + srcPath: __dirname+'/scripts/uncompressed' + + # Compression (without outPath only the generated bundle files are compressed) + compressScripts: options.compress # Array or true or false + + # Order + scriptsOrder: [ + 'history.adapter.dojo.js' + 'history.js' + ] + + # Bundling + bundleScriptPath: __dirname+'/scripts/bundled/html5/dojo.history.js' + } + + # ----------------------------- + # ExtJS + + { + # Options + name: 'html4+html5+extjs' + watch: options.watch + + # Paths + srcPath: __dirname+'/scripts/uncompressed' + + # Compression (without outPath only the generated bundle files are compressed) + compressScripts: options.compress # Array or true or false + + # Order + scriptsOrder: [ + 'json2.js' + 'history.adapter.extjs.js' + 'history.html4.js' + 'history.js' + ] + + # Bundling + bundleScriptPath: __dirname+'/scripts/bundled/html4+html5/extjs.history.js' + } + { + # Options + name: 'html5+extjs' + watch: options.watch + + # Paths + srcPath: __dirname+'/scripts/uncompressed' + + # Compression (without outPath only the generated bundle files are compressed) + compressScripts: options.compress # Array or true or false + + # Order + scriptsOrder: [ + 'history.adapter.extjs.js' + 'history.js' + ] + + # Bundling + bundleScriptPath: __dirname+'/scripts/bundled/html5/extjs.history.js' + } + + # ----------------------------- + # JQUERY + + { + # Options + name: 'html4+html5+jquery' + watch: options.watch + + # Paths + srcPath: __dirname+'/scripts/uncompressed' + + # Compression (without outPath only the generated bundle files are compressed) + compressScripts: options.compress # Array or true or false + + # Order + scriptsOrder: [ + 'json2.js' + 'history.adapter.jquery.js' + 'history.html4.js' + 'history.js' + ] + + # Bundling + bundleScriptPath: __dirname+'/scripts/bundled/html4+html5/jquery.history.js' + } + { + # Options + name: 'html5+jquery' + watch: options.watch + + # Paths + srcPath: __dirname+'/scripts/uncompressed' + + # Compression (without outPath only the generated bundle files are compressed) + compressScripts: options.compress # Array or true or false + + # Order + scriptsOrder: [ + 'history.adapter.jquery.js' + 'history.js' + ] + + # Bundling + bundleScriptPath: __dirname+'/scripts/bundled/html5/jquery.history.js' + } + + + # ----------------------------- + # MOOTOOLS + + { + # Options + name: 'html4+html5+mootools' + watch: options.watch + + # Paths + srcPath: __dirname+'/scripts/uncompressed' + + # Compression (without outPath only the generated bundle files are compressed) + compressScripts: options.compress # Array or true or false + + # Order + scriptsOrder: [ + 'json2.js' + 'history.adapter.mootools.js' + 'history.html4.js' + 'history.js' + ] + + # Bundling + bundleScriptPath: __dirname+'/scripts/bundled/html4+html5/mootools.history.js' + } + { + # Options + name: 'html5+mootools' + watch: options.watch + + # Paths + srcPath: __dirname+'/scripts/uncompressed' + + # Compression (without outPath only the generated bundle files are compressed) + compressScripts: options.compress # Array or true or false + + # Order + scriptsOrder: [ + 'history.adapter.mootools.js' + 'history.js' + ] + + # Bundling + bundleScriptPath: __dirname+'/scripts/bundled/html5/mootools.history.js' + } + + + # ----------------------------- + # NATIVE + + { + # Options + name: 'html4+html5+native' + watch: options.watch + + # Paths + srcPath: __dirname+'/scripts/uncompressed' + + # Compression (without outPath only the generated bundle files are compressed) + compressScripts: options.compress # Array or true or false + + # Order + scriptsOrder: [ + 'json2.js' + 'history.adapter.native.js' + 'history.html4.js' + 'history.js' + ] + + # Bundling + bundleScriptPath: __dirname+'/scripts/bundled/html4+html5/native.history.js' + } + { + # Options + name: 'html5+native' + watch: options.watch + + # Paths + srcPath: __dirname+'/scripts/uncompressed' + + # Compression (without outPath only the generated bundle files are compressed) + compressScripts: options.compress # Array or true or false + + # Order + scriptsOrder: [ + 'history.adapter.native.js' + 'history.js' + ] + + # Bundling + bundleScriptPath: __dirname+'/scripts/bundled/html5/native.history.js' + } + + + # ----------------------------- + # RIGHT.JS + + { + # Options + name: 'html4+html5+right' + watch: options.watch + + # Paths + srcPath: __dirname+'/scripts/uncompressed' + + # Compression (without outPath only the generated bundle files are compressed) + compressScripts: options.compress # Array or true or false + + # Order + scriptsOrder: [ + 'json2.js' + 'history.adapter.right.js' + 'history.html4.js' + 'history.js' + ] + + # Bundling + bundleScriptPath: __dirname+'/scripts/bundled/html4+html5/right.history.js' + } + { + # Options + name: 'html5+right' + watch: options.watch + + # Paths + srcPath: __dirname+'/scripts/uncompressed' + + # Compression (without outPath only the generated bundle files are compressed) + compressScripts: options.compress # Array or true or false + + # Order + scriptsOrder: [ + 'history.adapter.right.js' + 'history.js' + ] + + # Bundling + bundleScriptPath: __dirname+'/scripts/bundled/html5/right.history.js' + } + + + # ----------------------------- + # ZEPTO + + { + # Options + name: 'html4+html5+zepto' + watch: options.watch + + # Paths + srcPath: __dirname+'/scripts/uncompressed' + + # Compression (without outPath only the generated bundle files are compressed) + compressScripts: options.compress # Array or true or false + + # Order + scriptsOrder: [ + 'json2.js' + 'history.adapter.zepto.js' + 'history.html4.js' + 'history.js' + ] + + # Bundling + bundleScriptPath: __dirname+'/scripts/bundled/html4+html5/zepto.history.js' + } + { + # Options + name: 'html5+zepto' + watch: options.watch + + # Paths + srcPath: __dirname+'/scripts/uncompressed' + + # Compression (without outPath only the generated bundle files are compressed) + compressScripts: options.compress # Array or true or false + + # Order + scriptsOrder: [ + 'history.adapter.zepto.js' + 'history.js' + ] + + # Bundling + bundleScriptPath: __dirname+'/scripts/bundled/html5/zepto.history.js' + } + ] + +# Standard +standardConfig = configs.standard +standardConfig.successHandler = -> + for config in configs.other + buildrInstance = buildr.createInstance config + buildrInstance.process() + +# Process +standardBuildr = buildr.createInstance configs.standard +standardBuildr.process() diff --git a/sites/all/themes/gui/materiobasetheme/bower_components/history.js/component.json b/sites/all/themes/gui/materiobasetheme/bower_components/history.js/component.json new file mode 100644 index 00000000..fbe41338 --- /dev/null +++ b/sites/all/themes/gui/materiobasetheme/bower_components/history.js/component.json @@ -0,0 +1,4 @@ +{ + "name": "history.js", + "version": "1.8.0" +} diff --git a/sites/all/themes/gui/materiobasetheme/bower_components/history.js/demo/bcherry-orig.html b/sites/all/themes/gui/materiobasetheme/bower_components/history.js/demo/bcherry-orig.html new file mode 100644 index 00000000..43672f49 --- /dev/null +++ b/sites/all/themes/gui/materiobasetheme/bower_components/history.js/demo/bcherry-orig.html @@ -0,0 +1,58 @@ + + + + + + + WebKit is Dropping HTML5 "popstate" Events + + + + + + + + + + + + + +
+

There's a bug in the HTML5 "popstate" event, as implemented in WebKit (Safari and Chrome). View this page in one of those browsers. Your browser has had history entries added from #0 to #19 (you should start at #19). Hitting back/forward will navigate through these. On each URL, the large number above should reflect the hash value. If you hit back/forward quickly, you'll notice that your number gets out of sync with the URL. This is because WebKit is dropping popstate events (they are not firing). It seems to happen when outbound network requests are in progress when the user navigates in their browser happens. In this case, your browser is downloading an image that takes 1s to serve on every popstate, so you'll have to wait 1s between backs/forwards to have the feature work correctly. You could also cause constant network traffic by putting an image download in a setInterval, in which case your popstate events will never fire. This implementation simulates an AJAX application that makes a network request when you navigate between URLs using pushState/popstate. View the source for more info.

+

This was filed as Bug 42940 with WebKit on July 24, 2010. The Firefox 4 beta does not have this bug, which is good news.

+

This is put together by Ben Cherry. Ben is a front-end engineer at Twitter, and you can follow him at @bcherry.

+ + + diff --git a/sites/all/themes/gui/materiobasetheme/bower_components/history.js/demo/bcherry.html b/sites/all/themes/gui/materiobasetheme/bower_components/history.js/demo/bcherry.html new file mode 100644 index 00000000..309f4d44 --- /dev/null +++ b/sites/all/themes/gui/materiobasetheme/bower_components/history.js/demo/bcherry.html @@ -0,0 +1,62 @@ + + + + + + + WebKit is Dropping HTML5 "popstate" Events + + + + + + + + + + + + + +
+

There's a bug in the HTML5 "popstate" event, as implemented in WebKit (Safari and Chrome). View this page in one of those browsers. Your browser has had history entries added from #0 to #19 (you should start at #19). Hitting back/forward will navigate through these. On each URL, the large number above should reflect the hash value. If you hit back/forward quickly, you'll notice that your number gets out of sync with the URL. This is because WebKit is dropping popstate events (they are not firing). It seems to happen when outbound network requests are in progress when the user navigates in their browser happens. In this case, your browser is downloading an image that takes 1s to serve on every popstate, so you'll have to wait 1s between backs/forwards to have the feature work correctly. You could also cause constant network traffic by putting an image download in a setInterval, in which case your popstate events will never fire. This implementation simulates an AJAX application that makes a network request when you navigate between URLs using pushState/popstate. View the source for more info.

+

This was filed as Bug 42940 with WebKit on July 24, 2010. The Firefox 4 beta does not have this bug, which is good news.

+

This is put together by Ben Cherry. Ben is a front-end engineer at Twitter, and you can follow him at @bcherry.

+

This bug was fixed in History.js by Benjamin Lupton. Benjamin is a freelance web 2.0 consultant, and you can follow him at @balupton.

+ + + diff --git a/sites/all/themes/gui/materiobasetheme/bower_components/history.js/demo/chrome.html b/sites/all/themes/gui/materiobasetheme/bower_components/history.js/demo/chrome.html new file mode 100644 index 00000000..a2791a31 --- /dev/null +++ b/sites/all/themes/gui/materiobasetheme/bower_components/history.js/demo/chrome.html @@ -0,0 +1,37 @@ + + + Chrome History API Data Artifact + + +

This demo demonstrates an issue with Google Chrome versions 8-10 (possibly 11) where if you push a state with data, then do history.back to the initial state, the event.state will contain the pushed states data instead of being null.

+

Note: The issue requires a clean history list, as such this should always be opened in a new tab/window where there are no prior history items.

+

Reported by Benjamin Lupton author of History.js

+ + + + + + diff --git a/sites/all/themes/gui/materiobasetheme/bower_components/history.js/demo/index.html b/sites/all/themes/gui/materiobasetheme/bower_components/history.js/demo/index.html new file mode 100644 index 00000000..7e538b5c --- /dev/null +++ b/sites/all/themes/gui/materiobasetheme/bower_components/history.js/demo/index.html @@ -0,0 +1,84 @@ + + + + + + + History.js + + + + + + + + + +
+ +

History.js

+

History.js gracefully supports the HTML5 History/State APIs (pushState, replaceState, onPopState) in all browsers. Including continued support for data, titles, replaceState. Supports jQuery, MooTools and Prototype. For HTML5 browsers this means that you can modify the URL directly, without needing to use hashes anymore. For HTML4 browsers it will revert back to using the old onhashchange functionality.

+ + + + + +

Click through the buttons in order and you'll get the results demonstrated in the README.md file.

+ + +
    +
+ + + +
+ + diff --git a/sites/all/themes/gui/materiobasetheme/bower_components/history.js/demo/native-auto.html b/sites/all/themes/gui/materiobasetheme/bower_components/history.js/demo/native-auto.html new file mode 100644 index 00000000..1ea10ffa --- /dev/null +++ b/sites/all/themes/gui/materiobasetheme/bower_components/history.js/demo/native-auto.html @@ -0,0 +1,43 @@ + + + + + + + diff --git a/sites/all/themes/gui/materiobasetheme/bower_components/history.js/demo/native.html b/sites/all/themes/gui/materiobasetheme/bower_components/history.js/demo/native.html new file mode 100644 index 00000000..010f89a0 --- /dev/null +++ b/sites/all/themes/gui/materiobasetheme/bower_components/history.js/demo/native.html @@ -0,0 +1,62 @@ + + + HTML5 History API Demo + + + +
+
+ + + diff --git a/sites/all/themes/gui/materiobasetheme/bower_components/history.js/demo/navigator.html b/sites/all/themes/gui/materiobasetheme/bower_components/history.js/demo/navigator.html new file mode 100644 index 00000000..f9b15844 --- /dev/null +++ b/sites/all/themes/gui/materiobasetheme/bower_components/history.js/demo/navigator.html @@ -0,0 +1,23 @@ + + + + + + Navigator Output + + + + + + + + diff --git a/sites/all/themes/gui/materiobasetheme/bower_components/history.js/demo/safari.html b/sites/all/themes/gui/materiobasetheme/bower_components/history.js/demo/safari.html new file mode 100644 index 00000000..5da17755 --- /dev/null +++ b/sites/all/themes/gui/materiobasetheme/bower_components/history.js/demo/safari.html @@ -0,0 +1,61 @@ + + + Safari Hash ReplaceState History Traversal Bug + + +

This demo demonstrates an issue with Safari 5.0.4 (6533.20.27) handing of hashes and replace state. When a hash is set, and then replaced using replaceState the history list are then broken, when traversing back the hash does not change.

+

Note: The issue requires a clean history list, as such this should always be opened in a new tab/window where there are no prior history items.

+

Reported by Benjamin Lupton author of History.js

+ + + + + + + diff --git a/sites/all/themes/gui/materiobasetheme/bower_components/history.js/demo/unicode.html b/sites/all/themes/gui/materiobasetheme/bower_components/history.js/demo/unicode.html new file mode 100644 index 00000000..e34e562f --- /dev/null +++ b/sites/all/themes/gui/materiobasetheme/bower_components/history.js/demo/unicode.html @@ -0,0 +1,79 @@ + + + + + + + History.js + + + + + + + + + +
+ +

History.js

+

History.js gracefully supports unicode.

+ + + + + +
    +
+ + + +
+ + diff --git a/sites/all/themes/gui/materiobasetheme/bower_components/history.js/license.txt b/sites/all/themes/gui/materiobasetheme/bower_components/history.js/license.txt new file mode 100644 index 00000000..647bfd26 --- /dev/null +++ b/sites/all/themes/gui/materiobasetheme/bower_components/history.js/license.txt @@ -0,0 +1,10 @@ +Copyright (c) 2011, Benjamin Arthur Lupton +All rights reserved. + +Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: + + • Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. + • Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. + • Neither the name of Benjamin Arthur Lupton nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. \ No newline at end of file diff --git a/sites/all/themes/gui/materiobasetheme/bower_components/history.js/package.json b/sites/all/themes/gui/materiobasetheme/bower_components/history.js/package.json new file mode 100644 index 00000000..cc6f23d0 --- /dev/null +++ b/sites/all/themes/gui/materiobasetheme/bower_components/history.js/package.json @@ -0,0 +1,67 @@ +{ + "name": "history.js", + "version": "1.8.0", + "description": "History.js gracefully supports the HTML5 History/State APIs (pushState, replaceState, onPopState) in all browsers. Including continued support for data, titles, replaceState. Supports jQuery, MooTools and Prototype. For HTML5 browsers this means that you can modify the URL directly, without needing to use hashes anymore. For HTML4 browsers it will revert back to using the old onhashchange functionality.", + "homepage": "https://github.com/browserstate/history.js", + "keywords": [ + "javascript", + "html5 history api", + "hashchange", + "popstate", + "pushstate", + "replacestate", + "hashes", + "hashbang" + ], + "author": { + "name": "Benjamin Lupton", + "email": "b@lupton.cc", + "web": "http://balupton.com" + }, + "maintainers": [ + { + "name": "Benjamin Lupton", + "email": "b@lupton.cc", + "web": "http://balupton.com" + }, + { + "name": "Andreas Bernhard", + "email": "andreas@bernhard.im", + "web": "http://www.bs-infosys.com" + } + ], + "contributors": [ + { + "name": "Benjamin Lupton", + "email": "b@lupton.cc", + "web": "http://balupton.com" + }, + { + "name": "Andreas Bernhard", + "email": "andreas@bernhard.im", + "web": "http://www.bs-infosys.com" + } + ], + "bugs": { + "web": "https://github.com/browserstate/history.js/issues" + }, + "licenses": [ + { + "type": "New-BSD", + "url": "http://creativecommons.org/licenses/BSD/" + } + ], + "repository": { + "type": "git", + "url": "http://github.com/browserstate/history.js.git" + }, + "dependencies": { + "buildr": "0.8.x" + }, + "engines": { + }, + "directories": { + "out": "./scripts/compressed", + "src": "./scripts/uncompressed" + } +} \ No newline at end of file diff --git a/sites/all/themes/gui/materiobasetheme/bower_components/history.js/scripts/bundled-uncompressed/html4+html5/dojo.history.js b/sites/all/themes/gui/materiobasetheme/bower_components/history.js/scripts/bundled-uncompressed/html4+html5/dojo.history.js new file mode 100644 index 00000000..6b8b1d66 --- /dev/null +++ b/sites/all/themes/gui/materiobasetheme/bower_components/history.js/scripts/bundled-uncompressed/html4+html5/dojo.history.js @@ -0,0 +1,3335 @@ +/* + json2.js + 2012-10-08 + + Public Domain. + + NO WARRANTY EXPRESSED OR IMPLIED. USE AT YOUR OWN RISK. + + See http://www.JSON.org/js.html + + + This code should be minified before deployment. + See http://javascript.crockford.com/jsmin.html + + USE YOUR OWN COPY. IT IS EXTREMELY UNWISE TO LOAD CODE FROM SERVERS YOU DO + NOT CONTROL. + + + This file creates a global JSON object containing two methods: stringify + and parse. + + JSON.stringify(value, replacer, space) + value any JavaScript value, usually an object or array. + + replacer an optional parameter that determines how object + values are stringified for objects. It can be a + function or an array of strings. + + space an optional parameter that specifies the indentation + of nested structures. If it is omitted, the text will + be packed without extra whitespace. If it is a number, + it will specify the number of spaces to indent at each + level. If it is a string (such as '\t' or ' '), + it contains the characters used to indent at each level. + + This method produces a JSON text from a JavaScript value. + + When an object value is found, if the object contains a toJSON + method, its toJSON method will be called and the result will be + stringified. A toJSON method does not serialize: it returns the + value represented by the name/value pair that should be serialized, + or undefined if nothing should be serialized. The toJSON method + will be passed the key associated with the value, and this will be + bound to the value + + For example, this would serialize Dates as ISO strings. + + Date.prototype.toJSON = function (key) { + function f(n) { + // Format integers to have at least two digits. + return n < 10 ? '0' + n : n; + } + + return this.getUTCFullYear() + '-' + + f(this.getUTCMonth() + 1) + '-' + + f(this.getUTCDate()) + 'T' + + f(this.getUTCHours()) + ':' + + f(this.getUTCMinutes()) + ':' + + f(this.getUTCSeconds()) + 'Z'; + }; + + You can provide an optional replacer method. It will be passed the + key and value of each member, with this bound to the containing + object. The value that is returned from your method will be + serialized. If your method returns undefined, then the member will + be excluded from the serialization. + + If the replacer parameter is an array of strings, then it will be + used to select the members to be serialized. It filters the results + such that only members with keys listed in the replacer array are + stringified. + + Values that do not have JSON representations, such as undefined or + functions, will not be serialized. Such values in objects will be + dropped; in arrays they will be replaced with null. You can use + a replacer function to replace those with JSON values. + JSON.stringify(undefined) returns undefined. + + The optional space parameter produces a stringification of the + value that is filled with line breaks and indentation to make it + easier to read. + + If the space parameter is a non-empty string, then that string will + be used for indentation. If the space parameter is a number, then + the indentation will be that many spaces. + + Example: + + text = JSON.stringify(['e', {pluribus: 'unum'}]); + // text is '["e",{"pluribus":"unum"}]' + + + text = JSON.stringify(['e', {pluribus: 'unum'}], null, '\t'); + // text is '[\n\t"e",\n\t{\n\t\t"pluribus": "unum"\n\t}\n]' + + text = JSON.stringify([new Date()], function (key, value) { + return this[key] instanceof Date ? + 'Date(' + this[key] + ')' : value; + }); + // text is '["Date(---current time---)"]' + + + JSON.parse(text, reviver) + This method parses a JSON text to produce an object or array. + It can throw a SyntaxError exception. + + The optional reviver parameter is a function that can filter and + transform the results. It receives each of the keys and values, + and its return value is used instead of the original value. + If it returns what it received, then the structure is not modified. + If it returns undefined then the member is deleted. + + Example: + + // Parse the text. Values that look like ISO date strings will + // be converted to Date objects. + + myData = JSON.parse(text, function (key, value) { + var a; + if (typeof value === 'string') { + a = +/^(\d{4})-(\d{2})-(\d{2})T(\d{2}):(\d{2}):(\d{2}(?:\.\d*)?)Z$/.exec(value); + if (a) { + return new Date(Date.UTC(+a[1], +a[2] - 1, +a[3], +a[4], + +a[5], +a[6])); + } + } + return value; + }); + + myData = JSON.parse('["Date(09/09/2001)"]', function (key, value) { + var d; + if (typeof value === 'string' && + value.slice(0, 5) === 'Date(' && + value.slice(-1) === ')') { + d = new Date(value.slice(5, -1)); + if (d) { + return d; + } + } + return value; + }); + + + This is a reference implementation. You are free to copy, modify, or + redistribute. +*/ + +/*jslint evil: true, regexp: true */ + +/*members "", "\b", "\t", "\n", "\f", "\r", "\"", JSON, "\\", apply, + call, charCodeAt, getUTCDate, getUTCFullYear, getUTCHours, + getUTCMinutes, getUTCMonth, getUTCSeconds, hasOwnProperty, join, + lastIndex, length, parse, prototype, push, replace, slice, stringify, + test, toJSON, toString, valueOf +*/ + + +// Create a JSON object only if one does not already exist. We create the +// methods in a closure to avoid creating global variables. + +if (typeof JSON !== 'object') { + JSON = {}; +} + +(function () { + 'use strict'; + + function f(n) { + // Format integers to have at least two digits. + return n < 10 ? '0' + n : n; + } + + if (typeof Date.prototype.toJSON !== 'function') { + + Date.prototype.toJSON = function (key) { + + return isFinite(this.valueOf()) + ? this.getUTCFullYear() + '-' + + f(this.getUTCMonth() + 1) + '-' + + f(this.getUTCDate()) + 'T' + + f(this.getUTCHours()) + ':' + + f(this.getUTCMinutes()) + ':' + + f(this.getUTCSeconds()) + 'Z' + : null; + }; + + String.prototype.toJSON = + Number.prototype.toJSON = + Boolean.prototype.toJSON = function (key) { + return this.valueOf(); + }; + } + + var cx = /[\u0000\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g, + escapable = /[\\\"\x00-\x1f\x7f-\x9f\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g, + gap, + indent, + meta = { // table of character substitutions + '\b': '\\b', + '\t': '\\t', + '\n': '\\n', + '\f': '\\f', + '\r': '\\r', + '"' : '\\"', + '\\': '\\\\' + }, + rep; + + + function quote(string) { + +// If the string contains no control characters, no quote characters, and no +// backslash characters, then we can safely slap some quotes around it. +// Otherwise we must also replace the offending characters with safe escape +// sequences. + + escapable.lastIndex = 0; + return escapable.test(string) ? '"' + string.replace(escapable, function (a) { + var c = meta[a]; + return typeof c === 'string' + ? c + : '\\u' + ('0000' + a.charCodeAt(0).toString(16)).slice(-4); + }) + '"' : '"' + string + '"'; + } + + + function str(key, holder) { + +// Produce a string from holder[key]. + + var i, // The loop counter. + k, // The member key. + v, // The member value. + length, + mind = gap, + partial, + value = holder[key]; + +// If the value has a toJSON method, call it to obtain a replacement value. + + if (value && typeof value === 'object' && + typeof value.toJSON === 'function') { + value = value.toJSON(key); + } + +// If we were called with a replacer function, then call the replacer to +// obtain a replacement value. + + if (typeof rep === 'function') { + value = rep.call(holder, key, value); + } + +// What happens next depends on the value's type. + + switch (typeof value) { + case 'string': + return quote(value); + + case 'number': + +// JSON numbers must be finite. Encode non-finite numbers as null. + + return isFinite(value) ? String(value) : 'null'; + + case 'boolean': + case 'null': + +// If the value is a boolean or null, convert it to a string. Note: +// typeof null does not produce 'null'. The case is included here in +// the remote chance that this gets fixed someday. + + return String(value); + +// If the type is 'object', we might be dealing with an object or an array or +// null. + + case 'object': + +// Due to a specification blunder in ECMAScript, typeof null is 'object', +// so watch out for that case. + + if (!value) { + return 'null'; + } + +// Make an array to hold the partial results of stringifying this object value. + + gap += indent; + partial = []; + +// Is the value an array? + + if (Object.prototype.toString.apply(value) === '[object Array]') { + +// The value is an array. Stringify every element. Use null as a placeholder +// for non-JSON values. + + length = value.length; + for (i = 0; i < length; i += 1) { + partial[i] = str(i, value) || 'null'; + } + +// Join all of the elements together, separated with commas, and wrap them in +// brackets. + + v = partial.length === 0 + ? '[]' + : gap + ? '[\n' + gap + partial.join(',\n' + gap) + '\n' + mind + ']' + : '[' + partial.join(',') + ']'; + gap = mind; + return v; + } + +// If the replacer is an array, use it to select the members to be stringified. + + if (rep && typeof rep === 'object') { + length = rep.length; + for (i = 0; i < length; i += 1) { + if (typeof rep[i] === 'string') { + k = rep[i]; + v = str(k, value); + if (v) { + partial.push(quote(k) + (gap ? ': ' : ':') + v); + } + } + } + } else { + +// Otherwise, iterate through all of the keys in the object. + + for (k in value) { + if (Object.prototype.hasOwnProperty.call(value, k)) { + v = str(k, value); + if (v) { + partial.push(quote(k) + (gap ? ': ' : ':') + v); + } + } + } + } + +// Join all of the member texts together, separated with commas, +// and wrap them in braces. + + v = partial.length === 0 + ? '{}' + : gap + ? '{\n' + gap + partial.join(',\n' + gap) + '\n' + mind + '}' + : '{' + partial.join(',') + '}'; + gap = mind; + return v; + } + } + +// If the JSON object does not yet have a stringify method, give it one. + + if (typeof JSON.stringify !== 'function') { + JSON.stringify = function (value, replacer, space) { + +// The stringify method takes a value and an optional replacer, and an optional +// space parameter, and returns a JSON text. The replacer can be a function +// that can replace values, or an array of strings that will select the keys. +// A default replacer method can be provided. Use of the space parameter can +// produce text that is more easily readable. + + var i; + gap = ''; + indent = ''; + +// If the space parameter is a number, make an indent string containing that +// many spaces. + + if (typeof space === 'number') { + for (i = 0; i < space; i += 1) { + indent += ' '; + } + +// If the space parameter is a string, it will be used as the indent string. + + } else if (typeof space === 'string') { + indent = space; + } + +// If there is a replacer, it must be a function or an array. +// Otherwise, throw an error. + + rep = replacer; + if (replacer && typeof replacer !== 'function' && + (typeof replacer !== 'object' || + typeof replacer.length !== 'number')) { + throw new Error('JSON.stringify'); + } + +// Make a fake root object containing our value under the key of ''. +// Return the result of stringifying the value. + + return str('', {'': value}); + }; + } + + +// If the JSON object does not yet have a parse method, give it one. + + if (typeof JSON.parse !== 'function') { + JSON.parse = function (text, reviver) { + +// The parse method takes a text and an optional reviver function, and returns +// a JavaScript value if the text is a valid JSON text. + + var j; + + function walk(holder, key) { + +// The walk method is used to recursively walk the resulting structure so +// that modifications can be made. + + var k, v, value = holder[key]; + if (value && typeof value === 'object') { + for (k in value) { + if (Object.prototype.hasOwnProperty.call(value, k)) { + v = walk(value, k); + if (v !== undefined) { + value[k] = v; + } else { + delete value[k]; + } + } + } + } + return reviver.call(holder, key, value); + } + + +// Parsing happens in four stages. In the first stage, we replace certain +// Unicode characters with escape sequences. JavaScript handles many characters +// incorrectly, either silently deleting them, or treating them as line endings. + + text = String(text); + cx.lastIndex = 0; + if (cx.test(text)) { + text = text.replace(cx, function (a) { + return '\\u' + + ('0000' + a.charCodeAt(0).toString(16)).slice(-4); + }); + } + +// In the second stage, we run the text against regular expressions that look +// for non-JSON patterns. We are especially concerned with '()' and 'new' +// because they can cause invocation, and '=' because it can cause mutation. +// But just to be safe, we want to reject all unexpected forms. + +// We split the second stage into 4 regexp operations in order to work around +// crippling inefficiencies in IE's and Safari's regexp engines. First we +// replace the JSON backslash pairs with '@' (a non-JSON character). Second, we +// replace all simple value tokens with ']' characters. Third, we delete all +// open brackets that follow a colon or comma or that begin the text. Finally, +// we look to see that the remaining characters are only whitespace or ']' or +// ',' or ':' or '{' or '}'. If that is so, then the text is safe for eval. + + if (/^[\],:{}\s]*$/ + .test(text.replace(/\\(?:["\\\/bfnrt]|u[0-9a-fA-F]{4})/g, '@') + .replace(/"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g, ']') + .replace(/(?:^|:|,)(?:\s*\[)+/g, ''))) { + +// In the third stage we use the eval function to compile the text into a +// JavaScript structure. The '{' operator is subject to a syntactic ambiguity +// in JavaScript: it can begin a block or an object literal. We wrap the text +// in parens to eliminate the ambiguity. + + j = eval('(' + text + ')'); + +// In the optional fourth stage, we recursively walk the new structure, passing +// each name/value pair to a reviver function for possible transformation. + + return typeof reviver === 'function' + ? walk({'': j}, '') + : j; + } + +// If the text is not JSON parseable, then a SyntaxError is thrown. + + throw new SyntaxError('JSON.parse'); + }; + } +}());/** + * History.js Dojo Adapter + * + * Essentially the same as the native adapter but uses dojo/ready for the dom load callback. + * + * @author Benjamin Arthur Lupton + * @copyright 2010-2011 Benjamin Arthur Lupton + * @license New BSD License + */ + +// Closure +(function(window,undefined){ + "use strict"; + + // Localise Globals + var History = window.History = window.History||{}, + require = window.require; + + // Check Existence + if ( typeof History.Adapter !== 'undefined' ) { + throw new Error('History.js Adapter has already been loaded...'); + } + + // Add the Adapter + History.Adapter = { + /** + * History.Adapter.handlers[uid][eventName] = Array + */ + handlers: {}, + + /** + * History.Adapter._uid + * The current element unique identifier + */ + _uid: 1, + + /** + * History.Adapter.uid(element) + * @param {Element} element + * @return {String} uid + */ + uid: function(element){ + return element._uid || (element._uid = History.Adapter._uid++); + }, + + /** + * History.Adapter.bind(el,event,callback) + * @param {Element} element + * @param {String} eventName - custom and standard events + * @param {Function} callback + * @return + */ + bind: function(element,eventName,callback){ + // Prepare + var uid = History.Adapter.uid(element); + + // Apply Listener + History.Adapter.handlers[uid] = History.Adapter.handlers[uid] || {}; + History.Adapter.handlers[uid][eventName] = History.Adapter.handlers[uid][eventName] || []; + History.Adapter.handlers[uid][eventName].push(callback); + + // Bind Global Listener + element['on'+eventName] = (function(element,eventName){ + return function(event){ + History.Adapter.trigger(element,eventName,event); + }; + })(element,eventName); + }, + + /** + * History.Adapter.trigger(el,event) + * @param {Element} element + * @param {String} eventName - custom and standard events + * @param {Object} event - a object of event data + * @return + */ + trigger: function(element,eventName,event){ + // Prepare + event = event || {}; + var uid = History.Adapter.uid(element), + i,n; + + // Apply Listener + History.Adapter.handlers[uid] = History.Adapter.handlers[uid] || {}; + History.Adapter.handlers[uid][eventName] = History.Adapter.handlers[uid][eventName] || []; + + // Fire Listeners + for ( i=0,n=History.Adapter.handlers[uid][eventName].length; i + * @copyright 2010-2011 Benjamin Arthur Lupton + * @license New BSD License + */ + +(function(window,undefined){ + "use strict"; + + // ======================================================================== + // Initialise + + // Localise Globals + var + document = window.document, // Make sure we are using the correct document + setTimeout = window.setTimeout||setTimeout, + clearTimeout = window.clearTimeout||clearTimeout, + setInterval = window.setInterval||setInterval, + History = window.History = window.History||{}; // Public History Object + + // Check Existence + if ( typeof History.initHtml4 !== 'undefined' ) { + throw new Error('History.js HTML4 Support has already been loaded...'); + } + + + // ======================================================================== + // Initialise HTML4 Support + + // Initialise HTML4 Support + History.initHtml4 = function(){ + // Initialise + if ( typeof History.initHtml4.initialized !== 'undefined' ) { + // Already Loaded + return false; + } + else { + History.initHtml4.initialized = true; + } + + + // ==================================================================== + // Properties + + /** + * History.enabled + * Is History enabled? + */ + History.enabled = true; + + + // ==================================================================== + // Hash Storage + + /** + * History.savedHashes + * Store the hashes in an array + */ + History.savedHashes = []; + + /** + * History.isLastHash(newHash) + * Checks if the hash is the last hash + * @param {string} newHash + * @return {boolean} true + */ + History.isLastHash = function(newHash){ + // Prepare + var oldHash = History.getHashByIndex(), + isLast; + + // Check + isLast = newHash === oldHash; + + // Return isLast + return isLast; + }; + + /** + * History.isHashEqual(newHash, oldHash) + * Checks to see if two hashes are functionally equal + * @param {string} newHash + * @param {string} oldHash + * @return {boolean} true + */ + History.isHashEqual = function(newHash, oldHash){ + newHash = encodeURIComponent(newHash).replace(/%25/g, "%"); + oldHash = encodeURIComponent(oldHash).replace(/%25/g, "%"); + return newHash === oldHash; + }; + + /** + * History.saveHash(newHash) + * Push a Hash + * @param {string} newHash + * @return {boolean} true + */ + History.saveHash = function(newHash){ + // Check Hash + if ( History.isLastHash(newHash) ) { + return false; + } + + // Push the Hash + History.savedHashes.push(newHash); + + // Return true + return true; + }; + + /** + * History.getHashByIndex() + * Gets a hash by the index + * @param {integer} index + * @return {string} + */ + History.getHashByIndex = function(index){ + // Prepare + var hash = null; + + // Handle + if ( typeof index === 'undefined' ) { + // Get the last inserted + hash = History.savedHashes[History.savedHashes.length-1]; + } + else if ( index < 0 ) { + // Get from the end + hash = History.savedHashes[History.savedHashes.length+index]; + } + else { + // Get from the beginning + hash = History.savedHashes[index]; + } + + // Return hash + return hash; + }; + + + // ==================================================================== + // Discarded States + + /** + * History.discardedHashes + * A hashed array of discarded hashes + */ + History.discardedHashes = {}; + + /** + * History.discardedStates + * A hashed array of discarded states + */ + History.discardedStates = {}; + + /** + * History.discardState(State) + * Discards the state by ignoring it through History + * @param {object} State + * @return {true} + */ + History.discardState = function(discardedState,forwardState,backState){ + //History.debug('History.discardState', arguments); + // Prepare + var discardedStateHash = History.getHashByState(discardedState), + discardObject; + + // Create Discard Object + discardObject = { + 'discardedState': discardedState, + 'backState': backState, + 'forwardState': forwardState + }; + + // Add to DiscardedStates + History.discardedStates[discardedStateHash] = discardObject; + + // Return true + return true; + }; + + /** + * History.discardHash(hash) + * Discards the hash by ignoring it through History + * @param {string} hash + * @return {true} + */ + History.discardHash = function(discardedHash,forwardState,backState){ + //History.debug('History.discardState', arguments); + // Create Discard Object + var discardObject = { + 'discardedHash': discardedHash, + 'backState': backState, + 'forwardState': forwardState + }; + + // Add to discardedHash + History.discardedHashes[discardedHash] = discardObject; + + // Return true + return true; + }; + + /** + * History.discardedState(State) + * Checks to see if the state is discarded + * @param {object} State + * @return {bool} + */ + History.discardedState = function(State){ + // Prepare + var StateHash = History.getHashByState(State), + discarded; + + // Check + discarded = History.discardedStates[StateHash]||false; + + // Return true + return discarded; + }; + + /** + * History.discardedHash(hash) + * Checks to see if the state is discarded + * @param {string} State + * @return {bool} + */ + History.discardedHash = function(hash){ + // Check + var discarded = History.discardedHashes[hash]||false; + + // Return true + return discarded; + }; + + /** + * History.recycleState(State) + * Allows a discarded state to be used again + * @param {object} data + * @param {string} title + * @param {string} url + * @return {true} + */ + History.recycleState = function(State){ + //History.debug('History.recycleState', arguments); + // Prepare + var StateHash = History.getHashByState(State); + + // Remove from DiscardedStates + if ( History.discardedState(State) ) { + delete History.discardedStates[StateHash]; + } + + // Return true + return true; + }; + + + // ==================================================================== + // HTML4 HashChange Support + + if ( History.emulated.hashChange ) { + /* + * We must emulate the HTML4 HashChange Support by manually checking for hash changes + */ + + /** + * History.hashChangeInit() + * Init the HashChange Emulation + */ + History.hashChangeInit = function(){ + // Define our Checker Function + History.checkerFunction = null; + + // Define some variables that will help in our checker function + var lastDocumentHash = '', + iframeId, iframe, + lastIframeHash, checkerRunning, + startedWithHash = Boolean(History.getHash()); + + // Handle depending on the browser + if ( History.isInternetExplorer() ) { + // IE6 and IE7 + // We need to use an iframe to emulate the back and forward buttons + + // Create iFrame + iframeId = 'historyjs-iframe'; + iframe = document.createElement('iframe'); + + // Adjust iFarme + // IE 6 requires iframe to have a src on HTTPS pages, otherwise it will throw a + // "This page contains both secure and nonsecure items" warning. + iframe.setAttribute('id', iframeId); + iframe.setAttribute('src', '#'); + iframe.style.display = 'none'; + + // Append iFrame + document.body.appendChild(iframe); + + // Create initial history entry + iframe.contentWindow.document.open(); + iframe.contentWindow.document.close(); + + // Define some variables that will help in our checker function + lastIframeHash = ''; + checkerRunning = false; + + // Define the checker function + History.checkerFunction = function(){ + // Check Running + if ( checkerRunning ) { + return false; + } + + // Update Running + checkerRunning = true; + + // Fetch + var + documentHash = History.getHash(), + iframeHash = History.getHash(iframe.contentWindow.document); + + // The Document Hash has changed (application caused) + if ( documentHash !== lastDocumentHash ) { + // Equalise + lastDocumentHash = documentHash; + + // Create a history entry in the iframe + if ( iframeHash !== documentHash ) { + //History.debug('hashchange.checker: iframe hash change', 'documentHash (new):', documentHash, 'iframeHash (old):', iframeHash); + + // Equalise + lastIframeHash = iframeHash = documentHash; + + // Create History Entry + iframe.contentWindow.document.open(); + iframe.contentWindow.document.close(); + + // Update the iframe's hash + iframe.contentWindow.document.location.hash = History.escapeHash(documentHash); + } + + // Trigger Hashchange Event + History.Adapter.trigger(window,'hashchange'); + } + + // The iFrame Hash has changed (back button caused) + else if ( iframeHash !== lastIframeHash ) { + //History.debug('hashchange.checker: iframe hash out of sync', 'iframeHash (new):', iframeHash, 'documentHash (old):', documentHash); + + // Equalise + lastIframeHash = iframeHash; + + // If there is no iframe hash that means we're at the original + // iframe state. + // And if there was a hash on the original request, the original + // iframe state was replaced instantly, so skip this state and take + // the user back to where they came from. + if (startedWithHash && iframeHash === '') { + History.back(); + } + else { + // Update the Hash + History.setHash(iframeHash,false); + } + } + + // Reset Running + checkerRunning = false; + + // Return true + return true; + }; + } + else { + // We are not IE + // Firefox 1 or 2, Opera + + // Define the checker function + History.checkerFunction = function(){ + // Prepare + var documentHash = History.getHash()||''; + + // The Document Hash has changed (application caused) + if ( documentHash !== lastDocumentHash ) { + // Equalise + lastDocumentHash = documentHash; + + // Trigger Hashchange Event + History.Adapter.trigger(window,'hashchange'); + } + + // Return true + return true; + }; + } + + // Apply the checker function + History.intervalList.push(setInterval(History.checkerFunction, History.options.hashChangeInterval)); + + // Done + return true; + }; // History.hashChangeInit + + // Bind hashChangeInit + History.Adapter.onDomLoad(History.hashChangeInit); + + } // History.emulated.hashChange + + + // ==================================================================== + // HTML5 State Support + + // Non-Native pushState Implementation + if ( History.emulated.pushState ) { + /* + * We must emulate the HTML5 State Management by using HTML4 HashChange + */ + + /** + * History.onHashChange(event) + * Trigger HTML5's window.onpopstate via HTML4 HashChange Support + */ + History.onHashChange = function(event){ + //History.debug('History.onHashChange', arguments); + + // Prepare + var currentUrl = ((event && event.newURL) || History.getLocationHref()), + currentHash = History.getHashByUrl(currentUrl), + currentState = null, + currentStateHash = null, + currentStateHashExits = null, + discardObject; + + // Check if we are the same state + if ( History.isLastHash(currentHash) ) { + // There has been no change (just the page's hash has finally propagated) + //History.debug('History.onHashChange: no change'); + History.busy(false); + return false; + } + + // Reset the double check + History.doubleCheckComplete(); + + // Store our location for use in detecting back/forward direction + History.saveHash(currentHash); + + // Expand Hash + if ( currentHash && History.isTraditionalAnchor(currentHash) ) { + //History.debug('History.onHashChange: traditional anchor', currentHash); + // Traditional Anchor Hash + History.Adapter.trigger(window,'anchorchange'); + History.busy(false); + return false; + } + + // Create State + currentState = History.extractState(History.getFullUrl(currentHash||History.getLocationHref()),true); + + // Check if we are the same state + if ( History.isLastSavedState(currentState) ) { + //History.debug('History.onHashChange: no change'); + // There has been no change (just the page's hash has finally propagated) + History.busy(false); + return false; + } + + // Create the state Hash + currentStateHash = History.getHashByState(currentState); + + // Check if we are DiscardedState + discardObject = History.discardedState(currentState); + if ( discardObject ) { + // Ignore this state as it has been discarded and go back to the state before it + if ( History.getHashByIndex(-2) === History.getHashByState(discardObject.forwardState) ) { + // We are going backwards + //History.debug('History.onHashChange: go backwards'); + History.back(false); + } else { + // We are going forwards + //History.debug('History.onHashChange: go forwards'); + History.forward(false); + } + return false; + } + + // Push the new HTML5 State + //History.debug('History.onHashChange: success hashchange'); + History.pushState(currentState.data,currentState.title,encodeURI(currentState.url),false); + + // End onHashChange closure + return true; + }; + History.Adapter.bind(window,'hashchange',History.onHashChange); + + /** + * History.pushState(data,title,url) + * Add a new State to the history object, become it, and trigger onpopstate + * We have to trigger for HTML4 compatibility + * @param {object} data + * @param {string} title + * @param {string} url + * @return {true} + */ + History.pushState = function(data,title,url,queue){ + //History.debug('History.pushState: called', arguments); + + // We assume that the URL passed in is URI-encoded, but this makes + // sure that it's fully URI encoded; any '%'s that are encoded are + // converted back into '%'s + url = encodeURI(url).replace(/%25/g, "%"); + + // Check the State + if ( History.getHashByUrl(url) ) { + throw new Error('History.js does not support states with fragment-identifiers (hashes/anchors).'); + } + + // Handle Queueing + if ( queue !== false && History.busy() ) { + // Wait + Push to Queue + //History.debug('History.pushState: we must wait', arguments); + History.pushQueue({ + scope: History, + callback: History.pushState, + args: arguments, + queue: queue + }); + return false; + } + + // Make Busy + History.busy(true); + + // Fetch the State Object + var newState = History.createStateObject(data,title,url), + newStateHash = History.getHashByState(newState), + oldState = History.getState(false), + oldStateHash = History.getHashByState(oldState), + html4Hash = History.getHash(), + wasExpected = History.expectedStateId == newState.id; + + // Store the newState + History.storeState(newState); + History.expectedStateId = newState.id; + + // Recycle the State + History.recycleState(newState); + + // Force update of the title + History.setTitle(newState); + + // Check if we are the same State + if ( newStateHash === oldStateHash ) { + //History.debug('History.pushState: no change', newStateHash); + History.busy(false); + return false; + } + + // Update HTML5 State + History.saveState(newState); + + // Fire HTML5 Event + if(!wasExpected) + History.Adapter.trigger(window,'statechange'); + + // Update HTML4 Hash + if ( !History.isHashEqual(newStateHash, html4Hash) && !History.isHashEqual(newStateHash, History.getShortUrl(History.getLocationHref())) ) { + History.setHash(newStateHash,false); + } + + History.busy(false); + + // End pushState closure + return true; + }; + + /** + * History.replaceState(data,title,url) + * Replace the State and trigger onpopstate + * We have to trigger for HTML4 compatibility + * @param {object} data + * @param {string} title + * @param {string} url + * @return {true} + */ + History.replaceState = function(data,title,url,queue){ + //History.debug('History.replaceState: called', arguments); + + // We assume that the URL passed in is URI-encoded, but this makes + // sure that it's fully URI encoded; any '%'s that are encoded are + // converted back into '%'s + url = encodeURI(url).replace(/%25/g, "%"); + + // Check the State + if ( History.getHashByUrl(url) ) { + throw new Error('History.js does not support states with fragment-identifiers (hashes/anchors).'); + } + + // Handle Queueing + if ( queue !== false && History.busy() ) { + // Wait + Push to Queue + //History.debug('History.replaceState: we must wait', arguments); + History.pushQueue({ + scope: History, + callback: History.replaceState, + args: arguments, + queue: queue + }); + return false; + } + + // Make Busy + History.busy(true); + + // Fetch the State Objects + var newState = History.createStateObject(data,title,url), + newStateHash = History.getHashByState(newState), + oldState = History.getState(false), + oldStateHash = History.getHashByState(oldState), + previousState = History.getStateByIndex(-2); + + // Discard Old State + History.discardState(oldState,newState,previousState); + + // If the url hasn't changed, just store and save the state + // and fire a statechange event to be consistent with the + // html 5 api + if ( newStateHash === oldStateHash ) { + // Store the newState + History.storeState(newState); + History.expectedStateId = newState.id; + + // Recycle the State + History.recycleState(newState); + + // Force update of the title + History.setTitle(newState); + + // Update HTML5 State + History.saveState(newState); + + // Fire HTML5 Event + //History.debug('History.pushState: trigger popstate'); + History.Adapter.trigger(window,'statechange'); + History.busy(false); + } + else { + // Alias to PushState + History.pushState(newState.data,newState.title,newState.url,false); + } + + // End replaceState closure + return true; + }; + + } // History.emulated.pushState + + + + // ==================================================================== + // Initialise + + // Non-Native pushState Implementation + if ( History.emulated.pushState ) { + /** + * Ensure initial state is handled correctly + */ + if ( History.getHash() && !History.emulated.hashChange ) { + History.Adapter.onDomLoad(function(){ + History.Adapter.trigger(window,'hashchange'); + }); + } + + } // History.emulated.pushState + + }; // History.initHtml4 + + // Try to Initialise History + if ( typeof History.init !== 'undefined' ) { + History.init(); + } + +})(window); +/** + * History.js Core + * @author Benjamin Arthur Lupton + * @copyright 2010-2011 Benjamin Arthur Lupton + * @license New BSD License + */ + +(function(window,undefined){ + "use strict"; + + // ======================================================================== + // Initialise + + // Localise Globals + var + console = window.console||undefined, // Prevent a JSLint complain + document = window.document, // Make sure we are using the correct document + navigator = window.navigator, // Make sure we are using the correct navigator + sessionStorage = window.sessionStorage||false, // sessionStorage + setTimeout = window.setTimeout, + clearTimeout = window.clearTimeout, + setInterval = window.setInterval, + clearInterval = window.clearInterval, + JSON = window.JSON, + alert = window.alert, + History = window.History = window.History||{}, // Public History Object + history = window.history; // Old History Object + + try { + sessionStorage.setItem('TEST', '1'); + sessionStorage.removeItem('TEST'); + } catch(e) { + sessionStorage = false; + } + + // MooTools Compatibility + JSON.stringify = JSON.stringify||JSON.encode; + JSON.parse = JSON.parse||JSON.decode; + + // Check Existence + if ( typeof History.init !== 'undefined' ) { + throw new Error('History.js Core has already been loaded...'); + } + + // Initialise History + History.init = function(options){ + // Check Load Status of Adapter + if ( typeof History.Adapter === 'undefined' ) { + return false; + } + + // Check Load Status of Core + if ( typeof History.initCore !== 'undefined' ) { + History.initCore(); + } + + // Check Load Status of HTML4 Support + if ( typeof History.initHtml4 !== 'undefined' ) { + History.initHtml4(); + } + + // Return true + return true; + }; + + + // ======================================================================== + // Initialise Core + + // Initialise Core + History.initCore = function(options){ + // Initialise + if ( typeof History.initCore.initialized !== 'undefined' ) { + // Already Loaded + return false; + } + else { + History.initCore.initialized = true; + } + + + // ==================================================================== + // Options + + /** + * History.options + * Configurable options + */ + History.options = History.options||{}; + + /** + * History.options.hashChangeInterval + * How long should the interval be before hashchange checks + */ + History.options.hashChangeInterval = History.options.hashChangeInterval || 100; + + /** + * History.options.safariPollInterval + * How long should the interval be before safari poll checks + */ + History.options.safariPollInterval = History.options.safariPollInterval || 500; + + /** + * History.options.doubleCheckInterval + * How long should the interval be before we perform a double check + */ + History.options.doubleCheckInterval = History.options.doubleCheckInterval || 500; + + /** + * History.options.disableSuid + * Force History not to append suid + */ + History.options.disableSuid = History.options.disableSuid || false; + + /** + * History.options.storeInterval + * How long should we wait between store calls + */ + History.options.storeInterval = History.options.storeInterval || 1000; + + /** + * History.options.busyDelay + * How long should we wait between busy events + */ + History.options.busyDelay = History.options.busyDelay || 250; + + /** + * History.options.debug + * If true will enable debug messages to be logged + */ + History.options.debug = History.options.debug || false; + + /** + * History.options.initialTitle + * What is the title of the initial state + */ + History.options.initialTitle = History.options.initialTitle || document.title; + + /** + * History.options.html4Mode + * If true, will force HTMl4 mode (hashtags) + */ + History.options.html4Mode = History.options.html4Mode || false; + + /** + * History.options.delayInit + * Want to override default options and call init manually. + */ + History.options.delayInit = History.options.delayInit || false; + + + // ==================================================================== + // Interval record + + /** + * History.intervalList + * List of intervals set, to be cleared when document is unloaded. + */ + History.intervalList = []; + + /** + * History.clearAllIntervals + * Clears all setInterval instances. + */ + History.clearAllIntervals = function(){ + var i, il = History.intervalList; + if (typeof il !== "undefined" && il !== null) { + for (i = 0; i < il.length; i++) { + clearInterval(il[i]); + } + History.intervalList = null; + } + }; + + + // ==================================================================== + // Debug + + /** + * History.debug(message,...) + * Logs the passed arguments if debug enabled + */ + History.debug = function(){ + if ( (History.options.debug||false) ) { + History.log.apply(History,arguments); + } + }; + + /** + * History.log(message,...) + * Logs the passed arguments + */ + History.log = function(){ + // Prepare + var + consoleExists = !(typeof console === 'undefined' || typeof console.log === 'undefined' || typeof console.log.apply === 'undefined'), + textarea = document.getElementById('log'), + message, + i,n, + args,arg + ; + + // Write to Console + if ( consoleExists ) { + args = Array.prototype.slice.call(arguments); + message = args.shift(); + if ( typeof console.debug !== 'undefined' ) { + console.debug.apply(console,[message,args]); + } + else { + console.log.apply(console,[message,args]); + } + } + else { + message = ("\n"+arguments[0]+"\n"); + } + + // Write to log + for ( i=1,n=arguments.length; i + * @author James Padolsey + */ + History.getInternetExplorerMajorVersion = function(){ + var result = History.getInternetExplorerMajorVersion.cached = + (typeof History.getInternetExplorerMajorVersion.cached !== 'undefined') + ? History.getInternetExplorerMajorVersion.cached + : (function(){ + var v = 3, + div = document.createElement('div'), + all = div.getElementsByTagName('i'); + while ( (div.innerHTML = '') && all[0] ) {} + return (v > 4) ? v : false; + })() + ; + return result; + }; + + /** + * History.isInternetExplorer() + * Are we using Internet Explorer? + * @return {boolean} + * @license Public Domain + * @author Benjamin Arthur Lupton + */ + History.isInternetExplorer = function(){ + var result = + History.isInternetExplorer.cached = + (typeof History.isInternetExplorer.cached !== 'undefined') + ? History.isInternetExplorer.cached + : Boolean(History.getInternetExplorerMajorVersion()) + ; + return result; + }; + + /** + * History.emulated + * Which features require emulating? + */ + + if (History.options.html4Mode) { + History.emulated = { + pushState : true, + hashChange: true + }; + } + + else { + + History.emulated = { + pushState: !Boolean( + window.history && window.history.pushState && window.history.replaceState + && !( + (/ Mobile\/([1-7][a-z]|(8([abcde]|f(1[0-8]))))/i).test(navigator.userAgent) /* disable for versions of iOS before version 4.3 (8F190) */ + || (/AppleWebKit\/5([0-2]|3[0-2])/i).test(navigator.userAgent) /* disable for the mercury iOS browser, or at least older versions of the webkit engine */ + ) + ), + hashChange: Boolean( + !(('onhashchange' in window) || ('onhashchange' in document)) + || + (History.isInternetExplorer() && History.getInternetExplorerMajorVersion() < 8) + ) + }; + } + + /** + * History.enabled + * Is History enabled? + */ + History.enabled = !History.emulated.pushState; + + /** + * History.bugs + * Which bugs are present + */ + History.bugs = { + /** + * Safari 5 and Safari iOS 4 fail to return to the correct state once a hash is replaced by a `replaceState` call + * https://bugs.webkit.org/show_bug.cgi?id=56249 + */ + setHash: Boolean(!History.emulated.pushState && navigator.vendor === 'Apple Computer, Inc.' && /AppleWebKit\/5([0-2]|3[0-3])/.test(navigator.userAgent)), + + /** + * Safari 5 and Safari iOS 4 sometimes fail to apply the state change under busy conditions + * https://bugs.webkit.org/show_bug.cgi?id=42940 + */ + safariPoll: Boolean(!History.emulated.pushState && navigator.vendor === 'Apple Computer, Inc.' && /AppleWebKit\/5([0-2]|3[0-3])/.test(navigator.userAgent)), + + /** + * MSIE 6 and 7 sometimes do not apply a hash even it was told to (requiring a second call to the apply function) + */ + ieDoubleCheck: Boolean(History.isInternetExplorer() && History.getInternetExplorerMajorVersion() < 8), + + /** + * MSIE 6 requires the entire hash to be encoded for the hashes to trigger the onHashChange event + */ + hashEscape: Boolean(History.isInternetExplorer() && History.getInternetExplorerMajorVersion() < 7) + }; + + /** + * History.isEmptyObject(obj) + * Checks to see if the Object is Empty + * @param {Object} obj + * @return {boolean} + */ + History.isEmptyObject = function(obj) { + for ( var name in obj ) { + if ( obj.hasOwnProperty(name) ) { + return false; + } + } + return true; + }; + + /** + * History.cloneObject(obj) + * Clones a object and eliminate all references to the original contexts + * @param {Object} obj + * @return {Object} + */ + History.cloneObject = function(obj) { + var hash,newObj; + if ( obj ) { + hash = JSON.stringify(obj); + newObj = JSON.parse(hash); + } + else { + newObj = {}; + } + return newObj; + }; + + + // ==================================================================== + // URL Helpers + + /** + * History.getRootUrl() + * Turns "http://mysite.com/dir/page.html?asd" into "http://mysite.com" + * @return {String} rootUrl + */ + History.getRootUrl = function(){ + // Create + var rootUrl = document.location.protocol+'//'+(document.location.hostname||document.location.host); + if ( document.location.port||false ) { + rootUrl += ':'+document.location.port; + } + rootUrl += '/'; + + // Return + return rootUrl; + }; + + /** + * History.getBaseHref() + * Fetches the `href` attribute of the `` element if it exists + * @return {String} baseHref + */ + History.getBaseHref = function(){ + // Create + var + baseElements = document.getElementsByTagName('base'), + baseElement = null, + baseHref = ''; + + // Test for Base Element + if ( baseElements.length === 1 ) { + // Prepare for Base Element + baseElement = baseElements[0]; + baseHref = baseElement.href.replace(/[^\/]+$/,''); + } + + // Adjust trailing slash + baseHref = baseHref.replace(/\/+$/,''); + if ( baseHref ) baseHref += '/'; + + // Return + return baseHref; + }; + + /** + * History.getBaseUrl() + * Fetches the baseHref or basePageUrl or rootUrl (whichever one exists first) + * @return {String} baseUrl + */ + History.getBaseUrl = function(){ + // Create + var baseUrl = History.getBaseHref()||History.getBasePageUrl()||History.getRootUrl(); + + // Return + return baseUrl; + }; + + /** + * History.getPageUrl() + * Fetches the URL of the current page + * @return {String} pageUrl + */ + History.getPageUrl = function(){ + // Fetch + var + State = History.getState(false,false), + stateUrl = (State||{}).url||History.getLocationHref(), + pageUrl; + + // Create + pageUrl = stateUrl.replace(/\/+$/,'').replace(/[^\/]+$/,function(part,index,string){ + return (/\./).test(part) ? part : part+'/'; + }); + + // Return + return pageUrl; + }; + + /** + * History.getBasePageUrl() + * Fetches the Url of the directory of the current page + * @return {String} basePageUrl + */ + History.getBasePageUrl = function(){ + // Create + var basePageUrl = (History.getLocationHref()).replace(/[#\?].*/,'').replace(/[^\/]+$/,function(part,index,string){ + return (/[^\/]$/).test(part) ? '' : part; + }).replace(/\/+$/,'')+'/'; + + // Return + return basePageUrl; + }; + + /** + * History.getFullUrl(url) + * Ensures that we have an absolute URL and not a relative URL + * @param {string} url + * @param {Boolean} allowBaseHref + * @return {string} fullUrl + */ + History.getFullUrl = function(url,allowBaseHref){ + // Prepare + var fullUrl = url, firstChar = url.substring(0,1); + allowBaseHref = (typeof allowBaseHref === 'undefined') ? true : allowBaseHref; + + // Check + if ( /[a-z]+\:\/\//.test(url) ) { + // Full URL + } + else if ( firstChar === '/' ) { + // Root URL + fullUrl = History.getRootUrl()+url.replace(/^\/+/,''); + } + else if ( firstChar === '#' ) { + // Anchor URL + fullUrl = History.getPageUrl().replace(/#.*/,'')+url; + } + else if ( firstChar === '?' ) { + // Query URL + fullUrl = History.getPageUrl().replace(/[\?#].*/,'')+url; + } + else { + // Relative URL + if ( allowBaseHref ) { + fullUrl = History.getBaseUrl()+url.replace(/^(\.\/)+/,''); + } else { + fullUrl = History.getBasePageUrl()+url.replace(/^(\.\/)+/,''); + } + // We have an if condition above as we do not want hashes + // which are relative to the baseHref in our URLs + // as if the baseHref changes, then all our bookmarks + // would now point to different locations + // whereas the basePageUrl will always stay the same + } + + // Return + return fullUrl.replace(/\#$/,''); + }; + + /** + * History.getShortUrl(url) + * Ensures that we have a relative URL and not a absolute URL + * @param {string} url + * @return {string} url + */ + History.getShortUrl = function(url){ + // Prepare + var shortUrl = url, baseUrl = History.getBaseUrl(), rootUrl = History.getRootUrl(); + + // Trim baseUrl + if ( History.emulated.pushState ) { + // We are in a if statement as when pushState is not emulated + // The actual url these short urls are relative to can change + // So within the same session, we the url may end up somewhere different + shortUrl = shortUrl.replace(baseUrl,''); + } + + // Trim rootUrl + shortUrl = shortUrl.replace(rootUrl,'/'); + + // Ensure we can still detect it as a state + if ( History.isTraditionalAnchor(shortUrl) ) { + shortUrl = './'+shortUrl; + } + + // Clean It + shortUrl = shortUrl.replace(/^(\.\/)+/g,'./').replace(/\#$/,''); + + // Return + return shortUrl; + }; + + /** + * History.getLocationHref(document) + * Returns a normalized version of document.location.href + * accounting for browser inconsistencies, etc. + * + * This URL will be URI-encoded and will include the hash + * + * @param {object} document + * @return {string} url + */ + History.getLocationHref = function(doc) { + doc = doc || document; + + // most of the time, this will be true + if (doc.URL === doc.location.href) + return doc.location.href; + + // some versions of webkit URI-decode document.location.href + // but they leave document.URL in an encoded state + if (doc.location.href === decodeURIComponent(doc.URL)) + return doc.URL; + + // FF 3.6 only updates document.URL when a page is reloaded + // document.location.href is updated correctly + if (doc.location.hash && decodeURIComponent(doc.location.href.replace(/^[^#]+/, "")) === doc.location.hash) + return doc.location.href; + + if (doc.URL.indexOf('#') == -1 && doc.location.href.indexOf('#') != -1) + return doc.location.href; + + return doc.URL || doc.location.href; + }; + + + // ==================================================================== + // State Storage + + /** + * History.store + * The store for all session specific data + */ + History.store = {}; + + /** + * History.idToState + * 1-1: State ID to State Object + */ + History.idToState = History.idToState||{}; + + /** + * History.stateToId + * 1-1: State String to State ID + */ + History.stateToId = History.stateToId||{}; + + /** + * History.urlToId + * 1-1: State URL to State ID + */ + History.urlToId = History.urlToId||{}; + + /** + * History.storedStates + * Store the states in an array + */ + History.storedStates = History.storedStates||[]; + + /** + * History.savedStates + * Saved the states in an array + */ + History.savedStates = History.savedStates||[]; + + /** + * History.noramlizeStore() + * Noramlize the store by adding necessary values + */ + History.normalizeStore = function(){ + History.store.idToState = History.store.idToState||{}; + History.store.urlToId = History.store.urlToId||{}; + History.store.stateToId = History.store.stateToId||{}; + }; + + /** + * History.getState() + * Get an object containing the data, title and url of the current state + * @param {Boolean} friendly + * @param {Boolean} create + * @return {Object} State + */ + History.getState = function(friendly,create){ + // Prepare + if ( typeof friendly === 'undefined' ) { friendly = true; } + if ( typeof create === 'undefined' ) { create = true; } + + // Fetch + var State = History.getLastSavedState(); + + // Create + if ( !State && create ) { + State = History.createStateObject(); + } + + // Adjust + if ( friendly ) { + State = History.cloneObject(State); + State.url = State.cleanUrl||State.url; + } + + // Return + return State; + }; + + /** + * History.getIdByState(State) + * Gets a ID for a State + * @param {State} newState + * @return {String} id + */ + History.getIdByState = function(newState){ + + // Fetch ID + var id = History.extractId(newState.url), + str; + + if ( !id ) { + // Find ID via State String + str = History.getStateString(newState); + if ( typeof History.stateToId[str] !== 'undefined' ) { + id = History.stateToId[str]; + } + else if ( typeof History.store.stateToId[str] !== 'undefined' ) { + id = History.store.stateToId[str]; + } + else { + // Generate a new ID + while ( true ) { + id = (new Date()).getTime() + String(Math.random()).replace(/\D/g,''); + if ( typeof History.idToState[id] === 'undefined' && typeof History.store.idToState[id] === 'undefined' ) { + break; + } + } + + // Apply the new State to the ID + History.stateToId[str] = id; + History.idToState[id] = newState; + } + } + + // Return ID + return id; + }; + + /** + * History.normalizeState(State) + * Expands a State Object + * @param {object} State + * @return {object} + */ + History.normalizeState = function(oldState){ + // Variables + var newState, dataNotEmpty; + + // Prepare + if ( !oldState || (typeof oldState !== 'object') ) { + oldState = {}; + } + + // Check + if ( typeof oldState.normalized !== 'undefined' ) { + return oldState; + } + + // Adjust + if ( !oldState.data || (typeof oldState.data !== 'object') ) { + oldState.data = {}; + } + + // ---------------------------------------------------------------- + + // Create + newState = {}; + newState.normalized = true; + newState.title = oldState.title||''; + newState.url = History.getFullUrl(oldState.url?oldState.url:(History.getLocationHref())); + newState.hash = History.getShortUrl(newState.url); + newState.data = History.cloneObject(oldState.data); + + // Fetch ID + newState.id = History.getIdByState(newState); + + // ---------------------------------------------------------------- + + // Clean the URL + newState.cleanUrl = newState.url.replace(/\??\&_suid.*/,''); + newState.url = newState.cleanUrl; + + // Check to see if we have more than just a url + dataNotEmpty = !History.isEmptyObject(newState.data); + + // Apply + if ( (newState.title || dataNotEmpty) && History.options.disableSuid !== true ) { + // Add ID to Hash + newState.hash = History.getShortUrl(newState.url).replace(/\??\&_suid.*/,''); + if ( !/\?/.test(newState.hash) ) { + newState.hash += '?'; + } + newState.hash += '&_suid='+newState.id; + } + + // Create the Hashed URL + newState.hashedUrl = History.getFullUrl(newState.hash); + + // ---------------------------------------------------------------- + + // Update the URL if we have a duplicate + if ( (History.emulated.pushState || History.bugs.safariPoll) && History.hasUrlDuplicate(newState) ) { + newState.url = newState.hashedUrl; + } + + // ---------------------------------------------------------------- + + // Return + return newState; + }; + + /** + * History.createStateObject(data,title,url) + * Creates a object based on the data, title and url state params + * @param {object} data + * @param {string} title + * @param {string} url + * @return {object} + */ + History.createStateObject = function(data,title,url){ + // Hashify + var State = { + 'data': data, + 'title': title, + 'url': url + }; + + // Expand the State + State = History.normalizeState(State); + + // Return object + return State; + }; + + /** + * History.getStateById(id) + * Get a state by it's UID + * @param {String} id + */ + History.getStateById = function(id){ + // Prepare + id = String(id); + + // Retrieve + var State = History.idToState[id] || History.store.idToState[id] || undefined; + + // Return State + return State; + }; + + /** + * Get a State's String + * @param {State} passedState + */ + History.getStateString = function(passedState){ + // Prepare + var State, cleanedState, str; + + // Fetch + State = History.normalizeState(passedState); + + // Clean + cleanedState = { + data: State.data, + title: passedState.title, + url: passedState.url + }; + + // Fetch + str = JSON.stringify(cleanedState); + + // Return + return str; + }; + + /** + * Get a State's ID + * @param {State} passedState + * @return {String} id + */ + History.getStateId = function(passedState){ + // Prepare + var State, id; + + // Fetch + State = History.normalizeState(passedState); + + // Fetch + id = State.id; + + // Return + return id; + }; + + /** + * History.getHashByState(State) + * Creates a Hash for the State Object + * @param {State} passedState + * @return {String} hash + */ + History.getHashByState = function(passedState){ + // Prepare + var State, hash; + + // Fetch + State = History.normalizeState(passedState); + + // Hash + hash = State.hash; + + // Return + return hash; + }; + + /** + * History.extractId(url_or_hash) + * Get a State ID by it's URL or Hash + * @param {string} url_or_hash + * @return {string} id + */ + History.extractId = function ( url_or_hash ) { + // Prepare + var id,parts,url, tmp; + + // Extract + + // If the URL has a #, use the id from before the # + if (url_or_hash.indexOf('#') != -1) + { + tmp = url_or_hash.split("#")[0]; + } + else + { + tmp = url_or_hash; + } + + parts = /(.*)\&_suid=([0-9]+)$/.exec(tmp); + url = parts ? (parts[1]||url_or_hash) : url_or_hash; + id = parts ? String(parts[2]||'') : ''; + + // Return + return id||false; + }; + + /** + * History.isTraditionalAnchor + * Checks to see if the url is a traditional anchor or not + * @param {String} url_or_hash + * @return {Boolean} + */ + History.isTraditionalAnchor = function(url_or_hash){ + // Check + var isTraditional = !(/[\/\?\.]/.test(url_or_hash)); + + // Return + return isTraditional; + }; + + /** + * History.extractState + * Get a State by it's URL or Hash + * @param {String} url_or_hash + * @return {State|null} + */ + History.extractState = function(url_or_hash,create){ + // Prepare + var State = null, id, url; + create = create||false; + + // Fetch SUID + id = History.extractId(url_or_hash); + if ( id ) { + State = History.getStateById(id); + } + + // Fetch SUID returned no State + if ( !State ) { + // Fetch URL + url = History.getFullUrl(url_or_hash); + + // Check URL + id = History.getIdByUrl(url)||false; + if ( id ) { + State = History.getStateById(id); + } + + // Create State + if ( !State && create && !History.isTraditionalAnchor(url_or_hash) ) { + State = History.createStateObject(null,null,url); + } + } + + // Return + return State; + }; + + /** + * History.getIdByUrl() + * Get a State ID by a State URL + */ + History.getIdByUrl = function(url){ + // Fetch + var id = History.urlToId[url] || History.store.urlToId[url] || undefined; + + // Return + return id; + }; + + /** + * History.getLastSavedState() + * Get an object containing the data, title and url of the current state + * @return {Object} State + */ + History.getLastSavedState = function(){ + return History.savedStates[History.savedStates.length-1]||undefined; + }; + + /** + * History.getLastStoredState() + * Get an object containing the data, title and url of the current state + * @return {Object} State + */ + History.getLastStoredState = function(){ + return History.storedStates[History.storedStates.length-1]||undefined; + }; + + /** + * History.hasUrlDuplicate + * Checks if a Url will have a url conflict + * @param {Object} newState + * @return {Boolean} hasDuplicate + */ + History.hasUrlDuplicate = function(newState) { + // Prepare + var hasDuplicate = false, + oldState; + + // Fetch + oldState = History.extractState(newState.url); + + // Check + hasDuplicate = oldState && oldState.id !== newState.id; + + // Return + return hasDuplicate; + }; + + /** + * History.storeState + * Store a State + * @param {Object} newState + * @return {Object} newState + */ + History.storeState = function(newState){ + // Store the State + History.urlToId[newState.url] = newState.id; + + // Push the State + History.storedStates.push(History.cloneObject(newState)); + + // Return newState + return newState; + }; + + /** + * History.isLastSavedState(newState) + * Tests to see if the state is the last state + * @param {Object} newState + * @return {boolean} isLast + */ + History.isLastSavedState = function(newState){ + // Prepare + var isLast = false, + newId, oldState, oldId; + + // Check + if ( History.savedStates.length ) { + newId = newState.id; + oldState = History.getLastSavedState(); + oldId = oldState.id; + + // Check + isLast = (newId === oldId); + } + + // Return + return isLast; + }; + + /** + * History.saveState + * Push a State + * @param {Object} newState + * @return {boolean} changed + */ + History.saveState = function(newState){ + // Check Hash + if ( History.isLastSavedState(newState) ) { + return false; + } + + // Push the State + History.savedStates.push(History.cloneObject(newState)); + + // Return true + return true; + }; + + /** + * History.getStateByIndex() + * Gets a state by the index + * @param {integer} index + * @return {Object} + */ + History.getStateByIndex = function(index){ + // Prepare + var State = null; + + // Handle + if ( typeof index === 'undefined' ) { + // Get the last inserted + State = History.savedStates[History.savedStates.length-1]; + } + else if ( index < 0 ) { + // Get from the end + State = History.savedStates[History.savedStates.length+index]; + } + else { + // Get from the beginning + State = History.savedStates[index]; + } + + // Return State + return State; + }; + + /** + * History.getCurrentIndex() + * Gets the current index + * @return (integer) + */ + History.getCurrentIndex = function(){ + // Prepare + var index = null; + + // No states saved + if(History.savedStates.length < 1) { + index = 0; + } + else { + index = History.savedStates.length-1; + } + return index; + }; + + // ==================================================================== + // Hash Helpers + + /** + * History.getHash() + * @param {Location=} location + * Gets the current document hash + * Note: unlike location.hash, this is guaranteed to return the escaped hash in all browsers + * @return {string} + */ + History.getHash = function(doc){ + var url = History.getLocationHref(doc), + hash; + hash = History.getHashByUrl(url); + return hash; + }; + + /** + * History.unescapeHash() + * normalize and Unescape a Hash + * @param {String} hash + * @return {string} + */ + History.unescapeHash = function(hash){ + // Prepare + var result = History.normalizeHash(hash); + + // Unescape hash + result = decodeURIComponent(result); + + // Return result + return result; + }; + + /** + * History.normalizeHash() + * normalize a hash across browsers + * @return {string} + */ + History.normalizeHash = function(hash){ + // Prepare + var result = hash.replace(/[^#]*#/,'').replace(/#.*/, ''); + + // Return result + return result; + }; + + /** + * History.setHash(hash) + * Sets the document hash + * @param {string} hash + * @return {History} + */ + History.setHash = function(hash,queue){ + // Prepare + var State, pageUrl; + + // Handle Queueing + if ( queue !== false && History.busy() ) { + // Wait + Push to Queue + //History.debug('History.setHash: we must wait', arguments); + History.pushQueue({ + scope: History, + callback: History.setHash, + args: arguments, + queue: queue + }); + return false; + } + + // Log + //History.debug('History.setHash: called',hash); + + // Make Busy + Continue + History.busy(true); + + // Check if hash is a state + State = History.extractState(hash,true); + if ( State && !History.emulated.pushState ) { + // Hash is a state so skip the setHash + //History.debug('History.setHash: Hash is a state so skipping the hash set with a direct pushState call',arguments); + + // PushState + History.pushState(State.data,State.title,State.url,false); + } + else if ( History.getHash() !== hash ) { + // Hash is a proper hash, so apply it + + // Handle browser bugs + if ( History.bugs.setHash ) { + // Fix Safari Bug https://bugs.webkit.org/show_bug.cgi?id=56249 + + // Fetch the base page + pageUrl = History.getPageUrl(); + + // Safari hash apply + History.pushState(null,null,pageUrl+'#'+hash,false); + } + else { + // Normal hash apply + document.location.hash = hash; + } + } + + // Chain + return History; + }; + + /** + * History.escape() + * normalize and Escape a Hash + * @return {string} + */ + History.escapeHash = function(hash){ + // Prepare + var result = History.normalizeHash(hash); + + // Escape hash + result = window.encodeURIComponent(result); + + // IE6 Escape Bug + if ( !History.bugs.hashEscape ) { + // Restore common parts + result = result + .replace(/\%21/g,'!') + .replace(/\%26/g,'&') + .replace(/\%3D/g,'=') + .replace(/\%3F/g,'?'); + } + + // Return result + return result; + }; + + /** + * History.getHashByUrl(url) + * Extracts the Hash from a URL + * @param {string} url + * @return {string} url + */ + History.getHashByUrl = function(url){ + // Extract the hash + var hash = String(url) + .replace(/([^#]*)#?([^#]*)#?(.*)/, '$2') + ; + + // Unescape hash + hash = History.unescapeHash(hash); + + // Return hash + return hash; + }; + + /** + * History.setTitle(title) + * Applies the title to the document + * @param {State} newState + * @return {Boolean} + */ + History.setTitle = function(newState){ + // Prepare + var title = newState.title, + firstState; + + // Initial + if ( !title ) { + firstState = History.getStateByIndex(0); + if ( firstState && firstState.url === newState.url ) { + title = firstState.title||History.options.initialTitle; + } + } + + // Apply + try { + document.getElementsByTagName('title')[0].innerHTML = title.replace('<','<').replace('>','>').replace(' & ',' & '); + } + catch ( Exception ) { } + document.title = title; + + // Chain + return History; + }; + + + // ==================================================================== + // Queueing + + /** + * History.queues + * The list of queues to use + * First In, First Out + */ + History.queues = []; + + /** + * History.busy(value) + * @param {boolean} value [optional] + * @return {boolean} busy + */ + History.busy = function(value){ + // Apply + if ( typeof value !== 'undefined' ) { + //History.debug('History.busy: changing ['+(History.busy.flag||false)+'] to ['+(value||false)+']', History.queues.length); + History.busy.flag = value; + } + // Default + else if ( typeof History.busy.flag === 'undefined' ) { + History.busy.flag = false; + } + + // Queue + if ( !History.busy.flag ) { + // Execute the next item in the queue + clearTimeout(History.busy.timeout); + var fireNext = function(){ + var i, queue, item; + if ( History.busy.flag ) return; + for ( i=History.queues.length-1; i >= 0; --i ) { + queue = History.queues[i]; + if ( queue.length === 0 ) continue; + item = queue.shift(); + History.fireQueueItem(item); + History.busy.timeout = setTimeout(fireNext,History.options.busyDelay); + } + }; + History.busy.timeout = setTimeout(fireNext,History.options.busyDelay); + } + + // Return + return History.busy.flag; + }; + + /** + * History.busy.flag + */ + History.busy.flag = false; + + /** + * History.fireQueueItem(item) + * Fire a Queue Item + * @param {Object} item + * @return {Mixed} result + */ + History.fireQueueItem = function(item){ + return item.callback.apply(item.scope||History,item.args||[]); + }; + + /** + * History.pushQueue(callback,args) + * Add an item to the queue + * @param {Object} item [scope,callback,args,queue] + */ + History.pushQueue = function(item){ + // Prepare the queue + History.queues[item.queue||0] = History.queues[item.queue||0]||[]; + + // Add to the queue + History.queues[item.queue||0].push(item); + + // Chain + return History; + }; + + /** + * History.queue (item,queue), (func,queue), (func), (item) + * Either firs the item now if not busy, or adds it to the queue + */ + History.queue = function(item,queue){ + // Prepare + if ( typeof item === 'function' ) { + item = { + callback: item + }; + } + if ( typeof queue !== 'undefined' ) { + item.queue = queue; + } + + // Handle + if ( History.busy() ) { + History.pushQueue(item); + } else { + History.fireQueueItem(item); + } + + // Chain + return History; + }; + + /** + * History.clearQueue() + * Clears the Queue + */ + History.clearQueue = function(){ + History.busy.flag = false; + History.queues = []; + return History; + }; + + + // ==================================================================== + // IE Bug Fix + + /** + * History.stateChanged + * States whether or not the state has changed since the last double check was initialised + */ + History.stateChanged = false; + + /** + * History.doubleChecker + * Contains the timeout used for the double checks + */ + History.doubleChecker = false; + + /** + * History.doubleCheckComplete() + * Complete a double check + * @return {History} + */ + History.doubleCheckComplete = function(){ + // Update + History.stateChanged = true; + + // Clear + History.doubleCheckClear(); + + // Chain + return History; + }; + + /** + * History.doubleCheckClear() + * Clear a double check + * @return {History} + */ + History.doubleCheckClear = function(){ + // Clear + if ( History.doubleChecker ) { + clearTimeout(History.doubleChecker); + History.doubleChecker = false; + } + + // Chain + return History; + }; + + /** + * History.doubleCheck() + * Create a double check + * @return {History} + */ + History.doubleCheck = function(tryAgain){ + // Reset + History.stateChanged = false; + History.doubleCheckClear(); + + // Fix IE6,IE7 bug where calling history.back or history.forward does not actually change the hash (whereas doing it manually does) + // Fix Safari 5 bug where sometimes the state does not change: https://bugs.webkit.org/show_bug.cgi?id=42940 + if ( History.bugs.ieDoubleCheck ) { + // Apply Check + History.doubleChecker = setTimeout( + function(){ + History.doubleCheckClear(); + if ( !History.stateChanged ) { + //History.debug('History.doubleCheck: State has not yet changed, trying again', arguments); + // Re-Attempt + tryAgain(); + } + return true; + }, + History.options.doubleCheckInterval + ); + } + + // Chain + return History; + }; + + + // ==================================================================== + // Safari Bug Fix + + /** + * History.safariStatePoll() + * Poll the current state + * @return {History} + */ + History.safariStatePoll = function(){ + // Poll the URL + + // Get the Last State which has the new URL + var + urlState = History.extractState(History.getLocationHref()), + newState; + + // Check for a difference + if ( !History.isLastSavedState(urlState) ) { + newState = urlState; + } + else { + return; + } + + // Check if we have a state with that url + // If not create it + if ( !newState ) { + //History.debug('History.safariStatePoll: new'); + newState = History.createStateObject(); + } + + // Apply the New State + //History.debug('History.safariStatePoll: trigger'); + History.Adapter.trigger(window,'popstate'); + + // Chain + return History; + }; + + + // ==================================================================== + // State Aliases + + /** + * History.back(queue) + * Send the browser history back one item + * @param {Integer} queue [optional] + */ + History.back = function(queue){ + //History.debug('History.back: called', arguments); + + // Handle Queueing + if ( queue !== false && History.busy() ) { + // Wait + Push to Queue + //History.debug('History.back: we must wait', arguments); + History.pushQueue({ + scope: History, + callback: History.back, + args: arguments, + queue: queue + }); + return false; + } + + // Make Busy + Continue + History.busy(true); + + // Fix certain browser bugs that prevent the state from changing + History.doubleCheck(function(){ + History.back(false); + }); + + // Go back + history.go(-1); + + // End back closure + return true; + }; + + /** + * History.forward(queue) + * Send the browser history forward one item + * @param {Integer} queue [optional] + */ + History.forward = function(queue){ + //History.debug('History.forward: called', arguments); + + // Handle Queueing + if ( queue !== false && History.busy() ) { + // Wait + Push to Queue + //History.debug('History.forward: we must wait', arguments); + History.pushQueue({ + scope: History, + callback: History.forward, + args: arguments, + queue: queue + }); + return false; + } + + // Make Busy + Continue + History.busy(true); + + // Fix certain browser bugs that prevent the state from changing + History.doubleCheck(function(){ + History.forward(false); + }); + + // Go forward + history.go(1); + + // End forward closure + return true; + }; + + /** + * History.go(index,queue) + * Send the browser history back or forward index times + * @param {Integer} queue [optional] + */ + History.go = function(index,queue){ + //History.debug('History.go: called', arguments); + + // Prepare + var i; + + // Handle + if ( index > 0 ) { + // Forward + for ( i=1; i<=index; ++i ) { + History.forward(queue); + } + } + else if ( index < 0 ) { + // Backward + for ( i=-1; i>=index; --i ) { + History.back(queue); + } + } + else { + throw new Error('History.go: History.go requires a positive or negative integer passed.'); + } + + // Chain + return History; + }; + + + // ==================================================================== + // HTML5 State Support + + // Non-Native pushState Implementation + if ( History.emulated.pushState ) { + /* + * Provide Skeleton for HTML4 Browsers + */ + + // Prepare + var emptyFunction = function(){}; + History.pushState = History.pushState||emptyFunction; + History.replaceState = History.replaceState||emptyFunction; + } // History.emulated.pushState + + // Native pushState Implementation + else { + /* + * Use native HTML5 History API Implementation + */ + + /** + * History.onPopState(event,extra) + * Refresh the Current State + */ + History.onPopState = function(event,extra){ + // Prepare + var stateId = false, newState = false, currentHash, currentState; + + // Reset the double check + History.doubleCheckComplete(); + + // Check for a Hash, and handle apporiatly + currentHash = History.getHash(); + if ( currentHash ) { + // Expand Hash + currentState = History.extractState(currentHash||History.getLocationHref(),true); + if ( currentState ) { + // We were able to parse it, it must be a State! + // Let's forward to replaceState + //History.debug('History.onPopState: state anchor', currentHash, currentState); + History.replaceState(currentState.data, currentState.title, currentState.url, false); + } + else { + // Traditional Anchor + //History.debug('History.onPopState: traditional anchor', currentHash); + History.Adapter.trigger(window,'anchorchange'); + History.busy(false); + } + + // We don't care for hashes + History.expectedStateId = false; + return false; + } + + // Ensure + stateId = History.Adapter.extractEventData('state',event,extra) || false; + + // Fetch State + if ( stateId ) { + // Vanilla: Back/forward button was used + newState = History.getStateById(stateId); + } + else if ( History.expectedStateId ) { + // Vanilla: A new state was pushed, and popstate was called manually + newState = History.getStateById(History.expectedStateId); + } + else { + // Initial State + newState = History.extractState(History.getLocationHref()); + } + + // The State did not exist in our store + if ( !newState ) { + // Regenerate the State + newState = History.createStateObject(null,null,History.getLocationHref()); + } + + // Clean + History.expectedStateId = false; + + // Check if we are the same state + if ( History.isLastSavedState(newState) ) { + // There has been no change (just the page's hash has finally propagated) + //History.debug('History.onPopState: no change', newState, History.savedStates); + History.busy(false); + return false; + } + + // Store the State + History.storeState(newState); + History.saveState(newState); + + // Force update of the title + History.setTitle(newState); + + // Fire Our Event + History.Adapter.trigger(window,'statechange'); + History.busy(false); + + // Return true + return true; + }; + History.Adapter.bind(window,'popstate',History.onPopState); + + /** + * History.pushState(data,title,url) + * Add a new State to the history object, become it, and trigger onpopstate + * We have to trigger for HTML4 compatibility + * @param {object} data + * @param {string} title + * @param {string} url + * @return {true} + */ + History.pushState = function(data,title,url,queue){ + //History.debug('History.pushState: called', arguments); + + // Check the State + if ( History.getHashByUrl(url) && History.emulated.pushState ) { + throw new Error('History.js does not support states with fragement-identifiers (hashes/anchors).'); + } + + // Handle Queueing + if ( queue !== false && History.busy() ) { + // Wait + Push to Queue + //History.debug('History.pushState: we must wait', arguments); + History.pushQueue({ + scope: History, + callback: History.pushState, + args: arguments, + queue: queue + }); + return false; + } + + // Make Busy + Continue + History.busy(true); + + // Create the newState + var newState = History.createStateObject(data,title,url); + + // Check it + if ( History.isLastSavedState(newState) ) { + // Won't be a change + History.busy(false); + } + else { + // Store the newState + History.storeState(newState); + History.expectedStateId = newState.id; + + // Push the newState + history.pushState(newState.id,newState.title,newState.url); + + // Fire HTML5 Event + History.Adapter.trigger(window,'popstate'); + } + + // End pushState closure + return true; + }; + + /** + * History.replaceState(data,title,url) + * Replace the State and trigger onpopstate + * We have to trigger for HTML4 compatibility + * @param {object} data + * @param {string} title + * @param {string} url + * @return {true} + */ + History.replaceState = function(data,title,url,queue){ + //History.debug('History.replaceState: called', arguments); + + // Check the State + if ( History.getHashByUrl(url) && History.emulated.pushState ) { + throw new Error('History.js does not support states with fragement-identifiers (hashes/anchors).'); + } + + // Handle Queueing + if ( queue !== false && History.busy() ) { + // Wait + Push to Queue + //History.debug('History.replaceState: we must wait', arguments); + History.pushQueue({ + scope: History, + callback: History.replaceState, + args: arguments, + queue: queue + }); + return false; + } + + // Make Busy + Continue + History.busy(true); + + // Create the newState + var newState = History.createStateObject(data,title,url); + + // Check it + if ( History.isLastSavedState(newState) ) { + // Won't be a change + History.busy(false); + } + else { + // Store the newState + History.storeState(newState); + History.expectedStateId = newState.id; + + // Push the newState + history.replaceState(newState.id,newState.title,newState.url); + + // Fire HTML5 Event + History.Adapter.trigger(window,'popstate'); + } + + // End replaceState closure + return true; + }; + + } // !History.emulated.pushState + + + // ==================================================================== + // Initialise + + /** + * Load the Store + */ + if ( sessionStorage ) { + // Fetch + try { + History.store = JSON.parse(sessionStorage.getItem('History.store'))||{}; + } + catch ( err ) { + History.store = {}; + } + + // Normalize + History.normalizeStore(); + } + else { + // Default Load + History.store = {}; + History.normalizeStore(); + } + + /** + * Clear Intervals on exit to prevent memory leaks + */ + History.Adapter.bind(window,"unload",History.clearAllIntervals); + + /** + * Create the initial State + */ + History.saveState(History.storeState(History.extractState(History.getLocationHref(),true))); + + /** + * Bind for Saving Store + */ + if ( sessionStorage ) { + // When the page is closed + History.onUnload = function(){ + // Prepare + var currentStore, item, currentStoreString; + + // Fetch + try { + currentStore = JSON.parse(sessionStorage.getItem('History.store'))||{}; + } + catch ( err ) { + currentStore = {}; + } + + // Ensure + currentStore.idToState = currentStore.idToState || {}; + currentStore.urlToId = currentStore.urlToId || {}; + currentStore.stateToId = currentStore.stateToId || {}; + + // Sync + for ( item in History.idToState ) { + if ( !History.idToState.hasOwnProperty(item) ) { + continue; + } + currentStore.idToState[item] = History.idToState[item]; + } + for ( item in History.urlToId ) { + if ( !History.urlToId.hasOwnProperty(item) ) { + continue; + } + currentStore.urlToId[item] = History.urlToId[item]; + } + for ( item in History.stateToId ) { + if ( !History.stateToId.hasOwnProperty(item) ) { + continue; + } + currentStore.stateToId[item] = History.stateToId[item]; + } + + // Update + History.store = currentStore; + History.normalizeStore(); + + // In Safari, going into Private Browsing mode causes the + // Session Storage object to still exist but if you try and use + // or set any property/function of it it throws the exception + // "QUOTA_EXCEEDED_ERR: DOM Exception 22: An attempt was made to + // add something to storage that exceeded the quota." infinitely + // every second. + currentStoreString = JSON.stringify(currentStore); + try { + // Store + sessionStorage.setItem('History.store', currentStoreString); + } + catch (e) { + if (e.code === DOMException.QUOTA_EXCEEDED_ERR) { + if (sessionStorage.length) { + // Workaround for a bug seen on iPads. Sometimes the quota exceeded error comes up and simply + // removing/resetting the storage can work. + sessionStorage.removeItem('History.store'); + sessionStorage.setItem('History.store', currentStoreString); + } else { + // Otherwise, we're probably private browsing in Safari, so we'll ignore the exception. + } + } else { + throw e; + } + } + }; + + // For Internet Explorer + History.intervalList.push(setInterval(History.onUnload,History.options.storeInterval)); + + // For Other Browsers + History.Adapter.bind(window,'beforeunload',History.onUnload); + History.Adapter.bind(window,'unload',History.onUnload); + + // Both are enabled for consistency + } + + // Non-Native pushState Implementation + if ( !History.emulated.pushState ) { + // Be aware, the following is only for native pushState implementations + // If you are wanting to include something for all browsers + // Then include it above this if block + + /** + * Setup Safari Fix + */ + if ( History.bugs.safariPoll ) { + History.intervalList.push(setInterval(History.safariStatePoll, History.options.safariPollInterval)); + } + + /** + * Ensure Cross Browser Compatibility + */ + if ( navigator.vendor === 'Apple Computer, Inc.' || (navigator.appCodeName||'') === 'Mozilla' ) { + /** + * Fix Safari HashChange Issue + */ + + // Setup Alias + History.Adapter.bind(window,'hashchange',function(){ + History.Adapter.trigger(window,'popstate'); + }); + + // Initialise Alias + if ( History.getHash() ) { + History.Adapter.onDomLoad(function(){ + History.Adapter.trigger(window,'hashchange'); + }); + } + } + + } // !History.emulated.pushState + + + }; // History.initCore + + // Try to Initialise History + if (!History.options || !History.options.delayInit) { + History.init(); + } + +})(window); diff --git a/sites/all/themes/gui/materiobasetheme/bower_components/history.js/scripts/bundled-uncompressed/html4+html5/extjs.history.js b/sites/all/themes/gui/materiobasetheme/bower_components/history.js/scripts/bundled-uncompressed/html4+html5/extjs.history.js new file mode 100644 index 00000000..ed2ac9fe --- /dev/null +++ b/sites/all/themes/gui/materiobasetheme/bower_components/history.js/scripts/bundled-uncompressed/html4+html5/extjs.history.js @@ -0,0 +1,3305 @@ +/* + json2.js + 2012-10-08 + + Public Domain. + + NO WARRANTY EXPRESSED OR IMPLIED. USE AT YOUR OWN RISK. + + See http://www.JSON.org/js.html + + + This code should be minified before deployment. + See http://javascript.crockford.com/jsmin.html + + USE YOUR OWN COPY. IT IS EXTREMELY UNWISE TO LOAD CODE FROM SERVERS YOU DO + NOT CONTROL. + + + This file creates a global JSON object containing two methods: stringify + and parse. + + JSON.stringify(value, replacer, space) + value any JavaScript value, usually an object or array. + + replacer an optional parameter that determines how object + values are stringified for objects. It can be a + function or an array of strings. + + space an optional parameter that specifies the indentation + of nested structures. If it is omitted, the text will + be packed without extra whitespace. If it is a number, + it will specify the number of spaces to indent at each + level. If it is a string (such as '\t' or ' '), + it contains the characters used to indent at each level. + + This method produces a JSON text from a JavaScript value. + + When an object value is found, if the object contains a toJSON + method, its toJSON method will be called and the result will be + stringified. A toJSON method does not serialize: it returns the + value represented by the name/value pair that should be serialized, + or undefined if nothing should be serialized. The toJSON method + will be passed the key associated with the value, and this will be + bound to the value + + For example, this would serialize Dates as ISO strings. + + Date.prototype.toJSON = function (key) { + function f(n) { + // Format integers to have at least two digits. + return n < 10 ? '0' + n : n; + } + + return this.getUTCFullYear() + '-' + + f(this.getUTCMonth() + 1) + '-' + + f(this.getUTCDate()) + 'T' + + f(this.getUTCHours()) + ':' + + f(this.getUTCMinutes()) + ':' + + f(this.getUTCSeconds()) + 'Z'; + }; + + You can provide an optional replacer method. It will be passed the + key and value of each member, with this bound to the containing + object. The value that is returned from your method will be + serialized. If your method returns undefined, then the member will + be excluded from the serialization. + + If the replacer parameter is an array of strings, then it will be + used to select the members to be serialized. It filters the results + such that only members with keys listed in the replacer array are + stringified. + + Values that do not have JSON representations, such as undefined or + functions, will not be serialized. Such values in objects will be + dropped; in arrays they will be replaced with null. You can use + a replacer function to replace those with JSON values. + JSON.stringify(undefined) returns undefined. + + The optional space parameter produces a stringification of the + value that is filled with line breaks and indentation to make it + easier to read. + + If the space parameter is a non-empty string, then that string will + be used for indentation. If the space parameter is a number, then + the indentation will be that many spaces. + + Example: + + text = JSON.stringify(['e', {pluribus: 'unum'}]); + // text is '["e",{"pluribus":"unum"}]' + + + text = JSON.stringify(['e', {pluribus: 'unum'}], null, '\t'); + // text is '[\n\t"e",\n\t{\n\t\t"pluribus": "unum"\n\t}\n]' + + text = JSON.stringify([new Date()], function (key, value) { + return this[key] instanceof Date ? + 'Date(' + this[key] + ')' : value; + }); + // text is '["Date(---current time---)"]' + + + JSON.parse(text, reviver) + This method parses a JSON text to produce an object or array. + It can throw a SyntaxError exception. + + The optional reviver parameter is a function that can filter and + transform the results. It receives each of the keys and values, + and its return value is used instead of the original value. + If it returns what it received, then the structure is not modified. + If it returns undefined then the member is deleted. + + Example: + + // Parse the text. Values that look like ISO date strings will + // be converted to Date objects. + + myData = JSON.parse(text, function (key, value) { + var a; + if (typeof value === 'string') { + a = +/^(\d{4})-(\d{2})-(\d{2})T(\d{2}):(\d{2}):(\d{2}(?:\.\d*)?)Z$/.exec(value); + if (a) { + return new Date(Date.UTC(+a[1], +a[2] - 1, +a[3], +a[4], + +a[5], +a[6])); + } + } + return value; + }); + + myData = JSON.parse('["Date(09/09/2001)"]', function (key, value) { + var d; + if (typeof value === 'string' && + value.slice(0, 5) === 'Date(' && + value.slice(-1) === ')') { + d = new Date(value.slice(5, -1)); + if (d) { + return d; + } + } + return value; + }); + + + This is a reference implementation. You are free to copy, modify, or + redistribute. +*/ + +/*jslint evil: true, regexp: true */ + +/*members "", "\b", "\t", "\n", "\f", "\r", "\"", JSON, "\\", apply, + call, charCodeAt, getUTCDate, getUTCFullYear, getUTCHours, + getUTCMinutes, getUTCMonth, getUTCSeconds, hasOwnProperty, join, + lastIndex, length, parse, prototype, push, replace, slice, stringify, + test, toJSON, toString, valueOf +*/ + + +// Create a JSON object only if one does not already exist. We create the +// methods in a closure to avoid creating global variables. + +if (typeof JSON !== 'object') { + JSON = {}; +} + +(function () { + 'use strict'; + + function f(n) { + // Format integers to have at least two digits. + return n < 10 ? '0' + n : n; + } + + if (typeof Date.prototype.toJSON !== 'function') { + + Date.prototype.toJSON = function (key) { + + return isFinite(this.valueOf()) + ? this.getUTCFullYear() + '-' + + f(this.getUTCMonth() + 1) + '-' + + f(this.getUTCDate()) + 'T' + + f(this.getUTCHours()) + ':' + + f(this.getUTCMinutes()) + ':' + + f(this.getUTCSeconds()) + 'Z' + : null; + }; + + String.prototype.toJSON = + Number.prototype.toJSON = + Boolean.prototype.toJSON = function (key) { + return this.valueOf(); + }; + } + + var cx = /[\u0000\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g, + escapable = /[\\\"\x00-\x1f\x7f-\x9f\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g, + gap, + indent, + meta = { // table of character substitutions + '\b': '\\b', + '\t': '\\t', + '\n': '\\n', + '\f': '\\f', + '\r': '\\r', + '"' : '\\"', + '\\': '\\\\' + }, + rep; + + + function quote(string) { + +// If the string contains no control characters, no quote characters, and no +// backslash characters, then we can safely slap some quotes around it. +// Otherwise we must also replace the offending characters with safe escape +// sequences. + + escapable.lastIndex = 0; + return escapable.test(string) ? '"' + string.replace(escapable, function (a) { + var c = meta[a]; + return typeof c === 'string' + ? c + : '\\u' + ('0000' + a.charCodeAt(0).toString(16)).slice(-4); + }) + '"' : '"' + string + '"'; + } + + + function str(key, holder) { + +// Produce a string from holder[key]. + + var i, // The loop counter. + k, // The member key. + v, // The member value. + length, + mind = gap, + partial, + value = holder[key]; + +// If the value has a toJSON method, call it to obtain a replacement value. + + if (value && typeof value === 'object' && + typeof value.toJSON === 'function') { + value = value.toJSON(key); + } + +// If we were called with a replacer function, then call the replacer to +// obtain a replacement value. + + if (typeof rep === 'function') { + value = rep.call(holder, key, value); + } + +// What happens next depends on the value's type. + + switch (typeof value) { + case 'string': + return quote(value); + + case 'number': + +// JSON numbers must be finite. Encode non-finite numbers as null. + + return isFinite(value) ? String(value) : 'null'; + + case 'boolean': + case 'null': + +// If the value is a boolean or null, convert it to a string. Note: +// typeof null does not produce 'null'. The case is included here in +// the remote chance that this gets fixed someday. + + return String(value); + +// If the type is 'object', we might be dealing with an object or an array or +// null. + + case 'object': + +// Due to a specification blunder in ECMAScript, typeof null is 'object', +// so watch out for that case. + + if (!value) { + return 'null'; + } + +// Make an array to hold the partial results of stringifying this object value. + + gap += indent; + partial = []; + +// Is the value an array? + + if (Object.prototype.toString.apply(value) === '[object Array]') { + +// The value is an array. Stringify every element. Use null as a placeholder +// for non-JSON values. + + length = value.length; + for (i = 0; i < length; i += 1) { + partial[i] = str(i, value) || 'null'; + } + +// Join all of the elements together, separated with commas, and wrap them in +// brackets. + + v = partial.length === 0 + ? '[]' + : gap + ? '[\n' + gap + partial.join(',\n' + gap) + '\n' + mind + ']' + : '[' + partial.join(',') + ']'; + gap = mind; + return v; + } + +// If the replacer is an array, use it to select the members to be stringified. + + if (rep && typeof rep === 'object') { + length = rep.length; + for (i = 0; i < length; i += 1) { + if (typeof rep[i] === 'string') { + k = rep[i]; + v = str(k, value); + if (v) { + partial.push(quote(k) + (gap ? ': ' : ':') + v); + } + } + } + } else { + +// Otherwise, iterate through all of the keys in the object. + + for (k in value) { + if (Object.prototype.hasOwnProperty.call(value, k)) { + v = str(k, value); + if (v) { + partial.push(quote(k) + (gap ? ': ' : ':') + v); + } + } + } + } + +// Join all of the member texts together, separated with commas, +// and wrap them in braces. + + v = partial.length === 0 + ? '{}' + : gap + ? '{\n' + gap + partial.join(',\n' + gap) + '\n' + mind + '}' + : '{' + partial.join(',') + '}'; + gap = mind; + return v; + } + } + +// If the JSON object does not yet have a stringify method, give it one. + + if (typeof JSON.stringify !== 'function') { + JSON.stringify = function (value, replacer, space) { + +// The stringify method takes a value and an optional replacer, and an optional +// space parameter, and returns a JSON text. The replacer can be a function +// that can replace values, or an array of strings that will select the keys. +// A default replacer method can be provided. Use of the space parameter can +// produce text that is more easily readable. + + var i; + gap = ''; + indent = ''; + +// If the space parameter is a number, make an indent string containing that +// many spaces. + + if (typeof space === 'number') { + for (i = 0; i < space; i += 1) { + indent += ' '; + } + +// If the space parameter is a string, it will be used as the indent string. + + } else if (typeof space === 'string') { + indent = space; + } + +// If there is a replacer, it must be a function or an array. +// Otherwise, throw an error. + + rep = replacer; + if (replacer && typeof replacer !== 'function' && + (typeof replacer !== 'object' || + typeof replacer.length !== 'number')) { + throw new Error('JSON.stringify'); + } + +// Make a fake root object containing our value under the key of ''. +// Return the result of stringifying the value. + + return str('', {'': value}); + }; + } + + +// If the JSON object does not yet have a parse method, give it one. + + if (typeof JSON.parse !== 'function') { + JSON.parse = function (text, reviver) { + +// The parse method takes a text and an optional reviver function, and returns +// a JavaScript value if the text is a valid JSON text. + + var j; + + function walk(holder, key) { + +// The walk method is used to recursively walk the resulting structure so +// that modifications can be made. + + var k, v, value = holder[key]; + if (value && typeof value === 'object') { + for (k in value) { + if (Object.prototype.hasOwnProperty.call(value, k)) { + v = walk(value, k); + if (v !== undefined) { + value[k] = v; + } else { + delete value[k]; + } + } + } + } + return reviver.call(holder, key, value); + } + + +// Parsing happens in four stages. In the first stage, we replace certain +// Unicode characters with escape sequences. JavaScript handles many characters +// incorrectly, either silently deleting them, or treating them as line endings. + + text = String(text); + cx.lastIndex = 0; + if (cx.test(text)) { + text = text.replace(cx, function (a) { + return '\\u' + + ('0000' + a.charCodeAt(0).toString(16)).slice(-4); + }); + } + +// In the second stage, we run the text against regular expressions that look +// for non-JSON patterns. We are especially concerned with '()' and 'new' +// because they can cause invocation, and '=' because it can cause mutation. +// But just to be safe, we want to reject all unexpected forms. + +// We split the second stage into 4 regexp operations in order to work around +// crippling inefficiencies in IE's and Safari's regexp engines. First we +// replace the JSON backslash pairs with '@' (a non-JSON character). Second, we +// replace all simple value tokens with ']' characters. Third, we delete all +// open brackets that follow a colon or comma or that begin the text. Finally, +// we look to see that the remaining characters are only whitespace or ']' or +// ',' or ':' or '{' or '}'. If that is so, then the text is safe for eval. + + if (/^[\],:{}\s]*$/ + .test(text.replace(/\\(?:["\\\/bfnrt]|u[0-9a-fA-F]{4})/g, '@') + .replace(/"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g, ']') + .replace(/(?:^|:|,)(?:\s*\[)+/g, ''))) { + +// In the third stage we use the eval function to compile the text into a +// JavaScript structure. The '{' operator is subject to a syntactic ambiguity +// in JavaScript: it can begin a block or an object literal. We wrap the text +// in parens to eliminate the ambiguity. + + j = eval('(' + text + ')'); + +// In the optional fourth stage, we recursively walk the new structure, passing +// each name/value pair to a reviver function for possible transformation. + + return typeof reviver === 'function' + ? walk({'': j}, '') + : j; + } + +// If the text is not JSON parseable, then a SyntaxError is thrown. + + throw new SyntaxError('JSON.parse'); + }; + } +}());/** + * History.js ExtJS Adapter + * @author Sean Adkinson + * @copyright 2012 Sean Adkinson + * @license New BSD License + */ + +// Closure +(function(window,undefined){ + "use strict"; + + // Localise Globals + var + History = window.History = window.History||{}, + Ext = window.Ext; + + window.JSON = { + stringify: Ext.JSON.encode, + parse: Ext.JSON.decode + }; + + // Check Existence + if ( typeof History.Adapter !== 'undefined' ) { + throw new Error('History.js Adapter has already been loaded...'); + } + + // Add the Adapter + History.Adapter = { + observables: {}, + + /** + * History.Adapter.bind(el,event,callback) + * @param {Element|string} el + * @param {string} event - custom and standard events + * @param {function} callback + * @param {Object} scope + * @return {void} + */ + bind: function(element,eventName,callback,scope){ + Ext.EventManager.addListener(element, eventName, callback, scope); + + //bind an observable to the element that will let us "trigger" events on it + var id = Ext.id(element, 'history-'), observable = this.observables[id]; + if (!observable) { + observable = Ext.create('Ext.util.Observable'); + this.observables[id] = observable; + } + observable.on(eventName, callback, scope); + }, + + /** + * History.Adapter.trigger(el,event) + * @param {Element|string} el + * @param {string} event - custom and standard events + * @param {Object=} extra - a object of extra event data (optional) + * @return {void} + */ + trigger: function(element,eventName,extra){ + var id = Ext.id(element, 'history-'), observable = this.observables[id]; + if (observable) { + observable.fireEvent(eventName, extra); + } + }, + + /** + * History.Adapter.extractEventData(key,event,extra) + * @param {string} key - key for the event data to extract + * @param {string} event - custom and standard events + * @param {Object=} extra - a object of extra event data (optional) + * @return {mixed} + */ + extractEventData: function(key,event,extra){ + var result = (event && event.browserEvent && event.browserEvent[key]) || (extra && extra[key]) || undefined; + return result; + }, + + /** + * History.Adapter.onDomLoad(callback) + * @param {function} callback + * @return {void} + */ + onDomLoad: function(callback) { + Ext.onReady(callback); + } + }; + + // Try and Initialise History + if ( typeof History.init !== 'undefined' ) { + History.init(); + } + +})(window);/** + * History.js HTML4 Support + * Depends on the HTML5 Support + * @author Benjamin Arthur Lupton + * @copyright 2010-2011 Benjamin Arthur Lupton + * @license New BSD License + */ + +(function(window,undefined){ + "use strict"; + + // ======================================================================== + // Initialise + + // Localise Globals + var + document = window.document, // Make sure we are using the correct document + setTimeout = window.setTimeout||setTimeout, + clearTimeout = window.clearTimeout||clearTimeout, + setInterval = window.setInterval||setInterval, + History = window.History = window.History||{}; // Public History Object + + // Check Existence + if ( typeof History.initHtml4 !== 'undefined' ) { + throw new Error('History.js HTML4 Support has already been loaded...'); + } + + + // ======================================================================== + // Initialise HTML4 Support + + // Initialise HTML4 Support + History.initHtml4 = function(){ + // Initialise + if ( typeof History.initHtml4.initialized !== 'undefined' ) { + // Already Loaded + return false; + } + else { + History.initHtml4.initialized = true; + } + + + // ==================================================================== + // Properties + + /** + * History.enabled + * Is History enabled? + */ + History.enabled = true; + + + // ==================================================================== + // Hash Storage + + /** + * History.savedHashes + * Store the hashes in an array + */ + History.savedHashes = []; + + /** + * History.isLastHash(newHash) + * Checks if the hash is the last hash + * @param {string} newHash + * @return {boolean} true + */ + History.isLastHash = function(newHash){ + // Prepare + var oldHash = History.getHashByIndex(), + isLast; + + // Check + isLast = newHash === oldHash; + + // Return isLast + return isLast; + }; + + /** + * History.isHashEqual(newHash, oldHash) + * Checks to see if two hashes are functionally equal + * @param {string} newHash + * @param {string} oldHash + * @return {boolean} true + */ + History.isHashEqual = function(newHash, oldHash){ + newHash = encodeURIComponent(newHash).replace(/%25/g, "%"); + oldHash = encodeURIComponent(oldHash).replace(/%25/g, "%"); + return newHash === oldHash; + }; + + /** + * History.saveHash(newHash) + * Push a Hash + * @param {string} newHash + * @return {boolean} true + */ + History.saveHash = function(newHash){ + // Check Hash + if ( History.isLastHash(newHash) ) { + return false; + } + + // Push the Hash + History.savedHashes.push(newHash); + + // Return true + return true; + }; + + /** + * History.getHashByIndex() + * Gets a hash by the index + * @param {integer} index + * @return {string} + */ + History.getHashByIndex = function(index){ + // Prepare + var hash = null; + + // Handle + if ( typeof index === 'undefined' ) { + // Get the last inserted + hash = History.savedHashes[History.savedHashes.length-1]; + } + else if ( index < 0 ) { + // Get from the end + hash = History.savedHashes[History.savedHashes.length+index]; + } + else { + // Get from the beginning + hash = History.savedHashes[index]; + } + + // Return hash + return hash; + }; + + + // ==================================================================== + // Discarded States + + /** + * History.discardedHashes + * A hashed array of discarded hashes + */ + History.discardedHashes = {}; + + /** + * History.discardedStates + * A hashed array of discarded states + */ + History.discardedStates = {}; + + /** + * History.discardState(State) + * Discards the state by ignoring it through History + * @param {object} State + * @return {true} + */ + History.discardState = function(discardedState,forwardState,backState){ + //History.debug('History.discardState', arguments); + // Prepare + var discardedStateHash = History.getHashByState(discardedState), + discardObject; + + // Create Discard Object + discardObject = { + 'discardedState': discardedState, + 'backState': backState, + 'forwardState': forwardState + }; + + // Add to DiscardedStates + History.discardedStates[discardedStateHash] = discardObject; + + // Return true + return true; + }; + + /** + * History.discardHash(hash) + * Discards the hash by ignoring it through History + * @param {string} hash + * @return {true} + */ + History.discardHash = function(discardedHash,forwardState,backState){ + //History.debug('History.discardState', arguments); + // Create Discard Object + var discardObject = { + 'discardedHash': discardedHash, + 'backState': backState, + 'forwardState': forwardState + }; + + // Add to discardedHash + History.discardedHashes[discardedHash] = discardObject; + + // Return true + return true; + }; + + /** + * History.discardedState(State) + * Checks to see if the state is discarded + * @param {object} State + * @return {bool} + */ + History.discardedState = function(State){ + // Prepare + var StateHash = History.getHashByState(State), + discarded; + + // Check + discarded = History.discardedStates[StateHash]||false; + + // Return true + return discarded; + }; + + /** + * History.discardedHash(hash) + * Checks to see if the state is discarded + * @param {string} State + * @return {bool} + */ + History.discardedHash = function(hash){ + // Check + var discarded = History.discardedHashes[hash]||false; + + // Return true + return discarded; + }; + + /** + * History.recycleState(State) + * Allows a discarded state to be used again + * @param {object} data + * @param {string} title + * @param {string} url + * @return {true} + */ + History.recycleState = function(State){ + //History.debug('History.recycleState', arguments); + // Prepare + var StateHash = History.getHashByState(State); + + // Remove from DiscardedStates + if ( History.discardedState(State) ) { + delete History.discardedStates[StateHash]; + } + + // Return true + return true; + }; + + + // ==================================================================== + // HTML4 HashChange Support + + if ( History.emulated.hashChange ) { + /* + * We must emulate the HTML4 HashChange Support by manually checking for hash changes + */ + + /** + * History.hashChangeInit() + * Init the HashChange Emulation + */ + History.hashChangeInit = function(){ + // Define our Checker Function + History.checkerFunction = null; + + // Define some variables that will help in our checker function + var lastDocumentHash = '', + iframeId, iframe, + lastIframeHash, checkerRunning, + startedWithHash = Boolean(History.getHash()); + + // Handle depending on the browser + if ( History.isInternetExplorer() ) { + // IE6 and IE7 + // We need to use an iframe to emulate the back and forward buttons + + // Create iFrame + iframeId = 'historyjs-iframe'; + iframe = document.createElement('iframe'); + + // Adjust iFarme + // IE 6 requires iframe to have a src on HTTPS pages, otherwise it will throw a + // "This page contains both secure and nonsecure items" warning. + iframe.setAttribute('id', iframeId); + iframe.setAttribute('src', '#'); + iframe.style.display = 'none'; + + // Append iFrame + document.body.appendChild(iframe); + + // Create initial history entry + iframe.contentWindow.document.open(); + iframe.contentWindow.document.close(); + + // Define some variables that will help in our checker function + lastIframeHash = ''; + checkerRunning = false; + + // Define the checker function + History.checkerFunction = function(){ + // Check Running + if ( checkerRunning ) { + return false; + } + + // Update Running + checkerRunning = true; + + // Fetch + var + documentHash = History.getHash(), + iframeHash = History.getHash(iframe.contentWindow.document); + + // The Document Hash has changed (application caused) + if ( documentHash !== lastDocumentHash ) { + // Equalise + lastDocumentHash = documentHash; + + // Create a history entry in the iframe + if ( iframeHash !== documentHash ) { + //History.debug('hashchange.checker: iframe hash change', 'documentHash (new):', documentHash, 'iframeHash (old):', iframeHash); + + // Equalise + lastIframeHash = iframeHash = documentHash; + + // Create History Entry + iframe.contentWindow.document.open(); + iframe.contentWindow.document.close(); + + // Update the iframe's hash + iframe.contentWindow.document.location.hash = History.escapeHash(documentHash); + } + + // Trigger Hashchange Event + History.Adapter.trigger(window,'hashchange'); + } + + // The iFrame Hash has changed (back button caused) + else if ( iframeHash !== lastIframeHash ) { + //History.debug('hashchange.checker: iframe hash out of sync', 'iframeHash (new):', iframeHash, 'documentHash (old):', documentHash); + + // Equalise + lastIframeHash = iframeHash; + + // If there is no iframe hash that means we're at the original + // iframe state. + // And if there was a hash on the original request, the original + // iframe state was replaced instantly, so skip this state and take + // the user back to where they came from. + if (startedWithHash && iframeHash === '') { + History.back(); + } + else { + // Update the Hash + History.setHash(iframeHash,false); + } + } + + // Reset Running + checkerRunning = false; + + // Return true + return true; + }; + } + else { + // We are not IE + // Firefox 1 or 2, Opera + + // Define the checker function + History.checkerFunction = function(){ + // Prepare + var documentHash = History.getHash()||''; + + // The Document Hash has changed (application caused) + if ( documentHash !== lastDocumentHash ) { + // Equalise + lastDocumentHash = documentHash; + + // Trigger Hashchange Event + History.Adapter.trigger(window,'hashchange'); + } + + // Return true + return true; + }; + } + + // Apply the checker function + History.intervalList.push(setInterval(History.checkerFunction, History.options.hashChangeInterval)); + + // Done + return true; + }; // History.hashChangeInit + + // Bind hashChangeInit + History.Adapter.onDomLoad(History.hashChangeInit); + + } // History.emulated.hashChange + + + // ==================================================================== + // HTML5 State Support + + // Non-Native pushState Implementation + if ( History.emulated.pushState ) { + /* + * We must emulate the HTML5 State Management by using HTML4 HashChange + */ + + /** + * History.onHashChange(event) + * Trigger HTML5's window.onpopstate via HTML4 HashChange Support + */ + History.onHashChange = function(event){ + //History.debug('History.onHashChange', arguments); + + // Prepare + var currentUrl = ((event && event.newURL) || History.getLocationHref()), + currentHash = History.getHashByUrl(currentUrl), + currentState = null, + currentStateHash = null, + currentStateHashExits = null, + discardObject; + + // Check if we are the same state + if ( History.isLastHash(currentHash) ) { + // There has been no change (just the page's hash has finally propagated) + //History.debug('History.onHashChange: no change'); + History.busy(false); + return false; + } + + // Reset the double check + History.doubleCheckComplete(); + + // Store our location for use in detecting back/forward direction + History.saveHash(currentHash); + + // Expand Hash + if ( currentHash && History.isTraditionalAnchor(currentHash) ) { + //History.debug('History.onHashChange: traditional anchor', currentHash); + // Traditional Anchor Hash + History.Adapter.trigger(window,'anchorchange'); + History.busy(false); + return false; + } + + // Create State + currentState = History.extractState(History.getFullUrl(currentHash||History.getLocationHref()),true); + + // Check if we are the same state + if ( History.isLastSavedState(currentState) ) { + //History.debug('History.onHashChange: no change'); + // There has been no change (just the page's hash has finally propagated) + History.busy(false); + return false; + } + + // Create the state Hash + currentStateHash = History.getHashByState(currentState); + + // Check if we are DiscardedState + discardObject = History.discardedState(currentState); + if ( discardObject ) { + // Ignore this state as it has been discarded and go back to the state before it + if ( History.getHashByIndex(-2) === History.getHashByState(discardObject.forwardState) ) { + // We are going backwards + //History.debug('History.onHashChange: go backwards'); + History.back(false); + } else { + // We are going forwards + //History.debug('History.onHashChange: go forwards'); + History.forward(false); + } + return false; + } + + // Push the new HTML5 State + //History.debug('History.onHashChange: success hashchange'); + History.pushState(currentState.data,currentState.title,encodeURI(currentState.url),false); + + // End onHashChange closure + return true; + }; + History.Adapter.bind(window,'hashchange',History.onHashChange); + + /** + * History.pushState(data,title,url) + * Add a new State to the history object, become it, and trigger onpopstate + * We have to trigger for HTML4 compatibility + * @param {object} data + * @param {string} title + * @param {string} url + * @return {true} + */ + History.pushState = function(data,title,url,queue){ + //History.debug('History.pushState: called', arguments); + + // We assume that the URL passed in is URI-encoded, but this makes + // sure that it's fully URI encoded; any '%'s that are encoded are + // converted back into '%'s + url = encodeURI(url).replace(/%25/g, "%"); + + // Check the State + if ( History.getHashByUrl(url) ) { + throw new Error('History.js does not support states with fragment-identifiers (hashes/anchors).'); + } + + // Handle Queueing + if ( queue !== false && History.busy() ) { + // Wait + Push to Queue + //History.debug('History.pushState: we must wait', arguments); + History.pushQueue({ + scope: History, + callback: History.pushState, + args: arguments, + queue: queue + }); + return false; + } + + // Make Busy + History.busy(true); + + // Fetch the State Object + var newState = History.createStateObject(data,title,url), + newStateHash = History.getHashByState(newState), + oldState = History.getState(false), + oldStateHash = History.getHashByState(oldState), + html4Hash = History.getHash(), + wasExpected = History.expectedStateId == newState.id; + + // Store the newState + History.storeState(newState); + History.expectedStateId = newState.id; + + // Recycle the State + History.recycleState(newState); + + // Force update of the title + History.setTitle(newState); + + // Check if we are the same State + if ( newStateHash === oldStateHash ) { + //History.debug('History.pushState: no change', newStateHash); + History.busy(false); + return false; + } + + // Update HTML5 State + History.saveState(newState); + + // Fire HTML5 Event + if(!wasExpected) + History.Adapter.trigger(window,'statechange'); + + // Update HTML4 Hash + if ( !History.isHashEqual(newStateHash, html4Hash) && !History.isHashEqual(newStateHash, History.getShortUrl(History.getLocationHref())) ) { + History.setHash(newStateHash,false); + } + + History.busy(false); + + // End pushState closure + return true; + }; + + /** + * History.replaceState(data,title,url) + * Replace the State and trigger onpopstate + * We have to trigger for HTML4 compatibility + * @param {object} data + * @param {string} title + * @param {string} url + * @return {true} + */ + History.replaceState = function(data,title,url,queue){ + //History.debug('History.replaceState: called', arguments); + + // We assume that the URL passed in is URI-encoded, but this makes + // sure that it's fully URI encoded; any '%'s that are encoded are + // converted back into '%'s + url = encodeURI(url).replace(/%25/g, "%"); + + // Check the State + if ( History.getHashByUrl(url) ) { + throw new Error('History.js does not support states with fragment-identifiers (hashes/anchors).'); + } + + // Handle Queueing + if ( queue !== false && History.busy() ) { + // Wait + Push to Queue + //History.debug('History.replaceState: we must wait', arguments); + History.pushQueue({ + scope: History, + callback: History.replaceState, + args: arguments, + queue: queue + }); + return false; + } + + // Make Busy + History.busy(true); + + // Fetch the State Objects + var newState = History.createStateObject(data,title,url), + newStateHash = History.getHashByState(newState), + oldState = History.getState(false), + oldStateHash = History.getHashByState(oldState), + previousState = History.getStateByIndex(-2); + + // Discard Old State + History.discardState(oldState,newState,previousState); + + // If the url hasn't changed, just store and save the state + // and fire a statechange event to be consistent with the + // html 5 api + if ( newStateHash === oldStateHash ) { + // Store the newState + History.storeState(newState); + History.expectedStateId = newState.id; + + // Recycle the State + History.recycleState(newState); + + // Force update of the title + History.setTitle(newState); + + // Update HTML5 State + History.saveState(newState); + + // Fire HTML5 Event + //History.debug('History.pushState: trigger popstate'); + History.Adapter.trigger(window,'statechange'); + History.busy(false); + } + else { + // Alias to PushState + History.pushState(newState.data,newState.title,newState.url,false); + } + + // End replaceState closure + return true; + }; + + } // History.emulated.pushState + + + + // ==================================================================== + // Initialise + + // Non-Native pushState Implementation + if ( History.emulated.pushState ) { + /** + * Ensure initial state is handled correctly + */ + if ( History.getHash() && !History.emulated.hashChange ) { + History.Adapter.onDomLoad(function(){ + History.Adapter.trigger(window,'hashchange'); + }); + } + + } // History.emulated.pushState + + }; // History.initHtml4 + + // Try to Initialise History + if ( typeof History.init !== 'undefined' ) { + History.init(); + } + +})(window); +/** + * History.js Core + * @author Benjamin Arthur Lupton + * @copyright 2010-2011 Benjamin Arthur Lupton + * @license New BSD License + */ + +(function(window,undefined){ + "use strict"; + + // ======================================================================== + // Initialise + + // Localise Globals + var + console = window.console||undefined, // Prevent a JSLint complain + document = window.document, // Make sure we are using the correct document + navigator = window.navigator, // Make sure we are using the correct navigator + sessionStorage = window.sessionStorage||false, // sessionStorage + setTimeout = window.setTimeout, + clearTimeout = window.clearTimeout, + setInterval = window.setInterval, + clearInterval = window.clearInterval, + JSON = window.JSON, + alert = window.alert, + History = window.History = window.History||{}, // Public History Object + history = window.history; // Old History Object + + try { + sessionStorage.setItem('TEST', '1'); + sessionStorage.removeItem('TEST'); + } catch(e) { + sessionStorage = false; + } + + // MooTools Compatibility + JSON.stringify = JSON.stringify||JSON.encode; + JSON.parse = JSON.parse||JSON.decode; + + // Check Existence + if ( typeof History.init !== 'undefined' ) { + throw new Error('History.js Core has already been loaded...'); + } + + // Initialise History + History.init = function(options){ + // Check Load Status of Adapter + if ( typeof History.Adapter === 'undefined' ) { + return false; + } + + // Check Load Status of Core + if ( typeof History.initCore !== 'undefined' ) { + History.initCore(); + } + + // Check Load Status of HTML4 Support + if ( typeof History.initHtml4 !== 'undefined' ) { + History.initHtml4(); + } + + // Return true + return true; + }; + + + // ======================================================================== + // Initialise Core + + // Initialise Core + History.initCore = function(options){ + // Initialise + if ( typeof History.initCore.initialized !== 'undefined' ) { + // Already Loaded + return false; + } + else { + History.initCore.initialized = true; + } + + + // ==================================================================== + // Options + + /** + * History.options + * Configurable options + */ + History.options = History.options||{}; + + /** + * History.options.hashChangeInterval + * How long should the interval be before hashchange checks + */ + History.options.hashChangeInterval = History.options.hashChangeInterval || 100; + + /** + * History.options.safariPollInterval + * How long should the interval be before safari poll checks + */ + History.options.safariPollInterval = History.options.safariPollInterval || 500; + + /** + * History.options.doubleCheckInterval + * How long should the interval be before we perform a double check + */ + History.options.doubleCheckInterval = History.options.doubleCheckInterval || 500; + + /** + * History.options.disableSuid + * Force History not to append suid + */ + History.options.disableSuid = History.options.disableSuid || false; + + /** + * History.options.storeInterval + * How long should we wait between store calls + */ + History.options.storeInterval = History.options.storeInterval || 1000; + + /** + * History.options.busyDelay + * How long should we wait between busy events + */ + History.options.busyDelay = History.options.busyDelay || 250; + + /** + * History.options.debug + * If true will enable debug messages to be logged + */ + History.options.debug = History.options.debug || false; + + /** + * History.options.initialTitle + * What is the title of the initial state + */ + History.options.initialTitle = History.options.initialTitle || document.title; + + /** + * History.options.html4Mode + * If true, will force HTMl4 mode (hashtags) + */ + History.options.html4Mode = History.options.html4Mode || false; + + /** + * History.options.delayInit + * Want to override default options and call init manually. + */ + History.options.delayInit = History.options.delayInit || false; + + + // ==================================================================== + // Interval record + + /** + * History.intervalList + * List of intervals set, to be cleared when document is unloaded. + */ + History.intervalList = []; + + /** + * History.clearAllIntervals + * Clears all setInterval instances. + */ + History.clearAllIntervals = function(){ + var i, il = History.intervalList; + if (typeof il !== "undefined" && il !== null) { + for (i = 0; i < il.length; i++) { + clearInterval(il[i]); + } + History.intervalList = null; + } + }; + + + // ==================================================================== + // Debug + + /** + * History.debug(message,...) + * Logs the passed arguments if debug enabled + */ + History.debug = function(){ + if ( (History.options.debug||false) ) { + History.log.apply(History,arguments); + } + }; + + /** + * History.log(message,...) + * Logs the passed arguments + */ + History.log = function(){ + // Prepare + var + consoleExists = !(typeof console === 'undefined' || typeof console.log === 'undefined' || typeof console.log.apply === 'undefined'), + textarea = document.getElementById('log'), + message, + i,n, + args,arg + ; + + // Write to Console + if ( consoleExists ) { + args = Array.prototype.slice.call(arguments); + message = args.shift(); + if ( typeof console.debug !== 'undefined' ) { + console.debug.apply(console,[message,args]); + } + else { + console.log.apply(console,[message,args]); + } + } + else { + message = ("\n"+arguments[0]+"\n"); + } + + // Write to log + for ( i=1,n=arguments.length; i + * @author James Padolsey + */ + History.getInternetExplorerMajorVersion = function(){ + var result = History.getInternetExplorerMajorVersion.cached = + (typeof History.getInternetExplorerMajorVersion.cached !== 'undefined') + ? History.getInternetExplorerMajorVersion.cached + : (function(){ + var v = 3, + div = document.createElement('div'), + all = div.getElementsByTagName('i'); + while ( (div.innerHTML = '') && all[0] ) {} + return (v > 4) ? v : false; + })() + ; + return result; + }; + + /** + * History.isInternetExplorer() + * Are we using Internet Explorer? + * @return {boolean} + * @license Public Domain + * @author Benjamin Arthur Lupton + */ + History.isInternetExplorer = function(){ + var result = + History.isInternetExplorer.cached = + (typeof History.isInternetExplorer.cached !== 'undefined') + ? History.isInternetExplorer.cached + : Boolean(History.getInternetExplorerMajorVersion()) + ; + return result; + }; + + /** + * History.emulated + * Which features require emulating? + */ + + if (History.options.html4Mode) { + History.emulated = { + pushState : true, + hashChange: true + }; + } + + else { + + History.emulated = { + pushState: !Boolean( + window.history && window.history.pushState && window.history.replaceState + && !( + (/ Mobile\/([1-7][a-z]|(8([abcde]|f(1[0-8]))))/i).test(navigator.userAgent) /* disable for versions of iOS before version 4.3 (8F190) */ + || (/AppleWebKit\/5([0-2]|3[0-2])/i).test(navigator.userAgent) /* disable for the mercury iOS browser, or at least older versions of the webkit engine */ + ) + ), + hashChange: Boolean( + !(('onhashchange' in window) || ('onhashchange' in document)) + || + (History.isInternetExplorer() && History.getInternetExplorerMajorVersion() < 8) + ) + }; + } + + /** + * History.enabled + * Is History enabled? + */ + History.enabled = !History.emulated.pushState; + + /** + * History.bugs + * Which bugs are present + */ + History.bugs = { + /** + * Safari 5 and Safari iOS 4 fail to return to the correct state once a hash is replaced by a `replaceState` call + * https://bugs.webkit.org/show_bug.cgi?id=56249 + */ + setHash: Boolean(!History.emulated.pushState && navigator.vendor === 'Apple Computer, Inc.' && /AppleWebKit\/5([0-2]|3[0-3])/.test(navigator.userAgent)), + + /** + * Safari 5 and Safari iOS 4 sometimes fail to apply the state change under busy conditions + * https://bugs.webkit.org/show_bug.cgi?id=42940 + */ + safariPoll: Boolean(!History.emulated.pushState && navigator.vendor === 'Apple Computer, Inc.' && /AppleWebKit\/5([0-2]|3[0-3])/.test(navigator.userAgent)), + + /** + * MSIE 6 and 7 sometimes do not apply a hash even it was told to (requiring a second call to the apply function) + */ + ieDoubleCheck: Boolean(History.isInternetExplorer() && History.getInternetExplorerMajorVersion() < 8), + + /** + * MSIE 6 requires the entire hash to be encoded for the hashes to trigger the onHashChange event + */ + hashEscape: Boolean(History.isInternetExplorer() && History.getInternetExplorerMajorVersion() < 7) + }; + + /** + * History.isEmptyObject(obj) + * Checks to see if the Object is Empty + * @param {Object} obj + * @return {boolean} + */ + History.isEmptyObject = function(obj) { + for ( var name in obj ) { + if ( obj.hasOwnProperty(name) ) { + return false; + } + } + return true; + }; + + /** + * History.cloneObject(obj) + * Clones a object and eliminate all references to the original contexts + * @param {Object} obj + * @return {Object} + */ + History.cloneObject = function(obj) { + var hash,newObj; + if ( obj ) { + hash = JSON.stringify(obj); + newObj = JSON.parse(hash); + } + else { + newObj = {}; + } + return newObj; + }; + + + // ==================================================================== + // URL Helpers + + /** + * History.getRootUrl() + * Turns "http://mysite.com/dir/page.html?asd" into "http://mysite.com" + * @return {String} rootUrl + */ + History.getRootUrl = function(){ + // Create + var rootUrl = document.location.protocol+'//'+(document.location.hostname||document.location.host); + if ( document.location.port||false ) { + rootUrl += ':'+document.location.port; + } + rootUrl += '/'; + + // Return + return rootUrl; + }; + + /** + * History.getBaseHref() + * Fetches the `href` attribute of the `` element if it exists + * @return {String} baseHref + */ + History.getBaseHref = function(){ + // Create + var + baseElements = document.getElementsByTagName('base'), + baseElement = null, + baseHref = ''; + + // Test for Base Element + if ( baseElements.length === 1 ) { + // Prepare for Base Element + baseElement = baseElements[0]; + baseHref = baseElement.href.replace(/[^\/]+$/,''); + } + + // Adjust trailing slash + baseHref = baseHref.replace(/\/+$/,''); + if ( baseHref ) baseHref += '/'; + + // Return + return baseHref; + }; + + /** + * History.getBaseUrl() + * Fetches the baseHref or basePageUrl or rootUrl (whichever one exists first) + * @return {String} baseUrl + */ + History.getBaseUrl = function(){ + // Create + var baseUrl = History.getBaseHref()||History.getBasePageUrl()||History.getRootUrl(); + + // Return + return baseUrl; + }; + + /** + * History.getPageUrl() + * Fetches the URL of the current page + * @return {String} pageUrl + */ + History.getPageUrl = function(){ + // Fetch + var + State = History.getState(false,false), + stateUrl = (State||{}).url||History.getLocationHref(), + pageUrl; + + // Create + pageUrl = stateUrl.replace(/\/+$/,'').replace(/[^\/]+$/,function(part,index,string){ + return (/\./).test(part) ? part : part+'/'; + }); + + // Return + return pageUrl; + }; + + /** + * History.getBasePageUrl() + * Fetches the Url of the directory of the current page + * @return {String} basePageUrl + */ + History.getBasePageUrl = function(){ + // Create + var basePageUrl = (History.getLocationHref()).replace(/[#\?].*/,'').replace(/[^\/]+$/,function(part,index,string){ + return (/[^\/]$/).test(part) ? '' : part; + }).replace(/\/+$/,'')+'/'; + + // Return + return basePageUrl; + }; + + /** + * History.getFullUrl(url) + * Ensures that we have an absolute URL and not a relative URL + * @param {string} url + * @param {Boolean} allowBaseHref + * @return {string} fullUrl + */ + History.getFullUrl = function(url,allowBaseHref){ + // Prepare + var fullUrl = url, firstChar = url.substring(0,1); + allowBaseHref = (typeof allowBaseHref === 'undefined') ? true : allowBaseHref; + + // Check + if ( /[a-z]+\:\/\//.test(url) ) { + // Full URL + } + else if ( firstChar === '/' ) { + // Root URL + fullUrl = History.getRootUrl()+url.replace(/^\/+/,''); + } + else if ( firstChar === '#' ) { + // Anchor URL + fullUrl = History.getPageUrl().replace(/#.*/,'')+url; + } + else if ( firstChar === '?' ) { + // Query URL + fullUrl = History.getPageUrl().replace(/[\?#].*/,'')+url; + } + else { + // Relative URL + if ( allowBaseHref ) { + fullUrl = History.getBaseUrl()+url.replace(/^(\.\/)+/,''); + } else { + fullUrl = History.getBasePageUrl()+url.replace(/^(\.\/)+/,''); + } + // We have an if condition above as we do not want hashes + // which are relative to the baseHref in our URLs + // as if the baseHref changes, then all our bookmarks + // would now point to different locations + // whereas the basePageUrl will always stay the same + } + + // Return + return fullUrl.replace(/\#$/,''); + }; + + /** + * History.getShortUrl(url) + * Ensures that we have a relative URL and not a absolute URL + * @param {string} url + * @return {string} url + */ + History.getShortUrl = function(url){ + // Prepare + var shortUrl = url, baseUrl = History.getBaseUrl(), rootUrl = History.getRootUrl(); + + // Trim baseUrl + if ( History.emulated.pushState ) { + // We are in a if statement as when pushState is not emulated + // The actual url these short urls are relative to can change + // So within the same session, we the url may end up somewhere different + shortUrl = shortUrl.replace(baseUrl,''); + } + + // Trim rootUrl + shortUrl = shortUrl.replace(rootUrl,'/'); + + // Ensure we can still detect it as a state + if ( History.isTraditionalAnchor(shortUrl) ) { + shortUrl = './'+shortUrl; + } + + // Clean It + shortUrl = shortUrl.replace(/^(\.\/)+/g,'./').replace(/\#$/,''); + + // Return + return shortUrl; + }; + + /** + * History.getLocationHref(document) + * Returns a normalized version of document.location.href + * accounting for browser inconsistencies, etc. + * + * This URL will be URI-encoded and will include the hash + * + * @param {object} document + * @return {string} url + */ + History.getLocationHref = function(doc) { + doc = doc || document; + + // most of the time, this will be true + if (doc.URL === doc.location.href) + return doc.location.href; + + // some versions of webkit URI-decode document.location.href + // but they leave document.URL in an encoded state + if (doc.location.href === decodeURIComponent(doc.URL)) + return doc.URL; + + // FF 3.6 only updates document.URL when a page is reloaded + // document.location.href is updated correctly + if (doc.location.hash && decodeURIComponent(doc.location.href.replace(/^[^#]+/, "")) === doc.location.hash) + return doc.location.href; + + if (doc.URL.indexOf('#') == -1 && doc.location.href.indexOf('#') != -1) + return doc.location.href; + + return doc.URL || doc.location.href; + }; + + + // ==================================================================== + // State Storage + + /** + * History.store + * The store for all session specific data + */ + History.store = {}; + + /** + * History.idToState + * 1-1: State ID to State Object + */ + History.idToState = History.idToState||{}; + + /** + * History.stateToId + * 1-1: State String to State ID + */ + History.stateToId = History.stateToId||{}; + + /** + * History.urlToId + * 1-1: State URL to State ID + */ + History.urlToId = History.urlToId||{}; + + /** + * History.storedStates + * Store the states in an array + */ + History.storedStates = History.storedStates||[]; + + /** + * History.savedStates + * Saved the states in an array + */ + History.savedStates = History.savedStates||[]; + + /** + * History.noramlizeStore() + * Noramlize the store by adding necessary values + */ + History.normalizeStore = function(){ + History.store.idToState = History.store.idToState||{}; + History.store.urlToId = History.store.urlToId||{}; + History.store.stateToId = History.store.stateToId||{}; + }; + + /** + * History.getState() + * Get an object containing the data, title and url of the current state + * @param {Boolean} friendly + * @param {Boolean} create + * @return {Object} State + */ + History.getState = function(friendly,create){ + // Prepare + if ( typeof friendly === 'undefined' ) { friendly = true; } + if ( typeof create === 'undefined' ) { create = true; } + + // Fetch + var State = History.getLastSavedState(); + + // Create + if ( !State && create ) { + State = History.createStateObject(); + } + + // Adjust + if ( friendly ) { + State = History.cloneObject(State); + State.url = State.cleanUrl||State.url; + } + + // Return + return State; + }; + + /** + * History.getIdByState(State) + * Gets a ID for a State + * @param {State} newState + * @return {String} id + */ + History.getIdByState = function(newState){ + + // Fetch ID + var id = History.extractId(newState.url), + str; + + if ( !id ) { + // Find ID via State String + str = History.getStateString(newState); + if ( typeof History.stateToId[str] !== 'undefined' ) { + id = History.stateToId[str]; + } + else if ( typeof History.store.stateToId[str] !== 'undefined' ) { + id = History.store.stateToId[str]; + } + else { + // Generate a new ID + while ( true ) { + id = (new Date()).getTime() + String(Math.random()).replace(/\D/g,''); + if ( typeof History.idToState[id] === 'undefined' && typeof History.store.idToState[id] === 'undefined' ) { + break; + } + } + + // Apply the new State to the ID + History.stateToId[str] = id; + History.idToState[id] = newState; + } + } + + // Return ID + return id; + }; + + /** + * History.normalizeState(State) + * Expands a State Object + * @param {object} State + * @return {object} + */ + History.normalizeState = function(oldState){ + // Variables + var newState, dataNotEmpty; + + // Prepare + if ( !oldState || (typeof oldState !== 'object') ) { + oldState = {}; + } + + // Check + if ( typeof oldState.normalized !== 'undefined' ) { + return oldState; + } + + // Adjust + if ( !oldState.data || (typeof oldState.data !== 'object') ) { + oldState.data = {}; + } + + // ---------------------------------------------------------------- + + // Create + newState = {}; + newState.normalized = true; + newState.title = oldState.title||''; + newState.url = History.getFullUrl(oldState.url?oldState.url:(History.getLocationHref())); + newState.hash = History.getShortUrl(newState.url); + newState.data = History.cloneObject(oldState.data); + + // Fetch ID + newState.id = History.getIdByState(newState); + + // ---------------------------------------------------------------- + + // Clean the URL + newState.cleanUrl = newState.url.replace(/\??\&_suid.*/,''); + newState.url = newState.cleanUrl; + + // Check to see if we have more than just a url + dataNotEmpty = !History.isEmptyObject(newState.data); + + // Apply + if ( (newState.title || dataNotEmpty) && History.options.disableSuid !== true ) { + // Add ID to Hash + newState.hash = History.getShortUrl(newState.url).replace(/\??\&_suid.*/,''); + if ( !/\?/.test(newState.hash) ) { + newState.hash += '?'; + } + newState.hash += '&_suid='+newState.id; + } + + // Create the Hashed URL + newState.hashedUrl = History.getFullUrl(newState.hash); + + // ---------------------------------------------------------------- + + // Update the URL if we have a duplicate + if ( (History.emulated.pushState || History.bugs.safariPoll) && History.hasUrlDuplicate(newState) ) { + newState.url = newState.hashedUrl; + } + + // ---------------------------------------------------------------- + + // Return + return newState; + }; + + /** + * History.createStateObject(data,title,url) + * Creates a object based on the data, title and url state params + * @param {object} data + * @param {string} title + * @param {string} url + * @return {object} + */ + History.createStateObject = function(data,title,url){ + // Hashify + var State = { + 'data': data, + 'title': title, + 'url': url + }; + + // Expand the State + State = History.normalizeState(State); + + // Return object + return State; + }; + + /** + * History.getStateById(id) + * Get a state by it's UID + * @param {String} id + */ + History.getStateById = function(id){ + // Prepare + id = String(id); + + // Retrieve + var State = History.idToState[id] || History.store.idToState[id] || undefined; + + // Return State + return State; + }; + + /** + * Get a State's String + * @param {State} passedState + */ + History.getStateString = function(passedState){ + // Prepare + var State, cleanedState, str; + + // Fetch + State = History.normalizeState(passedState); + + // Clean + cleanedState = { + data: State.data, + title: passedState.title, + url: passedState.url + }; + + // Fetch + str = JSON.stringify(cleanedState); + + // Return + return str; + }; + + /** + * Get a State's ID + * @param {State} passedState + * @return {String} id + */ + History.getStateId = function(passedState){ + // Prepare + var State, id; + + // Fetch + State = History.normalizeState(passedState); + + // Fetch + id = State.id; + + // Return + return id; + }; + + /** + * History.getHashByState(State) + * Creates a Hash for the State Object + * @param {State} passedState + * @return {String} hash + */ + History.getHashByState = function(passedState){ + // Prepare + var State, hash; + + // Fetch + State = History.normalizeState(passedState); + + // Hash + hash = State.hash; + + // Return + return hash; + }; + + /** + * History.extractId(url_or_hash) + * Get a State ID by it's URL or Hash + * @param {string} url_or_hash + * @return {string} id + */ + History.extractId = function ( url_or_hash ) { + // Prepare + var id,parts,url, tmp; + + // Extract + + // If the URL has a #, use the id from before the # + if (url_or_hash.indexOf('#') != -1) + { + tmp = url_or_hash.split("#")[0]; + } + else + { + tmp = url_or_hash; + } + + parts = /(.*)\&_suid=([0-9]+)$/.exec(tmp); + url = parts ? (parts[1]||url_or_hash) : url_or_hash; + id = parts ? String(parts[2]||'') : ''; + + // Return + return id||false; + }; + + /** + * History.isTraditionalAnchor + * Checks to see if the url is a traditional anchor or not + * @param {String} url_or_hash + * @return {Boolean} + */ + History.isTraditionalAnchor = function(url_or_hash){ + // Check + var isTraditional = !(/[\/\?\.]/.test(url_or_hash)); + + // Return + return isTraditional; + }; + + /** + * History.extractState + * Get a State by it's URL or Hash + * @param {String} url_or_hash + * @return {State|null} + */ + History.extractState = function(url_or_hash,create){ + // Prepare + var State = null, id, url; + create = create||false; + + // Fetch SUID + id = History.extractId(url_or_hash); + if ( id ) { + State = History.getStateById(id); + } + + // Fetch SUID returned no State + if ( !State ) { + // Fetch URL + url = History.getFullUrl(url_or_hash); + + // Check URL + id = History.getIdByUrl(url)||false; + if ( id ) { + State = History.getStateById(id); + } + + // Create State + if ( !State && create && !History.isTraditionalAnchor(url_or_hash) ) { + State = History.createStateObject(null,null,url); + } + } + + // Return + return State; + }; + + /** + * History.getIdByUrl() + * Get a State ID by a State URL + */ + History.getIdByUrl = function(url){ + // Fetch + var id = History.urlToId[url] || History.store.urlToId[url] || undefined; + + // Return + return id; + }; + + /** + * History.getLastSavedState() + * Get an object containing the data, title and url of the current state + * @return {Object} State + */ + History.getLastSavedState = function(){ + return History.savedStates[History.savedStates.length-1]||undefined; + }; + + /** + * History.getLastStoredState() + * Get an object containing the data, title and url of the current state + * @return {Object} State + */ + History.getLastStoredState = function(){ + return History.storedStates[History.storedStates.length-1]||undefined; + }; + + /** + * History.hasUrlDuplicate + * Checks if a Url will have a url conflict + * @param {Object} newState + * @return {Boolean} hasDuplicate + */ + History.hasUrlDuplicate = function(newState) { + // Prepare + var hasDuplicate = false, + oldState; + + // Fetch + oldState = History.extractState(newState.url); + + // Check + hasDuplicate = oldState && oldState.id !== newState.id; + + // Return + return hasDuplicate; + }; + + /** + * History.storeState + * Store a State + * @param {Object} newState + * @return {Object} newState + */ + History.storeState = function(newState){ + // Store the State + History.urlToId[newState.url] = newState.id; + + // Push the State + History.storedStates.push(History.cloneObject(newState)); + + // Return newState + return newState; + }; + + /** + * History.isLastSavedState(newState) + * Tests to see if the state is the last state + * @param {Object} newState + * @return {boolean} isLast + */ + History.isLastSavedState = function(newState){ + // Prepare + var isLast = false, + newId, oldState, oldId; + + // Check + if ( History.savedStates.length ) { + newId = newState.id; + oldState = History.getLastSavedState(); + oldId = oldState.id; + + // Check + isLast = (newId === oldId); + } + + // Return + return isLast; + }; + + /** + * History.saveState + * Push a State + * @param {Object} newState + * @return {boolean} changed + */ + History.saveState = function(newState){ + // Check Hash + if ( History.isLastSavedState(newState) ) { + return false; + } + + // Push the State + History.savedStates.push(History.cloneObject(newState)); + + // Return true + return true; + }; + + /** + * History.getStateByIndex() + * Gets a state by the index + * @param {integer} index + * @return {Object} + */ + History.getStateByIndex = function(index){ + // Prepare + var State = null; + + // Handle + if ( typeof index === 'undefined' ) { + // Get the last inserted + State = History.savedStates[History.savedStates.length-1]; + } + else if ( index < 0 ) { + // Get from the end + State = History.savedStates[History.savedStates.length+index]; + } + else { + // Get from the beginning + State = History.savedStates[index]; + } + + // Return State + return State; + }; + + /** + * History.getCurrentIndex() + * Gets the current index + * @return (integer) + */ + History.getCurrentIndex = function(){ + // Prepare + var index = null; + + // No states saved + if(History.savedStates.length < 1) { + index = 0; + } + else { + index = History.savedStates.length-1; + } + return index; + }; + + // ==================================================================== + // Hash Helpers + + /** + * History.getHash() + * @param {Location=} location + * Gets the current document hash + * Note: unlike location.hash, this is guaranteed to return the escaped hash in all browsers + * @return {string} + */ + History.getHash = function(doc){ + var url = History.getLocationHref(doc), + hash; + hash = History.getHashByUrl(url); + return hash; + }; + + /** + * History.unescapeHash() + * normalize and Unescape a Hash + * @param {String} hash + * @return {string} + */ + History.unescapeHash = function(hash){ + // Prepare + var result = History.normalizeHash(hash); + + // Unescape hash + result = decodeURIComponent(result); + + // Return result + return result; + }; + + /** + * History.normalizeHash() + * normalize a hash across browsers + * @return {string} + */ + History.normalizeHash = function(hash){ + // Prepare + var result = hash.replace(/[^#]*#/,'').replace(/#.*/, ''); + + // Return result + return result; + }; + + /** + * History.setHash(hash) + * Sets the document hash + * @param {string} hash + * @return {History} + */ + History.setHash = function(hash,queue){ + // Prepare + var State, pageUrl; + + // Handle Queueing + if ( queue !== false && History.busy() ) { + // Wait + Push to Queue + //History.debug('History.setHash: we must wait', arguments); + History.pushQueue({ + scope: History, + callback: History.setHash, + args: arguments, + queue: queue + }); + return false; + } + + // Log + //History.debug('History.setHash: called',hash); + + // Make Busy + Continue + History.busy(true); + + // Check if hash is a state + State = History.extractState(hash,true); + if ( State && !History.emulated.pushState ) { + // Hash is a state so skip the setHash + //History.debug('History.setHash: Hash is a state so skipping the hash set with a direct pushState call',arguments); + + // PushState + History.pushState(State.data,State.title,State.url,false); + } + else if ( History.getHash() !== hash ) { + // Hash is a proper hash, so apply it + + // Handle browser bugs + if ( History.bugs.setHash ) { + // Fix Safari Bug https://bugs.webkit.org/show_bug.cgi?id=56249 + + // Fetch the base page + pageUrl = History.getPageUrl(); + + // Safari hash apply + History.pushState(null,null,pageUrl+'#'+hash,false); + } + else { + // Normal hash apply + document.location.hash = hash; + } + } + + // Chain + return History; + }; + + /** + * History.escape() + * normalize and Escape a Hash + * @return {string} + */ + History.escapeHash = function(hash){ + // Prepare + var result = History.normalizeHash(hash); + + // Escape hash + result = window.encodeURIComponent(result); + + // IE6 Escape Bug + if ( !History.bugs.hashEscape ) { + // Restore common parts + result = result + .replace(/\%21/g,'!') + .replace(/\%26/g,'&') + .replace(/\%3D/g,'=') + .replace(/\%3F/g,'?'); + } + + // Return result + return result; + }; + + /** + * History.getHashByUrl(url) + * Extracts the Hash from a URL + * @param {string} url + * @return {string} url + */ + History.getHashByUrl = function(url){ + // Extract the hash + var hash = String(url) + .replace(/([^#]*)#?([^#]*)#?(.*)/, '$2') + ; + + // Unescape hash + hash = History.unescapeHash(hash); + + // Return hash + return hash; + }; + + /** + * History.setTitle(title) + * Applies the title to the document + * @param {State} newState + * @return {Boolean} + */ + History.setTitle = function(newState){ + // Prepare + var title = newState.title, + firstState; + + // Initial + if ( !title ) { + firstState = History.getStateByIndex(0); + if ( firstState && firstState.url === newState.url ) { + title = firstState.title||History.options.initialTitle; + } + } + + // Apply + try { + document.getElementsByTagName('title')[0].innerHTML = title.replace('<','<').replace('>','>').replace(' & ',' & '); + } + catch ( Exception ) { } + document.title = title; + + // Chain + return History; + }; + + + // ==================================================================== + // Queueing + + /** + * History.queues + * The list of queues to use + * First In, First Out + */ + History.queues = []; + + /** + * History.busy(value) + * @param {boolean} value [optional] + * @return {boolean} busy + */ + History.busy = function(value){ + // Apply + if ( typeof value !== 'undefined' ) { + //History.debug('History.busy: changing ['+(History.busy.flag||false)+'] to ['+(value||false)+']', History.queues.length); + History.busy.flag = value; + } + // Default + else if ( typeof History.busy.flag === 'undefined' ) { + History.busy.flag = false; + } + + // Queue + if ( !History.busy.flag ) { + // Execute the next item in the queue + clearTimeout(History.busy.timeout); + var fireNext = function(){ + var i, queue, item; + if ( History.busy.flag ) return; + for ( i=History.queues.length-1; i >= 0; --i ) { + queue = History.queues[i]; + if ( queue.length === 0 ) continue; + item = queue.shift(); + History.fireQueueItem(item); + History.busy.timeout = setTimeout(fireNext,History.options.busyDelay); + } + }; + History.busy.timeout = setTimeout(fireNext,History.options.busyDelay); + } + + // Return + return History.busy.flag; + }; + + /** + * History.busy.flag + */ + History.busy.flag = false; + + /** + * History.fireQueueItem(item) + * Fire a Queue Item + * @param {Object} item + * @return {Mixed} result + */ + History.fireQueueItem = function(item){ + return item.callback.apply(item.scope||History,item.args||[]); + }; + + /** + * History.pushQueue(callback,args) + * Add an item to the queue + * @param {Object} item [scope,callback,args,queue] + */ + History.pushQueue = function(item){ + // Prepare the queue + History.queues[item.queue||0] = History.queues[item.queue||0]||[]; + + // Add to the queue + History.queues[item.queue||0].push(item); + + // Chain + return History; + }; + + /** + * History.queue (item,queue), (func,queue), (func), (item) + * Either firs the item now if not busy, or adds it to the queue + */ + History.queue = function(item,queue){ + // Prepare + if ( typeof item === 'function' ) { + item = { + callback: item + }; + } + if ( typeof queue !== 'undefined' ) { + item.queue = queue; + } + + // Handle + if ( History.busy() ) { + History.pushQueue(item); + } else { + History.fireQueueItem(item); + } + + // Chain + return History; + }; + + /** + * History.clearQueue() + * Clears the Queue + */ + History.clearQueue = function(){ + History.busy.flag = false; + History.queues = []; + return History; + }; + + + // ==================================================================== + // IE Bug Fix + + /** + * History.stateChanged + * States whether or not the state has changed since the last double check was initialised + */ + History.stateChanged = false; + + /** + * History.doubleChecker + * Contains the timeout used for the double checks + */ + History.doubleChecker = false; + + /** + * History.doubleCheckComplete() + * Complete a double check + * @return {History} + */ + History.doubleCheckComplete = function(){ + // Update + History.stateChanged = true; + + // Clear + History.doubleCheckClear(); + + // Chain + return History; + }; + + /** + * History.doubleCheckClear() + * Clear a double check + * @return {History} + */ + History.doubleCheckClear = function(){ + // Clear + if ( History.doubleChecker ) { + clearTimeout(History.doubleChecker); + History.doubleChecker = false; + } + + // Chain + return History; + }; + + /** + * History.doubleCheck() + * Create a double check + * @return {History} + */ + History.doubleCheck = function(tryAgain){ + // Reset + History.stateChanged = false; + History.doubleCheckClear(); + + // Fix IE6,IE7 bug where calling history.back or history.forward does not actually change the hash (whereas doing it manually does) + // Fix Safari 5 bug where sometimes the state does not change: https://bugs.webkit.org/show_bug.cgi?id=42940 + if ( History.bugs.ieDoubleCheck ) { + // Apply Check + History.doubleChecker = setTimeout( + function(){ + History.doubleCheckClear(); + if ( !History.stateChanged ) { + //History.debug('History.doubleCheck: State has not yet changed, trying again', arguments); + // Re-Attempt + tryAgain(); + } + return true; + }, + History.options.doubleCheckInterval + ); + } + + // Chain + return History; + }; + + + // ==================================================================== + // Safari Bug Fix + + /** + * History.safariStatePoll() + * Poll the current state + * @return {History} + */ + History.safariStatePoll = function(){ + // Poll the URL + + // Get the Last State which has the new URL + var + urlState = History.extractState(History.getLocationHref()), + newState; + + // Check for a difference + if ( !History.isLastSavedState(urlState) ) { + newState = urlState; + } + else { + return; + } + + // Check if we have a state with that url + // If not create it + if ( !newState ) { + //History.debug('History.safariStatePoll: new'); + newState = History.createStateObject(); + } + + // Apply the New State + //History.debug('History.safariStatePoll: trigger'); + History.Adapter.trigger(window,'popstate'); + + // Chain + return History; + }; + + + // ==================================================================== + // State Aliases + + /** + * History.back(queue) + * Send the browser history back one item + * @param {Integer} queue [optional] + */ + History.back = function(queue){ + //History.debug('History.back: called', arguments); + + // Handle Queueing + if ( queue !== false && History.busy() ) { + // Wait + Push to Queue + //History.debug('History.back: we must wait', arguments); + History.pushQueue({ + scope: History, + callback: History.back, + args: arguments, + queue: queue + }); + return false; + } + + // Make Busy + Continue + History.busy(true); + + // Fix certain browser bugs that prevent the state from changing + History.doubleCheck(function(){ + History.back(false); + }); + + // Go back + history.go(-1); + + // End back closure + return true; + }; + + /** + * History.forward(queue) + * Send the browser history forward one item + * @param {Integer} queue [optional] + */ + History.forward = function(queue){ + //History.debug('History.forward: called', arguments); + + // Handle Queueing + if ( queue !== false && History.busy() ) { + // Wait + Push to Queue + //History.debug('History.forward: we must wait', arguments); + History.pushQueue({ + scope: History, + callback: History.forward, + args: arguments, + queue: queue + }); + return false; + } + + // Make Busy + Continue + History.busy(true); + + // Fix certain browser bugs that prevent the state from changing + History.doubleCheck(function(){ + History.forward(false); + }); + + // Go forward + history.go(1); + + // End forward closure + return true; + }; + + /** + * History.go(index,queue) + * Send the browser history back or forward index times + * @param {Integer} queue [optional] + */ + History.go = function(index,queue){ + //History.debug('History.go: called', arguments); + + // Prepare + var i; + + // Handle + if ( index > 0 ) { + // Forward + for ( i=1; i<=index; ++i ) { + History.forward(queue); + } + } + else if ( index < 0 ) { + // Backward + for ( i=-1; i>=index; --i ) { + History.back(queue); + } + } + else { + throw new Error('History.go: History.go requires a positive or negative integer passed.'); + } + + // Chain + return History; + }; + + + // ==================================================================== + // HTML5 State Support + + // Non-Native pushState Implementation + if ( History.emulated.pushState ) { + /* + * Provide Skeleton for HTML4 Browsers + */ + + // Prepare + var emptyFunction = function(){}; + History.pushState = History.pushState||emptyFunction; + History.replaceState = History.replaceState||emptyFunction; + } // History.emulated.pushState + + // Native pushState Implementation + else { + /* + * Use native HTML5 History API Implementation + */ + + /** + * History.onPopState(event,extra) + * Refresh the Current State + */ + History.onPopState = function(event,extra){ + // Prepare + var stateId = false, newState = false, currentHash, currentState; + + // Reset the double check + History.doubleCheckComplete(); + + // Check for a Hash, and handle apporiatly + currentHash = History.getHash(); + if ( currentHash ) { + // Expand Hash + currentState = History.extractState(currentHash||History.getLocationHref(),true); + if ( currentState ) { + // We were able to parse it, it must be a State! + // Let's forward to replaceState + //History.debug('History.onPopState: state anchor', currentHash, currentState); + History.replaceState(currentState.data, currentState.title, currentState.url, false); + } + else { + // Traditional Anchor + //History.debug('History.onPopState: traditional anchor', currentHash); + History.Adapter.trigger(window,'anchorchange'); + History.busy(false); + } + + // We don't care for hashes + History.expectedStateId = false; + return false; + } + + // Ensure + stateId = History.Adapter.extractEventData('state',event,extra) || false; + + // Fetch State + if ( stateId ) { + // Vanilla: Back/forward button was used + newState = History.getStateById(stateId); + } + else if ( History.expectedStateId ) { + // Vanilla: A new state was pushed, and popstate was called manually + newState = History.getStateById(History.expectedStateId); + } + else { + // Initial State + newState = History.extractState(History.getLocationHref()); + } + + // The State did not exist in our store + if ( !newState ) { + // Regenerate the State + newState = History.createStateObject(null,null,History.getLocationHref()); + } + + // Clean + History.expectedStateId = false; + + // Check if we are the same state + if ( History.isLastSavedState(newState) ) { + // There has been no change (just the page's hash has finally propagated) + //History.debug('History.onPopState: no change', newState, History.savedStates); + History.busy(false); + return false; + } + + // Store the State + History.storeState(newState); + History.saveState(newState); + + // Force update of the title + History.setTitle(newState); + + // Fire Our Event + History.Adapter.trigger(window,'statechange'); + History.busy(false); + + // Return true + return true; + }; + History.Adapter.bind(window,'popstate',History.onPopState); + + /** + * History.pushState(data,title,url) + * Add a new State to the history object, become it, and trigger onpopstate + * We have to trigger for HTML4 compatibility + * @param {object} data + * @param {string} title + * @param {string} url + * @return {true} + */ + History.pushState = function(data,title,url,queue){ + //History.debug('History.pushState: called', arguments); + + // Check the State + if ( History.getHashByUrl(url) && History.emulated.pushState ) { + throw new Error('History.js does not support states with fragement-identifiers (hashes/anchors).'); + } + + // Handle Queueing + if ( queue !== false && History.busy() ) { + // Wait + Push to Queue + //History.debug('History.pushState: we must wait', arguments); + History.pushQueue({ + scope: History, + callback: History.pushState, + args: arguments, + queue: queue + }); + return false; + } + + // Make Busy + Continue + History.busy(true); + + // Create the newState + var newState = History.createStateObject(data,title,url); + + // Check it + if ( History.isLastSavedState(newState) ) { + // Won't be a change + History.busy(false); + } + else { + // Store the newState + History.storeState(newState); + History.expectedStateId = newState.id; + + // Push the newState + history.pushState(newState.id,newState.title,newState.url); + + // Fire HTML5 Event + History.Adapter.trigger(window,'popstate'); + } + + // End pushState closure + return true; + }; + + /** + * History.replaceState(data,title,url) + * Replace the State and trigger onpopstate + * We have to trigger for HTML4 compatibility + * @param {object} data + * @param {string} title + * @param {string} url + * @return {true} + */ + History.replaceState = function(data,title,url,queue){ + //History.debug('History.replaceState: called', arguments); + + // Check the State + if ( History.getHashByUrl(url) && History.emulated.pushState ) { + throw new Error('History.js does not support states with fragement-identifiers (hashes/anchors).'); + } + + // Handle Queueing + if ( queue !== false && History.busy() ) { + // Wait + Push to Queue + //History.debug('History.replaceState: we must wait', arguments); + History.pushQueue({ + scope: History, + callback: History.replaceState, + args: arguments, + queue: queue + }); + return false; + } + + // Make Busy + Continue + History.busy(true); + + // Create the newState + var newState = History.createStateObject(data,title,url); + + // Check it + if ( History.isLastSavedState(newState) ) { + // Won't be a change + History.busy(false); + } + else { + // Store the newState + History.storeState(newState); + History.expectedStateId = newState.id; + + // Push the newState + history.replaceState(newState.id,newState.title,newState.url); + + // Fire HTML5 Event + History.Adapter.trigger(window,'popstate'); + } + + // End replaceState closure + return true; + }; + + } // !History.emulated.pushState + + + // ==================================================================== + // Initialise + + /** + * Load the Store + */ + if ( sessionStorage ) { + // Fetch + try { + History.store = JSON.parse(sessionStorage.getItem('History.store'))||{}; + } + catch ( err ) { + History.store = {}; + } + + // Normalize + History.normalizeStore(); + } + else { + // Default Load + History.store = {}; + History.normalizeStore(); + } + + /** + * Clear Intervals on exit to prevent memory leaks + */ + History.Adapter.bind(window,"unload",History.clearAllIntervals); + + /** + * Create the initial State + */ + History.saveState(History.storeState(History.extractState(History.getLocationHref(),true))); + + /** + * Bind for Saving Store + */ + if ( sessionStorage ) { + // When the page is closed + History.onUnload = function(){ + // Prepare + var currentStore, item, currentStoreString; + + // Fetch + try { + currentStore = JSON.parse(sessionStorage.getItem('History.store'))||{}; + } + catch ( err ) { + currentStore = {}; + } + + // Ensure + currentStore.idToState = currentStore.idToState || {}; + currentStore.urlToId = currentStore.urlToId || {}; + currentStore.stateToId = currentStore.stateToId || {}; + + // Sync + for ( item in History.idToState ) { + if ( !History.idToState.hasOwnProperty(item) ) { + continue; + } + currentStore.idToState[item] = History.idToState[item]; + } + for ( item in History.urlToId ) { + if ( !History.urlToId.hasOwnProperty(item) ) { + continue; + } + currentStore.urlToId[item] = History.urlToId[item]; + } + for ( item in History.stateToId ) { + if ( !History.stateToId.hasOwnProperty(item) ) { + continue; + } + currentStore.stateToId[item] = History.stateToId[item]; + } + + // Update + History.store = currentStore; + History.normalizeStore(); + + // In Safari, going into Private Browsing mode causes the + // Session Storage object to still exist but if you try and use + // or set any property/function of it it throws the exception + // "QUOTA_EXCEEDED_ERR: DOM Exception 22: An attempt was made to + // add something to storage that exceeded the quota." infinitely + // every second. + currentStoreString = JSON.stringify(currentStore); + try { + // Store + sessionStorage.setItem('History.store', currentStoreString); + } + catch (e) { + if (e.code === DOMException.QUOTA_EXCEEDED_ERR) { + if (sessionStorage.length) { + // Workaround for a bug seen on iPads. Sometimes the quota exceeded error comes up and simply + // removing/resetting the storage can work. + sessionStorage.removeItem('History.store'); + sessionStorage.setItem('History.store', currentStoreString); + } else { + // Otherwise, we're probably private browsing in Safari, so we'll ignore the exception. + } + } else { + throw e; + } + } + }; + + // For Internet Explorer + History.intervalList.push(setInterval(History.onUnload,History.options.storeInterval)); + + // For Other Browsers + History.Adapter.bind(window,'beforeunload',History.onUnload); + History.Adapter.bind(window,'unload',History.onUnload); + + // Both are enabled for consistency + } + + // Non-Native pushState Implementation + if ( !History.emulated.pushState ) { + // Be aware, the following is only for native pushState implementations + // If you are wanting to include something for all browsers + // Then include it above this if block + + /** + * Setup Safari Fix + */ + if ( History.bugs.safariPoll ) { + History.intervalList.push(setInterval(History.safariStatePoll, History.options.safariPollInterval)); + } + + /** + * Ensure Cross Browser Compatibility + */ + if ( navigator.vendor === 'Apple Computer, Inc.' || (navigator.appCodeName||'') === 'Mozilla' ) { + /** + * Fix Safari HashChange Issue + */ + + // Setup Alias + History.Adapter.bind(window,'hashchange',function(){ + History.Adapter.trigger(window,'popstate'); + }); + + // Initialise Alias + if ( History.getHash() ) { + History.Adapter.onDomLoad(function(){ + History.Adapter.trigger(window,'hashchange'); + }); + } + } + + } // !History.emulated.pushState + + + }; // History.initCore + + // Try to Initialise History + if (!History.options || !History.options.delayInit) { + History.init(); + } + +})(window); diff --git a/sites/all/themes/gui/materiobasetheme/bower_components/history.js/scripts/bundled-uncompressed/html4+html5/jquery.history.js b/sites/all/themes/gui/materiobasetheme/bower_components/history.js/scripts/bundled-uncompressed/html4+html5/jquery.history.js new file mode 100644 index 00000000..dc47ce7c --- /dev/null +++ b/sites/all/themes/gui/materiobasetheme/bower_components/history.js/scripts/bundled-uncompressed/html4+html5/jquery.history.js @@ -0,0 +1,3291 @@ +/* + json2.js + 2012-10-08 + + Public Domain. + + NO WARRANTY EXPRESSED OR IMPLIED. USE AT YOUR OWN RISK. + + See http://www.JSON.org/js.html + + + This code should be minified before deployment. + See http://javascript.crockford.com/jsmin.html + + USE YOUR OWN COPY. IT IS EXTREMELY UNWISE TO LOAD CODE FROM SERVERS YOU DO + NOT CONTROL. + + + This file creates a global JSON object containing two methods: stringify + and parse. + + JSON.stringify(value, replacer, space) + value any JavaScript value, usually an object or array. + + replacer an optional parameter that determines how object + values are stringified for objects. It can be a + function or an array of strings. + + space an optional parameter that specifies the indentation + of nested structures. If it is omitted, the text will + be packed without extra whitespace. If it is a number, + it will specify the number of spaces to indent at each + level. If it is a string (such as '\t' or ' '), + it contains the characters used to indent at each level. + + This method produces a JSON text from a JavaScript value. + + When an object value is found, if the object contains a toJSON + method, its toJSON method will be called and the result will be + stringified. A toJSON method does not serialize: it returns the + value represented by the name/value pair that should be serialized, + or undefined if nothing should be serialized. The toJSON method + will be passed the key associated with the value, and this will be + bound to the value + + For example, this would serialize Dates as ISO strings. + + Date.prototype.toJSON = function (key) { + function f(n) { + // Format integers to have at least two digits. + return n < 10 ? '0' + n : n; + } + + return this.getUTCFullYear() + '-' + + f(this.getUTCMonth() + 1) + '-' + + f(this.getUTCDate()) + 'T' + + f(this.getUTCHours()) + ':' + + f(this.getUTCMinutes()) + ':' + + f(this.getUTCSeconds()) + 'Z'; + }; + + You can provide an optional replacer method. It will be passed the + key and value of each member, with this bound to the containing + object. The value that is returned from your method will be + serialized. If your method returns undefined, then the member will + be excluded from the serialization. + + If the replacer parameter is an array of strings, then it will be + used to select the members to be serialized. It filters the results + such that only members with keys listed in the replacer array are + stringified. + + Values that do not have JSON representations, such as undefined or + functions, will not be serialized. Such values in objects will be + dropped; in arrays they will be replaced with null. You can use + a replacer function to replace those with JSON values. + JSON.stringify(undefined) returns undefined. + + The optional space parameter produces a stringification of the + value that is filled with line breaks and indentation to make it + easier to read. + + If the space parameter is a non-empty string, then that string will + be used for indentation. If the space parameter is a number, then + the indentation will be that many spaces. + + Example: + + text = JSON.stringify(['e', {pluribus: 'unum'}]); + // text is '["e",{"pluribus":"unum"}]' + + + text = JSON.stringify(['e', {pluribus: 'unum'}], null, '\t'); + // text is '[\n\t"e",\n\t{\n\t\t"pluribus": "unum"\n\t}\n]' + + text = JSON.stringify([new Date()], function (key, value) { + return this[key] instanceof Date ? + 'Date(' + this[key] + ')' : value; + }); + // text is '["Date(---current time---)"]' + + + JSON.parse(text, reviver) + This method parses a JSON text to produce an object or array. + It can throw a SyntaxError exception. + + The optional reviver parameter is a function that can filter and + transform the results. It receives each of the keys and values, + and its return value is used instead of the original value. + If it returns what it received, then the structure is not modified. + If it returns undefined then the member is deleted. + + Example: + + // Parse the text. Values that look like ISO date strings will + // be converted to Date objects. + + myData = JSON.parse(text, function (key, value) { + var a; + if (typeof value === 'string') { + a = +/^(\d{4})-(\d{2})-(\d{2})T(\d{2}):(\d{2}):(\d{2}(?:\.\d*)?)Z$/.exec(value); + if (a) { + return new Date(Date.UTC(+a[1], +a[2] - 1, +a[3], +a[4], + +a[5], +a[6])); + } + } + return value; + }); + + myData = JSON.parse('["Date(09/09/2001)"]', function (key, value) { + var d; + if (typeof value === 'string' && + value.slice(0, 5) === 'Date(' && + value.slice(-1) === ')') { + d = new Date(value.slice(5, -1)); + if (d) { + return d; + } + } + return value; + }); + + + This is a reference implementation. You are free to copy, modify, or + redistribute. +*/ + +/*jslint evil: true, regexp: true */ + +/*members "", "\b", "\t", "\n", "\f", "\r", "\"", JSON, "\\", apply, + call, charCodeAt, getUTCDate, getUTCFullYear, getUTCHours, + getUTCMinutes, getUTCMonth, getUTCSeconds, hasOwnProperty, join, + lastIndex, length, parse, prototype, push, replace, slice, stringify, + test, toJSON, toString, valueOf +*/ + + +// Create a JSON object only if one does not already exist. We create the +// methods in a closure to avoid creating global variables. + +if (typeof JSON !== 'object') { + JSON = {}; +} + +(function () { + 'use strict'; + + function f(n) { + // Format integers to have at least two digits. + return n < 10 ? '0' + n : n; + } + + if (typeof Date.prototype.toJSON !== 'function') { + + Date.prototype.toJSON = function (key) { + + return isFinite(this.valueOf()) + ? this.getUTCFullYear() + '-' + + f(this.getUTCMonth() + 1) + '-' + + f(this.getUTCDate()) + 'T' + + f(this.getUTCHours()) + ':' + + f(this.getUTCMinutes()) + ':' + + f(this.getUTCSeconds()) + 'Z' + : null; + }; + + String.prototype.toJSON = + Number.prototype.toJSON = + Boolean.prototype.toJSON = function (key) { + return this.valueOf(); + }; + } + + var cx = /[\u0000\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g, + escapable = /[\\\"\x00-\x1f\x7f-\x9f\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g, + gap, + indent, + meta = { // table of character substitutions + '\b': '\\b', + '\t': '\\t', + '\n': '\\n', + '\f': '\\f', + '\r': '\\r', + '"' : '\\"', + '\\': '\\\\' + }, + rep; + + + function quote(string) { + +// If the string contains no control characters, no quote characters, and no +// backslash characters, then we can safely slap some quotes around it. +// Otherwise we must also replace the offending characters with safe escape +// sequences. + + escapable.lastIndex = 0; + return escapable.test(string) ? '"' + string.replace(escapable, function (a) { + var c = meta[a]; + return typeof c === 'string' + ? c + : '\\u' + ('0000' + a.charCodeAt(0).toString(16)).slice(-4); + }) + '"' : '"' + string + '"'; + } + + + function str(key, holder) { + +// Produce a string from holder[key]. + + var i, // The loop counter. + k, // The member key. + v, // The member value. + length, + mind = gap, + partial, + value = holder[key]; + +// If the value has a toJSON method, call it to obtain a replacement value. + + if (value && typeof value === 'object' && + typeof value.toJSON === 'function') { + value = value.toJSON(key); + } + +// If we were called with a replacer function, then call the replacer to +// obtain a replacement value. + + if (typeof rep === 'function') { + value = rep.call(holder, key, value); + } + +// What happens next depends on the value's type. + + switch (typeof value) { + case 'string': + return quote(value); + + case 'number': + +// JSON numbers must be finite. Encode non-finite numbers as null. + + return isFinite(value) ? String(value) : 'null'; + + case 'boolean': + case 'null': + +// If the value is a boolean or null, convert it to a string. Note: +// typeof null does not produce 'null'. The case is included here in +// the remote chance that this gets fixed someday. + + return String(value); + +// If the type is 'object', we might be dealing with an object or an array or +// null. + + case 'object': + +// Due to a specification blunder in ECMAScript, typeof null is 'object', +// so watch out for that case. + + if (!value) { + return 'null'; + } + +// Make an array to hold the partial results of stringifying this object value. + + gap += indent; + partial = []; + +// Is the value an array? + + if (Object.prototype.toString.apply(value) === '[object Array]') { + +// The value is an array. Stringify every element. Use null as a placeholder +// for non-JSON values. + + length = value.length; + for (i = 0; i < length; i += 1) { + partial[i] = str(i, value) || 'null'; + } + +// Join all of the elements together, separated with commas, and wrap them in +// brackets. + + v = partial.length === 0 + ? '[]' + : gap + ? '[\n' + gap + partial.join(',\n' + gap) + '\n' + mind + ']' + : '[' + partial.join(',') + ']'; + gap = mind; + return v; + } + +// If the replacer is an array, use it to select the members to be stringified. + + if (rep && typeof rep === 'object') { + length = rep.length; + for (i = 0; i < length; i += 1) { + if (typeof rep[i] === 'string') { + k = rep[i]; + v = str(k, value); + if (v) { + partial.push(quote(k) + (gap ? ': ' : ':') + v); + } + } + } + } else { + +// Otherwise, iterate through all of the keys in the object. + + for (k in value) { + if (Object.prototype.hasOwnProperty.call(value, k)) { + v = str(k, value); + if (v) { + partial.push(quote(k) + (gap ? ': ' : ':') + v); + } + } + } + } + +// Join all of the member texts together, separated with commas, +// and wrap them in braces. + + v = partial.length === 0 + ? '{}' + : gap + ? '{\n' + gap + partial.join(',\n' + gap) + '\n' + mind + '}' + : '{' + partial.join(',') + '}'; + gap = mind; + return v; + } + } + +// If the JSON object does not yet have a stringify method, give it one. + + if (typeof JSON.stringify !== 'function') { + JSON.stringify = function (value, replacer, space) { + +// The stringify method takes a value and an optional replacer, and an optional +// space parameter, and returns a JSON text. The replacer can be a function +// that can replace values, or an array of strings that will select the keys. +// A default replacer method can be provided. Use of the space parameter can +// produce text that is more easily readable. + + var i; + gap = ''; + indent = ''; + +// If the space parameter is a number, make an indent string containing that +// many spaces. + + if (typeof space === 'number') { + for (i = 0; i < space; i += 1) { + indent += ' '; + } + +// If the space parameter is a string, it will be used as the indent string. + + } else if (typeof space === 'string') { + indent = space; + } + +// If there is a replacer, it must be a function or an array. +// Otherwise, throw an error. + + rep = replacer; + if (replacer && typeof replacer !== 'function' && + (typeof replacer !== 'object' || + typeof replacer.length !== 'number')) { + throw new Error('JSON.stringify'); + } + +// Make a fake root object containing our value under the key of ''. +// Return the result of stringifying the value. + + return str('', {'': value}); + }; + } + + +// If the JSON object does not yet have a parse method, give it one. + + if (typeof JSON.parse !== 'function') { + JSON.parse = function (text, reviver) { + +// The parse method takes a text and an optional reviver function, and returns +// a JavaScript value if the text is a valid JSON text. + + var j; + + function walk(holder, key) { + +// The walk method is used to recursively walk the resulting structure so +// that modifications can be made. + + var k, v, value = holder[key]; + if (value && typeof value === 'object') { + for (k in value) { + if (Object.prototype.hasOwnProperty.call(value, k)) { + v = walk(value, k); + if (v !== undefined) { + value[k] = v; + } else { + delete value[k]; + } + } + } + } + return reviver.call(holder, key, value); + } + + +// Parsing happens in four stages. In the first stage, we replace certain +// Unicode characters with escape sequences. JavaScript handles many characters +// incorrectly, either silently deleting them, or treating them as line endings. + + text = String(text); + cx.lastIndex = 0; + if (cx.test(text)) { + text = text.replace(cx, function (a) { + return '\\u' + + ('0000' + a.charCodeAt(0).toString(16)).slice(-4); + }); + } + +// In the second stage, we run the text against regular expressions that look +// for non-JSON patterns. We are especially concerned with '()' and 'new' +// because they can cause invocation, and '=' because it can cause mutation. +// But just to be safe, we want to reject all unexpected forms. + +// We split the second stage into 4 regexp operations in order to work around +// crippling inefficiencies in IE's and Safari's regexp engines. First we +// replace the JSON backslash pairs with '@' (a non-JSON character). Second, we +// replace all simple value tokens with ']' characters. Third, we delete all +// open brackets that follow a colon or comma or that begin the text. Finally, +// we look to see that the remaining characters are only whitespace or ']' or +// ',' or ':' or '{' or '}'. If that is so, then the text is safe for eval. + + if (/^[\],:{}\s]*$/ + .test(text.replace(/\\(?:["\\\/bfnrt]|u[0-9a-fA-F]{4})/g, '@') + .replace(/"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g, ']') + .replace(/(?:^|:|,)(?:\s*\[)+/g, ''))) { + +// In the third stage we use the eval function to compile the text into a +// JavaScript structure. The '{' operator is subject to a syntactic ambiguity +// in JavaScript: it can begin a block or an object literal. We wrap the text +// in parens to eliminate the ambiguity. + + j = eval('(' + text + ')'); + +// In the optional fourth stage, we recursively walk the new structure, passing +// each name/value pair to a reviver function for possible transformation. + + return typeof reviver === 'function' + ? walk({'': j}, '') + : j; + } + +// If the text is not JSON parseable, then a SyntaxError is thrown. + + throw new SyntaxError('JSON.parse'); + }; + } +}());/** + * History.js jQuery Adapter + * @author Benjamin Arthur Lupton + * @copyright 2010-2011 Benjamin Arthur Lupton + * @license New BSD License + */ + +// Closure +(function(window,undefined){ + "use strict"; + + // Localise Globals + var + History = window.History = window.History||{}, + jQuery = window.jQuery; + + // Check Existence + if ( typeof History.Adapter !== 'undefined' ) { + throw new Error('History.js Adapter has already been loaded...'); + } + + // Add the Adapter + History.Adapter = { + /** + * History.Adapter.bind(el,event,callback) + * @param {Element|string} el + * @param {string} event - custom and standard events + * @param {function} callback + * @return {void} + */ + bind: function(el,event,callback){ + jQuery(el).bind(event,callback); + }, + + /** + * History.Adapter.trigger(el,event) + * @param {Element|string} el + * @param {string} event - custom and standard events + * @param {Object=} extra - a object of extra event data (optional) + * @return {void} + */ + trigger: function(el,event,extra){ + jQuery(el).trigger(event,extra); + }, + + /** + * History.Adapter.extractEventData(key,event,extra) + * @param {string} key - key for the event data to extract + * @param {string} event - custom and standard events + * @param {Object=} extra - a object of extra event data (optional) + * @return {mixed} + */ + extractEventData: function(key,event,extra){ + // jQuery Native then jQuery Custom + var result = (event && event.originalEvent && event.originalEvent[key]) || (extra && extra[key]) || undefined; + + // Return + return result; + }, + + /** + * History.Adapter.onDomLoad(callback) + * @param {function} callback + * @return {void} + */ + onDomLoad: function(callback) { + jQuery(callback); + } + }; + + // Try and Initialise History + if ( typeof History.init !== 'undefined' ) { + History.init(); + } + +})(window); + +/** + * History.js HTML4 Support + * Depends on the HTML5 Support + * @author Benjamin Arthur Lupton + * @copyright 2010-2011 Benjamin Arthur Lupton + * @license New BSD License + */ + +(function(window,undefined){ + "use strict"; + + // ======================================================================== + // Initialise + + // Localise Globals + var + document = window.document, // Make sure we are using the correct document + setTimeout = window.setTimeout||setTimeout, + clearTimeout = window.clearTimeout||clearTimeout, + setInterval = window.setInterval||setInterval, + History = window.History = window.History||{}; // Public History Object + + // Check Existence + if ( typeof History.initHtml4 !== 'undefined' ) { + throw new Error('History.js HTML4 Support has already been loaded...'); + } + + + // ======================================================================== + // Initialise HTML4 Support + + // Initialise HTML4 Support + History.initHtml4 = function(){ + // Initialise + if ( typeof History.initHtml4.initialized !== 'undefined' ) { + // Already Loaded + return false; + } + else { + History.initHtml4.initialized = true; + } + + + // ==================================================================== + // Properties + + /** + * History.enabled + * Is History enabled? + */ + History.enabled = true; + + + // ==================================================================== + // Hash Storage + + /** + * History.savedHashes + * Store the hashes in an array + */ + History.savedHashes = []; + + /** + * History.isLastHash(newHash) + * Checks if the hash is the last hash + * @param {string} newHash + * @return {boolean} true + */ + History.isLastHash = function(newHash){ + // Prepare + var oldHash = History.getHashByIndex(), + isLast; + + // Check + isLast = newHash === oldHash; + + // Return isLast + return isLast; + }; + + /** + * History.isHashEqual(newHash, oldHash) + * Checks to see if two hashes are functionally equal + * @param {string} newHash + * @param {string} oldHash + * @return {boolean} true + */ + History.isHashEqual = function(newHash, oldHash){ + newHash = encodeURIComponent(newHash).replace(/%25/g, "%"); + oldHash = encodeURIComponent(oldHash).replace(/%25/g, "%"); + return newHash === oldHash; + }; + + /** + * History.saveHash(newHash) + * Push a Hash + * @param {string} newHash + * @return {boolean} true + */ + History.saveHash = function(newHash){ + // Check Hash + if ( History.isLastHash(newHash) ) { + return false; + } + + // Push the Hash + History.savedHashes.push(newHash); + + // Return true + return true; + }; + + /** + * History.getHashByIndex() + * Gets a hash by the index + * @param {integer} index + * @return {string} + */ + History.getHashByIndex = function(index){ + // Prepare + var hash = null; + + // Handle + if ( typeof index === 'undefined' ) { + // Get the last inserted + hash = History.savedHashes[History.savedHashes.length-1]; + } + else if ( index < 0 ) { + // Get from the end + hash = History.savedHashes[History.savedHashes.length+index]; + } + else { + // Get from the beginning + hash = History.savedHashes[index]; + } + + // Return hash + return hash; + }; + + + // ==================================================================== + // Discarded States + + /** + * History.discardedHashes + * A hashed array of discarded hashes + */ + History.discardedHashes = {}; + + /** + * History.discardedStates + * A hashed array of discarded states + */ + History.discardedStates = {}; + + /** + * History.discardState(State) + * Discards the state by ignoring it through History + * @param {object} State + * @return {true} + */ + History.discardState = function(discardedState,forwardState,backState){ + //History.debug('History.discardState', arguments); + // Prepare + var discardedStateHash = History.getHashByState(discardedState), + discardObject; + + // Create Discard Object + discardObject = { + 'discardedState': discardedState, + 'backState': backState, + 'forwardState': forwardState + }; + + // Add to DiscardedStates + History.discardedStates[discardedStateHash] = discardObject; + + // Return true + return true; + }; + + /** + * History.discardHash(hash) + * Discards the hash by ignoring it through History + * @param {string} hash + * @return {true} + */ + History.discardHash = function(discardedHash,forwardState,backState){ + //History.debug('History.discardState', arguments); + // Create Discard Object + var discardObject = { + 'discardedHash': discardedHash, + 'backState': backState, + 'forwardState': forwardState + }; + + // Add to discardedHash + History.discardedHashes[discardedHash] = discardObject; + + // Return true + return true; + }; + + /** + * History.discardedState(State) + * Checks to see if the state is discarded + * @param {object} State + * @return {bool} + */ + History.discardedState = function(State){ + // Prepare + var StateHash = History.getHashByState(State), + discarded; + + // Check + discarded = History.discardedStates[StateHash]||false; + + // Return true + return discarded; + }; + + /** + * History.discardedHash(hash) + * Checks to see if the state is discarded + * @param {string} State + * @return {bool} + */ + History.discardedHash = function(hash){ + // Check + var discarded = History.discardedHashes[hash]||false; + + // Return true + return discarded; + }; + + /** + * History.recycleState(State) + * Allows a discarded state to be used again + * @param {object} data + * @param {string} title + * @param {string} url + * @return {true} + */ + History.recycleState = function(State){ + //History.debug('History.recycleState', arguments); + // Prepare + var StateHash = History.getHashByState(State); + + // Remove from DiscardedStates + if ( History.discardedState(State) ) { + delete History.discardedStates[StateHash]; + } + + // Return true + return true; + }; + + + // ==================================================================== + // HTML4 HashChange Support + + if ( History.emulated.hashChange ) { + /* + * We must emulate the HTML4 HashChange Support by manually checking for hash changes + */ + + /** + * History.hashChangeInit() + * Init the HashChange Emulation + */ + History.hashChangeInit = function(){ + // Define our Checker Function + History.checkerFunction = null; + + // Define some variables that will help in our checker function + var lastDocumentHash = '', + iframeId, iframe, + lastIframeHash, checkerRunning, + startedWithHash = Boolean(History.getHash()); + + // Handle depending on the browser + if ( History.isInternetExplorer() ) { + // IE6 and IE7 + // We need to use an iframe to emulate the back and forward buttons + + // Create iFrame + iframeId = 'historyjs-iframe'; + iframe = document.createElement('iframe'); + + // Adjust iFarme + // IE 6 requires iframe to have a src on HTTPS pages, otherwise it will throw a + // "This page contains both secure and nonsecure items" warning. + iframe.setAttribute('id', iframeId); + iframe.setAttribute('src', '#'); + iframe.style.display = 'none'; + + // Append iFrame + document.body.appendChild(iframe); + + // Create initial history entry + iframe.contentWindow.document.open(); + iframe.contentWindow.document.close(); + + // Define some variables that will help in our checker function + lastIframeHash = ''; + checkerRunning = false; + + // Define the checker function + History.checkerFunction = function(){ + // Check Running + if ( checkerRunning ) { + return false; + } + + // Update Running + checkerRunning = true; + + // Fetch + var + documentHash = History.getHash(), + iframeHash = History.getHash(iframe.contentWindow.document); + + // The Document Hash has changed (application caused) + if ( documentHash !== lastDocumentHash ) { + // Equalise + lastDocumentHash = documentHash; + + // Create a history entry in the iframe + if ( iframeHash !== documentHash ) { + //History.debug('hashchange.checker: iframe hash change', 'documentHash (new):', documentHash, 'iframeHash (old):', iframeHash); + + // Equalise + lastIframeHash = iframeHash = documentHash; + + // Create History Entry + iframe.contentWindow.document.open(); + iframe.contentWindow.document.close(); + + // Update the iframe's hash + iframe.contentWindow.document.location.hash = History.escapeHash(documentHash); + } + + // Trigger Hashchange Event + History.Adapter.trigger(window,'hashchange'); + } + + // The iFrame Hash has changed (back button caused) + else if ( iframeHash !== lastIframeHash ) { + //History.debug('hashchange.checker: iframe hash out of sync', 'iframeHash (new):', iframeHash, 'documentHash (old):', documentHash); + + // Equalise + lastIframeHash = iframeHash; + + // If there is no iframe hash that means we're at the original + // iframe state. + // And if there was a hash on the original request, the original + // iframe state was replaced instantly, so skip this state and take + // the user back to where they came from. + if (startedWithHash && iframeHash === '') { + History.back(); + } + else { + // Update the Hash + History.setHash(iframeHash,false); + } + } + + // Reset Running + checkerRunning = false; + + // Return true + return true; + }; + } + else { + // We are not IE + // Firefox 1 or 2, Opera + + // Define the checker function + History.checkerFunction = function(){ + // Prepare + var documentHash = History.getHash()||''; + + // The Document Hash has changed (application caused) + if ( documentHash !== lastDocumentHash ) { + // Equalise + lastDocumentHash = documentHash; + + // Trigger Hashchange Event + History.Adapter.trigger(window,'hashchange'); + } + + // Return true + return true; + }; + } + + // Apply the checker function + History.intervalList.push(setInterval(History.checkerFunction, History.options.hashChangeInterval)); + + // Done + return true; + }; // History.hashChangeInit + + // Bind hashChangeInit + History.Adapter.onDomLoad(History.hashChangeInit); + + } // History.emulated.hashChange + + + // ==================================================================== + // HTML5 State Support + + // Non-Native pushState Implementation + if ( History.emulated.pushState ) { + /* + * We must emulate the HTML5 State Management by using HTML4 HashChange + */ + + /** + * History.onHashChange(event) + * Trigger HTML5's window.onpopstate via HTML4 HashChange Support + */ + History.onHashChange = function(event){ + //History.debug('History.onHashChange', arguments); + + // Prepare + var currentUrl = ((event && event.newURL) || History.getLocationHref()), + currentHash = History.getHashByUrl(currentUrl), + currentState = null, + currentStateHash = null, + currentStateHashExits = null, + discardObject; + + // Check if we are the same state + if ( History.isLastHash(currentHash) ) { + // There has been no change (just the page's hash has finally propagated) + //History.debug('History.onHashChange: no change'); + History.busy(false); + return false; + } + + // Reset the double check + History.doubleCheckComplete(); + + // Store our location for use in detecting back/forward direction + History.saveHash(currentHash); + + // Expand Hash + if ( currentHash && History.isTraditionalAnchor(currentHash) ) { + //History.debug('History.onHashChange: traditional anchor', currentHash); + // Traditional Anchor Hash + History.Adapter.trigger(window,'anchorchange'); + History.busy(false); + return false; + } + + // Create State + currentState = History.extractState(History.getFullUrl(currentHash||History.getLocationHref()),true); + + // Check if we are the same state + if ( History.isLastSavedState(currentState) ) { + //History.debug('History.onHashChange: no change'); + // There has been no change (just the page's hash has finally propagated) + History.busy(false); + return false; + } + + // Create the state Hash + currentStateHash = History.getHashByState(currentState); + + // Check if we are DiscardedState + discardObject = History.discardedState(currentState); + if ( discardObject ) { + // Ignore this state as it has been discarded and go back to the state before it + if ( History.getHashByIndex(-2) === History.getHashByState(discardObject.forwardState) ) { + // We are going backwards + //History.debug('History.onHashChange: go backwards'); + History.back(false); + } else { + // We are going forwards + //History.debug('History.onHashChange: go forwards'); + History.forward(false); + } + return false; + } + + // Push the new HTML5 State + //History.debug('History.onHashChange: success hashchange'); + History.pushState(currentState.data,currentState.title,encodeURI(currentState.url),false); + + // End onHashChange closure + return true; + }; + History.Adapter.bind(window,'hashchange',History.onHashChange); + + /** + * History.pushState(data,title,url) + * Add a new State to the history object, become it, and trigger onpopstate + * We have to trigger for HTML4 compatibility + * @param {object} data + * @param {string} title + * @param {string} url + * @return {true} + */ + History.pushState = function(data,title,url,queue){ + //History.debug('History.pushState: called', arguments); + + // We assume that the URL passed in is URI-encoded, but this makes + // sure that it's fully URI encoded; any '%'s that are encoded are + // converted back into '%'s + url = encodeURI(url).replace(/%25/g, "%"); + + // Check the State + if ( History.getHashByUrl(url) ) { + throw new Error('History.js does not support states with fragment-identifiers (hashes/anchors).'); + } + + // Handle Queueing + if ( queue !== false && History.busy() ) { + // Wait + Push to Queue + //History.debug('History.pushState: we must wait', arguments); + History.pushQueue({ + scope: History, + callback: History.pushState, + args: arguments, + queue: queue + }); + return false; + } + + // Make Busy + History.busy(true); + + // Fetch the State Object + var newState = History.createStateObject(data,title,url), + newStateHash = History.getHashByState(newState), + oldState = History.getState(false), + oldStateHash = History.getHashByState(oldState), + html4Hash = History.getHash(), + wasExpected = History.expectedStateId == newState.id; + + // Store the newState + History.storeState(newState); + History.expectedStateId = newState.id; + + // Recycle the State + History.recycleState(newState); + + // Force update of the title + History.setTitle(newState); + + // Check if we are the same State + if ( newStateHash === oldStateHash ) { + //History.debug('History.pushState: no change', newStateHash); + History.busy(false); + return false; + } + + // Update HTML5 State + History.saveState(newState); + + // Fire HTML5 Event + if(!wasExpected) + History.Adapter.trigger(window,'statechange'); + + // Update HTML4 Hash + if ( !History.isHashEqual(newStateHash, html4Hash) && !History.isHashEqual(newStateHash, History.getShortUrl(History.getLocationHref())) ) { + History.setHash(newStateHash,false); + } + + History.busy(false); + + // End pushState closure + return true; + }; + + /** + * History.replaceState(data,title,url) + * Replace the State and trigger onpopstate + * We have to trigger for HTML4 compatibility + * @param {object} data + * @param {string} title + * @param {string} url + * @return {true} + */ + History.replaceState = function(data,title,url,queue){ + //History.debug('History.replaceState: called', arguments); + + // We assume that the URL passed in is URI-encoded, but this makes + // sure that it's fully URI encoded; any '%'s that are encoded are + // converted back into '%'s + url = encodeURI(url).replace(/%25/g, "%"); + + // Check the State + if ( History.getHashByUrl(url) ) { + throw new Error('History.js does not support states with fragment-identifiers (hashes/anchors).'); + } + + // Handle Queueing + if ( queue !== false && History.busy() ) { + // Wait + Push to Queue + //History.debug('History.replaceState: we must wait', arguments); + History.pushQueue({ + scope: History, + callback: History.replaceState, + args: arguments, + queue: queue + }); + return false; + } + + // Make Busy + History.busy(true); + + // Fetch the State Objects + var newState = History.createStateObject(data,title,url), + newStateHash = History.getHashByState(newState), + oldState = History.getState(false), + oldStateHash = History.getHashByState(oldState), + previousState = History.getStateByIndex(-2); + + // Discard Old State + History.discardState(oldState,newState,previousState); + + // If the url hasn't changed, just store and save the state + // and fire a statechange event to be consistent with the + // html 5 api + if ( newStateHash === oldStateHash ) { + // Store the newState + History.storeState(newState); + History.expectedStateId = newState.id; + + // Recycle the State + History.recycleState(newState); + + // Force update of the title + History.setTitle(newState); + + // Update HTML5 State + History.saveState(newState); + + // Fire HTML5 Event + //History.debug('History.pushState: trigger popstate'); + History.Adapter.trigger(window,'statechange'); + History.busy(false); + } + else { + // Alias to PushState + History.pushState(newState.data,newState.title,newState.url,false); + } + + // End replaceState closure + return true; + }; + + } // History.emulated.pushState + + + + // ==================================================================== + // Initialise + + // Non-Native pushState Implementation + if ( History.emulated.pushState ) { + /** + * Ensure initial state is handled correctly + */ + if ( History.getHash() && !History.emulated.hashChange ) { + History.Adapter.onDomLoad(function(){ + History.Adapter.trigger(window,'hashchange'); + }); + } + + } // History.emulated.pushState + + }; // History.initHtml4 + + // Try to Initialise History + if ( typeof History.init !== 'undefined' ) { + History.init(); + } + +})(window); +/** + * History.js Core + * @author Benjamin Arthur Lupton + * @copyright 2010-2011 Benjamin Arthur Lupton + * @license New BSD License + */ + +(function(window,undefined){ + "use strict"; + + // ======================================================================== + // Initialise + + // Localise Globals + var + console = window.console||undefined, // Prevent a JSLint complain + document = window.document, // Make sure we are using the correct document + navigator = window.navigator, // Make sure we are using the correct navigator + sessionStorage = window.sessionStorage||false, // sessionStorage + setTimeout = window.setTimeout, + clearTimeout = window.clearTimeout, + setInterval = window.setInterval, + clearInterval = window.clearInterval, + JSON = window.JSON, + alert = window.alert, + History = window.History = window.History||{}, // Public History Object + history = window.history; // Old History Object + + try { + sessionStorage.setItem('TEST', '1'); + sessionStorage.removeItem('TEST'); + } catch(e) { + sessionStorage = false; + } + + // MooTools Compatibility + JSON.stringify = JSON.stringify||JSON.encode; + JSON.parse = JSON.parse||JSON.decode; + + // Check Existence + if ( typeof History.init !== 'undefined' ) { + throw new Error('History.js Core has already been loaded...'); + } + + // Initialise History + History.init = function(options){ + // Check Load Status of Adapter + if ( typeof History.Adapter === 'undefined' ) { + return false; + } + + // Check Load Status of Core + if ( typeof History.initCore !== 'undefined' ) { + History.initCore(); + } + + // Check Load Status of HTML4 Support + if ( typeof History.initHtml4 !== 'undefined' ) { + History.initHtml4(); + } + + // Return true + return true; + }; + + + // ======================================================================== + // Initialise Core + + // Initialise Core + History.initCore = function(options){ + // Initialise + if ( typeof History.initCore.initialized !== 'undefined' ) { + // Already Loaded + return false; + } + else { + History.initCore.initialized = true; + } + + + // ==================================================================== + // Options + + /** + * History.options + * Configurable options + */ + History.options = History.options||{}; + + /** + * History.options.hashChangeInterval + * How long should the interval be before hashchange checks + */ + History.options.hashChangeInterval = History.options.hashChangeInterval || 100; + + /** + * History.options.safariPollInterval + * How long should the interval be before safari poll checks + */ + History.options.safariPollInterval = History.options.safariPollInterval || 500; + + /** + * History.options.doubleCheckInterval + * How long should the interval be before we perform a double check + */ + History.options.doubleCheckInterval = History.options.doubleCheckInterval || 500; + + /** + * History.options.disableSuid + * Force History not to append suid + */ + History.options.disableSuid = History.options.disableSuid || false; + + /** + * History.options.storeInterval + * How long should we wait between store calls + */ + History.options.storeInterval = History.options.storeInterval || 1000; + + /** + * History.options.busyDelay + * How long should we wait between busy events + */ + History.options.busyDelay = History.options.busyDelay || 250; + + /** + * History.options.debug + * If true will enable debug messages to be logged + */ + History.options.debug = History.options.debug || false; + + /** + * History.options.initialTitle + * What is the title of the initial state + */ + History.options.initialTitle = History.options.initialTitle || document.title; + + /** + * History.options.html4Mode + * If true, will force HTMl4 mode (hashtags) + */ + History.options.html4Mode = History.options.html4Mode || false; + + /** + * History.options.delayInit + * Want to override default options and call init manually. + */ + History.options.delayInit = History.options.delayInit || false; + + + // ==================================================================== + // Interval record + + /** + * History.intervalList + * List of intervals set, to be cleared when document is unloaded. + */ + History.intervalList = []; + + /** + * History.clearAllIntervals + * Clears all setInterval instances. + */ + History.clearAllIntervals = function(){ + var i, il = History.intervalList; + if (typeof il !== "undefined" && il !== null) { + for (i = 0; i < il.length; i++) { + clearInterval(il[i]); + } + History.intervalList = null; + } + }; + + + // ==================================================================== + // Debug + + /** + * History.debug(message,...) + * Logs the passed arguments if debug enabled + */ + History.debug = function(){ + if ( (History.options.debug||false) ) { + History.log.apply(History,arguments); + } + }; + + /** + * History.log(message,...) + * Logs the passed arguments + */ + History.log = function(){ + // Prepare + var + consoleExists = !(typeof console === 'undefined' || typeof console.log === 'undefined' || typeof console.log.apply === 'undefined'), + textarea = document.getElementById('log'), + message, + i,n, + args,arg + ; + + // Write to Console + if ( consoleExists ) { + args = Array.prototype.slice.call(arguments); + message = args.shift(); + if ( typeof console.debug !== 'undefined' ) { + console.debug.apply(console,[message,args]); + } + else { + console.log.apply(console,[message,args]); + } + } + else { + message = ("\n"+arguments[0]+"\n"); + } + + // Write to log + for ( i=1,n=arguments.length; i + * @author James Padolsey + */ + History.getInternetExplorerMajorVersion = function(){ + var result = History.getInternetExplorerMajorVersion.cached = + (typeof History.getInternetExplorerMajorVersion.cached !== 'undefined') + ? History.getInternetExplorerMajorVersion.cached + : (function(){ + var v = 3, + div = document.createElement('div'), + all = div.getElementsByTagName('i'); + while ( (div.innerHTML = '') && all[0] ) {} + return (v > 4) ? v : false; + })() + ; + return result; + }; + + /** + * History.isInternetExplorer() + * Are we using Internet Explorer? + * @return {boolean} + * @license Public Domain + * @author Benjamin Arthur Lupton + */ + History.isInternetExplorer = function(){ + var result = + History.isInternetExplorer.cached = + (typeof History.isInternetExplorer.cached !== 'undefined') + ? History.isInternetExplorer.cached + : Boolean(History.getInternetExplorerMajorVersion()) + ; + return result; + }; + + /** + * History.emulated + * Which features require emulating? + */ + + if (History.options.html4Mode) { + History.emulated = { + pushState : true, + hashChange: true + }; + } + + else { + + History.emulated = { + pushState: !Boolean( + window.history && window.history.pushState && window.history.replaceState + && !( + (/ Mobile\/([1-7][a-z]|(8([abcde]|f(1[0-8]))))/i).test(navigator.userAgent) /* disable for versions of iOS before version 4.3 (8F190) */ + || (/AppleWebKit\/5([0-2]|3[0-2])/i).test(navigator.userAgent) /* disable for the mercury iOS browser, or at least older versions of the webkit engine */ + ) + ), + hashChange: Boolean( + !(('onhashchange' in window) || ('onhashchange' in document)) + || + (History.isInternetExplorer() && History.getInternetExplorerMajorVersion() < 8) + ) + }; + } + + /** + * History.enabled + * Is History enabled? + */ + History.enabled = !History.emulated.pushState; + + /** + * History.bugs + * Which bugs are present + */ + History.bugs = { + /** + * Safari 5 and Safari iOS 4 fail to return to the correct state once a hash is replaced by a `replaceState` call + * https://bugs.webkit.org/show_bug.cgi?id=56249 + */ + setHash: Boolean(!History.emulated.pushState && navigator.vendor === 'Apple Computer, Inc.' && /AppleWebKit\/5([0-2]|3[0-3])/.test(navigator.userAgent)), + + /** + * Safari 5 and Safari iOS 4 sometimes fail to apply the state change under busy conditions + * https://bugs.webkit.org/show_bug.cgi?id=42940 + */ + safariPoll: Boolean(!History.emulated.pushState && navigator.vendor === 'Apple Computer, Inc.' && /AppleWebKit\/5([0-2]|3[0-3])/.test(navigator.userAgent)), + + /** + * MSIE 6 and 7 sometimes do not apply a hash even it was told to (requiring a second call to the apply function) + */ + ieDoubleCheck: Boolean(History.isInternetExplorer() && History.getInternetExplorerMajorVersion() < 8), + + /** + * MSIE 6 requires the entire hash to be encoded for the hashes to trigger the onHashChange event + */ + hashEscape: Boolean(History.isInternetExplorer() && History.getInternetExplorerMajorVersion() < 7) + }; + + /** + * History.isEmptyObject(obj) + * Checks to see if the Object is Empty + * @param {Object} obj + * @return {boolean} + */ + History.isEmptyObject = function(obj) { + for ( var name in obj ) { + if ( obj.hasOwnProperty(name) ) { + return false; + } + } + return true; + }; + + /** + * History.cloneObject(obj) + * Clones a object and eliminate all references to the original contexts + * @param {Object} obj + * @return {Object} + */ + History.cloneObject = function(obj) { + var hash,newObj; + if ( obj ) { + hash = JSON.stringify(obj); + newObj = JSON.parse(hash); + } + else { + newObj = {}; + } + return newObj; + }; + + + // ==================================================================== + // URL Helpers + + /** + * History.getRootUrl() + * Turns "http://mysite.com/dir/page.html?asd" into "http://mysite.com" + * @return {String} rootUrl + */ + History.getRootUrl = function(){ + // Create + var rootUrl = document.location.protocol+'//'+(document.location.hostname||document.location.host); + if ( document.location.port||false ) { + rootUrl += ':'+document.location.port; + } + rootUrl += '/'; + + // Return + return rootUrl; + }; + + /** + * History.getBaseHref() + * Fetches the `href` attribute of the `` element if it exists + * @return {String} baseHref + */ + History.getBaseHref = function(){ + // Create + var + baseElements = document.getElementsByTagName('base'), + baseElement = null, + baseHref = ''; + + // Test for Base Element + if ( baseElements.length === 1 ) { + // Prepare for Base Element + baseElement = baseElements[0]; + baseHref = baseElement.href.replace(/[^\/]+$/,''); + } + + // Adjust trailing slash + baseHref = baseHref.replace(/\/+$/,''); + if ( baseHref ) baseHref += '/'; + + // Return + return baseHref; + }; + + /** + * History.getBaseUrl() + * Fetches the baseHref or basePageUrl or rootUrl (whichever one exists first) + * @return {String} baseUrl + */ + History.getBaseUrl = function(){ + // Create + var baseUrl = History.getBaseHref()||History.getBasePageUrl()||History.getRootUrl(); + + // Return + return baseUrl; + }; + + /** + * History.getPageUrl() + * Fetches the URL of the current page + * @return {String} pageUrl + */ + History.getPageUrl = function(){ + // Fetch + var + State = History.getState(false,false), + stateUrl = (State||{}).url||History.getLocationHref(), + pageUrl; + + // Create + pageUrl = stateUrl.replace(/\/+$/,'').replace(/[^\/]+$/,function(part,index,string){ + return (/\./).test(part) ? part : part+'/'; + }); + + // Return + return pageUrl; + }; + + /** + * History.getBasePageUrl() + * Fetches the Url of the directory of the current page + * @return {String} basePageUrl + */ + History.getBasePageUrl = function(){ + // Create + var basePageUrl = (History.getLocationHref()).replace(/[#\?].*/,'').replace(/[^\/]+$/,function(part,index,string){ + return (/[^\/]$/).test(part) ? '' : part; + }).replace(/\/+$/,'')+'/'; + + // Return + return basePageUrl; + }; + + /** + * History.getFullUrl(url) + * Ensures that we have an absolute URL and not a relative URL + * @param {string} url + * @param {Boolean} allowBaseHref + * @return {string} fullUrl + */ + History.getFullUrl = function(url,allowBaseHref){ + // Prepare + var fullUrl = url, firstChar = url.substring(0,1); + allowBaseHref = (typeof allowBaseHref === 'undefined') ? true : allowBaseHref; + + // Check + if ( /[a-z]+\:\/\//.test(url) ) { + // Full URL + } + else if ( firstChar === '/' ) { + // Root URL + fullUrl = History.getRootUrl()+url.replace(/^\/+/,''); + } + else if ( firstChar === '#' ) { + // Anchor URL + fullUrl = History.getPageUrl().replace(/#.*/,'')+url; + } + else if ( firstChar === '?' ) { + // Query URL + fullUrl = History.getPageUrl().replace(/[\?#].*/,'')+url; + } + else { + // Relative URL + if ( allowBaseHref ) { + fullUrl = History.getBaseUrl()+url.replace(/^(\.\/)+/,''); + } else { + fullUrl = History.getBasePageUrl()+url.replace(/^(\.\/)+/,''); + } + // We have an if condition above as we do not want hashes + // which are relative to the baseHref in our URLs + // as if the baseHref changes, then all our bookmarks + // would now point to different locations + // whereas the basePageUrl will always stay the same + } + + // Return + return fullUrl.replace(/\#$/,''); + }; + + /** + * History.getShortUrl(url) + * Ensures that we have a relative URL and not a absolute URL + * @param {string} url + * @return {string} url + */ + History.getShortUrl = function(url){ + // Prepare + var shortUrl = url, baseUrl = History.getBaseUrl(), rootUrl = History.getRootUrl(); + + // Trim baseUrl + if ( History.emulated.pushState ) { + // We are in a if statement as when pushState is not emulated + // The actual url these short urls are relative to can change + // So within the same session, we the url may end up somewhere different + shortUrl = shortUrl.replace(baseUrl,''); + } + + // Trim rootUrl + shortUrl = shortUrl.replace(rootUrl,'/'); + + // Ensure we can still detect it as a state + if ( History.isTraditionalAnchor(shortUrl) ) { + shortUrl = './'+shortUrl; + } + + // Clean It + shortUrl = shortUrl.replace(/^(\.\/)+/g,'./').replace(/\#$/,''); + + // Return + return shortUrl; + }; + + /** + * History.getLocationHref(document) + * Returns a normalized version of document.location.href + * accounting for browser inconsistencies, etc. + * + * This URL will be URI-encoded and will include the hash + * + * @param {object} document + * @return {string} url + */ + History.getLocationHref = function(doc) { + doc = doc || document; + + // most of the time, this will be true + if (doc.URL === doc.location.href) + return doc.location.href; + + // some versions of webkit URI-decode document.location.href + // but they leave document.URL in an encoded state + if (doc.location.href === decodeURIComponent(doc.URL)) + return doc.URL; + + // FF 3.6 only updates document.URL when a page is reloaded + // document.location.href is updated correctly + if (doc.location.hash && decodeURIComponent(doc.location.href.replace(/^[^#]+/, "")) === doc.location.hash) + return doc.location.href; + + if (doc.URL.indexOf('#') == -1 && doc.location.href.indexOf('#') != -1) + return doc.location.href; + + return doc.URL || doc.location.href; + }; + + + // ==================================================================== + // State Storage + + /** + * History.store + * The store for all session specific data + */ + History.store = {}; + + /** + * History.idToState + * 1-1: State ID to State Object + */ + History.idToState = History.idToState||{}; + + /** + * History.stateToId + * 1-1: State String to State ID + */ + History.stateToId = History.stateToId||{}; + + /** + * History.urlToId + * 1-1: State URL to State ID + */ + History.urlToId = History.urlToId||{}; + + /** + * History.storedStates + * Store the states in an array + */ + History.storedStates = History.storedStates||[]; + + /** + * History.savedStates + * Saved the states in an array + */ + History.savedStates = History.savedStates||[]; + + /** + * History.noramlizeStore() + * Noramlize the store by adding necessary values + */ + History.normalizeStore = function(){ + History.store.idToState = History.store.idToState||{}; + History.store.urlToId = History.store.urlToId||{}; + History.store.stateToId = History.store.stateToId||{}; + }; + + /** + * History.getState() + * Get an object containing the data, title and url of the current state + * @param {Boolean} friendly + * @param {Boolean} create + * @return {Object} State + */ + History.getState = function(friendly,create){ + // Prepare + if ( typeof friendly === 'undefined' ) { friendly = true; } + if ( typeof create === 'undefined' ) { create = true; } + + // Fetch + var State = History.getLastSavedState(); + + // Create + if ( !State && create ) { + State = History.createStateObject(); + } + + // Adjust + if ( friendly ) { + State = History.cloneObject(State); + State.url = State.cleanUrl||State.url; + } + + // Return + return State; + }; + + /** + * History.getIdByState(State) + * Gets a ID for a State + * @param {State} newState + * @return {String} id + */ + History.getIdByState = function(newState){ + + // Fetch ID + var id = History.extractId(newState.url), + str; + + if ( !id ) { + // Find ID via State String + str = History.getStateString(newState); + if ( typeof History.stateToId[str] !== 'undefined' ) { + id = History.stateToId[str]; + } + else if ( typeof History.store.stateToId[str] !== 'undefined' ) { + id = History.store.stateToId[str]; + } + else { + // Generate a new ID + while ( true ) { + id = (new Date()).getTime() + String(Math.random()).replace(/\D/g,''); + if ( typeof History.idToState[id] === 'undefined' && typeof History.store.idToState[id] === 'undefined' ) { + break; + } + } + + // Apply the new State to the ID + History.stateToId[str] = id; + History.idToState[id] = newState; + } + } + + // Return ID + return id; + }; + + /** + * History.normalizeState(State) + * Expands a State Object + * @param {object} State + * @return {object} + */ + History.normalizeState = function(oldState){ + // Variables + var newState, dataNotEmpty; + + // Prepare + if ( !oldState || (typeof oldState !== 'object') ) { + oldState = {}; + } + + // Check + if ( typeof oldState.normalized !== 'undefined' ) { + return oldState; + } + + // Adjust + if ( !oldState.data || (typeof oldState.data !== 'object') ) { + oldState.data = {}; + } + + // ---------------------------------------------------------------- + + // Create + newState = {}; + newState.normalized = true; + newState.title = oldState.title||''; + newState.url = History.getFullUrl(oldState.url?oldState.url:(History.getLocationHref())); + newState.hash = History.getShortUrl(newState.url); + newState.data = History.cloneObject(oldState.data); + + // Fetch ID + newState.id = History.getIdByState(newState); + + // ---------------------------------------------------------------- + + // Clean the URL + newState.cleanUrl = newState.url.replace(/\??\&_suid.*/,''); + newState.url = newState.cleanUrl; + + // Check to see if we have more than just a url + dataNotEmpty = !History.isEmptyObject(newState.data); + + // Apply + if ( (newState.title || dataNotEmpty) && History.options.disableSuid !== true ) { + // Add ID to Hash + newState.hash = History.getShortUrl(newState.url).replace(/\??\&_suid.*/,''); + if ( !/\?/.test(newState.hash) ) { + newState.hash += '?'; + } + newState.hash += '&_suid='+newState.id; + } + + // Create the Hashed URL + newState.hashedUrl = History.getFullUrl(newState.hash); + + // ---------------------------------------------------------------- + + // Update the URL if we have a duplicate + if ( (History.emulated.pushState || History.bugs.safariPoll) && History.hasUrlDuplicate(newState) ) { + newState.url = newState.hashedUrl; + } + + // ---------------------------------------------------------------- + + // Return + return newState; + }; + + /** + * History.createStateObject(data,title,url) + * Creates a object based on the data, title and url state params + * @param {object} data + * @param {string} title + * @param {string} url + * @return {object} + */ + History.createStateObject = function(data,title,url){ + // Hashify + var State = { + 'data': data, + 'title': title, + 'url': url + }; + + // Expand the State + State = History.normalizeState(State); + + // Return object + return State; + }; + + /** + * History.getStateById(id) + * Get a state by it's UID + * @param {String} id + */ + History.getStateById = function(id){ + // Prepare + id = String(id); + + // Retrieve + var State = History.idToState[id] || History.store.idToState[id] || undefined; + + // Return State + return State; + }; + + /** + * Get a State's String + * @param {State} passedState + */ + History.getStateString = function(passedState){ + // Prepare + var State, cleanedState, str; + + // Fetch + State = History.normalizeState(passedState); + + // Clean + cleanedState = { + data: State.data, + title: passedState.title, + url: passedState.url + }; + + // Fetch + str = JSON.stringify(cleanedState); + + // Return + return str; + }; + + /** + * Get a State's ID + * @param {State} passedState + * @return {String} id + */ + History.getStateId = function(passedState){ + // Prepare + var State, id; + + // Fetch + State = History.normalizeState(passedState); + + // Fetch + id = State.id; + + // Return + return id; + }; + + /** + * History.getHashByState(State) + * Creates a Hash for the State Object + * @param {State} passedState + * @return {String} hash + */ + History.getHashByState = function(passedState){ + // Prepare + var State, hash; + + // Fetch + State = History.normalizeState(passedState); + + // Hash + hash = State.hash; + + // Return + return hash; + }; + + /** + * History.extractId(url_or_hash) + * Get a State ID by it's URL or Hash + * @param {string} url_or_hash + * @return {string} id + */ + History.extractId = function ( url_or_hash ) { + // Prepare + var id,parts,url, tmp; + + // Extract + + // If the URL has a #, use the id from before the # + if (url_or_hash.indexOf('#') != -1) + { + tmp = url_or_hash.split("#")[0]; + } + else + { + tmp = url_or_hash; + } + + parts = /(.*)\&_suid=([0-9]+)$/.exec(tmp); + url = parts ? (parts[1]||url_or_hash) : url_or_hash; + id = parts ? String(parts[2]||'') : ''; + + // Return + return id||false; + }; + + /** + * History.isTraditionalAnchor + * Checks to see if the url is a traditional anchor or not + * @param {String} url_or_hash + * @return {Boolean} + */ + History.isTraditionalAnchor = function(url_or_hash){ + // Check + var isTraditional = !(/[\/\?\.]/.test(url_or_hash)); + + // Return + return isTraditional; + }; + + /** + * History.extractState + * Get a State by it's URL or Hash + * @param {String} url_or_hash + * @return {State|null} + */ + History.extractState = function(url_or_hash,create){ + // Prepare + var State = null, id, url; + create = create||false; + + // Fetch SUID + id = History.extractId(url_or_hash); + if ( id ) { + State = History.getStateById(id); + } + + // Fetch SUID returned no State + if ( !State ) { + // Fetch URL + url = History.getFullUrl(url_or_hash); + + // Check URL + id = History.getIdByUrl(url)||false; + if ( id ) { + State = History.getStateById(id); + } + + // Create State + if ( !State && create && !History.isTraditionalAnchor(url_or_hash) ) { + State = History.createStateObject(null,null,url); + } + } + + // Return + return State; + }; + + /** + * History.getIdByUrl() + * Get a State ID by a State URL + */ + History.getIdByUrl = function(url){ + // Fetch + var id = History.urlToId[url] || History.store.urlToId[url] || undefined; + + // Return + return id; + }; + + /** + * History.getLastSavedState() + * Get an object containing the data, title and url of the current state + * @return {Object} State + */ + History.getLastSavedState = function(){ + return History.savedStates[History.savedStates.length-1]||undefined; + }; + + /** + * History.getLastStoredState() + * Get an object containing the data, title and url of the current state + * @return {Object} State + */ + History.getLastStoredState = function(){ + return History.storedStates[History.storedStates.length-1]||undefined; + }; + + /** + * History.hasUrlDuplicate + * Checks if a Url will have a url conflict + * @param {Object} newState + * @return {Boolean} hasDuplicate + */ + History.hasUrlDuplicate = function(newState) { + // Prepare + var hasDuplicate = false, + oldState; + + // Fetch + oldState = History.extractState(newState.url); + + // Check + hasDuplicate = oldState && oldState.id !== newState.id; + + // Return + return hasDuplicate; + }; + + /** + * History.storeState + * Store a State + * @param {Object} newState + * @return {Object} newState + */ + History.storeState = function(newState){ + // Store the State + History.urlToId[newState.url] = newState.id; + + // Push the State + History.storedStates.push(History.cloneObject(newState)); + + // Return newState + return newState; + }; + + /** + * History.isLastSavedState(newState) + * Tests to see if the state is the last state + * @param {Object} newState + * @return {boolean} isLast + */ + History.isLastSavedState = function(newState){ + // Prepare + var isLast = false, + newId, oldState, oldId; + + // Check + if ( History.savedStates.length ) { + newId = newState.id; + oldState = History.getLastSavedState(); + oldId = oldState.id; + + // Check + isLast = (newId === oldId); + } + + // Return + return isLast; + }; + + /** + * History.saveState + * Push a State + * @param {Object} newState + * @return {boolean} changed + */ + History.saveState = function(newState){ + // Check Hash + if ( History.isLastSavedState(newState) ) { + return false; + } + + // Push the State + History.savedStates.push(History.cloneObject(newState)); + + // Return true + return true; + }; + + /** + * History.getStateByIndex() + * Gets a state by the index + * @param {integer} index + * @return {Object} + */ + History.getStateByIndex = function(index){ + // Prepare + var State = null; + + // Handle + if ( typeof index === 'undefined' ) { + // Get the last inserted + State = History.savedStates[History.savedStates.length-1]; + } + else if ( index < 0 ) { + // Get from the end + State = History.savedStates[History.savedStates.length+index]; + } + else { + // Get from the beginning + State = History.savedStates[index]; + } + + // Return State + return State; + }; + + /** + * History.getCurrentIndex() + * Gets the current index + * @return (integer) + */ + History.getCurrentIndex = function(){ + // Prepare + var index = null; + + // No states saved + if(History.savedStates.length < 1) { + index = 0; + } + else { + index = History.savedStates.length-1; + } + return index; + }; + + // ==================================================================== + // Hash Helpers + + /** + * History.getHash() + * @param {Location=} location + * Gets the current document hash + * Note: unlike location.hash, this is guaranteed to return the escaped hash in all browsers + * @return {string} + */ + History.getHash = function(doc){ + var url = History.getLocationHref(doc), + hash; + hash = History.getHashByUrl(url); + return hash; + }; + + /** + * History.unescapeHash() + * normalize and Unescape a Hash + * @param {String} hash + * @return {string} + */ + History.unescapeHash = function(hash){ + // Prepare + var result = History.normalizeHash(hash); + + // Unescape hash + result = decodeURIComponent(result); + + // Return result + return result; + }; + + /** + * History.normalizeHash() + * normalize a hash across browsers + * @return {string} + */ + History.normalizeHash = function(hash){ + // Prepare + var result = hash.replace(/[^#]*#/,'').replace(/#.*/, ''); + + // Return result + return result; + }; + + /** + * History.setHash(hash) + * Sets the document hash + * @param {string} hash + * @return {History} + */ + History.setHash = function(hash,queue){ + // Prepare + var State, pageUrl; + + // Handle Queueing + if ( queue !== false && History.busy() ) { + // Wait + Push to Queue + //History.debug('History.setHash: we must wait', arguments); + History.pushQueue({ + scope: History, + callback: History.setHash, + args: arguments, + queue: queue + }); + return false; + } + + // Log + //History.debug('History.setHash: called',hash); + + // Make Busy + Continue + History.busy(true); + + // Check if hash is a state + State = History.extractState(hash,true); + if ( State && !History.emulated.pushState ) { + // Hash is a state so skip the setHash + //History.debug('History.setHash: Hash is a state so skipping the hash set with a direct pushState call',arguments); + + // PushState + History.pushState(State.data,State.title,State.url,false); + } + else if ( History.getHash() !== hash ) { + // Hash is a proper hash, so apply it + + // Handle browser bugs + if ( History.bugs.setHash ) { + // Fix Safari Bug https://bugs.webkit.org/show_bug.cgi?id=56249 + + // Fetch the base page + pageUrl = History.getPageUrl(); + + // Safari hash apply + History.pushState(null,null,pageUrl+'#'+hash,false); + } + else { + // Normal hash apply + document.location.hash = hash; + } + } + + // Chain + return History; + }; + + /** + * History.escape() + * normalize and Escape a Hash + * @return {string} + */ + History.escapeHash = function(hash){ + // Prepare + var result = History.normalizeHash(hash); + + // Escape hash + result = window.encodeURIComponent(result); + + // IE6 Escape Bug + if ( !History.bugs.hashEscape ) { + // Restore common parts + result = result + .replace(/\%21/g,'!') + .replace(/\%26/g,'&') + .replace(/\%3D/g,'=') + .replace(/\%3F/g,'?'); + } + + // Return result + return result; + }; + + /** + * History.getHashByUrl(url) + * Extracts the Hash from a URL + * @param {string} url + * @return {string} url + */ + History.getHashByUrl = function(url){ + // Extract the hash + var hash = String(url) + .replace(/([^#]*)#?([^#]*)#?(.*)/, '$2') + ; + + // Unescape hash + hash = History.unescapeHash(hash); + + // Return hash + return hash; + }; + + /** + * History.setTitle(title) + * Applies the title to the document + * @param {State} newState + * @return {Boolean} + */ + History.setTitle = function(newState){ + // Prepare + var title = newState.title, + firstState; + + // Initial + if ( !title ) { + firstState = History.getStateByIndex(0); + if ( firstState && firstState.url === newState.url ) { + title = firstState.title||History.options.initialTitle; + } + } + + // Apply + try { + document.getElementsByTagName('title')[0].innerHTML = title.replace('<','<').replace('>','>').replace(' & ',' & '); + } + catch ( Exception ) { } + document.title = title; + + // Chain + return History; + }; + + + // ==================================================================== + // Queueing + + /** + * History.queues + * The list of queues to use + * First In, First Out + */ + History.queues = []; + + /** + * History.busy(value) + * @param {boolean} value [optional] + * @return {boolean} busy + */ + History.busy = function(value){ + // Apply + if ( typeof value !== 'undefined' ) { + //History.debug('History.busy: changing ['+(History.busy.flag||false)+'] to ['+(value||false)+']', History.queues.length); + History.busy.flag = value; + } + // Default + else if ( typeof History.busy.flag === 'undefined' ) { + History.busy.flag = false; + } + + // Queue + if ( !History.busy.flag ) { + // Execute the next item in the queue + clearTimeout(History.busy.timeout); + var fireNext = function(){ + var i, queue, item; + if ( History.busy.flag ) return; + for ( i=History.queues.length-1; i >= 0; --i ) { + queue = History.queues[i]; + if ( queue.length === 0 ) continue; + item = queue.shift(); + History.fireQueueItem(item); + History.busy.timeout = setTimeout(fireNext,History.options.busyDelay); + } + }; + History.busy.timeout = setTimeout(fireNext,History.options.busyDelay); + } + + // Return + return History.busy.flag; + }; + + /** + * History.busy.flag + */ + History.busy.flag = false; + + /** + * History.fireQueueItem(item) + * Fire a Queue Item + * @param {Object} item + * @return {Mixed} result + */ + History.fireQueueItem = function(item){ + return item.callback.apply(item.scope||History,item.args||[]); + }; + + /** + * History.pushQueue(callback,args) + * Add an item to the queue + * @param {Object} item [scope,callback,args,queue] + */ + History.pushQueue = function(item){ + // Prepare the queue + History.queues[item.queue||0] = History.queues[item.queue||0]||[]; + + // Add to the queue + History.queues[item.queue||0].push(item); + + // Chain + return History; + }; + + /** + * History.queue (item,queue), (func,queue), (func), (item) + * Either firs the item now if not busy, or adds it to the queue + */ + History.queue = function(item,queue){ + // Prepare + if ( typeof item === 'function' ) { + item = { + callback: item + }; + } + if ( typeof queue !== 'undefined' ) { + item.queue = queue; + } + + // Handle + if ( History.busy() ) { + History.pushQueue(item); + } else { + History.fireQueueItem(item); + } + + // Chain + return History; + }; + + /** + * History.clearQueue() + * Clears the Queue + */ + History.clearQueue = function(){ + History.busy.flag = false; + History.queues = []; + return History; + }; + + + // ==================================================================== + // IE Bug Fix + + /** + * History.stateChanged + * States whether or not the state has changed since the last double check was initialised + */ + History.stateChanged = false; + + /** + * History.doubleChecker + * Contains the timeout used for the double checks + */ + History.doubleChecker = false; + + /** + * History.doubleCheckComplete() + * Complete a double check + * @return {History} + */ + History.doubleCheckComplete = function(){ + // Update + History.stateChanged = true; + + // Clear + History.doubleCheckClear(); + + // Chain + return History; + }; + + /** + * History.doubleCheckClear() + * Clear a double check + * @return {History} + */ + History.doubleCheckClear = function(){ + // Clear + if ( History.doubleChecker ) { + clearTimeout(History.doubleChecker); + History.doubleChecker = false; + } + + // Chain + return History; + }; + + /** + * History.doubleCheck() + * Create a double check + * @return {History} + */ + History.doubleCheck = function(tryAgain){ + // Reset + History.stateChanged = false; + History.doubleCheckClear(); + + // Fix IE6,IE7 bug where calling history.back or history.forward does not actually change the hash (whereas doing it manually does) + // Fix Safari 5 bug where sometimes the state does not change: https://bugs.webkit.org/show_bug.cgi?id=42940 + if ( History.bugs.ieDoubleCheck ) { + // Apply Check + History.doubleChecker = setTimeout( + function(){ + History.doubleCheckClear(); + if ( !History.stateChanged ) { + //History.debug('History.doubleCheck: State has not yet changed, trying again', arguments); + // Re-Attempt + tryAgain(); + } + return true; + }, + History.options.doubleCheckInterval + ); + } + + // Chain + return History; + }; + + + // ==================================================================== + // Safari Bug Fix + + /** + * History.safariStatePoll() + * Poll the current state + * @return {History} + */ + History.safariStatePoll = function(){ + // Poll the URL + + // Get the Last State which has the new URL + var + urlState = History.extractState(History.getLocationHref()), + newState; + + // Check for a difference + if ( !History.isLastSavedState(urlState) ) { + newState = urlState; + } + else { + return; + } + + // Check if we have a state with that url + // If not create it + if ( !newState ) { + //History.debug('History.safariStatePoll: new'); + newState = History.createStateObject(); + } + + // Apply the New State + //History.debug('History.safariStatePoll: trigger'); + History.Adapter.trigger(window,'popstate'); + + // Chain + return History; + }; + + + // ==================================================================== + // State Aliases + + /** + * History.back(queue) + * Send the browser history back one item + * @param {Integer} queue [optional] + */ + History.back = function(queue){ + //History.debug('History.back: called', arguments); + + // Handle Queueing + if ( queue !== false && History.busy() ) { + // Wait + Push to Queue + //History.debug('History.back: we must wait', arguments); + History.pushQueue({ + scope: History, + callback: History.back, + args: arguments, + queue: queue + }); + return false; + } + + // Make Busy + Continue + History.busy(true); + + // Fix certain browser bugs that prevent the state from changing + History.doubleCheck(function(){ + History.back(false); + }); + + // Go back + history.go(-1); + + // End back closure + return true; + }; + + /** + * History.forward(queue) + * Send the browser history forward one item + * @param {Integer} queue [optional] + */ + History.forward = function(queue){ + //History.debug('History.forward: called', arguments); + + // Handle Queueing + if ( queue !== false && History.busy() ) { + // Wait + Push to Queue + //History.debug('History.forward: we must wait', arguments); + History.pushQueue({ + scope: History, + callback: History.forward, + args: arguments, + queue: queue + }); + return false; + } + + // Make Busy + Continue + History.busy(true); + + // Fix certain browser bugs that prevent the state from changing + History.doubleCheck(function(){ + History.forward(false); + }); + + // Go forward + history.go(1); + + // End forward closure + return true; + }; + + /** + * History.go(index,queue) + * Send the browser history back or forward index times + * @param {Integer} queue [optional] + */ + History.go = function(index,queue){ + //History.debug('History.go: called', arguments); + + // Prepare + var i; + + // Handle + if ( index > 0 ) { + // Forward + for ( i=1; i<=index; ++i ) { + History.forward(queue); + } + } + else if ( index < 0 ) { + // Backward + for ( i=-1; i>=index; --i ) { + History.back(queue); + } + } + else { + throw new Error('History.go: History.go requires a positive or negative integer passed.'); + } + + // Chain + return History; + }; + + + // ==================================================================== + // HTML5 State Support + + // Non-Native pushState Implementation + if ( History.emulated.pushState ) { + /* + * Provide Skeleton for HTML4 Browsers + */ + + // Prepare + var emptyFunction = function(){}; + History.pushState = History.pushState||emptyFunction; + History.replaceState = History.replaceState||emptyFunction; + } // History.emulated.pushState + + // Native pushState Implementation + else { + /* + * Use native HTML5 History API Implementation + */ + + /** + * History.onPopState(event,extra) + * Refresh the Current State + */ + History.onPopState = function(event,extra){ + // Prepare + var stateId = false, newState = false, currentHash, currentState; + + // Reset the double check + History.doubleCheckComplete(); + + // Check for a Hash, and handle apporiatly + currentHash = History.getHash(); + if ( currentHash ) { + // Expand Hash + currentState = History.extractState(currentHash||History.getLocationHref(),true); + if ( currentState ) { + // We were able to parse it, it must be a State! + // Let's forward to replaceState + //History.debug('History.onPopState: state anchor', currentHash, currentState); + History.replaceState(currentState.data, currentState.title, currentState.url, false); + } + else { + // Traditional Anchor + //History.debug('History.onPopState: traditional anchor', currentHash); + History.Adapter.trigger(window,'anchorchange'); + History.busy(false); + } + + // We don't care for hashes + History.expectedStateId = false; + return false; + } + + // Ensure + stateId = History.Adapter.extractEventData('state',event,extra) || false; + + // Fetch State + if ( stateId ) { + // Vanilla: Back/forward button was used + newState = History.getStateById(stateId); + } + else if ( History.expectedStateId ) { + // Vanilla: A new state was pushed, and popstate was called manually + newState = History.getStateById(History.expectedStateId); + } + else { + // Initial State + newState = History.extractState(History.getLocationHref()); + } + + // The State did not exist in our store + if ( !newState ) { + // Regenerate the State + newState = History.createStateObject(null,null,History.getLocationHref()); + } + + // Clean + History.expectedStateId = false; + + // Check if we are the same state + if ( History.isLastSavedState(newState) ) { + // There has been no change (just the page's hash has finally propagated) + //History.debug('History.onPopState: no change', newState, History.savedStates); + History.busy(false); + return false; + } + + // Store the State + History.storeState(newState); + History.saveState(newState); + + // Force update of the title + History.setTitle(newState); + + // Fire Our Event + History.Adapter.trigger(window,'statechange'); + History.busy(false); + + // Return true + return true; + }; + History.Adapter.bind(window,'popstate',History.onPopState); + + /** + * History.pushState(data,title,url) + * Add a new State to the history object, become it, and trigger onpopstate + * We have to trigger for HTML4 compatibility + * @param {object} data + * @param {string} title + * @param {string} url + * @return {true} + */ + History.pushState = function(data,title,url,queue){ + //History.debug('History.pushState: called', arguments); + + // Check the State + if ( History.getHashByUrl(url) && History.emulated.pushState ) { + throw new Error('History.js does not support states with fragement-identifiers (hashes/anchors).'); + } + + // Handle Queueing + if ( queue !== false && History.busy() ) { + // Wait + Push to Queue + //History.debug('History.pushState: we must wait', arguments); + History.pushQueue({ + scope: History, + callback: History.pushState, + args: arguments, + queue: queue + }); + return false; + } + + // Make Busy + Continue + History.busy(true); + + // Create the newState + var newState = History.createStateObject(data,title,url); + + // Check it + if ( History.isLastSavedState(newState) ) { + // Won't be a change + History.busy(false); + } + else { + // Store the newState + History.storeState(newState); + History.expectedStateId = newState.id; + + // Push the newState + history.pushState(newState.id,newState.title,newState.url); + + // Fire HTML5 Event + History.Adapter.trigger(window,'popstate'); + } + + // End pushState closure + return true; + }; + + /** + * History.replaceState(data,title,url) + * Replace the State and trigger onpopstate + * We have to trigger for HTML4 compatibility + * @param {object} data + * @param {string} title + * @param {string} url + * @return {true} + */ + History.replaceState = function(data,title,url,queue){ + //History.debug('History.replaceState: called', arguments); + + // Check the State + if ( History.getHashByUrl(url) && History.emulated.pushState ) { + throw new Error('History.js does not support states with fragement-identifiers (hashes/anchors).'); + } + + // Handle Queueing + if ( queue !== false && History.busy() ) { + // Wait + Push to Queue + //History.debug('History.replaceState: we must wait', arguments); + History.pushQueue({ + scope: History, + callback: History.replaceState, + args: arguments, + queue: queue + }); + return false; + } + + // Make Busy + Continue + History.busy(true); + + // Create the newState + var newState = History.createStateObject(data,title,url); + + // Check it + if ( History.isLastSavedState(newState) ) { + // Won't be a change + History.busy(false); + } + else { + // Store the newState + History.storeState(newState); + History.expectedStateId = newState.id; + + // Push the newState + history.replaceState(newState.id,newState.title,newState.url); + + // Fire HTML5 Event + History.Adapter.trigger(window,'popstate'); + } + + // End replaceState closure + return true; + }; + + } // !History.emulated.pushState + + + // ==================================================================== + // Initialise + + /** + * Load the Store + */ + if ( sessionStorage ) { + // Fetch + try { + History.store = JSON.parse(sessionStorage.getItem('History.store'))||{}; + } + catch ( err ) { + History.store = {}; + } + + // Normalize + History.normalizeStore(); + } + else { + // Default Load + History.store = {}; + History.normalizeStore(); + } + + /** + * Clear Intervals on exit to prevent memory leaks + */ + History.Adapter.bind(window,"unload",History.clearAllIntervals); + + /** + * Create the initial State + */ + History.saveState(History.storeState(History.extractState(History.getLocationHref(),true))); + + /** + * Bind for Saving Store + */ + if ( sessionStorage ) { + // When the page is closed + History.onUnload = function(){ + // Prepare + var currentStore, item, currentStoreString; + + // Fetch + try { + currentStore = JSON.parse(sessionStorage.getItem('History.store'))||{}; + } + catch ( err ) { + currentStore = {}; + } + + // Ensure + currentStore.idToState = currentStore.idToState || {}; + currentStore.urlToId = currentStore.urlToId || {}; + currentStore.stateToId = currentStore.stateToId || {}; + + // Sync + for ( item in History.idToState ) { + if ( !History.idToState.hasOwnProperty(item) ) { + continue; + } + currentStore.idToState[item] = History.idToState[item]; + } + for ( item in History.urlToId ) { + if ( !History.urlToId.hasOwnProperty(item) ) { + continue; + } + currentStore.urlToId[item] = History.urlToId[item]; + } + for ( item in History.stateToId ) { + if ( !History.stateToId.hasOwnProperty(item) ) { + continue; + } + currentStore.stateToId[item] = History.stateToId[item]; + } + + // Update + History.store = currentStore; + History.normalizeStore(); + + // In Safari, going into Private Browsing mode causes the + // Session Storage object to still exist but if you try and use + // or set any property/function of it it throws the exception + // "QUOTA_EXCEEDED_ERR: DOM Exception 22: An attempt was made to + // add something to storage that exceeded the quota." infinitely + // every second. + currentStoreString = JSON.stringify(currentStore); + try { + // Store + sessionStorage.setItem('History.store', currentStoreString); + } + catch (e) { + if (e.code === DOMException.QUOTA_EXCEEDED_ERR) { + if (sessionStorage.length) { + // Workaround for a bug seen on iPads. Sometimes the quota exceeded error comes up and simply + // removing/resetting the storage can work. + sessionStorage.removeItem('History.store'); + sessionStorage.setItem('History.store', currentStoreString); + } else { + // Otherwise, we're probably private browsing in Safari, so we'll ignore the exception. + } + } else { + throw e; + } + } + }; + + // For Internet Explorer + History.intervalList.push(setInterval(History.onUnload,History.options.storeInterval)); + + // For Other Browsers + History.Adapter.bind(window,'beforeunload',History.onUnload); + History.Adapter.bind(window,'unload',History.onUnload); + + // Both are enabled for consistency + } + + // Non-Native pushState Implementation + if ( !History.emulated.pushState ) { + // Be aware, the following is only for native pushState implementations + // If you are wanting to include something for all browsers + // Then include it above this if block + + /** + * Setup Safari Fix + */ + if ( History.bugs.safariPoll ) { + History.intervalList.push(setInterval(History.safariStatePoll, History.options.safariPollInterval)); + } + + /** + * Ensure Cross Browser Compatibility + */ + if ( navigator.vendor === 'Apple Computer, Inc.' || (navigator.appCodeName||'') === 'Mozilla' ) { + /** + * Fix Safari HashChange Issue + */ + + // Setup Alias + History.Adapter.bind(window,'hashchange',function(){ + History.Adapter.trigger(window,'popstate'); + }); + + // Initialise Alias + if ( History.getHash() ) { + History.Adapter.onDomLoad(function(){ + History.Adapter.trigger(window,'hashchange'); + }); + } + } + + } // !History.emulated.pushState + + + }; // History.initCore + + // Try to Initialise History + if (!History.options || !History.options.delayInit) { + History.init(); + } + +})(window); diff --git a/sites/all/themes/gui/materiobasetheme/bower_components/history.js/scripts/bundled-uncompressed/html4+html5/mootools.history.js b/sites/all/themes/gui/materiobasetheme/bower_components/history.js/scripts/bundled-uncompressed/html4+html5/mootools.history.js new file mode 100644 index 00000000..df63dee7 --- /dev/null +++ b/sites/all/themes/gui/materiobasetheme/bower_components/history.js/scripts/bundled-uncompressed/html4+html5/mootools.history.js @@ -0,0 +1,3298 @@ +/* + json2.js + 2012-10-08 + + Public Domain. + + NO WARRANTY EXPRESSED OR IMPLIED. USE AT YOUR OWN RISK. + + See http://www.JSON.org/js.html + + + This code should be minified before deployment. + See http://javascript.crockford.com/jsmin.html + + USE YOUR OWN COPY. IT IS EXTREMELY UNWISE TO LOAD CODE FROM SERVERS YOU DO + NOT CONTROL. + + + This file creates a global JSON object containing two methods: stringify + and parse. + + JSON.stringify(value, replacer, space) + value any JavaScript value, usually an object or array. + + replacer an optional parameter that determines how object + values are stringified for objects. It can be a + function or an array of strings. + + space an optional parameter that specifies the indentation + of nested structures. If it is omitted, the text will + be packed without extra whitespace. If it is a number, + it will specify the number of spaces to indent at each + level. If it is a string (such as '\t' or ' '), + it contains the characters used to indent at each level. + + This method produces a JSON text from a JavaScript value. + + When an object value is found, if the object contains a toJSON + method, its toJSON method will be called and the result will be + stringified. A toJSON method does not serialize: it returns the + value represented by the name/value pair that should be serialized, + or undefined if nothing should be serialized. The toJSON method + will be passed the key associated with the value, and this will be + bound to the value + + For example, this would serialize Dates as ISO strings. + + Date.prototype.toJSON = function (key) { + function f(n) { + // Format integers to have at least two digits. + return n < 10 ? '0' + n : n; + } + + return this.getUTCFullYear() + '-' + + f(this.getUTCMonth() + 1) + '-' + + f(this.getUTCDate()) + 'T' + + f(this.getUTCHours()) + ':' + + f(this.getUTCMinutes()) + ':' + + f(this.getUTCSeconds()) + 'Z'; + }; + + You can provide an optional replacer method. It will be passed the + key and value of each member, with this bound to the containing + object. The value that is returned from your method will be + serialized. If your method returns undefined, then the member will + be excluded from the serialization. + + If the replacer parameter is an array of strings, then it will be + used to select the members to be serialized. It filters the results + such that only members with keys listed in the replacer array are + stringified. + + Values that do not have JSON representations, such as undefined or + functions, will not be serialized. Such values in objects will be + dropped; in arrays they will be replaced with null. You can use + a replacer function to replace those with JSON values. + JSON.stringify(undefined) returns undefined. + + The optional space parameter produces a stringification of the + value that is filled with line breaks and indentation to make it + easier to read. + + If the space parameter is a non-empty string, then that string will + be used for indentation. If the space parameter is a number, then + the indentation will be that many spaces. + + Example: + + text = JSON.stringify(['e', {pluribus: 'unum'}]); + // text is '["e",{"pluribus":"unum"}]' + + + text = JSON.stringify(['e', {pluribus: 'unum'}], null, '\t'); + // text is '[\n\t"e",\n\t{\n\t\t"pluribus": "unum"\n\t}\n]' + + text = JSON.stringify([new Date()], function (key, value) { + return this[key] instanceof Date ? + 'Date(' + this[key] + ')' : value; + }); + // text is '["Date(---current time---)"]' + + + JSON.parse(text, reviver) + This method parses a JSON text to produce an object or array. + It can throw a SyntaxError exception. + + The optional reviver parameter is a function that can filter and + transform the results. It receives each of the keys and values, + and its return value is used instead of the original value. + If it returns what it received, then the structure is not modified. + If it returns undefined then the member is deleted. + + Example: + + // Parse the text. Values that look like ISO date strings will + // be converted to Date objects. + + myData = JSON.parse(text, function (key, value) { + var a; + if (typeof value === 'string') { + a = +/^(\d{4})-(\d{2})-(\d{2})T(\d{2}):(\d{2}):(\d{2}(?:\.\d*)?)Z$/.exec(value); + if (a) { + return new Date(Date.UTC(+a[1], +a[2] - 1, +a[3], +a[4], + +a[5], +a[6])); + } + } + return value; + }); + + myData = JSON.parse('["Date(09/09/2001)"]', function (key, value) { + var d; + if (typeof value === 'string' && + value.slice(0, 5) === 'Date(' && + value.slice(-1) === ')') { + d = new Date(value.slice(5, -1)); + if (d) { + return d; + } + } + return value; + }); + + + This is a reference implementation. You are free to copy, modify, or + redistribute. +*/ + +/*jslint evil: true, regexp: true */ + +/*members "", "\b", "\t", "\n", "\f", "\r", "\"", JSON, "\\", apply, + call, charCodeAt, getUTCDate, getUTCFullYear, getUTCHours, + getUTCMinutes, getUTCMonth, getUTCSeconds, hasOwnProperty, join, + lastIndex, length, parse, prototype, push, replace, slice, stringify, + test, toJSON, toString, valueOf +*/ + + +// Create a JSON object only if one does not already exist. We create the +// methods in a closure to avoid creating global variables. + +if (typeof JSON !== 'object') { + JSON = {}; +} + +(function () { + 'use strict'; + + function f(n) { + // Format integers to have at least two digits. + return n < 10 ? '0' + n : n; + } + + if (typeof Date.prototype.toJSON !== 'function') { + + Date.prototype.toJSON = function (key) { + + return isFinite(this.valueOf()) + ? this.getUTCFullYear() + '-' + + f(this.getUTCMonth() + 1) + '-' + + f(this.getUTCDate()) + 'T' + + f(this.getUTCHours()) + ':' + + f(this.getUTCMinutes()) + ':' + + f(this.getUTCSeconds()) + 'Z' + : null; + }; + + String.prototype.toJSON = + Number.prototype.toJSON = + Boolean.prototype.toJSON = function (key) { + return this.valueOf(); + }; + } + + var cx = /[\u0000\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g, + escapable = /[\\\"\x00-\x1f\x7f-\x9f\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g, + gap, + indent, + meta = { // table of character substitutions + '\b': '\\b', + '\t': '\\t', + '\n': '\\n', + '\f': '\\f', + '\r': '\\r', + '"' : '\\"', + '\\': '\\\\' + }, + rep; + + + function quote(string) { + +// If the string contains no control characters, no quote characters, and no +// backslash characters, then we can safely slap some quotes around it. +// Otherwise we must also replace the offending characters with safe escape +// sequences. + + escapable.lastIndex = 0; + return escapable.test(string) ? '"' + string.replace(escapable, function (a) { + var c = meta[a]; + return typeof c === 'string' + ? c + : '\\u' + ('0000' + a.charCodeAt(0).toString(16)).slice(-4); + }) + '"' : '"' + string + '"'; + } + + + function str(key, holder) { + +// Produce a string from holder[key]. + + var i, // The loop counter. + k, // The member key. + v, // The member value. + length, + mind = gap, + partial, + value = holder[key]; + +// If the value has a toJSON method, call it to obtain a replacement value. + + if (value && typeof value === 'object' && + typeof value.toJSON === 'function') { + value = value.toJSON(key); + } + +// If we were called with a replacer function, then call the replacer to +// obtain a replacement value. + + if (typeof rep === 'function') { + value = rep.call(holder, key, value); + } + +// What happens next depends on the value's type. + + switch (typeof value) { + case 'string': + return quote(value); + + case 'number': + +// JSON numbers must be finite. Encode non-finite numbers as null. + + return isFinite(value) ? String(value) : 'null'; + + case 'boolean': + case 'null': + +// If the value is a boolean or null, convert it to a string. Note: +// typeof null does not produce 'null'. The case is included here in +// the remote chance that this gets fixed someday. + + return String(value); + +// If the type is 'object', we might be dealing with an object or an array or +// null. + + case 'object': + +// Due to a specification blunder in ECMAScript, typeof null is 'object', +// so watch out for that case. + + if (!value) { + return 'null'; + } + +// Make an array to hold the partial results of stringifying this object value. + + gap += indent; + partial = []; + +// Is the value an array? + + if (Object.prototype.toString.apply(value) === '[object Array]') { + +// The value is an array. Stringify every element. Use null as a placeholder +// for non-JSON values. + + length = value.length; + for (i = 0; i < length; i += 1) { + partial[i] = str(i, value) || 'null'; + } + +// Join all of the elements together, separated with commas, and wrap them in +// brackets. + + v = partial.length === 0 + ? '[]' + : gap + ? '[\n' + gap + partial.join(',\n' + gap) + '\n' + mind + ']' + : '[' + partial.join(',') + ']'; + gap = mind; + return v; + } + +// If the replacer is an array, use it to select the members to be stringified. + + if (rep && typeof rep === 'object') { + length = rep.length; + for (i = 0; i < length; i += 1) { + if (typeof rep[i] === 'string') { + k = rep[i]; + v = str(k, value); + if (v) { + partial.push(quote(k) + (gap ? ': ' : ':') + v); + } + } + } + } else { + +// Otherwise, iterate through all of the keys in the object. + + for (k in value) { + if (Object.prototype.hasOwnProperty.call(value, k)) { + v = str(k, value); + if (v) { + partial.push(quote(k) + (gap ? ': ' : ':') + v); + } + } + } + } + +// Join all of the member texts together, separated with commas, +// and wrap them in braces. + + v = partial.length === 0 + ? '{}' + : gap + ? '{\n' + gap + partial.join(',\n' + gap) + '\n' + mind + '}' + : '{' + partial.join(',') + '}'; + gap = mind; + return v; + } + } + +// If the JSON object does not yet have a stringify method, give it one. + + if (typeof JSON.stringify !== 'function') { + JSON.stringify = function (value, replacer, space) { + +// The stringify method takes a value and an optional replacer, and an optional +// space parameter, and returns a JSON text. The replacer can be a function +// that can replace values, or an array of strings that will select the keys. +// A default replacer method can be provided. Use of the space parameter can +// produce text that is more easily readable. + + var i; + gap = ''; + indent = ''; + +// If the space parameter is a number, make an indent string containing that +// many spaces. + + if (typeof space === 'number') { + for (i = 0; i < space; i += 1) { + indent += ' '; + } + +// If the space parameter is a string, it will be used as the indent string. + + } else if (typeof space === 'string') { + indent = space; + } + +// If there is a replacer, it must be a function or an array. +// Otherwise, throw an error. + + rep = replacer; + if (replacer && typeof replacer !== 'function' && + (typeof replacer !== 'object' || + typeof replacer.length !== 'number')) { + throw new Error('JSON.stringify'); + } + +// Make a fake root object containing our value under the key of ''. +// Return the result of stringifying the value. + + return str('', {'': value}); + }; + } + + +// If the JSON object does not yet have a parse method, give it one. + + if (typeof JSON.parse !== 'function') { + JSON.parse = function (text, reviver) { + +// The parse method takes a text and an optional reviver function, and returns +// a JavaScript value if the text is a valid JSON text. + + var j; + + function walk(holder, key) { + +// The walk method is used to recursively walk the resulting structure so +// that modifications can be made. + + var k, v, value = holder[key]; + if (value && typeof value === 'object') { + for (k in value) { + if (Object.prototype.hasOwnProperty.call(value, k)) { + v = walk(value, k); + if (v !== undefined) { + value[k] = v; + } else { + delete value[k]; + } + } + } + } + return reviver.call(holder, key, value); + } + + +// Parsing happens in four stages. In the first stage, we replace certain +// Unicode characters with escape sequences. JavaScript handles many characters +// incorrectly, either silently deleting them, or treating them as line endings. + + text = String(text); + cx.lastIndex = 0; + if (cx.test(text)) { + text = text.replace(cx, function (a) { + return '\\u' + + ('0000' + a.charCodeAt(0).toString(16)).slice(-4); + }); + } + +// In the second stage, we run the text against regular expressions that look +// for non-JSON patterns. We are especially concerned with '()' and 'new' +// because they can cause invocation, and '=' because it can cause mutation. +// But just to be safe, we want to reject all unexpected forms. + +// We split the second stage into 4 regexp operations in order to work around +// crippling inefficiencies in IE's and Safari's regexp engines. First we +// replace the JSON backslash pairs with '@' (a non-JSON character). Second, we +// replace all simple value tokens with ']' characters. Third, we delete all +// open brackets that follow a colon or comma or that begin the text. Finally, +// we look to see that the remaining characters are only whitespace or ']' or +// ',' or ':' or '{' or '}'. If that is so, then the text is safe for eval. + + if (/^[\],:{}\s]*$/ + .test(text.replace(/\\(?:["\\\/bfnrt]|u[0-9a-fA-F]{4})/g, '@') + .replace(/"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g, ']') + .replace(/(?:^|:|,)(?:\s*\[)+/g, ''))) { + +// In the third stage we use the eval function to compile the text into a +// JavaScript structure. The '{' operator is subject to a syntactic ambiguity +// in JavaScript: it can begin a block or an object literal. We wrap the text +// in parens to eliminate the ambiguity. + + j = eval('(' + text + ')'); + +// In the optional fourth stage, we recursively walk the new structure, passing +// each name/value pair to a reviver function for possible transformation. + + return typeof reviver === 'function' + ? walk({'': j}, '') + : j; + } + +// If the text is not JSON parseable, then a SyntaxError is thrown. + + throw new SyntaxError('JSON.parse'); + }; + } +}());/** + * History.js MooTools Adapter + * @author Benjamin Arthur Lupton + * @copyright 2010-2011 Benjamin Arthur Lupton + * @license New BSD License + */ + +// Closure +(function(window,undefined){ + "use strict"; + + // Localise Globals + var + History = window.History = window.History||{}, + MooTools = window.MooTools, + Element = window.Element; + + // Check Existence + if ( typeof History.Adapter !== 'undefined' ) { + throw new Error('History.js Adapter has already been loaded...'); + } + + // Make MooTools aware of History.js Events + Object.append(Element.NativeEvents,{ + 'popstate':2, + 'hashchange':2 + }); + + // Add the Adapter + History.Adapter = { + /** + * History.Adapter.bind(el,event,callback) + * @param {Element|string} el + * @param {string} event - custom and standard events + * @param {function} callback + * @return {void} + */ + bind: function(el,event,callback){ + var El = typeof el === 'string' ? document.id(el) : el; + El.addEvent(event,callback); + }, + + /** + * History.Adapter.trigger(el,event) + * @param {Element|string} el + * @param {string} event - custom and standard events + * @param {Object=} extra - a object of extra event data (optional) + * @return void + */ + trigger: function(el,event,extra){ + var El = typeof el === 'string' ? document.id(el) : el; + El.fireEvent(event,extra); + }, + + /** + * History.Adapter.extractEventData(key,event,extra) + * @param {string} key - key for the event data to extract + * @param {string} event - custom and standard events + * @return {mixed} + */ + extractEventData: function(key,event){ + // MooTools Native then MooTools Custom + var result = (event && event.event && event.event[key]) || (event && event[key]) || undefined; + + // Return + return result; + }, + + /** + * History.Adapter.onDomLoad(callback) + * @param {function} callback + * @return {void} + */ + onDomLoad: function(callback) { + window.addEvent('domready',callback); + } + }; + + // Try and Initialise History + if ( typeof History.init !== 'undefined' ) { + History.init(); + } + +})(window); +/** + * History.js HTML4 Support + * Depends on the HTML5 Support + * @author Benjamin Arthur Lupton + * @copyright 2010-2011 Benjamin Arthur Lupton + * @license New BSD License + */ + +(function(window,undefined){ + "use strict"; + + // ======================================================================== + // Initialise + + // Localise Globals + var + document = window.document, // Make sure we are using the correct document + setTimeout = window.setTimeout||setTimeout, + clearTimeout = window.clearTimeout||clearTimeout, + setInterval = window.setInterval||setInterval, + History = window.History = window.History||{}; // Public History Object + + // Check Existence + if ( typeof History.initHtml4 !== 'undefined' ) { + throw new Error('History.js HTML4 Support has already been loaded...'); + } + + + // ======================================================================== + // Initialise HTML4 Support + + // Initialise HTML4 Support + History.initHtml4 = function(){ + // Initialise + if ( typeof History.initHtml4.initialized !== 'undefined' ) { + // Already Loaded + return false; + } + else { + History.initHtml4.initialized = true; + } + + + // ==================================================================== + // Properties + + /** + * History.enabled + * Is History enabled? + */ + History.enabled = true; + + + // ==================================================================== + // Hash Storage + + /** + * History.savedHashes + * Store the hashes in an array + */ + History.savedHashes = []; + + /** + * History.isLastHash(newHash) + * Checks if the hash is the last hash + * @param {string} newHash + * @return {boolean} true + */ + History.isLastHash = function(newHash){ + // Prepare + var oldHash = History.getHashByIndex(), + isLast; + + // Check + isLast = newHash === oldHash; + + // Return isLast + return isLast; + }; + + /** + * History.isHashEqual(newHash, oldHash) + * Checks to see if two hashes are functionally equal + * @param {string} newHash + * @param {string} oldHash + * @return {boolean} true + */ + History.isHashEqual = function(newHash, oldHash){ + newHash = encodeURIComponent(newHash).replace(/%25/g, "%"); + oldHash = encodeURIComponent(oldHash).replace(/%25/g, "%"); + return newHash === oldHash; + }; + + /** + * History.saveHash(newHash) + * Push a Hash + * @param {string} newHash + * @return {boolean} true + */ + History.saveHash = function(newHash){ + // Check Hash + if ( History.isLastHash(newHash) ) { + return false; + } + + // Push the Hash + History.savedHashes.push(newHash); + + // Return true + return true; + }; + + /** + * History.getHashByIndex() + * Gets a hash by the index + * @param {integer} index + * @return {string} + */ + History.getHashByIndex = function(index){ + // Prepare + var hash = null; + + // Handle + if ( typeof index === 'undefined' ) { + // Get the last inserted + hash = History.savedHashes[History.savedHashes.length-1]; + } + else if ( index < 0 ) { + // Get from the end + hash = History.savedHashes[History.savedHashes.length+index]; + } + else { + // Get from the beginning + hash = History.savedHashes[index]; + } + + // Return hash + return hash; + }; + + + // ==================================================================== + // Discarded States + + /** + * History.discardedHashes + * A hashed array of discarded hashes + */ + History.discardedHashes = {}; + + /** + * History.discardedStates + * A hashed array of discarded states + */ + History.discardedStates = {}; + + /** + * History.discardState(State) + * Discards the state by ignoring it through History + * @param {object} State + * @return {true} + */ + History.discardState = function(discardedState,forwardState,backState){ + //History.debug('History.discardState', arguments); + // Prepare + var discardedStateHash = History.getHashByState(discardedState), + discardObject; + + // Create Discard Object + discardObject = { + 'discardedState': discardedState, + 'backState': backState, + 'forwardState': forwardState + }; + + // Add to DiscardedStates + History.discardedStates[discardedStateHash] = discardObject; + + // Return true + return true; + }; + + /** + * History.discardHash(hash) + * Discards the hash by ignoring it through History + * @param {string} hash + * @return {true} + */ + History.discardHash = function(discardedHash,forwardState,backState){ + //History.debug('History.discardState', arguments); + // Create Discard Object + var discardObject = { + 'discardedHash': discardedHash, + 'backState': backState, + 'forwardState': forwardState + }; + + // Add to discardedHash + History.discardedHashes[discardedHash] = discardObject; + + // Return true + return true; + }; + + /** + * History.discardedState(State) + * Checks to see if the state is discarded + * @param {object} State + * @return {bool} + */ + History.discardedState = function(State){ + // Prepare + var StateHash = History.getHashByState(State), + discarded; + + // Check + discarded = History.discardedStates[StateHash]||false; + + // Return true + return discarded; + }; + + /** + * History.discardedHash(hash) + * Checks to see if the state is discarded + * @param {string} State + * @return {bool} + */ + History.discardedHash = function(hash){ + // Check + var discarded = History.discardedHashes[hash]||false; + + // Return true + return discarded; + }; + + /** + * History.recycleState(State) + * Allows a discarded state to be used again + * @param {object} data + * @param {string} title + * @param {string} url + * @return {true} + */ + History.recycleState = function(State){ + //History.debug('History.recycleState', arguments); + // Prepare + var StateHash = History.getHashByState(State); + + // Remove from DiscardedStates + if ( History.discardedState(State) ) { + delete History.discardedStates[StateHash]; + } + + // Return true + return true; + }; + + + // ==================================================================== + // HTML4 HashChange Support + + if ( History.emulated.hashChange ) { + /* + * We must emulate the HTML4 HashChange Support by manually checking for hash changes + */ + + /** + * History.hashChangeInit() + * Init the HashChange Emulation + */ + History.hashChangeInit = function(){ + // Define our Checker Function + History.checkerFunction = null; + + // Define some variables that will help in our checker function + var lastDocumentHash = '', + iframeId, iframe, + lastIframeHash, checkerRunning, + startedWithHash = Boolean(History.getHash()); + + // Handle depending on the browser + if ( History.isInternetExplorer() ) { + // IE6 and IE7 + // We need to use an iframe to emulate the back and forward buttons + + // Create iFrame + iframeId = 'historyjs-iframe'; + iframe = document.createElement('iframe'); + + // Adjust iFarme + // IE 6 requires iframe to have a src on HTTPS pages, otherwise it will throw a + // "This page contains both secure and nonsecure items" warning. + iframe.setAttribute('id', iframeId); + iframe.setAttribute('src', '#'); + iframe.style.display = 'none'; + + // Append iFrame + document.body.appendChild(iframe); + + // Create initial history entry + iframe.contentWindow.document.open(); + iframe.contentWindow.document.close(); + + // Define some variables that will help in our checker function + lastIframeHash = ''; + checkerRunning = false; + + // Define the checker function + History.checkerFunction = function(){ + // Check Running + if ( checkerRunning ) { + return false; + } + + // Update Running + checkerRunning = true; + + // Fetch + var + documentHash = History.getHash(), + iframeHash = History.getHash(iframe.contentWindow.document); + + // The Document Hash has changed (application caused) + if ( documentHash !== lastDocumentHash ) { + // Equalise + lastDocumentHash = documentHash; + + // Create a history entry in the iframe + if ( iframeHash !== documentHash ) { + //History.debug('hashchange.checker: iframe hash change', 'documentHash (new):', documentHash, 'iframeHash (old):', iframeHash); + + // Equalise + lastIframeHash = iframeHash = documentHash; + + // Create History Entry + iframe.contentWindow.document.open(); + iframe.contentWindow.document.close(); + + // Update the iframe's hash + iframe.contentWindow.document.location.hash = History.escapeHash(documentHash); + } + + // Trigger Hashchange Event + History.Adapter.trigger(window,'hashchange'); + } + + // The iFrame Hash has changed (back button caused) + else if ( iframeHash !== lastIframeHash ) { + //History.debug('hashchange.checker: iframe hash out of sync', 'iframeHash (new):', iframeHash, 'documentHash (old):', documentHash); + + // Equalise + lastIframeHash = iframeHash; + + // If there is no iframe hash that means we're at the original + // iframe state. + // And if there was a hash on the original request, the original + // iframe state was replaced instantly, so skip this state and take + // the user back to where they came from. + if (startedWithHash && iframeHash === '') { + History.back(); + } + else { + // Update the Hash + History.setHash(iframeHash,false); + } + } + + // Reset Running + checkerRunning = false; + + // Return true + return true; + }; + } + else { + // We are not IE + // Firefox 1 or 2, Opera + + // Define the checker function + History.checkerFunction = function(){ + // Prepare + var documentHash = History.getHash()||''; + + // The Document Hash has changed (application caused) + if ( documentHash !== lastDocumentHash ) { + // Equalise + lastDocumentHash = documentHash; + + // Trigger Hashchange Event + History.Adapter.trigger(window,'hashchange'); + } + + // Return true + return true; + }; + } + + // Apply the checker function + History.intervalList.push(setInterval(History.checkerFunction, History.options.hashChangeInterval)); + + // Done + return true; + }; // History.hashChangeInit + + // Bind hashChangeInit + History.Adapter.onDomLoad(History.hashChangeInit); + + } // History.emulated.hashChange + + + // ==================================================================== + // HTML5 State Support + + // Non-Native pushState Implementation + if ( History.emulated.pushState ) { + /* + * We must emulate the HTML5 State Management by using HTML4 HashChange + */ + + /** + * History.onHashChange(event) + * Trigger HTML5's window.onpopstate via HTML4 HashChange Support + */ + History.onHashChange = function(event){ + //History.debug('History.onHashChange', arguments); + + // Prepare + var currentUrl = ((event && event.newURL) || History.getLocationHref()), + currentHash = History.getHashByUrl(currentUrl), + currentState = null, + currentStateHash = null, + currentStateHashExits = null, + discardObject; + + // Check if we are the same state + if ( History.isLastHash(currentHash) ) { + // There has been no change (just the page's hash has finally propagated) + //History.debug('History.onHashChange: no change'); + History.busy(false); + return false; + } + + // Reset the double check + History.doubleCheckComplete(); + + // Store our location for use in detecting back/forward direction + History.saveHash(currentHash); + + // Expand Hash + if ( currentHash && History.isTraditionalAnchor(currentHash) ) { + //History.debug('History.onHashChange: traditional anchor', currentHash); + // Traditional Anchor Hash + History.Adapter.trigger(window,'anchorchange'); + History.busy(false); + return false; + } + + // Create State + currentState = History.extractState(History.getFullUrl(currentHash||History.getLocationHref()),true); + + // Check if we are the same state + if ( History.isLastSavedState(currentState) ) { + //History.debug('History.onHashChange: no change'); + // There has been no change (just the page's hash has finally propagated) + History.busy(false); + return false; + } + + // Create the state Hash + currentStateHash = History.getHashByState(currentState); + + // Check if we are DiscardedState + discardObject = History.discardedState(currentState); + if ( discardObject ) { + // Ignore this state as it has been discarded and go back to the state before it + if ( History.getHashByIndex(-2) === History.getHashByState(discardObject.forwardState) ) { + // We are going backwards + //History.debug('History.onHashChange: go backwards'); + History.back(false); + } else { + // We are going forwards + //History.debug('History.onHashChange: go forwards'); + History.forward(false); + } + return false; + } + + // Push the new HTML5 State + //History.debug('History.onHashChange: success hashchange'); + History.pushState(currentState.data,currentState.title,encodeURI(currentState.url),false); + + // End onHashChange closure + return true; + }; + History.Adapter.bind(window,'hashchange',History.onHashChange); + + /** + * History.pushState(data,title,url) + * Add a new State to the history object, become it, and trigger onpopstate + * We have to trigger for HTML4 compatibility + * @param {object} data + * @param {string} title + * @param {string} url + * @return {true} + */ + History.pushState = function(data,title,url,queue){ + //History.debug('History.pushState: called', arguments); + + // We assume that the URL passed in is URI-encoded, but this makes + // sure that it's fully URI encoded; any '%'s that are encoded are + // converted back into '%'s + url = encodeURI(url).replace(/%25/g, "%"); + + // Check the State + if ( History.getHashByUrl(url) ) { + throw new Error('History.js does not support states with fragment-identifiers (hashes/anchors).'); + } + + // Handle Queueing + if ( queue !== false && History.busy() ) { + // Wait + Push to Queue + //History.debug('History.pushState: we must wait', arguments); + History.pushQueue({ + scope: History, + callback: History.pushState, + args: arguments, + queue: queue + }); + return false; + } + + // Make Busy + History.busy(true); + + // Fetch the State Object + var newState = History.createStateObject(data,title,url), + newStateHash = History.getHashByState(newState), + oldState = History.getState(false), + oldStateHash = History.getHashByState(oldState), + html4Hash = History.getHash(), + wasExpected = History.expectedStateId == newState.id; + + // Store the newState + History.storeState(newState); + History.expectedStateId = newState.id; + + // Recycle the State + History.recycleState(newState); + + // Force update of the title + History.setTitle(newState); + + // Check if we are the same State + if ( newStateHash === oldStateHash ) { + //History.debug('History.pushState: no change', newStateHash); + History.busy(false); + return false; + } + + // Update HTML5 State + History.saveState(newState); + + // Fire HTML5 Event + if(!wasExpected) + History.Adapter.trigger(window,'statechange'); + + // Update HTML4 Hash + if ( !History.isHashEqual(newStateHash, html4Hash) && !History.isHashEqual(newStateHash, History.getShortUrl(History.getLocationHref())) ) { + History.setHash(newStateHash,false); + } + + History.busy(false); + + // End pushState closure + return true; + }; + + /** + * History.replaceState(data,title,url) + * Replace the State and trigger onpopstate + * We have to trigger for HTML4 compatibility + * @param {object} data + * @param {string} title + * @param {string} url + * @return {true} + */ + History.replaceState = function(data,title,url,queue){ + //History.debug('History.replaceState: called', arguments); + + // We assume that the URL passed in is URI-encoded, but this makes + // sure that it's fully URI encoded; any '%'s that are encoded are + // converted back into '%'s + url = encodeURI(url).replace(/%25/g, "%"); + + // Check the State + if ( History.getHashByUrl(url) ) { + throw new Error('History.js does not support states with fragment-identifiers (hashes/anchors).'); + } + + // Handle Queueing + if ( queue !== false && History.busy() ) { + // Wait + Push to Queue + //History.debug('History.replaceState: we must wait', arguments); + History.pushQueue({ + scope: History, + callback: History.replaceState, + args: arguments, + queue: queue + }); + return false; + } + + // Make Busy + History.busy(true); + + // Fetch the State Objects + var newState = History.createStateObject(data,title,url), + newStateHash = History.getHashByState(newState), + oldState = History.getState(false), + oldStateHash = History.getHashByState(oldState), + previousState = History.getStateByIndex(-2); + + // Discard Old State + History.discardState(oldState,newState,previousState); + + // If the url hasn't changed, just store and save the state + // and fire a statechange event to be consistent with the + // html 5 api + if ( newStateHash === oldStateHash ) { + // Store the newState + History.storeState(newState); + History.expectedStateId = newState.id; + + // Recycle the State + History.recycleState(newState); + + // Force update of the title + History.setTitle(newState); + + // Update HTML5 State + History.saveState(newState); + + // Fire HTML5 Event + //History.debug('History.pushState: trigger popstate'); + History.Adapter.trigger(window,'statechange'); + History.busy(false); + } + else { + // Alias to PushState + History.pushState(newState.data,newState.title,newState.url,false); + } + + // End replaceState closure + return true; + }; + + } // History.emulated.pushState + + + + // ==================================================================== + // Initialise + + // Non-Native pushState Implementation + if ( History.emulated.pushState ) { + /** + * Ensure initial state is handled correctly + */ + if ( History.getHash() && !History.emulated.hashChange ) { + History.Adapter.onDomLoad(function(){ + History.Adapter.trigger(window,'hashchange'); + }); + } + + } // History.emulated.pushState + + }; // History.initHtml4 + + // Try to Initialise History + if ( typeof History.init !== 'undefined' ) { + History.init(); + } + +})(window); +/** + * History.js Core + * @author Benjamin Arthur Lupton + * @copyright 2010-2011 Benjamin Arthur Lupton + * @license New BSD License + */ + +(function(window,undefined){ + "use strict"; + + // ======================================================================== + // Initialise + + // Localise Globals + var + console = window.console||undefined, // Prevent a JSLint complain + document = window.document, // Make sure we are using the correct document + navigator = window.navigator, // Make sure we are using the correct navigator + sessionStorage = window.sessionStorage||false, // sessionStorage + setTimeout = window.setTimeout, + clearTimeout = window.clearTimeout, + setInterval = window.setInterval, + clearInterval = window.clearInterval, + JSON = window.JSON, + alert = window.alert, + History = window.History = window.History||{}, // Public History Object + history = window.history; // Old History Object + + try { + sessionStorage.setItem('TEST', '1'); + sessionStorage.removeItem('TEST'); + } catch(e) { + sessionStorage = false; + } + + // MooTools Compatibility + JSON.stringify = JSON.stringify||JSON.encode; + JSON.parse = JSON.parse||JSON.decode; + + // Check Existence + if ( typeof History.init !== 'undefined' ) { + throw new Error('History.js Core has already been loaded...'); + } + + // Initialise History + History.init = function(options){ + // Check Load Status of Adapter + if ( typeof History.Adapter === 'undefined' ) { + return false; + } + + // Check Load Status of Core + if ( typeof History.initCore !== 'undefined' ) { + History.initCore(); + } + + // Check Load Status of HTML4 Support + if ( typeof History.initHtml4 !== 'undefined' ) { + History.initHtml4(); + } + + // Return true + return true; + }; + + + // ======================================================================== + // Initialise Core + + // Initialise Core + History.initCore = function(options){ + // Initialise + if ( typeof History.initCore.initialized !== 'undefined' ) { + // Already Loaded + return false; + } + else { + History.initCore.initialized = true; + } + + + // ==================================================================== + // Options + + /** + * History.options + * Configurable options + */ + History.options = History.options||{}; + + /** + * History.options.hashChangeInterval + * How long should the interval be before hashchange checks + */ + History.options.hashChangeInterval = History.options.hashChangeInterval || 100; + + /** + * History.options.safariPollInterval + * How long should the interval be before safari poll checks + */ + History.options.safariPollInterval = History.options.safariPollInterval || 500; + + /** + * History.options.doubleCheckInterval + * How long should the interval be before we perform a double check + */ + History.options.doubleCheckInterval = History.options.doubleCheckInterval || 500; + + /** + * History.options.disableSuid + * Force History not to append suid + */ + History.options.disableSuid = History.options.disableSuid || false; + + /** + * History.options.storeInterval + * How long should we wait between store calls + */ + History.options.storeInterval = History.options.storeInterval || 1000; + + /** + * History.options.busyDelay + * How long should we wait between busy events + */ + History.options.busyDelay = History.options.busyDelay || 250; + + /** + * History.options.debug + * If true will enable debug messages to be logged + */ + History.options.debug = History.options.debug || false; + + /** + * History.options.initialTitle + * What is the title of the initial state + */ + History.options.initialTitle = History.options.initialTitle || document.title; + + /** + * History.options.html4Mode + * If true, will force HTMl4 mode (hashtags) + */ + History.options.html4Mode = History.options.html4Mode || false; + + /** + * History.options.delayInit + * Want to override default options and call init manually. + */ + History.options.delayInit = History.options.delayInit || false; + + + // ==================================================================== + // Interval record + + /** + * History.intervalList + * List of intervals set, to be cleared when document is unloaded. + */ + History.intervalList = []; + + /** + * History.clearAllIntervals + * Clears all setInterval instances. + */ + History.clearAllIntervals = function(){ + var i, il = History.intervalList; + if (typeof il !== "undefined" && il !== null) { + for (i = 0; i < il.length; i++) { + clearInterval(il[i]); + } + History.intervalList = null; + } + }; + + + // ==================================================================== + // Debug + + /** + * History.debug(message,...) + * Logs the passed arguments if debug enabled + */ + History.debug = function(){ + if ( (History.options.debug||false) ) { + History.log.apply(History,arguments); + } + }; + + /** + * History.log(message,...) + * Logs the passed arguments + */ + History.log = function(){ + // Prepare + var + consoleExists = !(typeof console === 'undefined' || typeof console.log === 'undefined' || typeof console.log.apply === 'undefined'), + textarea = document.getElementById('log'), + message, + i,n, + args,arg + ; + + // Write to Console + if ( consoleExists ) { + args = Array.prototype.slice.call(arguments); + message = args.shift(); + if ( typeof console.debug !== 'undefined' ) { + console.debug.apply(console,[message,args]); + } + else { + console.log.apply(console,[message,args]); + } + } + else { + message = ("\n"+arguments[0]+"\n"); + } + + // Write to log + for ( i=1,n=arguments.length; i + * @author James Padolsey + */ + History.getInternetExplorerMajorVersion = function(){ + var result = History.getInternetExplorerMajorVersion.cached = + (typeof History.getInternetExplorerMajorVersion.cached !== 'undefined') + ? History.getInternetExplorerMajorVersion.cached + : (function(){ + var v = 3, + div = document.createElement('div'), + all = div.getElementsByTagName('i'); + while ( (div.innerHTML = '') && all[0] ) {} + return (v > 4) ? v : false; + })() + ; + return result; + }; + + /** + * History.isInternetExplorer() + * Are we using Internet Explorer? + * @return {boolean} + * @license Public Domain + * @author Benjamin Arthur Lupton + */ + History.isInternetExplorer = function(){ + var result = + History.isInternetExplorer.cached = + (typeof History.isInternetExplorer.cached !== 'undefined') + ? History.isInternetExplorer.cached + : Boolean(History.getInternetExplorerMajorVersion()) + ; + return result; + }; + + /** + * History.emulated + * Which features require emulating? + */ + + if (History.options.html4Mode) { + History.emulated = { + pushState : true, + hashChange: true + }; + } + + else { + + History.emulated = { + pushState: !Boolean( + window.history && window.history.pushState && window.history.replaceState + && !( + (/ Mobile\/([1-7][a-z]|(8([abcde]|f(1[0-8]))))/i).test(navigator.userAgent) /* disable for versions of iOS before version 4.3 (8F190) */ + || (/AppleWebKit\/5([0-2]|3[0-2])/i).test(navigator.userAgent) /* disable for the mercury iOS browser, or at least older versions of the webkit engine */ + ) + ), + hashChange: Boolean( + !(('onhashchange' in window) || ('onhashchange' in document)) + || + (History.isInternetExplorer() && History.getInternetExplorerMajorVersion() < 8) + ) + }; + } + + /** + * History.enabled + * Is History enabled? + */ + History.enabled = !History.emulated.pushState; + + /** + * History.bugs + * Which bugs are present + */ + History.bugs = { + /** + * Safari 5 and Safari iOS 4 fail to return to the correct state once a hash is replaced by a `replaceState` call + * https://bugs.webkit.org/show_bug.cgi?id=56249 + */ + setHash: Boolean(!History.emulated.pushState && navigator.vendor === 'Apple Computer, Inc.' && /AppleWebKit\/5([0-2]|3[0-3])/.test(navigator.userAgent)), + + /** + * Safari 5 and Safari iOS 4 sometimes fail to apply the state change under busy conditions + * https://bugs.webkit.org/show_bug.cgi?id=42940 + */ + safariPoll: Boolean(!History.emulated.pushState && navigator.vendor === 'Apple Computer, Inc.' && /AppleWebKit\/5([0-2]|3[0-3])/.test(navigator.userAgent)), + + /** + * MSIE 6 and 7 sometimes do not apply a hash even it was told to (requiring a second call to the apply function) + */ + ieDoubleCheck: Boolean(History.isInternetExplorer() && History.getInternetExplorerMajorVersion() < 8), + + /** + * MSIE 6 requires the entire hash to be encoded for the hashes to trigger the onHashChange event + */ + hashEscape: Boolean(History.isInternetExplorer() && History.getInternetExplorerMajorVersion() < 7) + }; + + /** + * History.isEmptyObject(obj) + * Checks to see if the Object is Empty + * @param {Object} obj + * @return {boolean} + */ + History.isEmptyObject = function(obj) { + for ( var name in obj ) { + if ( obj.hasOwnProperty(name) ) { + return false; + } + } + return true; + }; + + /** + * History.cloneObject(obj) + * Clones a object and eliminate all references to the original contexts + * @param {Object} obj + * @return {Object} + */ + History.cloneObject = function(obj) { + var hash,newObj; + if ( obj ) { + hash = JSON.stringify(obj); + newObj = JSON.parse(hash); + } + else { + newObj = {}; + } + return newObj; + }; + + + // ==================================================================== + // URL Helpers + + /** + * History.getRootUrl() + * Turns "http://mysite.com/dir/page.html?asd" into "http://mysite.com" + * @return {String} rootUrl + */ + History.getRootUrl = function(){ + // Create + var rootUrl = document.location.protocol+'//'+(document.location.hostname||document.location.host); + if ( document.location.port||false ) { + rootUrl += ':'+document.location.port; + } + rootUrl += '/'; + + // Return + return rootUrl; + }; + + /** + * History.getBaseHref() + * Fetches the `href` attribute of the `` element if it exists + * @return {String} baseHref + */ + History.getBaseHref = function(){ + // Create + var + baseElements = document.getElementsByTagName('base'), + baseElement = null, + baseHref = ''; + + // Test for Base Element + if ( baseElements.length === 1 ) { + // Prepare for Base Element + baseElement = baseElements[0]; + baseHref = baseElement.href.replace(/[^\/]+$/,''); + } + + // Adjust trailing slash + baseHref = baseHref.replace(/\/+$/,''); + if ( baseHref ) baseHref += '/'; + + // Return + return baseHref; + }; + + /** + * History.getBaseUrl() + * Fetches the baseHref or basePageUrl or rootUrl (whichever one exists first) + * @return {String} baseUrl + */ + History.getBaseUrl = function(){ + // Create + var baseUrl = History.getBaseHref()||History.getBasePageUrl()||History.getRootUrl(); + + // Return + return baseUrl; + }; + + /** + * History.getPageUrl() + * Fetches the URL of the current page + * @return {String} pageUrl + */ + History.getPageUrl = function(){ + // Fetch + var + State = History.getState(false,false), + stateUrl = (State||{}).url||History.getLocationHref(), + pageUrl; + + // Create + pageUrl = stateUrl.replace(/\/+$/,'').replace(/[^\/]+$/,function(part,index,string){ + return (/\./).test(part) ? part : part+'/'; + }); + + // Return + return pageUrl; + }; + + /** + * History.getBasePageUrl() + * Fetches the Url of the directory of the current page + * @return {String} basePageUrl + */ + History.getBasePageUrl = function(){ + // Create + var basePageUrl = (History.getLocationHref()).replace(/[#\?].*/,'').replace(/[^\/]+$/,function(part,index,string){ + return (/[^\/]$/).test(part) ? '' : part; + }).replace(/\/+$/,'')+'/'; + + // Return + return basePageUrl; + }; + + /** + * History.getFullUrl(url) + * Ensures that we have an absolute URL and not a relative URL + * @param {string} url + * @param {Boolean} allowBaseHref + * @return {string} fullUrl + */ + History.getFullUrl = function(url,allowBaseHref){ + // Prepare + var fullUrl = url, firstChar = url.substring(0,1); + allowBaseHref = (typeof allowBaseHref === 'undefined') ? true : allowBaseHref; + + // Check + if ( /[a-z]+\:\/\//.test(url) ) { + // Full URL + } + else if ( firstChar === '/' ) { + // Root URL + fullUrl = History.getRootUrl()+url.replace(/^\/+/,''); + } + else if ( firstChar === '#' ) { + // Anchor URL + fullUrl = History.getPageUrl().replace(/#.*/,'')+url; + } + else if ( firstChar === '?' ) { + // Query URL + fullUrl = History.getPageUrl().replace(/[\?#].*/,'')+url; + } + else { + // Relative URL + if ( allowBaseHref ) { + fullUrl = History.getBaseUrl()+url.replace(/^(\.\/)+/,''); + } else { + fullUrl = History.getBasePageUrl()+url.replace(/^(\.\/)+/,''); + } + // We have an if condition above as we do not want hashes + // which are relative to the baseHref in our URLs + // as if the baseHref changes, then all our bookmarks + // would now point to different locations + // whereas the basePageUrl will always stay the same + } + + // Return + return fullUrl.replace(/\#$/,''); + }; + + /** + * History.getShortUrl(url) + * Ensures that we have a relative URL and not a absolute URL + * @param {string} url + * @return {string} url + */ + History.getShortUrl = function(url){ + // Prepare + var shortUrl = url, baseUrl = History.getBaseUrl(), rootUrl = History.getRootUrl(); + + // Trim baseUrl + if ( History.emulated.pushState ) { + // We are in a if statement as when pushState is not emulated + // The actual url these short urls are relative to can change + // So within the same session, we the url may end up somewhere different + shortUrl = shortUrl.replace(baseUrl,''); + } + + // Trim rootUrl + shortUrl = shortUrl.replace(rootUrl,'/'); + + // Ensure we can still detect it as a state + if ( History.isTraditionalAnchor(shortUrl) ) { + shortUrl = './'+shortUrl; + } + + // Clean It + shortUrl = shortUrl.replace(/^(\.\/)+/g,'./').replace(/\#$/,''); + + // Return + return shortUrl; + }; + + /** + * History.getLocationHref(document) + * Returns a normalized version of document.location.href + * accounting for browser inconsistencies, etc. + * + * This URL will be URI-encoded and will include the hash + * + * @param {object} document + * @return {string} url + */ + History.getLocationHref = function(doc) { + doc = doc || document; + + // most of the time, this will be true + if (doc.URL === doc.location.href) + return doc.location.href; + + // some versions of webkit URI-decode document.location.href + // but they leave document.URL in an encoded state + if (doc.location.href === decodeURIComponent(doc.URL)) + return doc.URL; + + // FF 3.6 only updates document.URL when a page is reloaded + // document.location.href is updated correctly + if (doc.location.hash && decodeURIComponent(doc.location.href.replace(/^[^#]+/, "")) === doc.location.hash) + return doc.location.href; + + if (doc.URL.indexOf('#') == -1 && doc.location.href.indexOf('#') != -1) + return doc.location.href; + + return doc.URL || doc.location.href; + }; + + + // ==================================================================== + // State Storage + + /** + * History.store + * The store for all session specific data + */ + History.store = {}; + + /** + * History.idToState + * 1-1: State ID to State Object + */ + History.idToState = History.idToState||{}; + + /** + * History.stateToId + * 1-1: State String to State ID + */ + History.stateToId = History.stateToId||{}; + + /** + * History.urlToId + * 1-1: State URL to State ID + */ + History.urlToId = History.urlToId||{}; + + /** + * History.storedStates + * Store the states in an array + */ + History.storedStates = History.storedStates||[]; + + /** + * History.savedStates + * Saved the states in an array + */ + History.savedStates = History.savedStates||[]; + + /** + * History.noramlizeStore() + * Noramlize the store by adding necessary values + */ + History.normalizeStore = function(){ + History.store.idToState = History.store.idToState||{}; + History.store.urlToId = History.store.urlToId||{}; + History.store.stateToId = History.store.stateToId||{}; + }; + + /** + * History.getState() + * Get an object containing the data, title and url of the current state + * @param {Boolean} friendly + * @param {Boolean} create + * @return {Object} State + */ + History.getState = function(friendly,create){ + // Prepare + if ( typeof friendly === 'undefined' ) { friendly = true; } + if ( typeof create === 'undefined' ) { create = true; } + + // Fetch + var State = History.getLastSavedState(); + + // Create + if ( !State && create ) { + State = History.createStateObject(); + } + + // Adjust + if ( friendly ) { + State = History.cloneObject(State); + State.url = State.cleanUrl||State.url; + } + + // Return + return State; + }; + + /** + * History.getIdByState(State) + * Gets a ID for a State + * @param {State} newState + * @return {String} id + */ + History.getIdByState = function(newState){ + + // Fetch ID + var id = History.extractId(newState.url), + str; + + if ( !id ) { + // Find ID via State String + str = History.getStateString(newState); + if ( typeof History.stateToId[str] !== 'undefined' ) { + id = History.stateToId[str]; + } + else if ( typeof History.store.stateToId[str] !== 'undefined' ) { + id = History.store.stateToId[str]; + } + else { + // Generate a new ID + while ( true ) { + id = (new Date()).getTime() + String(Math.random()).replace(/\D/g,''); + if ( typeof History.idToState[id] === 'undefined' && typeof History.store.idToState[id] === 'undefined' ) { + break; + } + } + + // Apply the new State to the ID + History.stateToId[str] = id; + History.idToState[id] = newState; + } + } + + // Return ID + return id; + }; + + /** + * History.normalizeState(State) + * Expands a State Object + * @param {object} State + * @return {object} + */ + History.normalizeState = function(oldState){ + // Variables + var newState, dataNotEmpty; + + // Prepare + if ( !oldState || (typeof oldState !== 'object') ) { + oldState = {}; + } + + // Check + if ( typeof oldState.normalized !== 'undefined' ) { + return oldState; + } + + // Adjust + if ( !oldState.data || (typeof oldState.data !== 'object') ) { + oldState.data = {}; + } + + // ---------------------------------------------------------------- + + // Create + newState = {}; + newState.normalized = true; + newState.title = oldState.title||''; + newState.url = History.getFullUrl(oldState.url?oldState.url:(History.getLocationHref())); + newState.hash = History.getShortUrl(newState.url); + newState.data = History.cloneObject(oldState.data); + + // Fetch ID + newState.id = History.getIdByState(newState); + + // ---------------------------------------------------------------- + + // Clean the URL + newState.cleanUrl = newState.url.replace(/\??\&_suid.*/,''); + newState.url = newState.cleanUrl; + + // Check to see if we have more than just a url + dataNotEmpty = !History.isEmptyObject(newState.data); + + // Apply + if ( (newState.title || dataNotEmpty) && History.options.disableSuid !== true ) { + // Add ID to Hash + newState.hash = History.getShortUrl(newState.url).replace(/\??\&_suid.*/,''); + if ( !/\?/.test(newState.hash) ) { + newState.hash += '?'; + } + newState.hash += '&_suid='+newState.id; + } + + // Create the Hashed URL + newState.hashedUrl = History.getFullUrl(newState.hash); + + // ---------------------------------------------------------------- + + // Update the URL if we have a duplicate + if ( (History.emulated.pushState || History.bugs.safariPoll) && History.hasUrlDuplicate(newState) ) { + newState.url = newState.hashedUrl; + } + + // ---------------------------------------------------------------- + + // Return + return newState; + }; + + /** + * History.createStateObject(data,title,url) + * Creates a object based on the data, title and url state params + * @param {object} data + * @param {string} title + * @param {string} url + * @return {object} + */ + History.createStateObject = function(data,title,url){ + // Hashify + var State = { + 'data': data, + 'title': title, + 'url': url + }; + + // Expand the State + State = History.normalizeState(State); + + // Return object + return State; + }; + + /** + * History.getStateById(id) + * Get a state by it's UID + * @param {String} id + */ + History.getStateById = function(id){ + // Prepare + id = String(id); + + // Retrieve + var State = History.idToState[id] || History.store.idToState[id] || undefined; + + // Return State + return State; + }; + + /** + * Get a State's String + * @param {State} passedState + */ + History.getStateString = function(passedState){ + // Prepare + var State, cleanedState, str; + + // Fetch + State = History.normalizeState(passedState); + + // Clean + cleanedState = { + data: State.data, + title: passedState.title, + url: passedState.url + }; + + // Fetch + str = JSON.stringify(cleanedState); + + // Return + return str; + }; + + /** + * Get a State's ID + * @param {State} passedState + * @return {String} id + */ + History.getStateId = function(passedState){ + // Prepare + var State, id; + + // Fetch + State = History.normalizeState(passedState); + + // Fetch + id = State.id; + + // Return + return id; + }; + + /** + * History.getHashByState(State) + * Creates a Hash for the State Object + * @param {State} passedState + * @return {String} hash + */ + History.getHashByState = function(passedState){ + // Prepare + var State, hash; + + // Fetch + State = History.normalizeState(passedState); + + // Hash + hash = State.hash; + + // Return + return hash; + }; + + /** + * History.extractId(url_or_hash) + * Get a State ID by it's URL or Hash + * @param {string} url_or_hash + * @return {string} id + */ + History.extractId = function ( url_or_hash ) { + // Prepare + var id,parts,url, tmp; + + // Extract + + // If the URL has a #, use the id from before the # + if (url_or_hash.indexOf('#') != -1) + { + tmp = url_or_hash.split("#")[0]; + } + else + { + tmp = url_or_hash; + } + + parts = /(.*)\&_suid=([0-9]+)$/.exec(tmp); + url = parts ? (parts[1]||url_or_hash) : url_or_hash; + id = parts ? String(parts[2]||'') : ''; + + // Return + return id||false; + }; + + /** + * History.isTraditionalAnchor + * Checks to see if the url is a traditional anchor or not + * @param {String} url_or_hash + * @return {Boolean} + */ + History.isTraditionalAnchor = function(url_or_hash){ + // Check + var isTraditional = !(/[\/\?\.]/.test(url_or_hash)); + + // Return + return isTraditional; + }; + + /** + * History.extractState + * Get a State by it's URL or Hash + * @param {String} url_or_hash + * @return {State|null} + */ + History.extractState = function(url_or_hash,create){ + // Prepare + var State = null, id, url; + create = create||false; + + // Fetch SUID + id = History.extractId(url_or_hash); + if ( id ) { + State = History.getStateById(id); + } + + // Fetch SUID returned no State + if ( !State ) { + // Fetch URL + url = History.getFullUrl(url_or_hash); + + // Check URL + id = History.getIdByUrl(url)||false; + if ( id ) { + State = History.getStateById(id); + } + + // Create State + if ( !State && create && !History.isTraditionalAnchor(url_or_hash) ) { + State = History.createStateObject(null,null,url); + } + } + + // Return + return State; + }; + + /** + * History.getIdByUrl() + * Get a State ID by a State URL + */ + History.getIdByUrl = function(url){ + // Fetch + var id = History.urlToId[url] || History.store.urlToId[url] || undefined; + + // Return + return id; + }; + + /** + * History.getLastSavedState() + * Get an object containing the data, title and url of the current state + * @return {Object} State + */ + History.getLastSavedState = function(){ + return History.savedStates[History.savedStates.length-1]||undefined; + }; + + /** + * History.getLastStoredState() + * Get an object containing the data, title and url of the current state + * @return {Object} State + */ + History.getLastStoredState = function(){ + return History.storedStates[History.storedStates.length-1]||undefined; + }; + + /** + * History.hasUrlDuplicate + * Checks if a Url will have a url conflict + * @param {Object} newState + * @return {Boolean} hasDuplicate + */ + History.hasUrlDuplicate = function(newState) { + // Prepare + var hasDuplicate = false, + oldState; + + // Fetch + oldState = History.extractState(newState.url); + + // Check + hasDuplicate = oldState && oldState.id !== newState.id; + + // Return + return hasDuplicate; + }; + + /** + * History.storeState + * Store a State + * @param {Object} newState + * @return {Object} newState + */ + History.storeState = function(newState){ + // Store the State + History.urlToId[newState.url] = newState.id; + + // Push the State + History.storedStates.push(History.cloneObject(newState)); + + // Return newState + return newState; + }; + + /** + * History.isLastSavedState(newState) + * Tests to see if the state is the last state + * @param {Object} newState + * @return {boolean} isLast + */ + History.isLastSavedState = function(newState){ + // Prepare + var isLast = false, + newId, oldState, oldId; + + // Check + if ( History.savedStates.length ) { + newId = newState.id; + oldState = History.getLastSavedState(); + oldId = oldState.id; + + // Check + isLast = (newId === oldId); + } + + // Return + return isLast; + }; + + /** + * History.saveState + * Push a State + * @param {Object} newState + * @return {boolean} changed + */ + History.saveState = function(newState){ + // Check Hash + if ( History.isLastSavedState(newState) ) { + return false; + } + + // Push the State + History.savedStates.push(History.cloneObject(newState)); + + // Return true + return true; + }; + + /** + * History.getStateByIndex() + * Gets a state by the index + * @param {integer} index + * @return {Object} + */ + History.getStateByIndex = function(index){ + // Prepare + var State = null; + + // Handle + if ( typeof index === 'undefined' ) { + // Get the last inserted + State = History.savedStates[History.savedStates.length-1]; + } + else if ( index < 0 ) { + // Get from the end + State = History.savedStates[History.savedStates.length+index]; + } + else { + // Get from the beginning + State = History.savedStates[index]; + } + + // Return State + return State; + }; + + /** + * History.getCurrentIndex() + * Gets the current index + * @return (integer) + */ + History.getCurrentIndex = function(){ + // Prepare + var index = null; + + // No states saved + if(History.savedStates.length < 1) { + index = 0; + } + else { + index = History.savedStates.length-1; + } + return index; + }; + + // ==================================================================== + // Hash Helpers + + /** + * History.getHash() + * @param {Location=} location + * Gets the current document hash + * Note: unlike location.hash, this is guaranteed to return the escaped hash in all browsers + * @return {string} + */ + History.getHash = function(doc){ + var url = History.getLocationHref(doc), + hash; + hash = History.getHashByUrl(url); + return hash; + }; + + /** + * History.unescapeHash() + * normalize and Unescape a Hash + * @param {String} hash + * @return {string} + */ + History.unescapeHash = function(hash){ + // Prepare + var result = History.normalizeHash(hash); + + // Unescape hash + result = decodeURIComponent(result); + + // Return result + return result; + }; + + /** + * History.normalizeHash() + * normalize a hash across browsers + * @return {string} + */ + History.normalizeHash = function(hash){ + // Prepare + var result = hash.replace(/[^#]*#/,'').replace(/#.*/, ''); + + // Return result + return result; + }; + + /** + * History.setHash(hash) + * Sets the document hash + * @param {string} hash + * @return {History} + */ + History.setHash = function(hash,queue){ + // Prepare + var State, pageUrl; + + // Handle Queueing + if ( queue !== false && History.busy() ) { + // Wait + Push to Queue + //History.debug('History.setHash: we must wait', arguments); + History.pushQueue({ + scope: History, + callback: History.setHash, + args: arguments, + queue: queue + }); + return false; + } + + // Log + //History.debug('History.setHash: called',hash); + + // Make Busy + Continue + History.busy(true); + + // Check if hash is a state + State = History.extractState(hash,true); + if ( State && !History.emulated.pushState ) { + // Hash is a state so skip the setHash + //History.debug('History.setHash: Hash is a state so skipping the hash set with a direct pushState call',arguments); + + // PushState + History.pushState(State.data,State.title,State.url,false); + } + else if ( History.getHash() !== hash ) { + // Hash is a proper hash, so apply it + + // Handle browser bugs + if ( History.bugs.setHash ) { + // Fix Safari Bug https://bugs.webkit.org/show_bug.cgi?id=56249 + + // Fetch the base page + pageUrl = History.getPageUrl(); + + // Safari hash apply + History.pushState(null,null,pageUrl+'#'+hash,false); + } + else { + // Normal hash apply + document.location.hash = hash; + } + } + + // Chain + return History; + }; + + /** + * History.escape() + * normalize and Escape a Hash + * @return {string} + */ + History.escapeHash = function(hash){ + // Prepare + var result = History.normalizeHash(hash); + + // Escape hash + result = window.encodeURIComponent(result); + + // IE6 Escape Bug + if ( !History.bugs.hashEscape ) { + // Restore common parts + result = result + .replace(/\%21/g,'!') + .replace(/\%26/g,'&') + .replace(/\%3D/g,'=') + .replace(/\%3F/g,'?'); + } + + // Return result + return result; + }; + + /** + * History.getHashByUrl(url) + * Extracts the Hash from a URL + * @param {string} url + * @return {string} url + */ + History.getHashByUrl = function(url){ + // Extract the hash + var hash = String(url) + .replace(/([^#]*)#?([^#]*)#?(.*)/, '$2') + ; + + // Unescape hash + hash = History.unescapeHash(hash); + + // Return hash + return hash; + }; + + /** + * History.setTitle(title) + * Applies the title to the document + * @param {State} newState + * @return {Boolean} + */ + History.setTitle = function(newState){ + // Prepare + var title = newState.title, + firstState; + + // Initial + if ( !title ) { + firstState = History.getStateByIndex(0); + if ( firstState && firstState.url === newState.url ) { + title = firstState.title||History.options.initialTitle; + } + } + + // Apply + try { + document.getElementsByTagName('title')[0].innerHTML = title.replace('<','<').replace('>','>').replace(' & ',' & '); + } + catch ( Exception ) { } + document.title = title; + + // Chain + return History; + }; + + + // ==================================================================== + // Queueing + + /** + * History.queues + * The list of queues to use + * First In, First Out + */ + History.queues = []; + + /** + * History.busy(value) + * @param {boolean} value [optional] + * @return {boolean} busy + */ + History.busy = function(value){ + // Apply + if ( typeof value !== 'undefined' ) { + //History.debug('History.busy: changing ['+(History.busy.flag||false)+'] to ['+(value||false)+']', History.queues.length); + History.busy.flag = value; + } + // Default + else if ( typeof History.busy.flag === 'undefined' ) { + History.busy.flag = false; + } + + // Queue + if ( !History.busy.flag ) { + // Execute the next item in the queue + clearTimeout(History.busy.timeout); + var fireNext = function(){ + var i, queue, item; + if ( History.busy.flag ) return; + for ( i=History.queues.length-1; i >= 0; --i ) { + queue = History.queues[i]; + if ( queue.length === 0 ) continue; + item = queue.shift(); + History.fireQueueItem(item); + History.busy.timeout = setTimeout(fireNext,History.options.busyDelay); + } + }; + History.busy.timeout = setTimeout(fireNext,History.options.busyDelay); + } + + // Return + return History.busy.flag; + }; + + /** + * History.busy.flag + */ + History.busy.flag = false; + + /** + * History.fireQueueItem(item) + * Fire a Queue Item + * @param {Object} item + * @return {Mixed} result + */ + History.fireQueueItem = function(item){ + return item.callback.apply(item.scope||History,item.args||[]); + }; + + /** + * History.pushQueue(callback,args) + * Add an item to the queue + * @param {Object} item [scope,callback,args,queue] + */ + History.pushQueue = function(item){ + // Prepare the queue + History.queues[item.queue||0] = History.queues[item.queue||0]||[]; + + // Add to the queue + History.queues[item.queue||0].push(item); + + // Chain + return History; + }; + + /** + * History.queue (item,queue), (func,queue), (func), (item) + * Either firs the item now if not busy, or adds it to the queue + */ + History.queue = function(item,queue){ + // Prepare + if ( typeof item === 'function' ) { + item = { + callback: item + }; + } + if ( typeof queue !== 'undefined' ) { + item.queue = queue; + } + + // Handle + if ( History.busy() ) { + History.pushQueue(item); + } else { + History.fireQueueItem(item); + } + + // Chain + return History; + }; + + /** + * History.clearQueue() + * Clears the Queue + */ + History.clearQueue = function(){ + History.busy.flag = false; + History.queues = []; + return History; + }; + + + // ==================================================================== + // IE Bug Fix + + /** + * History.stateChanged + * States whether or not the state has changed since the last double check was initialised + */ + History.stateChanged = false; + + /** + * History.doubleChecker + * Contains the timeout used for the double checks + */ + History.doubleChecker = false; + + /** + * History.doubleCheckComplete() + * Complete a double check + * @return {History} + */ + History.doubleCheckComplete = function(){ + // Update + History.stateChanged = true; + + // Clear + History.doubleCheckClear(); + + // Chain + return History; + }; + + /** + * History.doubleCheckClear() + * Clear a double check + * @return {History} + */ + History.doubleCheckClear = function(){ + // Clear + if ( History.doubleChecker ) { + clearTimeout(History.doubleChecker); + History.doubleChecker = false; + } + + // Chain + return History; + }; + + /** + * History.doubleCheck() + * Create a double check + * @return {History} + */ + History.doubleCheck = function(tryAgain){ + // Reset + History.stateChanged = false; + History.doubleCheckClear(); + + // Fix IE6,IE7 bug where calling history.back or history.forward does not actually change the hash (whereas doing it manually does) + // Fix Safari 5 bug where sometimes the state does not change: https://bugs.webkit.org/show_bug.cgi?id=42940 + if ( History.bugs.ieDoubleCheck ) { + // Apply Check + History.doubleChecker = setTimeout( + function(){ + History.doubleCheckClear(); + if ( !History.stateChanged ) { + //History.debug('History.doubleCheck: State has not yet changed, trying again', arguments); + // Re-Attempt + tryAgain(); + } + return true; + }, + History.options.doubleCheckInterval + ); + } + + // Chain + return History; + }; + + + // ==================================================================== + // Safari Bug Fix + + /** + * History.safariStatePoll() + * Poll the current state + * @return {History} + */ + History.safariStatePoll = function(){ + // Poll the URL + + // Get the Last State which has the new URL + var + urlState = History.extractState(History.getLocationHref()), + newState; + + // Check for a difference + if ( !History.isLastSavedState(urlState) ) { + newState = urlState; + } + else { + return; + } + + // Check if we have a state with that url + // If not create it + if ( !newState ) { + //History.debug('History.safariStatePoll: new'); + newState = History.createStateObject(); + } + + // Apply the New State + //History.debug('History.safariStatePoll: trigger'); + History.Adapter.trigger(window,'popstate'); + + // Chain + return History; + }; + + + // ==================================================================== + // State Aliases + + /** + * History.back(queue) + * Send the browser history back one item + * @param {Integer} queue [optional] + */ + History.back = function(queue){ + //History.debug('History.back: called', arguments); + + // Handle Queueing + if ( queue !== false && History.busy() ) { + // Wait + Push to Queue + //History.debug('History.back: we must wait', arguments); + History.pushQueue({ + scope: History, + callback: History.back, + args: arguments, + queue: queue + }); + return false; + } + + // Make Busy + Continue + History.busy(true); + + // Fix certain browser bugs that prevent the state from changing + History.doubleCheck(function(){ + History.back(false); + }); + + // Go back + history.go(-1); + + // End back closure + return true; + }; + + /** + * History.forward(queue) + * Send the browser history forward one item + * @param {Integer} queue [optional] + */ + History.forward = function(queue){ + //History.debug('History.forward: called', arguments); + + // Handle Queueing + if ( queue !== false && History.busy() ) { + // Wait + Push to Queue + //History.debug('History.forward: we must wait', arguments); + History.pushQueue({ + scope: History, + callback: History.forward, + args: arguments, + queue: queue + }); + return false; + } + + // Make Busy + Continue + History.busy(true); + + // Fix certain browser bugs that prevent the state from changing + History.doubleCheck(function(){ + History.forward(false); + }); + + // Go forward + history.go(1); + + // End forward closure + return true; + }; + + /** + * History.go(index,queue) + * Send the browser history back or forward index times + * @param {Integer} queue [optional] + */ + History.go = function(index,queue){ + //History.debug('History.go: called', arguments); + + // Prepare + var i; + + // Handle + if ( index > 0 ) { + // Forward + for ( i=1; i<=index; ++i ) { + History.forward(queue); + } + } + else if ( index < 0 ) { + // Backward + for ( i=-1; i>=index; --i ) { + History.back(queue); + } + } + else { + throw new Error('History.go: History.go requires a positive or negative integer passed.'); + } + + // Chain + return History; + }; + + + // ==================================================================== + // HTML5 State Support + + // Non-Native pushState Implementation + if ( History.emulated.pushState ) { + /* + * Provide Skeleton for HTML4 Browsers + */ + + // Prepare + var emptyFunction = function(){}; + History.pushState = History.pushState||emptyFunction; + History.replaceState = History.replaceState||emptyFunction; + } // History.emulated.pushState + + // Native pushState Implementation + else { + /* + * Use native HTML5 History API Implementation + */ + + /** + * History.onPopState(event,extra) + * Refresh the Current State + */ + History.onPopState = function(event,extra){ + // Prepare + var stateId = false, newState = false, currentHash, currentState; + + // Reset the double check + History.doubleCheckComplete(); + + // Check for a Hash, and handle apporiatly + currentHash = History.getHash(); + if ( currentHash ) { + // Expand Hash + currentState = History.extractState(currentHash||History.getLocationHref(),true); + if ( currentState ) { + // We were able to parse it, it must be a State! + // Let's forward to replaceState + //History.debug('History.onPopState: state anchor', currentHash, currentState); + History.replaceState(currentState.data, currentState.title, currentState.url, false); + } + else { + // Traditional Anchor + //History.debug('History.onPopState: traditional anchor', currentHash); + History.Adapter.trigger(window,'anchorchange'); + History.busy(false); + } + + // We don't care for hashes + History.expectedStateId = false; + return false; + } + + // Ensure + stateId = History.Adapter.extractEventData('state',event,extra) || false; + + // Fetch State + if ( stateId ) { + // Vanilla: Back/forward button was used + newState = History.getStateById(stateId); + } + else if ( History.expectedStateId ) { + // Vanilla: A new state was pushed, and popstate was called manually + newState = History.getStateById(History.expectedStateId); + } + else { + // Initial State + newState = History.extractState(History.getLocationHref()); + } + + // The State did not exist in our store + if ( !newState ) { + // Regenerate the State + newState = History.createStateObject(null,null,History.getLocationHref()); + } + + // Clean + History.expectedStateId = false; + + // Check if we are the same state + if ( History.isLastSavedState(newState) ) { + // There has been no change (just the page's hash has finally propagated) + //History.debug('History.onPopState: no change', newState, History.savedStates); + History.busy(false); + return false; + } + + // Store the State + History.storeState(newState); + History.saveState(newState); + + // Force update of the title + History.setTitle(newState); + + // Fire Our Event + History.Adapter.trigger(window,'statechange'); + History.busy(false); + + // Return true + return true; + }; + History.Adapter.bind(window,'popstate',History.onPopState); + + /** + * History.pushState(data,title,url) + * Add a new State to the history object, become it, and trigger onpopstate + * We have to trigger for HTML4 compatibility + * @param {object} data + * @param {string} title + * @param {string} url + * @return {true} + */ + History.pushState = function(data,title,url,queue){ + //History.debug('History.pushState: called', arguments); + + // Check the State + if ( History.getHashByUrl(url) && History.emulated.pushState ) { + throw new Error('History.js does not support states with fragement-identifiers (hashes/anchors).'); + } + + // Handle Queueing + if ( queue !== false && History.busy() ) { + // Wait + Push to Queue + //History.debug('History.pushState: we must wait', arguments); + History.pushQueue({ + scope: History, + callback: History.pushState, + args: arguments, + queue: queue + }); + return false; + } + + // Make Busy + Continue + History.busy(true); + + // Create the newState + var newState = History.createStateObject(data,title,url); + + // Check it + if ( History.isLastSavedState(newState) ) { + // Won't be a change + History.busy(false); + } + else { + // Store the newState + History.storeState(newState); + History.expectedStateId = newState.id; + + // Push the newState + history.pushState(newState.id,newState.title,newState.url); + + // Fire HTML5 Event + History.Adapter.trigger(window,'popstate'); + } + + // End pushState closure + return true; + }; + + /** + * History.replaceState(data,title,url) + * Replace the State and trigger onpopstate + * We have to trigger for HTML4 compatibility + * @param {object} data + * @param {string} title + * @param {string} url + * @return {true} + */ + History.replaceState = function(data,title,url,queue){ + //History.debug('History.replaceState: called', arguments); + + // Check the State + if ( History.getHashByUrl(url) && History.emulated.pushState ) { + throw new Error('History.js does not support states with fragement-identifiers (hashes/anchors).'); + } + + // Handle Queueing + if ( queue !== false && History.busy() ) { + // Wait + Push to Queue + //History.debug('History.replaceState: we must wait', arguments); + History.pushQueue({ + scope: History, + callback: History.replaceState, + args: arguments, + queue: queue + }); + return false; + } + + // Make Busy + Continue + History.busy(true); + + // Create the newState + var newState = History.createStateObject(data,title,url); + + // Check it + if ( History.isLastSavedState(newState) ) { + // Won't be a change + History.busy(false); + } + else { + // Store the newState + History.storeState(newState); + History.expectedStateId = newState.id; + + // Push the newState + history.replaceState(newState.id,newState.title,newState.url); + + // Fire HTML5 Event + History.Adapter.trigger(window,'popstate'); + } + + // End replaceState closure + return true; + }; + + } // !History.emulated.pushState + + + // ==================================================================== + // Initialise + + /** + * Load the Store + */ + if ( sessionStorage ) { + // Fetch + try { + History.store = JSON.parse(sessionStorage.getItem('History.store'))||{}; + } + catch ( err ) { + History.store = {}; + } + + // Normalize + History.normalizeStore(); + } + else { + // Default Load + History.store = {}; + History.normalizeStore(); + } + + /** + * Clear Intervals on exit to prevent memory leaks + */ + History.Adapter.bind(window,"unload",History.clearAllIntervals); + + /** + * Create the initial State + */ + History.saveState(History.storeState(History.extractState(History.getLocationHref(),true))); + + /** + * Bind for Saving Store + */ + if ( sessionStorage ) { + // When the page is closed + History.onUnload = function(){ + // Prepare + var currentStore, item, currentStoreString; + + // Fetch + try { + currentStore = JSON.parse(sessionStorage.getItem('History.store'))||{}; + } + catch ( err ) { + currentStore = {}; + } + + // Ensure + currentStore.idToState = currentStore.idToState || {}; + currentStore.urlToId = currentStore.urlToId || {}; + currentStore.stateToId = currentStore.stateToId || {}; + + // Sync + for ( item in History.idToState ) { + if ( !History.idToState.hasOwnProperty(item) ) { + continue; + } + currentStore.idToState[item] = History.idToState[item]; + } + for ( item in History.urlToId ) { + if ( !History.urlToId.hasOwnProperty(item) ) { + continue; + } + currentStore.urlToId[item] = History.urlToId[item]; + } + for ( item in History.stateToId ) { + if ( !History.stateToId.hasOwnProperty(item) ) { + continue; + } + currentStore.stateToId[item] = History.stateToId[item]; + } + + // Update + History.store = currentStore; + History.normalizeStore(); + + // In Safari, going into Private Browsing mode causes the + // Session Storage object to still exist but if you try and use + // or set any property/function of it it throws the exception + // "QUOTA_EXCEEDED_ERR: DOM Exception 22: An attempt was made to + // add something to storage that exceeded the quota." infinitely + // every second. + currentStoreString = JSON.stringify(currentStore); + try { + // Store + sessionStorage.setItem('History.store', currentStoreString); + } + catch (e) { + if (e.code === DOMException.QUOTA_EXCEEDED_ERR) { + if (sessionStorage.length) { + // Workaround for a bug seen on iPads. Sometimes the quota exceeded error comes up and simply + // removing/resetting the storage can work. + sessionStorage.removeItem('History.store'); + sessionStorage.setItem('History.store', currentStoreString); + } else { + // Otherwise, we're probably private browsing in Safari, so we'll ignore the exception. + } + } else { + throw e; + } + } + }; + + // For Internet Explorer + History.intervalList.push(setInterval(History.onUnload,History.options.storeInterval)); + + // For Other Browsers + History.Adapter.bind(window,'beforeunload',History.onUnload); + History.Adapter.bind(window,'unload',History.onUnload); + + // Both are enabled for consistency + } + + // Non-Native pushState Implementation + if ( !History.emulated.pushState ) { + // Be aware, the following is only for native pushState implementations + // If you are wanting to include something for all browsers + // Then include it above this if block + + /** + * Setup Safari Fix + */ + if ( History.bugs.safariPoll ) { + History.intervalList.push(setInterval(History.safariStatePoll, History.options.safariPollInterval)); + } + + /** + * Ensure Cross Browser Compatibility + */ + if ( navigator.vendor === 'Apple Computer, Inc.' || (navigator.appCodeName||'') === 'Mozilla' ) { + /** + * Fix Safari HashChange Issue + */ + + // Setup Alias + History.Adapter.bind(window,'hashchange',function(){ + History.Adapter.trigger(window,'popstate'); + }); + + // Initialise Alias + if ( History.getHash() ) { + History.Adapter.onDomLoad(function(){ + History.Adapter.trigger(window,'hashchange'); + }); + } + } + + } // !History.emulated.pushState + + + }; // History.initCore + + // Try to Initialise History + if (!History.options || !History.options.delayInit) { + History.init(); + } + +})(window); diff --git a/sites/all/themes/gui/materiobasetheme/bower_components/history.js/scripts/bundled-uncompressed/html4+html5/native.history.js b/sites/all/themes/gui/materiobasetheme/bower_components/history.js/scripts/bundled-uncompressed/html4+html5/native.history.js new file mode 100644 index 00000000..fe39c496 --- /dev/null +++ b/sites/all/themes/gui/materiobasetheme/bower_components/history.js/scripts/bundled-uncompressed/html4+html5/native.history.js @@ -0,0 +1,3335 @@ +/* + json2.js + 2012-10-08 + + Public Domain. + + NO WARRANTY EXPRESSED OR IMPLIED. USE AT YOUR OWN RISK. + + See http://www.JSON.org/js.html + + + This code should be minified before deployment. + See http://javascript.crockford.com/jsmin.html + + USE YOUR OWN COPY. IT IS EXTREMELY UNWISE TO LOAD CODE FROM SERVERS YOU DO + NOT CONTROL. + + + This file creates a global JSON object containing two methods: stringify + and parse. + + JSON.stringify(value, replacer, space) + value any JavaScript value, usually an object or array. + + replacer an optional parameter that determines how object + values are stringified for objects. It can be a + function or an array of strings. + + space an optional parameter that specifies the indentation + of nested structures. If it is omitted, the text will + be packed without extra whitespace. If it is a number, + it will specify the number of spaces to indent at each + level. If it is a string (such as '\t' or ' '), + it contains the characters used to indent at each level. + + This method produces a JSON text from a JavaScript value. + + When an object value is found, if the object contains a toJSON + method, its toJSON method will be called and the result will be + stringified. A toJSON method does not serialize: it returns the + value represented by the name/value pair that should be serialized, + or undefined if nothing should be serialized. The toJSON method + will be passed the key associated with the value, and this will be + bound to the value + + For example, this would serialize Dates as ISO strings. + + Date.prototype.toJSON = function (key) { + function f(n) { + // Format integers to have at least two digits. + return n < 10 ? '0' + n : n; + } + + return this.getUTCFullYear() + '-' + + f(this.getUTCMonth() + 1) + '-' + + f(this.getUTCDate()) + 'T' + + f(this.getUTCHours()) + ':' + + f(this.getUTCMinutes()) + ':' + + f(this.getUTCSeconds()) + 'Z'; + }; + + You can provide an optional replacer method. It will be passed the + key and value of each member, with this bound to the containing + object. The value that is returned from your method will be + serialized. If your method returns undefined, then the member will + be excluded from the serialization. + + If the replacer parameter is an array of strings, then it will be + used to select the members to be serialized. It filters the results + such that only members with keys listed in the replacer array are + stringified. + + Values that do not have JSON representations, such as undefined or + functions, will not be serialized. Such values in objects will be + dropped; in arrays they will be replaced with null. You can use + a replacer function to replace those with JSON values. + JSON.stringify(undefined) returns undefined. + + The optional space parameter produces a stringification of the + value that is filled with line breaks and indentation to make it + easier to read. + + If the space parameter is a non-empty string, then that string will + be used for indentation. If the space parameter is a number, then + the indentation will be that many spaces. + + Example: + + text = JSON.stringify(['e', {pluribus: 'unum'}]); + // text is '["e",{"pluribus":"unum"}]' + + + text = JSON.stringify(['e', {pluribus: 'unum'}], null, '\t'); + // text is '[\n\t"e",\n\t{\n\t\t"pluribus": "unum"\n\t}\n]' + + text = JSON.stringify([new Date()], function (key, value) { + return this[key] instanceof Date ? + 'Date(' + this[key] + ')' : value; + }); + // text is '["Date(---current time---)"]' + + + JSON.parse(text, reviver) + This method parses a JSON text to produce an object or array. + It can throw a SyntaxError exception. + + The optional reviver parameter is a function that can filter and + transform the results. It receives each of the keys and values, + and its return value is used instead of the original value. + If it returns what it received, then the structure is not modified. + If it returns undefined then the member is deleted. + + Example: + + // Parse the text. Values that look like ISO date strings will + // be converted to Date objects. + + myData = JSON.parse(text, function (key, value) { + var a; + if (typeof value === 'string') { + a = +/^(\d{4})-(\d{2})-(\d{2})T(\d{2}):(\d{2}):(\d{2}(?:\.\d*)?)Z$/.exec(value); + if (a) { + return new Date(Date.UTC(+a[1], +a[2] - 1, +a[3], +a[4], + +a[5], +a[6])); + } + } + return value; + }); + + myData = JSON.parse('["Date(09/09/2001)"]', function (key, value) { + var d; + if (typeof value === 'string' && + value.slice(0, 5) === 'Date(' && + value.slice(-1) === ')') { + d = new Date(value.slice(5, -1)); + if (d) { + return d; + } + } + return value; + }); + + + This is a reference implementation. You are free to copy, modify, or + redistribute. +*/ + +/*jslint evil: true, regexp: true */ + +/*members "", "\b", "\t", "\n", "\f", "\r", "\"", JSON, "\\", apply, + call, charCodeAt, getUTCDate, getUTCFullYear, getUTCHours, + getUTCMinutes, getUTCMonth, getUTCSeconds, hasOwnProperty, join, + lastIndex, length, parse, prototype, push, replace, slice, stringify, + test, toJSON, toString, valueOf +*/ + + +// Create a JSON object only if one does not already exist. We create the +// methods in a closure to avoid creating global variables. + +if (typeof JSON !== 'object') { + JSON = {}; +} + +(function () { + 'use strict'; + + function f(n) { + // Format integers to have at least two digits. + return n < 10 ? '0' + n : n; + } + + if (typeof Date.prototype.toJSON !== 'function') { + + Date.prototype.toJSON = function (key) { + + return isFinite(this.valueOf()) + ? this.getUTCFullYear() + '-' + + f(this.getUTCMonth() + 1) + '-' + + f(this.getUTCDate()) + 'T' + + f(this.getUTCHours()) + ':' + + f(this.getUTCMinutes()) + ':' + + f(this.getUTCSeconds()) + 'Z' + : null; + }; + + String.prototype.toJSON = + Number.prototype.toJSON = + Boolean.prototype.toJSON = function (key) { + return this.valueOf(); + }; + } + + var cx = /[\u0000\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g, + escapable = /[\\\"\x00-\x1f\x7f-\x9f\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g, + gap, + indent, + meta = { // table of character substitutions + '\b': '\\b', + '\t': '\\t', + '\n': '\\n', + '\f': '\\f', + '\r': '\\r', + '"' : '\\"', + '\\': '\\\\' + }, + rep; + + + function quote(string) { + +// If the string contains no control characters, no quote characters, and no +// backslash characters, then we can safely slap some quotes around it. +// Otherwise we must also replace the offending characters with safe escape +// sequences. + + escapable.lastIndex = 0; + return escapable.test(string) ? '"' + string.replace(escapable, function (a) { + var c = meta[a]; + return typeof c === 'string' + ? c + : '\\u' + ('0000' + a.charCodeAt(0).toString(16)).slice(-4); + }) + '"' : '"' + string + '"'; + } + + + function str(key, holder) { + +// Produce a string from holder[key]. + + var i, // The loop counter. + k, // The member key. + v, // The member value. + length, + mind = gap, + partial, + value = holder[key]; + +// If the value has a toJSON method, call it to obtain a replacement value. + + if (value && typeof value === 'object' && + typeof value.toJSON === 'function') { + value = value.toJSON(key); + } + +// If we were called with a replacer function, then call the replacer to +// obtain a replacement value. + + if (typeof rep === 'function') { + value = rep.call(holder, key, value); + } + +// What happens next depends on the value's type. + + switch (typeof value) { + case 'string': + return quote(value); + + case 'number': + +// JSON numbers must be finite. Encode non-finite numbers as null. + + return isFinite(value) ? String(value) : 'null'; + + case 'boolean': + case 'null': + +// If the value is a boolean or null, convert it to a string. Note: +// typeof null does not produce 'null'. The case is included here in +// the remote chance that this gets fixed someday. + + return String(value); + +// If the type is 'object', we might be dealing with an object or an array or +// null. + + case 'object': + +// Due to a specification blunder in ECMAScript, typeof null is 'object', +// so watch out for that case. + + if (!value) { + return 'null'; + } + +// Make an array to hold the partial results of stringifying this object value. + + gap += indent; + partial = []; + +// Is the value an array? + + if (Object.prototype.toString.apply(value) === '[object Array]') { + +// The value is an array. Stringify every element. Use null as a placeholder +// for non-JSON values. + + length = value.length; + for (i = 0; i < length; i += 1) { + partial[i] = str(i, value) || 'null'; + } + +// Join all of the elements together, separated with commas, and wrap them in +// brackets. + + v = partial.length === 0 + ? '[]' + : gap + ? '[\n' + gap + partial.join(',\n' + gap) + '\n' + mind + ']' + : '[' + partial.join(',') + ']'; + gap = mind; + return v; + } + +// If the replacer is an array, use it to select the members to be stringified. + + if (rep && typeof rep === 'object') { + length = rep.length; + for (i = 0; i < length; i += 1) { + if (typeof rep[i] === 'string') { + k = rep[i]; + v = str(k, value); + if (v) { + partial.push(quote(k) + (gap ? ': ' : ':') + v); + } + } + } + } else { + +// Otherwise, iterate through all of the keys in the object. + + for (k in value) { + if (Object.prototype.hasOwnProperty.call(value, k)) { + v = str(k, value); + if (v) { + partial.push(quote(k) + (gap ? ': ' : ':') + v); + } + } + } + } + +// Join all of the member texts together, separated with commas, +// and wrap them in braces. + + v = partial.length === 0 + ? '{}' + : gap + ? '{\n' + gap + partial.join(',\n' + gap) + '\n' + mind + '}' + : '{' + partial.join(',') + '}'; + gap = mind; + return v; + } + } + +// If the JSON object does not yet have a stringify method, give it one. + + if (typeof JSON.stringify !== 'function') { + JSON.stringify = function (value, replacer, space) { + +// The stringify method takes a value and an optional replacer, and an optional +// space parameter, and returns a JSON text. The replacer can be a function +// that can replace values, or an array of strings that will select the keys. +// A default replacer method can be provided. Use of the space parameter can +// produce text that is more easily readable. + + var i; + gap = ''; + indent = ''; + +// If the space parameter is a number, make an indent string containing that +// many spaces. + + if (typeof space === 'number') { + for (i = 0; i < space; i += 1) { + indent += ' '; + } + +// If the space parameter is a string, it will be used as the indent string. + + } else if (typeof space === 'string') { + indent = space; + } + +// If there is a replacer, it must be a function or an array. +// Otherwise, throw an error. + + rep = replacer; + if (replacer && typeof replacer !== 'function' && + (typeof replacer !== 'object' || + typeof replacer.length !== 'number')) { + throw new Error('JSON.stringify'); + } + +// Make a fake root object containing our value under the key of ''. +// Return the result of stringifying the value. + + return str('', {'': value}); + }; + } + + +// If the JSON object does not yet have a parse method, give it one. + + if (typeof JSON.parse !== 'function') { + JSON.parse = function (text, reviver) { + +// The parse method takes a text and an optional reviver function, and returns +// a JavaScript value if the text is a valid JSON text. + + var j; + + function walk(holder, key) { + +// The walk method is used to recursively walk the resulting structure so +// that modifications can be made. + + var k, v, value = holder[key]; + if (value && typeof value === 'object') { + for (k in value) { + if (Object.prototype.hasOwnProperty.call(value, k)) { + v = walk(value, k); + if (v !== undefined) { + value[k] = v; + } else { + delete value[k]; + } + } + } + } + return reviver.call(holder, key, value); + } + + +// Parsing happens in four stages. In the first stage, we replace certain +// Unicode characters with escape sequences. JavaScript handles many characters +// incorrectly, either silently deleting them, or treating them as line endings. + + text = String(text); + cx.lastIndex = 0; + if (cx.test(text)) { + text = text.replace(cx, function (a) { + return '\\u' + + ('0000' + a.charCodeAt(0).toString(16)).slice(-4); + }); + } + +// In the second stage, we run the text against regular expressions that look +// for non-JSON patterns. We are especially concerned with '()' and 'new' +// because they can cause invocation, and '=' because it can cause mutation. +// But just to be safe, we want to reject all unexpected forms. + +// We split the second stage into 4 regexp operations in order to work around +// crippling inefficiencies in IE's and Safari's regexp engines. First we +// replace the JSON backslash pairs with '@' (a non-JSON character). Second, we +// replace all simple value tokens with ']' characters. Third, we delete all +// open brackets that follow a colon or comma or that begin the text. Finally, +// we look to see that the remaining characters are only whitespace or ']' or +// ',' or ':' or '{' or '}'. If that is so, then the text is safe for eval. + + if (/^[\],:{}\s]*$/ + .test(text.replace(/\\(?:["\\\/bfnrt]|u[0-9a-fA-F]{4})/g, '@') + .replace(/"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g, ']') + .replace(/(?:^|:|,)(?:\s*\[)+/g, ''))) { + +// In the third stage we use the eval function to compile the text into a +// JavaScript structure. The '{' operator is subject to a syntactic ambiguity +// in JavaScript: it can begin a block or an object literal. We wrap the text +// in parens to eliminate the ambiguity. + + j = eval('(' + text + ')'); + +// In the optional fourth stage, we recursively walk the new structure, passing +// each name/value pair to a reviver function for possible transformation. + + return typeof reviver === 'function' + ? walk({'': j}, '') + : j; + } + +// If the text is not JSON parseable, then a SyntaxError is thrown. + + throw new SyntaxError('JSON.parse'); + }; + } +}());/** + * History.js Native Adapter + * @author Benjamin Arthur Lupton + * @copyright 2010-2011 Benjamin Arthur Lupton + * @license New BSD License + */ + +// Closure +(function(window,undefined){ + "use strict"; + + // Localise Globals + var History = window.History = window.History||{}; + + // Check Existence + if ( typeof History.Adapter !== 'undefined' ) { + throw new Error('History.js Adapter has already been loaded...'); + } + + // Add the Adapter + History.Adapter = { + /** + * History.Adapter.handlers[uid][eventName] = Array + */ + handlers: {}, + + /** + * History.Adapter._uid + * The current element unique identifier + */ + _uid: 1, + + /** + * History.Adapter.uid(element) + * @param {Element} element + * @return {String} uid + */ + uid: function(element){ + return element._uid || (element._uid = History.Adapter._uid++); + }, + + /** + * History.Adapter.bind(el,event,callback) + * @param {Element} element + * @param {String} eventName - custom and standard events + * @param {Function} callback + * @return + */ + bind: function(element,eventName,callback){ + // Prepare + var uid = History.Adapter.uid(element); + + // Apply Listener + History.Adapter.handlers[uid] = History.Adapter.handlers[uid] || {}; + History.Adapter.handlers[uid][eventName] = History.Adapter.handlers[uid][eventName] || []; + History.Adapter.handlers[uid][eventName].push(callback); + + // Bind Global Listener + element['on'+eventName] = (function(element,eventName){ + return function(event){ + History.Adapter.trigger(element,eventName,event); + }; + })(element,eventName); + }, + + /** + * History.Adapter.trigger(el,event) + * @param {Element} element + * @param {String} eventName - custom and standard events + * @param {Object} event - a object of event data + * @return + */ + trigger: function(element,eventName,event){ + // Prepare + event = event || {}; + var uid = History.Adapter.uid(element), + i,n; + + // Apply Listener + History.Adapter.handlers[uid] = History.Adapter.handlers[uid] || {}; + History.Adapter.handlers[uid][eventName] = History.Adapter.handlers[uid][eventName] || []; + + // Fire Listeners + for ( i=0,n=History.Adapter.handlers[uid][eventName].length; i + * @copyright 2010-2011 Benjamin Arthur Lupton + * @license New BSD License + */ + +(function(window,undefined){ + "use strict"; + + // ======================================================================== + // Initialise + + // Localise Globals + var + document = window.document, // Make sure we are using the correct document + setTimeout = window.setTimeout||setTimeout, + clearTimeout = window.clearTimeout||clearTimeout, + setInterval = window.setInterval||setInterval, + History = window.History = window.History||{}; // Public History Object + + // Check Existence + if ( typeof History.initHtml4 !== 'undefined' ) { + throw new Error('History.js HTML4 Support has already been loaded...'); + } + + + // ======================================================================== + // Initialise HTML4 Support + + // Initialise HTML4 Support + History.initHtml4 = function(){ + // Initialise + if ( typeof History.initHtml4.initialized !== 'undefined' ) { + // Already Loaded + return false; + } + else { + History.initHtml4.initialized = true; + } + + + // ==================================================================== + // Properties + + /** + * History.enabled + * Is History enabled? + */ + History.enabled = true; + + + // ==================================================================== + // Hash Storage + + /** + * History.savedHashes + * Store the hashes in an array + */ + History.savedHashes = []; + + /** + * History.isLastHash(newHash) + * Checks if the hash is the last hash + * @param {string} newHash + * @return {boolean} true + */ + History.isLastHash = function(newHash){ + // Prepare + var oldHash = History.getHashByIndex(), + isLast; + + // Check + isLast = newHash === oldHash; + + // Return isLast + return isLast; + }; + + /** + * History.isHashEqual(newHash, oldHash) + * Checks to see if two hashes are functionally equal + * @param {string} newHash + * @param {string} oldHash + * @return {boolean} true + */ + History.isHashEqual = function(newHash, oldHash){ + newHash = encodeURIComponent(newHash).replace(/%25/g, "%"); + oldHash = encodeURIComponent(oldHash).replace(/%25/g, "%"); + return newHash === oldHash; + }; + + /** + * History.saveHash(newHash) + * Push a Hash + * @param {string} newHash + * @return {boolean} true + */ + History.saveHash = function(newHash){ + // Check Hash + if ( History.isLastHash(newHash) ) { + return false; + } + + // Push the Hash + History.savedHashes.push(newHash); + + // Return true + return true; + }; + + /** + * History.getHashByIndex() + * Gets a hash by the index + * @param {integer} index + * @return {string} + */ + History.getHashByIndex = function(index){ + // Prepare + var hash = null; + + // Handle + if ( typeof index === 'undefined' ) { + // Get the last inserted + hash = History.savedHashes[History.savedHashes.length-1]; + } + else if ( index < 0 ) { + // Get from the end + hash = History.savedHashes[History.savedHashes.length+index]; + } + else { + // Get from the beginning + hash = History.savedHashes[index]; + } + + // Return hash + return hash; + }; + + + // ==================================================================== + // Discarded States + + /** + * History.discardedHashes + * A hashed array of discarded hashes + */ + History.discardedHashes = {}; + + /** + * History.discardedStates + * A hashed array of discarded states + */ + History.discardedStates = {}; + + /** + * History.discardState(State) + * Discards the state by ignoring it through History + * @param {object} State + * @return {true} + */ + History.discardState = function(discardedState,forwardState,backState){ + //History.debug('History.discardState', arguments); + // Prepare + var discardedStateHash = History.getHashByState(discardedState), + discardObject; + + // Create Discard Object + discardObject = { + 'discardedState': discardedState, + 'backState': backState, + 'forwardState': forwardState + }; + + // Add to DiscardedStates + History.discardedStates[discardedStateHash] = discardObject; + + // Return true + return true; + }; + + /** + * History.discardHash(hash) + * Discards the hash by ignoring it through History + * @param {string} hash + * @return {true} + */ + History.discardHash = function(discardedHash,forwardState,backState){ + //History.debug('History.discardState', arguments); + // Create Discard Object + var discardObject = { + 'discardedHash': discardedHash, + 'backState': backState, + 'forwardState': forwardState + }; + + // Add to discardedHash + History.discardedHashes[discardedHash] = discardObject; + + // Return true + return true; + }; + + /** + * History.discardedState(State) + * Checks to see if the state is discarded + * @param {object} State + * @return {bool} + */ + History.discardedState = function(State){ + // Prepare + var StateHash = History.getHashByState(State), + discarded; + + // Check + discarded = History.discardedStates[StateHash]||false; + + // Return true + return discarded; + }; + + /** + * History.discardedHash(hash) + * Checks to see if the state is discarded + * @param {string} State + * @return {bool} + */ + History.discardedHash = function(hash){ + // Check + var discarded = History.discardedHashes[hash]||false; + + // Return true + return discarded; + }; + + /** + * History.recycleState(State) + * Allows a discarded state to be used again + * @param {object} data + * @param {string} title + * @param {string} url + * @return {true} + */ + History.recycleState = function(State){ + //History.debug('History.recycleState', arguments); + // Prepare + var StateHash = History.getHashByState(State); + + // Remove from DiscardedStates + if ( History.discardedState(State) ) { + delete History.discardedStates[StateHash]; + } + + // Return true + return true; + }; + + + // ==================================================================== + // HTML4 HashChange Support + + if ( History.emulated.hashChange ) { + /* + * We must emulate the HTML4 HashChange Support by manually checking for hash changes + */ + + /** + * History.hashChangeInit() + * Init the HashChange Emulation + */ + History.hashChangeInit = function(){ + // Define our Checker Function + History.checkerFunction = null; + + // Define some variables that will help in our checker function + var lastDocumentHash = '', + iframeId, iframe, + lastIframeHash, checkerRunning, + startedWithHash = Boolean(History.getHash()); + + // Handle depending on the browser + if ( History.isInternetExplorer() ) { + // IE6 and IE7 + // We need to use an iframe to emulate the back and forward buttons + + // Create iFrame + iframeId = 'historyjs-iframe'; + iframe = document.createElement('iframe'); + + // Adjust iFarme + // IE 6 requires iframe to have a src on HTTPS pages, otherwise it will throw a + // "This page contains both secure and nonsecure items" warning. + iframe.setAttribute('id', iframeId); + iframe.setAttribute('src', '#'); + iframe.style.display = 'none'; + + // Append iFrame + document.body.appendChild(iframe); + + // Create initial history entry + iframe.contentWindow.document.open(); + iframe.contentWindow.document.close(); + + // Define some variables that will help in our checker function + lastIframeHash = ''; + checkerRunning = false; + + // Define the checker function + History.checkerFunction = function(){ + // Check Running + if ( checkerRunning ) { + return false; + } + + // Update Running + checkerRunning = true; + + // Fetch + var + documentHash = History.getHash(), + iframeHash = History.getHash(iframe.contentWindow.document); + + // The Document Hash has changed (application caused) + if ( documentHash !== lastDocumentHash ) { + // Equalise + lastDocumentHash = documentHash; + + // Create a history entry in the iframe + if ( iframeHash !== documentHash ) { + //History.debug('hashchange.checker: iframe hash change', 'documentHash (new):', documentHash, 'iframeHash (old):', iframeHash); + + // Equalise + lastIframeHash = iframeHash = documentHash; + + // Create History Entry + iframe.contentWindow.document.open(); + iframe.contentWindow.document.close(); + + // Update the iframe's hash + iframe.contentWindow.document.location.hash = History.escapeHash(documentHash); + } + + // Trigger Hashchange Event + History.Adapter.trigger(window,'hashchange'); + } + + // The iFrame Hash has changed (back button caused) + else if ( iframeHash !== lastIframeHash ) { + //History.debug('hashchange.checker: iframe hash out of sync', 'iframeHash (new):', iframeHash, 'documentHash (old):', documentHash); + + // Equalise + lastIframeHash = iframeHash; + + // If there is no iframe hash that means we're at the original + // iframe state. + // And if there was a hash on the original request, the original + // iframe state was replaced instantly, so skip this state and take + // the user back to where they came from. + if (startedWithHash && iframeHash === '') { + History.back(); + } + else { + // Update the Hash + History.setHash(iframeHash,false); + } + } + + // Reset Running + checkerRunning = false; + + // Return true + return true; + }; + } + else { + // We are not IE + // Firefox 1 or 2, Opera + + // Define the checker function + History.checkerFunction = function(){ + // Prepare + var documentHash = History.getHash()||''; + + // The Document Hash has changed (application caused) + if ( documentHash !== lastDocumentHash ) { + // Equalise + lastDocumentHash = documentHash; + + // Trigger Hashchange Event + History.Adapter.trigger(window,'hashchange'); + } + + // Return true + return true; + }; + } + + // Apply the checker function + History.intervalList.push(setInterval(History.checkerFunction, History.options.hashChangeInterval)); + + // Done + return true; + }; // History.hashChangeInit + + // Bind hashChangeInit + History.Adapter.onDomLoad(History.hashChangeInit); + + } // History.emulated.hashChange + + + // ==================================================================== + // HTML5 State Support + + // Non-Native pushState Implementation + if ( History.emulated.pushState ) { + /* + * We must emulate the HTML5 State Management by using HTML4 HashChange + */ + + /** + * History.onHashChange(event) + * Trigger HTML5's window.onpopstate via HTML4 HashChange Support + */ + History.onHashChange = function(event){ + //History.debug('History.onHashChange', arguments); + + // Prepare + var currentUrl = ((event && event.newURL) || History.getLocationHref()), + currentHash = History.getHashByUrl(currentUrl), + currentState = null, + currentStateHash = null, + currentStateHashExits = null, + discardObject; + + // Check if we are the same state + if ( History.isLastHash(currentHash) ) { + // There has been no change (just the page's hash has finally propagated) + //History.debug('History.onHashChange: no change'); + History.busy(false); + return false; + } + + // Reset the double check + History.doubleCheckComplete(); + + // Store our location for use in detecting back/forward direction + History.saveHash(currentHash); + + // Expand Hash + if ( currentHash && History.isTraditionalAnchor(currentHash) ) { + //History.debug('History.onHashChange: traditional anchor', currentHash); + // Traditional Anchor Hash + History.Adapter.trigger(window,'anchorchange'); + History.busy(false); + return false; + } + + // Create State + currentState = History.extractState(History.getFullUrl(currentHash||History.getLocationHref()),true); + + // Check if we are the same state + if ( History.isLastSavedState(currentState) ) { + //History.debug('History.onHashChange: no change'); + // There has been no change (just the page's hash has finally propagated) + History.busy(false); + return false; + } + + // Create the state Hash + currentStateHash = History.getHashByState(currentState); + + // Check if we are DiscardedState + discardObject = History.discardedState(currentState); + if ( discardObject ) { + // Ignore this state as it has been discarded and go back to the state before it + if ( History.getHashByIndex(-2) === History.getHashByState(discardObject.forwardState) ) { + // We are going backwards + //History.debug('History.onHashChange: go backwards'); + History.back(false); + } else { + // We are going forwards + //History.debug('History.onHashChange: go forwards'); + History.forward(false); + } + return false; + } + + // Push the new HTML5 State + //History.debug('History.onHashChange: success hashchange'); + History.pushState(currentState.data,currentState.title,encodeURI(currentState.url),false); + + // End onHashChange closure + return true; + }; + History.Adapter.bind(window,'hashchange',History.onHashChange); + + /** + * History.pushState(data,title,url) + * Add a new State to the history object, become it, and trigger onpopstate + * We have to trigger for HTML4 compatibility + * @param {object} data + * @param {string} title + * @param {string} url + * @return {true} + */ + History.pushState = function(data,title,url,queue){ + //History.debug('History.pushState: called', arguments); + + // We assume that the URL passed in is URI-encoded, but this makes + // sure that it's fully URI encoded; any '%'s that are encoded are + // converted back into '%'s + url = encodeURI(url).replace(/%25/g, "%"); + + // Check the State + if ( History.getHashByUrl(url) ) { + throw new Error('History.js does not support states with fragment-identifiers (hashes/anchors).'); + } + + // Handle Queueing + if ( queue !== false && History.busy() ) { + // Wait + Push to Queue + //History.debug('History.pushState: we must wait', arguments); + History.pushQueue({ + scope: History, + callback: History.pushState, + args: arguments, + queue: queue + }); + return false; + } + + // Make Busy + History.busy(true); + + // Fetch the State Object + var newState = History.createStateObject(data,title,url), + newStateHash = History.getHashByState(newState), + oldState = History.getState(false), + oldStateHash = History.getHashByState(oldState), + html4Hash = History.getHash(), + wasExpected = History.expectedStateId == newState.id; + + // Store the newState + History.storeState(newState); + History.expectedStateId = newState.id; + + // Recycle the State + History.recycleState(newState); + + // Force update of the title + History.setTitle(newState); + + // Check if we are the same State + if ( newStateHash === oldStateHash ) { + //History.debug('History.pushState: no change', newStateHash); + History.busy(false); + return false; + } + + // Update HTML5 State + History.saveState(newState); + + // Fire HTML5 Event + if(!wasExpected) + History.Adapter.trigger(window,'statechange'); + + // Update HTML4 Hash + if ( !History.isHashEqual(newStateHash, html4Hash) && !History.isHashEqual(newStateHash, History.getShortUrl(History.getLocationHref())) ) { + History.setHash(newStateHash,false); + } + + History.busy(false); + + // End pushState closure + return true; + }; + + /** + * History.replaceState(data,title,url) + * Replace the State and trigger onpopstate + * We have to trigger for HTML4 compatibility + * @param {object} data + * @param {string} title + * @param {string} url + * @return {true} + */ + History.replaceState = function(data,title,url,queue){ + //History.debug('History.replaceState: called', arguments); + + // We assume that the URL passed in is URI-encoded, but this makes + // sure that it's fully URI encoded; any '%'s that are encoded are + // converted back into '%'s + url = encodeURI(url).replace(/%25/g, "%"); + + // Check the State + if ( History.getHashByUrl(url) ) { + throw new Error('History.js does not support states with fragment-identifiers (hashes/anchors).'); + } + + // Handle Queueing + if ( queue !== false && History.busy() ) { + // Wait + Push to Queue + //History.debug('History.replaceState: we must wait', arguments); + History.pushQueue({ + scope: History, + callback: History.replaceState, + args: arguments, + queue: queue + }); + return false; + } + + // Make Busy + History.busy(true); + + // Fetch the State Objects + var newState = History.createStateObject(data,title,url), + newStateHash = History.getHashByState(newState), + oldState = History.getState(false), + oldStateHash = History.getHashByState(oldState), + previousState = History.getStateByIndex(-2); + + // Discard Old State + History.discardState(oldState,newState,previousState); + + // If the url hasn't changed, just store and save the state + // and fire a statechange event to be consistent with the + // html 5 api + if ( newStateHash === oldStateHash ) { + // Store the newState + History.storeState(newState); + History.expectedStateId = newState.id; + + // Recycle the State + History.recycleState(newState); + + // Force update of the title + History.setTitle(newState); + + // Update HTML5 State + History.saveState(newState); + + // Fire HTML5 Event + //History.debug('History.pushState: trigger popstate'); + History.Adapter.trigger(window,'statechange'); + History.busy(false); + } + else { + // Alias to PushState + History.pushState(newState.data,newState.title,newState.url,false); + } + + // End replaceState closure + return true; + }; + + } // History.emulated.pushState + + + + // ==================================================================== + // Initialise + + // Non-Native pushState Implementation + if ( History.emulated.pushState ) { + /** + * Ensure initial state is handled correctly + */ + if ( History.getHash() && !History.emulated.hashChange ) { + History.Adapter.onDomLoad(function(){ + History.Adapter.trigger(window,'hashchange'); + }); + } + + } // History.emulated.pushState + + }; // History.initHtml4 + + // Try to Initialise History + if ( typeof History.init !== 'undefined' ) { + History.init(); + } + +})(window); +/** + * History.js Core + * @author Benjamin Arthur Lupton + * @copyright 2010-2011 Benjamin Arthur Lupton + * @license New BSD License + */ + +(function(window,undefined){ + "use strict"; + + // ======================================================================== + // Initialise + + // Localise Globals + var + console = window.console||undefined, // Prevent a JSLint complain + document = window.document, // Make sure we are using the correct document + navigator = window.navigator, // Make sure we are using the correct navigator + sessionStorage = window.sessionStorage||false, // sessionStorage + setTimeout = window.setTimeout, + clearTimeout = window.clearTimeout, + setInterval = window.setInterval, + clearInterval = window.clearInterval, + JSON = window.JSON, + alert = window.alert, + History = window.History = window.History||{}, // Public History Object + history = window.history; // Old History Object + + try { + sessionStorage.setItem('TEST', '1'); + sessionStorage.removeItem('TEST'); + } catch(e) { + sessionStorage = false; + } + + // MooTools Compatibility + JSON.stringify = JSON.stringify||JSON.encode; + JSON.parse = JSON.parse||JSON.decode; + + // Check Existence + if ( typeof History.init !== 'undefined' ) { + throw new Error('History.js Core has already been loaded...'); + } + + // Initialise History + History.init = function(options){ + // Check Load Status of Adapter + if ( typeof History.Adapter === 'undefined' ) { + return false; + } + + // Check Load Status of Core + if ( typeof History.initCore !== 'undefined' ) { + History.initCore(); + } + + // Check Load Status of HTML4 Support + if ( typeof History.initHtml4 !== 'undefined' ) { + History.initHtml4(); + } + + // Return true + return true; + }; + + + // ======================================================================== + // Initialise Core + + // Initialise Core + History.initCore = function(options){ + // Initialise + if ( typeof History.initCore.initialized !== 'undefined' ) { + // Already Loaded + return false; + } + else { + History.initCore.initialized = true; + } + + + // ==================================================================== + // Options + + /** + * History.options + * Configurable options + */ + History.options = History.options||{}; + + /** + * History.options.hashChangeInterval + * How long should the interval be before hashchange checks + */ + History.options.hashChangeInterval = History.options.hashChangeInterval || 100; + + /** + * History.options.safariPollInterval + * How long should the interval be before safari poll checks + */ + History.options.safariPollInterval = History.options.safariPollInterval || 500; + + /** + * History.options.doubleCheckInterval + * How long should the interval be before we perform a double check + */ + History.options.doubleCheckInterval = History.options.doubleCheckInterval || 500; + + /** + * History.options.disableSuid + * Force History not to append suid + */ + History.options.disableSuid = History.options.disableSuid || false; + + /** + * History.options.storeInterval + * How long should we wait between store calls + */ + History.options.storeInterval = History.options.storeInterval || 1000; + + /** + * History.options.busyDelay + * How long should we wait between busy events + */ + History.options.busyDelay = History.options.busyDelay || 250; + + /** + * History.options.debug + * If true will enable debug messages to be logged + */ + History.options.debug = History.options.debug || false; + + /** + * History.options.initialTitle + * What is the title of the initial state + */ + History.options.initialTitle = History.options.initialTitle || document.title; + + /** + * History.options.html4Mode + * If true, will force HTMl4 mode (hashtags) + */ + History.options.html4Mode = History.options.html4Mode || false; + + /** + * History.options.delayInit + * Want to override default options and call init manually. + */ + History.options.delayInit = History.options.delayInit || false; + + + // ==================================================================== + // Interval record + + /** + * History.intervalList + * List of intervals set, to be cleared when document is unloaded. + */ + History.intervalList = []; + + /** + * History.clearAllIntervals + * Clears all setInterval instances. + */ + History.clearAllIntervals = function(){ + var i, il = History.intervalList; + if (typeof il !== "undefined" && il !== null) { + for (i = 0; i < il.length; i++) { + clearInterval(il[i]); + } + History.intervalList = null; + } + }; + + + // ==================================================================== + // Debug + + /** + * History.debug(message,...) + * Logs the passed arguments if debug enabled + */ + History.debug = function(){ + if ( (History.options.debug||false) ) { + History.log.apply(History,arguments); + } + }; + + /** + * History.log(message,...) + * Logs the passed arguments + */ + History.log = function(){ + // Prepare + var + consoleExists = !(typeof console === 'undefined' || typeof console.log === 'undefined' || typeof console.log.apply === 'undefined'), + textarea = document.getElementById('log'), + message, + i,n, + args,arg + ; + + // Write to Console + if ( consoleExists ) { + args = Array.prototype.slice.call(arguments); + message = args.shift(); + if ( typeof console.debug !== 'undefined' ) { + console.debug.apply(console,[message,args]); + } + else { + console.log.apply(console,[message,args]); + } + } + else { + message = ("\n"+arguments[0]+"\n"); + } + + // Write to log + for ( i=1,n=arguments.length; i + * @author James Padolsey + */ + History.getInternetExplorerMajorVersion = function(){ + var result = History.getInternetExplorerMajorVersion.cached = + (typeof History.getInternetExplorerMajorVersion.cached !== 'undefined') + ? History.getInternetExplorerMajorVersion.cached + : (function(){ + var v = 3, + div = document.createElement('div'), + all = div.getElementsByTagName('i'); + while ( (div.innerHTML = '') && all[0] ) {} + return (v > 4) ? v : false; + })() + ; + return result; + }; + + /** + * History.isInternetExplorer() + * Are we using Internet Explorer? + * @return {boolean} + * @license Public Domain + * @author Benjamin Arthur Lupton + */ + History.isInternetExplorer = function(){ + var result = + History.isInternetExplorer.cached = + (typeof History.isInternetExplorer.cached !== 'undefined') + ? History.isInternetExplorer.cached + : Boolean(History.getInternetExplorerMajorVersion()) + ; + return result; + }; + + /** + * History.emulated + * Which features require emulating? + */ + + if (History.options.html4Mode) { + History.emulated = { + pushState : true, + hashChange: true + }; + } + + else { + + History.emulated = { + pushState: !Boolean( + window.history && window.history.pushState && window.history.replaceState + && !( + (/ Mobile\/([1-7][a-z]|(8([abcde]|f(1[0-8]))))/i).test(navigator.userAgent) /* disable for versions of iOS before version 4.3 (8F190) */ + || (/AppleWebKit\/5([0-2]|3[0-2])/i).test(navigator.userAgent) /* disable for the mercury iOS browser, or at least older versions of the webkit engine */ + ) + ), + hashChange: Boolean( + !(('onhashchange' in window) || ('onhashchange' in document)) + || + (History.isInternetExplorer() && History.getInternetExplorerMajorVersion() < 8) + ) + }; + } + + /** + * History.enabled + * Is History enabled? + */ + History.enabled = !History.emulated.pushState; + + /** + * History.bugs + * Which bugs are present + */ + History.bugs = { + /** + * Safari 5 and Safari iOS 4 fail to return to the correct state once a hash is replaced by a `replaceState` call + * https://bugs.webkit.org/show_bug.cgi?id=56249 + */ + setHash: Boolean(!History.emulated.pushState && navigator.vendor === 'Apple Computer, Inc.' && /AppleWebKit\/5([0-2]|3[0-3])/.test(navigator.userAgent)), + + /** + * Safari 5 and Safari iOS 4 sometimes fail to apply the state change under busy conditions + * https://bugs.webkit.org/show_bug.cgi?id=42940 + */ + safariPoll: Boolean(!History.emulated.pushState && navigator.vendor === 'Apple Computer, Inc.' && /AppleWebKit\/5([0-2]|3[0-3])/.test(navigator.userAgent)), + + /** + * MSIE 6 and 7 sometimes do not apply a hash even it was told to (requiring a second call to the apply function) + */ + ieDoubleCheck: Boolean(History.isInternetExplorer() && History.getInternetExplorerMajorVersion() < 8), + + /** + * MSIE 6 requires the entire hash to be encoded for the hashes to trigger the onHashChange event + */ + hashEscape: Boolean(History.isInternetExplorer() && History.getInternetExplorerMajorVersion() < 7) + }; + + /** + * History.isEmptyObject(obj) + * Checks to see if the Object is Empty + * @param {Object} obj + * @return {boolean} + */ + History.isEmptyObject = function(obj) { + for ( var name in obj ) { + if ( obj.hasOwnProperty(name) ) { + return false; + } + } + return true; + }; + + /** + * History.cloneObject(obj) + * Clones a object and eliminate all references to the original contexts + * @param {Object} obj + * @return {Object} + */ + History.cloneObject = function(obj) { + var hash,newObj; + if ( obj ) { + hash = JSON.stringify(obj); + newObj = JSON.parse(hash); + } + else { + newObj = {}; + } + return newObj; + }; + + + // ==================================================================== + // URL Helpers + + /** + * History.getRootUrl() + * Turns "http://mysite.com/dir/page.html?asd" into "http://mysite.com" + * @return {String} rootUrl + */ + History.getRootUrl = function(){ + // Create + var rootUrl = document.location.protocol+'//'+(document.location.hostname||document.location.host); + if ( document.location.port||false ) { + rootUrl += ':'+document.location.port; + } + rootUrl += '/'; + + // Return + return rootUrl; + }; + + /** + * History.getBaseHref() + * Fetches the `href` attribute of the `` element if it exists + * @return {String} baseHref + */ + History.getBaseHref = function(){ + // Create + var + baseElements = document.getElementsByTagName('base'), + baseElement = null, + baseHref = ''; + + // Test for Base Element + if ( baseElements.length === 1 ) { + // Prepare for Base Element + baseElement = baseElements[0]; + baseHref = baseElement.href.replace(/[^\/]+$/,''); + } + + // Adjust trailing slash + baseHref = baseHref.replace(/\/+$/,''); + if ( baseHref ) baseHref += '/'; + + // Return + return baseHref; + }; + + /** + * History.getBaseUrl() + * Fetches the baseHref or basePageUrl or rootUrl (whichever one exists first) + * @return {String} baseUrl + */ + History.getBaseUrl = function(){ + // Create + var baseUrl = History.getBaseHref()||History.getBasePageUrl()||History.getRootUrl(); + + // Return + return baseUrl; + }; + + /** + * History.getPageUrl() + * Fetches the URL of the current page + * @return {String} pageUrl + */ + History.getPageUrl = function(){ + // Fetch + var + State = History.getState(false,false), + stateUrl = (State||{}).url||History.getLocationHref(), + pageUrl; + + // Create + pageUrl = stateUrl.replace(/\/+$/,'').replace(/[^\/]+$/,function(part,index,string){ + return (/\./).test(part) ? part : part+'/'; + }); + + // Return + return pageUrl; + }; + + /** + * History.getBasePageUrl() + * Fetches the Url of the directory of the current page + * @return {String} basePageUrl + */ + History.getBasePageUrl = function(){ + // Create + var basePageUrl = (History.getLocationHref()).replace(/[#\?].*/,'').replace(/[^\/]+$/,function(part,index,string){ + return (/[^\/]$/).test(part) ? '' : part; + }).replace(/\/+$/,'')+'/'; + + // Return + return basePageUrl; + }; + + /** + * History.getFullUrl(url) + * Ensures that we have an absolute URL and not a relative URL + * @param {string} url + * @param {Boolean} allowBaseHref + * @return {string} fullUrl + */ + History.getFullUrl = function(url,allowBaseHref){ + // Prepare + var fullUrl = url, firstChar = url.substring(0,1); + allowBaseHref = (typeof allowBaseHref === 'undefined') ? true : allowBaseHref; + + // Check + if ( /[a-z]+\:\/\//.test(url) ) { + // Full URL + } + else if ( firstChar === '/' ) { + // Root URL + fullUrl = History.getRootUrl()+url.replace(/^\/+/,''); + } + else if ( firstChar === '#' ) { + // Anchor URL + fullUrl = History.getPageUrl().replace(/#.*/,'')+url; + } + else if ( firstChar === '?' ) { + // Query URL + fullUrl = History.getPageUrl().replace(/[\?#].*/,'')+url; + } + else { + // Relative URL + if ( allowBaseHref ) { + fullUrl = History.getBaseUrl()+url.replace(/^(\.\/)+/,''); + } else { + fullUrl = History.getBasePageUrl()+url.replace(/^(\.\/)+/,''); + } + // We have an if condition above as we do not want hashes + // which are relative to the baseHref in our URLs + // as if the baseHref changes, then all our bookmarks + // would now point to different locations + // whereas the basePageUrl will always stay the same + } + + // Return + return fullUrl.replace(/\#$/,''); + }; + + /** + * History.getShortUrl(url) + * Ensures that we have a relative URL and not a absolute URL + * @param {string} url + * @return {string} url + */ + History.getShortUrl = function(url){ + // Prepare + var shortUrl = url, baseUrl = History.getBaseUrl(), rootUrl = History.getRootUrl(); + + // Trim baseUrl + if ( History.emulated.pushState ) { + // We are in a if statement as when pushState is not emulated + // The actual url these short urls are relative to can change + // So within the same session, we the url may end up somewhere different + shortUrl = shortUrl.replace(baseUrl,''); + } + + // Trim rootUrl + shortUrl = shortUrl.replace(rootUrl,'/'); + + // Ensure we can still detect it as a state + if ( History.isTraditionalAnchor(shortUrl) ) { + shortUrl = './'+shortUrl; + } + + // Clean It + shortUrl = shortUrl.replace(/^(\.\/)+/g,'./').replace(/\#$/,''); + + // Return + return shortUrl; + }; + + /** + * History.getLocationHref(document) + * Returns a normalized version of document.location.href + * accounting for browser inconsistencies, etc. + * + * This URL will be URI-encoded and will include the hash + * + * @param {object} document + * @return {string} url + */ + History.getLocationHref = function(doc) { + doc = doc || document; + + // most of the time, this will be true + if (doc.URL === doc.location.href) + return doc.location.href; + + // some versions of webkit URI-decode document.location.href + // but they leave document.URL in an encoded state + if (doc.location.href === decodeURIComponent(doc.URL)) + return doc.URL; + + // FF 3.6 only updates document.URL when a page is reloaded + // document.location.href is updated correctly + if (doc.location.hash && decodeURIComponent(doc.location.href.replace(/^[^#]+/, "")) === doc.location.hash) + return doc.location.href; + + if (doc.URL.indexOf('#') == -1 && doc.location.href.indexOf('#') != -1) + return doc.location.href; + + return doc.URL || doc.location.href; + }; + + + // ==================================================================== + // State Storage + + /** + * History.store + * The store for all session specific data + */ + History.store = {}; + + /** + * History.idToState + * 1-1: State ID to State Object + */ + History.idToState = History.idToState||{}; + + /** + * History.stateToId + * 1-1: State String to State ID + */ + History.stateToId = History.stateToId||{}; + + /** + * History.urlToId + * 1-1: State URL to State ID + */ + History.urlToId = History.urlToId||{}; + + /** + * History.storedStates + * Store the states in an array + */ + History.storedStates = History.storedStates||[]; + + /** + * History.savedStates + * Saved the states in an array + */ + History.savedStates = History.savedStates||[]; + + /** + * History.noramlizeStore() + * Noramlize the store by adding necessary values + */ + History.normalizeStore = function(){ + History.store.idToState = History.store.idToState||{}; + History.store.urlToId = History.store.urlToId||{}; + History.store.stateToId = History.store.stateToId||{}; + }; + + /** + * History.getState() + * Get an object containing the data, title and url of the current state + * @param {Boolean} friendly + * @param {Boolean} create + * @return {Object} State + */ + History.getState = function(friendly,create){ + // Prepare + if ( typeof friendly === 'undefined' ) { friendly = true; } + if ( typeof create === 'undefined' ) { create = true; } + + // Fetch + var State = History.getLastSavedState(); + + // Create + if ( !State && create ) { + State = History.createStateObject(); + } + + // Adjust + if ( friendly ) { + State = History.cloneObject(State); + State.url = State.cleanUrl||State.url; + } + + // Return + return State; + }; + + /** + * History.getIdByState(State) + * Gets a ID for a State + * @param {State} newState + * @return {String} id + */ + History.getIdByState = function(newState){ + + // Fetch ID + var id = History.extractId(newState.url), + str; + + if ( !id ) { + // Find ID via State String + str = History.getStateString(newState); + if ( typeof History.stateToId[str] !== 'undefined' ) { + id = History.stateToId[str]; + } + else if ( typeof History.store.stateToId[str] !== 'undefined' ) { + id = History.store.stateToId[str]; + } + else { + // Generate a new ID + while ( true ) { + id = (new Date()).getTime() + String(Math.random()).replace(/\D/g,''); + if ( typeof History.idToState[id] === 'undefined' && typeof History.store.idToState[id] === 'undefined' ) { + break; + } + } + + // Apply the new State to the ID + History.stateToId[str] = id; + History.idToState[id] = newState; + } + } + + // Return ID + return id; + }; + + /** + * History.normalizeState(State) + * Expands a State Object + * @param {object} State + * @return {object} + */ + History.normalizeState = function(oldState){ + // Variables + var newState, dataNotEmpty; + + // Prepare + if ( !oldState || (typeof oldState !== 'object') ) { + oldState = {}; + } + + // Check + if ( typeof oldState.normalized !== 'undefined' ) { + return oldState; + } + + // Adjust + if ( !oldState.data || (typeof oldState.data !== 'object') ) { + oldState.data = {}; + } + + // ---------------------------------------------------------------- + + // Create + newState = {}; + newState.normalized = true; + newState.title = oldState.title||''; + newState.url = History.getFullUrl(oldState.url?oldState.url:(History.getLocationHref())); + newState.hash = History.getShortUrl(newState.url); + newState.data = History.cloneObject(oldState.data); + + // Fetch ID + newState.id = History.getIdByState(newState); + + // ---------------------------------------------------------------- + + // Clean the URL + newState.cleanUrl = newState.url.replace(/\??\&_suid.*/,''); + newState.url = newState.cleanUrl; + + // Check to see if we have more than just a url + dataNotEmpty = !History.isEmptyObject(newState.data); + + // Apply + if ( (newState.title || dataNotEmpty) && History.options.disableSuid !== true ) { + // Add ID to Hash + newState.hash = History.getShortUrl(newState.url).replace(/\??\&_suid.*/,''); + if ( !/\?/.test(newState.hash) ) { + newState.hash += '?'; + } + newState.hash += '&_suid='+newState.id; + } + + // Create the Hashed URL + newState.hashedUrl = History.getFullUrl(newState.hash); + + // ---------------------------------------------------------------- + + // Update the URL if we have a duplicate + if ( (History.emulated.pushState || History.bugs.safariPoll) && History.hasUrlDuplicate(newState) ) { + newState.url = newState.hashedUrl; + } + + // ---------------------------------------------------------------- + + // Return + return newState; + }; + + /** + * History.createStateObject(data,title,url) + * Creates a object based on the data, title and url state params + * @param {object} data + * @param {string} title + * @param {string} url + * @return {object} + */ + History.createStateObject = function(data,title,url){ + // Hashify + var State = { + 'data': data, + 'title': title, + 'url': url + }; + + // Expand the State + State = History.normalizeState(State); + + // Return object + return State; + }; + + /** + * History.getStateById(id) + * Get a state by it's UID + * @param {String} id + */ + History.getStateById = function(id){ + // Prepare + id = String(id); + + // Retrieve + var State = History.idToState[id] || History.store.idToState[id] || undefined; + + // Return State + return State; + }; + + /** + * Get a State's String + * @param {State} passedState + */ + History.getStateString = function(passedState){ + // Prepare + var State, cleanedState, str; + + // Fetch + State = History.normalizeState(passedState); + + // Clean + cleanedState = { + data: State.data, + title: passedState.title, + url: passedState.url + }; + + // Fetch + str = JSON.stringify(cleanedState); + + // Return + return str; + }; + + /** + * Get a State's ID + * @param {State} passedState + * @return {String} id + */ + History.getStateId = function(passedState){ + // Prepare + var State, id; + + // Fetch + State = History.normalizeState(passedState); + + // Fetch + id = State.id; + + // Return + return id; + }; + + /** + * History.getHashByState(State) + * Creates a Hash for the State Object + * @param {State} passedState + * @return {String} hash + */ + History.getHashByState = function(passedState){ + // Prepare + var State, hash; + + // Fetch + State = History.normalizeState(passedState); + + // Hash + hash = State.hash; + + // Return + return hash; + }; + + /** + * History.extractId(url_or_hash) + * Get a State ID by it's URL or Hash + * @param {string} url_or_hash + * @return {string} id + */ + History.extractId = function ( url_or_hash ) { + // Prepare + var id,parts,url, tmp; + + // Extract + + // If the URL has a #, use the id from before the # + if (url_or_hash.indexOf('#') != -1) + { + tmp = url_or_hash.split("#")[0]; + } + else + { + tmp = url_or_hash; + } + + parts = /(.*)\&_suid=([0-9]+)$/.exec(tmp); + url = parts ? (parts[1]||url_or_hash) : url_or_hash; + id = parts ? String(parts[2]||'') : ''; + + // Return + return id||false; + }; + + /** + * History.isTraditionalAnchor + * Checks to see if the url is a traditional anchor or not + * @param {String} url_or_hash + * @return {Boolean} + */ + History.isTraditionalAnchor = function(url_or_hash){ + // Check + var isTraditional = !(/[\/\?\.]/.test(url_or_hash)); + + // Return + return isTraditional; + }; + + /** + * History.extractState + * Get a State by it's URL or Hash + * @param {String} url_or_hash + * @return {State|null} + */ + History.extractState = function(url_or_hash,create){ + // Prepare + var State = null, id, url; + create = create||false; + + // Fetch SUID + id = History.extractId(url_or_hash); + if ( id ) { + State = History.getStateById(id); + } + + // Fetch SUID returned no State + if ( !State ) { + // Fetch URL + url = History.getFullUrl(url_or_hash); + + // Check URL + id = History.getIdByUrl(url)||false; + if ( id ) { + State = History.getStateById(id); + } + + // Create State + if ( !State && create && !History.isTraditionalAnchor(url_or_hash) ) { + State = History.createStateObject(null,null,url); + } + } + + // Return + return State; + }; + + /** + * History.getIdByUrl() + * Get a State ID by a State URL + */ + History.getIdByUrl = function(url){ + // Fetch + var id = History.urlToId[url] || History.store.urlToId[url] || undefined; + + // Return + return id; + }; + + /** + * History.getLastSavedState() + * Get an object containing the data, title and url of the current state + * @return {Object} State + */ + History.getLastSavedState = function(){ + return History.savedStates[History.savedStates.length-1]||undefined; + }; + + /** + * History.getLastStoredState() + * Get an object containing the data, title and url of the current state + * @return {Object} State + */ + History.getLastStoredState = function(){ + return History.storedStates[History.storedStates.length-1]||undefined; + }; + + /** + * History.hasUrlDuplicate + * Checks if a Url will have a url conflict + * @param {Object} newState + * @return {Boolean} hasDuplicate + */ + History.hasUrlDuplicate = function(newState) { + // Prepare + var hasDuplicate = false, + oldState; + + // Fetch + oldState = History.extractState(newState.url); + + // Check + hasDuplicate = oldState && oldState.id !== newState.id; + + // Return + return hasDuplicate; + }; + + /** + * History.storeState + * Store a State + * @param {Object} newState + * @return {Object} newState + */ + History.storeState = function(newState){ + // Store the State + History.urlToId[newState.url] = newState.id; + + // Push the State + History.storedStates.push(History.cloneObject(newState)); + + // Return newState + return newState; + }; + + /** + * History.isLastSavedState(newState) + * Tests to see if the state is the last state + * @param {Object} newState + * @return {boolean} isLast + */ + History.isLastSavedState = function(newState){ + // Prepare + var isLast = false, + newId, oldState, oldId; + + // Check + if ( History.savedStates.length ) { + newId = newState.id; + oldState = History.getLastSavedState(); + oldId = oldState.id; + + // Check + isLast = (newId === oldId); + } + + // Return + return isLast; + }; + + /** + * History.saveState + * Push a State + * @param {Object} newState + * @return {boolean} changed + */ + History.saveState = function(newState){ + // Check Hash + if ( History.isLastSavedState(newState) ) { + return false; + } + + // Push the State + History.savedStates.push(History.cloneObject(newState)); + + // Return true + return true; + }; + + /** + * History.getStateByIndex() + * Gets a state by the index + * @param {integer} index + * @return {Object} + */ + History.getStateByIndex = function(index){ + // Prepare + var State = null; + + // Handle + if ( typeof index === 'undefined' ) { + // Get the last inserted + State = History.savedStates[History.savedStates.length-1]; + } + else if ( index < 0 ) { + // Get from the end + State = History.savedStates[History.savedStates.length+index]; + } + else { + // Get from the beginning + State = History.savedStates[index]; + } + + // Return State + return State; + }; + + /** + * History.getCurrentIndex() + * Gets the current index + * @return (integer) + */ + History.getCurrentIndex = function(){ + // Prepare + var index = null; + + // No states saved + if(History.savedStates.length < 1) { + index = 0; + } + else { + index = History.savedStates.length-1; + } + return index; + }; + + // ==================================================================== + // Hash Helpers + + /** + * History.getHash() + * @param {Location=} location + * Gets the current document hash + * Note: unlike location.hash, this is guaranteed to return the escaped hash in all browsers + * @return {string} + */ + History.getHash = function(doc){ + var url = History.getLocationHref(doc), + hash; + hash = History.getHashByUrl(url); + return hash; + }; + + /** + * History.unescapeHash() + * normalize and Unescape a Hash + * @param {String} hash + * @return {string} + */ + History.unescapeHash = function(hash){ + // Prepare + var result = History.normalizeHash(hash); + + // Unescape hash + result = decodeURIComponent(result); + + // Return result + return result; + }; + + /** + * History.normalizeHash() + * normalize a hash across browsers + * @return {string} + */ + History.normalizeHash = function(hash){ + // Prepare + var result = hash.replace(/[^#]*#/,'').replace(/#.*/, ''); + + // Return result + return result; + }; + + /** + * History.setHash(hash) + * Sets the document hash + * @param {string} hash + * @return {History} + */ + History.setHash = function(hash,queue){ + // Prepare + var State, pageUrl; + + // Handle Queueing + if ( queue !== false && History.busy() ) { + // Wait + Push to Queue + //History.debug('History.setHash: we must wait', arguments); + History.pushQueue({ + scope: History, + callback: History.setHash, + args: arguments, + queue: queue + }); + return false; + } + + // Log + //History.debug('History.setHash: called',hash); + + // Make Busy + Continue + History.busy(true); + + // Check if hash is a state + State = History.extractState(hash,true); + if ( State && !History.emulated.pushState ) { + // Hash is a state so skip the setHash + //History.debug('History.setHash: Hash is a state so skipping the hash set with a direct pushState call',arguments); + + // PushState + History.pushState(State.data,State.title,State.url,false); + } + else if ( History.getHash() !== hash ) { + // Hash is a proper hash, so apply it + + // Handle browser bugs + if ( History.bugs.setHash ) { + // Fix Safari Bug https://bugs.webkit.org/show_bug.cgi?id=56249 + + // Fetch the base page + pageUrl = History.getPageUrl(); + + // Safari hash apply + History.pushState(null,null,pageUrl+'#'+hash,false); + } + else { + // Normal hash apply + document.location.hash = hash; + } + } + + // Chain + return History; + }; + + /** + * History.escape() + * normalize and Escape a Hash + * @return {string} + */ + History.escapeHash = function(hash){ + // Prepare + var result = History.normalizeHash(hash); + + // Escape hash + result = window.encodeURIComponent(result); + + // IE6 Escape Bug + if ( !History.bugs.hashEscape ) { + // Restore common parts + result = result + .replace(/\%21/g,'!') + .replace(/\%26/g,'&') + .replace(/\%3D/g,'=') + .replace(/\%3F/g,'?'); + } + + // Return result + return result; + }; + + /** + * History.getHashByUrl(url) + * Extracts the Hash from a URL + * @param {string} url + * @return {string} url + */ + History.getHashByUrl = function(url){ + // Extract the hash + var hash = String(url) + .replace(/([^#]*)#?([^#]*)#?(.*)/, '$2') + ; + + // Unescape hash + hash = History.unescapeHash(hash); + + // Return hash + return hash; + }; + + /** + * History.setTitle(title) + * Applies the title to the document + * @param {State} newState + * @return {Boolean} + */ + History.setTitle = function(newState){ + // Prepare + var title = newState.title, + firstState; + + // Initial + if ( !title ) { + firstState = History.getStateByIndex(0); + if ( firstState && firstState.url === newState.url ) { + title = firstState.title||History.options.initialTitle; + } + } + + // Apply + try { + document.getElementsByTagName('title')[0].innerHTML = title.replace('<','<').replace('>','>').replace(' & ',' & '); + } + catch ( Exception ) { } + document.title = title; + + // Chain + return History; + }; + + + // ==================================================================== + // Queueing + + /** + * History.queues + * The list of queues to use + * First In, First Out + */ + History.queues = []; + + /** + * History.busy(value) + * @param {boolean} value [optional] + * @return {boolean} busy + */ + History.busy = function(value){ + // Apply + if ( typeof value !== 'undefined' ) { + //History.debug('History.busy: changing ['+(History.busy.flag||false)+'] to ['+(value||false)+']', History.queues.length); + History.busy.flag = value; + } + // Default + else if ( typeof History.busy.flag === 'undefined' ) { + History.busy.flag = false; + } + + // Queue + if ( !History.busy.flag ) { + // Execute the next item in the queue + clearTimeout(History.busy.timeout); + var fireNext = function(){ + var i, queue, item; + if ( History.busy.flag ) return; + for ( i=History.queues.length-1; i >= 0; --i ) { + queue = History.queues[i]; + if ( queue.length === 0 ) continue; + item = queue.shift(); + History.fireQueueItem(item); + History.busy.timeout = setTimeout(fireNext,History.options.busyDelay); + } + }; + History.busy.timeout = setTimeout(fireNext,History.options.busyDelay); + } + + // Return + return History.busy.flag; + }; + + /** + * History.busy.flag + */ + History.busy.flag = false; + + /** + * History.fireQueueItem(item) + * Fire a Queue Item + * @param {Object} item + * @return {Mixed} result + */ + History.fireQueueItem = function(item){ + return item.callback.apply(item.scope||History,item.args||[]); + }; + + /** + * History.pushQueue(callback,args) + * Add an item to the queue + * @param {Object} item [scope,callback,args,queue] + */ + History.pushQueue = function(item){ + // Prepare the queue + History.queues[item.queue||0] = History.queues[item.queue||0]||[]; + + // Add to the queue + History.queues[item.queue||0].push(item); + + // Chain + return History; + }; + + /** + * History.queue (item,queue), (func,queue), (func), (item) + * Either firs the item now if not busy, or adds it to the queue + */ + History.queue = function(item,queue){ + // Prepare + if ( typeof item === 'function' ) { + item = { + callback: item + }; + } + if ( typeof queue !== 'undefined' ) { + item.queue = queue; + } + + // Handle + if ( History.busy() ) { + History.pushQueue(item); + } else { + History.fireQueueItem(item); + } + + // Chain + return History; + }; + + /** + * History.clearQueue() + * Clears the Queue + */ + History.clearQueue = function(){ + History.busy.flag = false; + History.queues = []; + return History; + }; + + + // ==================================================================== + // IE Bug Fix + + /** + * History.stateChanged + * States whether or not the state has changed since the last double check was initialised + */ + History.stateChanged = false; + + /** + * History.doubleChecker + * Contains the timeout used for the double checks + */ + History.doubleChecker = false; + + /** + * History.doubleCheckComplete() + * Complete a double check + * @return {History} + */ + History.doubleCheckComplete = function(){ + // Update + History.stateChanged = true; + + // Clear + History.doubleCheckClear(); + + // Chain + return History; + }; + + /** + * History.doubleCheckClear() + * Clear a double check + * @return {History} + */ + History.doubleCheckClear = function(){ + // Clear + if ( History.doubleChecker ) { + clearTimeout(History.doubleChecker); + History.doubleChecker = false; + } + + // Chain + return History; + }; + + /** + * History.doubleCheck() + * Create a double check + * @return {History} + */ + History.doubleCheck = function(tryAgain){ + // Reset + History.stateChanged = false; + History.doubleCheckClear(); + + // Fix IE6,IE7 bug where calling history.back or history.forward does not actually change the hash (whereas doing it manually does) + // Fix Safari 5 bug where sometimes the state does not change: https://bugs.webkit.org/show_bug.cgi?id=42940 + if ( History.bugs.ieDoubleCheck ) { + // Apply Check + History.doubleChecker = setTimeout( + function(){ + History.doubleCheckClear(); + if ( !History.stateChanged ) { + //History.debug('History.doubleCheck: State has not yet changed, trying again', arguments); + // Re-Attempt + tryAgain(); + } + return true; + }, + History.options.doubleCheckInterval + ); + } + + // Chain + return History; + }; + + + // ==================================================================== + // Safari Bug Fix + + /** + * History.safariStatePoll() + * Poll the current state + * @return {History} + */ + History.safariStatePoll = function(){ + // Poll the URL + + // Get the Last State which has the new URL + var + urlState = History.extractState(History.getLocationHref()), + newState; + + // Check for a difference + if ( !History.isLastSavedState(urlState) ) { + newState = urlState; + } + else { + return; + } + + // Check if we have a state with that url + // If not create it + if ( !newState ) { + //History.debug('History.safariStatePoll: new'); + newState = History.createStateObject(); + } + + // Apply the New State + //History.debug('History.safariStatePoll: trigger'); + History.Adapter.trigger(window,'popstate'); + + // Chain + return History; + }; + + + // ==================================================================== + // State Aliases + + /** + * History.back(queue) + * Send the browser history back one item + * @param {Integer} queue [optional] + */ + History.back = function(queue){ + //History.debug('History.back: called', arguments); + + // Handle Queueing + if ( queue !== false && History.busy() ) { + // Wait + Push to Queue + //History.debug('History.back: we must wait', arguments); + History.pushQueue({ + scope: History, + callback: History.back, + args: arguments, + queue: queue + }); + return false; + } + + // Make Busy + Continue + History.busy(true); + + // Fix certain browser bugs that prevent the state from changing + History.doubleCheck(function(){ + History.back(false); + }); + + // Go back + history.go(-1); + + // End back closure + return true; + }; + + /** + * History.forward(queue) + * Send the browser history forward one item + * @param {Integer} queue [optional] + */ + History.forward = function(queue){ + //History.debug('History.forward: called', arguments); + + // Handle Queueing + if ( queue !== false && History.busy() ) { + // Wait + Push to Queue + //History.debug('History.forward: we must wait', arguments); + History.pushQueue({ + scope: History, + callback: History.forward, + args: arguments, + queue: queue + }); + return false; + } + + // Make Busy + Continue + History.busy(true); + + // Fix certain browser bugs that prevent the state from changing + History.doubleCheck(function(){ + History.forward(false); + }); + + // Go forward + history.go(1); + + // End forward closure + return true; + }; + + /** + * History.go(index,queue) + * Send the browser history back or forward index times + * @param {Integer} queue [optional] + */ + History.go = function(index,queue){ + //History.debug('History.go: called', arguments); + + // Prepare + var i; + + // Handle + if ( index > 0 ) { + // Forward + for ( i=1; i<=index; ++i ) { + History.forward(queue); + } + } + else if ( index < 0 ) { + // Backward + for ( i=-1; i>=index; --i ) { + History.back(queue); + } + } + else { + throw new Error('History.go: History.go requires a positive or negative integer passed.'); + } + + // Chain + return History; + }; + + + // ==================================================================== + // HTML5 State Support + + // Non-Native pushState Implementation + if ( History.emulated.pushState ) { + /* + * Provide Skeleton for HTML4 Browsers + */ + + // Prepare + var emptyFunction = function(){}; + History.pushState = History.pushState||emptyFunction; + History.replaceState = History.replaceState||emptyFunction; + } // History.emulated.pushState + + // Native pushState Implementation + else { + /* + * Use native HTML5 History API Implementation + */ + + /** + * History.onPopState(event,extra) + * Refresh the Current State + */ + History.onPopState = function(event,extra){ + // Prepare + var stateId = false, newState = false, currentHash, currentState; + + // Reset the double check + History.doubleCheckComplete(); + + // Check for a Hash, and handle apporiatly + currentHash = History.getHash(); + if ( currentHash ) { + // Expand Hash + currentState = History.extractState(currentHash||History.getLocationHref(),true); + if ( currentState ) { + // We were able to parse it, it must be a State! + // Let's forward to replaceState + //History.debug('History.onPopState: state anchor', currentHash, currentState); + History.replaceState(currentState.data, currentState.title, currentState.url, false); + } + else { + // Traditional Anchor + //History.debug('History.onPopState: traditional anchor', currentHash); + History.Adapter.trigger(window,'anchorchange'); + History.busy(false); + } + + // We don't care for hashes + History.expectedStateId = false; + return false; + } + + // Ensure + stateId = History.Adapter.extractEventData('state',event,extra) || false; + + // Fetch State + if ( stateId ) { + // Vanilla: Back/forward button was used + newState = History.getStateById(stateId); + } + else if ( History.expectedStateId ) { + // Vanilla: A new state was pushed, and popstate was called manually + newState = History.getStateById(History.expectedStateId); + } + else { + // Initial State + newState = History.extractState(History.getLocationHref()); + } + + // The State did not exist in our store + if ( !newState ) { + // Regenerate the State + newState = History.createStateObject(null,null,History.getLocationHref()); + } + + // Clean + History.expectedStateId = false; + + // Check if we are the same state + if ( History.isLastSavedState(newState) ) { + // There has been no change (just the page's hash has finally propagated) + //History.debug('History.onPopState: no change', newState, History.savedStates); + History.busy(false); + return false; + } + + // Store the State + History.storeState(newState); + History.saveState(newState); + + // Force update of the title + History.setTitle(newState); + + // Fire Our Event + History.Adapter.trigger(window,'statechange'); + History.busy(false); + + // Return true + return true; + }; + History.Adapter.bind(window,'popstate',History.onPopState); + + /** + * History.pushState(data,title,url) + * Add a new State to the history object, become it, and trigger onpopstate + * We have to trigger for HTML4 compatibility + * @param {object} data + * @param {string} title + * @param {string} url + * @return {true} + */ + History.pushState = function(data,title,url,queue){ + //History.debug('History.pushState: called', arguments); + + // Check the State + if ( History.getHashByUrl(url) && History.emulated.pushState ) { + throw new Error('History.js does not support states with fragement-identifiers (hashes/anchors).'); + } + + // Handle Queueing + if ( queue !== false && History.busy() ) { + // Wait + Push to Queue + //History.debug('History.pushState: we must wait', arguments); + History.pushQueue({ + scope: History, + callback: History.pushState, + args: arguments, + queue: queue + }); + return false; + } + + // Make Busy + Continue + History.busy(true); + + // Create the newState + var newState = History.createStateObject(data,title,url); + + // Check it + if ( History.isLastSavedState(newState) ) { + // Won't be a change + History.busy(false); + } + else { + // Store the newState + History.storeState(newState); + History.expectedStateId = newState.id; + + // Push the newState + history.pushState(newState.id,newState.title,newState.url); + + // Fire HTML5 Event + History.Adapter.trigger(window,'popstate'); + } + + // End pushState closure + return true; + }; + + /** + * History.replaceState(data,title,url) + * Replace the State and trigger onpopstate + * We have to trigger for HTML4 compatibility + * @param {object} data + * @param {string} title + * @param {string} url + * @return {true} + */ + History.replaceState = function(data,title,url,queue){ + //History.debug('History.replaceState: called', arguments); + + // Check the State + if ( History.getHashByUrl(url) && History.emulated.pushState ) { + throw new Error('History.js does not support states with fragement-identifiers (hashes/anchors).'); + } + + // Handle Queueing + if ( queue !== false && History.busy() ) { + // Wait + Push to Queue + //History.debug('History.replaceState: we must wait', arguments); + History.pushQueue({ + scope: History, + callback: History.replaceState, + args: arguments, + queue: queue + }); + return false; + } + + // Make Busy + Continue + History.busy(true); + + // Create the newState + var newState = History.createStateObject(data,title,url); + + // Check it + if ( History.isLastSavedState(newState) ) { + // Won't be a change + History.busy(false); + } + else { + // Store the newState + History.storeState(newState); + History.expectedStateId = newState.id; + + // Push the newState + history.replaceState(newState.id,newState.title,newState.url); + + // Fire HTML5 Event + History.Adapter.trigger(window,'popstate'); + } + + // End replaceState closure + return true; + }; + + } // !History.emulated.pushState + + + // ==================================================================== + // Initialise + + /** + * Load the Store + */ + if ( sessionStorage ) { + // Fetch + try { + History.store = JSON.parse(sessionStorage.getItem('History.store'))||{}; + } + catch ( err ) { + History.store = {}; + } + + // Normalize + History.normalizeStore(); + } + else { + // Default Load + History.store = {}; + History.normalizeStore(); + } + + /** + * Clear Intervals on exit to prevent memory leaks + */ + History.Adapter.bind(window,"unload",History.clearAllIntervals); + + /** + * Create the initial State + */ + History.saveState(History.storeState(History.extractState(History.getLocationHref(),true))); + + /** + * Bind for Saving Store + */ + if ( sessionStorage ) { + // When the page is closed + History.onUnload = function(){ + // Prepare + var currentStore, item, currentStoreString; + + // Fetch + try { + currentStore = JSON.parse(sessionStorage.getItem('History.store'))||{}; + } + catch ( err ) { + currentStore = {}; + } + + // Ensure + currentStore.idToState = currentStore.idToState || {}; + currentStore.urlToId = currentStore.urlToId || {}; + currentStore.stateToId = currentStore.stateToId || {}; + + // Sync + for ( item in History.idToState ) { + if ( !History.idToState.hasOwnProperty(item) ) { + continue; + } + currentStore.idToState[item] = History.idToState[item]; + } + for ( item in History.urlToId ) { + if ( !History.urlToId.hasOwnProperty(item) ) { + continue; + } + currentStore.urlToId[item] = History.urlToId[item]; + } + for ( item in History.stateToId ) { + if ( !History.stateToId.hasOwnProperty(item) ) { + continue; + } + currentStore.stateToId[item] = History.stateToId[item]; + } + + // Update + History.store = currentStore; + History.normalizeStore(); + + // In Safari, going into Private Browsing mode causes the + // Session Storage object to still exist but if you try and use + // or set any property/function of it it throws the exception + // "QUOTA_EXCEEDED_ERR: DOM Exception 22: An attempt was made to + // add something to storage that exceeded the quota." infinitely + // every second. + currentStoreString = JSON.stringify(currentStore); + try { + // Store + sessionStorage.setItem('History.store', currentStoreString); + } + catch (e) { + if (e.code === DOMException.QUOTA_EXCEEDED_ERR) { + if (sessionStorage.length) { + // Workaround for a bug seen on iPads. Sometimes the quota exceeded error comes up and simply + // removing/resetting the storage can work. + sessionStorage.removeItem('History.store'); + sessionStorage.setItem('History.store', currentStoreString); + } else { + // Otherwise, we're probably private browsing in Safari, so we'll ignore the exception. + } + } else { + throw e; + } + } + }; + + // For Internet Explorer + History.intervalList.push(setInterval(History.onUnload,History.options.storeInterval)); + + // For Other Browsers + History.Adapter.bind(window,'beforeunload',History.onUnload); + History.Adapter.bind(window,'unload',History.onUnload); + + // Both are enabled for consistency + } + + // Non-Native pushState Implementation + if ( !History.emulated.pushState ) { + // Be aware, the following is only for native pushState implementations + // If you are wanting to include something for all browsers + // Then include it above this if block + + /** + * Setup Safari Fix + */ + if ( History.bugs.safariPoll ) { + History.intervalList.push(setInterval(History.safariStatePoll, History.options.safariPollInterval)); + } + + /** + * Ensure Cross Browser Compatibility + */ + if ( navigator.vendor === 'Apple Computer, Inc.' || (navigator.appCodeName||'') === 'Mozilla' ) { + /** + * Fix Safari HashChange Issue + */ + + // Setup Alias + History.Adapter.bind(window,'hashchange',function(){ + History.Adapter.trigger(window,'popstate'); + }); + + // Initialise Alias + if ( History.getHash() ) { + History.Adapter.onDomLoad(function(){ + History.Adapter.trigger(window,'hashchange'); + }); + } + } + + } // !History.emulated.pushState + + + }; // History.initCore + + // Try to Initialise History + if (!History.options || !History.options.delayInit) { + History.init(); + } + +})(window); diff --git a/sites/all/themes/gui/materiobasetheme/bower_components/history.js/scripts/bundled-uncompressed/html4+html5/right.history.js b/sites/all/themes/gui/materiobasetheme/bower_components/history.js/scripts/bundled-uncompressed/html4+html5/right.history.js new file mode 100644 index 00000000..ef0eb22f --- /dev/null +++ b/sites/all/themes/gui/materiobasetheme/bower_components/history.js/scripts/bundled-uncompressed/html4+html5/right.history.js @@ -0,0 +1,3292 @@ +/* + json2.js + 2012-10-08 + + Public Domain. + + NO WARRANTY EXPRESSED OR IMPLIED. USE AT YOUR OWN RISK. + + See http://www.JSON.org/js.html + + + This code should be minified before deployment. + See http://javascript.crockford.com/jsmin.html + + USE YOUR OWN COPY. IT IS EXTREMELY UNWISE TO LOAD CODE FROM SERVERS YOU DO + NOT CONTROL. + + + This file creates a global JSON object containing two methods: stringify + and parse. + + JSON.stringify(value, replacer, space) + value any JavaScript value, usually an object or array. + + replacer an optional parameter that determines how object + values are stringified for objects. It can be a + function or an array of strings. + + space an optional parameter that specifies the indentation + of nested structures. If it is omitted, the text will + be packed without extra whitespace. If it is a number, + it will specify the number of spaces to indent at each + level. If it is a string (such as '\t' or ' '), + it contains the characters used to indent at each level. + + This method produces a JSON text from a JavaScript value. + + When an object value is found, if the object contains a toJSON + method, its toJSON method will be called and the result will be + stringified. A toJSON method does not serialize: it returns the + value represented by the name/value pair that should be serialized, + or undefined if nothing should be serialized. The toJSON method + will be passed the key associated with the value, and this will be + bound to the value + + For example, this would serialize Dates as ISO strings. + + Date.prototype.toJSON = function (key) { + function f(n) { + // Format integers to have at least two digits. + return n < 10 ? '0' + n : n; + } + + return this.getUTCFullYear() + '-' + + f(this.getUTCMonth() + 1) + '-' + + f(this.getUTCDate()) + 'T' + + f(this.getUTCHours()) + ':' + + f(this.getUTCMinutes()) + ':' + + f(this.getUTCSeconds()) + 'Z'; + }; + + You can provide an optional replacer method. It will be passed the + key and value of each member, with this bound to the containing + object. The value that is returned from your method will be + serialized. If your method returns undefined, then the member will + be excluded from the serialization. + + If the replacer parameter is an array of strings, then it will be + used to select the members to be serialized. It filters the results + such that only members with keys listed in the replacer array are + stringified. + + Values that do not have JSON representations, such as undefined or + functions, will not be serialized. Such values in objects will be + dropped; in arrays they will be replaced with null. You can use + a replacer function to replace those with JSON values. + JSON.stringify(undefined) returns undefined. + + The optional space parameter produces a stringification of the + value that is filled with line breaks and indentation to make it + easier to read. + + If the space parameter is a non-empty string, then that string will + be used for indentation. If the space parameter is a number, then + the indentation will be that many spaces. + + Example: + + text = JSON.stringify(['e', {pluribus: 'unum'}]); + // text is '["e",{"pluribus":"unum"}]' + + + text = JSON.stringify(['e', {pluribus: 'unum'}], null, '\t'); + // text is '[\n\t"e",\n\t{\n\t\t"pluribus": "unum"\n\t}\n]' + + text = JSON.stringify([new Date()], function (key, value) { + return this[key] instanceof Date ? + 'Date(' + this[key] + ')' : value; + }); + // text is '["Date(---current time---)"]' + + + JSON.parse(text, reviver) + This method parses a JSON text to produce an object or array. + It can throw a SyntaxError exception. + + The optional reviver parameter is a function that can filter and + transform the results. It receives each of the keys and values, + and its return value is used instead of the original value. + If it returns what it received, then the structure is not modified. + If it returns undefined then the member is deleted. + + Example: + + // Parse the text. Values that look like ISO date strings will + // be converted to Date objects. + + myData = JSON.parse(text, function (key, value) { + var a; + if (typeof value === 'string') { + a = +/^(\d{4})-(\d{2})-(\d{2})T(\d{2}):(\d{2}):(\d{2}(?:\.\d*)?)Z$/.exec(value); + if (a) { + return new Date(Date.UTC(+a[1], +a[2] - 1, +a[3], +a[4], + +a[5], +a[6])); + } + } + return value; + }); + + myData = JSON.parse('["Date(09/09/2001)"]', function (key, value) { + var d; + if (typeof value === 'string' && + value.slice(0, 5) === 'Date(' && + value.slice(-1) === ')') { + d = new Date(value.slice(5, -1)); + if (d) { + return d; + } + } + return value; + }); + + + This is a reference implementation. You are free to copy, modify, or + redistribute. +*/ + +/*jslint evil: true, regexp: true */ + +/*members "", "\b", "\t", "\n", "\f", "\r", "\"", JSON, "\\", apply, + call, charCodeAt, getUTCDate, getUTCFullYear, getUTCHours, + getUTCMinutes, getUTCMonth, getUTCSeconds, hasOwnProperty, join, + lastIndex, length, parse, prototype, push, replace, slice, stringify, + test, toJSON, toString, valueOf +*/ + + +// Create a JSON object only if one does not already exist. We create the +// methods in a closure to avoid creating global variables. + +if (typeof JSON !== 'object') { + JSON = {}; +} + +(function () { + 'use strict'; + + function f(n) { + // Format integers to have at least two digits. + return n < 10 ? '0' + n : n; + } + + if (typeof Date.prototype.toJSON !== 'function') { + + Date.prototype.toJSON = function (key) { + + return isFinite(this.valueOf()) + ? this.getUTCFullYear() + '-' + + f(this.getUTCMonth() + 1) + '-' + + f(this.getUTCDate()) + 'T' + + f(this.getUTCHours()) + ':' + + f(this.getUTCMinutes()) + ':' + + f(this.getUTCSeconds()) + 'Z' + : null; + }; + + String.prototype.toJSON = + Number.prototype.toJSON = + Boolean.prototype.toJSON = function (key) { + return this.valueOf(); + }; + } + + var cx = /[\u0000\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g, + escapable = /[\\\"\x00-\x1f\x7f-\x9f\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g, + gap, + indent, + meta = { // table of character substitutions + '\b': '\\b', + '\t': '\\t', + '\n': '\\n', + '\f': '\\f', + '\r': '\\r', + '"' : '\\"', + '\\': '\\\\' + }, + rep; + + + function quote(string) { + +// If the string contains no control characters, no quote characters, and no +// backslash characters, then we can safely slap some quotes around it. +// Otherwise we must also replace the offending characters with safe escape +// sequences. + + escapable.lastIndex = 0; + return escapable.test(string) ? '"' + string.replace(escapable, function (a) { + var c = meta[a]; + return typeof c === 'string' + ? c + : '\\u' + ('0000' + a.charCodeAt(0).toString(16)).slice(-4); + }) + '"' : '"' + string + '"'; + } + + + function str(key, holder) { + +// Produce a string from holder[key]. + + var i, // The loop counter. + k, // The member key. + v, // The member value. + length, + mind = gap, + partial, + value = holder[key]; + +// If the value has a toJSON method, call it to obtain a replacement value. + + if (value && typeof value === 'object' && + typeof value.toJSON === 'function') { + value = value.toJSON(key); + } + +// If we were called with a replacer function, then call the replacer to +// obtain a replacement value. + + if (typeof rep === 'function') { + value = rep.call(holder, key, value); + } + +// What happens next depends on the value's type. + + switch (typeof value) { + case 'string': + return quote(value); + + case 'number': + +// JSON numbers must be finite. Encode non-finite numbers as null. + + return isFinite(value) ? String(value) : 'null'; + + case 'boolean': + case 'null': + +// If the value is a boolean or null, convert it to a string. Note: +// typeof null does not produce 'null'. The case is included here in +// the remote chance that this gets fixed someday. + + return String(value); + +// If the type is 'object', we might be dealing with an object or an array or +// null. + + case 'object': + +// Due to a specification blunder in ECMAScript, typeof null is 'object', +// so watch out for that case. + + if (!value) { + return 'null'; + } + +// Make an array to hold the partial results of stringifying this object value. + + gap += indent; + partial = []; + +// Is the value an array? + + if (Object.prototype.toString.apply(value) === '[object Array]') { + +// The value is an array. Stringify every element. Use null as a placeholder +// for non-JSON values. + + length = value.length; + for (i = 0; i < length; i += 1) { + partial[i] = str(i, value) || 'null'; + } + +// Join all of the elements together, separated with commas, and wrap them in +// brackets. + + v = partial.length === 0 + ? '[]' + : gap + ? '[\n' + gap + partial.join(',\n' + gap) + '\n' + mind + ']' + : '[' + partial.join(',') + ']'; + gap = mind; + return v; + } + +// If the replacer is an array, use it to select the members to be stringified. + + if (rep && typeof rep === 'object') { + length = rep.length; + for (i = 0; i < length; i += 1) { + if (typeof rep[i] === 'string') { + k = rep[i]; + v = str(k, value); + if (v) { + partial.push(quote(k) + (gap ? ': ' : ':') + v); + } + } + } + } else { + +// Otherwise, iterate through all of the keys in the object. + + for (k in value) { + if (Object.prototype.hasOwnProperty.call(value, k)) { + v = str(k, value); + if (v) { + partial.push(quote(k) + (gap ? ': ' : ':') + v); + } + } + } + } + +// Join all of the member texts together, separated with commas, +// and wrap them in braces. + + v = partial.length === 0 + ? '{}' + : gap + ? '{\n' + gap + partial.join(',\n' + gap) + '\n' + mind + '}' + : '{' + partial.join(',') + '}'; + gap = mind; + return v; + } + } + +// If the JSON object does not yet have a stringify method, give it one. + + if (typeof JSON.stringify !== 'function') { + JSON.stringify = function (value, replacer, space) { + +// The stringify method takes a value and an optional replacer, and an optional +// space parameter, and returns a JSON text. The replacer can be a function +// that can replace values, or an array of strings that will select the keys. +// A default replacer method can be provided. Use of the space parameter can +// produce text that is more easily readable. + + var i; + gap = ''; + indent = ''; + +// If the space parameter is a number, make an indent string containing that +// many spaces. + + if (typeof space === 'number') { + for (i = 0; i < space; i += 1) { + indent += ' '; + } + +// If the space parameter is a string, it will be used as the indent string. + + } else if (typeof space === 'string') { + indent = space; + } + +// If there is a replacer, it must be a function or an array. +// Otherwise, throw an error. + + rep = replacer; + if (replacer && typeof replacer !== 'function' && + (typeof replacer !== 'object' || + typeof replacer.length !== 'number')) { + throw new Error('JSON.stringify'); + } + +// Make a fake root object containing our value under the key of ''. +// Return the result of stringifying the value. + + return str('', {'': value}); + }; + } + + +// If the JSON object does not yet have a parse method, give it one. + + if (typeof JSON.parse !== 'function') { + JSON.parse = function (text, reviver) { + +// The parse method takes a text and an optional reviver function, and returns +// a JavaScript value if the text is a valid JSON text. + + var j; + + function walk(holder, key) { + +// The walk method is used to recursively walk the resulting structure so +// that modifications can be made. + + var k, v, value = holder[key]; + if (value && typeof value === 'object') { + for (k in value) { + if (Object.prototype.hasOwnProperty.call(value, k)) { + v = walk(value, k); + if (v !== undefined) { + value[k] = v; + } else { + delete value[k]; + } + } + } + } + return reviver.call(holder, key, value); + } + + +// Parsing happens in four stages. In the first stage, we replace certain +// Unicode characters with escape sequences. JavaScript handles many characters +// incorrectly, either silently deleting them, or treating them as line endings. + + text = String(text); + cx.lastIndex = 0; + if (cx.test(text)) { + text = text.replace(cx, function (a) { + return '\\u' + + ('0000' + a.charCodeAt(0).toString(16)).slice(-4); + }); + } + +// In the second stage, we run the text against regular expressions that look +// for non-JSON patterns. We are especially concerned with '()' and 'new' +// because they can cause invocation, and '=' because it can cause mutation. +// But just to be safe, we want to reject all unexpected forms. + +// We split the second stage into 4 regexp operations in order to work around +// crippling inefficiencies in IE's and Safari's regexp engines. First we +// replace the JSON backslash pairs with '@' (a non-JSON character). Second, we +// replace all simple value tokens with ']' characters. Third, we delete all +// open brackets that follow a colon or comma or that begin the text. Finally, +// we look to see that the remaining characters are only whitespace or ']' or +// ',' or ':' or '{' or '}'. If that is so, then the text is safe for eval. + + if (/^[\],:{}\s]*$/ + .test(text.replace(/\\(?:["\\\/bfnrt]|u[0-9a-fA-F]{4})/g, '@') + .replace(/"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g, ']') + .replace(/(?:^|:|,)(?:\s*\[)+/g, ''))) { + +// In the third stage we use the eval function to compile the text into a +// JavaScript structure. The '{' operator is subject to a syntactic ambiguity +// in JavaScript: it can begin a block or an object literal. We wrap the text +// in parens to eliminate the ambiguity. + + j = eval('(' + text + ')'); + +// In the optional fourth stage, we recursively walk the new structure, passing +// each name/value pair to a reviver function for possible transformation. + + return typeof reviver === 'function' + ? walk({'': j}, '') + : j; + } + +// If the text is not JSON parseable, then a SyntaxError is thrown. + + throw new SyntaxError('JSON.parse'); + }; + } +}());/** + * History.js RightJS Adapter + * @author Benjamin Arthur Lupton + * @copyright 2010-2011 Benjamin Arthur Lupton + * @license New BSD License + */ + +// Closure +(function(window,undefined){ + "use strict"; + + // Localise Globals + var + History = window.History = window.History||{}, + document = window.document, + RightJS = window.RightJS, + $ = RightJS.$; + + // Check Existence + if ( typeof History.Adapter !== 'undefined' ) { + throw new Error('History.js Adapter has already been loaded...'); + } + + // Add the Adapter + History.Adapter = { + /** + * History.Adapter.bind(el,event,callback) + * @param {Element|Selector} el + * @param {String} event - custom and standard events + * @param {Function} callback + * @return + */ + bind: function(el,event,callback){ + $(el).on(event,callback); + }, + + /** + * History.Adapter.trigger(el,event) + * @param {Element|Selector} el + * @param {String} event - custom and standard events + * @param {Object} extraEventData - a object of extra event data + * @return + */ + trigger: function(el,event,extraEventData){ + $(el).fire(event,extraEventData); + }, + + /** + * History.Adapter.extractEventData(key,event,extra) + * @param {String} key - key for the event data to extract + * @param {String} event - custom and standard events + * @return {mixed} + */ + extractEventData: function(key,event){ + // Right.js Native + // Right.js Custom + var result = (event && event._ && event._[key]) || undefined; + + // Return + return result; + }, + + /** + * History.Adapter.onDomLoad(callback) + * @param {Function} callback + * @return + */ + onDomLoad: function(callback) { + $(document).onReady(callback); + } + }; + + // Try and Initialise History + if ( typeof History.init !== 'undefined' ) { + History.init(); + } + +})(window); +/** + * History.js HTML4 Support + * Depends on the HTML5 Support + * @author Benjamin Arthur Lupton + * @copyright 2010-2011 Benjamin Arthur Lupton + * @license New BSD License + */ + +(function(window,undefined){ + "use strict"; + + // ======================================================================== + // Initialise + + // Localise Globals + var + document = window.document, // Make sure we are using the correct document + setTimeout = window.setTimeout||setTimeout, + clearTimeout = window.clearTimeout||clearTimeout, + setInterval = window.setInterval||setInterval, + History = window.History = window.History||{}; // Public History Object + + // Check Existence + if ( typeof History.initHtml4 !== 'undefined' ) { + throw new Error('History.js HTML4 Support has already been loaded...'); + } + + + // ======================================================================== + // Initialise HTML4 Support + + // Initialise HTML4 Support + History.initHtml4 = function(){ + // Initialise + if ( typeof History.initHtml4.initialized !== 'undefined' ) { + // Already Loaded + return false; + } + else { + History.initHtml4.initialized = true; + } + + + // ==================================================================== + // Properties + + /** + * History.enabled + * Is History enabled? + */ + History.enabled = true; + + + // ==================================================================== + // Hash Storage + + /** + * History.savedHashes + * Store the hashes in an array + */ + History.savedHashes = []; + + /** + * History.isLastHash(newHash) + * Checks if the hash is the last hash + * @param {string} newHash + * @return {boolean} true + */ + History.isLastHash = function(newHash){ + // Prepare + var oldHash = History.getHashByIndex(), + isLast; + + // Check + isLast = newHash === oldHash; + + // Return isLast + return isLast; + }; + + /** + * History.isHashEqual(newHash, oldHash) + * Checks to see if two hashes are functionally equal + * @param {string} newHash + * @param {string} oldHash + * @return {boolean} true + */ + History.isHashEqual = function(newHash, oldHash){ + newHash = encodeURIComponent(newHash).replace(/%25/g, "%"); + oldHash = encodeURIComponent(oldHash).replace(/%25/g, "%"); + return newHash === oldHash; + }; + + /** + * History.saveHash(newHash) + * Push a Hash + * @param {string} newHash + * @return {boolean} true + */ + History.saveHash = function(newHash){ + // Check Hash + if ( History.isLastHash(newHash) ) { + return false; + } + + // Push the Hash + History.savedHashes.push(newHash); + + // Return true + return true; + }; + + /** + * History.getHashByIndex() + * Gets a hash by the index + * @param {integer} index + * @return {string} + */ + History.getHashByIndex = function(index){ + // Prepare + var hash = null; + + // Handle + if ( typeof index === 'undefined' ) { + // Get the last inserted + hash = History.savedHashes[History.savedHashes.length-1]; + } + else if ( index < 0 ) { + // Get from the end + hash = History.savedHashes[History.savedHashes.length+index]; + } + else { + // Get from the beginning + hash = History.savedHashes[index]; + } + + // Return hash + return hash; + }; + + + // ==================================================================== + // Discarded States + + /** + * History.discardedHashes + * A hashed array of discarded hashes + */ + History.discardedHashes = {}; + + /** + * History.discardedStates + * A hashed array of discarded states + */ + History.discardedStates = {}; + + /** + * History.discardState(State) + * Discards the state by ignoring it through History + * @param {object} State + * @return {true} + */ + History.discardState = function(discardedState,forwardState,backState){ + //History.debug('History.discardState', arguments); + // Prepare + var discardedStateHash = History.getHashByState(discardedState), + discardObject; + + // Create Discard Object + discardObject = { + 'discardedState': discardedState, + 'backState': backState, + 'forwardState': forwardState + }; + + // Add to DiscardedStates + History.discardedStates[discardedStateHash] = discardObject; + + // Return true + return true; + }; + + /** + * History.discardHash(hash) + * Discards the hash by ignoring it through History + * @param {string} hash + * @return {true} + */ + History.discardHash = function(discardedHash,forwardState,backState){ + //History.debug('History.discardState', arguments); + // Create Discard Object + var discardObject = { + 'discardedHash': discardedHash, + 'backState': backState, + 'forwardState': forwardState + }; + + // Add to discardedHash + History.discardedHashes[discardedHash] = discardObject; + + // Return true + return true; + }; + + /** + * History.discardedState(State) + * Checks to see if the state is discarded + * @param {object} State + * @return {bool} + */ + History.discardedState = function(State){ + // Prepare + var StateHash = History.getHashByState(State), + discarded; + + // Check + discarded = History.discardedStates[StateHash]||false; + + // Return true + return discarded; + }; + + /** + * History.discardedHash(hash) + * Checks to see if the state is discarded + * @param {string} State + * @return {bool} + */ + History.discardedHash = function(hash){ + // Check + var discarded = History.discardedHashes[hash]||false; + + // Return true + return discarded; + }; + + /** + * History.recycleState(State) + * Allows a discarded state to be used again + * @param {object} data + * @param {string} title + * @param {string} url + * @return {true} + */ + History.recycleState = function(State){ + //History.debug('History.recycleState', arguments); + // Prepare + var StateHash = History.getHashByState(State); + + // Remove from DiscardedStates + if ( History.discardedState(State) ) { + delete History.discardedStates[StateHash]; + } + + // Return true + return true; + }; + + + // ==================================================================== + // HTML4 HashChange Support + + if ( History.emulated.hashChange ) { + /* + * We must emulate the HTML4 HashChange Support by manually checking for hash changes + */ + + /** + * History.hashChangeInit() + * Init the HashChange Emulation + */ + History.hashChangeInit = function(){ + // Define our Checker Function + History.checkerFunction = null; + + // Define some variables that will help in our checker function + var lastDocumentHash = '', + iframeId, iframe, + lastIframeHash, checkerRunning, + startedWithHash = Boolean(History.getHash()); + + // Handle depending on the browser + if ( History.isInternetExplorer() ) { + // IE6 and IE7 + // We need to use an iframe to emulate the back and forward buttons + + // Create iFrame + iframeId = 'historyjs-iframe'; + iframe = document.createElement('iframe'); + + // Adjust iFarme + // IE 6 requires iframe to have a src on HTTPS pages, otherwise it will throw a + // "This page contains both secure and nonsecure items" warning. + iframe.setAttribute('id', iframeId); + iframe.setAttribute('src', '#'); + iframe.style.display = 'none'; + + // Append iFrame + document.body.appendChild(iframe); + + // Create initial history entry + iframe.contentWindow.document.open(); + iframe.contentWindow.document.close(); + + // Define some variables that will help in our checker function + lastIframeHash = ''; + checkerRunning = false; + + // Define the checker function + History.checkerFunction = function(){ + // Check Running + if ( checkerRunning ) { + return false; + } + + // Update Running + checkerRunning = true; + + // Fetch + var + documentHash = History.getHash(), + iframeHash = History.getHash(iframe.contentWindow.document); + + // The Document Hash has changed (application caused) + if ( documentHash !== lastDocumentHash ) { + // Equalise + lastDocumentHash = documentHash; + + // Create a history entry in the iframe + if ( iframeHash !== documentHash ) { + //History.debug('hashchange.checker: iframe hash change', 'documentHash (new):', documentHash, 'iframeHash (old):', iframeHash); + + // Equalise + lastIframeHash = iframeHash = documentHash; + + // Create History Entry + iframe.contentWindow.document.open(); + iframe.contentWindow.document.close(); + + // Update the iframe's hash + iframe.contentWindow.document.location.hash = History.escapeHash(documentHash); + } + + // Trigger Hashchange Event + History.Adapter.trigger(window,'hashchange'); + } + + // The iFrame Hash has changed (back button caused) + else if ( iframeHash !== lastIframeHash ) { + //History.debug('hashchange.checker: iframe hash out of sync', 'iframeHash (new):', iframeHash, 'documentHash (old):', documentHash); + + // Equalise + lastIframeHash = iframeHash; + + // If there is no iframe hash that means we're at the original + // iframe state. + // And if there was a hash on the original request, the original + // iframe state was replaced instantly, so skip this state and take + // the user back to where they came from. + if (startedWithHash && iframeHash === '') { + History.back(); + } + else { + // Update the Hash + History.setHash(iframeHash,false); + } + } + + // Reset Running + checkerRunning = false; + + // Return true + return true; + }; + } + else { + // We are not IE + // Firefox 1 or 2, Opera + + // Define the checker function + History.checkerFunction = function(){ + // Prepare + var documentHash = History.getHash()||''; + + // The Document Hash has changed (application caused) + if ( documentHash !== lastDocumentHash ) { + // Equalise + lastDocumentHash = documentHash; + + // Trigger Hashchange Event + History.Adapter.trigger(window,'hashchange'); + } + + // Return true + return true; + }; + } + + // Apply the checker function + History.intervalList.push(setInterval(History.checkerFunction, History.options.hashChangeInterval)); + + // Done + return true; + }; // History.hashChangeInit + + // Bind hashChangeInit + History.Adapter.onDomLoad(History.hashChangeInit); + + } // History.emulated.hashChange + + + // ==================================================================== + // HTML5 State Support + + // Non-Native pushState Implementation + if ( History.emulated.pushState ) { + /* + * We must emulate the HTML5 State Management by using HTML4 HashChange + */ + + /** + * History.onHashChange(event) + * Trigger HTML5's window.onpopstate via HTML4 HashChange Support + */ + History.onHashChange = function(event){ + //History.debug('History.onHashChange', arguments); + + // Prepare + var currentUrl = ((event && event.newURL) || History.getLocationHref()), + currentHash = History.getHashByUrl(currentUrl), + currentState = null, + currentStateHash = null, + currentStateHashExits = null, + discardObject; + + // Check if we are the same state + if ( History.isLastHash(currentHash) ) { + // There has been no change (just the page's hash has finally propagated) + //History.debug('History.onHashChange: no change'); + History.busy(false); + return false; + } + + // Reset the double check + History.doubleCheckComplete(); + + // Store our location for use in detecting back/forward direction + History.saveHash(currentHash); + + // Expand Hash + if ( currentHash && History.isTraditionalAnchor(currentHash) ) { + //History.debug('History.onHashChange: traditional anchor', currentHash); + // Traditional Anchor Hash + History.Adapter.trigger(window,'anchorchange'); + History.busy(false); + return false; + } + + // Create State + currentState = History.extractState(History.getFullUrl(currentHash||History.getLocationHref()),true); + + // Check if we are the same state + if ( History.isLastSavedState(currentState) ) { + //History.debug('History.onHashChange: no change'); + // There has been no change (just the page's hash has finally propagated) + History.busy(false); + return false; + } + + // Create the state Hash + currentStateHash = History.getHashByState(currentState); + + // Check if we are DiscardedState + discardObject = History.discardedState(currentState); + if ( discardObject ) { + // Ignore this state as it has been discarded and go back to the state before it + if ( History.getHashByIndex(-2) === History.getHashByState(discardObject.forwardState) ) { + // We are going backwards + //History.debug('History.onHashChange: go backwards'); + History.back(false); + } else { + // We are going forwards + //History.debug('History.onHashChange: go forwards'); + History.forward(false); + } + return false; + } + + // Push the new HTML5 State + //History.debug('History.onHashChange: success hashchange'); + History.pushState(currentState.data,currentState.title,encodeURI(currentState.url),false); + + // End onHashChange closure + return true; + }; + History.Adapter.bind(window,'hashchange',History.onHashChange); + + /** + * History.pushState(data,title,url) + * Add a new State to the history object, become it, and trigger onpopstate + * We have to trigger for HTML4 compatibility + * @param {object} data + * @param {string} title + * @param {string} url + * @return {true} + */ + History.pushState = function(data,title,url,queue){ + //History.debug('History.pushState: called', arguments); + + // We assume that the URL passed in is URI-encoded, but this makes + // sure that it's fully URI encoded; any '%'s that are encoded are + // converted back into '%'s + url = encodeURI(url).replace(/%25/g, "%"); + + // Check the State + if ( History.getHashByUrl(url) ) { + throw new Error('History.js does not support states with fragment-identifiers (hashes/anchors).'); + } + + // Handle Queueing + if ( queue !== false && History.busy() ) { + // Wait + Push to Queue + //History.debug('History.pushState: we must wait', arguments); + History.pushQueue({ + scope: History, + callback: History.pushState, + args: arguments, + queue: queue + }); + return false; + } + + // Make Busy + History.busy(true); + + // Fetch the State Object + var newState = History.createStateObject(data,title,url), + newStateHash = History.getHashByState(newState), + oldState = History.getState(false), + oldStateHash = History.getHashByState(oldState), + html4Hash = History.getHash(), + wasExpected = History.expectedStateId == newState.id; + + // Store the newState + History.storeState(newState); + History.expectedStateId = newState.id; + + // Recycle the State + History.recycleState(newState); + + // Force update of the title + History.setTitle(newState); + + // Check if we are the same State + if ( newStateHash === oldStateHash ) { + //History.debug('History.pushState: no change', newStateHash); + History.busy(false); + return false; + } + + // Update HTML5 State + History.saveState(newState); + + // Fire HTML5 Event + if(!wasExpected) + History.Adapter.trigger(window,'statechange'); + + // Update HTML4 Hash + if ( !History.isHashEqual(newStateHash, html4Hash) && !History.isHashEqual(newStateHash, History.getShortUrl(History.getLocationHref())) ) { + History.setHash(newStateHash,false); + } + + History.busy(false); + + // End pushState closure + return true; + }; + + /** + * History.replaceState(data,title,url) + * Replace the State and trigger onpopstate + * We have to trigger for HTML4 compatibility + * @param {object} data + * @param {string} title + * @param {string} url + * @return {true} + */ + History.replaceState = function(data,title,url,queue){ + //History.debug('History.replaceState: called', arguments); + + // We assume that the URL passed in is URI-encoded, but this makes + // sure that it's fully URI encoded; any '%'s that are encoded are + // converted back into '%'s + url = encodeURI(url).replace(/%25/g, "%"); + + // Check the State + if ( History.getHashByUrl(url) ) { + throw new Error('History.js does not support states with fragment-identifiers (hashes/anchors).'); + } + + // Handle Queueing + if ( queue !== false && History.busy() ) { + // Wait + Push to Queue + //History.debug('History.replaceState: we must wait', arguments); + History.pushQueue({ + scope: History, + callback: History.replaceState, + args: arguments, + queue: queue + }); + return false; + } + + // Make Busy + History.busy(true); + + // Fetch the State Objects + var newState = History.createStateObject(data,title,url), + newStateHash = History.getHashByState(newState), + oldState = History.getState(false), + oldStateHash = History.getHashByState(oldState), + previousState = History.getStateByIndex(-2); + + // Discard Old State + History.discardState(oldState,newState,previousState); + + // If the url hasn't changed, just store and save the state + // and fire a statechange event to be consistent with the + // html 5 api + if ( newStateHash === oldStateHash ) { + // Store the newState + History.storeState(newState); + History.expectedStateId = newState.id; + + // Recycle the State + History.recycleState(newState); + + // Force update of the title + History.setTitle(newState); + + // Update HTML5 State + History.saveState(newState); + + // Fire HTML5 Event + //History.debug('History.pushState: trigger popstate'); + History.Adapter.trigger(window,'statechange'); + History.busy(false); + } + else { + // Alias to PushState + History.pushState(newState.data,newState.title,newState.url,false); + } + + // End replaceState closure + return true; + }; + + } // History.emulated.pushState + + + + // ==================================================================== + // Initialise + + // Non-Native pushState Implementation + if ( History.emulated.pushState ) { + /** + * Ensure initial state is handled correctly + */ + if ( History.getHash() && !History.emulated.hashChange ) { + History.Adapter.onDomLoad(function(){ + History.Adapter.trigger(window,'hashchange'); + }); + } + + } // History.emulated.pushState + + }; // History.initHtml4 + + // Try to Initialise History + if ( typeof History.init !== 'undefined' ) { + History.init(); + } + +})(window); +/** + * History.js Core + * @author Benjamin Arthur Lupton + * @copyright 2010-2011 Benjamin Arthur Lupton + * @license New BSD License + */ + +(function(window,undefined){ + "use strict"; + + // ======================================================================== + // Initialise + + // Localise Globals + var + console = window.console||undefined, // Prevent a JSLint complain + document = window.document, // Make sure we are using the correct document + navigator = window.navigator, // Make sure we are using the correct navigator + sessionStorage = window.sessionStorage||false, // sessionStorage + setTimeout = window.setTimeout, + clearTimeout = window.clearTimeout, + setInterval = window.setInterval, + clearInterval = window.clearInterval, + JSON = window.JSON, + alert = window.alert, + History = window.History = window.History||{}, // Public History Object + history = window.history; // Old History Object + + try { + sessionStorage.setItem('TEST', '1'); + sessionStorage.removeItem('TEST'); + } catch(e) { + sessionStorage = false; + } + + // MooTools Compatibility + JSON.stringify = JSON.stringify||JSON.encode; + JSON.parse = JSON.parse||JSON.decode; + + // Check Existence + if ( typeof History.init !== 'undefined' ) { + throw new Error('History.js Core has already been loaded...'); + } + + // Initialise History + History.init = function(options){ + // Check Load Status of Adapter + if ( typeof History.Adapter === 'undefined' ) { + return false; + } + + // Check Load Status of Core + if ( typeof History.initCore !== 'undefined' ) { + History.initCore(); + } + + // Check Load Status of HTML4 Support + if ( typeof History.initHtml4 !== 'undefined' ) { + History.initHtml4(); + } + + // Return true + return true; + }; + + + // ======================================================================== + // Initialise Core + + // Initialise Core + History.initCore = function(options){ + // Initialise + if ( typeof History.initCore.initialized !== 'undefined' ) { + // Already Loaded + return false; + } + else { + History.initCore.initialized = true; + } + + + // ==================================================================== + // Options + + /** + * History.options + * Configurable options + */ + History.options = History.options||{}; + + /** + * History.options.hashChangeInterval + * How long should the interval be before hashchange checks + */ + History.options.hashChangeInterval = History.options.hashChangeInterval || 100; + + /** + * History.options.safariPollInterval + * How long should the interval be before safari poll checks + */ + History.options.safariPollInterval = History.options.safariPollInterval || 500; + + /** + * History.options.doubleCheckInterval + * How long should the interval be before we perform a double check + */ + History.options.doubleCheckInterval = History.options.doubleCheckInterval || 500; + + /** + * History.options.disableSuid + * Force History not to append suid + */ + History.options.disableSuid = History.options.disableSuid || false; + + /** + * History.options.storeInterval + * How long should we wait between store calls + */ + History.options.storeInterval = History.options.storeInterval || 1000; + + /** + * History.options.busyDelay + * How long should we wait between busy events + */ + History.options.busyDelay = History.options.busyDelay || 250; + + /** + * History.options.debug + * If true will enable debug messages to be logged + */ + History.options.debug = History.options.debug || false; + + /** + * History.options.initialTitle + * What is the title of the initial state + */ + History.options.initialTitle = History.options.initialTitle || document.title; + + /** + * History.options.html4Mode + * If true, will force HTMl4 mode (hashtags) + */ + History.options.html4Mode = History.options.html4Mode || false; + + /** + * History.options.delayInit + * Want to override default options and call init manually. + */ + History.options.delayInit = History.options.delayInit || false; + + + // ==================================================================== + // Interval record + + /** + * History.intervalList + * List of intervals set, to be cleared when document is unloaded. + */ + History.intervalList = []; + + /** + * History.clearAllIntervals + * Clears all setInterval instances. + */ + History.clearAllIntervals = function(){ + var i, il = History.intervalList; + if (typeof il !== "undefined" && il !== null) { + for (i = 0; i < il.length; i++) { + clearInterval(il[i]); + } + History.intervalList = null; + } + }; + + + // ==================================================================== + // Debug + + /** + * History.debug(message,...) + * Logs the passed arguments if debug enabled + */ + History.debug = function(){ + if ( (History.options.debug||false) ) { + History.log.apply(History,arguments); + } + }; + + /** + * History.log(message,...) + * Logs the passed arguments + */ + History.log = function(){ + // Prepare + var + consoleExists = !(typeof console === 'undefined' || typeof console.log === 'undefined' || typeof console.log.apply === 'undefined'), + textarea = document.getElementById('log'), + message, + i,n, + args,arg + ; + + // Write to Console + if ( consoleExists ) { + args = Array.prototype.slice.call(arguments); + message = args.shift(); + if ( typeof console.debug !== 'undefined' ) { + console.debug.apply(console,[message,args]); + } + else { + console.log.apply(console,[message,args]); + } + } + else { + message = ("\n"+arguments[0]+"\n"); + } + + // Write to log + for ( i=1,n=arguments.length; i + * @author James Padolsey + */ + History.getInternetExplorerMajorVersion = function(){ + var result = History.getInternetExplorerMajorVersion.cached = + (typeof History.getInternetExplorerMajorVersion.cached !== 'undefined') + ? History.getInternetExplorerMajorVersion.cached + : (function(){ + var v = 3, + div = document.createElement('div'), + all = div.getElementsByTagName('i'); + while ( (div.innerHTML = '') && all[0] ) {} + return (v > 4) ? v : false; + })() + ; + return result; + }; + + /** + * History.isInternetExplorer() + * Are we using Internet Explorer? + * @return {boolean} + * @license Public Domain + * @author Benjamin Arthur Lupton + */ + History.isInternetExplorer = function(){ + var result = + History.isInternetExplorer.cached = + (typeof History.isInternetExplorer.cached !== 'undefined') + ? History.isInternetExplorer.cached + : Boolean(History.getInternetExplorerMajorVersion()) + ; + return result; + }; + + /** + * History.emulated + * Which features require emulating? + */ + + if (History.options.html4Mode) { + History.emulated = { + pushState : true, + hashChange: true + }; + } + + else { + + History.emulated = { + pushState: !Boolean( + window.history && window.history.pushState && window.history.replaceState + && !( + (/ Mobile\/([1-7][a-z]|(8([abcde]|f(1[0-8]))))/i).test(navigator.userAgent) /* disable for versions of iOS before version 4.3 (8F190) */ + || (/AppleWebKit\/5([0-2]|3[0-2])/i).test(navigator.userAgent) /* disable for the mercury iOS browser, or at least older versions of the webkit engine */ + ) + ), + hashChange: Boolean( + !(('onhashchange' in window) || ('onhashchange' in document)) + || + (History.isInternetExplorer() && History.getInternetExplorerMajorVersion() < 8) + ) + }; + } + + /** + * History.enabled + * Is History enabled? + */ + History.enabled = !History.emulated.pushState; + + /** + * History.bugs + * Which bugs are present + */ + History.bugs = { + /** + * Safari 5 and Safari iOS 4 fail to return to the correct state once a hash is replaced by a `replaceState` call + * https://bugs.webkit.org/show_bug.cgi?id=56249 + */ + setHash: Boolean(!History.emulated.pushState && navigator.vendor === 'Apple Computer, Inc.' && /AppleWebKit\/5([0-2]|3[0-3])/.test(navigator.userAgent)), + + /** + * Safari 5 and Safari iOS 4 sometimes fail to apply the state change under busy conditions + * https://bugs.webkit.org/show_bug.cgi?id=42940 + */ + safariPoll: Boolean(!History.emulated.pushState && navigator.vendor === 'Apple Computer, Inc.' && /AppleWebKit\/5([0-2]|3[0-3])/.test(navigator.userAgent)), + + /** + * MSIE 6 and 7 sometimes do not apply a hash even it was told to (requiring a second call to the apply function) + */ + ieDoubleCheck: Boolean(History.isInternetExplorer() && History.getInternetExplorerMajorVersion() < 8), + + /** + * MSIE 6 requires the entire hash to be encoded for the hashes to trigger the onHashChange event + */ + hashEscape: Boolean(History.isInternetExplorer() && History.getInternetExplorerMajorVersion() < 7) + }; + + /** + * History.isEmptyObject(obj) + * Checks to see if the Object is Empty + * @param {Object} obj + * @return {boolean} + */ + History.isEmptyObject = function(obj) { + for ( var name in obj ) { + if ( obj.hasOwnProperty(name) ) { + return false; + } + } + return true; + }; + + /** + * History.cloneObject(obj) + * Clones a object and eliminate all references to the original contexts + * @param {Object} obj + * @return {Object} + */ + History.cloneObject = function(obj) { + var hash,newObj; + if ( obj ) { + hash = JSON.stringify(obj); + newObj = JSON.parse(hash); + } + else { + newObj = {}; + } + return newObj; + }; + + + // ==================================================================== + // URL Helpers + + /** + * History.getRootUrl() + * Turns "http://mysite.com/dir/page.html?asd" into "http://mysite.com" + * @return {String} rootUrl + */ + History.getRootUrl = function(){ + // Create + var rootUrl = document.location.protocol+'//'+(document.location.hostname||document.location.host); + if ( document.location.port||false ) { + rootUrl += ':'+document.location.port; + } + rootUrl += '/'; + + // Return + return rootUrl; + }; + + /** + * History.getBaseHref() + * Fetches the `href` attribute of the `` element if it exists + * @return {String} baseHref + */ + History.getBaseHref = function(){ + // Create + var + baseElements = document.getElementsByTagName('base'), + baseElement = null, + baseHref = ''; + + // Test for Base Element + if ( baseElements.length === 1 ) { + // Prepare for Base Element + baseElement = baseElements[0]; + baseHref = baseElement.href.replace(/[^\/]+$/,''); + } + + // Adjust trailing slash + baseHref = baseHref.replace(/\/+$/,''); + if ( baseHref ) baseHref += '/'; + + // Return + return baseHref; + }; + + /** + * History.getBaseUrl() + * Fetches the baseHref or basePageUrl or rootUrl (whichever one exists first) + * @return {String} baseUrl + */ + History.getBaseUrl = function(){ + // Create + var baseUrl = History.getBaseHref()||History.getBasePageUrl()||History.getRootUrl(); + + // Return + return baseUrl; + }; + + /** + * History.getPageUrl() + * Fetches the URL of the current page + * @return {String} pageUrl + */ + History.getPageUrl = function(){ + // Fetch + var + State = History.getState(false,false), + stateUrl = (State||{}).url||History.getLocationHref(), + pageUrl; + + // Create + pageUrl = stateUrl.replace(/\/+$/,'').replace(/[^\/]+$/,function(part,index,string){ + return (/\./).test(part) ? part : part+'/'; + }); + + // Return + return pageUrl; + }; + + /** + * History.getBasePageUrl() + * Fetches the Url of the directory of the current page + * @return {String} basePageUrl + */ + History.getBasePageUrl = function(){ + // Create + var basePageUrl = (History.getLocationHref()).replace(/[#\?].*/,'').replace(/[^\/]+$/,function(part,index,string){ + return (/[^\/]$/).test(part) ? '' : part; + }).replace(/\/+$/,'')+'/'; + + // Return + return basePageUrl; + }; + + /** + * History.getFullUrl(url) + * Ensures that we have an absolute URL and not a relative URL + * @param {string} url + * @param {Boolean} allowBaseHref + * @return {string} fullUrl + */ + History.getFullUrl = function(url,allowBaseHref){ + // Prepare + var fullUrl = url, firstChar = url.substring(0,1); + allowBaseHref = (typeof allowBaseHref === 'undefined') ? true : allowBaseHref; + + // Check + if ( /[a-z]+\:\/\//.test(url) ) { + // Full URL + } + else if ( firstChar === '/' ) { + // Root URL + fullUrl = History.getRootUrl()+url.replace(/^\/+/,''); + } + else if ( firstChar === '#' ) { + // Anchor URL + fullUrl = History.getPageUrl().replace(/#.*/,'')+url; + } + else if ( firstChar === '?' ) { + // Query URL + fullUrl = History.getPageUrl().replace(/[\?#].*/,'')+url; + } + else { + // Relative URL + if ( allowBaseHref ) { + fullUrl = History.getBaseUrl()+url.replace(/^(\.\/)+/,''); + } else { + fullUrl = History.getBasePageUrl()+url.replace(/^(\.\/)+/,''); + } + // We have an if condition above as we do not want hashes + // which are relative to the baseHref in our URLs + // as if the baseHref changes, then all our bookmarks + // would now point to different locations + // whereas the basePageUrl will always stay the same + } + + // Return + return fullUrl.replace(/\#$/,''); + }; + + /** + * History.getShortUrl(url) + * Ensures that we have a relative URL and not a absolute URL + * @param {string} url + * @return {string} url + */ + History.getShortUrl = function(url){ + // Prepare + var shortUrl = url, baseUrl = History.getBaseUrl(), rootUrl = History.getRootUrl(); + + // Trim baseUrl + if ( History.emulated.pushState ) { + // We are in a if statement as when pushState is not emulated + // The actual url these short urls are relative to can change + // So within the same session, we the url may end up somewhere different + shortUrl = shortUrl.replace(baseUrl,''); + } + + // Trim rootUrl + shortUrl = shortUrl.replace(rootUrl,'/'); + + // Ensure we can still detect it as a state + if ( History.isTraditionalAnchor(shortUrl) ) { + shortUrl = './'+shortUrl; + } + + // Clean It + shortUrl = shortUrl.replace(/^(\.\/)+/g,'./').replace(/\#$/,''); + + // Return + return shortUrl; + }; + + /** + * History.getLocationHref(document) + * Returns a normalized version of document.location.href + * accounting for browser inconsistencies, etc. + * + * This URL will be URI-encoded and will include the hash + * + * @param {object} document + * @return {string} url + */ + History.getLocationHref = function(doc) { + doc = doc || document; + + // most of the time, this will be true + if (doc.URL === doc.location.href) + return doc.location.href; + + // some versions of webkit URI-decode document.location.href + // but they leave document.URL in an encoded state + if (doc.location.href === decodeURIComponent(doc.URL)) + return doc.URL; + + // FF 3.6 only updates document.URL when a page is reloaded + // document.location.href is updated correctly + if (doc.location.hash && decodeURIComponent(doc.location.href.replace(/^[^#]+/, "")) === doc.location.hash) + return doc.location.href; + + if (doc.URL.indexOf('#') == -1 && doc.location.href.indexOf('#') != -1) + return doc.location.href; + + return doc.URL || doc.location.href; + }; + + + // ==================================================================== + // State Storage + + /** + * History.store + * The store for all session specific data + */ + History.store = {}; + + /** + * History.idToState + * 1-1: State ID to State Object + */ + History.idToState = History.idToState||{}; + + /** + * History.stateToId + * 1-1: State String to State ID + */ + History.stateToId = History.stateToId||{}; + + /** + * History.urlToId + * 1-1: State URL to State ID + */ + History.urlToId = History.urlToId||{}; + + /** + * History.storedStates + * Store the states in an array + */ + History.storedStates = History.storedStates||[]; + + /** + * History.savedStates + * Saved the states in an array + */ + History.savedStates = History.savedStates||[]; + + /** + * History.noramlizeStore() + * Noramlize the store by adding necessary values + */ + History.normalizeStore = function(){ + History.store.idToState = History.store.idToState||{}; + History.store.urlToId = History.store.urlToId||{}; + History.store.stateToId = History.store.stateToId||{}; + }; + + /** + * History.getState() + * Get an object containing the data, title and url of the current state + * @param {Boolean} friendly + * @param {Boolean} create + * @return {Object} State + */ + History.getState = function(friendly,create){ + // Prepare + if ( typeof friendly === 'undefined' ) { friendly = true; } + if ( typeof create === 'undefined' ) { create = true; } + + // Fetch + var State = History.getLastSavedState(); + + // Create + if ( !State && create ) { + State = History.createStateObject(); + } + + // Adjust + if ( friendly ) { + State = History.cloneObject(State); + State.url = State.cleanUrl||State.url; + } + + // Return + return State; + }; + + /** + * History.getIdByState(State) + * Gets a ID for a State + * @param {State} newState + * @return {String} id + */ + History.getIdByState = function(newState){ + + // Fetch ID + var id = History.extractId(newState.url), + str; + + if ( !id ) { + // Find ID via State String + str = History.getStateString(newState); + if ( typeof History.stateToId[str] !== 'undefined' ) { + id = History.stateToId[str]; + } + else if ( typeof History.store.stateToId[str] !== 'undefined' ) { + id = History.store.stateToId[str]; + } + else { + // Generate a new ID + while ( true ) { + id = (new Date()).getTime() + String(Math.random()).replace(/\D/g,''); + if ( typeof History.idToState[id] === 'undefined' && typeof History.store.idToState[id] === 'undefined' ) { + break; + } + } + + // Apply the new State to the ID + History.stateToId[str] = id; + History.idToState[id] = newState; + } + } + + // Return ID + return id; + }; + + /** + * History.normalizeState(State) + * Expands a State Object + * @param {object} State + * @return {object} + */ + History.normalizeState = function(oldState){ + // Variables + var newState, dataNotEmpty; + + // Prepare + if ( !oldState || (typeof oldState !== 'object') ) { + oldState = {}; + } + + // Check + if ( typeof oldState.normalized !== 'undefined' ) { + return oldState; + } + + // Adjust + if ( !oldState.data || (typeof oldState.data !== 'object') ) { + oldState.data = {}; + } + + // ---------------------------------------------------------------- + + // Create + newState = {}; + newState.normalized = true; + newState.title = oldState.title||''; + newState.url = History.getFullUrl(oldState.url?oldState.url:(History.getLocationHref())); + newState.hash = History.getShortUrl(newState.url); + newState.data = History.cloneObject(oldState.data); + + // Fetch ID + newState.id = History.getIdByState(newState); + + // ---------------------------------------------------------------- + + // Clean the URL + newState.cleanUrl = newState.url.replace(/\??\&_suid.*/,''); + newState.url = newState.cleanUrl; + + // Check to see if we have more than just a url + dataNotEmpty = !History.isEmptyObject(newState.data); + + // Apply + if ( (newState.title || dataNotEmpty) && History.options.disableSuid !== true ) { + // Add ID to Hash + newState.hash = History.getShortUrl(newState.url).replace(/\??\&_suid.*/,''); + if ( !/\?/.test(newState.hash) ) { + newState.hash += '?'; + } + newState.hash += '&_suid='+newState.id; + } + + // Create the Hashed URL + newState.hashedUrl = History.getFullUrl(newState.hash); + + // ---------------------------------------------------------------- + + // Update the URL if we have a duplicate + if ( (History.emulated.pushState || History.bugs.safariPoll) && History.hasUrlDuplicate(newState) ) { + newState.url = newState.hashedUrl; + } + + // ---------------------------------------------------------------- + + // Return + return newState; + }; + + /** + * History.createStateObject(data,title,url) + * Creates a object based on the data, title and url state params + * @param {object} data + * @param {string} title + * @param {string} url + * @return {object} + */ + History.createStateObject = function(data,title,url){ + // Hashify + var State = { + 'data': data, + 'title': title, + 'url': url + }; + + // Expand the State + State = History.normalizeState(State); + + // Return object + return State; + }; + + /** + * History.getStateById(id) + * Get a state by it's UID + * @param {String} id + */ + History.getStateById = function(id){ + // Prepare + id = String(id); + + // Retrieve + var State = History.idToState[id] || History.store.idToState[id] || undefined; + + // Return State + return State; + }; + + /** + * Get a State's String + * @param {State} passedState + */ + History.getStateString = function(passedState){ + // Prepare + var State, cleanedState, str; + + // Fetch + State = History.normalizeState(passedState); + + // Clean + cleanedState = { + data: State.data, + title: passedState.title, + url: passedState.url + }; + + // Fetch + str = JSON.stringify(cleanedState); + + // Return + return str; + }; + + /** + * Get a State's ID + * @param {State} passedState + * @return {String} id + */ + History.getStateId = function(passedState){ + // Prepare + var State, id; + + // Fetch + State = History.normalizeState(passedState); + + // Fetch + id = State.id; + + // Return + return id; + }; + + /** + * History.getHashByState(State) + * Creates a Hash for the State Object + * @param {State} passedState + * @return {String} hash + */ + History.getHashByState = function(passedState){ + // Prepare + var State, hash; + + // Fetch + State = History.normalizeState(passedState); + + // Hash + hash = State.hash; + + // Return + return hash; + }; + + /** + * History.extractId(url_or_hash) + * Get a State ID by it's URL or Hash + * @param {string} url_or_hash + * @return {string} id + */ + History.extractId = function ( url_or_hash ) { + // Prepare + var id,parts,url, tmp; + + // Extract + + // If the URL has a #, use the id from before the # + if (url_or_hash.indexOf('#') != -1) + { + tmp = url_or_hash.split("#")[0]; + } + else + { + tmp = url_or_hash; + } + + parts = /(.*)\&_suid=([0-9]+)$/.exec(tmp); + url = parts ? (parts[1]||url_or_hash) : url_or_hash; + id = parts ? String(parts[2]||'') : ''; + + // Return + return id||false; + }; + + /** + * History.isTraditionalAnchor + * Checks to see if the url is a traditional anchor or not + * @param {String} url_or_hash + * @return {Boolean} + */ + History.isTraditionalAnchor = function(url_or_hash){ + // Check + var isTraditional = !(/[\/\?\.]/.test(url_or_hash)); + + // Return + return isTraditional; + }; + + /** + * History.extractState + * Get a State by it's URL or Hash + * @param {String} url_or_hash + * @return {State|null} + */ + History.extractState = function(url_or_hash,create){ + // Prepare + var State = null, id, url; + create = create||false; + + // Fetch SUID + id = History.extractId(url_or_hash); + if ( id ) { + State = History.getStateById(id); + } + + // Fetch SUID returned no State + if ( !State ) { + // Fetch URL + url = History.getFullUrl(url_or_hash); + + // Check URL + id = History.getIdByUrl(url)||false; + if ( id ) { + State = History.getStateById(id); + } + + // Create State + if ( !State && create && !History.isTraditionalAnchor(url_or_hash) ) { + State = History.createStateObject(null,null,url); + } + } + + // Return + return State; + }; + + /** + * History.getIdByUrl() + * Get a State ID by a State URL + */ + History.getIdByUrl = function(url){ + // Fetch + var id = History.urlToId[url] || History.store.urlToId[url] || undefined; + + // Return + return id; + }; + + /** + * History.getLastSavedState() + * Get an object containing the data, title and url of the current state + * @return {Object} State + */ + History.getLastSavedState = function(){ + return History.savedStates[History.savedStates.length-1]||undefined; + }; + + /** + * History.getLastStoredState() + * Get an object containing the data, title and url of the current state + * @return {Object} State + */ + History.getLastStoredState = function(){ + return History.storedStates[History.storedStates.length-1]||undefined; + }; + + /** + * History.hasUrlDuplicate + * Checks if a Url will have a url conflict + * @param {Object} newState + * @return {Boolean} hasDuplicate + */ + History.hasUrlDuplicate = function(newState) { + // Prepare + var hasDuplicate = false, + oldState; + + // Fetch + oldState = History.extractState(newState.url); + + // Check + hasDuplicate = oldState && oldState.id !== newState.id; + + // Return + return hasDuplicate; + }; + + /** + * History.storeState + * Store a State + * @param {Object} newState + * @return {Object} newState + */ + History.storeState = function(newState){ + // Store the State + History.urlToId[newState.url] = newState.id; + + // Push the State + History.storedStates.push(History.cloneObject(newState)); + + // Return newState + return newState; + }; + + /** + * History.isLastSavedState(newState) + * Tests to see if the state is the last state + * @param {Object} newState + * @return {boolean} isLast + */ + History.isLastSavedState = function(newState){ + // Prepare + var isLast = false, + newId, oldState, oldId; + + // Check + if ( History.savedStates.length ) { + newId = newState.id; + oldState = History.getLastSavedState(); + oldId = oldState.id; + + // Check + isLast = (newId === oldId); + } + + // Return + return isLast; + }; + + /** + * History.saveState + * Push a State + * @param {Object} newState + * @return {boolean} changed + */ + History.saveState = function(newState){ + // Check Hash + if ( History.isLastSavedState(newState) ) { + return false; + } + + // Push the State + History.savedStates.push(History.cloneObject(newState)); + + // Return true + return true; + }; + + /** + * History.getStateByIndex() + * Gets a state by the index + * @param {integer} index + * @return {Object} + */ + History.getStateByIndex = function(index){ + // Prepare + var State = null; + + // Handle + if ( typeof index === 'undefined' ) { + // Get the last inserted + State = History.savedStates[History.savedStates.length-1]; + } + else if ( index < 0 ) { + // Get from the end + State = History.savedStates[History.savedStates.length+index]; + } + else { + // Get from the beginning + State = History.savedStates[index]; + } + + // Return State + return State; + }; + + /** + * History.getCurrentIndex() + * Gets the current index + * @return (integer) + */ + History.getCurrentIndex = function(){ + // Prepare + var index = null; + + // No states saved + if(History.savedStates.length < 1) { + index = 0; + } + else { + index = History.savedStates.length-1; + } + return index; + }; + + // ==================================================================== + // Hash Helpers + + /** + * History.getHash() + * @param {Location=} location + * Gets the current document hash + * Note: unlike location.hash, this is guaranteed to return the escaped hash in all browsers + * @return {string} + */ + History.getHash = function(doc){ + var url = History.getLocationHref(doc), + hash; + hash = History.getHashByUrl(url); + return hash; + }; + + /** + * History.unescapeHash() + * normalize and Unescape a Hash + * @param {String} hash + * @return {string} + */ + History.unescapeHash = function(hash){ + // Prepare + var result = History.normalizeHash(hash); + + // Unescape hash + result = decodeURIComponent(result); + + // Return result + return result; + }; + + /** + * History.normalizeHash() + * normalize a hash across browsers + * @return {string} + */ + History.normalizeHash = function(hash){ + // Prepare + var result = hash.replace(/[^#]*#/,'').replace(/#.*/, ''); + + // Return result + return result; + }; + + /** + * History.setHash(hash) + * Sets the document hash + * @param {string} hash + * @return {History} + */ + History.setHash = function(hash,queue){ + // Prepare + var State, pageUrl; + + // Handle Queueing + if ( queue !== false && History.busy() ) { + // Wait + Push to Queue + //History.debug('History.setHash: we must wait', arguments); + History.pushQueue({ + scope: History, + callback: History.setHash, + args: arguments, + queue: queue + }); + return false; + } + + // Log + //History.debug('History.setHash: called',hash); + + // Make Busy + Continue + History.busy(true); + + // Check if hash is a state + State = History.extractState(hash,true); + if ( State && !History.emulated.pushState ) { + // Hash is a state so skip the setHash + //History.debug('History.setHash: Hash is a state so skipping the hash set with a direct pushState call',arguments); + + // PushState + History.pushState(State.data,State.title,State.url,false); + } + else if ( History.getHash() !== hash ) { + // Hash is a proper hash, so apply it + + // Handle browser bugs + if ( History.bugs.setHash ) { + // Fix Safari Bug https://bugs.webkit.org/show_bug.cgi?id=56249 + + // Fetch the base page + pageUrl = History.getPageUrl(); + + // Safari hash apply + History.pushState(null,null,pageUrl+'#'+hash,false); + } + else { + // Normal hash apply + document.location.hash = hash; + } + } + + // Chain + return History; + }; + + /** + * History.escape() + * normalize and Escape a Hash + * @return {string} + */ + History.escapeHash = function(hash){ + // Prepare + var result = History.normalizeHash(hash); + + // Escape hash + result = window.encodeURIComponent(result); + + // IE6 Escape Bug + if ( !History.bugs.hashEscape ) { + // Restore common parts + result = result + .replace(/\%21/g,'!') + .replace(/\%26/g,'&') + .replace(/\%3D/g,'=') + .replace(/\%3F/g,'?'); + } + + // Return result + return result; + }; + + /** + * History.getHashByUrl(url) + * Extracts the Hash from a URL + * @param {string} url + * @return {string} url + */ + History.getHashByUrl = function(url){ + // Extract the hash + var hash = String(url) + .replace(/([^#]*)#?([^#]*)#?(.*)/, '$2') + ; + + // Unescape hash + hash = History.unescapeHash(hash); + + // Return hash + return hash; + }; + + /** + * History.setTitle(title) + * Applies the title to the document + * @param {State} newState + * @return {Boolean} + */ + History.setTitle = function(newState){ + // Prepare + var title = newState.title, + firstState; + + // Initial + if ( !title ) { + firstState = History.getStateByIndex(0); + if ( firstState && firstState.url === newState.url ) { + title = firstState.title||History.options.initialTitle; + } + } + + // Apply + try { + document.getElementsByTagName('title')[0].innerHTML = title.replace('<','<').replace('>','>').replace(' & ',' & '); + } + catch ( Exception ) { } + document.title = title; + + // Chain + return History; + }; + + + // ==================================================================== + // Queueing + + /** + * History.queues + * The list of queues to use + * First In, First Out + */ + History.queues = []; + + /** + * History.busy(value) + * @param {boolean} value [optional] + * @return {boolean} busy + */ + History.busy = function(value){ + // Apply + if ( typeof value !== 'undefined' ) { + //History.debug('History.busy: changing ['+(History.busy.flag||false)+'] to ['+(value||false)+']', History.queues.length); + History.busy.flag = value; + } + // Default + else if ( typeof History.busy.flag === 'undefined' ) { + History.busy.flag = false; + } + + // Queue + if ( !History.busy.flag ) { + // Execute the next item in the queue + clearTimeout(History.busy.timeout); + var fireNext = function(){ + var i, queue, item; + if ( History.busy.flag ) return; + for ( i=History.queues.length-1; i >= 0; --i ) { + queue = History.queues[i]; + if ( queue.length === 0 ) continue; + item = queue.shift(); + History.fireQueueItem(item); + History.busy.timeout = setTimeout(fireNext,History.options.busyDelay); + } + }; + History.busy.timeout = setTimeout(fireNext,History.options.busyDelay); + } + + // Return + return History.busy.flag; + }; + + /** + * History.busy.flag + */ + History.busy.flag = false; + + /** + * History.fireQueueItem(item) + * Fire a Queue Item + * @param {Object} item + * @return {Mixed} result + */ + History.fireQueueItem = function(item){ + return item.callback.apply(item.scope||History,item.args||[]); + }; + + /** + * History.pushQueue(callback,args) + * Add an item to the queue + * @param {Object} item [scope,callback,args,queue] + */ + History.pushQueue = function(item){ + // Prepare the queue + History.queues[item.queue||0] = History.queues[item.queue||0]||[]; + + // Add to the queue + History.queues[item.queue||0].push(item); + + // Chain + return History; + }; + + /** + * History.queue (item,queue), (func,queue), (func), (item) + * Either firs the item now if not busy, or adds it to the queue + */ + History.queue = function(item,queue){ + // Prepare + if ( typeof item === 'function' ) { + item = { + callback: item + }; + } + if ( typeof queue !== 'undefined' ) { + item.queue = queue; + } + + // Handle + if ( History.busy() ) { + History.pushQueue(item); + } else { + History.fireQueueItem(item); + } + + // Chain + return History; + }; + + /** + * History.clearQueue() + * Clears the Queue + */ + History.clearQueue = function(){ + History.busy.flag = false; + History.queues = []; + return History; + }; + + + // ==================================================================== + // IE Bug Fix + + /** + * History.stateChanged + * States whether or not the state has changed since the last double check was initialised + */ + History.stateChanged = false; + + /** + * History.doubleChecker + * Contains the timeout used for the double checks + */ + History.doubleChecker = false; + + /** + * History.doubleCheckComplete() + * Complete a double check + * @return {History} + */ + History.doubleCheckComplete = function(){ + // Update + History.stateChanged = true; + + // Clear + History.doubleCheckClear(); + + // Chain + return History; + }; + + /** + * History.doubleCheckClear() + * Clear a double check + * @return {History} + */ + History.doubleCheckClear = function(){ + // Clear + if ( History.doubleChecker ) { + clearTimeout(History.doubleChecker); + History.doubleChecker = false; + } + + // Chain + return History; + }; + + /** + * History.doubleCheck() + * Create a double check + * @return {History} + */ + History.doubleCheck = function(tryAgain){ + // Reset + History.stateChanged = false; + History.doubleCheckClear(); + + // Fix IE6,IE7 bug where calling history.back or history.forward does not actually change the hash (whereas doing it manually does) + // Fix Safari 5 bug where sometimes the state does not change: https://bugs.webkit.org/show_bug.cgi?id=42940 + if ( History.bugs.ieDoubleCheck ) { + // Apply Check + History.doubleChecker = setTimeout( + function(){ + History.doubleCheckClear(); + if ( !History.stateChanged ) { + //History.debug('History.doubleCheck: State has not yet changed, trying again', arguments); + // Re-Attempt + tryAgain(); + } + return true; + }, + History.options.doubleCheckInterval + ); + } + + // Chain + return History; + }; + + + // ==================================================================== + // Safari Bug Fix + + /** + * History.safariStatePoll() + * Poll the current state + * @return {History} + */ + History.safariStatePoll = function(){ + // Poll the URL + + // Get the Last State which has the new URL + var + urlState = History.extractState(History.getLocationHref()), + newState; + + // Check for a difference + if ( !History.isLastSavedState(urlState) ) { + newState = urlState; + } + else { + return; + } + + // Check if we have a state with that url + // If not create it + if ( !newState ) { + //History.debug('History.safariStatePoll: new'); + newState = History.createStateObject(); + } + + // Apply the New State + //History.debug('History.safariStatePoll: trigger'); + History.Adapter.trigger(window,'popstate'); + + // Chain + return History; + }; + + + // ==================================================================== + // State Aliases + + /** + * History.back(queue) + * Send the browser history back one item + * @param {Integer} queue [optional] + */ + History.back = function(queue){ + //History.debug('History.back: called', arguments); + + // Handle Queueing + if ( queue !== false && History.busy() ) { + // Wait + Push to Queue + //History.debug('History.back: we must wait', arguments); + History.pushQueue({ + scope: History, + callback: History.back, + args: arguments, + queue: queue + }); + return false; + } + + // Make Busy + Continue + History.busy(true); + + // Fix certain browser bugs that prevent the state from changing + History.doubleCheck(function(){ + History.back(false); + }); + + // Go back + history.go(-1); + + // End back closure + return true; + }; + + /** + * History.forward(queue) + * Send the browser history forward one item + * @param {Integer} queue [optional] + */ + History.forward = function(queue){ + //History.debug('History.forward: called', arguments); + + // Handle Queueing + if ( queue !== false && History.busy() ) { + // Wait + Push to Queue + //History.debug('History.forward: we must wait', arguments); + History.pushQueue({ + scope: History, + callback: History.forward, + args: arguments, + queue: queue + }); + return false; + } + + // Make Busy + Continue + History.busy(true); + + // Fix certain browser bugs that prevent the state from changing + History.doubleCheck(function(){ + History.forward(false); + }); + + // Go forward + history.go(1); + + // End forward closure + return true; + }; + + /** + * History.go(index,queue) + * Send the browser history back or forward index times + * @param {Integer} queue [optional] + */ + History.go = function(index,queue){ + //History.debug('History.go: called', arguments); + + // Prepare + var i; + + // Handle + if ( index > 0 ) { + // Forward + for ( i=1; i<=index; ++i ) { + History.forward(queue); + } + } + else if ( index < 0 ) { + // Backward + for ( i=-1; i>=index; --i ) { + History.back(queue); + } + } + else { + throw new Error('History.go: History.go requires a positive or negative integer passed.'); + } + + // Chain + return History; + }; + + + // ==================================================================== + // HTML5 State Support + + // Non-Native pushState Implementation + if ( History.emulated.pushState ) { + /* + * Provide Skeleton for HTML4 Browsers + */ + + // Prepare + var emptyFunction = function(){}; + History.pushState = History.pushState||emptyFunction; + History.replaceState = History.replaceState||emptyFunction; + } // History.emulated.pushState + + // Native pushState Implementation + else { + /* + * Use native HTML5 History API Implementation + */ + + /** + * History.onPopState(event,extra) + * Refresh the Current State + */ + History.onPopState = function(event,extra){ + // Prepare + var stateId = false, newState = false, currentHash, currentState; + + // Reset the double check + History.doubleCheckComplete(); + + // Check for a Hash, and handle apporiatly + currentHash = History.getHash(); + if ( currentHash ) { + // Expand Hash + currentState = History.extractState(currentHash||History.getLocationHref(),true); + if ( currentState ) { + // We were able to parse it, it must be a State! + // Let's forward to replaceState + //History.debug('History.onPopState: state anchor', currentHash, currentState); + History.replaceState(currentState.data, currentState.title, currentState.url, false); + } + else { + // Traditional Anchor + //History.debug('History.onPopState: traditional anchor', currentHash); + History.Adapter.trigger(window,'anchorchange'); + History.busy(false); + } + + // We don't care for hashes + History.expectedStateId = false; + return false; + } + + // Ensure + stateId = History.Adapter.extractEventData('state',event,extra) || false; + + // Fetch State + if ( stateId ) { + // Vanilla: Back/forward button was used + newState = History.getStateById(stateId); + } + else if ( History.expectedStateId ) { + // Vanilla: A new state was pushed, and popstate was called manually + newState = History.getStateById(History.expectedStateId); + } + else { + // Initial State + newState = History.extractState(History.getLocationHref()); + } + + // The State did not exist in our store + if ( !newState ) { + // Regenerate the State + newState = History.createStateObject(null,null,History.getLocationHref()); + } + + // Clean + History.expectedStateId = false; + + // Check if we are the same state + if ( History.isLastSavedState(newState) ) { + // There has been no change (just the page's hash has finally propagated) + //History.debug('History.onPopState: no change', newState, History.savedStates); + History.busy(false); + return false; + } + + // Store the State + History.storeState(newState); + History.saveState(newState); + + // Force update of the title + History.setTitle(newState); + + // Fire Our Event + History.Adapter.trigger(window,'statechange'); + History.busy(false); + + // Return true + return true; + }; + History.Adapter.bind(window,'popstate',History.onPopState); + + /** + * History.pushState(data,title,url) + * Add a new State to the history object, become it, and trigger onpopstate + * We have to trigger for HTML4 compatibility + * @param {object} data + * @param {string} title + * @param {string} url + * @return {true} + */ + History.pushState = function(data,title,url,queue){ + //History.debug('History.pushState: called', arguments); + + // Check the State + if ( History.getHashByUrl(url) && History.emulated.pushState ) { + throw new Error('History.js does not support states with fragement-identifiers (hashes/anchors).'); + } + + // Handle Queueing + if ( queue !== false && History.busy() ) { + // Wait + Push to Queue + //History.debug('History.pushState: we must wait', arguments); + History.pushQueue({ + scope: History, + callback: History.pushState, + args: arguments, + queue: queue + }); + return false; + } + + // Make Busy + Continue + History.busy(true); + + // Create the newState + var newState = History.createStateObject(data,title,url); + + // Check it + if ( History.isLastSavedState(newState) ) { + // Won't be a change + History.busy(false); + } + else { + // Store the newState + History.storeState(newState); + History.expectedStateId = newState.id; + + // Push the newState + history.pushState(newState.id,newState.title,newState.url); + + // Fire HTML5 Event + History.Adapter.trigger(window,'popstate'); + } + + // End pushState closure + return true; + }; + + /** + * History.replaceState(data,title,url) + * Replace the State and trigger onpopstate + * We have to trigger for HTML4 compatibility + * @param {object} data + * @param {string} title + * @param {string} url + * @return {true} + */ + History.replaceState = function(data,title,url,queue){ + //History.debug('History.replaceState: called', arguments); + + // Check the State + if ( History.getHashByUrl(url) && History.emulated.pushState ) { + throw new Error('History.js does not support states with fragement-identifiers (hashes/anchors).'); + } + + // Handle Queueing + if ( queue !== false && History.busy() ) { + // Wait + Push to Queue + //History.debug('History.replaceState: we must wait', arguments); + History.pushQueue({ + scope: History, + callback: History.replaceState, + args: arguments, + queue: queue + }); + return false; + } + + // Make Busy + Continue + History.busy(true); + + // Create the newState + var newState = History.createStateObject(data,title,url); + + // Check it + if ( History.isLastSavedState(newState) ) { + // Won't be a change + History.busy(false); + } + else { + // Store the newState + History.storeState(newState); + History.expectedStateId = newState.id; + + // Push the newState + history.replaceState(newState.id,newState.title,newState.url); + + // Fire HTML5 Event + History.Adapter.trigger(window,'popstate'); + } + + // End replaceState closure + return true; + }; + + } // !History.emulated.pushState + + + // ==================================================================== + // Initialise + + /** + * Load the Store + */ + if ( sessionStorage ) { + // Fetch + try { + History.store = JSON.parse(sessionStorage.getItem('History.store'))||{}; + } + catch ( err ) { + History.store = {}; + } + + // Normalize + History.normalizeStore(); + } + else { + // Default Load + History.store = {}; + History.normalizeStore(); + } + + /** + * Clear Intervals on exit to prevent memory leaks + */ + History.Adapter.bind(window,"unload",History.clearAllIntervals); + + /** + * Create the initial State + */ + History.saveState(History.storeState(History.extractState(History.getLocationHref(),true))); + + /** + * Bind for Saving Store + */ + if ( sessionStorage ) { + // When the page is closed + History.onUnload = function(){ + // Prepare + var currentStore, item, currentStoreString; + + // Fetch + try { + currentStore = JSON.parse(sessionStorage.getItem('History.store'))||{}; + } + catch ( err ) { + currentStore = {}; + } + + // Ensure + currentStore.idToState = currentStore.idToState || {}; + currentStore.urlToId = currentStore.urlToId || {}; + currentStore.stateToId = currentStore.stateToId || {}; + + // Sync + for ( item in History.idToState ) { + if ( !History.idToState.hasOwnProperty(item) ) { + continue; + } + currentStore.idToState[item] = History.idToState[item]; + } + for ( item in History.urlToId ) { + if ( !History.urlToId.hasOwnProperty(item) ) { + continue; + } + currentStore.urlToId[item] = History.urlToId[item]; + } + for ( item in History.stateToId ) { + if ( !History.stateToId.hasOwnProperty(item) ) { + continue; + } + currentStore.stateToId[item] = History.stateToId[item]; + } + + // Update + History.store = currentStore; + History.normalizeStore(); + + // In Safari, going into Private Browsing mode causes the + // Session Storage object to still exist but if you try and use + // or set any property/function of it it throws the exception + // "QUOTA_EXCEEDED_ERR: DOM Exception 22: An attempt was made to + // add something to storage that exceeded the quota." infinitely + // every second. + currentStoreString = JSON.stringify(currentStore); + try { + // Store + sessionStorage.setItem('History.store', currentStoreString); + } + catch (e) { + if (e.code === DOMException.QUOTA_EXCEEDED_ERR) { + if (sessionStorage.length) { + // Workaround for a bug seen on iPads. Sometimes the quota exceeded error comes up and simply + // removing/resetting the storage can work. + sessionStorage.removeItem('History.store'); + sessionStorage.setItem('History.store', currentStoreString); + } else { + // Otherwise, we're probably private browsing in Safari, so we'll ignore the exception. + } + } else { + throw e; + } + } + }; + + // For Internet Explorer + History.intervalList.push(setInterval(History.onUnload,History.options.storeInterval)); + + // For Other Browsers + History.Adapter.bind(window,'beforeunload',History.onUnload); + History.Adapter.bind(window,'unload',History.onUnload); + + // Both are enabled for consistency + } + + // Non-Native pushState Implementation + if ( !History.emulated.pushState ) { + // Be aware, the following is only for native pushState implementations + // If you are wanting to include something for all browsers + // Then include it above this if block + + /** + * Setup Safari Fix + */ + if ( History.bugs.safariPoll ) { + History.intervalList.push(setInterval(History.safariStatePoll, History.options.safariPollInterval)); + } + + /** + * Ensure Cross Browser Compatibility + */ + if ( navigator.vendor === 'Apple Computer, Inc.' || (navigator.appCodeName||'') === 'Mozilla' ) { + /** + * Fix Safari HashChange Issue + */ + + // Setup Alias + History.Adapter.bind(window,'hashchange',function(){ + History.Adapter.trigger(window,'popstate'); + }); + + // Initialise Alias + if ( History.getHash() ) { + History.Adapter.onDomLoad(function(){ + History.Adapter.trigger(window,'hashchange'); + }); + } + } + + } // !History.emulated.pushState + + + }; // History.initCore + + // Try to Initialise History + if (!History.options || !History.options.delayInit) { + History.init(); + } + +})(window); diff --git a/sites/all/themes/gui/materiobasetheme/bower_components/history.js/scripts/bundled-uncompressed/html4+html5/zepto.history.js b/sites/all/themes/gui/materiobasetheme/bower_components/history.js/scripts/bundled-uncompressed/html4+html5/zepto.history.js new file mode 100644 index 00000000..02b19b77 --- /dev/null +++ b/sites/all/themes/gui/materiobasetheme/bower_components/history.js/scripts/bundled-uncompressed/html4+html5/zepto.history.js @@ -0,0 +1,3288 @@ +/* + json2.js + 2012-10-08 + + Public Domain. + + NO WARRANTY EXPRESSED OR IMPLIED. USE AT YOUR OWN RISK. + + See http://www.JSON.org/js.html + + + This code should be minified before deployment. + See http://javascript.crockford.com/jsmin.html + + USE YOUR OWN COPY. IT IS EXTREMELY UNWISE TO LOAD CODE FROM SERVERS YOU DO + NOT CONTROL. + + + This file creates a global JSON object containing two methods: stringify + and parse. + + JSON.stringify(value, replacer, space) + value any JavaScript value, usually an object or array. + + replacer an optional parameter that determines how object + values are stringified for objects. It can be a + function or an array of strings. + + space an optional parameter that specifies the indentation + of nested structures. If it is omitted, the text will + be packed without extra whitespace. If it is a number, + it will specify the number of spaces to indent at each + level. If it is a string (such as '\t' or ' '), + it contains the characters used to indent at each level. + + This method produces a JSON text from a JavaScript value. + + When an object value is found, if the object contains a toJSON + method, its toJSON method will be called and the result will be + stringified. A toJSON method does not serialize: it returns the + value represented by the name/value pair that should be serialized, + or undefined if nothing should be serialized. The toJSON method + will be passed the key associated with the value, and this will be + bound to the value + + For example, this would serialize Dates as ISO strings. + + Date.prototype.toJSON = function (key) { + function f(n) { + // Format integers to have at least two digits. + return n < 10 ? '0' + n : n; + } + + return this.getUTCFullYear() + '-' + + f(this.getUTCMonth() + 1) + '-' + + f(this.getUTCDate()) + 'T' + + f(this.getUTCHours()) + ':' + + f(this.getUTCMinutes()) + ':' + + f(this.getUTCSeconds()) + 'Z'; + }; + + You can provide an optional replacer method. It will be passed the + key and value of each member, with this bound to the containing + object. The value that is returned from your method will be + serialized. If your method returns undefined, then the member will + be excluded from the serialization. + + If the replacer parameter is an array of strings, then it will be + used to select the members to be serialized. It filters the results + such that only members with keys listed in the replacer array are + stringified. + + Values that do not have JSON representations, such as undefined or + functions, will not be serialized. Such values in objects will be + dropped; in arrays they will be replaced with null. You can use + a replacer function to replace those with JSON values. + JSON.stringify(undefined) returns undefined. + + The optional space parameter produces a stringification of the + value that is filled with line breaks and indentation to make it + easier to read. + + If the space parameter is a non-empty string, then that string will + be used for indentation. If the space parameter is a number, then + the indentation will be that many spaces. + + Example: + + text = JSON.stringify(['e', {pluribus: 'unum'}]); + // text is '["e",{"pluribus":"unum"}]' + + + text = JSON.stringify(['e', {pluribus: 'unum'}], null, '\t'); + // text is '[\n\t"e",\n\t{\n\t\t"pluribus": "unum"\n\t}\n]' + + text = JSON.stringify([new Date()], function (key, value) { + return this[key] instanceof Date ? + 'Date(' + this[key] + ')' : value; + }); + // text is '["Date(---current time---)"]' + + + JSON.parse(text, reviver) + This method parses a JSON text to produce an object or array. + It can throw a SyntaxError exception. + + The optional reviver parameter is a function that can filter and + transform the results. It receives each of the keys and values, + and its return value is used instead of the original value. + If it returns what it received, then the structure is not modified. + If it returns undefined then the member is deleted. + + Example: + + // Parse the text. Values that look like ISO date strings will + // be converted to Date objects. + + myData = JSON.parse(text, function (key, value) { + var a; + if (typeof value === 'string') { + a = +/^(\d{4})-(\d{2})-(\d{2})T(\d{2}):(\d{2}):(\d{2}(?:\.\d*)?)Z$/.exec(value); + if (a) { + return new Date(Date.UTC(+a[1], +a[2] - 1, +a[3], +a[4], + +a[5], +a[6])); + } + } + return value; + }); + + myData = JSON.parse('["Date(09/09/2001)"]', function (key, value) { + var d; + if (typeof value === 'string' && + value.slice(0, 5) === 'Date(' && + value.slice(-1) === ')') { + d = new Date(value.slice(5, -1)); + if (d) { + return d; + } + } + return value; + }); + + + This is a reference implementation. You are free to copy, modify, or + redistribute. +*/ + +/*jslint evil: true, regexp: true */ + +/*members "", "\b", "\t", "\n", "\f", "\r", "\"", JSON, "\\", apply, + call, charCodeAt, getUTCDate, getUTCFullYear, getUTCHours, + getUTCMinutes, getUTCMonth, getUTCSeconds, hasOwnProperty, join, + lastIndex, length, parse, prototype, push, replace, slice, stringify, + test, toJSON, toString, valueOf +*/ + + +// Create a JSON object only if one does not already exist. We create the +// methods in a closure to avoid creating global variables. + +if (typeof JSON !== 'object') { + JSON = {}; +} + +(function () { + 'use strict'; + + function f(n) { + // Format integers to have at least two digits. + return n < 10 ? '0' + n : n; + } + + if (typeof Date.prototype.toJSON !== 'function') { + + Date.prototype.toJSON = function (key) { + + return isFinite(this.valueOf()) + ? this.getUTCFullYear() + '-' + + f(this.getUTCMonth() + 1) + '-' + + f(this.getUTCDate()) + 'T' + + f(this.getUTCHours()) + ':' + + f(this.getUTCMinutes()) + ':' + + f(this.getUTCSeconds()) + 'Z' + : null; + }; + + String.prototype.toJSON = + Number.prototype.toJSON = + Boolean.prototype.toJSON = function (key) { + return this.valueOf(); + }; + } + + var cx = /[\u0000\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g, + escapable = /[\\\"\x00-\x1f\x7f-\x9f\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g, + gap, + indent, + meta = { // table of character substitutions + '\b': '\\b', + '\t': '\\t', + '\n': '\\n', + '\f': '\\f', + '\r': '\\r', + '"' : '\\"', + '\\': '\\\\' + }, + rep; + + + function quote(string) { + +// If the string contains no control characters, no quote characters, and no +// backslash characters, then we can safely slap some quotes around it. +// Otherwise we must also replace the offending characters with safe escape +// sequences. + + escapable.lastIndex = 0; + return escapable.test(string) ? '"' + string.replace(escapable, function (a) { + var c = meta[a]; + return typeof c === 'string' + ? c + : '\\u' + ('0000' + a.charCodeAt(0).toString(16)).slice(-4); + }) + '"' : '"' + string + '"'; + } + + + function str(key, holder) { + +// Produce a string from holder[key]. + + var i, // The loop counter. + k, // The member key. + v, // The member value. + length, + mind = gap, + partial, + value = holder[key]; + +// If the value has a toJSON method, call it to obtain a replacement value. + + if (value && typeof value === 'object' && + typeof value.toJSON === 'function') { + value = value.toJSON(key); + } + +// If we were called with a replacer function, then call the replacer to +// obtain a replacement value. + + if (typeof rep === 'function') { + value = rep.call(holder, key, value); + } + +// What happens next depends on the value's type. + + switch (typeof value) { + case 'string': + return quote(value); + + case 'number': + +// JSON numbers must be finite. Encode non-finite numbers as null. + + return isFinite(value) ? String(value) : 'null'; + + case 'boolean': + case 'null': + +// If the value is a boolean or null, convert it to a string. Note: +// typeof null does not produce 'null'. The case is included here in +// the remote chance that this gets fixed someday. + + return String(value); + +// If the type is 'object', we might be dealing with an object or an array or +// null. + + case 'object': + +// Due to a specification blunder in ECMAScript, typeof null is 'object', +// so watch out for that case. + + if (!value) { + return 'null'; + } + +// Make an array to hold the partial results of stringifying this object value. + + gap += indent; + partial = []; + +// Is the value an array? + + if (Object.prototype.toString.apply(value) === '[object Array]') { + +// The value is an array. Stringify every element. Use null as a placeholder +// for non-JSON values. + + length = value.length; + for (i = 0; i < length; i += 1) { + partial[i] = str(i, value) || 'null'; + } + +// Join all of the elements together, separated with commas, and wrap them in +// brackets. + + v = partial.length === 0 + ? '[]' + : gap + ? '[\n' + gap + partial.join(',\n' + gap) + '\n' + mind + ']' + : '[' + partial.join(',') + ']'; + gap = mind; + return v; + } + +// If the replacer is an array, use it to select the members to be stringified. + + if (rep && typeof rep === 'object') { + length = rep.length; + for (i = 0; i < length; i += 1) { + if (typeof rep[i] === 'string') { + k = rep[i]; + v = str(k, value); + if (v) { + partial.push(quote(k) + (gap ? ': ' : ':') + v); + } + } + } + } else { + +// Otherwise, iterate through all of the keys in the object. + + for (k in value) { + if (Object.prototype.hasOwnProperty.call(value, k)) { + v = str(k, value); + if (v) { + partial.push(quote(k) + (gap ? ': ' : ':') + v); + } + } + } + } + +// Join all of the member texts together, separated with commas, +// and wrap them in braces. + + v = partial.length === 0 + ? '{}' + : gap + ? '{\n' + gap + partial.join(',\n' + gap) + '\n' + mind + '}' + : '{' + partial.join(',') + '}'; + gap = mind; + return v; + } + } + +// If the JSON object does not yet have a stringify method, give it one. + + if (typeof JSON.stringify !== 'function') { + JSON.stringify = function (value, replacer, space) { + +// The stringify method takes a value and an optional replacer, and an optional +// space parameter, and returns a JSON text. The replacer can be a function +// that can replace values, or an array of strings that will select the keys. +// A default replacer method can be provided. Use of the space parameter can +// produce text that is more easily readable. + + var i; + gap = ''; + indent = ''; + +// If the space parameter is a number, make an indent string containing that +// many spaces. + + if (typeof space === 'number') { + for (i = 0; i < space; i += 1) { + indent += ' '; + } + +// If the space parameter is a string, it will be used as the indent string. + + } else if (typeof space === 'string') { + indent = space; + } + +// If there is a replacer, it must be a function or an array. +// Otherwise, throw an error. + + rep = replacer; + if (replacer && typeof replacer !== 'function' && + (typeof replacer !== 'object' || + typeof replacer.length !== 'number')) { + throw new Error('JSON.stringify'); + } + +// Make a fake root object containing our value under the key of ''. +// Return the result of stringifying the value. + + return str('', {'': value}); + }; + } + + +// If the JSON object does not yet have a parse method, give it one. + + if (typeof JSON.parse !== 'function') { + JSON.parse = function (text, reviver) { + +// The parse method takes a text and an optional reviver function, and returns +// a JavaScript value if the text is a valid JSON text. + + var j; + + function walk(holder, key) { + +// The walk method is used to recursively walk the resulting structure so +// that modifications can be made. + + var k, v, value = holder[key]; + if (value && typeof value === 'object') { + for (k in value) { + if (Object.prototype.hasOwnProperty.call(value, k)) { + v = walk(value, k); + if (v !== undefined) { + value[k] = v; + } else { + delete value[k]; + } + } + } + } + return reviver.call(holder, key, value); + } + + +// Parsing happens in four stages. In the first stage, we replace certain +// Unicode characters with escape sequences. JavaScript handles many characters +// incorrectly, either silently deleting them, or treating them as line endings. + + text = String(text); + cx.lastIndex = 0; + if (cx.test(text)) { + text = text.replace(cx, function (a) { + return '\\u' + + ('0000' + a.charCodeAt(0).toString(16)).slice(-4); + }); + } + +// In the second stage, we run the text against regular expressions that look +// for non-JSON patterns. We are especially concerned with '()' and 'new' +// because they can cause invocation, and '=' because it can cause mutation. +// But just to be safe, we want to reject all unexpected forms. + +// We split the second stage into 4 regexp operations in order to work around +// crippling inefficiencies in IE's and Safari's regexp engines. First we +// replace the JSON backslash pairs with '@' (a non-JSON character). Second, we +// replace all simple value tokens with ']' characters. Third, we delete all +// open brackets that follow a colon or comma or that begin the text. Finally, +// we look to see that the remaining characters are only whitespace or ']' or +// ',' or ':' or '{' or '}'. If that is so, then the text is safe for eval. + + if (/^[\],:{}\s]*$/ + .test(text.replace(/\\(?:["\\\/bfnrt]|u[0-9a-fA-F]{4})/g, '@') + .replace(/"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g, ']') + .replace(/(?:^|:|,)(?:\s*\[)+/g, ''))) { + +// In the third stage we use the eval function to compile the text into a +// JavaScript structure. The '{' operator is subject to a syntactic ambiguity +// in JavaScript: it can begin a block or an object literal. We wrap the text +// in parens to eliminate the ambiguity. + + j = eval('(' + text + ')'); + +// In the optional fourth stage, we recursively walk the new structure, passing +// each name/value pair to a reviver function for possible transformation. + + return typeof reviver === 'function' + ? walk({'': j}, '') + : j; + } + +// If the text is not JSON parseable, then a SyntaxError is thrown. + + throw new SyntaxError('JSON.parse'); + }; + } +}());/** + * History.js Zepto Adapter + * @author Benjamin Arthur Lupton + * @copyright 2010-2011 Benjamin Arthur Lupton + * @license New BSD License + */ + +// Closure +(function(window,undefined){ + "use strict"; + + // Localise Globals + var + History = window.History = window.History||{}, + Zepto = window.Zepto; + + // Check Existence + if ( typeof History.Adapter !== 'undefined' ) { + throw new Error('History.js Adapter has already been loaded...'); + } + + // Add the Adapter + History.Adapter = { + /** + * History.Adapter.bind(el,event,callback) + * @param {Element|string} el + * @param {string} event - custom and standard events + * @param {function} callback + * @return {void} + */ + bind: function(el,event,callback){ + new Zepto(el).bind(event,callback); + }, + + /** + * History.Adapter.trigger(el,event) + * @param {Element|string} el + * @param {string} event - custom and standard events + * @return {void} + */ + trigger: function(el,event){ + new Zepto(el).trigger(event); + }, + + /** + * History.Adapter.extractEventData(key,event,extra) + * @param {string} key - key for the event data to extract + * @param {string} event - custom and standard events + * @return {mixed} + */ + extractEventData: function(key,event){ + // Zepto Native + var result = (event && event[key]) || undefined; + + // Return + return result; + }, + + /** + * History.Adapter.onDomLoad(callback) + * @param {function} callback + * @return {void} + */ + onDomLoad: function(callback) { + new Zepto(callback); + } + }; + + // Try and Initialise History + if ( typeof History.init !== 'undefined' ) { + History.init(); + } + +})(window); +/** + * History.js HTML4 Support + * Depends on the HTML5 Support + * @author Benjamin Arthur Lupton + * @copyright 2010-2011 Benjamin Arthur Lupton + * @license New BSD License + */ + +(function(window,undefined){ + "use strict"; + + // ======================================================================== + // Initialise + + // Localise Globals + var + document = window.document, // Make sure we are using the correct document + setTimeout = window.setTimeout||setTimeout, + clearTimeout = window.clearTimeout||clearTimeout, + setInterval = window.setInterval||setInterval, + History = window.History = window.History||{}; // Public History Object + + // Check Existence + if ( typeof History.initHtml4 !== 'undefined' ) { + throw new Error('History.js HTML4 Support has already been loaded...'); + } + + + // ======================================================================== + // Initialise HTML4 Support + + // Initialise HTML4 Support + History.initHtml4 = function(){ + // Initialise + if ( typeof History.initHtml4.initialized !== 'undefined' ) { + // Already Loaded + return false; + } + else { + History.initHtml4.initialized = true; + } + + + // ==================================================================== + // Properties + + /** + * History.enabled + * Is History enabled? + */ + History.enabled = true; + + + // ==================================================================== + // Hash Storage + + /** + * History.savedHashes + * Store the hashes in an array + */ + History.savedHashes = []; + + /** + * History.isLastHash(newHash) + * Checks if the hash is the last hash + * @param {string} newHash + * @return {boolean} true + */ + History.isLastHash = function(newHash){ + // Prepare + var oldHash = History.getHashByIndex(), + isLast; + + // Check + isLast = newHash === oldHash; + + // Return isLast + return isLast; + }; + + /** + * History.isHashEqual(newHash, oldHash) + * Checks to see if two hashes are functionally equal + * @param {string} newHash + * @param {string} oldHash + * @return {boolean} true + */ + History.isHashEqual = function(newHash, oldHash){ + newHash = encodeURIComponent(newHash).replace(/%25/g, "%"); + oldHash = encodeURIComponent(oldHash).replace(/%25/g, "%"); + return newHash === oldHash; + }; + + /** + * History.saveHash(newHash) + * Push a Hash + * @param {string} newHash + * @return {boolean} true + */ + History.saveHash = function(newHash){ + // Check Hash + if ( History.isLastHash(newHash) ) { + return false; + } + + // Push the Hash + History.savedHashes.push(newHash); + + // Return true + return true; + }; + + /** + * History.getHashByIndex() + * Gets a hash by the index + * @param {integer} index + * @return {string} + */ + History.getHashByIndex = function(index){ + // Prepare + var hash = null; + + // Handle + if ( typeof index === 'undefined' ) { + // Get the last inserted + hash = History.savedHashes[History.savedHashes.length-1]; + } + else if ( index < 0 ) { + // Get from the end + hash = History.savedHashes[History.savedHashes.length+index]; + } + else { + // Get from the beginning + hash = History.savedHashes[index]; + } + + // Return hash + return hash; + }; + + + // ==================================================================== + // Discarded States + + /** + * History.discardedHashes + * A hashed array of discarded hashes + */ + History.discardedHashes = {}; + + /** + * History.discardedStates + * A hashed array of discarded states + */ + History.discardedStates = {}; + + /** + * History.discardState(State) + * Discards the state by ignoring it through History + * @param {object} State + * @return {true} + */ + History.discardState = function(discardedState,forwardState,backState){ + //History.debug('History.discardState', arguments); + // Prepare + var discardedStateHash = History.getHashByState(discardedState), + discardObject; + + // Create Discard Object + discardObject = { + 'discardedState': discardedState, + 'backState': backState, + 'forwardState': forwardState + }; + + // Add to DiscardedStates + History.discardedStates[discardedStateHash] = discardObject; + + // Return true + return true; + }; + + /** + * History.discardHash(hash) + * Discards the hash by ignoring it through History + * @param {string} hash + * @return {true} + */ + History.discardHash = function(discardedHash,forwardState,backState){ + //History.debug('History.discardState', arguments); + // Create Discard Object + var discardObject = { + 'discardedHash': discardedHash, + 'backState': backState, + 'forwardState': forwardState + }; + + // Add to discardedHash + History.discardedHashes[discardedHash] = discardObject; + + // Return true + return true; + }; + + /** + * History.discardedState(State) + * Checks to see if the state is discarded + * @param {object} State + * @return {bool} + */ + History.discardedState = function(State){ + // Prepare + var StateHash = History.getHashByState(State), + discarded; + + // Check + discarded = History.discardedStates[StateHash]||false; + + // Return true + return discarded; + }; + + /** + * History.discardedHash(hash) + * Checks to see if the state is discarded + * @param {string} State + * @return {bool} + */ + History.discardedHash = function(hash){ + // Check + var discarded = History.discardedHashes[hash]||false; + + // Return true + return discarded; + }; + + /** + * History.recycleState(State) + * Allows a discarded state to be used again + * @param {object} data + * @param {string} title + * @param {string} url + * @return {true} + */ + History.recycleState = function(State){ + //History.debug('History.recycleState', arguments); + // Prepare + var StateHash = History.getHashByState(State); + + // Remove from DiscardedStates + if ( History.discardedState(State) ) { + delete History.discardedStates[StateHash]; + } + + // Return true + return true; + }; + + + // ==================================================================== + // HTML4 HashChange Support + + if ( History.emulated.hashChange ) { + /* + * We must emulate the HTML4 HashChange Support by manually checking for hash changes + */ + + /** + * History.hashChangeInit() + * Init the HashChange Emulation + */ + History.hashChangeInit = function(){ + // Define our Checker Function + History.checkerFunction = null; + + // Define some variables that will help in our checker function + var lastDocumentHash = '', + iframeId, iframe, + lastIframeHash, checkerRunning, + startedWithHash = Boolean(History.getHash()); + + // Handle depending on the browser + if ( History.isInternetExplorer() ) { + // IE6 and IE7 + // We need to use an iframe to emulate the back and forward buttons + + // Create iFrame + iframeId = 'historyjs-iframe'; + iframe = document.createElement('iframe'); + + // Adjust iFarme + // IE 6 requires iframe to have a src on HTTPS pages, otherwise it will throw a + // "This page contains both secure and nonsecure items" warning. + iframe.setAttribute('id', iframeId); + iframe.setAttribute('src', '#'); + iframe.style.display = 'none'; + + // Append iFrame + document.body.appendChild(iframe); + + // Create initial history entry + iframe.contentWindow.document.open(); + iframe.contentWindow.document.close(); + + // Define some variables that will help in our checker function + lastIframeHash = ''; + checkerRunning = false; + + // Define the checker function + History.checkerFunction = function(){ + // Check Running + if ( checkerRunning ) { + return false; + } + + // Update Running + checkerRunning = true; + + // Fetch + var + documentHash = History.getHash(), + iframeHash = History.getHash(iframe.contentWindow.document); + + // The Document Hash has changed (application caused) + if ( documentHash !== lastDocumentHash ) { + // Equalise + lastDocumentHash = documentHash; + + // Create a history entry in the iframe + if ( iframeHash !== documentHash ) { + //History.debug('hashchange.checker: iframe hash change', 'documentHash (new):', documentHash, 'iframeHash (old):', iframeHash); + + // Equalise + lastIframeHash = iframeHash = documentHash; + + // Create History Entry + iframe.contentWindow.document.open(); + iframe.contentWindow.document.close(); + + // Update the iframe's hash + iframe.contentWindow.document.location.hash = History.escapeHash(documentHash); + } + + // Trigger Hashchange Event + History.Adapter.trigger(window,'hashchange'); + } + + // The iFrame Hash has changed (back button caused) + else if ( iframeHash !== lastIframeHash ) { + //History.debug('hashchange.checker: iframe hash out of sync', 'iframeHash (new):', iframeHash, 'documentHash (old):', documentHash); + + // Equalise + lastIframeHash = iframeHash; + + // If there is no iframe hash that means we're at the original + // iframe state. + // And if there was a hash on the original request, the original + // iframe state was replaced instantly, so skip this state and take + // the user back to where they came from. + if (startedWithHash && iframeHash === '') { + History.back(); + } + else { + // Update the Hash + History.setHash(iframeHash,false); + } + } + + // Reset Running + checkerRunning = false; + + // Return true + return true; + }; + } + else { + // We are not IE + // Firefox 1 or 2, Opera + + // Define the checker function + History.checkerFunction = function(){ + // Prepare + var documentHash = History.getHash()||''; + + // The Document Hash has changed (application caused) + if ( documentHash !== lastDocumentHash ) { + // Equalise + lastDocumentHash = documentHash; + + // Trigger Hashchange Event + History.Adapter.trigger(window,'hashchange'); + } + + // Return true + return true; + }; + } + + // Apply the checker function + History.intervalList.push(setInterval(History.checkerFunction, History.options.hashChangeInterval)); + + // Done + return true; + }; // History.hashChangeInit + + // Bind hashChangeInit + History.Adapter.onDomLoad(History.hashChangeInit); + + } // History.emulated.hashChange + + + // ==================================================================== + // HTML5 State Support + + // Non-Native pushState Implementation + if ( History.emulated.pushState ) { + /* + * We must emulate the HTML5 State Management by using HTML4 HashChange + */ + + /** + * History.onHashChange(event) + * Trigger HTML5's window.onpopstate via HTML4 HashChange Support + */ + History.onHashChange = function(event){ + //History.debug('History.onHashChange', arguments); + + // Prepare + var currentUrl = ((event && event.newURL) || History.getLocationHref()), + currentHash = History.getHashByUrl(currentUrl), + currentState = null, + currentStateHash = null, + currentStateHashExits = null, + discardObject; + + // Check if we are the same state + if ( History.isLastHash(currentHash) ) { + // There has been no change (just the page's hash has finally propagated) + //History.debug('History.onHashChange: no change'); + History.busy(false); + return false; + } + + // Reset the double check + History.doubleCheckComplete(); + + // Store our location for use in detecting back/forward direction + History.saveHash(currentHash); + + // Expand Hash + if ( currentHash && History.isTraditionalAnchor(currentHash) ) { + //History.debug('History.onHashChange: traditional anchor', currentHash); + // Traditional Anchor Hash + History.Adapter.trigger(window,'anchorchange'); + History.busy(false); + return false; + } + + // Create State + currentState = History.extractState(History.getFullUrl(currentHash||History.getLocationHref()),true); + + // Check if we are the same state + if ( History.isLastSavedState(currentState) ) { + //History.debug('History.onHashChange: no change'); + // There has been no change (just the page's hash has finally propagated) + History.busy(false); + return false; + } + + // Create the state Hash + currentStateHash = History.getHashByState(currentState); + + // Check if we are DiscardedState + discardObject = History.discardedState(currentState); + if ( discardObject ) { + // Ignore this state as it has been discarded and go back to the state before it + if ( History.getHashByIndex(-2) === History.getHashByState(discardObject.forwardState) ) { + // We are going backwards + //History.debug('History.onHashChange: go backwards'); + History.back(false); + } else { + // We are going forwards + //History.debug('History.onHashChange: go forwards'); + History.forward(false); + } + return false; + } + + // Push the new HTML5 State + //History.debug('History.onHashChange: success hashchange'); + History.pushState(currentState.data,currentState.title,encodeURI(currentState.url),false); + + // End onHashChange closure + return true; + }; + History.Adapter.bind(window,'hashchange',History.onHashChange); + + /** + * History.pushState(data,title,url) + * Add a new State to the history object, become it, and trigger onpopstate + * We have to trigger for HTML4 compatibility + * @param {object} data + * @param {string} title + * @param {string} url + * @return {true} + */ + History.pushState = function(data,title,url,queue){ + //History.debug('History.pushState: called', arguments); + + // We assume that the URL passed in is URI-encoded, but this makes + // sure that it's fully URI encoded; any '%'s that are encoded are + // converted back into '%'s + url = encodeURI(url).replace(/%25/g, "%"); + + // Check the State + if ( History.getHashByUrl(url) ) { + throw new Error('History.js does not support states with fragment-identifiers (hashes/anchors).'); + } + + // Handle Queueing + if ( queue !== false && History.busy() ) { + // Wait + Push to Queue + //History.debug('History.pushState: we must wait', arguments); + History.pushQueue({ + scope: History, + callback: History.pushState, + args: arguments, + queue: queue + }); + return false; + } + + // Make Busy + History.busy(true); + + // Fetch the State Object + var newState = History.createStateObject(data,title,url), + newStateHash = History.getHashByState(newState), + oldState = History.getState(false), + oldStateHash = History.getHashByState(oldState), + html4Hash = History.getHash(), + wasExpected = History.expectedStateId == newState.id; + + // Store the newState + History.storeState(newState); + History.expectedStateId = newState.id; + + // Recycle the State + History.recycleState(newState); + + // Force update of the title + History.setTitle(newState); + + // Check if we are the same State + if ( newStateHash === oldStateHash ) { + //History.debug('History.pushState: no change', newStateHash); + History.busy(false); + return false; + } + + // Update HTML5 State + History.saveState(newState); + + // Fire HTML5 Event + if(!wasExpected) + History.Adapter.trigger(window,'statechange'); + + // Update HTML4 Hash + if ( !History.isHashEqual(newStateHash, html4Hash) && !History.isHashEqual(newStateHash, History.getShortUrl(History.getLocationHref())) ) { + History.setHash(newStateHash,false); + } + + History.busy(false); + + // End pushState closure + return true; + }; + + /** + * History.replaceState(data,title,url) + * Replace the State and trigger onpopstate + * We have to trigger for HTML4 compatibility + * @param {object} data + * @param {string} title + * @param {string} url + * @return {true} + */ + History.replaceState = function(data,title,url,queue){ + //History.debug('History.replaceState: called', arguments); + + // We assume that the URL passed in is URI-encoded, but this makes + // sure that it's fully URI encoded; any '%'s that are encoded are + // converted back into '%'s + url = encodeURI(url).replace(/%25/g, "%"); + + // Check the State + if ( History.getHashByUrl(url) ) { + throw new Error('History.js does not support states with fragment-identifiers (hashes/anchors).'); + } + + // Handle Queueing + if ( queue !== false && History.busy() ) { + // Wait + Push to Queue + //History.debug('History.replaceState: we must wait', arguments); + History.pushQueue({ + scope: History, + callback: History.replaceState, + args: arguments, + queue: queue + }); + return false; + } + + // Make Busy + History.busy(true); + + // Fetch the State Objects + var newState = History.createStateObject(data,title,url), + newStateHash = History.getHashByState(newState), + oldState = History.getState(false), + oldStateHash = History.getHashByState(oldState), + previousState = History.getStateByIndex(-2); + + // Discard Old State + History.discardState(oldState,newState,previousState); + + // If the url hasn't changed, just store and save the state + // and fire a statechange event to be consistent with the + // html 5 api + if ( newStateHash === oldStateHash ) { + // Store the newState + History.storeState(newState); + History.expectedStateId = newState.id; + + // Recycle the State + History.recycleState(newState); + + // Force update of the title + History.setTitle(newState); + + // Update HTML5 State + History.saveState(newState); + + // Fire HTML5 Event + //History.debug('History.pushState: trigger popstate'); + History.Adapter.trigger(window,'statechange'); + History.busy(false); + } + else { + // Alias to PushState + History.pushState(newState.data,newState.title,newState.url,false); + } + + // End replaceState closure + return true; + }; + + } // History.emulated.pushState + + + + // ==================================================================== + // Initialise + + // Non-Native pushState Implementation + if ( History.emulated.pushState ) { + /** + * Ensure initial state is handled correctly + */ + if ( History.getHash() && !History.emulated.hashChange ) { + History.Adapter.onDomLoad(function(){ + History.Adapter.trigger(window,'hashchange'); + }); + } + + } // History.emulated.pushState + + }; // History.initHtml4 + + // Try to Initialise History + if ( typeof History.init !== 'undefined' ) { + History.init(); + } + +})(window); +/** + * History.js Core + * @author Benjamin Arthur Lupton + * @copyright 2010-2011 Benjamin Arthur Lupton + * @license New BSD License + */ + +(function(window,undefined){ + "use strict"; + + // ======================================================================== + // Initialise + + // Localise Globals + var + console = window.console||undefined, // Prevent a JSLint complain + document = window.document, // Make sure we are using the correct document + navigator = window.navigator, // Make sure we are using the correct navigator + sessionStorage = window.sessionStorage||false, // sessionStorage + setTimeout = window.setTimeout, + clearTimeout = window.clearTimeout, + setInterval = window.setInterval, + clearInterval = window.clearInterval, + JSON = window.JSON, + alert = window.alert, + History = window.History = window.History||{}, // Public History Object + history = window.history; // Old History Object + + try { + sessionStorage.setItem('TEST', '1'); + sessionStorage.removeItem('TEST'); + } catch(e) { + sessionStorage = false; + } + + // MooTools Compatibility + JSON.stringify = JSON.stringify||JSON.encode; + JSON.parse = JSON.parse||JSON.decode; + + // Check Existence + if ( typeof History.init !== 'undefined' ) { + throw new Error('History.js Core has already been loaded...'); + } + + // Initialise History + History.init = function(options){ + // Check Load Status of Adapter + if ( typeof History.Adapter === 'undefined' ) { + return false; + } + + // Check Load Status of Core + if ( typeof History.initCore !== 'undefined' ) { + History.initCore(); + } + + // Check Load Status of HTML4 Support + if ( typeof History.initHtml4 !== 'undefined' ) { + History.initHtml4(); + } + + // Return true + return true; + }; + + + // ======================================================================== + // Initialise Core + + // Initialise Core + History.initCore = function(options){ + // Initialise + if ( typeof History.initCore.initialized !== 'undefined' ) { + // Already Loaded + return false; + } + else { + History.initCore.initialized = true; + } + + + // ==================================================================== + // Options + + /** + * History.options + * Configurable options + */ + History.options = History.options||{}; + + /** + * History.options.hashChangeInterval + * How long should the interval be before hashchange checks + */ + History.options.hashChangeInterval = History.options.hashChangeInterval || 100; + + /** + * History.options.safariPollInterval + * How long should the interval be before safari poll checks + */ + History.options.safariPollInterval = History.options.safariPollInterval || 500; + + /** + * History.options.doubleCheckInterval + * How long should the interval be before we perform a double check + */ + History.options.doubleCheckInterval = History.options.doubleCheckInterval || 500; + + /** + * History.options.disableSuid + * Force History not to append suid + */ + History.options.disableSuid = History.options.disableSuid || false; + + /** + * History.options.storeInterval + * How long should we wait between store calls + */ + History.options.storeInterval = History.options.storeInterval || 1000; + + /** + * History.options.busyDelay + * How long should we wait between busy events + */ + History.options.busyDelay = History.options.busyDelay || 250; + + /** + * History.options.debug + * If true will enable debug messages to be logged + */ + History.options.debug = History.options.debug || false; + + /** + * History.options.initialTitle + * What is the title of the initial state + */ + History.options.initialTitle = History.options.initialTitle || document.title; + + /** + * History.options.html4Mode + * If true, will force HTMl4 mode (hashtags) + */ + History.options.html4Mode = History.options.html4Mode || false; + + /** + * History.options.delayInit + * Want to override default options and call init manually. + */ + History.options.delayInit = History.options.delayInit || false; + + + // ==================================================================== + // Interval record + + /** + * History.intervalList + * List of intervals set, to be cleared when document is unloaded. + */ + History.intervalList = []; + + /** + * History.clearAllIntervals + * Clears all setInterval instances. + */ + History.clearAllIntervals = function(){ + var i, il = History.intervalList; + if (typeof il !== "undefined" && il !== null) { + for (i = 0; i < il.length; i++) { + clearInterval(il[i]); + } + History.intervalList = null; + } + }; + + + // ==================================================================== + // Debug + + /** + * History.debug(message,...) + * Logs the passed arguments if debug enabled + */ + History.debug = function(){ + if ( (History.options.debug||false) ) { + History.log.apply(History,arguments); + } + }; + + /** + * History.log(message,...) + * Logs the passed arguments + */ + History.log = function(){ + // Prepare + var + consoleExists = !(typeof console === 'undefined' || typeof console.log === 'undefined' || typeof console.log.apply === 'undefined'), + textarea = document.getElementById('log'), + message, + i,n, + args,arg + ; + + // Write to Console + if ( consoleExists ) { + args = Array.prototype.slice.call(arguments); + message = args.shift(); + if ( typeof console.debug !== 'undefined' ) { + console.debug.apply(console,[message,args]); + } + else { + console.log.apply(console,[message,args]); + } + } + else { + message = ("\n"+arguments[0]+"\n"); + } + + // Write to log + for ( i=1,n=arguments.length; i + * @author James Padolsey + */ + History.getInternetExplorerMajorVersion = function(){ + var result = History.getInternetExplorerMajorVersion.cached = + (typeof History.getInternetExplorerMajorVersion.cached !== 'undefined') + ? History.getInternetExplorerMajorVersion.cached + : (function(){ + var v = 3, + div = document.createElement('div'), + all = div.getElementsByTagName('i'); + while ( (div.innerHTML = '') && all[0] ) {} + return (v > 4) ? v : false; + })() + ; + return result; + }; + + /** + * History.isInternetExplorer() + * Are we using Internet Explorer? + * @return {boolean} + * @license Public Domain + * @author Benjamin Arthur Lupton + */ + History.isInternetExplorer = function(){ + var result = + History.isInternetExplorer.cached = + (typeof History.isInternetExplorer.cached !== 'undefined') + ? History.isInternetExplorer.cached + : Boolean(History.getInternetExplorerMajorVersion()) + ; + return result; + }; + + /** + * History.emulated + * Which features require emulating? + */ + + if (History.options.html4Mode) { + History.emulated = { + pushState : true, + hashChange: true + }; + } + + else { + + History.emulated = { + pushState: !Boolean( + window.history && window.history.pushState && window.history.replaceState + && !( + (/ Mobile\/([1-7][a-z]|(8([abcde]|f(1[0-8]))))/i).test(navigator.userAgent) /* disable for versions of iOS before version 4.3 (8F190) */ + || (/AppleWebKit\/5([0-2]|3[0-2])/i).test(navigator.userAgent) /* disable for the mercury iOS browser, or at least older versions of the webkit engine */ + ) + ), + hashChange: Boolean( + !(('onhashchange' in window) || ('onhashchange' in document)) + || + (History.isInternetExplorer() && History.getInternetExplorerMajorVersion() < 8) + ) + }; + } + + /** + * History.enabled + * Is History enabled? + */ + History.enabled = !History.emulated.pushState; + + /** + * History.bugs + * Which bugs are present + */ + History.bugs = { + /** + * Safari 5 and Safari iOS 4 fail to return to the correct state once a hash is replaced by a `replaceState` call + * https://bugs.webkit.org/show_bug.cgi?id=56249 + */ + setHash: Boolean(!History.emulated.pushState && navigator.vendor === 'Apple Computer, Inc.' && /AppleWebKit\/5([0-2]|3[0-3])/.test(navigator.userAgent)), + + /** + * Safari 5 and Safari iOS 4 sometimes fail to apply the state change under busy conditions + * https://bugs.webkit.org/show_bug.cgi?id=42940 + */ + safariPoll: Boolean(!History.emulated.pushState && navigator.vendor === 'Apple Computer, Inc.' && /AppleWebKit\/5([0-2]|3[0-3])/.test(navigator.userAgent)), + + /** + * MSIE 6 and 7 sometimes do not apply a hash even it was told to (requiring a second call to the apply function) + */ + ieDoubleCheck: Boolean(History.isInternetExplorer() && History.getInternetExplorerMajorVersion() < 8), + + /** + * MSIE 6 requires the entire hash to be encoded for the hashes to trigger the onHashChange event + */ + hashEscape: Boolean(History.isInternetExplorer() && History.getInternetExplorerMajorVersion() < 7) + }; + + /** + * History.isEmptyObject(obj) + * Checks to see if the Object is Empty + * @param {Object} obj + * @return {boolean} + */ + History.isEmptyObject = function(obj) { + for ( var name in obj ) { + if ( obj.hasOwnProperty(name) ) { + return false; + } + } + return true; + }; + + /** + * History.cloneObject(obj) + * Clones a object and eliminate all references to the original contexts + * @param {Object} obj + * @return {Object} + */ + History.cloneObject = function(obj) { + var hash,newObj; + if ( obj ) { + hash = JSON.stringify(obj); + newObj = JSON.parse(hash); + } + else { + newObj = {}; + } + return newObj; + }; + + + // ==================================================================== + // URL Helpers + + /** + * History.getRootUrl() + * Turns "http://mysite.com/dir/page.html?asd" into "http://mysite.com" + * @return {String} rootUrl + */ + History.getRootUrl = function(){ + // Create + var rootUrl = document.location.protocol+'//'+(document.location.hostname||document.location.host); + if ( document.location.port||false ) { + rootUrl += ':'+document.location.port; + } + rootUrl += '/'; + + // Return + return rootUrl; + }; + + /** + * History.getBaseHref() + * Fetches the `href` attribute of the `` element if it exists + * @return {String} baseHref + */ + History.getBaseHref = function(){ + // Create + var + baseElements = document.getElementsByTagName('base'), + baseElement = null, + baseHref = ''; + + // Test for Base Element + if ( baseElements.length === 1 ) { + // Prepare for Base Element + baseElement = baseElements[0]; + baseHref = baseElement.href.replace(/[^\/]+$/,''); + } + + // Adjust trailing slash + baseHref = baseHref.replace(/\/+$/,''); + if ( baseHref ) baseHref += '/'; + + // Return + return baseHref; + }; + + /** + * History.getBaseUrl() + * Fetches the baseHref or basePageUrl or rootUrl (whichever one exists first) + * @return {String} baseUrl + */ + History.getBaseUrl = function(){ + // Create + var baseUrl = History.getBaseHref()||History.getBasePageUrl()||History.getRootUrl(); + + // Return + return baseUrl; + }; + + /** + * History.getPageUrl() + * Fetches the URL of the current page + * @return {String} pageUrl + */ + History.getPageUrl = function(){ + // Fetch + var + State = History.getState(false,false), + stateUrl = (State||{}).url||History.getLocationHref(), + pageUrl; + + // Create + pageUrl = stateUrl.replace(/\/+$/,'').replace(/[^\/]+$/,function(part,index,string){ + return (/\./).test(part) ? part : part+'/'; + }); + + // Return + return pageUrl; + }; + + /** + * History.getBasePageUrl() + * Fetches the Url of the directory of the current page + * @return {String} basePageUrl + */ + History.getBasePageUrl = function(){ + // Create + var basePageUrl = (History.getLocationHref()).replace(/[#\?].*/,'').replace(/[^\/]+$/,function(part,index,string){ + return (/[^\/]$/).test(part) ? '' : part; + }).replace(/\/+$/,'')+'/'; + + // Return + return basePageUrl; + }; + + /** + * History.getFullUrl(url) + * Ensures that we have an absolute URL and not a relative URL + * @param {string} url + * @param {Boolean} allowBaseHref + * @return {string} fullUrl + */ + History.getFullUrl = function(url,allowBaseHref){ + // Prepare + var fullUrl = url, firstChar = url.substring(0,1); + allowBaseHref = (typeof allowBaseHref === 'undefined') ? true : allowBaseHref; + + // Check + if ( /[a-z]+\:\/\//.test(url) ) { + // Full URL + } + else if ( firstChar === '/' ) { + // Root URL + fullUrl = History.getRootUrl()+url.replace(/^\/+/,''); + } + else if ( firstChar === '#' ) { + // Anchor URL + fullUrl = History.getPageUrl().replace(/#.*/,'')+url; + } + else if ( firstChar === '?' ) { + // Query URL + fullUrl = History.getPageUrl().replace(/[\?#].*/,'')+url; + } + else { + // Relative URL + if ( allowBaseHref ) { + fullUrl = History.getBaseUrl()+url.replace(/^(\.\/)+/,''); + } else { + fullUrl = History.getBasePageUrl()+url.replace(/^(\.\/)+/,''); + } + // We have an if condition above as we do not want hashes + // which are relative to the baseHref in our URLs + // as if the baseHref changes, then all our bookmarks + // would now point to different locations + // whereas the basePageUrl will always stay the same + } + + // Return + return fullUrl.replace(/\#$/,''); + }; + + /** + * History.getShortUrl(url) + * Ensures that we have a relative URL and not a absolute URL + * @param {string} url + * @return {string} url + */ + History.getShortUrl = function(url){ + // Prepare + var shortUrl = url, baseUrl = History.getBaseUrl(), rootUrl = History.getRootUrl(); + + // Trim baseUrl + if ( History.emulated.pushState ) { + // We are in a if statement as when pushState is not emulated + // The actual url these short urls are relative to can change + // So within the same session, we the url may end up somewhere different + shortUrl = shortUrl.replace(baseUrl,''); + } + + // Trim rootUrl + shortUrl = shortUrl.replace(rootUrl,'/'); + + // Ensure we can still detect it as a state + if ( History.isTraditionalAnchor(shortUrl) ) { + shortUrl = './'+shortUrl; + } + + // Clean It + shortUrl = shortUrl.replace(/^(\.\/)+/g,'./').replace(/\#$/,''); + + // Return + return shortUrl; + }; + + /** + * History.getLocationHref(document) + * Returns a normalized version of document.location.href + * accounting for browser inconsistencies, etc. + * + * This URL will be URI-encoded and will include the hash + * + * @param {object} document + * @return {string} url + */ + History.getLocationHref = function(doc) { + doc = doc || document; + + // most of the time, this will be true + if (doc.URL === doc.location.href) + return doc.location.href; + + // some versions of webkit URI-decode document.location.href + // but they leave document.URL in an encoded state + if (doc.location.href === decodeURIComponent(doc.URL)) + return doc.URL; + + // FF 3.6 only updates document.URL when a page is reloaded + // document.location.href is updated correctly + if (doc.location.hash && decodeURIComponent(doc.location.href.replace(/^[^#]+/, "")) === doc.location.hash) + return doc.location.href; + + if (doc.URL.indexOf('#') == -1 && doc.location.href.indexOf('#') != -1) + return doc.location.href; + + return doc.URL || doc.location.href; + }; + + + // ==================================================================== + // State Storage + + /** + * History.store + * The store for all session specific data + */ + History.store = {}; + + /** + * History.idToState + * 1-1: State ID to State Object + */ + History.idToState = History.idToState||{}; + + /** + * History.stateToId + * 1-1: State String to State ID + */ + History.stateToId = History.stateToId||{}; + + /** + * History.urlToId + * 1-1: State URL to State ID + */ + History.urlToId = History.urlToId||{}; + + /** + * History.storedStates + * Store the states in an array + */ + History.storedStates = History.storedStates||[]; + + /** + * History.savedStates + * Saved the states in an array + */ + History.savedStates = History.savedStates||[]; + + /** + * History.noramlizeStore() + * Noramlize the store by adding necessary values + */ + History.normalizeStore = function(){ + History.store.idToState = History.store.idToState||{}; + History.store.urlToId = History.store.urlToId||{}; + History.store.stateToId = History.store.stateToId||{}; + }; + + /** + * History.getState() + * Get an object containing the data, title and url of the current state + * @param {Boolean} friendly + * @param {Boolean} create + * @return {Object} State + */ + History.getState = function(friendly,create){ + // Prepare + if ( typeof friendly === 'undefined' ) { friendly = true; } + if ( typeof create === 'undefined' ) { create = true; } + + // Fetch + var State = History.getLastSavedState(); + + // Create + if ( !State && create ) { + State = History.createStateObject(); + } + + // Adjust + if ( friendly ) { + State = History.cloneObject(State); + State.url = State.cleanUrl||State.url; + } + + // Return + return State; + }; + + /** + * History.getIdByState(State) + * Gets a ID for a State + * @param {State} newState + * @return {String} id + */ + History.getIdByState = function(newState){ + + // Fetch ID + var id = History.extractId(newState.url), + str; + + if ( !id ) { + // Find ID via State String + str = History.getStateString(newState); + if ( typeof History.stateToId[str] !== 'undefined' ) { + id = History.stateToId[str]; + } + else if ( typeof History.store.stateToId[str] !== 'undefined' ) { + id = History.store.stateToId[str]; + } + else { + // Generate a new ID + while ( true ) { + id = (new Date()).getTime() + String(Math.random()).replace(/\D/g,''); + if ( typeof History.idToState[id] === 'undefined' && typeof History.store.idToState[id] === 'undefined' ) { + break; + } + } + + // Apply the new State to the ID + History.stateToId[str] = id; + History.idToState[id] = newState; + } + } + + // Return ID + return id; + }; + + /** + * History.normalizeState(State) + * Expands a State Object + * @param {object} State + * @return {object} + */ + History.normalizeState = function(oldState){ + // Variables + var newState, dataNotEmpty; + + // Prepare + if ( !oldState || (typeof oldState !== 'object') ) { + oldState = {}; + } + + // Check + if ( typeof oldState.normalized !== 'undefined' ) { + return oldState; + } + + // Adjust + if ( !oldState.data || (typeof oldState.data !== 'object') ) { + oldState.data = {}; + } + + // ---------------------------------------------------------------- + + // Create + newState = {}; + newState.normalized = true; + newState.title = oldState.title||''; + newState.url = History.getFullUrl(oldState.url?oldState.url:(History.getLocationHref())); + newState.hash = History.getShortUrl(newState.url); + newState.data = History.cloneObject(oldState.data); + + // Fetch ID + newState.id = History.getIdByState(newState); + + // ---------------------------------------------------------------- + + // Clean the URL + newState.cleanUrl = newState.url.replace(/\??\&_suid.*/,''); + newState.url = newState.cleanUrl; + + // Check to see if we have more than just a url + dataNotEmpty = !History.isEmptyObject(newState.data); + + // Apply + if ( (newState.title || dataNotEmpty) && History.options.disableSuid !== true ) { + // Add ID to Hash + newState.hash = History.getShortUrl(newState.url).replace(/\??\&_suid.*/,''); + if ( !/\?/.test(newState.hash) ) { + newState.hash += '?'; + } + newState.hash += '&_suid='+newState.id; + } + + // Create the Hashed URL + newState.hashedUrl = History.getFullUrl(newState.hash); + + // ---------------------------------------------------------------- + + // Update the URL if we have a duplicate + if ( (History.emulated.pushState || History.bugs.safariPoll) && History.hasUrlDuplicate(newState) ) { + newState.url = newState.hashedUrl; + } + + // ---------------------------------------------------------------- + + // Return + return newState; + }; + + /** + * History.createStateObject(data,title,url) + * Creates a object based on the data, title and url state params + * @param {object} data + * @param {string} title + * @param {string} url + * @return {object} + */ + History.createStateObject = function(data,title,url){ + // Hashify + var State = { + 'data': data, + 'title': title, + 'url': url + }; + + // Expand the State + State = History.normalizeState(State); + + // Return object + return State; + }; + + /** + * History.getStateById(id) + * Get a state by it's UID + * @param {String} id + */ + History.getStateById = function(id){ + // Prepare + id = String(id); + + // Retrieve + var State = History.idToState[id] || History.store.idToState[id] || undefined; + + // Return State + return State; + }; + + /** + * Get a State's String + * @param {State} passedState + */ + History.getStateString = function(passedState){ + // Prepare + var State, cleanedState, str; + + // Fetch + State = History.normalizeState(passedState); + + // Clean + cleanedState = { + data: State.data, + title: passedState.title, + url: passedState.url + }; + + // Fetch + str = JSON.stringify(cleanedState); + + // Return + return str; + }; + + /** + * Get a State's ID + * @param {State} passedState + * @return {String} id + */ + History.getStateId = function(passedState){ + // Prepare + var State, id; + + // Fetch + State = History.normalizeState(passedState); + + // Fetch + id = State.id; + + // Return + return id; + }; + + /** + * History.getHashByState(State) + * Creates a Hash for the State Object + * @param {State} passedState + * @return {String} hash + */ + History.getHashByState = function(passedState){ + // Prepare + var State, hash; + + // Fetch + State = History.normalizeState(passedState); + + // Hash + hash = State.hash; + + // Return + return hash; + }; + + /** + * History.extractId(url_or_hash) + * Get a State ID by it's URL or Hash + * @param {string} url_or_hash + * @return {string} id + */ + History.extractId = function ( url_or_hash ) { + // Prepare + var id,parts,url, tmp; + + // Extract + + // If the URL has a #, use the id from before the # + if (url_or_hash.indexOf('#') != -1) + { + tmp = url_or_hash.split("#")[0]; + } + else + { + tmp = url_or_hash; + } + + parts = /(.*)\&_suid=([0-9]+)$/.exec(tmp); + url = parts ? (parts[1]||url_or_hash) : url_or_hash; + id = parts ? String(parts[2]||'') : ''; + + // Return + return id||false; + }; + + /** + * History.isTraditionalAnchor + * Checks to see if the url is a traditional anchor or not + * @param {String} url_or_hash + * @return {Boolean} + */ + History.isTraditionalAnchor = function(url_or_hash){ + // Check + var isTraditional = !(/[\/\?\.]/.test(url_or_hash)); + + // Return + return isTraditional; + }; + + /** + * History.extractState + * Get a State by it's URL or Hash + * @param {String} url_or_hash + * @return {State|null} + */ + History.extractState = function(url_or_hash,create){ + // Prepare + var State = null, id, url; + create = create||false; + + // Fetch SUID + id = History.extractId(url_or_hash); + if ( id ) { + State = History.getStateById(id); + } + + // Fetch SUID returned no State + if ( !State ) { + // Fetch URL + url = History.getFullUrl(url_or_hash); + + // Check URL + id = History.getIdByUrl(url)||false; + if ( id ) { + State = History.getStateById(id); + } + + // Create State + if ( !State && create && !History.isTraditionalAnchor(url_or_hash) ) { + State = History.createStateObject(null,null,url); + } + } + + // Return + return State; + }; + + /** + * History.getIdByUrl() + * Get a State ID by a State URL + */ + History.getIdByUrl = function(url){ + // Fetch + var id = History.urlToId[url] || History.store.urlToId[url] || undefined; + + // Return + return id; + }; + + /** + * History.getLastSavedState() + * Get an object containing the data, title and url of the current state + * @return {Object} State + */ + History.getLastSavedState = function(){ + return History.savedStates[History.savedStates.length-1]||undefined; + }; + + /** + * History.getLastStoredState() + * Get an object containing the data, title and url of the current state + * @return {Object} State + */ + History.getLastStoredState = function(){ + return History.storedStates[History.storedStates.length-1]||undefined; + }; + + /** + * History.hasUrlDuplicate + * Checks if a Url will have a url conflict + * @param {Object} newState + * @return {Boolean} hasDuplicate + */ + History.hasUrlDuplicate = function(newState) { + // Prepare + var hasDuplicate = false, + oldState; + + // Fetch + oldState = History.extractState(newState.url); + + // Check + hasDuplicate = oldState && oldState.id !== newState.id; + + // Return + return hasDuplicate; + }; + + /** + * History.storeState + * Store a State + * @param {Object} newState + * @return {Object} newState + */ + History.storeState = function(newState){ + // Store the State + History.urlToId[newState.url] = newState.id; + + // Push the State + History.storedStates.push(History.cloneObject(newState)); + + // Return newState + return newState; + }; + + /** + * History.isLastSavedState(newState) + * Tests to see if the state is the last state + * @param {Object} newState + * @return {boolean} isLast + */ + History.isLastSavedState = function(newState){ + // Prepare + var isLast = false, + newId, oldState, oldId; + + // Check + if ( History.savedStates.length ) { + newId = newState.id; + oldState = History.getLastSavedState(); + oldId = oldState.id; + + // Check + isLast = (newId === oldId); + } + + // Return + return isLast; + }; + + /** + * History.saveState + * Push a State + * @param {Object} newState + * @return {boolean} changed + */ + History.saveState = function(newState){ + // Check Hash + if ( History.isLastSavedState(newState) ) { + return false; + } + + // Push the State + History.savedStates.push(History.cloneObject(newState)); + + // Return true + return true; + }; + + /** + * History.getStateByIndex() + * Gets a state by the index + * @param {integer} index + * @return {Object} + */ + History.getStateByIndex = function(index){ + // Prepare + var State = null; + + // Handle + if ( typeof index === 'undefined' ) { + // Get the last inserted + State = History.savedStates[History.savedStates.length-1]; + } + else if ( index < 0 ) { + // Get from the end + State = History.savedStates[History.savedStates.length+index]; + } + else { + // Get from the beginning + State = History.savedStates[index]; + } + + // Return State + return State; + }; + + /** + * History.getCurrentIndex() + * Gets the current index + * @return (integer) + */ + History.getCurrentIndex = function(){ + // Prepare + var index = null; + + // No states saved + if(History.savedStates.length < 1) { + index = 0; + } + else { + index = History.savedStates.length-1; + } + return index; + }; + + // ==================================================================== + // Hash Helpers + + /** + * History.getHash() + * @param {Location=} location + * Gets the current document hash + * Note: unlike location.hash, this is guaranteed to return the escaped hash in all browsers + * @return {string} + */ + History.getHash = function(doc){ + var url = History.getLocationHref(doc), + hash; + hash = History.getHashByUrl(url); + return hash; + }; + + /** + * History.unescapeHash() + * normalize and Unescape a Hash + * @param {String} hash + * @return {string} + */ + History.unescapeHash = function(hash){ + // Prepare + var result = History.normalizeHash(hash); + + // Unescape hash + result = decodeURIComponent(result); + + // Return result + return result; + }; + + /** + * History.normalizeHash() + * normalize a hash across browsers + * @return {string} + */ + History.normalizeHash = function(hash){ + // Prepare + var result = hash.replace(/[^#]*#/,'').replace(/#.*/, ''); + + // Return result + return result; + }; + + /** + * History.setHash(hash) + * Sets the document hash + * @param {string} hash + * @return {History} + */ + History.setHash = function(hash,queue){ + // Prepare + var State, pageUrl; + + // Handle Queueing + if ( queue !== false && History.busy() ) { + // Wait + Push to Queue + //History.debug('History.setHash: we must wait', arguments); + History.pushQueue({ + scope: History, + callback: History.setHash, + args: arguments, + queue: queue + }); + return false; + } + + // Log + //History.debug('History.setHash: called',hash); + + // Make Busy + Continue + History.busy(true); + + // Check if hash is a state + State = History.extractState(hash,true); + if ( State && !History.emulated.pushState ) { + // Hash is a state so skip the setHash + //History.debug('History.setHash: Hash is a state so skipping the hash set with a direct pushState call',arguments); + + // PushState + History.pushState(State.data,State.title,State.url,false); + } + else if ( History.getHash() !== hash ) { + // Hash is a proper hash, so apply it + + // Handle browser bugs + if ( History.bugs.setHash ) { + // Fix Safari Bug https://bugs.webkit.org/show_bug.cgi?id=56249 + + // Fetch the base page + pageUrl = History.getPageUrl(); + + // Safari hash apply + History.pushState(null,null,pageUrl+'#'+hash,false); + } + else { + // Normal hash apply + document.location.hash = hash; + } + } + + // Chain + return History; + }; + + /** + * History.escape() + * normalize and Escape a Hash + * @return {string} + */ + History.escapeHash = function(hash){ + // Prepare + var result = History.normalizeHash(hash); + + // Escape hash + result = window.encodeURIComponent(result); + + // IE6 Escape Bug + if ( !History.bugs.hashEscape ) { + // Restore common parts + result = result + .replace(/\%21/g,'!') + .replace(/\%26/g,'&') + .replace(/\%3D/g,'=') + .replace(/\%3F/g,'?'); + } + + // Return result + return result; + }; + + /** + * History.getHashByUrl(url) + * Extracts the Hash from a URL + * @param {string} url + * @return {string} url + */ + History.getHashByUrl = function(url){ + // Extract the hash + var hash = String(url) + .replace(/([^#]*)#?([^#]*)#?(.*)/, '$2') + ; + + // Unescape hash + hash = History.unescapeHash(hash); + + // Return hash + return hash; + }; + + /** + * History.setTitle(title) + * Applies the title to the document + * @param {State} newState + * @return {Boolean} + */ + History.setTitle = function(newState){ + // Prepare + var title = newState.title, + firstState; + + // Initial + if ( !title ) { + firstState = History.getStateByIndex(0); + if ( firstState && firstState.url === newState.url ) { + title = firstState.title||History.options.initialTitle; + } + } + + // Apply + try { + document.getElementsByTagName('title')[0].innerHTML = title.replace('<','<').replace('>','>').replace(' & ',' & '); + } + catch ( Exception ) { } + document.title = title; + + // Chain + return History; + }; + + + // ==================================================================== + // Queueing + + /** + * History.queues + * The list of queues to use + * First In, First Out + */ + History.queues = []; + + /** + * History.busy(value) + * @param {boolean} value [optional] + * @return {boolean} busy + */ + History.busy = function(value){ + // Apply + if ( typeof value !== 'undefined' ) { + //History.debug('History.busy: changing ['+(History.busy.flag||false)+'] to ['+(value||false)+']', History.queues.length); + History.busy.flag = value; + } + // Default + else if ( typeof History.busy.flag === 'undefined' ) { + History.busy.flag = false; + } + + // Queue + if ( !History.busy.flag ) { + // Execute the next item in the queue + clearTimeout(History.busy.timeout); + var fireNext = function(){ + var i, queue, item; + if ( History.busy.flag ) return; + for ( i=History.queues.length-1; i >= 0; --i ) { + queue = History.queues[i]; + if ( queue.length === 0 ) continue; + item = queue.shift(); + History.fireQueueItem(item); + History.busy.timeout = setTimeout(fireNext,History.options.busyDelay); + } + }; + History.busy.timeout = setTimeout(fireNext,History.options.busyDelay); + } + + // Return + return History.busy.flag; + }; + + /** + * History.busy.flag + */ + History.busy.flag = false; + + /** + * History.fireQueueItem(item) + * Fire a Queue Item + * @param {Object} item + * @return {Mixed} result + */ + History.fireQueueItem = function(item){ + return item.callback.apply(item.scope||History,item.args||[]); + }; + + /** + * History.pushQueue(callback,args) + * Add an item to the queue + * @param {Object} item [scope,callback,args,queue] + */ + History.pushQueue = function(item){ + // Prepare the queue + History.queues[item.queue||0] = History.queues[item.queue||0]||[]; + + // Add to the queue + History.queues[item.queue||0].push(item); + + // Chain + return History; + }; + + /** + * History.queue (item,queue), (func,queue), (func), (item) + * Either firs the item now if not busy, or adds it to the queue + */ + History.queue = function(item,queue){ + // Prepare + if ( typeof item === 'function' ) { + item = { + callback: item + }; + } + if ( typeof queue !== 'undefined' ) { + item.queue = queue; + } + + // Handle + if ( History.busy() ) { + History.pushQueue(item); + } else { + History.fireQueueItem(item); + } + + // Chain + return History; + }; + + /** + * History.clearQueue() + * Clears the Queue + */ + History.clearQueue = function(){ + History.busy.flag = false; + History.queues = []; + return History; + }; + + + // ==================================================================== + // IE Bug Fix + + /** + * History.stateChanged + * States whether or not the state has changed since the last double check was initialised + */ + History.stateChanged = false; + + /** + * History.doubleChecker + * Contains the timeout used for the double checks + */ + History.doubleChecker = false; + + /** + * History.doubleCheckComplete() + * Complete a double check + * @return {History} + */ + History.doubleCheckComplete = function(){ + // Update + History.stateChanged = true; + + // Clear + History.doubleCheckClear(); + + // Chain + return History; + }; + + /** + * History.doubleCheckClear() + * Clear a double check + * @return {History} + */ + History.doubleCheckClear = function(){ + // Clear + if ( History.doubleChecker ) { + clearTimeout(History.doubleChecker); + History.doubleChecker = false; + } + + // Chain + return History; + }; + + /** + * History.doubleCheck() + * Create a double check + * @return {History} + */ + History.doubleCheck = function(tryAgain){ + // Reset + History.stateChanged = false; + History.doubleCheckClear(); + + // Fix IE6,IE7 bug where calling history.back or history.forward does not actually change the hash (whereas doing it manually does) + // Fix Safari 5 bug where sometimes the state does not change: https://bugs.webkit.org/show_bug.cgi?id=42940 + if ( History.bugs.ieDoubleCheck ) { + // Apply Check + History.doubleChecker = setTimeout( + function(){ + History.doubleCheckClear(); + if ( !History.stateChanged ) { + //History.debug('History.doubleCheck: State has not yet changed, trying again', arguments); + // Re-Attempt + tryAgain(); + } + return true; + }, + History.options.doubleCheckInterval + ); + } + + // Chain + return History; + }; + + + // ==================================================================== + // Safari Bug Fix + + /** + * History.safariStatePoll() + * Poll the current state + * @return {History} + */ + History.safariStatePoll = function(){ + // Poll the URL + + // Get the Last State which has the new URL + var + urlState = History.extractState(History.getLocationHref()), + newState; + + // Check for a difference + if ( !History.isLastSavedState(urlState) ) { + newState = urlState; + } + else { + return; + } + + // Check if we have a state with that url + // If not create it + if ( !newState ) { + //History.debug('History.safariStatePoll: new'); + newState = History.createStateObject(); + } + + // Apply the New State + //History.debug('History.safariStatePoll: trigger'); + History.Adapter.trigger(window,'popstate'); + + // Chain + return History; + }; + + + // ==================================================================== + // State Aliases + + /** + * History.back(queue) + * Send the browser history back one item + * @param {Integer} queue [optional] + */ + History.back = function(queue){ + //History.debug('History.back: called', arguments); + + // Handle Queueing + if ( queue !== false && History.busy() ) { + // Wait + Push to Queue + //History.debug('History.back: we must wait', arguments); + History.pushQueue({ + scope: History, + callback: History.back, + args: arguments, + queue: queue + }); + return false; + } + + // Make Busy + Continue + History.busy(true); + + // Fix certain browser bugs that prevent the state from changing + History.doubleCheck(function(){ + History.back(false); + }); + + // Go back + history.go(-1); + + // End back closure + return true; + }; + + /** + * History.forward(queue) + * Send the browser history forward one item + * @param {Integer} queue [optional] + */ + History.forward = function(queue){ + //History.debug('History.forward: called', arguments); + + // Handle Queueing + if ( queue !== false && History.busy() ) { + // Wait + Push to Queue + //History.debug('History.forward: we must wait', arguments); + History.pushQueue({ + scope: History, + callback: History.forward, + args: arguments, + queue: queue + }); + return false; + } + + // Make Busy + Continue + History.busy(true); + + // Fix certain browser bugs that prevent the state from changing + History.doubleCheck(function(){ + History.forward(false); + }); + + // Go forward + history.go(1); + + // End forward closure + return true; + }; + + /** + * History.go(index,queue) + * Send the browser history back or forward index times + * @param {Integer} queue [optional] + */ + History.go = function(index,queue){ + //History.debug('History.go: called', arguments); + + // Prepare + var i; + + // Handle + if ( index > 0 ) { + // Forward + for ( i=1; i<=index; ++i ) { + History.forward(queue); + } + } + else if ( index < 0 ) { + // Backward + for ( i=-1; i>=index; --i ) { + History.back(queue); + } + } + else { + throw new Error('History.go: History.go requires a positive or negative integer passed.'); + } + + // Chain + return History; + }; + + + // ==================================================================== + // HTML5 State Support + + // Non-Native pushState Implementation + if ( History.emulated.pushState ) { + /* + * Provide Skeleton for HTML4 Browsers + */ + + // Prepare + var emptyFunction = function(){}; + History.pushState = History.pushState||emptyFunction; + History.replaceState = History.replaceState||emptyFunction; + } // History.emulated.pushState + + // Native pushState Implementation + else { + /* + * Use native HTML5 History API Implementation + */ + + /** + * History.onPopState(event,extra) + * Refresh the Current State + */ + History.onPopState = function(event,extra){ + // Prepare + var stateId = false, newState = false, currentHash, currentState; + + // Reset the double check + History.doubleCheckComplete(); + + // Check for a Hash, and handle apporiatly + currentHash = History.getHash(); + if ( currentHash ) { + // Expand Hash + currentState = History.extractState(currentHash||History.getLocationHref(),true); + if ( currentState ) { + // We were able to parse it, it must be a State! + // Let's forward to replaceState + //History.debug('History.onPopState: state anchor', currentHash, currentState); + History.replaceState(currentState.data, currentState.title, currentState.url, false); + } + else { + // Traditional Anchor + //History.debug('History.onPopState: traditional anchor', currentHash); + History.Adapter.trigger(window,'anchorchange'); + History.busy(false); + } + + // We don't care for hashes + History.expectedStateId = false; + return false; + } + + // Ensure + stateId = History.Adapter.extractEventData('state',event,extra) || false; + + // Fetch State + if ( stateId ) { + // Vanilla: Back/forward button was used + newState = History.getStateById(stateId); + } + else if ( History.expectedStateId ) { + // Vanilla: A new state was pushed, and popstate was called manually + newState = History.getStateById(History.expectedStateId); + } + else { + // Initial State + newState = History.extractState(History.getLocationHref()); + } + + // The State did not exist in our store + if ( !newState ) { + // Regenerate the State + newState = History.createStateObject(null,null,History.getLocationHref()); + } + + // Clean + History.expectedStateId = false; + + // Check if we are the same state + if ( History.isLastSavedState(newState) ) { + // There has been no change (just the page's hash has finally propagated) + //History.debug('History.onPopState: no change', newState, History.savedStates); + History.busy(false); + return false; + } + + // Store the State + History.storeState(newState); + History.saveState(newState); + + // Force update of the title + History.setTitle(newState); + + // Fire Our Event + History.Adapter.trigger(window,'statechange'); + History.busy(false); + + // Return true + return true; + }; + History.Adapter.bind(window,'popstate',History.onPopState); + + /** + * History.pushState(data,title,url) + * Add a new State to the history object, become it, and trigger onpopstate + * We have to trigger for HTML4 compatibility + * @param {object} data + * @param {string} title + * @param {string} url + * @return {true} + */ + History.pushState = function(data,title,url,queue){ + //History.debug('History.pushState: called', arguments); + + // Check the State + if ( History.getHashByUrl(url) && History.emulated.pushState ) { + throw new Error('History.js does not support states with fragement-identifiers (hashes/anchors).'); + } + + // Handle Queueing + if ( queue !== false && History.busy() ) { + // Wait + Push to Queue + //History.debug('History.pushState: we must wait', arguments); + History.pushQueue({ + scope: History, + callback: History.pushState, + args: arguments, + queue: queue + }); + return false; + } + + // Make Busy + Continue + History.busy(true); + + // Create the newState + var newState = History.createStateObject(data,title,url); + + // Check it + if ( History.isLastSavedState(newState) ) { + // Won't be a change + History.busy(false); + } + else { + // Store the newState + History.storeState(newState); + History.expectedStateId = newState.id; + + // Push the newState + history.pushState(newState.id,newState.title,newState.url); + + // Fire HTML5 Event + History.Adapter.trigger(window,'popstate'); + } + + // End pushState closure + return true; + }; + + /** + * History.replaceState(data,title,url) + * Replace the State and trigger onpopstate + * We have to trigger for HTML4 compatibility + * @param {object} data + * @param {string} title + * @param {string} url + * @return {true} + */ + History.replaceState = function(data,title,url,queue){ + //History.debug('History.replaceState: called', arguments); + + // Check the State + if ( History.getHashByUrl(url) && History.emulated.pushState ) { + throw new Error('History.js does not support states with fragement-identifiers (hashes/anchors).'); + } + + // Handle Queueing + if ( queue !== false && History.busy() ) { + // Wait + Push to Queue + //History.debug('History.replaceState: we must wait', arguments); + History.pushQueue({ + scope: History, + callback: History.replaceState, + args: arguments, + queue: queue + }); + return false; + } + + // Make Busy + Continue + History.busy(true); + + // Create the newState + var newState = History.createStateObject(data,title,url); + + // Check it + if ( History.isLastSavedState(newState) ) { + // Won't be a change + History.busy(false); + } + else { + // Store the newState + History.storeState(newState); + History.expectedStateId = newState.id; + + // Push the newState + history.replaceState(newState.id,newState.title,newState.url); + + // Fire HTML5 Event + History.Adapter.trigger(window,'popstate'); + } + + // End replaceState closure + return true; + }; + + } // !History.emulated.pushState + + + // ==================================================================== + // Initialise + + /** + * Load the Store + */ + if ( sessionStorage ) { + // Fetch + try { + History.store = JSON.parse(sessionStorage.getItem('History.store'))||{}; + } + catch ( err ) { + History.store = {}; + } + + // Normalize + History.normalizeStore(); + } + else { + // Default Load + History.store = {}; + History.normalizeStore(); + } + + /** + * Clear Intervals on exit to prevent memory leaks + */ + History.Adapter.bind(window,"unload",History.clearAllIntervals); + + /** + * Create the initial State + */ + History.saveState(History.storeState(History.extractState(History.getLocationHref(),true))); + + /** + * Bind for Saving Store + */ + if ( sessionStorage ) { + // When the page is closed + History.onUnload = function(){ + // Prepare + var currentStore, item, currentStoreString; + + // Fetch + try { + currentStore = JSON.parse(sessionStorage.getItem('History.store'))||{}; + } + catch ( err ) { + currentStore = {}; + } + + // Ensure + currentStore.idToState = currentStore.idToState || {}; + currentStore.urlToId = currentStore.urlToId || {}; + currentStore.stateToId = currentStore.stateToId || {}; + + // Sync + for ( item in History.idToState ) { + if ( !History.idToState.hasOwnProperty(item) ) { + continue; + } + currentStore.idToState[item] = History.idToState[item]; + } + for ( item in History.urlToId ) { + if ( !History.urlToId.hasOwnProperty(item) ) { + continue; + } + currentStore.urlToId[item] = History.urlToId[item]; + } + for ( item in History.stateToId ) { + if ( !History.stateToId.hasOwnProperty(item) ) { + continue; + } + currentStore.stateToId[item] = History.stateToId[item]; + } + + // Update + History.store = currentStore; + History.normalizeStore(); + + // In Safari, going into Private Browsing mode causes the + // Session Storage object to still exist but if you try and use + // or set any property/function of it it throws the exception + // "QUOTA_EXCEEDED_ERR: DOM Exception 22: An attempt was made to + // add something to storage that exceeded the quota." infinitely + // every second. + currentStoreString = JSON.stringify(currentStore); + try { + // Store + sessionStorage.setItem('History.store', currentStoreString); + } + catch (e) { + if (e.code === DOMException.QUOTA_EXCEEDED_ERR) { + if (sessionStorage.length) { + // Workaround for a bug seen on iPads. Sometimes the quota exceeded error comes up and simply + // removing/resetting the storage can work. + sessionStorage.removeItem('History.store'); + sessionStorage.setItem('History.store', currentStoreString); + } else { + // Otherwise, we're probably private browsing in Safari, so we'll ignore the exception. + } + } else { + throw e; + } + } + }; + + // For Internet Explorer + History.intervalList.push(setInterval(History.onUnload,History.options.storeInterval)); + + // For Other Browsers + History.Adapter.bind(window,'beforeunload',History.onUnload); + History.Adapter.bind(window,'unload',History.onUnload); + + // Both are enabled for consistency + } + + // Non-Native pushState Implementation + if ( !History.emulated.pushState ) { + // Be aware, the following is only for native pushState implementations + // If you are wanting to include something for all browsers + // Then include it above this if block + + /** + * Setup Safari Fix + */ + if ( History.bugs.safariPoll ) { + History.intervalList.push(setInterval(History.safariStatePoll, History.options.safariPollInterval)); + } + + /** + * Ensure Cross Browser Compatibility + */ + if ( navigator.vendor === 'Apple Computer, Inc.' || (navigator.appCodeName||'') === 'Mozilla' ) { + /** + * Fix Safari HashChange Issue + */ + + // Setup Alias + History.Adapter.bind(window,'hashchange',function(){ + History.Adapter.trigger(window,'popstate'); + }); + + // Initialise Alias + if ( History.getHash() ) { + History.Adapter.onDomLoad(function(){ + History.Adapter.trigger(window,'hashchange'); + }); + } + } + + } // !History.emulated.pushState + + + }; // History.initCore + + // Try to Initialise History + if (!History.options || !History.options.delayInit) { + History.init(); + } + +})(window); diff --git a/sites/all/themes/gui/materiobasetheme/bower_components/history.js/scripts/bundled-uncompressed/html5/dojo.history.js b/sites/all/themes/gui/materiobasetheme/bower_components/history.js/scripts/bundled-uncompressed/html5/dojo.history.js new file mode 100644 index 00000000..1adedd24 --- /dev/null +++ b/sites/all/themes/gui/materiobasetheme/bower_components/history.js/scripts/bundled-uncompressed/html5/dojo.history.js @@ -0,0 +1,2165 @@ +/** + * History.js Dojo Adapter + * + * Essentially the same as the native adapter but uses dojo/ready for the dom load callback. + * + * @author Benjamin Arthur Lupton + * @copyright 2010-2011 Benjamin Arthur Lupton + * @license New BSD License + */ + +// Closure +(function(window,undefined){ + "use strict"; + + // Localise Globals + var History = window.History = window.History||{}, + require = window.require; + + // Check Existence + if ( typeof History.Adapter !== 'undefined' ) { + throw new Error('History.js Adapter has already been loaded...'); + } + + // Add the Adapter + History.Adapter = { + /** + * History.Adapter.handlers[uid][eventName] = Array + */ + handlers: {}, + + /** + * History.Adapter._uid + * The current element unique identifier + */ + _uid: 1, + + /** + * History.Adapter.uid(element) + * @param {Element} element + * @return {String} uid + */ + uid: function(element){ + return element._uid || (element._uid = History.Adapter._uid++); + }, + + /** + * History.Adapter.bind(el,event,callback) + * @param {Element} element + * @param {String} eventName - custom and standard events + * @param {Function} callback + * @return + */ + bind: function(element,eventName,callback){ + // Prepare + var uid = History.Adapter.uid(element); + + // Apply Listener + History.Adapter.handlers[uid] = History.Adapter.handlers[uid] || {}; + History.Adapter.handlers[uid][eventName] = History.Adapter.handlers[uid][eventName] || []; + History.Adapter.handlers[uid][eventName].push(callback); + + // Bind Global Listener + element['on'+eventName] = (function(element,eventName){ + return function(event){ + History.Adapter.trigger(element,eventName,event); + }; + })(element,eventName); + }, + + /** + * History.Adapter.trigger(el,event) + * @param {Element} element + * @param {String} eventName - custom and standard events + * @param {Object} event - a object of event data + * @return + */ + trigger: function(element,eventName,event){ + // Prepare + event = event || {}; + var uid = History.Adapter.uid(element), + i,n; + + // Apply Listener + History.Adapter.handlers[uid] = History.Adapter.handlers[uid] || {}; + History.Adapter.handlers[uid][eventName] = History.Adapter.handlers[uid][eventName] || []; + + // Fire Listeners + for ( i=0,n=History.Adapter.handlers[uid][eventName].length; i + * @copyright 2010-2011 Benjamin Arthur Lupton + * @license New BSD License + */ + +(function(window,undefined){ + "use strict"; + + // ======================================================================== + // Initialise + + // Localise Globals + var + console = window.console||undefined, // Prevent a JSLint complain + document = window.document, // Make sure we are using the correct document + navigator = window.navigator, // Make sure we are using the correct navigator + sessionStorage = window.sessionStorage||false, // sessionStorage + setTimeout = window.setTimeout, + clearTimeout = window.clearTimeout, + setInterval = window.setInterval, + clearInterval = window.clearInterval, + JSON = window.JSON, + alert = window.alert, + History = window.History = window.History||{}, // Public History Object + history = window.history; // Old History Object + + try { + sessionStorage.setItem('TEST', '1'); + sessionStorage.removeItem('TEST'); + } catch(e) { + sessionStorage = false; + } + + // MooTools Compatibility + JSON.stringify = JSON.stringify||JSON.encode; + JSON.parse = JSON.parse||JSON.decode; + + // Check Existence + if ( typeof History.init !== 'undefined' ) { + throw new Error('History.js Core has already been loaded...'); + } + + // Initialise History + History.init = function(options){ + // Check Load Status of Adapter + if ( typeof History.Adapter === 'undefined' ) { + return false; + } + + // Check Load Status of Core + if ( typeof History.initCore !== 'undefined' ) { + History.initCore(); + } + + // Check Load Status of HTML4 Support + if ( typeof History.initHtml4 !== 'undefined' ) { + History.initHtml4(); + } + + // Return true + return true; + }; + + + // ======================================================================== + // Initialise Core + + // Initialise Core + History.initCore = function(options){ + // Initialise + if ( typeof History.initCore.initialized !== 'undefined' ) { + // Already Loaded + return false; + } + else { + History.initCore.initialized = true; + } + + + // ==================================================================== + // Options + + /** + * History.options + * Configurable options + */ + History.options = History.options||{}; + + /** + * History.options.hashChangeInterval + * How long should the interval be before hashchange checks + */ + History.options.hashChangeInterval = History.options.hashChangeInterval || 100; + + /** + * History.options.safariPollInterval + * How long should the interval be before safari poll checks + */ + History.options.safariPollInterval = History.options.safariPollInterval || 500; + + /** + * History.options.doubleCheckInterval + * How long should the interval be before we perform a double check + */ + History.options.doubleCheckInterval = History.options.doubleCheckInterval || 500; + + /** + * History.options.disableSuid + * Force History not to append suid + */ + History.options.disableSuid = History.options.disableSuid || false; + + /** + * History.options.storeInterval + * How long should we wait between store calls + */ + History.options.storeInterval = History.options.storeInterval || 1000; + + /** + * History.options.busyDelay + * How long should we wait between busy events + */ + History.options.busyDelay = History.options.busyDelay || 250; + + /** + * History.options.debug + * If true will enable debug messages to be logged + */ + History.options.debug = History.options.debug || false; + + /** + * History.options.initialTitle + * What is the title of the initial state + */ + History.options.initialTitle = History.options.initialTitle || document.title; + + /** + * History.options.html4Mode + * If true, will force HTMl4 mode (hashtags) + */ + History.options.html4Mode = History.options.html4Mode || false; + + /** + * History.options.delayInit + * Want to override default options and call init manually. + */ + History.options.delayInit = History.options.delayInit || false; + + + // ==================================================================== + // Interval record + + /** + * History.intervalList + * List of intervals set, to be cleared when document is unloaded. + */ + History.intervalList = []; + + /** + * History.clearAllIntervals + * Clears all setInterval instances. + */ + History.clearAllIntervals = function(){ + var i, il = History.intervalList; + if (typeof il !== "undefined" && il !== null) { + for (i = 0; i < il.length; i++) { + clearInterval(il[i]); + } + History.intervalList = null; + } + }; + + + // ==================================================================== + // Debug + + /** + * History.debug(message,...) + * Logs the passed arguments if debug enabled + */ + History.debug = function(){ + if ( (History.options.debug||false) ) { + History.log.apply(History,arguments); + } + }; + + /** + * History.log(message,...) + * Logs the passed arguments + */ + History.log = function(){ + // Prepare + var + consoleExists = !(typeof console === 'undefined' || typeof console.log === 'undefined' || typeof console.log.apply === 'undefined'), + textarea = document.getElementById('log'), + message, + i,n, + args,arg + ; + + // Write to Console + if ( consoleExists ) { + args = Array.prototype.slice.call(arguments); + message = args.shift(); + if ( typeof console.debug !== 'undefined' ) { + console.debug.apply(console,[message,args]); + } + else { + console.log.apply(console,[message,args]); + } + } + else { + message = ("\n"+arguments[0]+"\n"); + } + + // Write to log + for ( i=1,n=arguments.length; i + * @author James Padolsey + */ + History.getInternetExplorerMajorVersion = function(){ + var result = History.getInternetExplorerMajorVersion.cached = + (typeof History.getInternetExplorerMajorVersion.cached !== 'undefined') + ? History.getInternetExplorerMajorVersion.cached + : (function(){ + var v = 3, + div = document.createElement('div'), + all = div.getElementsByTagName('i'); + while ( (div.innerHTML = '') && all[0] ) {} + return (v > 4) ? v : false; + })() + ; + return result; + }; + + /** + * History.isInternetExplorer() + * Are we using Internet Explorer? + * @return {boolean} + * @license Public Domain + * @author Benjamin Arthur Lupton + */ + History.isInternetExplorer = function(){ + var result = + History.isInternetExplorer.cached = + (typeof History.isInternetExplorer.cached !== 'undefined') + ? History.isInternetExplorer.cached + : Boolean(History.getInternetExplorerMajorVersion()) + ; + return result; + }; + + /** + * History.emulated + * Which features require emulating? + */ + + if (History.options.html4Mode) { + History.emulated = { + pushState : true, + hashChange: true + }; + } + + else { + + History.emulated = { + pushState: !Boolean( + window.history && window.history.pushState && window.history.replaceState + && !( + (/ Mobile\/([1-7][a-z]|(8([abcde]|f(1[0-8]))))/i).test(navigator.userAgent) /* disable for versions of iOS before version 4.3 (8F190) */ + || (/AppleWebKit\/5([0-2]|3[0-2])/i).test(navigator.userAgent) /* disable for the mercury iOS browser, or at least older versions of the webkit engine */ + ) + ), + hashChange: Boolean( + !(('onhashchange' in window) || ('onhashchange' in document)) + || + (History.isInternetExplorer() && History.getInternetExplorerMajorVersion() < 8) + ) + }; + } + + /** + * History.enabled + * Is History enabled? + */ + History.enabled = !History.emulated.pushState; + + /** + * History.bugs + * Which bugs are present + */ + History.bugs = { + /** + * Safari 5 and Safari iOS 4 fail to return to the correct state once a hash is replaced by a `replaceState` call + * https://bugs.webkit.org/show_bug.cgi?id=56249 + */ + setHash: Boolean(!History.emulated.pushState && navigator.vendor === 'Apple Computer, Inc.' && /AppleWebKit\/5([0-2]|3[0-3])/.test(navigator.userAgent)), + + /** + * Safari 5 and Safari iOS 4 sometimes fail to apply the state change under busy conditions + * https://bugs.webkit.org/show_bug.cgi?id=42940 + */ + safariPoll: Boolean(!History.emulated.pushState && navigator.vendor === 'Apple Computer, Inc.' && /AppleWebKit\/5([0-2]|3[0-3])/.test(navigator.userAgent)), + + /** + * MSIE 6 and 7 sometimes do not apply a hash even it was told to (requiring a second call to the apply function) + */ + ieDoubleCheck: Boolean(History.isInternetExplorer() && History.getInternetExplorerMajorVersion() < 8), + + /** + * MSIE 6 requires the entire hash to be encoded for the hashes to trigger the onHashChange event + */ + hashEscape: Boolean(History.isInternetExplorer() && History.getInternetExplorerMajorVersion() < 7) + }; + + /** + * History.isEmptyObject(obj) + * Checks to see if the Object is Empty + * @param {Object} obj + * @return {boolean} + */ + History.isEmptyObject = function(obj) { + for ( var name in obj ) { + if ( obj.hasOwnProperty(name) ) { + return false; + } + } + return true; + }; + + /** + * History.cloneObject(obj) + * Clones a object and eliminate all references to the original contexts + * @param {Object} obj + * @return {Object} + */ + History.cloneObject = function(obj) { + var hash,newObj; + if ( obj ) { + hash = JSON.stringify(obj); + newObj = JSON.parse(hash); + } + else { + newObj = {}; + } + return newObj; + }; + + + // ==================================================================== + // URL Helpers + + /** + * History.getRootUrl() + * Turns "http://mysite.com/dir/page.html?asd" into "http://mysite.com" + * @return {String} rootUrl + */ + History.getRootUrl = function(){ + // Create + var rootUrl = document.location.protocol+'//'+(document.location.hostname||document.location.host); + if ( document.location.port||false ) { + rootUrl += ':'+document.location.port; + } + rootUrl += '/'; + + // Return + return rootUrl; + }; + + /** + * History.getBaseHref() + * Fetches the `href` attribute of the `` element if it exists + * @return {String} baseHref + */ + History.getBaseHref = function(){ + // Create + var + baseElements = document.getElementsByTagName('base'), + baseElement = null, + baseHref = ''; + + // Test for Base Element + if ( baseElements.length === 1 ) { + // Prepare for Base Element + baseElement = baseElements[0]; + baseHref = baseElement.href.replace(/[^\/]+$/,''); + } + + // Adjust trailing slash + baseHref = baseHref.replace(/\/+$/,''); + if ( baseHref ) baseHref += '/'; + + // Return + return baseHref; + }; + + /** + * History.getBaseUrl() + * Fetches the baseHref or basePageUrl or rootUrl (whichever one exists first) + * @return {String} baseUrl + */ + History.getBaseUrl = function(){ + // Create + var baseUrl = History.getBaseHref()||History.getBasePageUrl()||History.getRootUrl(); + + // Return + return baseUrl; + }; + + /** + * History.getPageUrl() + * Fetches the URL of the current page + * @return {String} pageUrl + */ + History.getPageUrl = function(){ + // Fetch + var + State = History.getState(false,false), + stateUrl = (State||{}).url||History.getLocationHref(), + pageUrl; + + // Create + pageUrl = stateUrl.replace(/\/+$/,'').replace(/[^\/]+$/,function(part,index,string){ + return (/\./).test(part) ? part : part+'/'; + }); + + // Return + return pageUrl; + }; + + /** + * History.getBasePageUrl() + * Fetches the Url of the directory of the current page + * @return {String} basePageUrl + */ + History.getBasePageUrl = function(){ + // Create + var basePageUrl = (History.getLocationHref()).replace(/[#\?].*/,'').replace(/[^\/]+$/,function(part,index,string){ + return (/[^\/]$/).test(part) ? '' : part; + }).replace(/\/+$/,'')+'/'; + + // Return + return basePageUrl; + }; + + /** + * History.getFullUrl(url) + * Ensures that we have an absolute URL and not a relative URL + * @param {string} url + * @param {Boolean} allowBaseHref + * @return {string} fullUrl + */ + History.getFullUrl = function(url,allowBaseHref){ + // Prepare + var fullUrl = url, firstChar = url.substring(0,1); + allowBaseHref = (typeof allowBaseHref === 'undefined') ? true : allowBaseHref; + + // Check + if ( /[a-z]+\:\/\//.test(url) ) { + // Full URL + } + else if ( firstChar === '/' ) { + // Root URL + fullUrl = History.getRootUrl()+url.replace(/^\/+/,''); + } + else if ( firstChar === '#' ) { + // Anchor URL + fullUrl = History.getPageUrl().replace(/#.*/,'')+url; + } + else if ( firstChar === '?' ) { + // Query URL + fullUrl = History.getPageUrl().replace(/[\?#].*/,'')+url; + } + else { + // Relative URL + if ( allowBaseHref ) { + fullUrl = History.getBaseUrl()+url.replace(/^(\.\/)+/,''); + } else { + fullUrl = History.getBasePageUrl()+url.replace(/^(\.\/)+/,''); + } + // We have an if condition above as we do not want hashes + // which are relative to the baseHref in our URLs + // as if the baseHref changes, then all our bookmarks + // would now point to different locations + // whereas the basePageUrl will always stay the same + } + + // Return + return fullUrl.replace(/\#$/,''); + }; + + /** + * History.getShortUrl(url) + * Ensures that we have a relative URL and not a absolute URL + * @param {string} url + * @return {string} url + */ + History.getShortUrl = function(url){ + // Prepare + var shortUrl = url, baseUrl = History.getBaseUrl(), rootUrl = History.getRootUrl(); + + // Trim baseUrl + if ( History.emulated.pushState ) { + // We are in a if statement as when pushState is not emulated + // The actual url these short urls are relative to can change + // So within the same session, we the url may end up somewhere different + shortUrl = shortUrl.replace(baseUrl,''); + } + + // Trim rootUrl + shortUrl = shortUrl.replace(rootUrl,'/'); + + // Ensure we can still detect it as a state + if ( History.isTraditionalAnchor(shortUrl) ) { + shortUrl = './'+shortUrl; + } + + // Clean It + shortUrl = shortUrl.replace(/^(\.\/)+/g,'./').replace(/\#$/,''); + + // Return + return shortUrl; + }; + + /** + * History.getLocationHref(document) + * Returns a normalized version of document.location.href + * accounting for browser inconsistencies, etc. + * + * This URL will be URI-encoded and will include the hash + * + * @param {object} document + * @return {string} url + */ + History.getLocationHref = function(doc) { + doc = doc || document; + + // most of the time, this will be true + if (doc.URL === doc.location.href) + return doc.location.href; + + // some versions of webkit URI-decode document.location.href + // but they leave document.URL in an encoded state + if (doc.location.href === decodeURIComponent(doc.URL)) + return doc.URL; + + // FF 3.6 only updates document.URL when a page is reloaded + // document.location.href is updated correctly + if (doc.location.hash && decodeURIComponent(doc.location.href.replace(/^[^#]+/, "")) === doc.location.hash) + return doc.location.href; + + if (doc.URL.indexOf('#') == -1 && doc.location.href.indexOf('#') != -1) + return doc.location.href; + + return doc.URL || doc.location.href; + }; + + + // ==================================================================== + // State Storage + + /** + * History.store + * The store for all session specific data + */ + History.store = {}; + + /** + * History.idToState + * 1-1: State ID to State Object + */ + History.idToState = History.idToState||{}; + + /** + * History.stateToId + * 1-1: State String to State ID + */ + History.stateToId = History.stateToId||{}; + + /** + * History.urlToId + * 1-1: State URL to State ID + */ + History.urlToId = History.urlToId||{}; + + /** + * History.storedStates + * Store the states in an array + */ + History.storedStates = History.storedStates||[]; + + /** + * History.savedStates + * Saved the states in an array + */ + History.savedStates = History.savedStates||[]; + + /** + * History.noramlizeStore() + * Noramlize the store by adding necessary values + */ + History.normalizeStore = function(){ + History.store.idToState = History.store.idToState||{}; + History.store.urlToId = History.store.urlToId||{}; + History.store.stateToId = History.store.stateToId||{}; + }; + + /** + * History.getState() + * Get an object containing the data, title and url of the current state + * @param {Boolean} friendly + * @param {Boolean} create + * @return {Object} State + */ + History.getState = function(friendly,create){ + // Prepare + if ( typeof friendly === 'undefined' ) { friendly = true; } + if ( typeof create === 'undefined' ) { create = true; } + + // Fetch + var State = History.getLastSavedState(); + + // Create + if ( !State && create ) { + State = History.createStateObject(); + } + + // Adjust + if ( friendly ) { + State = History.cloneObject(State); + State.url = State.cleanUrl||State.url; + } + + // Return + return State; + }; + + /** + * History.getIdByState(State) + * Gets a ID for a State + * @param {State} newState + * @return {String} id + */ + History.getIdByState = function(newState){ + + // Fetch ID + var id = History.extractId(newState.url), + str; + + if ( !id ) { + // Find ID via State String + str = History.getStateString(newState); + if ( typeof History.stateToId[str] !== 'undefined' ) { + id = History.stateToId[str]; + } + else if ( typeof History.store.stateToId[str] !== 'undefined' ) { + id = History.store.stateToId[str]; + } + else { + // Generate a new ID + while ( true ) { + id = (new Date()).getTime() + String(Math.random()).replace(/\D/g,''); + if ( typeof History.idToState[id] === 'undefined' && typeof History.store.idToState[id] === 'undefined' ) { + break; + } + } + + // Apply the new State to the ID + History.stateToId[str] = id; + History.idToState[id] = newState; + } + } + + // Return ID + return id; + }; + + /** + * History.normalizeState(State) + * Expands a State Object + * @param {object} State + * @return {object} + */ + History.normalizeState = function(oldState){ + // Variables + var newState, dataNotEmpty; + + // Prepare + if ( !oldState || (typeof oldState !== 'object') ) { + oldState = {}; + } + + // Check + if ( typeof oldState.normalized !== 'undefined' ) { + return oldState; + } + + // Adjust + if ( !oldState.data || (typeof oldState.data !== 'object') ) { + oldState.data = {}; + } + + // ---------------------------------------------------------------- + + // Create + newState = {}; + newState.normalized = true; + newState.title = oldState.title||''; + newState.url = History.getFullUrl(oldState.url?oldState.url:(History.getLocationHref())); + newState.hash = History.getShortUrl(newState.url); + newState.data = History.cloneObject(oldState.data); + + // Fetch ID + newState.id = History.getIdByState(newState); + + // ---------------------------------------------------------------- + + // Clean the URL + newState.cleanUrl = newState.url.replace(/\??\&_suid.*/,''); + newState.url = newState.cleanUrl; + + // Check to see if we have more than just a url + dataNotEmpty = !History.isEmptyObject(newState.data); + + // Apply + if ( (newState.title || dataNotEmpty) && History.options.disableSuid !== true ) { + // Add ID to Hash + newState.hash = History.getShortUrl(newState.url).replace(/\??\&_suid.*/,''); + if ( !/\?/.test(newState.hash) ) { + newState.hash += '?'; + } + newState.hash += '&_suid='+newState.id; + } + + // Create the Hashed URL + newState.hashedUrl = History.getFullUrl(newState.hash); + + // ---------------------------------------------------------------- + + // Update the URL if we have a duplicate + if ( (History.emulated.pushState || History.bugs.safariPoll) && History.hasUrlDuplicate(newState) ) { + newState.url = newState.hashedUrl; + } + + // ---------------------------------------------------------------- + + // Return + return newState; + }; + + /** + * History.createStateObject(data,title,url) + * Creates a object based on the data, title and url state params + * @param {object} data + * @param {string} title + * @param {string} url + * @return {object} + */ + History.createStateObject = function(data,title,url){ + // Hashify + var State = { + 'data': data, + 'title': title, + 'url': url + }; + + // Expand the State + State = History.normalizeState(State); + + // Return object + return State; + }; + + /** + * History.getStateById(id) + * Get a state by it's UID + * @param {String} id + */ + History.getStateById = function(id){ + // Prepare + id = String(id); + + // Retrieve + var State = History.idToState[id] || History.store.idToState[id] || undefined; + + // Return State + return State; + }; + + /** + * Get a State's String + * @param {State} passedState + */ + History.getStateString = function(passedState){ + // Prepare + var State, cleanedState, str; + + // Fetch + State = History.normalizeState(passedState); + + // Clean + cleanedState = { + data: State.data, + title: passedState.title, + url: passedState.url + }; + + // Fetch + str = JSON.stringify(cleanedState); + + // Return + return str; + }; + + /** + * Get a State's ID + * @param {State} passedState + * @return {String} id + */ + History.getStateId = function(passedState){ + // Prepare + var State, id; + + // Fetch + State = History.normalizeState(passedState); + + // Fetch + id = State.id; + + // Return + return id; + }; + + /** + * History.getHashByState(State) + * Creates a Hash for the State Object + * @param {State} passedState + * @return {String} hash + */ + History.getHashByState = function(passedState){ + // Prepare + var State, hash; + + // Fetch + State = History.normalizeState(passedState); + + // Hash + hash = State.hash; + + // Return + return hash; + }; + + /** + * History.extractId(url_or_hash) + * Get a State ID by it's URL or Hash + * @param {string} url_or_hash + * @return {string} id + */ + History.extractId = function ( url_or_hash ) { + // Prepare + var id,parts,url, tmp; + + // Extract + + // If the URL has a #, use the id from before the # + if (url_or_hash.indexOf('#') != -1) + { + tmp = url_or_hash.split("#")[0]; + } + else + { + tmp = url_or_hash; + } + + parts = /(.*)\&_suid=([0-9]+)$/.exec(tmp); + url = parts ? (parts[1]||url_or_hash) : url_or_hash; + id = parts ? String(parts[2]||'') : ''; + + // Return + return id||false; + }; + + /** + * History.isTraditionalAnchor + * Checks to see if the url is a traditional anchor or not + * @param {String} url_or_hash + * @return {Boolean} + */ + History.isTraditionalAnchor = function(url_or_hash){ + // Check + var isTraditional = !(/[\/\?\.]/.test(url_or_hash)); + + // Return + return isTraditional; + }; + + /** + * History.extractState + * Get a State by it's URL or Hash + * @param {String} url_or_hash + * @return {State|null} + */ + History.extractState = function(url_or_hash,create){ + // Prepare + var State = null, id, url; + create = create||false; + + // Fetch SUID + id = History.extractId(url_or_hash); + if ( id ) { + State = History.getStateById(id); + } + + // Fetch SUID returned no State + if ( !State ) { + // Fetch URL + url = History.getFullUrl(url_or_hash); + + // Check URL + id = History.getIdByUrl(url)||false; + if ( id ) { + State = History.getStateById(id); + } + + // Create State + if ( !State && create && !History.isTraditionalAnchor(url_or_hash) ) { + State = History.createStateObject(null,null,url); + } + } + + // Return + return State; + }; + + /** + * History.getIdByUrl() + * Get a State ID by a State URL + */ + History.getIdByUrl = function(url){ + // Fetch + var id = History.urlToId[url] || History.store.urlToId[url] || undefined; + + // Return + return id; + }; + + /** + * History.getLastSavedState() + * Get an object containing the data, title and url of the current state + * @return {Object} State + */ + History.getLastSavedState = function(){ + return History.savedStates[History.savedStates.length-1]||undefined; + }; + + /** + * History.getLastStoredState() + * Get an object containing the data, title and url of the current state + * @return {Object} State + */ + History.getLastStoredState = function(){ + return History.storedStates[History.storedStates.length-1]||undefined; + }; + + /** + * History.hasUrlDuplicate + * Checks if a Url will have a url conflict + * @param {Object} newState + * @return {Boolean} hasDuplicate + */ + History.hasUrlDuplicate = function(newState) { + // Prepare + var hasDuplicate = false, + oldState; + + // Fetch + oldState = History.extractState(newState.url); + + // Check + hasDuplicate = oldState && oldState.id !== newState.id; + + // Return + return hasDuplicate; + }; + + /** + * History.storeState + * Store a State + * @param {Object} newState + * @return {Object} newState + */ + History.storeState = function(newState){ + // Store the State + History.urlToId[newState.url] = newState.id; + + // Push the State + History.storedStates.push(History.cloneObject(newState)); + + // Return newState + return newState; + }; + + /** + * History.isLastSavedState(newState) + * Tests to see if the state is the last state + * @param {Object} newState + * @return {boolean} isLast + */ + History.isLastSavedState = function(newState){ + // Prepare + var isLast = false, + newId, oldState, oldId; + + // Check + if ( History.savedStates.length ) { + newId = newState.id; + oldState = History.getLastSavedState(); + oldId = oldState.id; + + // Check + isLast = (newId === oldId); + } + + // Return + return isLast; + }; + + /** + * History.saveState + * Push a State + * @param {Object} newState + * @return {boolean} changed + */ + History.saveState = function(newState){ + // Check Hash + if ( History.isLastSavedState(newState) ) { + return false; + } + + // Push the State + History.savedStates.push(History.cloneObject(newState)); + + // Return true + return true; + }; + + /** + * History.getStateByIndex() + * Gets a state by the index + * @param {integer} index + * @return {Object} + */ + History.getStateByIndex = function(index){ + // Prepare + var State = null; + + // Handle + if ( typeof index === 'undefined' ) { + // Get the last inserted + State = History.savedStates[History.savedStates.length-1]; + } + else if ( index < 0 ) { + // Get from the end + State = History.savedStates[History.savedStates.length+index]; + } + else { + // Get from the beginning + State = History.savedStates[index]; + } + + // Return State + return State; + }; + + /** + * History.getCurrentIndex() + * Gets the current index + * @return (integer) + */ + History.getCurrentIndex = function(){ + // Prepare + var index = null; + + // No states saved + if(History.savedStates.length < 1) { + index = 0; + } + else { + index = History.savedStates.length-1; + } + return index; + }; + + // ==================================================================== + // Hash Helpers + + /** + * History.getHash() + * @param {Location=} location + * Gets the current document hash + * Note: unlike location.hash, this is guaranteed to return the escaped hash in all browsers + * @return {string} + */ + History.getHash = function(doc){ + var url = History.getLocationHref(doc), + hash; + hash = History.getHashByUrl(url); + return hash; + }; + + /** + * History.unescapeHash() + * normalize and Unescape a Hash + * @param {String} hash + * @return {string} + */ + History.unescapeHash = function(hash){ + // Prepare + var result = History.normalizeHash(hash); + + // Unescape hash + result = decodeURIComponent(result); + + // Return result + return result; + }; + + /** + * History.normalizeHash() + * normalize a hash across browsers + * @return {string} + */ + History.normalizeHash = function(hash){ + // Prepare + var result = hash.replace(/[^#]*#/,'').replace(/#.*/, ''); + + // Return result + return result; + }; + + /** + * History.setHash(hash) + * Sets the document hash + * @param {string} hash + * @return {History} + */ + History.setHash = function(hash,queue){ + // Prepare + var State, pageUrl; + + // Handle Queueing + if ( queue !== false && History.busy() ) { + // Wait + Push to Queue + //History.debug('History.setHash: we must wait', arguments); + History.pushQueue({ + scope: History, + callback: History.setHash, + args: arguments, + queue: queue + }); + return false; + } + + // Log + //History.debug('History.setHash: called',hash); + + // Make Busy + Continue + History.busy(true); + + // Check if hash is a state + State = History.extractState(hash,true); + if ( State && !History.emulated.pushState ) { + // Hash is a state so skip the setHash + //History.debug('History.setHash: Hash is a state so skipping the hash set with a direct pushState call',arguments); + + // PushState + History.pushState(State.data,State.title,State.url,false); + } + else if ( History.getHash() !== hash ) { + // Hash is a proper hash, so apply it + + // Handle browser bugs + if ( History.bugs.setHash ) { + // Fix Safari Bug https://bugs.webkit.org/show_bug.cgi?id=56249 + + // Fetch the base page + pageUrl = History.getPageUrl(); + + // Safari hash apply + History.pushState(null,null,pageUrl+'#'+hash,false); + } + else { + // Normal hash apply + document.location.hash = hash; + } + } + + // Chain + return History; + }; + + /** + * History.escape() + * normalize and Escape a Hash + * @return {string} + */ + History.escapeHash = function(hash){ + // Prepare + var result = History.normalizeHash(hash); + + // Escape hash + result = window.encodeURIComponent(result); + + // IE6 Escape Bug + if ( !History.bugs.hashEscape ) { + // Restore common parts + result = result + .replace(/\%21/g,'!') + .replace(/\%26/g,'&') + .replace(/\%3D/g,'=') + .replace(/\%3F/g,'?'); + } + + // Return result + return result; + }; + + /** + * History.getHashByUrl(url) + * Extracts the Hash from a URL + * @param {string} url + * @return {string} url + */ + History.getHashByUrl = function(url){ + // Extract the hash + var hash = String(url) + .replace(/([^#]*)#?([^#]*)#?(.*)/, '$2') + ; + + // Unescape hash + hash = History.unescapeHash(hash); + + // Return hash + return hash; + }; + + /** + * History.setTitle(title) + * Applies the title to the document + * @param {State} newState + * @return {Boolean} + */ + History.setTitle = function(newState){ + // Prepare + var title = newState.title, + firstState; + + // Initial + if ( !title ) { + firstState = History.getStateByIndex(0); + if ( firstState && firstState.url === newState.url ) { + title = firstState.title||History.options.initialTitle; + } + } + + // Apply + try { + document.getElementsByTagName('title')[0].innerHTML = title.replace('<','<').replace('>','>').replace(' & ',' & '); + } + catch ( Exception ) { } + document.title = title; + + // Chain + return History; + }; + + + // ==================================================================== + // Queueing + + /** + * History.queues + * The list of queues to use + * First In, First Out + */ + History.queues = []; + + /** + * History.busy(value) + * @param {boolean} value [optional] + * @return {boolean} busy + */ + History.busy = function(value){ + // Apply + if ( typeof value !== 'undefined' ) { + //History.debug('History.busy: changing ['+(History.busy.flag||false)+'] to ['+(value||false)+']', History.queues.length); + History.busy.flag = value; + } + // Default + else if ( typeof History.busy.flag === 'undefined' ) { + History.busy.flag = false; + } + + // Queue + if ( !History.busy.flag ) { + // Execute the next item in the queue + clearTimeout(History.busy.timeout); + var fireNext = function(){ + var i, queue, item; + if ( History.busy.flag ) return; + for ( i=History.queues.length-1; i >= 0; --i ) { + queue = History.queues[i]; + if ( queue.length === 0 ) continue; + item = queue.shift(); + History.fireQueueItem(item); + History.busy.timeout = setTimeout(fireNext,History.options.busyDelay); + } + }; + History.busy.timeout = setTimeout(fireNext,History.options.busyDelay); + } + + // Return + return History.busy.flag; + }; + + /** + * History.busy.flag + */ + History.busy.flag = false; + + /** + * History.fireQueueItem(item) + * Fire a Queue Item + * @param {Object} item + * @return {Mixed} result + */ + History.fireQueueItem = function(item){ + return item.callback.apply(item.scope||History,item.args||[]); + }; + + /** + * History.pushQueue(callback,args) + * Add an item to the queue + * @param {Object} item [scope,callback,args,queue] + */ + History.pushQueue = function(item){ + // Prepare the queue + History.queues[item.queue||0] = History.queues[item.queue||0]||[]; + + // Add to the queue + History.queues[item.queue||0].push(item); + + // Chain + return History; + }; + + /** + * History.queue (item,queue), (func,queue), (func), (item) + * Either firs the item now if not busy, or adds it to the queue + */ + History.queue = function(item,queue){ + // Prepare + if ( typeof item === 'function' ) { + item = { + callback: item + }; + } + if ( typeof queue !== 'undefined' ) { + item.queue = queue; + } + + // Handle + if ( History.busy() ) { + History.pushQueue(item); + } else { + History.fireQueueItem(item); + } + + // Chain + return History; + }; + + /** + * History.clearQueue() + * Clears the Queue + */ + History.clearQueue = function(){ + History.busy.flag = false; + History.queues = []; + return History; + }; + + + // ==================================================================== + // IE Bug Fix + + /** + * History.stateChanged + * States whether or not the state has changed since the last double check was initialised + */ + History.stateChanged = false; + + /** + * History.doubleChecker + * Contains the timeout used for the double checks + */ + History.doubleChecker = false; + + /** + * History.doubleCheckComplete() + * Complete a double check + * @return {History} + */ + History.doubleCheckComplete = function(){ + // Update + History.stateChanged = true; + + // Clear + History.doubleCheckClear(); + + // Chain + return History; + }; + + /** + * History.doubleCheckClear() + * Clear a double check + * @return {History} + */ + History.doubleCheckClear = function(){ + // Clear + if ( History.doubleChecker ) { + clearTimeout(History.doubleChecker); + History.doubleChecker = false; + } + + // Chain + return History; + }; + + /** + * History.doubleCheck() + * Create a double check + * @return {History} + */ + History.doubleCheck = function(tryAgain){ + // Reset + History.stateChanged = false; + History.doubleCheckClear(); + + // Fix IE6,IE7 bug where calling history.back or history.forward does not actually change the hash (whereas doing it manually does) + // Fix Safari 5 bug where sometimes the state does not change: https://bugs.webkit.org/show_bug.cgi?id=42940 + if ( History.bugs.ieDoubleCheck ) { + // Apply Check + History.doubleChecker = setTimeout( + function(){ + History.doubleCheckClear(); + if ( !History.stateChanged ) { + //History.debug('History.doubleCheck: State has not yet changed, trying again', arguments); + // Re-Attempt + tryAgain(); + } + return true; + }, + History.options.doubleCheckInterval + ); + } + + // Chain + return History; + }; + + + // ==================================================================== + // Safari Bug Fix + + /** + * History.safariStatePoll() + * Poll the current state + * @return {History} + */ + History.safariStatePoll = function(){ + // Poll the URL + + // Get the Last State which has the new URL + var + urlState = History.extractState(History.getLocationHref()), + newState; + + // Check for a difference + if ( !History.isLastSavedState(urlState) ) { + newState = urlState; + } + else { + return; + } + + // Check if we have a state with that url + // If not create it + if ( !newState ) { + //History.debug('History.safariStatePoll: new'); + newState = History.createStateObject(); + } + + // Apply the New State + //History.debug('History.safariStatePoll: trigger'); + History.Adapter.trigger(window,'popstate'); + + // Chain + return History; + }; + + + // ==================================================================== + // State Aliases + + /** + * History.back(queue) + * Send the browser history back one item + * @param {Integer} queue [optional] + */ + History.back = function(queue){ + //History.debug('History.back: called', arguments); + + // Handle Queueing + if ( queue !== false && History.busy() ) { + // Wait + Push to Queue + //History.debug('History.back: we must wait', arguments); + History.pushQueue({ + scope: History, + callback: History.back, + args: arguments, + queue: queue + }); + return false; + } + + // Make Busy + Continue + History.busy(true); + + // Fix certain browser bugs that prevent the state from changing + History.doubleCheck(function(){ + History.back(false); + }); + + // Go back + history.go(-1); + + // End back closure + return true; + }; + + /** + * History.forward(queue) + * Send the browser history forward one item + * @param {Integer} queue [optional] + */ + History.forward = function(queue){ + //History.debug('History.forward: called', arguments); + + // Handle Queueing + if ( queue !== false && History.busy() ) { + // Wait + Push to Queue + //History.debug('History.forward: we must wait', arguments); + History.pushQueue({ + scope: History, + callback: History.forward, + args: arguments, + queue: queue + }); + return false; + } + + // Make Busy + Continue + History.busy(true); + + // Fix certain browser bugs that prevent the state from changing + History.doubleCheck(function(){ + History.forward(false); + }); + + // Go forward + history.go(1); + + // End forward closure + return true; + }; + + /** + * History.go(index,queue) + * Send the browser history back or forward index times + * @param {Integer} queue [optional] + */ + History.go = function(index,queue){ + //History.debug('History.go: called', arguments); + + // Prepare + var i; + + // Handle + if ( index > 0 ) { + // Forward + for ( i=1; i<=index; ++i ) { + History.forward(queue); + } + } + else if ( index < 0 ) { + // Backward + for ( i=-1; i>=index; --i ) { + History.back(queue); + } + } + else { + throw new Error('History.go: History.go requires a positive or negative integer passed.'); + } + + // Chain + return History; + }; + + + // ==================================================================== + // HTML5 State Support + + // Non-Native pushState Implementation + if ( History.emulated.pushState ) { + /* + * Provide Skeleton for HTML4 Browsers + */ + + // Prepare + var emptyFunction = function(){}; + History.pushState = History.pushState||emptyFunction; + History.replaceState = History.replaceState||emptyFunction; + } // History.emulated.pushState + + // Native pushState Implementation + else { + /* + * Use native HTML5 History API Implementation + */ + + /** + * History.onPopState(event,extra) + * Refresh the Current State + */ + History.onPopState = function(event,extra){ + // Prepare + var stateId = false, newState = false, currentHash, currentState; + + // Reset the double check + History.doubleCheckComplete(); + + // Check for a Hash, and handle apporiatly + currentHash = History.getHash(); + if ( currentHash ) { + // Expand Hash + currentState = History.extractState(currentHash||History.getLocationHref(),true); + if ( currentState ) { + // We were able to parse it, it must be a State! + // Let's forward to replaceState + //History.debug('History.onPopState: state anchor', currentHash, currentState); + History.replaceState(currentState.data, currentState.title, currentState.url, false); + } + else { + // Traditional Anchor + //History.debug('History.onPopState: traditional anchor', currentHash); + History.Adapter.trigger(window,'anchorchange'); + History.busy(false); + } + + // We don't care for hashes + History.expectedStateId = false; + return false; + } + + // Ensure + stateId = History.Adapter.extractEventData('state',event,extra) || false; + + // Fetch State + if ( stateId ) { + // Vanilla: Back/forward button was used + newState = History.getStateById(stateId); + } + else if ( History.expectedStateId ) { + // Vanilla: A new state was pushed, and popstate was called manually + newState = History.getStateById(History.expectedStateId); + } + else { + // Initial State + newState = History.extractState(History.getLocationHref()); + } + + // The State did not exist in our store + if ( !newState ) { + // Regenerate the State + newState = History.createStateObject(null,null,History.getLocationHref()); + } + + // Clean + History.expectedStateId = false; + + // Check if we are the same state + if ( History.isLastSavedState(newState) ) { + // There has been no change (just the page's hash has finally propagated) + //History.debug('History.onPopState: no change', newState, History.savedStates); + History.busy(false); + return false; + } + + // Store the State + History.storeState(newState); + History.saveState(newState); + + // Force update of the title + History.setTitle(newState); + + // Fire Our Event + History.Adapter.trigger(window,'statechange'); + History.busy(false); + + // Return true + return true; + }; + History.Adapter.bind(window,'popstate',History.onPopState); + + /** + * History.pushState(data,title,url) + * Add a new State to the history object, become it, and trigger onpopstate + * We have to trigger for HTML4 compatibility + * @param {object} data + * @param {string} title + * @param {string} url + * @return {true} + */ + History.pushState = function(data,title,url,queue){ + //History.debug('History.pushState: called', arguments); + + // Check the State + if ( History.getHashByUrl(url) && History.emulated.pushState ) { + throw new Error('History.js does not support states with fragement-identifiers (hashes/anchors).'); + } + + // Handle Queueing + if ( queue !== false && History.busy() ) { + // Wait + Push to Queue + //History.debug('History.pushState: we must wait', arguments); + History.pushQueue({ + scope: History, + callback: History.pushState, + args: arguments, + queue: queue + }); + return false; + } + + // Make Busy + Continue + History.busy(true); + + // Create the newState + var newState = History.createStateObject(data,title,url); + + // Check it + if ( History.isLastSavedState(newState) ) { + // Won't be a change + History.busy(false); + } + else { + // Store the newState + History.storeState(newState); + History.expectedStateId = newState.id; + + // Push the newState + history.pushState(newState.id,newState.title,newState.url); + + // Fire HTML5 Event + History.Adapter.trigger(window,'popstate'); + } + + // End pushState closure + return true; + }; + + /** + * History.replaceState(data,title,url) + * Replace the State and trigger onpopstate + * We have to trigger for HTML4 compatibility + * @param {object} data + * @param {string} title + * @param {string} url + * @return {true} + */ + History.replaceState = function(data,title,url,queue){ + //History.debug('History.replaceState: called', arguments); + + // Check the State + if ( History.getHashByUrl(url) && History.emulated.pushState ) { + throw new Error('History.js does not support states with fragement-identifiers (hashes/anchors).'); + } + + // Handle Queueing + if ( queue !== false && History.busy() ) { + // Wait + Push to Queue + //History.debug('History.replaceState: we must wait', arguments); + History.pushQueue({ + scope: History, + callback: History.replaceState, + args: arguments, + queue: queue + }); + return false; + } + + // Make Busy + Continue + History.busy(true); + + // Create the newState + var newState = History.createStateObject(data,title,url); + + // Check it + if ( History.isLastSavedState(newState) ) { + // Won't be a change + History.busy(false); + } + else { + // Store the newState + History.storeState(newState); + History.expectedStateId = newState.id; + + // Push the newState + history.replaceState(newState.id,newState.title,newState.url); + + // Fire HTML5 Event + History.Adapter.trigger(window,'popstate'); + } + + // End replaceState closure + return true; + }; + + } // !History.emulated.pushState + + + // ==================================================================== + // Initialise + + /** + * Load the Store + */ + if ( sessionStorage ) { + // Fetch + try { + History.store = JSON.parse(sessionStorage.getItem('History.store'))||{}; + } + catch ( err ) { + History.store = {}; + } + + // Normalize + History.normalizeStore(); + } + else { + // Default Load + History.store = {}; + History.normalizeStore(); + } + + /** + * Clear Intervals on exit to prevent memory leaks + */ + History.Adapter.bind(window,"unload",History.clearAllIntervals); + + /** + * Create the initial State + */ + History.saveState(History.storeState(History.extractState(History.getLocationHref(),true))); + + /** + * Bind for Saving Store + */ + if ( sessionStorage ) { + // When the page is closed + History.onUnload = function(){ + // Prepare + var currentStore, item, currentStoreString; + + // Fetch + try { + currentStore = JSON.parse(sessionStorage.getItem('History.store'))||{}; + } + catch ( err ) { + currentStore = {}; + } + + // Ensure + currentStore.idToState = currentStore.idToState || {}; + currentStore.urlToId = currentStore.urlToId || {}; + currentStore.stateToId = currentStore.stateToId || {}; + + // Sync + for ( item in History.idToState ) { + if ( !History.idToState.hasOwnProperty(item) ) { + continue; + } + currentStore.idToState[item] = History.idToState[item]; + } + for ( item in History.urlToId ) { + if ( !History.urlToId.hasOwnProperty(item) ) { + continue; + } + currentStore.urlToId[item] = History.urlToId[item]; + } + for ( item in History.stateToId ) { + if ( !History.stateToId.hasOwnProperty(item) ) { + continue; + } + currentStore.stateToId[item] = History.stateToId[item]; + } + + // Update + History.store = currentStore; + History.normalizeStore(); + + // In Safari, going into Private Browsing mode causes the + // Session Storage object to still exist but if you try and use + // or set any property/function of it it throws the exception + // "QUOTA_EXCEEDED_ERR: DOM Exception 22: An attempt was made to + // add something to storage that exceeded the quota." infinitely + // every second. + currentStoreString = JSON.stringify(currentStore); + try { + // Store + sessionStorage.setItem('History.store', currentStoreString); + } + catch (e) { + if (e.code === DOMException.QUOTA_EXCEEDED_ERR) { + if (sessionStorage.length) { + // Workaround for a bug seen on iPads. Sometimes the quota exceeded error comes up and simply + // removing/resetting the storage can work. + sessionStorage.removeItem('History.store'); + sessionStorage.setItem('History.store', currentStoreString); + } else { + // Otherwise, we're probably private browsing in Safari, so we'll ignore the exception. + } + } else { + throw e; + } + } + }; + + // For Internet Explorer + History.intervalList.push(setInterval(History.onUnload,History.options.storeInterval)); + + // For Other Browsers + History.Adapter.bind(window,'beforeunload',History.onUnload); + History.Adapter.bind(window,'unload',History.onUnload); + + // Both are enabled for consistency + } + + // Non-Native pushState Implementation + if ( !History.emulated.pushState ) { + // Be aware, the following is only for native pushState implementations + // If you are wanting to include something for all browsers + // Then include it above this if block + + /** + * Setup Safari Fix + */ + if ( History.bugs.safariPoll ) { + History.intervalList.push(setInterval(History.safariStatePoll, History.options.safariPollInterval)); + } + + /** + * Ensure Cross Browser Compatibility + */ + if ( navigator.vendor === 'Apple Computer, Inc.' || (navigator.appCodeName||'') === 'Mozilla' ) { + /** + * Fix Safari HashChange Issue + */ + + // Setup Alias + History.Adapter.bind(window,'hashchange',function(){ + History.Adapter.trigger(window,'popstate'); + }); + + // Initialise Alias + if ( History.getHash() ) { + History.Adapter.onDomLoad(function(){ + History.Adapter.trigger(window,'hashchange'); + }); + } + } + + } // !History.emulated.pushState + + + }; // History.initCore + + // Try to Initialise History + if (!History.options || !History.options.delayInit) { + History.init(); + } + +})(window); diff --git a/sites/all/themes/gui/materiobasetheme/bower_components/history.js/scripts/bundled-uncompressed/html5/extjs.history.js b/sites/all/themes/gui/materiobasetheme/bower_components/history.js/scripts/bundled-uncompressed/html5/extjs.history.js new file mode 100644 index 00000000..58aba58b --- /dev/null +++ b/sites/all/themes/gui/materiobasetheme/bower_components/history.js/scripts/bundled-uncompressed/html5/extjs.history.js @@ -0,0 +1,2135 @@ +/** + * History.js ExtJS Adapter + * @author Sean Adkinson + * @copyright 2012 Sean Adkinson + * @license New BSD License + */ + +// Closure +(function(window,undefined){ + "use strict"; + + // Localise Globals + var + History = window.History = window.History||{}, + Ext = window.Ext; + + window.JSON = { + stringify: Ext.JSON.encode, + parse: Ext.JSON.decode + }; + + // Check Existence + if ( typeof History.Adapter !== 'undefined' ) { + throw new Error('History.js Adapter has already been loaded...'); + } + + // Add the Adapter + History.Adapter = { + observables: {}, + + /** + * History.Adapter.bind(el,event,callback) + * @param {Element|string} el + * @param {string} event - custom and standard events + * @param {function} callback + * @param {Object} scope + * @return {void} + */ + bind: function(element,eventName,callback,scope){ + Ext.EventManager.addListener(element, eventName, callback, scope); + + //bind an observable to the element that will let us "trigger" events on it + var id = Ext.id(element, 'history-'), observable = this.observables[id]; + if (!observable) { + observable = Ext.create('Ext.util.Observable'); + this.observables[id] = observable; + } + observable.on(eventName, callback, scope); + }, + + /** + * History.Adapter.trigger(el,event) + * @param {Element|string} el + * @param {string} event - custom and standard events + * @param {Object=} extra - a object of extra event data (optional) + * @return {void} + */ + trigger: function(element,eventName,extra){ + var id = Ext.id(element, 'history-'), observable = this.observables[id]; + if (observable) { + observable.fireEvent(eventName, extra); + } + }, + + /** + * History.Adapter.extractEventData(key,event,extra) + * @param {string} key - key for the event data to extract + * @param {string} event - custom and standard events + * @param {Object=} extra - a object of extra event data (optional) + * @return {mixed} + */ + extractEventData: function(key,event,extra){ + var result = (event && event.browserEvent && event.browserEvent[key]) || (extra && extra[key]) || undefined; + return result; + }, + + /** + * History.Adapter.onDomLoad(callback) + * @param {function} callback + * @return {void} + */ + onDomLoad: function(callback) { + Ext.onReady(callback); + } + }; + + // Try and Initialise History + if ( typeof History.init !== 'undefined' ) { + History.init(); + } + +})(window);/** + * History.js Core + * @author Benjamin Arthur Lupton + * @copyright 2010-2011 Benjamin Arthur Lupton + * @license New BSD License + */ + +(function(window,undefined){ + "use strict"; + + // ======================================================================== + // Initialise + + // Localise Globals + var + console = window.console||undefined, // Prevent a JSLint complain + document = window.document, // Make sure we are using the correct document + navigator = window.navigator, // Make sure we are using the correct navigator + sessionStorage = window.sessionStorage||false, // sessionStorage + setTimeout = window.setTimeout, + clearTimeout = window.clearTimeout, + setInterval = window.setInterval, + clearInterval = window.clearInterval, + JSON = window.JSON, + alert = window.alert, + History = window.History = window.History||{}, // Public History Object + history = window.history; // Old History Object + + try { + sessionStorage.setItem('TEST', '1'); + sessionStorage.removeItem('TEST'); + } catch(e) { + sessionStorage = false; + } + + // MooTools Compatibility + JSON.stringify = JSON.stringify||JSON.encode; + JSON.parse = JSON.parse||JSON.decode; + + // Check Existence + if ( typeof History.init !== 'undefined' ) { + throw new Error('History.js Core has already been loaded...'); + } + + // Initialise History + History.init = function(options){ + // Check Load Status of Adapter + if ( typeof History.Adapter === 'undefined' ) { + return false; + } + + // Check Load Status of Core + if ( typeof History.initCore !== 'undefined' ) { + History.initCore(); + } + + // Check Load Status of HTML4 Support + if ( typeof History.initHtml4 !== 'undefined' ) { + History.initHtml4(); + } + + // Return true + return true; + }; + + + // ======================================================================== + // Initialise Core + + // Initialise Core + History.initCore = function(options){ + // Initialise + if ( typeof History.initCore.initialized !== 'undefined' ) { + // Already Loaded + return false; + } + else { + History.initCore.initialized = true; + } + + + // ==================================================================== + // Options + + /** + * History.options + * Configurable options + */ + History.options = History.options||{}; + + /** + * History.options.hashChangeInterval + * How long should the interval be before hashchange checks + */ + History.options.hashChangeInterval = History.options.hashChangeInterval || 100; + + /** + * History.options.safariPollInterval + * How long should the interval be before safari poll checks + */ + History.options.safariPollInterval = History.options.safariPollInterval || 500; + + /** + * History.options.doubleCheckInterval + * How long should the interval be before we perform a double check + */ + History.options.doubleCheckInterval = History.options.doubleCheckInterval || 500; + + /** + * History.options.disableSuid + * Force History not to append suid + */ + History.options.disableSuid = History.options.disableSuid || false; + + /** + * History.options.storeInterval + * How long should we wait between store calls + */ + History.options.storeInterval = History.options.storeInterval || 1000; + + /** + * History.options.busyDelay + * How long should we wait between busy events + */ + History.options.busyDelay = History.options.busyDelay || 250; + + /** + * History.options.debug + * If true will enable debug messages to be logged + */ + History.options.debug = History.options.debug || false; + + /** + * History.options.initialTitle + * What is the title of the initial state + */ + History.options.initialTitle = History.options.initialTitle || document.title; + + /** + * History.options.html4Mode + * If true, will force HTMl4 mode (hashtags) + */ + History.options.html4Mode = History.options.html4Mode || false; + + /** + * History.options.delayInit + * Want to override default options and call init manually. + */ + History.options.delayInit = History.options.delayInit || false; + + + // ==================================================================== + // Interval record + + /** + * History.intervalList + * List of intervals set, to be cleared when document is unloaded. + */ + History.intervalList = []; + + /** + * History.clearAllIntervals + * Clears all setInterval instances. + */ + History.clearAllIntervals = function(){ + var i, il = History.intervalList; + if (typeof il !== "undefined" && il !== null) { + for (i = 0; i < il.length; i++) { + clearInterval(il[i]); + } + History.intervalList = null; + } + }; + + + // ==================================================================== + // Debug + + /** + * History.debug(message,...) + * Logs the passed arguments if debug enabled + */ + History.debug = function(){ + if ( (History.options.debug||false) ) { + History.log.apply(History,arguments); + } + }; + + /** + * History.log(message,...) + * Logs the passed arguments + */ + History.log = function(){ + // Prepare + var + consoleExists = !(typeof console === 'undefined' || typeof console.log === 'undefined' || typeof console.log.apply === 'undefined'), + textarea = document.getElementById('log'), + message, + i,n, + args,arg + ; + + // Write to Console + if ( consoleExists ) { + args = Array.prototype.slice.call(arguments); + message = args.shift(); + if ( typeof console.debug !== 'undefined' ) { + console.debug.apply(console,[message,args]); + } + else { + console.log.apply(console,[message,args]); + } + } + else { + message = ("\n"+arguments[0]+"\n"); + } + + // Write to log + for ( i=1,n=arguments.length; i + * @author James Padolsey + */ + History.getInternetExplorerMajorVersion = function(){ + var result = History.getInternetExplorerMajorVersion.cached = + (typeof History.getInternetExplorerMajorVersion.cached !== 'undefined') + ? History.getInternetExplorerMajorVersion.cached + : (function(){ + var v = 3, + div = document.createElement('div'), + all = div.getElementsByTagName('i'); + while ( (div.innerHTML = '') && all[0] ) {} + return (v > 4) ? v : false; + })() + ; + return result; + }; + + /** + * History.isInternetExplorer() + * Are we using Internet Explorer? + * @return {boolean} + * @license Public Domain + * @author Benjamin Arthur Lupton + */ + History.isInternetExplorer = function(){ + var result = + History.isInternetExplorer.cached = + (typeof History.isInternetExplorer.cached !== 'undefined') + ? History.isInternetExplorer.cached + : Boolean(History.getInternetExplorerMajorVersion()) + ; + return result; + }; + + /** + * History.emulated + * Which features require emulating? + */ + + if (History.options.html4Mode) { + History.emulated = { + pushState : true, + hashChange: true + }; + } + + else { + + History.emulated = { + pushState: !Boolean( + window.history && window.history.pushState && window.history.replaceState + && !( + (/ Mobile\/([1-7][a-z]|(8([abcde]|f(1[0-8]))))/i).test(navigator.userAgent) /* disable for versions of iOS before version 4.3 (8F190) */ + || (/AppleWebKit\/5([0-2]|3[0-2])/i).test(navigator.userAgent) /* disable for the mercury iOS browser, or at least older versions of the webkit engine */ + ) + ), + hashChange: Boolean( + !(('onhashchange' in window) || ('onhashchange' in document)) + || + (History.isInternetExplorer() && History.getInternetExplorerMajorVersion() < 8) + ) + }; + } + + /** + * History.enabled + * Is History enabled? + */ + History.enabled = !History.emulated.pushState; + + /** + * History.bugs + * Which bugs are present + */ + History.bugs = { + /** + * Safari 5 and Safari iOS 4 fail to return to the correct state once a hash is replaced by a `replaceState` call + * https://bugs.webkit.org/show_bug.cgi?id=56249 + */ + setHash: Boolean(!History.emulated.pushState && navigator.vendor === 'Apple Computer, Inc.' && /AppleWebKit\/5([0-2]|3[0-3])/.test(navigator.userAgent)), + + /** + * Safari 5 and Safari iOS 4 sometimes fail to apply the state change under busy conditions + * https://bugs.webkit.org/show_bug.cgi?id=42940 + */ + safariPoll: Boolean(!History.emulated.pushState && navigator.vendor === 'Apple Computer, Inc.' && /AppleWebKit\/5([0-2]|3[0-3])/.test(navigator.userAgent)), + + /** + * MSIE 6 and 7 sometimes do not apply a hash even it was told to (requiring a second call to the apply function) + */ + ieDoubleCheck: Boolean(History.isInternetExplorer() && History.getInternetExplorerMajorVersion() < 8), + + /** + * MSIE 6 requires the entire hash to be encoded for the hashes to trigger the onHashChange event + */ + hashEscape: Boolean(History.isInternetExplorer() && History.getInternetExplorerMajorVersion() < 7) + }; + + /** + * History.isEmptyObject(obj) + * Checks to see if the Object is Empty + * @param {Object} obj + * @return {boolean} + */ + History.isEmptyObject = function(obj) { + for ( var name in obj ) { + if ( obj.hasOwnProperty(name) ) { + return false; + } + } + return true; + }; + + /** + * History.cloneObject(obj) + * Clones a object and eliminate all references to the original contexts + * @param {Object} obj + * @return {Object} + */ + History.cloneObject = function(obj) { + var hash,newObj; + if ( obj ) { + hash = JSON.stringify(obj); + newObj = JSON.parse(hash); + } + else { + newObj = {}; + } + return newObj; + }; + + + // ==================================================================== + // URL Helpers + + /** + * History.getRootUrl() + * Turns "http://mysite.com/dir/page.html?asd" into "http://mysite.com" + * @return {String} rootUrl + */ + History.getRootUrl = function(){ + // Create + var rootUrl = document.location.protocol+'//'+(document.location.hostname||document.location.host); + if ( document.location.port||false ) { + rootUrl += ':'+document.location.port; + } + rootUrl += '/'; + + // Return + return rootUrl; + }; + + /** + * History.getBaseHref() + * Fetches the `href` attribute of the `` element if it exists + * @return {String} baseHref + */ + History.getBaseHref = function(){ + // Create + var + baseElements = document.getElementsByTagName('base'), + baseElement = null, + baseHref = ''; + + // Test for Base Element + if ( baseElements.length === 1 ) { + // Prepare for Base Element + baseElement = baseElements[0]; + baseHref = baseElement.href.replace(/[^\/]+$/,''); + } + + // Adjust trailing slash + baseHref = baseHref.replace(/\/+$/,''); + if ( baseHref ) baseHref += '/'; + + // Return + return baseHref; + }; + + /** + * History.getBaseUrl() + * Fetches the baseHref or basePageUrl or rootUrl (whichever one exists first) + * @return {String} baseUrl + */ + History.getBaseUrl = function(){ + // Create + var baseUrl = History.getBaseHref()||History.getBasePageUrl()||History.getRootUrl(); + + // Return + return baseUrl; + }; + + /** + * History.getPageUrl() + * Fetches the URL of the current page + * @return {String} pageUrl + */ + History.getPageUrl = function(){ + // Fetch + var + State = History.getState(false,false), + stateUrl = (State||{}).url||History.getLocationHref(), + pageUrl; + + // Create + pageUrl = stateUrl.replace(/\/+$/,'').replace(/[^\/]+$/,function(part,index,string){ + return (/\./).test(part) ? part : part+'/'; + }); + + // Return + return pageUrl; + }; + + /** + * History.getBasePageUrl() + * Fetches the Url of the directory of the current page + * @return {String} basePageUrl + */ + History.getBasePageUrl = function(){ + // Create + var basePageUrl = (History.getLocationHref()).replace(/[#\?].*/,'').replace(/[^\/]+$/,function(part,index,string){ + return (/[^\/]$/).test(part) ? '' : part; + }).replace(/\/+$/,'')+'/'; + + // Return + return basePageUrl; + }; + + /** + * History.getFullUrl(url) + * Ensures that we have an absolute URL and not a relative URL + * @param {string} url + * @param {Boolean} allowBaseHref + * @return {string} fullUrl + */ + History.getFullUrl = function(url,allowBaseHref){ + // Prepare + var fullUrl = url, firstChar = url.substring(0,1); + allowBaseHref = (typeof allowBaseHref === 'undefined') ? true : allowBaseHref; + + // Check + if ( /[a-z]+\:\/\//.test(url) ) { + // Full URL + } + else if ( firstChar === '/' ) { + // Root URL + fullUrl = History.getRootUrl()+url.replace(/^\/+/,''); + } + else if ( firstChar === '#' ) { + // Anchor URL + fullUrl = History.getPageUrl().replace(/#.*/,'')+url; + } + else if ( firstChar === '?' ) { + // Query URL + fullUrl = History.getPageUrl().replace(/[\?#].*/,'')+url; + } + else { + // Relative URL + if ( allowBaseHref ) { + fullUrl = History.getBaseUrl()+url.replace(/^(\.\/)+/,''); + } else { + fullUrl = History.getBasePageUrl()+url.replace(/^(\.\/)+/,''); + } + // We have an if condition above as we do not want hashes + // which are relative to the baseHref in our URLs + // as if the baseHref changes, then all our bookmarks + // would now point to different locations + // whereas the basePageUrl will always stay the same + } + + // Return + return fullUrl.replace(/\#$/,''); + }; + + /** + * History.getShortUrl(url) + * Ensures that we have a relative URL and not a absolute URL + * @param {string} url + * @return {string} url + */ + History.getShortUrl = function(url){ + // Prepare + var shortUrl = url, baseUrl = History.getBaseUrl(), rootUrl = History.getRootUrl(); + + // Trim baseUrl + if ( History.emulated.pushState ) { + // We are in a if statement as when pushState is not emulated + // The actual url these short urls are relative to can change + // So within the same session, we the url may end up somewhere different + shortUrl = shortUrl.replace(baseUrl,''); + } + + // Trim rootUrl + shortUrl = shortUrl.replace(rootUrl,'/'); + + // Ensure we can still detect it as a state + if ( History.isTraditionalAnchor(shortUrl) ) { + shortUrl = './'+shortUrl; + } + + // Clean It + shortUrl = shortUrl.replace(/^(\.\/)+/g,'./').replace(/\#$/,''); + + // Return + return shortUrl; + }; + + /** + * History.getLocationHref(document) + * Returns a normalized version of document.location.href + * accounting for browser inconsistencies, etc. + * + * This URL will be URI-encoded and will include the hash + * + * @param {object} document + * @return {string} url + */ + History.getLocationHref = function(doc) { + doc = doc || document; + + // most of the time, this will be true + if (doc.URL === doc.location.href) + return doc.location.href; + + // some versions of webkit URI-decode document.location.href + // but they leave document.URL in an encoded state + if (doc.location.href === decodeURIComponent(doc.URL)) + return doc.URL; + + // FF 3.6 only updates document.URL when a page is reloaded + // document.location.href is updated correctly + if (doc.location.hash && decodeURIComponent(doc.location.href.replace(/^[^#]+/, "")) === doc.location.hash) + return doc.location.href; + + if (doc.URL.indexOf('#') == -1 && doc.location.href.indexOf('#') != -1) + return doc.location.href; + + return doc.URL || doc.location.href; + }; + + + // ==================================================================== + // State Storage + + /** + * History.store + * The store for all session specific data + */ + History.store = {}; + + /** + * History.idToState + * 1-1: State ID to State Object + */ + History.idToState = History.idToState||{}; + + /** + * History.stateToId + * 1-1: State String to State ID + */ + History.stateToId = History.stateToId||{}; + + /** + * History.urlToId + * 1-1: State URL to State ID + */ + History.urlToId = History.urlToId||{}; + + /** + * History.storedStates + * Store the states in an array + */ + History.storedStates = History.storedStates||[]; + + /** + * History.savedStates + * Saved the states in an array + */ + History.savedStates = History.savedStates||[]; + + /** + * History.noramlizeStore() + * Noramlize the store by adding necessary values + */ + History.normalizeStore = function(){ + History.store.idToState = History.store.idToState||{}; + History.store.urlToId = History.store.urlToId||{}; + History.store.stateToId = History.store.stateToId||{}; + }; + + /** + * History.getState() + * Get an object containing the data, title and url of the current state + * @param {Boolean} friendly + * @param {Boolean} create + * @return {Object} State + */ + History.getState = function(friendly,create){ + // Prepare + if ( typeof friendly === 'undefined' ) { friendly = true; } + if ( typeof create === 'undefined' ) { create = true; } + + // Fetch + var State = History.getLastSavedState(); + + // Create + if ( !State && create ) { + State = History.createStateObject(); + } + + // Adjust + if ( friendly ) { + State = History.cloneObject(State); + State.url = State.cleanUrl||State.url; + } + + // Return + return State; + }; + + /** + * History.getIdByState(State) + * Gets a ID for a State + * @param {State} newState + * @return {String} id + */ + History.getIdByState = function(newState){ + + // Fetch ID + var id = History.extractId(newState.url), + str; + + if ( !id ) { + // Find ID via State String + str = History.getStateString(newState); + if ( typeof History.stateToId[str] !== 'undefined' ) { + id = History.stateToId[str]; + } + else if ( typeof History.store.stateToId[str] !== 'undefined' ) { + id = History.store.stateToId[str]; + } + else { + // Generate a new ID + while ( true ) { + id = (new Date()).getTime() + String(Math.random()).replace(/\D/g,''); + if ( typeof History.idToState[id] === 'undefined' && typeof History.store.idToState[id] === 'undefined' ) { + break; + } + } + + // Apply the new State to the ID + History.stateToId[str] = id; + History.idToState[id] = newState; + } + } + + // Return ID + return id; + }; + + /** + * History.normalizeState(State) + * Expands a State Object + * @param {object} State + * @return {object} + */ + History.normalizeState = function(oldState){ + // Variables + var newState, dataNotEmpty; + + // Prepare + if ( !oldState || (typeof oldState !== 'object') ) { + oldState = {}; + } + + // Check + if ( typeof oldState.normalized !== 'undefined' ) { + return oldState; + } + + // Adjust + if ( !oldState.data || (typeof oldState.data !== 'object') ) { + oldState.data = {}; + } + + // ---------------------------------------------------------------- + + // Create + newState = {}; + newState.normalized = true; + newState.title = oldState.title||''; + newState.url = History.getFullUrl(oldState.url?oldState.url:(History.getLocationHref())); + newState.hash = History.getShortUrl(newState.url); + newState.data = History.cloneObject(oldState.data); + + // Fetch ID + newState.id = History.getIdByState(newState); + + // ---------------------------------------------------------------- + + // Clean the URL + newState.cleanUrl = newState.url.replace(/\??\&_suid.*/,''); + newState.url = newState.cleanUrl; + + // Check to see if we have more than just a url + dataNotEmpty = !History.isEmptyObject(newState.data); + + // Apply + if ( (newState.title || dataNotEmpty) && History.options.disableSuid !== true ) { + // Add ID to Hash + newState.hash = History.getShortUrl(newState.url).replace(/\??\&_suid.*/,''); + if ( !/\?/.test(newState.hash) ) { + newState.hash += '?'; + } + newState.hash += '&_suid='+newState.id; + } + + // Create the Hashed URL + newState.hashedUrl = History.getFullUrl(newState.hash); + + // ---------------------------------------------------------------- + + // Update the URL if we have a duplicate + if ( (History.emulated.pushState || History.bugs.safariPoll) && History.hasUrlDuplicate(newState) ) { + newState.url = newState.hashedUrl; + } + + // ---------------------------------------------------------------- + + // Return + return newState; + }; + + /** + * History.createStateObject(data,title,url) + * Creates a object based on the data, title and url state params + * @param {object} data + * @param {string} title + * @param {string} url + * @return {object} + */ + History.createStateObject = function(data,title,url){ + // Hashify + var State = { + 'data': data, + 'title': title, + 'url': url + }; + + // Expand the State + State = History.normalizeState(State); + + // Return object + return State; + }; + + /** + * History.getStateById(id) + * Get a state by it's UID + * @param {String} id + */ + History.getStateById = function(id){ + // Prepare + id = String(id); + + // Retrieve + var State = History.idToState[id] || History.store.idToState[id] || undefined; + + // Return State + return State; + }; + + /** + * Get a State's String + * @param {State} passedState + */ + History.getStateString = function(passedState){ + // Prepare + var State, cleanedState, str; + + // Fetch + State = History.normalizeState(passedState); + + // Clean + cleanedState = { + data: State.data, + title: passedState.title, + url: passedState.url + }; + + // Fetch + str = JSON.stringify(cleanedState); + + // Return + return str; + }; + + /** + * Get a State's ID + * @param {State} passedState + * @return {String} id + */ + History.getStateId = function(passedState){ + // Prepare + var State, id; + + // Fetch + State = History.normalizeState(passedState); + + // Fetch + id = State.id; + + // Return + return id; + }; + + /** + * History.getHashByState(State) + * Creates a Hash for the State Object + * @param {State} passedState + * @return {String} hash + */ + History.getHashByState = function(passedState){ + // Prepare + var State, hash; + + // Fetch + State = History.normalizeState(passedState); + + // Hash + hash = State.hash; + + // Return + return hash; + }; + + /** + * History.extractId(url_or_hash) + * Get a State ID by it's URL or Hash + * @param {string} url_or_hash + * @return {string} id + */ + History.extractId = function ( url_or_hash ) { + // Prepare + var id,parts,url, tmp; + + // Extract + + // If the URL has a #, use the id from before the # + if (url_or_hash.indexOf('#') != -1) + { + tmp = url_or_hash.split("#")[0]; + } + else + { + tmp = url_or_hash; + } + + parts = /(.*)\&_suid=([0-9]+)$/.exec(tmp); + url = parts ? (parts[1]||url_or_hash) : url_or_hash; + id = parts ? String(parts[2]||'') : ''; + + // Return + return id||false; + }; + + /** + * History.isTraditionalAnchor + * Checks to see if the url is a traditional anchor or not + * @param {String} url_or_hash + * @return {Boolean} + */ + History.isTraditionalAnchor = function(url_or_hash){ + // Check + var isTraditional = !(/[\/\?\.]/.test(url_or_hash)); + + // Return + return isTraditional; + }; + + /** + * History.extractState + * Get a State by it's URL or Hash + * @param {String} url_or_hash + * @return {State|null} + */ + History.extractState = function(url_or_hash,create){ + // Prepare + var State = null, id, url; + create = create||false; + + // Fetch SUID + id = History.extractId(url_or_hash); + if ( id ) { + State = History.getStateById(id); + } + + // Fetch SUID returned no State + if ( !State ) { + // Fetch URL + url = History.getFullUrl(url_or_hash); + + // Check URL + id = History.getIdByUrl(url)||false; + if ( id ) { + State = History.getStateById(id); + } + + // Create State + if ( !State && create && !History.isTraditionalAnchor(url_or_hash) ) { + State = History.createStateObject(null,null,url); + } + } + + // Return + return State; + }; + + /** + * History.getIdByUrl() + * Get a State ID by a State URL + */ + History.getIdByUrl = function(url){ + // Fetch + var id = History.urlToId[url] || History.store.urlToId[url] || undefined; + + // Return + return id; + }; + + /** + * History.getLastSavedState() + * Get an object containing the data, title and url of the current state + * @return {Object} State + */ + History.getLastSavedState = function(){ + return History.savedStates[History.savedStates.length-1]||undefined; + }; + + /** + * History.getLastStoredState() + * Get an object containing the data, title and url of the current state + * @return {Object} State + */ + History.getLastStoredState = function(){ + return History.storedStates[History.storedStates.length-1]||undefined; + }; + + /** + * History.hasUrlDuplicate + * Checks if a Url will have a url conflict + * @param {Object} newState + * @return {Boolean} hasDuplicate + */ + History.hasUrlDuplicate = function(newState) { + // Prepare + var hasDuplicate = false, + oldState; + + // Fetch + oldState = History.extractState(newState.url); + + // Check + hasDuplicate = oldState && oldState.id !== newState.id; + + // Return + return hasDuplicate; + }; + + /** + * History.storeState + * Store a State + * @param {Object} newState + * @return {Object} newState + */ + History.storeState = function(newState){ + // Store the State + History.urlToId[newState.url] = newState.id; + + // Push the State + History.storedStates.push(History.cloneObject(newState)); + + // Return newState + return newState; + }; + + /** + * History.isLastSavedState(newState) + * Tests to see if the state is the last state + * @param {Object} newState + * @return {boolean} isLast + */ + History.isLastSavedState = function(newState){ + // Prepare + var isLast = false, + newId, oldState, oldId; + + // Check + if ( History.savedStates.length ) { + newId = newState.id; + oldState = History.getLastSavedState(); + oldId = oldState.id; + + // Check + isLast = (newId === oldId); + } + + // Return + return isLast; + }; + + /** + * History.saveState + * Push a State + * @param {Object} newState + * @return {boolean} changed + */ + History.saveState = function(newState){ + // Check Hash + if ( History.isLastSavedState(newState) ) { + return false; + } + + // Push the State + History.savedStates.push(History.cloneObject(newState)); + + // Return true + return true; + }; + + /** + * History.getStateByIndex() + * Gets a state by the index + * @param {integer} index + * @return {Object} + */ + History.getStateByIndex = function(index){ + // Prepare + var State = null; + + // Handle + if ( typeof index === 'undefined' ) { + // Get the last inserted + State = History.savedStates[History.savedStates.length-1]; + } + else if ( index < 0 ) { + // Get from the end + State = History.savedStates[History.savedStates.length+index]; + } + else { + // Get from the beginning + State = History.savedStates[index]; + } + + // Return State + return State; + }; + + /** + * History.getCurrentIndex() + * Gets the current index + * @return (integer) + */ + History.getCurrentIndex = function(){ + // Prepare + var index = null; + + // No states saved + if(History.savedStates.length < 1) { + index = 0; + } + else { + index = History.savedStates.length-1; + } + return index; + }; + + // ==================================================================== + // Hash Helpers + + /** + * History.getHash() + * @param {Location=} location + * Gets the current document hash + * Note: unlike location.hash, this is guaranteed to return the escaped hash in all browsers + * @return {string} + */ + History.getHash = function(doc){ + var url = History.getLocationHref(doc), + hash; + hash = History.getHashByUrl(url); + return hash; + }; + + /** + * History.unescapeHash() + * normalize and Unescape a Hash + * @param {String} hash + * @return {string} + */ + History.unescapeHash = function(hash){ + // Prepare + var result = History.normalizeHash(hash); + + // Unescape hash + result = decodeURIComponent(result); + + // Return result + return result; + }; + + /** + * History.normalizeHash() + * normalize a hash across browsers + * @return {string} + */ + History.normalizeHash = function(hash){ + // Prepare + var result = hash.replace(/[^#]*#/,'').replace(/#.*/, ''); + + // Return result + return result; + }; + + /** + * History.setHash(hash) + * Sets the document hash + * @param {string} hash + * @return {History} + */ + History.setHash = function(hash,queue){ + // Prepare + var State, pageUrl; + + // Handle Queueing + if ( queue !== false && History.busy() ) { + // Wait + Push to Queue + //History.debug('History.setHash: we must wait', arguments); + History.pushQueue({ + scope: History, + callback: History.setHash, + args: arguments, + queue: queue + }); + return false; + } + + // Log + //History.debug('History.setHash: called',hash); + + // Make Busy + Continue + History.busy(true); + + // Check if hash is a state + State = History.extractState(hash,true); + if ( State && !History.emulated.pushState ) { + // Hash is a state so skip the setHash + //History.debug('History.setHash: Hash is a state so skipping the hash set with a direct pushState call',arguments); + + // PushState + History.pushState(State.data,State.title,State.url,false); + } + else if ( History.getHash() !== hash ) { + // Hash is a proper hash, so apply it + + // Handle browser bugs + if ( History.bugs.setHash ) { + // Fix Safari Bug https://bugs.webkit.org/show_bug.cgi?id=56249 + + // Fetch the base page + pageUrl = History.getPageUrl(); + + // Safari hash apply + History.pushState(null,null,pageUrl+'#'+hash,false); + } + else { + // Normal hash apply + document.location.hash = hash; + } + } + + // Chain + return History; + }; + + /** + * History.escape() + * normalize and Escape a Hash + * @return {string} + */ + History.escapeHash = function(hash){ + // Prepare + var result = History.normalizeHash(hash); + + // Escape hash + result = window.encodeURIComponent(result); + + // IE6 Escape Bug + if ( !History.bugs.hashEscape ) { + // Restore common parts + result = result + .replace(/\%21/g,'!') + .replace(/\%26/g,'&') + .replace(/\%3D/g,'=') + .replace(/\%3F/g,'?'); + } + + // Return result + return result; + }; + + /** + * History.getHashByUrl(url) + * Extracts the Hash from a URL + * @param {string} url + * @return {string} url + */ + History.getHashByUrl = function(url){ + // Extract the hash + var hash = String(url) + .replace(/([^#]*)#?([^#]*)#?(.*)/, '$2') + ; + + // Unescape hash + hash = History.unescapeHash(hash); + + // Return hash + return hash; + }; + + /** + * History.setTitle(title) + * Applies the title to the document + * @param {State} newState + * @return {Boolean} + */ + History.setTitle = function(newState){ + // Prepare + var title = newState.title, + firstState; + + // Initial + if ( !title ) { + firstState = History.getStateByIndex(0); + if ( firstState && firstState.url === newState.url ) { + title = firstState.title||History.options.initialTitle; + } + } + + // Apply + try { + document.getElementsByTagName('title')[0].innerHTML = title.replace('<','<').replace('>','>').replace(' & ',' & '); + } + catch ( Exception ) { } + document.title = title; + + // Chain + return History; + }; + + + // ==================================================================== + // Queueing + + /** + * History.queues + * The list of queues to use + * First In, First Out + */ + History.queues = []; + + /** + * History.busy(value) + * @param {boolean} value [optional] + * @return {boolean} busy + */ + History.busy = function(value){ + // Apply + if ( typeof value !== 'undefined' ) { + //History.debug('History.busy: changing ['+(History.busy.flag||false)+'] to ['+(value||false)+']', History.queues.length); + History.busy.flag = value; + } + // Default + else if ( typeof History.busy.flag === 'undefined' ) { + History.busy.flag = false; + } + + // Queue + if ( !History.busy.flag ) { + // Execute the next item in the queue + clearTimeout(History.busy.timeout); + var fireNext = function(){ + var i, queue, item; + if ( History.busy.flag ) return; + for ( i=History.queues.length-1; i >= 0; --i ) { + queue = History.queues[i]; + if ( queue.length === 0 ) continue; + item = queue.shift(); + History.fireQueueItem(item); + History.busy.timeout = setTimeout(fireNext,History.options.busyDelay); + } + }; + History.busy.timeout = setTimeout(fireNext,History.options.busyDelay); + } + + // Return + return History.busy.flag; + }; + + /** + * History.busy.flag + */ + History.busy.flag = false; + + /** + * History.fireQueueItem(item) + * Fire a Queue Item + * @param {Object} item + * @return {Mixed} result + */ + History.fireQueueItem = function(item){ + return item.callback.apply(item.scope||History,item.args||[]); + }; + + /** + * History.pushQueue(callback,args) + * Add an item to the queue + * @param {Object} item [scope,callback,args,queue] + */ + History.pushQueue = function(item){ + // Prepare the queue + History.queues[item.queue||0] = History.queues[item.queue||0]||[]; + + // Add to the queue + History.queues[item.queue||0].push(item); + + // Chain + return History; + }; + + /** + * History.queue (item,queue), (func,queue), (func), (item) + * Either firs the item now if not busy, or adds it to the queue + */ + History.queue = function(item,queue){ + // Prepare + if ( typeof item === 'function' ) { + item = { + callback: item + }; + } + if ( typeof queue !== 'undefined' ) { + item.queue = queue; + } + + // Handle + if ( History.busy() ) { + History.pushQueue(item); + } else { + History.fireQueueItem(item); + } + + // Chain + return History; + }; + + /** + * History.clearQueue() + * Clears the Queue + */ + History.clearQueue = function(){ + History.busy.flag = false; + History.queues = []; + return History; + }; + + + // ==================================================================== + // IE Bug Fix + + /** + * History.stateChanged + * States whether or not the state has changed since the last double check was initialised + */ + History.stateChanged = false; + + /** + * History.doubleChecker + * Contains the timeout used for the double checks + */ + History.doubleChecker = false; + + /** + * History.doubleCheckComplete() + * Complete a double check + * @return {History} + */ + History.doubleCheckComplete = function(){ + // Update + History.stateChanged = true; + + // Clear + History.doubleCheckClear(); + + // Chain + return History; + }; + + /** + * History.doubleCheckClear() + * Clear a double check + * @return {History} + */ + History.doubleCheckClear = function(){ + // Clear + if ( History.doubleChecker ) { + clearTimeout(History.doubleChecker); + History.doubleChecker = false; + } + + // Chain + return History; + }; + + /** + * History.doubleCheck() + * Create a double check + * @return {History} + */ + History.doubleCheck = function(tryAgain){ + // Reset + History.stateChanged = false; + History.doubleCheckClear(); + + // Fix IE6,IE7 bug where calling history.back or history.forward does not actually change the hash (whereas doing it manually does) + // Fix Safari 5 bug where sometimes the state does not change: https://bugs.webkit.org/show_bug.cgi?id=42940 + if ( History.bugs.ieDoubleCheck ) { + // Apply Check + History.doubleChecker = setTimeout( + function(){ + History.doubleCheckClear(); + if ( !History.stateChanged ) { + //History.debug('History.doubleCheck: State has not yet changed, trying again', arguments); + // Re-Attempt + tryAgain(); + } + return true; + }, + History.options.doubleCheckInterval + ); + } + + // Chain + return History; + }; + + + // ==================================================================== + // Safari Bug Fix + + /** + * History.safariStatePoll() + * Poll the current state + * @return {History} + */ + History.safariStatePoll = function(){ + // Poll the URL + + // Get the Last State which has the new URL + var + urlState = History.extractState(History.getLocationHref()), + newState; + + // Check for a difference + if ( !History.isLastSavedState(urlState) ) { + newState = urlState; + } + else { + return; + } + + // Check if we have a state with that url + // If not create it + if ( !newState ) { + //History.debug('History.safariStatePoll: new'); + newState = History.createStateObject(); + } + + // Apply the New State + //History.debug('History.safariStatePoll: trigger'); + History.Adapter.trigger(window,'popstate'); + + // Chain + return History; + }; + + + // ==================================================================== + // State Aliases + + /** + * History.back(queue) + * Send the browser history back one item + * @param {Integer} queue [optional] + */ + History.back = function(queue){ + //History.debug('History.back: called', arguments); + + // Handle Queueing + if ( queue !== false && History.busy() ) { + // Wait + Push to Queue + //History.debug('History.back: we must wait', arguments); + History.pushQueue({ + scope: History, + callback: History.back, + args: arguments, + queue: queue + }); + return false; + } + + // Make Busy + Continue + History.busy(true); + + // Fix certain browser bugs that prevent the state from changing + History.doubleCheck(function(){ + History.back(false); + }); + + // Go back + history.go(-1); + + // End back closure + return true; + }; + + /** + * History.forward(queue) + * Send the browser history forward one item + * @param {Integer} queue [optional] + */ + History.forward = function(queue){ + //History.debug('History.forward: called', arguments); + + // Handle Queueing + if ( queue !== false && History.busy() ) { + // Wait + Push to Queue + //History.debug('History.forward: we must wait', arguments); + History.pushQueue({ + scope: History, + callback: History.forward, + args: arguments, + queue: queue + }); + return false; + } + + // Make Busy + Continue + History.busy(true); + + // Fix certain browser bugs that prevent the state from changing + History.doubleCheck(function(){ + History.forward(false); + }); + + // Go forward + history.go(1); + + // End forward closure + return true; + }; + + /** + * History.go(index,queue) + * Send the browser history back or forward index times + * @param {Integer} queue [optional] + */ + History.go = function(index,queue){ + //History.debug('History.go: called', arguments); + + // Prepare + var i; + + // Handle + if ( index > 0 ) { + // Forward + for ( i=1; i<=index; ++i ) { + History.forward(queue); + } + } + else if ( index < 0 ) { + // Backward + for ( i=-1; i>=index; --i ) { + History.back(queue); + } + } + else { + throw new Error('History.go: History.go requires a positive or negative integer passed.'); + } + + // Chain + return History; + }; + + + // ==================================================================== + // HTML5 State Support + + // Non-Native pushState Implementation + if ( History.emulated.pushState ) { + /* + * Provide Skeleton for HTML4 Browsers + */ + + // Prepare + var emptyFunction = function(){}; + History.pushState = History.pushState||emptyFunction; + History.replaceState = History.replaceState||emptyFunction; + } // History.emulated.pushState + + // Native pushState Implementation + else { + /* + * Use native HTML5 History API Implementation + */ + + /** + * History.onPopState(event,extra) + * Refresh the Current State + */ + History.onPopState = function(event,extra){ + // Prepare + var stateId = false, newState = false, currentHash, currentState; + + // Reset the double check + History.doubleCheckComplete(); + + // Check for a Hash, and handle apporiatly + currentHash = History.getHash(); + if ( currentHash ) { + // Expand Hash + currentState = History.extractState(currentHash||History.getLocationHref(),true); + if ( currentState ) { + // We were able to parse it, it must be a State! + // Let's forward to replaceState + //History.debug('History.onPopState: state anchor', currentHash, currentState); + History.replaceState(currentState.data, currentState.title, currentState.url, false); + } + else { + // Traditional Anchor + //History.debug('History.onPopState: traditional anchor', currentHash); + History.Adapter.trigger(window,'anchorchange'); + History.busy(false); + } + + // We don't care for hashes + History.expectedStateId = false; + return false; + } + + // Ensure + stateId = History.Adapter.extractEventData('state',event,extra) || false; + + // Fetch State + if ( stateId ) { + // Vanilla: Back/forward button was used + newState = History.getStateById(stateId); + } + else if ( History.expectedStateId ) { + // Vanilla: A new state was pushed, and popstate was called manually + newState = History.getStateById(History.expectedStateId); + } + else { + // Initial State + newState = History.extractState(History.getLocationHref()); + } + + // The State did not exist in our store + if ( !newState ) { + // Regenerate the State + newState = History.createStateObject(null,null,History.getLocationHref()); + } + + // Clean + History.expectedStateId = false; + + // Check if we are the same state + if ( History.isLastSavedState(newState) ) { + // There has been no change (just the page's hash has finally propagated) + //History.debug('History.onPopState: no change', newState, History.savedStates); + History.busy(false); + return false; + } + + // Store the State + History.storeState(newState); + History.saveState(newState); + + // Force update of the title + History.setTitle(newState); + + // Fire Our Event + History.Adapter.trigger(window,'statechange'); + History.busy(false); + + // Return true + return true; + }; + History.Adapter.bind(window,'popstate',History.onPopState); + + /** + * History.pushState(data,title,url) + * Add a new State to the history object, become it, and trigger onpopstate + * We have to trigger for HTML4 compatibility + * @param {object} data + * @param {string} title + * @param {string} url + * @return {true} + */ + History.pushState = function(data,title,url,queue){ + //History.debug('History.pushState: called', arguments); + + // Check the State + if ( History.getHashByUrl(url) && History.emulated.pushState ) { + throw new Error('History.js does not support states with fragement-identifiers (hashes/anchors).'); + } + + // Handle Queueing + if ( queue !== false && History.busy() ) { + // Wait + Push to Queue + //History.debug('History.pushState: we must wait', arguments); + History.pushQueue({ + scope: History, + callback: History.pushState, + args: arguments, + queue: queue + }); + return false; + } + + // Make Busy + Continue + History.busy(true); + + // Create the newState + var newState = History.createStateObject(data,title,url); + + // Check it + if ( History.isLastSavedState(newState) ) { + // Won't be a change + History.busy(false); + } + else { + // Store the newState + History.storeState(newState); + History.expectedStateId = newState.id; + + // Push the newState + history.pushState(newState.id,newState.title,newState.url); + + // Fire HTML5 Event + History.Adapter.trigger(window,'popstate'); + } + + // End pushState closure + return true; + }; + + /** + * History.replaceState(data,title,url) + * Replace the State and trigger onpopstate + * We have to trigger for HTML4 compatibility + * @param {object} data + * @param {string} title + * @param {string} url + * @return {true} + */ + History.replaceState = function(data,title,url,queue){ + //History.debug('History.replaceState: called', arguments); + + // Check the State + if ( History.getHashByUrl(url) && History.emulated.pushState ) { + throw new Error('History.js does not support states with fragement-identifiers (hashes/anchors).'); + } + + // Handle Queueing + if ( queue !== false && History.busy() ) { + // Wait + Push to Queue + //History.debug('History.replaceState: we must wait', arguments); + History.pushQueue({ + scope: History, + callback: History.replaceState, + args: arguments, + queue: queue + }); + return false; + } + + // Make Busy + Continue + History.busy(true); + + // Create the newState + var newState = History.createStateObject(data,title,url); + + // Check it + if ( History.isLastSavedState(newState) ) { + // Won't be a change + History.busy(false); + } + else { + // Store the newState + History.storeState(newState); + History.expectedStateId = newState.id; + + // Push the newState + history.replaceState(newState.id,newState.title,newState.url); + + // Fire HTML5 Event + History.Adapter.trigger(window,'popstate'); + } + + // End replaceState closure + return true; + }; + + } // !History.emulated.pushState + + + // ==================================================================== + // Initialise + + /** + * Load the Store + */ + if ( sessionStorage ) { + // Fetch + try { + History.store = JSON.parse(sessionStorage.getItem('History.store'))||{}; + } + catch ( err ) { + History.store = {}; + } + + // Normalize + History.normalizeStore(); + } + else { + // Default Load + History.store = {}; + History.normalizeStore(); + } + + /** + * Clear Intervals on exit to prevent memory leaks + */ + History.Adapter.bind(window,"unload",History.clearAllIntervals); + + /** + * Create the initial State + */ + History.saveState(History.storeState(History.extractState(History.getLocationHref(),true))); + + /** + * Bind for Saving Store + */ + if ( sessionStorage ) { + // When the page is closed + History.onUnload = function(){ + // Prepare + var currentStore, item, currentStoreString; + + // Fetch + try { + currentStore = JSON.parse(sessionStorage.getItem('History.store'))||{}; + } + catch ( err ) { + currentStore = {}; + } + + // Ensure + currentStore.idToState = currentStore.idToState || {}; + currentStore.urlToId = currentStore.urlToId || {}; + currentStore.stateToId = currentStore.stateToId || {}; + + // Sync + for ( item in History.idToState ) { + if ( !History.idToState.hasOwnProperty(item) ) { + continue; + } + currentStore.idToState[item] = History.idToState[item]; + } + for ( item in History.urlToId ) { + if ( !History.urlToId.hasOwnProperty(item) ) { + continue; + } + currentStore.urlToId[item] = History.urlToId[item]; + } + for ( item in History.stateToId ) { + if ( !History.stateToId.hasOwnProperty(item) ) { + continue; + } + currentStore.stateToId[item] = History.stateToId[item]; + } + + // Update + History.store = currentStore; + History.normalizeStore(); + + // In Safari, going into Private Browsing mode causes the + // Session Storage object to still exist but if you try and use + // or set any property/function of it it throws the exception + // "QUOTA_EXCEEDED_ERR: DOM Exception 22: An attempt was made to + // add something to storage that exceeded the quota." infinitely + // every second. + currentStoreString = JSON.stringify(currentStore); + try { + // Store + sessionStorage.setItem('History.store', currentStoreString); + } + catch (e) { + if (e.code === DOMException.QUOTA_EXCEEDED_ERR) { + if (sessionStorage.length) { + // Workaround for a bug seen on iPads. Sometimes the quota exceeded error comes up and simply + // removing/resetting the storage can work. + sessionStorage.removeItem('History.store'); + sessionStorage.setItem('History.store', currentStoreString); + } else { + // Otherwise, we're probably private browsing in Safari, so we'll ignore the exception. + } + } else { + throw e; + } + } + }; + + // For Internet Explorer + History.intervalList.push(setInterval(History.onUnload,History.options.storeInterval)); + + // For Other Browsers + History.Adapter.bind(window,'beforeunload',History.onUnload); + History.Adapter.bind(window,'unload',History.onUnload); + + // Both are enabled for consistency + } + + // Non-Native pushState Implementation + if ( !History.emulated.pushState ) { + // Be aware, the following is only for native pushState implementations + // If you are wanting to include something for all browsers + // Then include it above this if block + + /** + * Setup Safari Fix + */ + if ( History.bugs.safariPoll ) { + History.intervalList.push(setInterval(History.safariStatePoll, History.options.safariPollInterval)); + } + + /** + * Ensure Cross Browser Compatibility + */ + if ( navigator.vendor === 'Apple Computer, Inc.' || (navigator.appCodeName||'') === 'Mozilla' ) { + /** + * Fix Safari HashChange Issue + */ + + // Setup Alias + History.Adapter.bind(window,'hashchange',function(){ + History.Adapter.trigger(window,'popstate'); + }); + + // Initialise Alias + if ( History.getHash() ) { + History.Adapter.onDomLoad(function(){ + History.Adapter.trigger(window,'hashchange'); + }); + } + } + + } // !History.emulated.pushState + + + }; // History.initCore + + // Try to Initialise History + if (!History.options || !History.options.delayInit) { + History.init(); + } + +})(window); diff --git a/sites/all/themes/gui/materiobasetheme/bower_components/history.js/scripts/bundled-uncompressed/html5/jquery.history.js b/sites/all/themes/gui/materiobasetheme/bower_components/history.js/scripts/bundled-uncompressed/html5/jquery.history.js new file mode 100644 index 00000000..c53a5b4f --- /dev/null +++ b/sites/all/themes/gui/materiobasetheme/bower_components/history.js/scripts/bundled-uncompressed/html5/jquery.history.js @@ -0,0 +1,2121 @@ +/** + * History.js jQuery Adapter + * @author Benjamin Arthur Lupton + * @copyright 2010-2011 Benjamin Arthur Lupton + * @license New BSD License + */ + +// Closure +(function(window,undefined){ + "use strict"; + + // Localise Globals + var + History = window.History = window.History||{}, + jQuery = window.jQuery; + + // Check Existence + if ( typeof History.Adapter !== 'undefined' ) { + throw new Error('History.js Adapter has already been loaded...'); + } + + // Add the Adapter + History.Adapter = { + /** + * History.Adapter.bind(el,event,callback) + * @param {Element|string} el + * @param {string} event - custom and standard events + * @param {function} callback + * @return {void} + */ + bind: function(el,event,callback){ + jQuery(el).bind(event,callback); + }, + + /** + * History.Adapter.trigger(el,event) + * @param {Element|string} el + * @param {string} event - custom and standard events + * @param {Object=} extra - a object of extra event data (optional) + * @return {void} + */ + trigger: function(el,event,extra){ + jQuery(el).trigger(event,extra); + }, + + /** + * History.Adapter.extractEventData(key,event,extra) + * @param {string} key - key for the event data to extract + * @param {string} event - custom and standard events + * @param {Object=} extra - a object of extra event data (optional) + * @return {mixed} + */ + extractEventData: function(key,event,extra){ + // jQuery Native then jQuery Custom + var result = (event && event.originalEvent && event.originalEvent[key]) || (extra && extra[key]) || undefined; + + // Return + return result; + }, + + /** + * History.Adapter.onDomLoad(callback) + * @param {function} callback + * @return {void} + */ + onDomLoad: function(callback) { + jQuery(callback); + } + }; + + // Try and Initialise History + if ( typeof History.init !== 'undefined' ) { + History.init(); + } + +})(window); + +/** + * History.js Core + * @author Benjamin Arthur Lupton + * @copyright 2010-2011 Benjamin Arthur Lupton + * @license New BSD License + */ + +(function(window,undefined){ + "use strict"; + + // ======================================================================== + // Initialise + + // Localise Globals + var + console = window.console||undefined, // Prevent a JSLint complain + document = window.document, // Make sure we are using the correct document + navigator = window.navigator, // Make sure we are using the correct navigator + sessionStorage = window.sessionStorage||false, // sessionStorage + setTimeout = window.setTimeout, + clearTimeout = window.clearTimeout, + setInterval = window.setInterval, + clearInterval = window.clearInterval, + JSON = window.JSON, + alert = window.alert, + History = window.History = window.History||{}, // Public History Object + history = window.history; // Old History Object + + try { + sessionStorage.setItem('TEST', '1'); + sessionStorage.removeItem('TEST'); + } catch(e) { + sessionStorage = false; + } + + // MooTools Compatibility + JSON.stringify = JSON.stringify||JSON.encode; + JSON.parse = JSON.parse||JSON.decode; + + // Check Existence + if ( typeof History.init !== 'undefined' ) { + throw new Error('History.js Core has already been loaded...'); + } + + // Initialise History + History.init = function(options){ + // Check Load Status of Adapter + if ( typeof History.Adapter === 'undefined' ) { + return false; + } + + // Check Load Status of Core + if ( typeof History.initCore !== 'undefined' ) { + History.initCore(); + } + + // Check Load Status of HTML4 Support + if ( typeof History.initHtml4 !== 'undefined' ) { + History.initHtml4(); + } + + // Return true + return true; + }; + + + // ======================================================================== + // Initialise Core + + // Initialise Core + History.initCore = function(options){ + // Initialise + if ( typeof History.initCore.initialized !== 'undefined' ) { + // Already Loaded + return false; + } + else { + History.initCore.initialized = true; + } + + + // ==================================================================== + // Options + + /** + * History.options + * Configurable options + */ + History.options = History.options||{}; + + /** + * History.options.hashChangeInterval + * How long should the interval be before hashchange checks + */ + History.options.hashChangeInterval = History.options.hashChangeInterval || 100; + + /** + * History.options.safariPollInterval + * How long should the interval be before safari poll checks + */ + History.options.safariPollInterval = History.options.safariPollInterval || 500; + + /** + * History.options.doubleCheckInterval + * How long should the interval be before we perform a double check + */ + History.options.doubleCheckInterval = History.options.doubleCheckInterval || 500; + + /** + * History.options.disableSuid + * Force History not to append suid + */ + History.options.disableSuid = History.options.disableSuid || false; + + /** + * History.options.storeInterval + * How long should we wait between store calls + */ + History.options.storeInterval = History.options.storeInterval || 1000; + + /** + * History.options.busyDelay + * How long should we wait between busy events + */ + History.options.busyDelay = History.options.busyDelay || 250; + + /** + * History.options.debug + * If true will enable debug messages to be logged + */ + History.options.debug = History.options.debug || false; + + /** + * History.options.initialTitle + * What is the title of the initial state + */ + History.options.initialTitle = History.options.initialTitle || document.title; + + /** + * History.options.html4Mode + * If true, will force HTMl4 mode (hashtags) + */ + History.options.html4Mode = History.options.html4Mode || false; + + /** + * History.options.delayInit + * Want to override default options and call init manually. + */ + History.options.delayInit = History.options.delayInit || false; + + + // ==================================================================== + // Interval record + + /** + * History.intervalList + * List of intervals set, to be cleared when document is unloaded. + */ + History.intervalList = []; + + /** + * History.clearAllIntervals + * Clears all setInterval instances. + */ + History.clearAllIntervals = function(){ + var i, il = History.intervalList; + if (typeof il !== "undefined" && il !== null) { + for (i = 0; i < il.length; i++) { + clearInterval(il[i]); + } + History.intervalList = null; + } + }; + + + // ==================================================================== + // Debug + + /** + * History.debug(message,...) + * Logs the passed arguments if debug enabled + */ + History.debug = function(){ + if ( (History.options.debug||false) ) { + History.log.apply(History,arguments); + } + }; + + /** + * History.log(message,...) + * Logs the passed arguments + */ + History.log = function(){ + // Prepare + var + consoleExists = !(typeof console === 'undefined' || typeof console.log === 'undefined' || typeof console.log.apply === 'undefined'), + textarea = document.getElementById('log'), + message, + i,n, + args,arg + ; + + // Write to Console + if ( consoleExists ) { + args = Array.prototype.slice.call(arguments); + message = args.shift(); + if ( typeof console.debug !== 'undefined' ) { + console.debug.apply(console,[message,args]); + } + else { + console.log.apply(console,[message,args]); + } + } + else { + message = ("\n"+arguments[0]+"\n"); + } + + // Write to log + for ( i=1,n=arguments.length; i + * @author James Padolsey + */ + History.getInternetExplorerMajorVersion = function(){ + var result = History.getInternetExplorerMajorVersion.cached = + (typeof History.getInternetExplorerMajorVersion.cached !== 'undefined') + ? History.getInternetExplorerMajorVersion.cached + : (function(){ + var v = 3, + div = document.createElement('div'), + all = div.getElementsByTagName('i'); + while ( (div.innerHTML = '') && all[0] ) {} + return (v > 4) ? v : false; + })() + ; + return result; + }; + + /** + * History.isInternetExplorer() + * Are we using Internet Explorer? + * @return {boolean} + * @license Public Domain + * @author Benjamin Arthur Lupton + */ + History.isInternetExplorer = function(){ + var result = + History.isInternetExplorer.cached = + (typeof History.isInternetExplorer.cached !== 'undefined') + ? History.isInternetExplorer.cached + : Boolean(History.getInternetExplorerMajorVersion()) + ; + return result; + }; + + /** + * History.emulated + * Which features require emulating? + */ + + if (History.options.html4Mode) { + History.emulated = { + pushState : true, + hashChange: true + }; + } + + else { + + History.emulated = { + pushState: !Boolean( + window.history && window.history.pushState && window.history.replaceState + && !( + (/ Mobile\/([1-7][a-z]|(8([abcde]|f(1[0-8]))))/i).test(navigator.userAgent) /* disable for versions of iOS before version 4.3 (8F190) */ + || (/AppleWebKit\/5([0-2]|3[0-2])/i).test(navigator.userAgent) /* disable for the mercury iOS browser, or at least older versions of the webkit engine */ + ) + ), + hashChange: Boolean( + !(('onhashchange' in window) || ('onhashchange' in document)) + || + (History.isInternetExplorer() && History.getInternetExplorerMajorVersion() < 8) + ) + }; + } + + /** + * History.enabled + * Is History enabled? + */ + History.enabled = !History.emulated.pushState; + + /** + * History.bugs + * Which bugs are present + */ + History.bugs = { + /** + * Safari 5 and Safari iOS 4 fail to return to the correct state once a hash is replaced by a `replaceState` call + * https://bugs.webkit.org/show_bug.cgi?id=56249 + */ + setHash: Boolean(!History.emulated.pushState && navigator.vendor === 'Apple Computer, Inc.' && /AppleWebKit\/5([0-2]|3[0-3])/.test(navigator.userAgent)), + + /** + * Safari 5 and Safari iOS 4 sometimes fail to apply the state change under busy conditions + * https://bugs.webkit.org/show_bug.cgi?id=42940 + */ + safariPoll: Boolean(!History.emulated.pushState && navigator.vendor === 'Apple Computer, Inc.' && /AppleWebKit\/5([0-2]|3[0-3])/.test(navigator.userAgent)), + + /** + * MSIE 6 and 7 sometimes do not apply a hash even it was told to (requiring a second call to the apply function) + */ + ieDoubleCheck: Boolean(History.isInternetExplorer() && History.getInternetExplorerMajorVersion() < 8), + + /** + * MSIE 6 requires the entire hash to be encoded for the hashes to trigger the onHashChange event + */ + hashEscape: Boolean(History.isInternetExplorer() && History.getInternetExplorerMajorVersion() < 7) + }; + + /** + * History.isEmptyObject(obj) + * Checks to see if the Object is Empty + * @param {Object} obj + * @return {boolean} + */ + History.isEmptyObject = function(obj) { + for ( var name in obj ) { + if ( obj.hasOwnProperty(name) ) { + return false; + } + } + return true; + }; + + /** + * History.cloneObject(obj) + * Clones a object and eliminate all references to the original contexts + * @param {Object} obj + * @return {Object} + */ + History.cloneObject = function(obj) { + var hash,newObj; + if ( obj ) { + hash = JSON.stringify(obj); + newObj = JSON.parse(hash); + } + else { + newObj = {}; + } + return newObj; + }; + + + // ==================================================================== + // URL Helpers + + /** + * History.getRootUrl() + * Turns "http://mysite.com/dir/page.html?asd" into "http://mysite.com" + * @return {String} rootUrl + */ + History.getRootUrl = function(){ + // Create + var rootUrl = document.location.protocol+'//'+(document.location.hostname||document.location.host); + if ( document.location.port||false ) { + rootUrl += ':'+document.location.port; + } + rootUrl += '/'; + + // Return + return rootUrl; + }; + + /** + * History.getBaseHref() + * Fetches the `href` attribute of the `` element if it exists + * @return {String} baseHref + */ + History.getBaseHref = function(){ + // Create + var + baseElements = document.getElementsByTagName('base'), + baseElement = null, + baseHref = ''; + + // Test for Base Element + if ( baseElements.length === 1 ) { + // Prepare for Base Element + baseElement = baseElements[0]; + baseHref = baseElement.href.replace(/[^\/]+$/,''); + } + + // Adjust trailing slash + baseHref = baseHref.replace(/\/+$/,''); + if ( baseHref ) baseHref += '/'; + + // Return + return baseHref; + }; + + /** + * History.getBaseUrl() + * Fetches the baseHref or basePageUrl or rootUrl (whichever one exists first) + * @return {String} baseUrl + */ + History.getBaseUrl = function(){ + // Create + var baseUrl = History.getBaseHref()||History.getBasePageUrl()||History.getRootUrl(); + + // Return + return baseUrl; + }; + + /** + * History.getPageUrl() + * Fetches the URL of the current page + * @return {String} pageUrl + */ + History.getPageUrl = function(){ + // Fetch + var + State = History.getState(false,false), + stateUrl = (State||{}).url||History.getLocationHref(), + pageUrl; + + // Create + pageUrl = stateUrl.replace(/\/+$/,'').replace(/[^\/]+$/,function(part,index,string){ + return (/\./).test(part) ? part : part+'/'; + }); + + // Return + return pageUrl; + }; + + /** + * History.getBasePageUrl() + * Fetches the Url of the directory of the current page + * @return {String} basePageUrl + */ + History.getBasePageUrl = function(){ + // Create + var basePageUrl = (History.getLocationHref()).replace(/[#\?].*/,'').replace(/[^\/]+$/,function(part,index,string){ + return (/[^\/]$/).test(part) ? '' : part; + }).replace(/\/+$/,'')+'/'; + + // Return + return basePageUrl; + }; + + /** + * History.getFullUrl(url) + * Ensures that we have an absolute URL and not a relative URL + * @param {string} url + * @param {Boolean} allowBaseHref + * @return {string} fullUrl + */ + History.getFullUrl = function(url,allowBaseHref){ + // Prepare + var fullUrl = url, firstChar = url.substring(0,1); + allowBaseHref = (typeof allowBaseHref === 'undefined') ? true : allowBaseHref; + + // Check + if ( /[a-z]+\:\/\//.test(url) ) { + // Full URL + } + else if ( firstChar === '/' ) { + // Root URL + fullUrl = History.getRootUrl()+url.replace(/^\/+/,''); + } + else if ( firstChar === '#' ) { + // Anchor URL + fullUrl = History.getPageUrl().replace(/#.*/,'')+url; + } + else if ( firstChar === '?' ) { + // Query URL + fullUrl = History.getPageUrl().replace(/[\?#].*/,'')+url; + } + else { + // Relative URL + if ( allowBaseHref ) { + fullUrl = History.getBaseUrl()+url.replace(/^(\.\/)+/,''); + } else { + fullUrl = History.getBasePageUrl()+url.replace(/^(\.\/)+/,''); + } + // We have an if condition above as we do not want hashes + // which are relative to the baseHref in our URLs + // as if the baseHref changes, then all our bookmarks + // would now point to different locations + // whereas the basePageUrl will always stay the same + } + + // Return + return fullUrl.replace(/\#$/,''); + }; + + /** + * History.getShortUrl(url) + * Ensures that we have a relative URL and not a absolute URL + * @param {string} url + * @return {string} url + */ + History.getShortUrl = function(url){ + // Prepare + var shortUrl = url, baseUrl = History.getBaseUrl(), rootUrl = History.getRootUrl(); + + // Trim baseUrl + if ( History.emulated.pushState ) { + // We are in a if statement as when pushState is not emulated + // The actual url these short urls are relative to can change + // So within the same session, we the url may end up somewhere different + shortUrl = shortUrl.replace(baseUrl,''); + } + + // Trim rootUrl + shortUrl = shortUrl.replace(rootUrl,'/'); + + // Ensure we can still detect it as a state + if ( History.isTraditionalAnchor(shortUrl) ) { + shortUrl = './'+shortUrl; + } + + // Clean It + shortUrl = shortUrl.replace(/^(\.\/)+/g,'./').replace(/\#$/,''); + + // Return + return shortUrl; + }; + + /** + * History.getLocationHref(document) + * Returns a normalized version of document.location.href + * accounting for browser inconsistencies, etc. + * + * This URL will be URI-encoded and will include the hash + * + * @param {object} document + * @return {string} url + */ + History.getLocationHref = function(doc) { + doc = doc || document; + + // most of the time, this will be true + if (doc.URL === doc.location.href) + return doc.location.href; + + // some versions of webkit URI-decode document.location.href + // but they leave document.URL in an encoded state + if (doc.location.href === decodeURIComponent(doc.URL)) + return doc.URL; + + // FF 3.6 only updates document.URL when a page is reloaded + // document.location.href is updated correctly + if (doc.location.hash && decodeURIComponent(doc.location.href.replace(/^[^#]+/, "")) === doc.location.hash) + return doc.location.href; + + if (doc.URL.indexOf('#') == -1 && doc.location.href.indexOf('#') != -1) + return doc.location.href; + + return doc.URL || doc.location.href; + }; + + + // ==================================================================== + // State Storage + + /** + * History.store + * The store for all session specific data + */ + History.store = {}; + + /** + * History.idToState + * 1-1: State ID to State Object + */ + History.idToState = History.idToState||{}; + + /** + * History.stateToId + * 1-1: State String to State ID + */ + History.stateToId = History.stateToId||{}; + + /** + * History.urlToId + * 1-1: State URL to State ID + */ + History.urlToId = History.urlToId||{}; + + /** + * History.storedStates + * Store the states in an array + */ + History.storedStates = History.storedStates||[]; + + /** + * History.savedStates + * Saved the states in an array + */ + History.savedStates = History.savedStates||[]; + + /** + * History.noramlizeStore() + * Noramlize the store by adding necessary values + */ + History.normalizeStore = function(){ + History.store.idToState = History.store.idToState||{}; + History.store.urlToId = History.store.urlToId||{}; + History.store.stateToId = History.store.stateToId||{}; + }; + + /** + * History.getState() + * Get an object containing the data, title and url of the current state + * @param {Boolean} friendly + * @param {Boolean} create + * @return {Object} State + */ + History.getState = function(friendly,create){ + // Prepare + if ( typeof friendly === 'undefined' ) { friendly = true; } + if ( typeof create === 'undefined' ) { create = true; } + + // Fetch + var State = History.getLastSavedState(); + + // Create + if ( !State && create ) { + State = History.createStateObject(); + } + + // Adjust + if ( friendly ) { + State = History.cloneObject(State); + State.url = State.cleanUrl||State.url; + } + + // Return + return State; + }; + + /** + * History.getIdByState(State) + * Gets a ID for a State + * @param {State} newState + * @return {String} id + */ + History.getIdByState = function(newState){ + + // Fetch ID + var id = History.extractId(newState.url), + str; + + if ( !id ) { + // Find ID via State String + str = History.getStateString(newState); + if ( typeof History.stateToId[str] !== 'undefined' ) { + id = History.stateToId[str]; + } + else if ( typeof History.store.stateToId[str] !== 'undefined' ) { + id = History.store.stateToId[str]; + } + else { + // Generate a new ID + while ( true ) { + id = (new Date()).getTime() + String(Math.random()).replace(/\D/g,''); + if ( typeof History.idToState[id] === 'undefined' && typeof History.store.idToState[id] === 'undefined' ) { + break; + } + } + + // Apply the new State to the ID + History.stateToId[str] = id; + History.idToState[id] = newState; + } + } + + // Return ID + return id; + }; + + /** + * History.normalizeState(State) + * Expands a State Object + * @param {object} State + * @return {object} + */ + History.normalizeState = function(oldState){ + // Variables + var newState, dataNotEmpty; + + // Prepare + if ( !oldState || (typeof oldState !== 'object') ) { + oldState = {}; + } + + // Check + if ( typeof oldState.normalized !== 'undefined' ) { + return oldState; + } + + // Adjust + if ( !oldState.data || (typeof oldState.data !== 'object') ) { + oldState.data = {}; + } + + // ---------------------------------------------------------------- + + // Create + newState = {}; + newState.normalized = true; + newState.title = oldState.title||''; + newState.url = History.getFullUrl(oldState.url?oldState.url:(History.getLocationHref())); + newState.hash = History.getShortUrl(newState.url); + newState.data = History.cloneObject(oldState.data); + + // Fetch ID + newState.id = History.getIdByState(newState); + + // ---------------------------------------------------------------- + + // Clean the URL + newState.cleanUrl = newState.url.replace(/\??\&_suid.*/,''); + newState.url = newState.cleanUrl; + + // Check to see if we have more than just a url + dataNotEmpty = !History.isEmptyObject(newState.data); + + // Apply + if ( (newState.title || dataNotEmpty) && History.options.disableSuid !== true ) { + // Add ID to Hash + newState.hash = History.getShortUrl(newState.url).replace(/\??\&_suid.*/,''); + if ( !/\?/.test(newState.hash) ) { + newState.hash += '?'; + } + newState.hash += '&_suid='+newState.id; + } + + // Create the Hashed URL + newState.hashedUrl = History.getFullUrl(newState.hash); + + // ---------------------------------------------------------------- + + // Update the URL if we have a duplicate + if ( (History.emulated.pushState || History.bugs.safariPoll) && History.hasUrlDuplicate(newState) ) { + newState.url = newState.hashedUrl; + } + + // ---------------------------------------------------------------- + + // Return + return newState; + }; + + /** + * History.createStateObject(data,title,url) + * Creates a object based on the data, title and url state params + * @param {object} data + * @param {string} title + * @param {string} url + * @return {object} + */ + History.createStateObject = function(data,title,url){ + // Hashify + var State = { + 'data': data, + 'title': title, + 'url': url + }; + + // Expand the State + State = History.normalizeState(State); + + // Return object + return State; + }; + + /** + * History.getStateById(id) + * Get a state by it's UID + * @param {String} id + */ + History.getStateById = function(id){ + // Prepare + id = String(id); + + // Retrieve + var State = History.idToState[id] || History.store.idToState[id] || undefined; + + // Return State + return State; + }; + + /** + * Get a State's String + * @param {State} passedState + */ + History.getStateString = function(passedState){ + // Prepare + var State, cleanedState, str; + + // Fetch + State = History.normalizeState(passedState); + + // Clean + cleanedState = { + data: State.data, + title: passedState.title, + url: passedState.url + }; + + // Fetch + str = JSON.stringify(cleanedState); + + // Return + return str; + }; + + /** + * Get a State's ID + * @param {State} passedState + * @return {String} id + */ + History.getStateId = function(passedState){ + // Prepare + var State, id; + + // Fetch + State = History.normalizeState(passedState); + + // Fetch + id = State.id; + + // Return + return id; + }; + + /** + * History.getHashByState(State) + * Creates a Hash for the State Object + * @param {State} passedState + * @return {String} hash + */ + History.getHashByState = function(passedState){ + // Prepare + var State, hash; + + // Fetch + State = History.normalizeState(passedState); + + // Hash + hash = State.hash; + + // Return + return hash; + }; + + /** + * History.extractId(url_or_hash) + * Get a State ID by it's URL or Hash + * @param {string} url_or_hash + * @return {string} id + */ + History.extractId = function ( url_or_hash ) { + // Prepare + var id,parts,url, tmp; + + // Extract + + // If the URL has a #, use the id from before the # + if (url_or_hash.indexOf('#') != -1) + { + tmp = url_or_hash.split("#")[0]; + } + else + { + tmp = url_or_hash; + } + + parts = /(.*)\&_suid=([0-9]+)$/.exec(tmp); + url = parts ? (parts[1]||url_or_hash) : url_or_hash; + id = parts ? String(parts[2]||'') : ''; + + // Return + return id||false; + }; + + /** + * History.isTraditionalAnchor + * Checks to see if the url is a traditional anchor or not + * @param {String} url_or_hash + * @return {Boolean} + */ + History.isTraditionalAnchor = function(url_or_hash){ + // Check + var isTraditional = !(/[\/\?\.]/.test(url_or_hash)); + + // Return + return isTraditional; + }; + + /** + * History.extractState + * Get a State by it's URL or Hash + * @param {String} url_or_hash + * @return {State|null} + */ + History.extractState = function(url_or_hash,create){ + // Prepare + var State = null, id, url; + create = create||false; + + // Fetch SUID + id = History.extractId(url_or_hash); + if ( id ) { + State = History.getStateById(id); + } + + // Fetch SUID returned no State + if ( !State ) { + // Fetch URL + url = History.getFullUrl(url_or_hash); + + // Check URL + id = History.getIdByUrl(url)||false; + if ( id ) { + State = History.getStateById(id); + } + + // Create State + if ( !State && create && !History.isTraditionalAnchor(url_or_hash) ) { + State = History.createStateObject(null,null,url); + } + } + + // Return + return State; + }; + + /** + * History.getIdByUrl() + * Get a State ID by a State URL + */ + History.getIdByUrl = function(url){ + // Fetch + var id = History.urlToId[url] || History.store.urlToId[url] || undefined; + + // Return + return id; + }; + + /** + * History.getLastSavedState() + * Get an object containing the data, title and url of the current state + * @return {Object} State + */ + History.getLastSavedState = function(){ + return History.savedStates[History.savedStates.length-1]||undefined; + }; + + /** + * History.getLastStoredState() + * Get an object containing the data, title and url of the current state + * @return {Object} State + */ + History.getLastStoredState = function(){ + return History.storedStates[History.storedStates.length-1]||undefined; + }; + + /** + * History.hasUrlDuplicate + * Checks if a Url will have a url conflict + * @param {Object} newState + * @return {Boolean} hasDuplicate + */ + History.hasUrlDuplicate = function(newState) { + // Prepare + var hasDuplicate = false, + oldState; + + // Fetch + oldState = History.extractState(newState.url); + + // Check + hasDuplicate = oldState && oldState.id !== newState.id; + + // Return + return hasDuplicate; + }; + + /** + * History.storeState + * Store a State + * @param {Object} newState + * @return {Object} newState + */ + History.storeState = function(newState){ + // Store the State + History.urlToId[newState.url] = newState.id; + + // Push the State + History.storedStates.push(History.cloneObject(newState)); + + // Return newState + return newState; + }; + + /** + * History.isLastSavedState(newState) + * Tests to see if the state is the last state + * @param {Object} newState + * @return {boolean} isLast + */ + History.isLastSavedState = function(newState){ + // Prepare + var isLast = false, + newId, oldState, oldId; + + // Check + if ( History.savedStates.length ) { + newId = newState.id; + oldState = History.getLastSavedState(); + oldId = oldState.id; + + // Check + isLast = (newId === oldId); + } + + // Return + return isLast; + }; + + /** + * History.saveState + * Push a State + * @param {Object} newState + * @return {boolean} changed + */ + History.saveState = function(newState){ + // Check Hash + if ( History.isLastSavedState(newState) ) { + return false; + } + + // Push the State + History.savedStates.push(History.cloneObject(newState)); + + // Return true + return true; + }; + + /** + * History.getStateByIndex() + * Gets a state by the index + * @param {integer} index + * @return {Object} + */ + History.getStateByIndex = function(index){ + // Prepare + var State = null; + + // Handle + if ( typeof index === 'undefined' ) { + // Get the last inserted + State = History.savedStates[History.savedStates.length-1]; + } + else if ( index < 0 ) { + // Get from the end + State = History.savedStates[History.savedStates.length+index]; + } + else { + // Get from the beginning + State = History.savedStates[index]; + } + + // Return State + return State; + }; + + /** + * History.getCurrentIndex() + * Gets the current index + * @return (integer) + */ + History.getCurrentIndex = function(){ + // Prepare + var index = null; + + // No states saved + if(History.savedStates.length < 1) { + index = 0; + } + else { + index = History.savedStates.length-1; + } + return index; + }; + + // ==================================================================== + // Hash Helpers + + /** + * History.getHash() + * @param {Location=} location + * Gets the current document hash + * Note: unlike location.hash, this is guaranteed to return the escaped hash in all browsers + * @return {string} + */ + History.getHash = function(doc){ + var url = History.getLocationHref(doc), + hash; + hash = History.getHashByUrl(url); + return hash; + }; + + /** + * History.unescapeHash() + * normalize and Unescape a Hash + * @param {String} hash + * @return {string} + */ + History.unescapeHash = function(hash){ + // Prepare + var result = History.normalizeHash(hash); + + // Unescape hash + result = decodeURIComponent(result); + + // Return result + return result; + }; + + /** + * History.normalizeHash() + * normalize a hash across browsers + * @return {string} + */ + History.normalizeHash = function(hash){ + // Prepare + var result = hash.replace(/[^#]*#/,'').replace(/#.*/, ''); + + // Return result + return result; + }; + + /** + * History.setHash(hash) + * Sets the document hash + * @param {string} hash + * @return {History} + */ + History.setHash = function(hash,queue){ + // Prepare + var State, pageUrl; + + // Handle Queueing + if ( queue !== false && History.busy() ) { + // Wait + Push to Queue + //History.debug('History.setHash: we must wait', arguments); + History.pushQueue({ + scope: History, + callback: History.setHash, + args: arguments, + queue: queue + }); + return false; + } + + // Log + //History.debug('History.setHash: called',hash); + + // Make Busy + Continue + History.busy(true); + + // Check if hash is a state + State = History.extractState(hash,true); + if ( State && !History.emulated.pushState ) { + // Hash is a state so skip the setHash + //History.debug('History.setHash: Hash is a state so skipping the hash set with a direct pushState call',arguments); + + // PushState + History.pushState(State.data,State.title,State.url,false); + } + else if ( History.getHash() !== hash ) { + // Hash is a proper hash, so apply it + + // Handle browser bugs + if ( History.bugs.setHash ) { + // Fix Safari Bug https://bugs.webkit.org/show_bug.cgi?id=56249 + + // Fetch the base page + pageUrl = History.getPageUrl(); + + // Safari hash apply + History.pushState(null,null,pageUrl+'#'+hash,false); + } + else { + // Normal hash apply + document.location.hash = hash; + } + } + + // Chain + return History; + }; + + /** + * History.escape() + * normalize and Escape a Hash + * @return {string} + */ + History.escapeHash = function(hash){ + // Prepare + var result = History.normalizeHash(hash); + + // Escape hash + result = window.encodeURIComponent(result); + + // IE6 Escape Bug + if ( !History.bugs.hashEscape ) { + // Restore common parts + result = result + .replace(/\%21/g,'!') + .replace(/\%26/g,'&') + .replace(/\%3D/g,'=') + .replace(/\%3F/g,'?'); + } + + // Return result + return result; + }; + + /** + * History.getHashByUrl(url) + * Extracts the Hash from a URL + * @param {string} url + * @return {string} url + */ + History.getHashByUrl = function(url){ + // Extract the hash + var hash = String(url) + .replace(/([^#]*)#?([^#]*)#?(.*)/, '$2') + ; + + // Unescape hash + hash = History.unescapeHash(hash); + + // Return hash + return hash; + }; + + /** + * History.setTitle(title) + * Applies the title to the document + * @param {State} newState + * @return {Boolean} + */ + History.setTitle = function(newState){ + // Prepare + var title = newState.title, + firstState; + + // Initial + if ( !title ) { + firstState = History.getStateByIndex(0); + if ( firstState && firstState.url === newState.url ) { + title = firstState.title||History.options.initialTitle; + } + } + + // Apply + try { + document.getElementsByTagName('title')[0].innerHTML = title.replace('<','<').replace('>','>').replace(' & ',' & '); + } + catch ( Exception ) { } + document.title = title; + + // Chain + return History; + }; + + + // ==================================================================== + // Queueing + + /** + * History.queues + * The list of queues to use + * First In, First Out + */ + History.queues = []; + + /** + * History.busy(value) + * @param {boolean} value [optional] + * @return {boolean} busy + */ + History.busy = function(value){ + // Apply + if ( typeof value !== 'undefined' ) { + //History.debug('History.busy: changing ['+(History.busy.flag||false)+'] to ['+(value||false)+']', History.queues.length); + History.busy.flag = value; + } + // Default + else if ( typeof History.busy.flag === 'undefined' ) { + History.busy.flag = false; + } + + // Queue + if ( !History.busy.flag ) { + // Execute the next item in the queue + clearTimeout(History.busy.timeout); + var fireNext = function(){ + var i, queue, item; + if ( History.busy.flag ) return; + for ( i=History.queues.length-1; i >= 0; --i ) { + queue = History.queues[i]; + if ( queue.length === 0 ) continue; + item = queue.shift(); + History.fireQueueItem(item); + History.busy.timeout = setTimeout(fireNext,History.options.busyDelay); + } + }; + History.busy.timeout = setTimeout(fireNext,History.options.busyDelay); + } + + // Return + return History.busy.flag; + }; + + /** + * History.busy.flag + */ + History.busy.flag = false; + + /** + * History.fireQueueItem(item) + * Fire a Queue Item + * @param {Object} item + * @return {Mixed} result + */ + History.fireQueueItem = function(item){ + return item.callback.apply(item.scope||History,item.args||[]); + }; + + /** + * History.pushQueue(callback,args) + * Add an item to the queue + * @param {Object} item [scope,callback,args,queue] + */ + History.pushQueue = function(item){ + // Prepare the queue + History.queues[item.queue||0] = History.queues[item.queue||0]||[]; + + // Add to the queue + History.queues[item.queue||0].push(item); + + // Chain + return History; + }; + + /** + * History.queue (item,queue), (func,queue), (func), (item) + * Either firs the item now if not busy, or adds it to the queue + */ + History.queue = function(item,queue){ + // Prepare + if ( typeof item === 'function' ) { + item = { + callback: item + }; + } + if ( typeof queue !== 'undefined' ) { + item.queue = queue; + } + + // Handle + if ( History.busy() ) { + History.pushQueue(item); + } else { + History.fireQueueItem(item); + } + + // Chain + return History; + }; + + /** + * History.clearQueue() + * Clears the Queue + */ + History.clearQueue = function(){ + History.busy.flag = false; + History.queues = []; + return History; + }; + + + // ==================================================================== + // IE Bug Fix + + /** + * History.stateChanged + * States whether or not the state has changed since the last double check was initialised + */ + History.stateChanged = false; + + /** + * History.doubleChecker + * Contains the timeout used for the double checks + */ + History.doubleChecker = false; + + /** + * History.doubleCheckComplete() + * Complete a double check + * @return {History} + */ + History.doubleCheckComplete = function(){ + // Update + History.stateChanged = true; + + // Clear + History.doubleCheckClear(); + + // Chain + return History; + }; + + /** + * History.doubleCheckClear() + * Clear a double check + * @return {History} + */ + History.doubleCheckClear = function(){ + // Clear + if ( History.doubleChecker ) { + clearTimeout(History.doubleChecker); + History.doubleChecker = false; + } + + // Chain + return History; + }; + + /** + * History.doubleCheck() + * Create a double check + * @return {History} + */ + History.doubleCheck = function(tryAgain){ + // Reset + History.stateChanged = false; + History.doubleCheckClear(); + + // Fix IE6,IE7 bug where calling history.back or history.forward does not actually change the hash (whereas doing it manually does) + // Fix Safari 5 bug where sometimes the state does not change: https://bugs.webkit.org/show_bug.cgi?id=42940 + if ( History.bugs.ieDoubleCheck ) { + // Apply Check + History.doubleChecker = setTimeout( + function(){ + History.doubleCheckClear(); + if ( !History.stateChanged ) { + //History.debug('History.doubleCheck: State has not yet changed, trying again', arguments); + // Re-Attempt + tryAgain(); + } + return true; + }, + History.options.doubleCheckInterval + ); + } + + // Chain + return History; + }; + + + // ==================================================================== + // Safari Bug Fix + + /** + * History.safariStatePoll() + * Poll the current state + * @return {History} + */ + History.safariStatePoll = function(){ + // Poll the URL + + // Get the Last State which has the new URL + var + urlState = History.extractState(History.getLocationHref()), + newState; + + // Check for a difference + if ( !History.isLastSavedState(urlState) ) { + newState = urlState; + } + else { + return; + } + + // Check if we have a state with that url + // If not create it + if ( !newState ) { + //History.debug('History.safariStatePoll: new'); + newState = History.createStateObject(); + } + + // Apply the New State + //History.debug('History.safariStatePoll: trigger'); + History.Adapter.trigger(window,'popstate'); + + // Chain + return History; + }; + + + // ==================================================================== + // State Aliases + + /** + * History.back(queue) + * Send the browser history back one item + * @param {Integer} queue [optional] + */ + History.back = function(queue){ + //History.debug('History.back: called', arguments); + + // Handle Queueing + if ( queue !== false && History.busy() ) { + // Wait + Push to Queue + //History.debug('History.back: we must wait', arguments); + History.pushQueue({ + scope: History, + callback: History.back, + args: arguments, + queue: queue + }); + return false; + } + + // Make Busy + Continue + History.busy(true); + + // Fix certain browser bugs that prevent the state from changing + History.doubleCheck(function(){ + History.back(false); + }); + + // Go back + history.go(-1); + + // End back closure + return true; + }; + + /** + * History.forward(queue) + * Send the browser history forward one item + * @param {Integer} queue [optional] + */ + History.forward = function(queue){ + //History.debug('History.forward: called', arguments); + + // Handle Queueing + if ( queue !== false && History.busy() ) { + // Wait + Push to Queue + //History.debug('History.forward: we must wait', arguments); + History.pushQueue({ + scope: History, + callback: History.forward, + args: arguments, + queue: queue + }); + return false; + } + + // Make Busy + Continue + History.busy(true); + + // Fix certain browser bugs that prevent the state from changing + History.doubleCheck(function(){ + History.forward(false); + }); + + // Go forward + history.go(1); + + // End forward closure + return true; + }; + + /** + * History.go(index,queue) + * Send the browser history back or forward index times + * @param {Integer} queue [optional] + */ + History.go = function(index,queue){ + //History.debug('History.go: called', arguments); + + // Prepare + var i; + + // Handle + if ( index > 0 ) { + // Forward + for ( i=1; i<=index; ++i ) { + History.forward(queue); + } + } + else if ( index < 0 ) { + // Backward + for ( i=-1; i>=index; --i ) { + History.back(queue); + } + } + else { + throw new Error('History.go: History.go requires a positive or negative integer passed.'); + } + + // Chain + return History; + }; + + + // ==================================================================== + // HTML5 State Support + + // Non-Native pushState Implementation + if ( History.emulated.pushState ) { + /* + * Provide Skeleton for HTML4 Browsers + */ + + // Prepare + var emptyFunction = function(){}; + History.pushState = History.pushState||emptyFunction; + History.replaceState = History.replaceState||emptyFunction; + } // History.emulated.pushState + + // Native pushState Implementation + else { + /* + * Use native HTML5 History API Implementation + */ + + /** + * History.onPopState(event,extra) + * Refresh the Current State + */ + History.onPopState = function(event,extra){ + // Prepare + var stateId = false, newState = false, currentHash, currentState; + + // Reset the double check + History.doubleCheckComplete(); + + // Check for a Hash, and handle apporiatly + currentHash = History.getHash(); + if ( currentHash ) { + // Expand Hash + currentState = History.extractState(currentHash||History.getLocationHref(),true); + if ( currentState ) { + // We were able to parse it, it must be a State! + // Let's forward to replaceState + //History.debug('History.onPopState: state anchor', currentHash, currentState); + History.replaceState(currentState.data, currentState.title, currentState.url, false); + } + else { + // Traditional Anchor + //History.debug('History.onPopState: traditional anchor', currentHash); + History.Adapter.trigger(window,'anchorchange'); + History.busy(false); + } + + // We don't care for hashes + History.expectedStateId = false; + return false; + } + + // Ensure + stateId = History.Adapter.extractEventData('state',event,extra) || false; + + // Fetch State + if ( stateId ) { + // Vanilla: Back/forward button was used + newState = History.getStateById(stateId); + } + else if ( History.expectedStateId ) { + // Vanilla: A new state was pushed, and popstate was called manually + newState = History.getStateById(History.expectedStateId); + } + else { + // Initial State + newState = History.extractState(History.getLocationHref()); + } + + // The State did not exist in our store + if ( !newState ) { + // Regenerate the State + newState = History.createStateObject(null,null,History.getLocationHref()); + } + + // Clean + History.expectedStateId = false; + + // Check if we are the same state + if ( History.isLastSavedState(newState) ) { + // There has been no change (just the page's hash has finally propagated) + //History.debug('History.onPopState: no change', newState, History.savedStates); + History.busy(false); + return false; + } + + // Store the State + History.storeState(newState); + History.saveState(newState); + + // Force update of the title + History.setTitle(newState); + + // Fire Our Event + History.Adapter.trigger(window,'statechange'); + History.busy(false); + + // Return true + return true; + }; + History.Adapter.bind(window,'popstate',History.onPopState); + + /** + * History.pushState(data,title,url) + * Add a new State to the history object, become it, and trigger onpopstate + * We have to trigger for HTML4 compatibility + * @param {object} data + * @param {string} title + * @param {string} url + * @return {true} + */ + History.pushState = function(data,title,url,queue){ + //History.debug('History.pushState: called', arguments); + + // Check the State + if ( History.getHashByUrl(url) && History.emulated.pushState ) { + throw new Error('History.js does not support states with fragement-identifiers (hashes/anchors).'); + } + + // Handle Queueing + if ( queue !== false && History.busy() ) { + // Wait + Push to Queue + //History.debug('History.pushState: we must wait', arguments); + History.pushQueue({ + scope: History, + callback: History.pushState, + args: arguments, + queue: queue + }); + return false; + } + + // Make Busy + Continue + History.busy(true); + + // Create the newState + var newState = History.createStateObject(data,title,url); + + // Check it + if ( History.isLastSavedState(newState) ) { + // Won't be a change + History.busy(false); + } + else { + // Store the newState + History.storeState(newState); + History.expectedStateId = newState.id; + + // Push the newState + history.pushState(newState.id,newState.title,newState.url); + + // Fire HTML5 Event + History.Adapter.trigger(window,'popstate'); + } + + // End pushState closure + return true; + }; + + /** + * History.replaceState(data,title,url) + * Replace the State and trigger onpopstate + * We have to trigger for HTML4 compatibility + * @param {object} data + * @param {string} title + * @param {string} url + * @return {true} + */ + History.replaceState = function(data,title,url,queue){ + //History.debug('History.replaceState: called', arguments); + + // Check the State + if ( History.getHashByUrl(url) && History.emulated.pushState ) { + throw new Error('History.js does not support states with fragement-identifiers (hashes/anchors).'); + } + + // Handle Queueing + if ( queue !== false && History.busy() ) { + // Wait + Push to Queue + //History.debug('History.replaceState: we must wait', arguments); + History.pushQueue({ + scope: History, + callback: History.replaceState, + args: arguments, + queue: queue + }); + return false; + } + + // Make Busy + Continue + History.busy(true); + + // Create the newState + var newState = History.createStateObject(data,title,url); + + // Check it + if ( History.isLastSavedState(newState) ) { + // Won't be a change + History.busy(false); + } + else { + // Store the newState + History.storeState(newState); + History.expectedStateId = newState.id; + + // Push the newState + history.replaceState(newState.id,newState.title,newState.url); + + // Fire HTML5 Event + History.Adapter.trigger(window,'popstate'); + } + + // End replaceState closure + return true; + }; + + } // !History.emulated.pushState + + + // ==================================================================== + // Initialise + + /** + * Load the Store + */ + if ( sessionStorage ) { + // Fetch + try { + History.store = JSON.parse(sessionStorage.getItem('History.store'))||{}; + } + catch ( err ) { + History.store = {}; + } + + // Normalize + History.normalizeStore(); + } + else { + // Default Load + History.store = {}; + History.normalizeStore(); + } + + /** + * Clear Intervals on exit to prevent memory leaks + */ + History.Adapter.bind(window,"unload",History.clearAllIntervals); + + /** + * Create the initial State + */ + History.saveState(History.storeState(History.extractState(History.getLocationHref(),true))); + + /** + * Bind for Saving Store + */ + if ( sessionStorage ) { + // When the page is closed + History.onUnload = function(){ + // Prepare + var currentStore, item, currentStoreString; + + // Fetch + try { + currentStore = JSON.parse(sessionStorage.getItem('History.store'))||{}; + } + catch ( err ) { + currentStore = {}; + } + + // Ensure + currentStore.idToState = currentStore.idToState || {}; + currentStore.urlToId = currentStore.urlToId || {}; + currentStore.stateToId = currentStore.stateToId || {}; + + // Sync + for ( item in History.idToState ) { + if ( !History.idToState.hasOwnProperty(item) ) { + continue; + } + currentStore.idToState[item] = History.idToState[item]; + } + for ( item in History.urlToId ) { + if ( !History.urlToId.hasOwnProperty(item) ) { + continue; + } + currentStore.urlToId[item] = History.urlToId[item]; + } + for ( item in History.stateToId ) { + if ( !History.stateToId.hasOwnProperty(item) ) { + continue; + } + currentStore.stateToId[item] = History.stateToId[item]; + } + + // Update + History.store = currentStore; + History.normalizeStore(); + + // In Safari, going into Private Browsing mode causes the + // Session Storage object to still exist but if you try and use + // or set any property/function of it it throws the exception + // "QUOTA_EXCEEDED_ERR: DOM Exception 22: An attempt was made to + // add something to storage that exceeded the quota." infinitely + // every second. + currentStoreString = JSON.stringify(currentStore); + try { + // Store + sessionStorage.setItem('History.store', currentStoreString); + } + catch (e) { + if (e.code === DOMException.QUOTA_EXCEEDED_ERR) { + if (sessionStorage.length) { + // Workaround for a bug seen on iPads. Sometimes the quota exceeded error comes up and simply + // removing/resetting the storage can work. + sessionStorage.removeItem('History.store'); + sessionStorage.setItem('History.store', currentStoreString); + } else { + // Otherwise, we're probably private browsing in Safari, so we'll ignore the exception. + } + } else { + throw e; + } + } + }; + + // For Internet Explorer + History.intervalList.push(setInterval(History.onUnload,History.options.storeInterval)); + + // For Other Browsers + History.Adapter.bind(window,'beforeunload',History.onUnload); + History.Adapter.bind(window,'unload',History.onUnload); + + // Both are enabled for consistency + } + + // Non-Native pushState Implementation + if ( !History.emulated.pushState ) { + // Be aware, the following is only for native pushState implementations + // If you are wanting to include something for all browsers + // Then include it above this if block + + /** + * Setup Safari Fix + */ + if ( History.bugs.safariPoll ) { + History.intervalList.push(setInterval(History.safariStatePoll, History.options.safariPollInterval)); + } + + /** + * Ensure Cross Browser Compatibility + */ + if ( navigator.vendor === 'Apple Computer, Inc.' || (navigator.appCodeName||'') === 'Mozilla' ) { + /** + * Fix Safari HashChange Issue + */ + + // Setup Alias + History.Adapter.bind(window,'hashchange',function(){ + History.Adapter.trigger(window,'popstate'); + }); + + // Initialise Alias + if ( History.getHash() ) { + History.Adapter.onDomLoad(function(){ + History.Adapter.trigger(window,'hashchange'); + }); + } + } + + } // !History.emulated.pushState + + + }; // History.initCore + + // Try to Initialise History + if (!History.options || !History.options.delayInit) { + History.init(); + } + +})(window); diff --git a/sites/all/themes/gui/materiobasetheme/bower_components/history.js/scripts/bundled-uncompressed/html5/mootools.history.js b/sites/all/themes/gui/materiobasetheme/bower_components/history.js/scripts/bundled-uncompressed/html5/mootools.history.js new file mode 100644 index 00000000..b5eca0bb --- /dev/null +++ b/sites/all/themes/gui/materiobasetheme/bower_components/history.js/scripts/bundled-uncompressed/html5/mootools.history.js @@ -0,0 +1,2128 @@ +/** + * History.js MooTools Adapter + * @author Benjamin Arthur Lupton + * @copyright 2010-2011 Benjamin Arthur Lupton + * @license New BSD License + */ + +// Closure +(function(window,undefined){ + "use strict"; + + // Localise Globals + var + History = window.History = window.History||{}, + MooTools = window.MooTools, + Element = window.Element; + + // Check Existence + if ( typeof History.Adapter !== 'undefined' ) { + throw new Error('History.js Adapter has already been loaded...'); + } + + // Make MooTools aware of History.js Events + Object.append(Element.NativeEvents,{ + 'popstate':2, + 'hashchange':2 + }); + + // Add the Adapter + History.Adapter = { + /** + * History.Adapter.bind(el,event,callback) + * @param {Element|string} el + * @param {string} event - custom and standard events + * @param {function} callback + * @return {void} + */ + bind: function(el,event,callback){ + var El = typeof el === 'string' ? document.id(el) : el; + El.addEvent(event,callback); + }, + + /** + * History.Adapter.trigger(el,event) + * @param {Element|string} el + * @param {string} event - custom and standard events + * @param {Object=} extra - a object of extra event data (optional) + * @return void + */ + trigger: function(el,event,extra){ + var El = typeof el === 'string' ? document.id(el) : el; + El.fireEvent(event,extra); + }, + + /** + * History.Adapter.extractEventData(key,event,extra) + * @param {string} key - key for the event data to extract + * @param {string} event - custom and standard events + * @return {mixed} + */ + extractEventData: function(key,event){ + // MooTools Native then MooTools Custom + var result = (event && event.event && event.event[key]) || (event && event[key]) || undefined; + + // Return + return result; + }, + + /** + * History.Adapter.onDomLoad(callback) + * @param {function} callback + * @return {void} + */ + onDomLoad: function(callback) { + window.addEvent('domready',callback); + } + }; + + // Try and Initialise History + if ( typeof History.init !== 'undefined' ) { + History.init(); + } + +})(window); +/** + * History.js Core + * @author Benjamin Arthur Lupton + * @copyright 2010-2011 Benjamin Arthur Lupton + * @license New BSD License + */ + +(function(window,undefined){ + "use strict"; + + // ======================================================================== + // Initialise + + // Localise Globals + var + console = window.console||undefined, // Prevent a JSLint complain + document = window.document, // Make sure we are using the correct document + navigator = window.navigator, // Make sure we are using the correct navigator + sessionStorage = window.sessionStorage||false, // sessionStorage + setTimeout = window.setTimeout, + clearTimeout = window.clearTimeout, + setInterval = window.setInterval, + clearInterval = window.clearInterval, + JSON = window.JSON, + alert = window.alert, + History = window.History = window.History||{}, // Public History Object + history = window.history; // Old History Object + + try { + sessionStorage.setItem('TEST', '1'); + sessionStorage.removeItem('TEST'); + } catch(e) { + sessionStorage = false; + } + + // MooTools Compatibility + JSON.stringify = JSON.stringify||JSON.encode; + JSON.parse = JSON.parse||JSON.decode; + + // Check Existence + if ( typeof History.init !== 'undefined' ) { + throw new Error('History.js Core has already been loaded...'); + } + + // Initialise History + History.init = function(options){ + // Check Load Status of Adapter + if ( typeof History.Adapter === 'undefined' ) { + return false; + } + + // Check Load Status of Core + if ( typeof History.initCore !== 'undefined' ) { + History.initCore(); + } + + // Check Load Status of HTML4 Support + if ( typeof History.initHtml4 !== 'undefined' ) { + History.initHtml4(); + } + + // Return true + return true; + }; + + + // ======================================================================== + // Initialise Core + + // Initialise Core + History.initCore = function(options){ + // Initialise + if ( typeof History.initCore.initialized !== 'undefined' ) { + // Already Loaded + return false; + } + else { + History.initCore.initialized = true; + } + + + // ==================================================================== + // Options + + /** + * History.options + * Configurable options + */ + History.options = History.options||{}; + + /** + * History.options.hashChangeInterval + * How long should the interval be before hashchange checks + */ + History.options.hashChangeInterval = History.options.hashChangeInterval || 100; + + /** + * History.options.safariPollInterval + * How long should the interval be before safari poll checks + */ + History.options.safariPollInterval = History.options.safariPollInterval || 500; + + /** + * History.options.doubleCheckInterval + * How long should the interval be before we perform a double check + */ + History.options.doubleCheckInterval = History.options.doubleCheckInterval || 500; + + /** + * History.options.disableSuid + * Force History not to append suid + */ + History.options.disableSuid = History.options.disableSuid || false; + + /** + * History.options.storeInterval + * How long should we wait between store calls + */ + History.options.storeInterval = History.options.storeInterval || 1000; + + /** + * History.options.busyDelay + * How long should we wait between busy events + */ + History.options.busyDelay = History.options.busyDelay || 250; + + /** + * History.options.debug + * If true will enable debug messages to be logged + */ + History.options.debug = History.options.debug || false; + + /** + * History.options.initialTitle + * What is the title of the initial state + */ + History.options.initialTitle = History.options.initialTitle || document.title; + + /** + * History.options.html4Mode + * If true, will force HTMl4 mode (hashtags) + */ + History.options.html4Mode = History.options.html4Mode || false; + + /** + * History.options.delayInit + * Want to override default options and call init manually. + */ + History.options.delayInit = History.options.delayInit || false; + + + // ==================================================================== + // Interval record + + /** + * History.intervalList + * List of intervals set, to be cleared when document is unloaded. + */ + History.intervalList = []; + + /** + * History.clearAllIntervals + * Clears all setInterval instances. + */ + History.clearAllIntervals = function(){ + var i, il = History.intervalList; + if (typeof il !== "undefined" && il !== null) { + for (i = 0; i < il.length; i++) { + clearInterval(il[i]); + } + History.intervalList = null; + } + }; + + + // ==================================================================== + // Debug + + /** + * History.debug(message,...) + * Logs the passed arguments if debug enabled + */ + History.debug = function(){ + if ( (History.options.debug||false) ) { + History.log.apply(History,arguments); + } + }; + + /** + * History.log(message,...) + * Logs the passed arguments + */ + History.log = function(){ + // Prepare + var + consoleExists = !(typeof console === 'undefined' || typeof console.log === 'undefined' || typeof console.log.apply === 'undefined'), + textarea = document.getElementById('log'), + message, + i,n, + args,arg + ; + + // Write to Console + if ( consoleExists ) { + args = Array.prototype.slice.call(arguments); + message = args.shift(); + if ( typeof console.debug !== 'undefined' ) { + console.debug.apply(console,[message,args]); + } + else { + console.log.apply(console,[message,args]); + } + } + else { + message = ("\n"+arguments[0]+"\n"); + } + + // Write to log + for ( i=1,n=arguments.length; i + * @author James Padolsey + */ + History.getInternetExplorerMajorVersion = function(){ + var result = History.getInternetExplorerMajorVersion.cached = + (typeof History.getInternetExplorerMajorVersion.cached !== 'undefined') + ? History.getInternetExplorerMajorVersion.cached + : (function(){ + var v = 3, + div = document.createElement('div'), + all = div.getElementsByTagName('i'); + while ( (div.innerHTML = '') && all[0] ) {} + return (v > 4) ? v : false; + })() + ; + return result; + }; + + /** + * History.isInternetExplorer() + * Are we using Internet Explorer? + * @return {boolean} + * @license Public Domain + * @author Benjamin Arthur Lupton + */ + History.isInternetExplorer = function(){ + var result = + History.isInternetExplorer.cached = + (typeof History.isInternetExplorer.cached !== 'undefined') + ? History.isInternetExplorer.cached + : Boolean(History.getInternetExplorerMajorVersion()) + ; + return result; + }; + + /** + * History.emulated + * Which features require emulating? + */ + + if (History.options.html4Mode) { + History.emulated = { + pushState : true, + hashChange: true + }; + } + + else { + + History.emulated = { + pushState: !Boolean( + window.history && window.history.pushState && window.history.replaceState + && !( + (/ Mobile\/([1-7][a-z]|(8([abcde]|f(1[0-8]))))/i).test(navigator.userAgent) /* disable for versions of iOS before version 4.3 (8F190) */ + || (/AppleWebKit\/5([0-2]|3[0-2])/i).test(navigator.userAgent) /* disable for the mercury iOS browser, or at least older versions of the webkit engine */ + ) + ), + hashChange: Boolean( + !(('onhashchange' in window) || ('onhashchange' in document)) + || + (History.isInternetExplorer() && History.getInternetExplorerMajorVersion() < 8) + ) + }; + } + + /** + * History.enabled + * Is History enabled? + */ + History.enabled = !History.emulated.pushState; + + /** + * History.bugs + * Which bugs are present + */ + History.bugs = { + /** + * Safari 5 and Safari iOS 4 fail to return to the correct state once a hash is replaced by a `replaceState` call + * https://bugs.webkit.org/show_bug.cgi?id=56249 + */ + setHash: Boolean(!History.emulated.pushState && navigator.vendor === 'Apple Computer, Inc.' && /AppleWebKit\/5([0-2]|3[0-3])/.test(navigator.userAgent)), + + /** + * Safari 5 and Safari iOS 4 sometimes fail to apply the state change under busy conditions + * https://bugs.webkit.org/show_bug.cgi?id=42940 + */ + safariPoll: Boolean(!History.emulated.pushState && navigator.vendor === 'Apple Computer, Inc.' && /AppleWebKit\/5([0-2]|3[0-3])/.test(navigator.userAgent)), + + /** + * MSIE 6 and 7 sometimes do not apply a hash even it was told to (requiring a second call to the apply function) + */ + ieDoubleCheck: Boolean(History.isInternetExplorer() && History.getInternetExplorerMajorVersion() < 8), + + /** + * MSIE 6 requires the entire hash to be encoded for the hashes to trigger the onHashChange event + */ + hashEscape: Boolean(History.isInternetExplorer() && History.getInternetExplorerMajorVersion() < 7) + }; + + /** + * History.isEmptyObject(obj) + * Checks to see if the Object is Empty + * @param {Object} obj + * @return {boolean} + */ + History.isEmptyObject = function(obj) { + for ( var name in obj ) { + if ( obj.hasOwnProperty(name) ) { + return false; + } + } + return true; + }; + + /** + * History.cloneObject(obj) + * Clones a object and eliminate all references to the original contexts + * @param {Object} obj + * @return {Object} + */ + History.cloneObject = function(obj) { + var hash,newObj; + if ( obj ) { + hash = JSON.stringify(obj); + newObj = JSON.parse(hash); + } + else { + newObj = {}; + } + return newObj; + }; + + + // ==================================================================== + // URL Helpers + + /** + * History.getRootUrl() + * Turns "http://mysite.com/dir/page.html?asd" into "http://mysite.com" + * @return {String} rootUrl + */ + History.getRootUrl = function(){ + // Create + var rootUrl = document.location.protocol+'//'+(document.location.hostname||document.location.host); + if ( document.location.port||false ) { + rootUrl += ':'+document.location.port; + } + rootUrl += '/'; + + // Return + return rootUrl; + }; + + /** + * History.getBaseHref() + * Fetches the `href` attribute of the `` element if it exists + * @return {String} baseHref + */ + History.getBaseHref = function(){ + // Create + var + baseElements = document.getElementsByTagName('base'), + baseElement = null, + baseHref = ''; + + // Test for Base Element + if ( baseElements.length === 1 ) { + // Prepare for Base Element + baseElement = baseElements[0]; + baseHref = baseElement.href.replace(/[^\/]+$/,''); + } + + // Adjust trailing slash + baseHref = baseHref.replace(/\/+$/,''); + if ( baseHref ) baseHref += '/'; + + // Return + return baseHref; + }; + + /** + * History.getBaseUrl() + * Fetches the baseHref or basePageUrl or rootUrl (whichever one exists first) + * @return {String} baseUrl + */ + History.getBaseUrl = function(){ + // Create + var baseUrl = History.getBaseHref()||History.getBasePageUrl()||History.getRootUrl(); + + // Return + return baseUrl; + }; + + /** + * History.getPageUrl() + * Fetches the URL of the current page + * @return {String} pageUrl + */ + History.getPageUrl = function(){ + // Fetch + var + State = History.getState(false,false), + stateUrl = (State||{}).url||History.getLocationHref(), + pageUrl; + + // Create + pageUrl = stateUrl.replace(/\/+$/,'').replace(/[^\/]+$/,function(part,index,string){ + return (/\./).test(part) ? part : part+'/'; + }); + + // Return + return pageUrl; + }; + + /** + * History.getBasePageUrl() + * Fetches the Url of the directory of the current page + * @return {String} basePageUrl + */ + History.getBasePageUrl = function(){ + // Create + var basePageUrl = (History.getLocationHref()).replace(/[#\?].*/,'').replace(/[^\/]+$/,function(part,index,string){ + return (/[^\/]$/).test(part) ? '' : part; + }).replace(/\/+$/,'')+'/'; + + // Return + return basePageUrl; + }; + + /** + * History.getFullUrl(url) + * Ensures that we have an absolute URL and not a relative URL + * @param {string} url + * @param {Boolean} allowBaseHref + * @return {string} fullUrl + */ + History.getFullUrl = function(url,allowBaseHref){ + // Prepare + var fullUrl = url, firstChar = url.substring(0,1); + allowBaseHref = (typeof allowBaseHref === 'undefined') ? true : allowBaseHref; + + // Check + if ( /[a-z]+\:\/\//.test(url) ) { + // Full URL + } + else if ( firstChar === '/' ) { + // Root URL + fullUrl = History.getRootUrl()+url.replace(/^\/+/,''); + } + else if ( firstChar === '#' ) { + // Anchor URL + fullUrl = History.getPageUrl().replace(/#.*/,'')+url; + } + else if ( firstChar === '?' ) { + // Query URL + fullUrl = History.getPageUrl().replace(/[\?#].*/,'')+url; + } + else { + // Relative URL + if ( allowBaseHref ) { + fullUrl = History.getBaseUrl()+url.replace(/^(\.\/)+/,''); + } else { + fullUrl = History.getBasePageUrl()+url.replace(/^(\.\/)+/,''); + } + // We have an if condition above as we do not want hashes + // which are relative to the baseHref in our URLs + // as if the baseHref changes, then all our bookmarks + // would now point to different locations + // whereas the basePageUrl will always stay the same + } + + // Return + return fullUrl.replace(/\#$/,''); + }; + + /** + * History.getShortUrl(url) + * Ensures that we have a relative URL and not a absolute URL + * @param {string} url + * @return {string} url + */ + History.getShortUrl = function(url){ + // Prepare + var shortUrl = url, baseUrl = History.getBaseUrl(), rootUrl = History.getRootUrl(); + + // Trim baseUrl + if ( History.emulated.pushState ) { + // We are in a if statement as when pushState is not emulated + // The actual url these short urls are relative to can change + // So within the same session, we the url may end up somewhere different + shortUrl = shortUrl.replace(baseUrl,''); + } + + // Trim rootUrl + shortUrl = shortUrl.replace(rootUrl,'/'); + + // Ensure we can still detect it as a state + if ( History.isTraditionalAnchor(shortUrl) ) { + shortUrl = './'+shortUrl; + } + + // Clean It + shortUrl = shortUrl.replace(/^(\.\/)+/g,'./').replace(/\#$/,''); + + // Return + return shortUrl; + }; + + /** + * History.getLocationHref(document) + * Returns a normalized version of document.location.href + * accounting for browser inconsistencies, etc. + * + * This URL will be URI-encoded and will include the hash + * + * @param {object} document + * @return {string} url + */ + History.getLocationHref = function(doc) { + doc = doc || document; + + // most of the time, this will be true + if (doc.URL === doc.location.href) + return doc.location.href; + + // some versions of webkit URI-decode document.location.href + // but they leave document.URL in an encoded state + if (doc.location.href === decodeURIComponent(doc.URL)) + return doc.URL; + + // FF 3.6 only updates document.URL when a page is reloaded + // document.location.href is updated correctly + if (doc.location.hash && decodeURIComponent(doc.location.href.replace(/^[^#]+/, "")) === doc.location.hash) + return doc.location.href; + + if (doc.URL.indexOf('#') == -1 && doc.location.href.indexOf('#') != -1) + return doc.location.href; + + return doc.URL || doc.location.href; + }; + + + // ==================================================================== + // State Storage + + /** + * History.store + * The store for all session specific data + */ + History.store = {}; + + /** + * History.idToState + * 1-1: State ID to State Object + */ + History.idToState = History.idToState||{}; + + /** + * History.stateToId + * 1-1: State String to State ID + */ + History.stateToId = History.stateToId||{}; + + /** + * History.urlToId + * 1-1: State URL to State ID + */ + History.urlToId = History.urlToId||{}; + + /** + * History.storedStates + * Store the states in an array + */ + History.storedStates = History.storedStates||[]; + + /** + * History.savedStates + * Saved the states in an array + */ + History.savedStates = History.savedStates||[]; + + /** + * History.noramlizeStore() + * Noramlize the store by adding necessary values + */ + History.normalizeStore = function(){ + History.store.idToState = History.store.idToState||{}; + History.store.urlToId = History.store.urlToId||{}; + History.store.stateToId = History.store.stateToId||{}; + }; + + /** + * History.getState() + * Get an object containing the data, title and url of the current state + * @param {Boolean} friendly + * @param {Boolean} create + * @return {Object} State + */ + History.getState = function(friendly,create){ + // Prepare + if ( typeof friendly === 'undefined' ) { friendly = true; } + if ( typeof create === 'undefined' ) { create = true; } + + // Fetch + var State = History.getLastSavedState(); + + // Create + if ( !State && create ) { + State = History.createStateObject(); + } + + // Adjust + if ( friendly ) { + State = History.cloneObject(State); + State.url = State.cleanUrl||State.url; + } + + // Return + return State; + }; + + /** + * History.getIdByState(State) + * Gets a ID for a State + * @param {State} newState + * @return {String} id + */ + History.getIdByState = function(newState){ + + // Fetch ID + var id = History.extractId(newState.url), + str; + + if ( !id ) { + // Find ID via State String + str = History.getStateString(newState); + if ( typeof History.stateToId[str] !== 'undefined' ) { + id = History.stateToId[str]; + } + else if ( typeof History.store.stateToId[str] !== 'undefined' ) { + id = History.store.stateToId[str]; + } + else { + // Generate a new ID + while ( true ) { + id = (new Date()).getTime() + String(Math.random()).replace(/\D/g,''); + if ( typeof History.idToState[id] === 'undefined' && typeof History.store.idToState[id] === 'undefined' ) { + break; + } + } + + // Apply the new State to the ID + History.stateToId[str] = id; + History.idToState[id] = newState; + } + } + + // Return ID + return id; + }; + + /** + * History.normalizeState(State) + * Expands a State Object + * @param {object} State + * @return {object} + */ + History.normalizeState = function(oldState){ + // Variables + var newState, dataNotEmpty; + + // Prepare + if ( !oldState || (typeof oldState !== 'object') ) { + oldState = {}; + } + + // Check + if ( typeof oldState.normalized !== 'undefined' ) { + return oldState; + } + + // Adjust + if ( !oldState.data || (typeof oldState.data !== 'object') ) { + oldState.data = {}; + } + + // ---------------------------------------------------------------- + + // Create + newState = {}; + newState.normalized = true; + newState.title = oldState.title||''; + newState.url = History.getFullUrl(oldState.url?oldState.url:(History.getLocationHref())); + newState.hash = History.getShortUrl(newState.url); + newState.data = History.cloneObject(oldState.data); + + // Fetch ID + newState.id = History.getIdByState(newState); + + // ---------------------------------------------------------------- + + // Clean the URL + newState.cleanUrl = newState.url.replace(/\??\&_suid.*/,''); + newState.url = newState.cleanUrl; + + // Check to see if we have more than just a url + dataNotEmpty = !History.isEmptyObject(newState.data); + + // Apply + if ( (newState.title || dataNotEmpty) && History.options.disableSuid !== true ) { + // Add ID to Hash + newState.hash = History.getShortUrl(newState.url).replace(/\??\&_suid.*/,''); + if ( !/\?/.test(newState.hash) ) { + newState.hash += '?'; + } + newState.hash += '&_suid='+newState.id; + } + + // Create the Hashed URL + newState.hashedUrl = History.getFullUrl(newState.hash); + + // ---------------------------------------------------------------- + + // Update the URL if we have a duplicate + if ( (History.emulated.pushState || History.bugs.safariPoll) && History.hasUrlDuplicate(newState) ) { + newState.url = newState.hashedUrl; + } + + // ---------------------------------------------------------------- + + // Return + return newState; + }; + + /** + * History.createStateObject(data,title,url) + * Creates a object based on the data, title and url state params + * @param {object} data + * @param {string} title + * @param {string} url + * @return {object} + */ + History.createStateObject = function(data,title,url){ + // Hashify + var State = { + 'data': data, + 'title': title, + 'url': url + }; + + // Expand the State + State = History.normalizeState(State); + + // Return object + return State; + }; + + /** + * History.getStateById(id) + * Get a state by it's UID + * @param {String} id + */ + History.getStateById = function(id){ + // Prepare + id = String(id); + + // Retrieve + var State = History.idToState[id] || History.store.idToState[id] || undefined; + + // Return State + return State; + }; + + /** + * Get a State's String + * @param {State} passedState + */ + History.getStateString = function(passedState){ + // Prepare + var State, cleanedState, str; + + // Fetch + State = History.normalizeState(passedState); + + // Clean + cleanedState = { + data: State.data, + title: passedState.title, + url: passedState.url + }; + + // Fetch + str = JSON.stringify(cleanedState); + + // Return + return str; + }; + + /** + * Get a State's ID + * @param {State} passedState + * @return {String} id + */ + History.getStateId = function(passedState){ + // Prepare + var State, id; + + // Fetch + State = History.normalizeState(passedState); + + // Fetch + id = State.id; + + // Return + return id; + }; + + /** + * History.getHashByState(State) + * Creates a Hash for the State Object + * @param {State} passedState + * @return {String} hash + */ + History.getHashByState = function(passedState){ + // Prepare + var State, hash; + + // Fetch + State = History.normalizeState(passedState); + + // Hash + hash = State.hash; + + // Return + return hash; + }; + + /** + * History.extractId(url_or_hash) + * Get a State ID by it's URL or Hash + * @param {string} url_or_hash + * @return {string} id + */ + History.extractId = function ( url_or_hash ) { + // Prepare + var id,parts,url, tmp; + + // Extract + + // If the URL has a #, use the id from before the # + if (url_or_hash.indexOf('#') != -1) + { + tmp = url_or_hash.split("#")[0]; + } + else + { + tmp = url_or_hash; + } + + parts = /(.*)\&_suid=([0-9]+)$/.exec(tmp); + url = parts ? (parts[1]||url_or_hash) : url_or_hash; + id = parts ? String(parts[2]||'') : ''; + + // Return + return id||false; + }; + + /** + * History.isTraditionalAnchor + * Checks to see if the url is a traditional anchor or not + * @param {String} url_or_hash + * @return {Boolean} + */ + History.isTraditionalAnchor = function(url_or_hash){ + // Check + var isTraditional = !(/[\/\?\.]/.test(url_or_hash)); + + // Return + return isTraditional; + }; + + /** + * History.extractState + * Get a State by it's URL or Hash + * @param {String} url_or_hash + * @return {State|null} + */ + History.extractState = function(url_or_hash,create){ + // Prepare + var State = null, id, url; + create = create||false; + + // Fetch SUID + id = History.extractId(url_or_hash); + if ( id ) { + State = History.getStateById(id); + } + + // Fetch SUID returned no State + if ( !State ) { + // Fetch URL + url = History.getFullUrl(url_or_hash); + + // Check URL + id = History.getIdByUrl(url)||false; + if ( id ) { + State = History.getStateById(id); + } + + // Create State + if ( !State && create && !History.isTraditionalAnchor(url_or_hash) ) { + State = History.createStateObject(null,null,url); + } + } + + // Return + return State; + }; + + /** + * History.getIdByUrl() + * Get a State ID by a State URL + */ + History.getIdByUrl = function(url){ + // Fetch + var id = History.urlToId[url] || History.store.urlToId[url] || undefined; + + // Return + return id; + }; + + /** + * History.getLastSavedState() + * Get an object containing the data, title and url of the current state + * @return {Object} State + */ + History.getLastSavedState = function(){ + return History.savedStates[History.savedStates.length-1]||undefined; + }; + + /** + * History.getLastStoredState() + * Get an object containing the data, title and url of the current state + * @return {Object} State + */ + History.getLastStoredState = function(){ + return History.storedStates[History.storedStates.length-1]||undefined; + }; + + /** + * History.hasUrlDuplicate + * Checks if a Url will have a url conflict + * @param {Object} newState + * @return {Boolean} hasDuplicate + */ + History.hasUrlDuplicate = function(newState) { + // Prepare + var hasDuplicate = false, + oldState; + + // Fetch + oldState = History.extractState(newState.url); + + // Check + hasDuplicate = oldState && oldState.id !== newState.id; + + // Return + return hasDuplicate; + }; + + /** + * History.storeState + * Store a State + * @param {Object} newState + * @return {Object} newState + */ + History.storeState = function(newState){ + // Store the State + History.urlToId[newState.url] = newState.id; + + // Push the State + History.storedStates.push(History.cloneObject(newState)); + + // Return newState + return newState; + }; + + /** + * History.isLastSavedState(newState) + * Tests to see if the state is the last state + * @param {Object} newState + * @return {boolean} isLast + */ + History.isLastSavedState = function(newState){ + // Prepare + var isLast = false, + newId, oldState, oldId; + + // Check + if ( History.savedStates.length ) { + newId = newState.id; + oldState = History.getLastSavedState(); + oldId = oldState.id; + + // Check + isLast = (newId === oldId); + } + + // Return + return isLast; + }; + + /** + * History.saveState + * Push a State + * @param {Object} newState + * @return {boolean} changed + */ + History.saveState = function(newState){ + // Check Hash + if ( History.isLastSavedState(newState) ) { + return false; + } + + // Push the State + History.savedStates.push(History.cloneObject(newState)); + + // Return true + return true; + }; + + /** + * History.getStateByIndex() + * Gets a state by the index + * @param {integer} index + * @return {Object} + */ + History.getStateByIndex = function(index){ + // Prepare + var State = null; + + // Handle + if ( typeof index === 'undefined' ) { + // Get the last inserted + State = History.savedStates[History.savedStates.length-1]; + } + else if ( index < 0 ) { + // Get from the end + State = History.savedStates[History.savedStates.length+index]; + } + else { + // Get from the beginning + State = History.savedStates[index]; + } + + // Return State + return State; + }; + + /** + * History.getCurrentIndex() + * Gets the current index + * @return (integer) + */ + History.getCurrentIndex = function(){ + // Prepare + var index = null; + + // No states saved + if(History.savedStates.length < 1) { + index = 0; + } + else { + index = History.savedStates.length-1; + } + return index; + }; + + // ==================================================================== + // Hash Helpers + + /** + * History.getHash() + * @param {Location=} location + * Gets the current document hash + * Note: unlike location.hash, this is guaranteed to return the escaped hash in all browsers + * @return {string} + */ + History.getHash = function(doc){ + var url = History.getLocationHref(doc), + hash; + hash = History.getHashByUrl(url); + return hash; + }; + + /** + * History.unescapeHash() + * normalize and Unescape a Hash + * @param {String} hash + * @return {string} + */ + History.unescapeHash = function(hash){ + // Prepare + var result = History.normalizeHash(hash); + + // Unescape hash + result = decodeURIComponent(result); + + // Return result + return result; + }; + + /** + * History.normalizeHash() + * normalize a hash across browsers + * @return {string} + */ + History.normalizeHash = function(hash){ + // Prepare + var result = hash.replace(/[^#]*#/,'').replace(/#.*/, ''); + + // Return result + return result; + }; + + /** + * History.setHash(hash) + * Sets the document hash + * @param {string} hash + * @return {History} + */ + History.setHash = function(hash,queue){ + // Prepare + var State, pageUrl; + + // Handle Queueing + if ( queue !== false && History.busy() ) { + // Wait + Push to Queue + //History.debug('History.setHash: we must wait', arguments); + History.pushQueue({ + scope: History, + callback: History.setHash, + args: arguments, + queue: queue + }); + return false; + } + + // Log + //History.debug('History.setHash: called',hash); + + // Make Busy + Continue + History.busy(true); + + // Check if hash is a state + State = History.extractState(hash,true); + if ( State && !History.emulated.pushState ) { + // Hash is a state so skip the setHash + //History.debug('History.setHash: Hash is a state so skipping the hash set with a direct pushState call',arguments); + + // PushState + History.pushState(State.data,State.title,State.url,false); + } + else if ( History.getHash() !== hash ) { + // Hash is a proper hash, so apply it + + // Handle browser bugs + if ( History.bugs.setHash ) { + // Fix Safari Bug https://bugs.webkit.org/show_bug.cgi?id=56249 + + // Fetch the base page + pageUrl = History.getPageUrl(); + + // Safari hash apply + History.pushState(null,null,pageUrl+'#'+hash,false); + } + else { + // Normal hash apply + document.location.hash = hash; + } + } + + // Chain + return History; + }; + + /** + * History.escape() + * normalize and Escape a Hash + * @return {string} + */ + History.escapeHash = function(hash){ + // Prepare + var result = History.normalizeHash(hash); + + // Escape hash + result = window.encodeURIComponent(result); + + // IE6 Escape Bug + if ( !History.bugs.hashEscape ) { + // Restore common parts + result = result + .replace(/\%21/g,'!') + .replace(/\%26/g,'&') + .replace(/\%3D/g,'=') + .replace(/\%3F/g,'?'); + } + + // Return result + return result; + }; + + /** + * History.getHashByUrl(url) + * Extracts the Hash from a URL + * @param {string} url + * @return {string} url + */ + History.getHashByUrl = function(url){ + // Extract the hash + var hash = String(url) + .replace(/([^#]*)#?([^#]*)#?(.*)/, '$2') + ; + + // Unescape hash + hash = History.unescapeHash(hash); + + // Return hash + return hash; + }; + + /** + * History.setTitle(title) + * Applies the title to the document + * @param {State} newState + * @return {Boolean} + */ + History.setTitle = function(newState){ + // Prepare + var title = newState.title, + firstState; + + // Initial + if ( !title ) { + firstState = History.getStateByIndex(0); + if ( firstState && firstState.url === newState.url ) { + title = firstState.title||History.options.initialTitle; + } + } + + // Apply + try { + document.getElementsByTagName('title')[0].innerHTML = title.replace('<','<').replace('>','>').replace(' & ',' & '); + } + catch ( Exception ) { } + document.title = title; + + // Chain + return History; + }; + + + // ==================================================================== + // Queueing + + /** + * History.queues + * The list of queues to use + * First In, First Out + */ + History.queues = []; + + /** + * History.busy(value) + * @param {boolean} value [optional] + * @return {boolean} busy + */ + History.busy = function(value){ + // Apply + if ( typeof value !== 'undefined' ) { + //History.debug('History.busy: changing ['+(History.busy.flag||false)+'] to ['+(value||false)+']', History.queues.length); + History.busy.flag = value; + } + // Default + else if ( typeof History.busy.flag === 'undefined' ) { + History.busy.flag = false; + } + + // Queue + if ( !History.busy.flag ) { + // Execute the next item in the queue + clearTimeout(History.busy.timeout); + var fireNext = function(){ + var i, queue, item; + if ( History.busy.flag ) return; + for ( i=History.queues.length-1; i >= 0; --i ) { + queue = History.queues[i]; + if ( queue.length === 0 ) continue; + item = queue.shift(); + History.fireQueueItem(item); + History.busy.timeout = setTimeout(fireNext,History.options.busyDelay); + } + }; + History.busy.timeout = setTimeout(fireNext,History.options.busyDelay); + } + + // Return + return History.busy.flag; + }; + + /** + * History.busy.flag + */ + History.busy.flag = false; + + /** + * History.fireQueueItem(item) + * Fire a Queue Item + * @param {Object} item + * @return {Mixed} result + */ + History.fireQueueItem = function(item){ + return item.callback.apply(item.scope||History,item.args||[]); + }; + + /** + * History.pushQueue(callback,args) + * Add an item to the queue + * @param {Object} item [scope,callback,args,queue] + */ + History.pushQueue = function(item){ + // Prepare the queue + History.queues[item.queue||0] = History.queues[item.queue||0]||[]; + + // Add to the queue + History.queues[item.queue||0].push(item); + + // Chain + return History; + }; + + /** + * History.queue (item,queue), (func,queue), (func), (item) + * Either firs the item now if not busy, or adds it to the queue + */ + History.queue = function(item,queue){ + // Prepare + if ( typeof item === 'function' ) { + item = { + callback: item + }; + } + if ( typeof queue !== 'undefined' ) { + item.queue = queue; + } + + // Handle + if ( History.busy() ) { + History.pushQueue(item); + } else { + History.fireQueueItem(item); + } + + // Chain + return History; + }; + + /** + * History.clearQueue() + * Clears the Queue + */ + History.clearQueue = function(){ + History.busy.flag = false; + History.queues = []; + return History; + }; + + + // ==================================================================== + // IE Bug Fix + + /** + * History.stateChanged + * States whether or not the state has changed since the last double check was initialised + */ + History.stateChanged = false; + + /** + * History.doubleChecker + * Contains the timeout used for the double checks + */ + History.doubleChecker = false; + + /** + * History.doubleCheckComplete() + * Complete a double check + * @return {History} + */ + History.doubleCheckComplete = function(){ + // Update + History.stateChanged = true; + + // Clear + History.doubleCheckClear(); + + // Chain + return History; + }; + + /** + * History.doubleCheckClear() + * Clear a double check + * @return {History} + */ + History.doubleCheckClear = function(){ + // Clear + if ( History.doubleChecker ) { + clearTimeout(History.doubleChecker); + History.doubleChecker = false; + } + + // Chain + return History; + }; + + /** + * History.doubleCheck() + * Create a double check + * @return {History} + */ + History.doubleCheck = function(tryAgain){ + // Reset + History.stateChanged = false; + History.doubleCheckClear(); + + // Fix IE6,IE7 bug where calling history.back or history.forward does not actually change the hash (whereas doing it manually does) + // Fix Safari 5 bug where sometimes the state does not change: https://bugs.webkit.org/show_bug.cgi?id=42940 + if ( History.bugs.ieDoubleCheck ) { + // Apply Check + History.doubleChecker = setTimeout( + function(){ + History.doubleCheckClear(); + if ( !History.stateChanged ) { + //History.debug('History.doubleCheck: State has not yet changed, trying again', arguments); + // Re-Attempt + tryAgain(); + } + return true; + }, + History.options.doubleCheckInterval + ); + } + + // Chain + return History; + }; + + + // ==================================================================== + // Safari Bug Fix + + /** + * History.safariStatePoll() + * Poll the current state + * @return {History} + */ + History.safariStatePoll = function(){ + // Poll the URL + + // Get the Last State which has the new URL + var + urlState = History.extractState(History.getLocationHref()), + newState; + + // Check for a difference + if ( !History.isLastSavedState(urlState) ) { + newState = urlState; + } + else { + return; + } + + // Check if we have a state with that url + // If not create it + if ( !newState ) { + //History.debug('History.safariStatePoll: new'); + newState = History.createStateObject(); + } + + // Apply the New State + //History.debug('History.safariStatePoll: trigger'); + History.Adapter.trigger(window,'popstate'); + + // Chain + return History; + }; + + + // ==================================================================== + // State Aliases + + /** + * History.back(queue) + * Send the browser history back one item + * @param {Integer} queue [optional] + */ + History.back = function(queue){ + //History.debug('History.back: called', arguments); + + // Handle Queueing + if ( queue !== false && History.busy() ) { + // Wait + Push to Queue + //History.debug('History.back: we must wait', arguments); + History.pushQueue({ + scope: History, + callback: History.back, + args: arguments, + queue: queue + }); + return false; + } + + // Make Busy + Continue + History.busy(true); + + // Fix certain browser bugs that prevent the state from changing + History.doubleCheck(function(){ + History.back(false); + }); + + // Go back + history.go(-1); + + // End back closure + return true; + }; + + /** + * History.forward(queue) + * Send the browser history forward one item + * @param {Integer} queue [optional] + */ + History.forward = function(queue){ + //History.debug('History.forward: called', arguments); + + // Handle Queueing + if ( queue !== false && History.busy() ) { + // Wait + Push to Queue + //History.debug('History.forward: we must wait', arguments); + History.pushQueue({ + scope: History, + callback: History.forward, + args: arguments, + queue: queue + }); + return false; + } + + // Make Busy + Continue + History.busy(true); + + // Fix certain browser bugs that prevent the state from changing + History.doubleCheck(function(){ + History.forward(false); + }); + + // Go forward + history.go(1); + + // End forward closure + return true; + }; + + /** + * History.go(index,queue) + * Send the browser history back or forward index times + * @param {Integer} queue [optional] + */ + History.go = function(index,queue){ + //History.debug('History.go: called', arguments); + + // Prepare + var i; + + // Handle + if ( index > 0 ) { + // Forward + for ( i=1; i<=index; ++i ) { + History.forward(queue); + } + } + else if ( index < 0 ) { + // Backward + for ( i=-1; i>=index; --i ) { + History.back(queue); + } + } + else { + throw new Error('History.go: History.go requires a positive or negative integer passed.'); + } + + // Chain + return History; + }; + + + // ==================================================================== + // HTML5 State Support + + // Non-Native pushState Implementation + if ( History.emulated.pushState ) { + /* + * Provide Skeleton for HTML4 Browsers + */ + + // Prepare + var emptyFunction = function(){}; + History.pushState = History.pushState||emptyFunction; + History.replaceState = History.replaceState||emptyFunction; + } // History.emulated.pushState + + // Native pushState Implementation + else { + /* + * Use native HTML5 History API Implementation + */ + + /** + * History.onPopState(event,extra) + * Refresh the Current State + */ + History.onPopState = function(event,extra){ + // Prepare + var stateId = false, newState = false, currentHash, currentState; + + // Reset the double check + History.doubleCheckComplete(); + + // Check for a Hash, and handle apporiatly + currentHash = History.getHash(); + if ( currentHash ) { + // Expand Hash + currentState = History.extractState(currentHash||History.getLocationHref(),true); + if ( currentState ) { + // We were able to parse it, it must be a State! + // Let's forward to replaceState + //History.debug('History.onPopState: state anchor', currentHash, currentState); + History.replaceState(currentState.data, currentState.title, currentState.url, false); + } + else { + // Traditional Anchor + //History.debug('History.onPopState: traditional anchor', currentHash); + History.Adapter.trigger(window,'anchorchange'); + History.busy(false); + } + + // We don't care for hashes + History.expectedStateId = false; + return false; + } + + // Ensure + stateId = History.Adapter.extractEventData('state',event,extra) || false; + + // Fetch State + if ( stateId ) { + // Vanilla: Back/forward button was used + newState = History.getStateById(stateId); + } + else if ( History.expectedStateId ) { + // Vanilla: A new state was pushed, and popstate was called manually + newState = History.getStateById(History.expectedStateId); + } + else { + // Initial State + newState = History.extractState(History.getLocationHref()); + } + + // The State did not exist in our store + if ( !newState ) { + // Regenerate the State + newState = History.createStateObject(null,null,History.getLocationHref()); + } + + // Clean + History.expectedStateId = false; + + // Check if we are the same state + if ( History.isLastSavedState(newState) ) { + // There has been no change (just the page's hash has finally propagated) + //History.debug('History.onPopState: no change', newState, History.savedStates); + History.busy(false); + return false; + } + + // Store the State + History.storeState(newState); + History.saveState(newState); + + // Force update of the title + History.setTitle(newState); + + // Fire Our Event + History.Adapter.trigger(window,'statechange'); + History.busy(false); + + // Return true + return true; + }; + History.Adapter.bind(window,'popstate',History.onPopState); + + /** + * History.pushState(data,title,url) + * Add a new State to the history object, become it, and trigger onpopstate + * We have to trigger for HTML4 compatibility + * @param {object} data + * @param {string} title + * @param {string} url + * @return {true} + */ + History.pushState = function(data,title,url,queue){ + //History.debug('History.pushState: called', arguments); + + // Check the State + if ( History.getHashByUrl(url) && History.emulated.pushState ) { + throw new Error('History.js does not support states with fragement-identifiers (hashes/anchors).'); + } + + // Handle Queueing + if ( queue !== false && History.busy() ) { + // Wait + Push to Queue + //History.debug('History.pushState: we must wait', arguments); + History.pushQueue({ + scope: History, + callback: History.pushState, + args: arguments, + queue: queue + }); + return false; + } + + // Make Busy + Continue + History.busy(true); + + // Create the newState + var newState = History.createStateObject(data,title,url); + + // Check it + if ( History.isLastSavedState(newState) ) { + // Won't be a change + History.busy(false); + } + else { + // Store the newState + History.storeState(newState); + History.expectedStateId = newState.id; + + // Push the newState + history.pushState(newState.id,newState.title,newState.url); + + // Fire HTML5 Event + History.Adapter.trigger(window,'popstate'); + } + + // End pushState closure + return true; + }; + + /** + * History.replaceState(data,title,url) + * Replace the State and trigger onpopstate + * We have to trigger for HTML4 compatibility + * @param {object} data + * @param {string} title + * @param {string} url + * @return {true} + */ + History.replaceState = function(data,title,url,queue){ + //History.debug('History.replaceState: called', arguments); + + // Check the State + if ( History.getHashByUrl(url) && History.emulated.pushState ) { + throw new Error('History.js does not support states with fragement-identifiers (hashes/anchors).'); + } + + // Handle Queueing + if ( queue !== false && History.busy() ) { + // Wait + Push to Queue + //History.debug('History.replaceState: we must wait', arguments); + History.pushQueue({ + scope: History, + callback: History.replaceState, + args: arguments, + queue: queue + }); + return false; + } + + // Make Busy + Continue + History.busy(true); + + // Create the newState + var newState = History.createStateObject(data,title,url); + + // Check it + if ( History.isLastSavedState(newState) ) { + // Won't be a change + History.busy(false); + } + else { + // Store the newState + History.storeState(newState); + History.expectedStateId = newState.id; + + // Push the newState + history.replaceState(newState.id,newState.title,newState.url); + + // Fire HTML5 Event + History.Adapter.trigger(window,'popstate'); + } + + // End replaceState closure + return true; + }; + + } // !History.emulated.pushState + + + // ==================================================================== + // Initialise + + /** + * Load the Store + */ + if ( sessionStorage ) { + // Fetch + try { + History.store = JSON.parse(sessionStorage.getItem('History.store'))||{}; + } + catch ( err ) { + History.store = {}; + } + + // Normalize + History.normalizeStore(); + } + else { + // Default Load + History.store = {}; + History.normalizeStore(); + } + + /** + * Clear Intervals on exit to prevent memory leaks + */ + History.Adapter.bind(window,"unload",History.clearAllIntervals); + + /** + * Create the initial State + */ + History.saveState(History.storeState(History.extractState(History.getLocationHref(),true))); + + /** + * Bind for Saving Store + */ + if ( sessionStorage ) { + // When the page is closed + History.onUnload = function(){ + // Prepare + var currentStore, item, currentStoreString; + + // Fetch + try { + currentStore = JSON.parse(sessionStorage.getItem('History.store'))||{}; + } + catch ( err ) { + currentStore = {}; + } + + // Ensure + currentStore.idToState = currentStore.idToState || {}; + currentStore.urlToId = currentStore.urlToId || {}; + currentStore.stateToId = currentStore.stateToId || {}; + + // Sync + for ( item in History.idToState ) { + if ( !History.idToState.hasOwnProperty(item) ) { + continue; + } + currentStore.idToState[item] = History.idToState[item]; + } + for ( item in History.urlToId ) { + if ( !History.urlToId.hasOwnProperty(item) ) { + continue; + } + currentStore.urlToId[item] = History.urlToId[item]; + } + for ( item in History.stateToId ) { + if ( !History.stateToId.hasOwnProperty(item) ) { + continue; + } + currentStore.stateToId[item] = History.stateToId[item]; + } + + // Update + History.store = currentStore; + History.normalizeStore(); + + // In Safari, going into Private Browsing mode causes the + // Session Storage object to still exist but if you try and use + // or set any property/function of it it throws the exception + // "QUOTA_EXCEEDED_ERR: DOM Exception 22: An attempt was made to + // add something to storage that exceeded the quota." infinitely + // every second. + currentStoreString = JSON.stringify(currentStore); + try { + // Store + sessionStorage.setItem('History.store', currentStoreString); + } + catch (e) { + if (e.code === DOMException.QUOTA_EXCEEDED_ERR) { + if (sessionStorage.length) { + // Workaround for a bug seen on iPads. Sometimes the quota exceeded error comes up and simply + // removing/resetting the storage can work. + sessionStorage.removeItem('History.store'); + sessionStorage.setItem('History.store', currentStoreString); + } else { + // Otherwise, we're probably private browsing in Safari, so we'll ignore the exception. + } + } else { + throw e; + } + } + }; + + // For Internet Explorer + History.intervalList.push(setInterval(History.onUnload,History.options.storeInterval)); + + // For Other Browsers + History.Adapter.bind(window,'beforeunload',History.onUnload); + History.Adapter.bind(window,'unload',History.onUnload); + + // Both are enabled for consistency + } + + // Non-Native pushState Implementation + if ( !History.emulated.pushState ) { + // Be aware, the following is only for native pushState implementations + // If you are wanting to include something for all browsers + // Then include it above this if block + + /** + * Setup Safari Fix + */ + if ( History.bugs.safariPoll ) { + History.intervalList.push(setInterval(History.safariStatePoll, History.options.safariPollInterval)); + } + + /** + * Ensure Cross Browser Compatibility + */ + if ( navigator.vendor === 'Apple Computer, Inc.' || (navigator.appCodeName||'') === 'Mozilla' ) { + /** + * Fix Safari HashChange Issue + */ + + // Setup Alias + History.Adapter.bind(window,'hashchange',function(){ + History.Adapter.trigger(window,'popstate'); + }); + + // Initialise Alias + if ( History.getHash() ) { + History.Adapter.onDomLoad(function(){ + History.Adapter.trigger(window,'hashchange'); + }); + } + } + + } // !History.emulated.pushState + + + }; // History.initCore + + // Try to Initialise History + if (!History.options || !History.options.delayInit) { + History.init(); + } + +})(window); diff --git a/sites/all/themes/gui/materiobasetheme/bower_components/history.js/scripts/bundled-uncompressed/html5/native.history.js b/sites/all/themes/gui/materiobasetheme/bower_components/history.js/scripts/bundled-uncompressed/html5/native.history.js new file mode 100644 index 00000000..f87e3f41 --- /dev/null +++ b/sites/all/themes/gui/materiobasetheme/bower_components/history.js/scripts/bundled-uncompressed/html5/native.history.js @@ -0,0 +1,2165 @@ +/** + * History.js Native Adapter + * @author Benjamin Arthur Lupton + * @copyright 2010-2011 Benjamin Arthur Lupton + * @license New BSD License + */ + +// Closure +(function(window,undefined){ + "use strict"; + + // Localise Globals + var History = window.History = window.History||{}; + + // Check Existence + if ( typeof History.Adapter !== 'undefined' ) { + throw new Error('History.js Adapter has already been loaded...'); + } + + // Add the Adapter + History.Adapter = { + /** + * History.Adapter.handlers[uid][eventName] = Array + */ + handlers: {}, + + /** + * History.Adapter._uid + * The current element unique identifier + */ + _uid: 1, + + /** + * History.Adapter.uid(element) + * @param {Element} element + * @return {String} uid + */ + uid: function(element){ + return element._uid || (element._uid = History.Adapter._uid++); + }, + + /** + * History.Adapter.bind(el,event,callback) + * @param {Element} element + * @param {String} eventName - custom and standard events + * @param {Function} callback + * @return + */ + bind: function(element,eventName,callback){ + // Prepare + var uid = History.Adapter.uid(element); + + // Apply Listener + History.Adapter.handlers[uid] = History.Adapter.handlers[uid] || {}; + History.Adapter.handlers[uid][eventName] = History.Adapter.handlers[uid][eventName] || []; + History.Adapter.handlers[uid][eventName].push(callback); + + // Bind Global Listener + element['on'+eventName] = (function(element,eventName){ + return function(event){ + History.Adapter.trigger(element,eventName,event); + }; + })(element,eventName); + }, + + /** + * History.Adapter.trigger(el,event) + * @param {Element} element + * @param {String} eventName - custom and standard events + * @param {Object} event - a object of event data + * @return + */ + trigger: function(element,eventName,event){ + // Prepare + event = event || {}; + var uid = History.Adapter.uid(element), + i,n; + + // Apply Listener + History.Adapter.handlers[uid] = History.Adapter.handlers[uid] || {}; + History.Adapter.handlers[uid][eventName] = History.Adapter.handlers[uid][eventName] || []; + + // Fire Listeners + for ( i=0,n=History.Adapter.handlers[uid][eventName].length; i + * @copyright 2010-2011 Benjamin Arthur Lupton + * @license New BSD License + */ + +(function(window,undefined){ + "use strict"; + + // ======================================================================== + // Initialise + + // Localise Globals + var + console = window.console||undefined, // Prevent a JSLint complain + document = window.document, // Make sure we are using the correct document + navigator = window.navigator, // Make sure we are using the correct navigator + sessionStorage = window.sessionStorage||false, // sessionStorage + setTimeout = window.setTimeout, + clearTimeout = window.clearTimeout, + setInterval = window.setInterval, + clearInterval = window.clearInterval, + JSON = window.JSON, + alert = window.alert, + History = window.History = window.History||{}, // Public History Object + history = window.history; // Old History Object + + try { + sessionStorage.setItem('TEST', '1'); + sessionStorage.removeItem('TEST'); + } catch(e) { + sessionStorage = false; + } + + // MooTools Compatibility + JSON.stringify = JSON.stringify||JSON.encode; + JSON.parse = JSON.parse||JSON.decode; + + // Check Existence + if ( typeof History.init !== 'undefined' ) { + throw new Error('History.js Core has already been loaded...'); + } + + // Initialise History + History.init = function(options){ + // Check Load Status of Adapter + if ( typeof History.Adapter === 'undefined' ) { + return false; + } + + // Check Load Status of Core + if ( typeof History.initCore !== 'undefined' ) { + History.initCore(); + } + + // Check Load Status of HTML4 Support + if ( typeof History.initHtml4 !== 'undefined' ) { + History.initHtml4(); + } + + // Return true + return true; + }; + + + // ======================================================================== + // Initialise Core + + // Initialise Core + History.initCore = function(options){ + // Initialise + if ( typeof History.initCore.initialized !== 'undefined' ) { + // Already Loaded + return false; + } + else { + History.initCore.initialized = true; + } + + + // ==================================================================== + // Options + + /** + * History.options + * Configurable options + */ + History.options = History.options||{}; + + /** + * History.options.hashChangeInterval + * How long should the interval be before hashchange checks + */ + History.options.hashChangeInterval = History.options.hashChangeInterval || 100; + + /** + * History.options.safariPollInterval + * How long should the interval be before safari poll checks + */ + History.options.safariPollInterval = History.options.safariPollInterval || 500; + + /** + * History.options.doubleCheckInterval + * How long should the interval be before we perform a double check + */ + History.options.doubleCheckInterval = History.options.doubleCheckInterval || 500; + + /** + * History.options.disableSuid + * Force History not to append suid + */ + History.options.disableSuid = History.options.disableSuid || false; + + /** + * History.options.storeInterval + * How long should we wait between store calls + */ + History.options.storeInterval = History.options.storeInterval || 1000; + + /** + * History.options.busyDelay + * How long should we wait between busy events + */ + History.options.busyDelay = History.options.busyDelay || 250; + + /** + * History.options.debug + * If true will enable debug messages to be logged + */ + History.options.debug = History.options.debug || false; + + /** + * History.options.initialTitle + * What is the title of the initial state + */ + History.options.initialTitle = History.options.initialTitle || document.title; + + /** + * History.options.html4Mode + * If true, will force HTMl4 mode (hashtags) + */ + History.options.html4Mode = History.options.html4Mode || false; + + /** + * History.options.delayInit + * Want to override default options and call init manually. + */ + History.options.delayInit = History.options.delayInit || false; + + + // ==================================================================== + // Interval record + + /** + * History.intervalList + * List of intervals set, to be cleared when document is unloaded. + */ + History.intervalList = []; + + /** + * History.clearAllIntervals + * Clears all setInterval instances. + */ + History.clearAllIntervals = function(){ + var i, il = History.intervalList; + if (typeof il !== "undefined" && il !== null) { + for (i = 0; i < il.length; i++) { + clearInterval(il[i]); + } + History.intervalList = null; + } + }; + + + // ==================================================================== + // Debug + + /** + * History.debug(message,...) + * Logs the passed arguments if debug enabled + */ + History.debug = function(){ + if ( (History.options.debug||false) ) { + History.log.apply(History,arguments); + } + }; + + /** + * History.log(message,...) + * Logs the passed arguments + */ + History.log = function(){ + // Prepare + var + consoleExists = !(typeof console === 'undefined' || typeof console.log === 'undefined' || typeof console.log.apply === 'undefined'), + textarea = document.getElementById('log'), + message, + i,n, + args,arg + ; + + // Write to Console + if ( consoleExists ) { + args = Array.prototype.slice.call(arguments); + message = args.shift(); + if ( typeof console.debug !== 'undefined' ) { + console.debug.apply(console,[message,args]); + } + else { + console.log.apply(console,[message,args]); + } + } + else { + message = ("\n"+arguments[0]+"\n"); + } + + // Write to log + for ( i=1,n=arguments.length; i + * @author James Padolsey + */ + History.getInternetExplorerMajorVersion = function(){ + var result = History.getInternetExplorerMajorVersion.cached = + (typeof History.getInternetExplorerMajorVersion.cached !== 'undefined') + ? History.getInternetExplorerMajorVersion.cached + : (function(){ + var v = 3, + div = document.createElement('div'), + all = div.getElementsByTagName('i'); + while ( (div.innerHTML = '') && all[0] ) {} + return (v > 4) ? v : false; + })() + ; + return result; + }; + + /** + * History.isInternetExplorer() + * Are we using Internet Explorer? + * @return {boolean} + * @license Public Domain + * @author Benjamin Arthur Lupton + */ + History.isInternetExplorer = function(){ + var result = + History.isInternetExplorer.cached = + (typeof History.isInternetExplorer.cached !== 'undefined') + ? History.isInternetExplorer.cached + : Boolean(History.getInternetExplorerMajorVersion()) + ; + return result; + }; + + /** + * History.emulated + * Which features require emulating? + */ + + if (History.options.html4Mode) { + History.emulated = { + pushState : true, + hashChange: true + }; + } + + else { + + History.emulated = { + pushState: !Boolean( + window.history && window.history.pushState && window.history.replaceState + && !( + (/ Mobile\/([1-7][a-z]|(8([abcde]|f(1[0-8]))))/i).test(navigator.userAgent) /* disable for versions of iOS before version 4.3 (8F190) */ + || (/AppleWebKit\/5([0-2]|3[0-2])/i).test(navigator.userAgent) /* disable for the mercury iOS browser, or at least older versions of the webkit engine */ + ) + ), + hashChange: Boolean( + !(('onhashchange' in window) || ('onhashchange' in document)) + || + (History.isInternetExplorer() && History.getInternetExplorerMajorVersion() < 8) + ) + }; + } + + /** + * History.enabled + * Is History enabled? + */ + History.enabled = !History.emulated.pushState; + + /** + * History.bugs + * Which bugs are present + */ + History.bugs = { + /** + * Safari 5 and Safari iOS 4 fail to return to the correct state once a hash is replaced by a `replaceState` call + * https://bugs.webkit.org/show_bug.cgi?id=56249 + */ + setHash: Boolean(!History.emulated.pushState && navigator.vendor === 'Apple Computer, Inc.' && /AppleWebKit\/5([0-2]|3[0-3])/.test(navigator.userAgent)), + + /** + * Safari 5 and Safari iOS 4 sometimes fail to apply the state change under busy conditions + * https://bugs.webkit.org/show_bug.cgi?id=42940 + */ + safariPoll: Boolean(!History.emulated.pushState && navigator.vendor === 'Apple Computer, Inc.' && /AppleWebKit\/5([0-2]|3[0-3])/.test(navigator.userAgent)), + + /** + * MSIE 6 and 7 sometimes do not apply a hash even it was told to (requiring a second call to the apply function) + */ + ieDoubleCheck: Boolean(History.isInternetExplorer() && History.getInternetExplorerMajorVersion() < 8), + + /** + * MSIE 6 requires the entire hash to be encoded for the hashes to trigger the onHashChange event + */ + hashEscape: Boolean(History.isInternetExplorer() && History.getInternetExplorerMajorVersion() < 7) + }; + + /** + * History.isEmptyObject(obj) + * Checks to see if the Object is Empty + * @param {Object} obj + * @return {boolean} + */ + History.isEmptyObject = function(obj) { + for ( var name in obj ) { + if ( obj.hasOwnProperty(name) ) { + return false; + } + } + return true; + }; + + /** + * History.cloneObject(obj) + * Clones a object and eliminate all references to the original contexts + * @param {Object} obj + * @return {Object} + */ + History.cloneObject = function(obj) { + var hash,newObj; + if ( obj ) { + hash = JSON.stringify(obj); + newObj = JSON.parse(hash); + } + else { + newObj = {}; + } + return newObj; + }; + + + // ==================================================================== + // URL Helpers + + /** + * History.getRootUrl() + * Turns "http://mysite.com/dir/page.html?asd" into "http://mysite.com" + * @return {String} rootUrl + */ + History.getRootUrl = function(){ + // Create + var rootUrl = document.location.protocol+'//'+(document.location.hostname||document.location.host); + if ( document.location.port||false ) { + rootUrl += ':'+document.location.port; + } + rootUrl += '/'; + + // Return + return rootUrl; + }; + + /** + * History.getBaseHref() + * Fetches the `href` attribute of the `` element if it exists + * @return {String} baseHref + */ + History.getBaseHref = function(){ + // Create + var + baseElements = document.getElementsByTagName('base'), + baseElement = null, + baseHref = ''; + + // Test for Base Element + if ( baseElements.length === 1 ) { + // Prepare for Base Element + baseElement = baseElements[0]; + baseHref = baseElement.href.replace(/[^\/]+$/,''); + } + + // Adjust trailing slash + baseHref = baseHref.replace(/\/+$/,''); + if ( baseHref ) baseHref += '/'; + + // Return + return baseHref; + }; + + /** + * History.getBaseUrl() + * Fetches the baseHref or basePageUrl or rootUrl (whichever one exists first) + * @return {String} baseUrl + */ + History.getBaseUrl = function(){ + // Create + var baseUrl = History.getBaseHref()||History.getBasePageUrl()||History.getRootUrl(); + + // Return + return baseUrl; + }; + + /** + * History.getPageUrl() + * Fetches the URL of the current page + * @return {String} pageUrl + */ + History.getPageUrl = function(){ + // Fetch + var + State = History.getState(false,false), + stateUrl = (State||{}).url||History.getLocationHref(), + pageUrl; + + // Create + pageUrl = stateUrl.replace(/\/+$/,'').replace(/[^\/]+$/,function(part,index,string){ + return (/\./).test(part) ? part : part+'/'; + }); + + // Return + return pageUrl; + }; + + /** + * History.getBasePageUrl() + * Fetches the Url of the directory of the current page + * @return {String} basePageUrl + */ + History.getBasePageUrl = function(){ + // Create + var basePageUrl = (History.getLocationHref()).replace(/[#\?].*/,'').replace(/[^\/]+$/,function(part,index,string){ + return (/[^\/]$/).test(part) ? '' : part; + }).replace(/\/+$/,'')+'/'; + + // Return + return basePageUrl; + }; + + /** + * History.getFullUrl(url) + * Ensures that we have an absolute URL and not a relative URL + * @param {string} url + * @param {Boolean} allowBaseHref + * @return {string} fullUrl + */ + History.getFullUrl = function(url,allowBaseHref){ + // Prepare + var fullUrl = url, firstChar = url.substring(0,1); + allowBaseHref = (typeof allowBaseHref === 'undefined') ? true : allowBaseHref; + + // Check + if ( /[a-z]+\:\/\//.test(url) ) { + // Full URL + } + else if ( firstChar === '/' ) { + // Root URL + fullUrl = History.getRootUrl()+url.replace(/^\/+/,''); + } + else if ( firstChar === '#' ) { + // Anchor URL + fullUrl = History.getPageUrl().replace(/#.*/,'')+url; + } + else if ( firstChar === '?' ) { + // Query URL + fullUrl = History.getPageUrl().replace(/[\?#].*/,'')+url; + } + else { + // Relative URL + if ( allowBaseHref ) { + fullUrl = History.getBaseUrl()+url.replace(/^(\.\/)+/,''); + } else { + fullUrl = History.getBasePageUrl()+url.replace(/^(\.\/)+/,''); + } + // We have an if condition above as we do not want hashes + // which are relative to the baseHref in our URLs + // as if the baseHref changes, then all our bookmarks + // would now point to different locations + // whereas the basePageUrl will always stay the same + } + + // Return + return fullUrl.replace(/\#$/,''); + }; + + /** + * History.getShortUrl(url) + * Ensures that we have a relative URL and not a absolute URL + * @param {string} url + * @return {string} url + */ + History.getShortUrl = function(url){ + // Prepare + var shortUrl = url, baseUrl = History.getBaseUrl(), rootUrl = History.getRootUrl(); + + // Trim baseUrl + if ( History.emulated.pushState ) { + // We are in a if statement as when pushState is not emulated + // The actual url these short urls are relative to can change + // So within the same session, we the url may end up somewhere different + shortUrl = shortUrl.replace(baseUrl,''); + } + + // Trim rootUrl + shortUrl = shortUrl.replace(rootUrl,'/'); + + // Ensure we can still detect it as a state + if ( History.isTraditionalAnchor(shortUrl) ) { + shortUrl = './'+shortUrl; + } + + // Clean It + shortUrl = shortUrl.replace(/^(\.\/)+/g,'./').replace(/\#$/,''); + + // Return + return shortUrl; + }; + + /** + * History.getLocationHref(document) + * Returns a normalized version of document.location.href + * accounting for browser inconsistencies, etc. + * + * This URL will be URI-encoded and will include the hash + * + * @param {object} document + * @return {string} url + */ + History.getLocationHref = function(doc) { + doc = doc || document; + + // most of the time, this will be true + if (doc.URL === doc.location.href) + return doc.location.href; + + // some versions of webkit URI-decode document.location.href + // but they leave document.URL in an encoded state + if (doc.location.href === decodeURIComponent(doc.URL)) + return doc.URL; + + // FF 3.6 only updates document.URL when a page is reloaded + // document.location.href is updated correctly + if (doc.location.hash && decodeURIComponent(doc.location.href.replace(/^[^#]+/, "")) === doc.location.hash) + return doc.location.href; + + if (doc.URL.indexOf('#') == -1 && doc.location.href.indexOf('#') != -1) + return doc.location.href; + + return doc.URL || doc.location.href; + }; + + + // ==================================================================== + // State Storage + + /** + * History.store + * The store for all session specific data + */ + History.store = {}; + + /** + * History.idToState + * 1-1: State ID to State Object + */ + History.idToState = History.idToState||{}; + + /** + * History.stateToId + * 1-1: State String to State ID + */ + History.stateToId = History.stateToId||{}; + + /** + * History.urlToId + * 1-1: State URL to State ID + */ + History.urlToId = History.urlToId||{}; + + /** + * History.storedStates + * Store the states in an array + */ + History.storedStates = History.storedStates||[]; + + /** + * History.savedStates + * Saved the states in an array + */ + History.savedStates = History.savedStates||[]; + + /** + * History.noramlizeStore() + * Noramlize the store by adding necessary values + */ + History.normalizeStore = function(){ + History.store.idToState = History.store.idToState||{}; + History.store.urlToId = History.store.urlToId||{}; + History.store.stateToId = History.store.stateToId||{}; + }; + + /** + * History.getState() + * Get an object containing the data, title and url of the current state + * @param {Boolean} friendly + * @param {Boolean} create + * @return {Object} State + */ + History.getState = function(friendly,create){ + // Prepare + if ( typeof friendly === 'undefined' ) { friendly = true; } + if ( typeof create === 'undefined' ) { create = true; } + + // Fetch + var State = History.getLastSavedState(); + + // Create + if ( !State && create ) { + State = History.createStateObject(); + } + + // Adjust + if ( friendly ) { + State = History.cloneObject(State); + State.url = State.cleanUrl||State.url; + } + + // Return + return State; + }; + + /** + * History.getIdByState(State) + * Gets a ID for a State + * @param {State} newState + * @return {String} id + */ + History.getIdByState = function(newState){ + + // Fetch ID + var id = History.extractId(newState.url), + str; + + if ( !id ) { + // Find ID via State String + str = History.getStateString(newState); + if ( typeof History.stateToId[str] !== 'undefined' ) { + id = History.stateToId[str]; + } + else if ( typeof History.store.stateToId[str] !== 'undefined' ) { + id = History.store.stateToId[str]; + } + else { + // Generate a new ID + while ( true ) { + id = (new Date()).getTime() + String(Math.random()).replace(/\D/g,''); + if ( typeof History.idToState[id] === 'undefined' && typeof History.store.idToState[id] === 'undefined' ) { + break; + } + } + + // Apply the new State to the ID + History.stateToId[str] = id; + History.idToState[id] = newState; + } + } + + // Return ID + return id; + }; + + /** + * History.normalizeState(State) + * Expands a State Object + * @param {object} State + * @return {object} + */ + History.normalizeState = function(oldState){ + // Variables + var newState, dataNotEmpty; + + // Prepare + if ( !oldState || (typeof oldState !== 'object') ) { + oldState = {}; + } + + // Check + if ( typeof oldState.normalized !== 'undefined' ) { + return oldState; + } + + // Adjust + if ( !oldState.data || (typeof oldState.data !== 'object') ) { + oldState.data = {}; + } + + // ---------------------------------------------------------------- + + // Create + newState = {}; + newState.normalized = true; + newState.title = oldState.title||''; + newState.url = History.getFullUrl(oldState.url?oldState.url:(History.getLocationHref())); + newState.hash = History.getShortUrl(newState.url); + newState.data = History.cloneObject(oldState.data); + + // Fetch ID + newState.id = History.getIdByState(newState); + + // ---------------------------------------------------------------- + + // Clean the URL + newState.cleanUrl = newState.url.replace(/\??\&_suid.*/,''); + newState.url = newState.cleanUrl; + + // Check to see if we have more than just a url + dataNotEmpty = !History.isEmptyObject(newState.data); + + // Apply + if ( (newState.title || dataNotEmpty) && History.options.disableSuid !== true ) { + // Add ID to Hash + newState.hash = History.getShortUrl(newState.url).replace(/\??\&_suid.*/,''); + if ( !/\?/.test(newState.hash) ) { + newState.hash += '?'; + } + newState.hash += '&_suid='+newState.id; + } + + // Create the Hashed URL + newState.hashedUrl = History.getFullUrl(newState.hash); + + // ---------------------------------------------------------------- + + // Update the URL if we have a duplicate + if ( (History.emulated.pushState || History.bugs.safariPoll) && History.hasUrlDuplicate(newState) ) { + newState.url = newState.hashedUrl; + } + + // ---------------------------------------------------------------- + + // Return + return newState; + }; + + /** + * History.createStateObject(data,title,url) + * Creates a object based on the data, title and url state params + * @param {object} data + * @param {string} title + * @param {string} url + * @return {object} + */ + History.createStateObject = function(data,title,url){ + // Hashify + var State = { + 'data': data, + 'title': title, + 'url': url + }; + + // Expand the State + State = History.normalizeState(State); + + // Return object + return State; + }; + + /** + * History.getStateById(id) + * Get a state by it's UID + * @param {String} id + */ + History.getStateById = function(id){ + // Prepare + id = String(id); + + // Retrieve + var State = History.idToState[id] || History.store.idToState[id] || undefined; + + // Return State + return State; + }; + + /** + * Get a State's String + * @param {State} passedState + */ + History.getStateString = function(passedState){ + // Prepare + var State, cleanedState, str; + + // Fetch + State = History.normalizeState(passedState); + + // Clean + cleanedState = { + data: State.data, + title: passedState.title, + url: passedState.url + }; + + // Fetch + str = JSON.stringify(cleanedState); + + // Return + return str; + }; + + /** + * Get a State's ID + * @param {State} passedState + * @return {String} id + */ + History.getStateId = function(passedState){ + // Prepare + var State, id; + + // Fetch + State = History.normalizeState(passedState); + + // Fetch + id = State.id; + + // Return + return id; + }; + + /** + * History.getHashByState(State) + * Creates a Hash for the State Object + * @param {State} passedState + * @return {String} hash + */ + History.getHashByState = function(passedState){ + // Prepare + var State, hash; + + // Fetch + State = History.normalizeState(passedState); + + // Hash + hash = State.hash; + + // Return + return hash; + }; + + /** + * History.extractId(url_or_hash) + * Get a State ID by it's URL or Hash + * @param {string} url_or_hash + * @return {string} id + */ + History.extractId = function ( url_or_hash ) { + // Prepare + var id,parts,url, tmp; + + // Extract + + // If the URL has a #, use the id from before the # + if (url_or_hash.indexOf('#') != -1) + { + tmp = url_or_hash.split("#")[0]; + } + else + { + tmp = url_or_hash; + } + + parts = /(.*)\&_suid=([0-9]+)$/.exec(tmp); + url = parts ? (parts[1]||url_or_hash) : url_or_hash; + id = parts ? String(parts[2]||'') : ''; + + // Return + return id||false; + }; + + /** + * History.isTraditionalAnchor + * Checks to see if the url is a traditional anchor or not + * @param {String} url_or_hash + * @return {Boolean} + */ + History.isTraditionalAnchor = function(url_or_hash){ + // Check + var isTraditional = !(/[\/\?\.]/.test(url_or_hash)); + + // Return + return isTraditional; + }; + + /** + * History.extractState + * Get a State by it's URL or Hash + * @param {String} url_or_hash + * @return {State|null} + */ + History.extractState = function(url_or_hash,create){ + // Prepare + var State = null, id, url; + create = create||false; + + // Fetch SUID + id = History.extractId(url_or_hash); + if ( id ) { + State = History.getStateById(id); + } + + // Fetch SUID returned no State + if ( !State ) { + // Fetch URL + url = History.getFullUrl(url_or_hash); + + // Check URL + id = History.getIdByUrl(url)||false; + if ( id ) { + State = History.getStateById(id); + } + + // Create State + if ( !State && create && !History.isTraditionalAnchor(url_or_hash) ) { + State = History.createStateObject(null,null,url); + } + } + + // Return + return State; + }; + + /** + * History.getIdByUrl() + * Get a State ID by a State URL + */ + History.getIdByUrl = function(url){ + // Fetch + var id = History.urlToId[url] || History.store.urlToId[url] || undefined; + + // Return + return id; + }; + + /** + * History.getLastSavedState() + * Get an object containing the data, title and url of the current state + * @return {Object} State + */ + History.getLastSavedState = function(){ + return History.savedStates[History.savedStates.length-1]||undefined; + }; + + /** + * History.getLastStoredState() + * Get an object containing the data, title and url of the current state + * @return {Object} State + */ + History.getLastStoredState = function(){ + return History.storedStates[History.storedStates.length-1]||undefined; + }; + + /** + * History.hasUrlDuplicate + * Checks if a Url will have a url conflict + * @param {Object} newState + * @return {Boolean} hasDuplicate + */ + History.hasUrlDuplicate = function(newState) { + // Prepare + var hasDuplicate = false, + oldState; + + // Fetch + oldState = History.extractState(newState.url); + + // Check + hasDuplicate = oldState && oldState.id !== newState.id; + + // Return + return hasDuplicate; + }; + + /** + * History.storeState + * Store a State + * @param {Object} newState + * @return {Object} newState + */ + History.storeState = function(newState){ + // Store the State + History.urlToId[newState.url] = newState.id; + + // Push the State + History.storedStates.push(History.cloneObject(newState)); + + // Return newState + return newState; + }; + + /** + * History.isLastSavedState(newState) + * Tests to see if the state is the last state + * @param {Object} newState + * @return {boolean} isLast + */ + History.isLastSavedState = function(newState){ + // Prepare + var isLast = false, + newId, oldState, oldId; + + // Check + if ( History.savedStates.length ) { + newId = newState.id; + oldState = History.getLastSavedState(); + oldId = oldState.id; + + // Check + isLast = (newId === oldId); + } + + // Return + return isLast; + }; + + /** + * History.saveState + * Push a State + * @param {Object} newState + * @return {boolean} changed + */ + History.saveState = function(newState){ + // Check Hash + if ( History.isLastSavedState(newState) ) { + return false; + } + + // Push the State + History.savedStates.push(History.cloneObject(newState)); + + // Return true + return true; + }; + + /** + * History.getStateByIndex() + * Gets a state by the index + * @param {integer} index + * @return {Object} + */ + History.getStateByIndex = function(index){ + // Prepare + var State = null; + + // Handle + if ( typeof index === 'undefined' ) { + // Get the last inserted + State = History.savedStates[History.savedStates.length-1]; + } + else if ( index < 0 ) { + // Get from the end + State = History.savedStates[History.savedStates.length+index]; + } + else { + // Get from the beginning + State = History.savedStates[index]; + } + + // Return State + return State; + }; + + /** + * History.getCurrentIndex() + * Gets the current index + * @return (integer) + */ + History.getCurrentIndex = function(){ + // Prepare + var index = null; + + // No states saved + if(History.savedStates.length < 1) { + index = 0; + } + else { + index = History.savedStates.length-1; + } + return index; + }; + + // ==================================================================== + // Hash Helpers + + /** + * History.getHash() + * @param {Location=} location + * Gets the current document hash + * Note: unlike location.hash, this is guaranteed to return the escaped hash in all browsers + * @return {string} + */ + History.getHash = function(doc){ + var url = History.getLocationHref(doc), + hash; + hash = History.getHashByUrl(url); + return hash; + }; + + /** + * History.unescapeHash() + * normalize and Unescape a Hash + * @param {String} hash + * @return {string} + */ + History.unescapeHash = function(hash){ + // Prepare + var result = History.normalizeHash(hash); + + // Unescape hash + result = decodeURIComponent(result); + + // Return result + return result; + }; + + /** + * History.normalizeHash() + * normalize a hash across browsers + * @return {string} + */ + History.normalizeHash = function(hash){ + // Prepare + var result = hash.replace(/[^#]*#/,'').replace(/#.*/, ''); + + // Return result + return result; + }; + + /** + * History.setHash(hash) + * Sets the document hash + * @param {string} hash + * @return {History} + */ + History.setHash = function(hash,queue){ + // Prepare + var State, pageUrl; + + // Handle Queueing + if ( queue !== false && History.busy() ) { + // Wait + Push to Queue + //History.debug('History.setHash: we must wait', arguments); + History.pushQueue({ + scope: History, + callback: History.setHash, + args: arguments, + queue: queue + }); + return false; + } + + // Log + //History.debug('History.setHash: called',hash); + + // Make Busy + Continue + History.busy(true); + + // Check if hash is a state + State = History.extractState(hash,true); + if ( State && !History.emulated.pushState ) { + // Hash is a state so skip the setHash + //History.debug('History.setHash: Hash is a state so skipping the hash set with a direct pushState call',arguments); + + // PushState + History.pushState(State.data,State.title,State.url,false); + } + else if ( History.getHash() !== hash ) { + // Hash is a proper hash, so apply it + + // Handle browser bugs + if ( History.bugs.setHash ) { + // Fix Safari Bug https://bugs.webkit.org/show_bug.cgi?id=56249 + + // Fetch the base page + pageUrl = History.getPageUrl(); + + // Safari hash apply + History.pushState(null,null,pageUrl+'#'+hash,false); + } + else { + // Normal hash apply + document.location.hash = hash; + } + } + + // Chain + return History; + }; + + /** + * History.escape() + * normalize and Escape a Hash + * @return {string} + */ + History.escapeHash = function(hash){ + // Prepare + var result = History.normalizeHash(hash); + + // Escape hash + result = window.encodeURIComponent(result); + + // IE6 Escape Bug + if ( !History.bugs.hashEscape ) { + // Restore common parts + result = result + .replace(/\%21/g,'!') + .replace(/\%26/g,'&') + .replace(/\%3D/g,'=') + .replace(/\%3F/g,'?'); + } + + // Return result + return result; + }; + + /** + * History.getHashByUrl(url) + * Extracts the Hash from a URL + * @param {string} url + * @return {string} url + */ + History.getHashByUrl = function(url){ + // Extract the hash + var hash = String(url) + .replace(/([^#]*)#?([^#]*)#?(.*)/, '$2') + ; + + // Unescape hash + hash = History.unescapeHash(hash); + + // Return hash + return hash; + }; + + /** + * History.setTitle(title) + * Applies the title to the document + * @param {State} newState + * @return {Boolean} + */ + History.setTitle = function(newState){ + // Prepare + var title = newState.title, + firstState; + + // Initial + if ( !title ) { + firstState = History.getStateByIndex(0); + if ( firstState && firstState.url === newState.url ) { + title = firstState.title||History.options.initialTitle; + } + } + + // Apply + try { + document.getElementsByTagName('title')[0].innerHTML = title.replace('<','<').replace('>','>').replace(' & ',' & '); + } + catch ( Exception ) { } + document.title = title; + + // Chain + return History; + }; + + + // ==================================================================== + // Queueing + + /** + * History.queues + * The list of queues to use + * First In, First Out + */ + History.queues = []; + + /** + * History.busy(value) + * @param {boolean} value [optional] + * @return {boolean} busy + */ + History.busy = function(value){ + // Apply + if ( typeof value !== 'undefined' ) { + //History.debug('History.busy: changing ['+(History.busy.flag||false)+'] to ['+(value||false)+']', History.queues.length); + History.busy.flag = value; + } + // Default + else if ( typeof History.busy.flag === 'undefined' ) { + History.busy.flag = false; + } + + // Queue + if ( !History.busy.flag ) { + // Execute the next item in the queue + clearTimeout(History.busy.timeout); + var fireNext = function(){ + var i, queue, item; + if ( History.busy.flag ) return; + for ( i=History.queues.length-1; i >= 0; --i ) { + queue = History.queues[i]; + if ( queue.length === 0 ) continue; + item = queue.shift(); + History.fireQueueItem(item); + History.busy.timeout = setTimeout(fireNext,History.options.busyDelay); + } + }; + History.busy.timeout = setTimeout(fireNext,History.options.busyDelay); + } + + // Return + return History.busy.flag; + }; + + /** + * History.busy.flag + */ + History.busy.flag = false; + + /** + * History.fireQueueItem(item) + * Fire a Queue Item + * @param {Object} item + * @return {Mixed} result + */ + History.fireQueueItem = function(item){ + return item.callback.apply(item.scope||History,item.args||[]); + }; + + /** + * History.pushQueue(callback,args) + * Add an item to the queue + * @param {Object} item [scope,callback,args,queue] + */ + History.pushQueue = function(item){ + // Prepare the queue + History.queues[item.queue||0] = History.queues[item.queue||0]||[]; + + // Add to the queue + History.queues[item.queue||0].push(item); + + // Chain + return History; + }; + + /** + * History.queue (item,queue), (func,queue), (func), (item) + * Either firs the item now if not busy, or adds it to the queue + */ + History.queue = function(item,queue){ + // Prepare + if ( typeof item === 'function' ) { + item = { + callback: item + }; + } + if ( typeof queue !== 'undefined' ) { + item.queue = queue; + } + + // Handle + if ( History.busy() ) { + History.pushQueue(item); + } else { + History.fireQueueItem(item); + } + + // Chain + return History; + }; + + /** + * History.clearQueue() + * Clears the Queue + */ + History.clearQueue = function(){ + History.busy.flag = false; + History.queues = []; + return History; + }; + + + // ==================================================================== + // IE Bug Fix + + /** + * History.stateChanged + * States whether or not the state has changed since the last double check was initialised + */ + History.stateChanged = false; + + /** + * History.doubleChecker + * Contains the timeout used for the double checks + */ + History.doubleChecker = false; + + /** + * History.doubleCheckComplete() + * Complete a double check + * @return {History} + */ + History.doubleCheckComplete = function(){ + // Update + History.stateChanged = true; + + // Clear + History.doubleCheckClear(); + + // Chain + return History; + }; + + /** + * History.doubleCheckClear() + * Clear a double check + * @return {History} + */ + History.doubleCheckClear = function(){ + // Clear + if ( History.doubleChecker ) { + clearTimeout(History.doubleChecker); + History.doubleChecker = false; + } + + // Chain + return History; + }; + + /** + * History.doubleCheck() + * Create a double check + * @return {History} + */ + History.doubleCheck = function(tryAgain){ + // Reset + History.stateChanged = false; + History.doubleCheckClear(); + + // Fix IE6,IE7 bug where calling history.back or history.forward does not actually change the hash (whereas doing it manually does) + // Fix Safari 5 bug where sometimes the state does not change: https://bugs.webkit.org/show_bug.cgi?id=42940 + if ( History.bugs.ieDoubleCheck ) { + // Apply Check + History.doubleChecker = setTimeout( + function(){ + History.doubleCheckClear(); + if ( !History.stateChanged ) { + //History.debug('History.doubleCheck: State has not yet changed, trying again', arguments); + // Re-Attempt + tryAgain(); + } + return true; + }, + History.options.doubleCheckInterval + ); + } + + // Chain + return History; + }; + + + // ==================================================================== + // Safari Bug Fix + + /** + * History.safariStatePoll() + * Poll the current state + * @return {History} + */ + History.safariStatePoll = function(){ + // Poll the URL + + // Get the Last State which has the new URL + var + urlState = History.extractState(History.getLocationHref()), + newState; + + // Check for a difference + if ( !History.isLastSavedState(urlState) ) { + newState = urlState; + } + else { + return; + } + + // Check if we have a state with that url + // If not create it + if ( !newState ) { + //History.debug('History.safariStatePoll: new'); + newState = History.createStateObject(); + } + + // Apply the New State + //History.debug('History.safariStatePoll: trigger'); + History.Adapter.trigger(window,'popstate'); + + // Chain + return History; + }; + + + // ==================================================================== + // State Aliases + + /** + * History.back(queue) + * Send the browser history back one item + * @param {Integer} queue [optional] + */ + History.back = function(queue){ + //History.debug('History.back: called', arguments); + + // Handle Queueing + if ( queue !== false && History.busy() ) { + // Wait + Push to Queue + //History.debug('History.back: we must wait', arguments); + History.pushQueue({ + scope: History, + callback: History.back, + args: arguments, + queue: queue + }); + return false; + } + + // Make Busy + Continue + History.busy(true); + + // Fix certain browser bugs that prevent the state from changing + History.doubleCheck(function(){ + History.back(false); + }); + + // Go back + history.go(-1); + + // End back closure + return true; + }; + + /** + * History.forward(queue) + * Send the browser history forward one item + * @param {Integer} queue [optional] + */ + History.forward = function(queue){ + //History.debug('History.forward: called', arguments); + + // Handle Queueing + if ( queue !== false && History.busy() ) { + // Wait + Push to Queue + //History.debug('History.forward: we must wait', arguments); + History.pushQueue({ + scope: History, + callback: History.forward, + args: arguments, + queue: queue + }); + return false; + } + + // Make Busy + Continue + History.busy(true); + + // Fix certain browser bugs that prevent the state from changing + History.doubleCheck(function(){ + History.forward(false); + }); + + // Go forward + history.go(1); + + // End forward closure + return true; + }; + + /** + * History.go(index,queue) + * Send the browser history back or forward index times + * @param {Integer} queue [optional] + */ + History.go = function(index,queue){ + //History.debug('History.go: called', arguments); + + // Prepare + var i; + + // Handle + if ( index > 0 ) { + // Forward + for ( i=1; i<=index; ++i ) { + History.forward(queue); + } + } + else if ( index < 0 ) { + // Backward + for ( i=-1; i>=index; --i ) { + History.back(queue); + } + } + else { + throw new Error('History.go: History.go requires a positive or negative integer passed.'); + } + + // Chain + return History; + }; + + + // ==================================================================== + // HTML5 State Support + + // Non-Native pushState Implementation + if ( History.emulated.pushState ) { + /* + * Provide Skeleton for HTML4 Browsers + */ + + // Prepare + var emptyFunction = function(){}; + History.pushState = History.pushState||emptyFunction; + History.replaceState = History.replaceState||emptyFunction; + } // History.emulated.pushState + + // Native pushState Implementation + else { + /* + * Use native HTML5 History API Implementation + */ + + /** + * History.onPopState(event,extra) + * Refresh the Current State + */ + History.onPopState = function(event,extra){ + // Prepare + var stateId = false, newState = false, currentHash, currentState; + + // Reset the double check + History.doubleCheckComplete(); + + // Check for a Hash, and handle apporiatly + currentHash = History.getHash(); + if ( currentHash ) { + // Expand Hash + currentState = History.extractState(currentHash||History.getLocationHref(),true); + if ( currentState ) { + // We were able to parse it, it must be a State! + // Let's forward to replaceState + //History.debug('History.onPopState: state anchor', currentHash, currentState); + History.replaceState(currentState.data, currentState.title, currentState.url, false); + } + else { + // Traditional Anchor + //History.debug('History.onPopState: traditional anchor', currentHash); + History.Adapter.trigger(window,'anchorchange'); + History.busy(false); + } + + // We don't care for hashes + History.expectedStateId = false; + return false; + } + + // Ensure + stateId = History.Adapter.extractEventData('state',event,extra) || false; + + // Fetch State + if ( stateId ) { + // Vanilla: Back/forward button was used + newState = History.getStateById(stateId); + } + else if ( History.expectedStateId ) { + // Vanilla: A new state was pushed, and popstate was called manually + newState = History.getStateById(History.expectedStateId); + } + else { + // Initial State + newState = History.extractState(History.getLocationHref()); + } + + // The State did not exist in our store + if ( !newState ) { + // Regenerate the State + newState = History.createStateObject(null,null,History.getLocationHref()); + } + + // Clean + History.expectedStateId = false; + + // Check if we are the same state + if ( History.isLastSavedState(newState) ) { + // There has been no change (just the page's hash has finally propagated) + //History.debug('History.onPopState: no change', newState, History.savedStates); + History.busy(false); + return false; + } + + // Store the State + History.storeState(newState); + History.saveState(newState); + + // Force update of the title + History.setTitle(newState); + + // Fire Our Event + History.Adapter.trigger(window,'statechange'); + History.busy(false); + + // Return true + return true; + }; + History.Adapter.bind(window,'popstate',History.onPopState); + + /** + * History.pushState(data,title,url) + * Add a new State to the history object, become it, and trigger onpopstate + * We have to trigger for HTML4 compatibility + * @param {object} data + * @param {string} title + * @param {string} url + * @return {true} + */ + History.pushState = function(data,title,url,queue){ + //History.debug('History.pushState: called', arguments); + + // Check the State + if ( History.getHashByUrl(url) && History.emulated.pushState ) { + throw new Error('History.js does not support states with fragement-identifiers (hashes/anchors).'); + } + + // Handle Queueing + if ( queue !== false && History.busy() ) { + // Wait + Push to Queue + //History.debug('History.pushState: we must wait', arguments); + History.pushQueue({ + scope: History, + callback: History.pushState, + args: arguments, + queue: queue + }); + return false; + } + + // Make Busy + Continue + History.busy(true); + + // Create the newState + var newState = History.createStateObject(data,title,url); + + // Check it + if ( History.isLastSavedState(newState) ) { + // Won't be a change + History.busy(false); + } + else { + // Store the newState + History.storeState(newState); + History.expectedStateId = newState.id; + + // Push the newState + history.pushState(newState.id,newState.title,newState.url); + + // Fire HTML5 Event + History.Adapter.trigger(window,'popstate'); + } + + // End pushState closure + return true; + }; + + /** + * History.replaceState(data,title,url) + * Replace the State and trigger onpopstate + * We have to trigger for HTML4 compatibility + * @param {object} data + * @param {string} title + * @param {string} url + * @return {true} + */ + History.replaceState = function(data,title,url,queue){ + //History.debug('History.replaceState: called', arguments); + + // Check the State + if ( History.getHashByUrl(url) && History.emulated.pushState ) { + throw new Error('History.js does not support states with fragement-identifiers (hashes/anchors).'); + } + + // Handle Queueing + if ( queue !== false && History.busy() ) { + // Wait + Push to Queue + //History.debug('History.replaceState: we must wait', arguments); + History.pushQueue({ + scope: History, + callback: History.replaceState, + args: arguments, + queue: queue + }); + return false; + } + + // Make Busy + Continue + History.busy(true); + + // Create the newState + var newState = History.createStateObject(data,title,url); + + // Check it + if ( History.isLastSavedState(newState) ) { + // Won't be a change + History.busy(false); + } + else { + // Store the newState + History.storeState(newState); + History.expectedStateId = newState.id; + + // Push the newState + history.replaceState(newState.id,newState.title,newState.url); + + // Fire HTML5 Event + History.Adapter.trigger(window,'popstate'); + } + + // End replaceState closure + return true; + }; + + } // !History.emulated.pushState + + + // ==================================================================== + // Initialise + + /** + * Load the Store + */ + if ( sessionStorage ) { + // Fetch + try { + History.store = JSON.parse(sessionStorage.getItem('History.store'))||{}; + } + catch ( err ) { + History.store = {}; + } + + // Normalize + History.normalizeStore(); + } + else { + // Default Load + History.store = {}; + History.normalizeStore(); + } + + /** + * Clear Intervals on exit to prevent memory leaks + */ + History.Adapter.bind(window,"unload",History.clearAllIntervals); + + /** + * Create the initial State + */ + History.saveState(History.storeState(History.extractState(History.getLocationHref(),true))); + + /** + * Bind for Saving Store + */ + if ( sessionStorage ) { + // When the page is closed + History.onUnload = function(){ + // Prepare + var currentStore, item, currentStoreString; + + // Fetch + try { + currentStore = JSON.parse(sessionStorage.getItem('History.store'))||{}; + } + catch ( err ) { + currentStore = {}; + } + + // Ensure + currentStore.idToState = currentStore.idToState || {}; + currentStore.urlToId = currentStore.urlToId || {}; + currentStore.stateToId = currentStore.stateToId || {}; + + // Sync + for ( item in History.idToState ) { + if ( !History.idToState.hasOwnProperty(item) ) { + continue; + } + currentStore.idToState[item] = History.idToState[item]; + } + for ( item in History.urlToId ) { + if ( !History.urlToId.hasOwnProperty(item) ) { + continue; + } + currentStore.urlToId[item] = History.urlToId[item]; + } + for ( item in History.stateToId ) { + if ( !History.stateToId.hasOwnProperty(item) ) { + continue; + } + currentStore.stateToId[item] = History.stateToId[item]; + } + + // Update + History.store = currentStore; + History.normalizeStore(); + + // In Safari, going into Private Browsing mode causes the + // Session Storage object to still exist but if you try and use + // or set any property/function of it it throws the exception + // "QUOTA_EXCEEDED_ERR: DOM Exception 22: An attempt was made to + // add something to storage that exceeded the quota." infinitely + // every second. + currentStoreString = JSON.stringify(currentStore); + try { + // Store + sessionStorage.setItem('History.store', currentStoreString); + } + catch (e) { + if (e.code === DOMException.QUOTA_EXCEEDED_ERR) { + if (sessionStorage.length) { + // Workaround for a bug seen on iPads. Sometimes the quota exceeded error comes up and simply + // removing/resetting the storage can work. + sessionStorage.removeItem('History.store'); + sessionStorage.setItem('History.store', currentStoreString); + } else { + // Otherwise, we're probably private browsing in Safari, so we'll ignore the exception. + } + } else { + throw e; + } + } + }; + + // For Internet Explorer + History.intervalList.push(setInterval(History.onUnload,History.options.storeInterval)); + + // For Other Browsers + History.Adapter.bind(window,'beforeunload',History.onUnload); + History.Adapter.bind(window,'unload',History.onUnload); + + // Both are enabled for consistency + } + + // Non-Native pushState Implementation + if ( !History.emulated.pushState ) { + // Be aware, the following is only for native pushState implementations + // If you are wanting to include something for all browsers + // Then include it above this if block + + /** + * Setup Safari Fix + */ + if ( History.bugs.safariPoll ) { + History.intervalList.push(setInterval(History.safariStatePoll, History.options.safariPollInterval)); + } + + /** + * Ensure Cross Browser Compatibility + */ + if ( navigator.vendor === 'Apple Computer, Inc.' || (navigator.appCodeName||'') === 'Mozilla' ) { + /** + * Fix Safari HashChange Issue + */ + + // Setup Alias + History.Adapter.bind(window,'hashchange',function(){ + History.Adapter.trigger(window,'popstate'); + }); + + // Initialise Alias + if ( History.getHash() ) { + History.Adapter.onDomLoad(function(){ + History.Adapter.trigger(window,'hashchange'); + }); + } + } + + } // !History.emulated.pushState + + + }; // History.initCore + + // Try to Initialise History + if (!History.options || !History.options.delayInit) { + History.init(); + } + +})(window); diff --git a/sites/all/themes/gui/materiobasetheme/bower_components/history.js/scripts/bundled-uncompressed/html5/right.history.js b/sites/all/themes/gui/materiobasetheme/bower_components/history.js/scripts/bundled-uncompressed/html5/right.history.js new file mode 100644 index 00000000..9a81c833 --- /dev/null +++ b/sites/all/themes/gui/materiobasetheme/bower_components/history.js/scripts/bundled-uncompressed/html5/right.history.js @@ -0,0 +1,2122 @@ +/** + * History.js RightJS Adapter + * @author Benjamin Arthur Lupton + * @copyright 2010-2011 Benjamin Arthur Lupton + * @license New BSD License + */ + +// Closure +(function(window,undefined){ + "use strict"; + + // Localise Globals + var + History = window.History = window.History||{}, + document = window.document, + RightJS = window.RightJS, + $ = RightJS.$; + + // Check Existence + if ( typeof History.Adapter !== 'undefined' ) { + throw new Error('History.js Adapter has already been loaded...'); + } + + // Add the Adapter + History.Adapter = { + /** + * History.Adapter.bind(el,event,callback) + * @param {Element|Selector} el + * @param {String} event - custom and standard events + * @param {Function} callback + * @return + */ + bind: function(el,event,callback){ + $(el).on(event,callback); + }, + + /** + * History.Adapter.trigger(el,event) + * @param {Element|Selector} el + * @param {String} event - custom and standard events + * @param {Object} extraEventData - a object of extra event data + * @return + */ + trigger: function(el,event,extraEventData){ + $(el).fire(event,extraEventData); + }, + + /** + * History.Adapter.extractEventData(key,event,extra) + * @param {String} key - key for the event data to extract + * @param {String} event - custom and standard events + * @return {mixed} + */ + extractEventData: function(key,event){ + // Right.js Native + // Right.js Custom + var result = (event && event._ && event._[key]) || undefined; + + // Return + return result; + }, + + /** + * History.Adapter.onDomLoad(callback) + * @param {Function} callback + * @return + */ + onDomLoad: function(callback) { + $(document).onReady(callback); + } + }; + + // Try and Initialise History + if ( typeof History.init !== 'undefined' ) { + History.init(); + } + +})(window); +/** + * History.js Core + * @author Benjamin Arthur Lupton + * @copyright 2010-2011 Benjamin Arthur Lupton + * @license New BSD License + */ + +(function(window,undefined){ + "use strict"; + + // ======================================================================== + // Initialise + + // Localise Globals + var + console = window.console||undefined, // Prevent a JSLint complain + document = window.document, // Make sure we are using the correct document + navigator = window.navigator, // Make sure we are using the correct navigator + sessionStorage = window.sessionStorage||false, // sessionStorage + setTimeout = window.setTimeout, + clearTimeout = window.clearTimeout, + setInterval = window.setInterval, + clearInterval = window.clearInterval, + JSON = window.JSON, + alert = window.alert, + History = window.History = window.History||{}, // Public History Object + history = window.history; // Old History Object + + try { + sessionStorage.setItem('TEST', '1'); + sessionStorage.removeItem('TEST'); + } catch(e) { + sessionStorage = false; + } + + // MooTools Compatibility + JSON.stringify = JSON.stringify||JSON.encode; + JSON.parse = JSON.parse||JSON.decode; + + // Check Existence + if ( typeof History.init !== 'undefined' ) { + throw new Error('History.js Core has already been loaded...'); + } + + // Initialise History + History.init = function(options){ + // Check Load Status of Adapter + if ( typeof History.Adapter === 'undefined' ) { + return false; + } + + // Check Load Status of Core + if ( typeof History.initCore !== 'undefined' ) { + History.initCore(); + } + + // Check Load Status of HTML4 Support + if ( typeof History.initHtml4 !== 'undefined' ) { + History.initHtml4(); + } + + // Return true + return true; + }; + + + // ======================================================================== + // Initialise Core + + // Initialise Core + History.initCore = function(options){ + // Initialise + if ( typeof History.initCore.initialized !== 'undefined' ) { + // Already Loaded + return false; + } + else { + History.initCore.initialized = true; + } + + + // ==================================================================== + // Options + + /** + * History.options + * Configurable options + */ + History.options = History.options||{}; + + /** + * History.options.hashChangeInterval + * How long should the interval be before hashchange checks + */ + History.options.hashChangeInterval = History.options.hashChangeInterval || 100; + + /** + * History.options.safariPollInterval + * How long should the interval be before safari poll checks + */ + History.options.safariPollInterval = History.options.safariPollInterval || 500; + + /** + * History.options.doubleCheckInterval + * How long should the interval be before we perform a double check + */ + History.options.doubleCheckInterval = History.options.doubleCheckInterval || 500; + + /** + * History.options.disableSuid + * Force History not to append suid + */ + History.options.disableSuid = History.options.disableSuid || false; + + /** + * History.options.storeInterval + * How long should we wait between store calls + */ + History.options.storeInterval = History.options.storeInterval || 1000; + + /** + * History.options.busyDelay + * How long should we wait between busy events + */ + History.options.busyDelay = History.options.busyDelay || 250; + + /** + * History.options.debug + * If true will enable debug messages to be logged + */ + History.options.debug = History.options.debug || false; + + /** + * History.options.initialTitle + * What is the title of the initial state + */ + History.options.initialTitle = History.options.initialTitle || document.title; + + /** + * History.options.html4Mode + * If true, will force HTMl4 mode (hashtags) + */ + History.options.html4Mode = History.options.html4Mode || false; + + /** + * History.options.delayInit + * Want to override default options and call init manually. + */ + History.options.delayInit = History.options.delayInit || false; + + + // ==================================================================== + // Interval record + + /** + * History.intervalList + * List of intervals set, to be cleared when document is unloaded. + */ + History.intervalList = []; + + /** + * History.clearAllIntervals + * Clears all setInterval instances. + */ + History.clearAllIntervals = function(){ + var i, il = History.intervalList; + if (typeof il !== "undefined" && il !== null) { + for (i = 0; i < il.length; i++) { + clearInterval(il[i]); + } + History.intervalList = null; + } + }; + + + // ==================================================================== + // Debug + + /** + * History.debug(message,...) + * Logs the passed arguments if debug enabled + */ + History.debug = function(){ + if ( (History.options.debug||false) ) { + History.log.apply(History,arguments); + } + }; + + /** + * History.log(message,...) + * Logs the passed arguments + */ + History.log = function(){ + // Prepare + var + consoleExists = !(typeof console === 'undefined' || typeof console.log === 'undefined' || typeof console.log.apply === 'undefined'), + textarea = document.getElementById('log'), + message, + i,n, + args,arg + ; + + // Write to Console + if ( consoleExists ) { + args = Array.prototype.slice.call(arguments); + message = args.shift(); + if ( typeof console.debug !== 'undefined' ) { + console.debug.apply(console,[message,args]); + } + else { + console.log.apply(console,[message,args]); + } + } + else { + message = ("\n"+arguments[0]+"\n"); + } + + // Write to log + for ( i=1,n=arguments.length; i + * @author James Padolsey + */ + History.getInternetExplorerMajorVersion = function(){ + var result = History.getInternetExplorerMajorVersion.cached = + (typeof History.getInternetExplorerMajorVersion.cached !== 'undefined') + ? History.getInternetExplorerMajorVersion.cached + : (function(){ + var v = 3, + div = document.createElement('div'), + all = div.getElementsByTagName('i'); + while ( (div.innerHTML = '') && all[0] ) {} + return (v > 4) ? v : false; + })() + ; + return result; + }; + + /** + * History.isInternetExplorer() + * Are we using Internet Explorer? + * @return {boolean} + * @license Public Domain + * @author Benjamin Arthur Lupton + */ + History.isInternetExplorer = function(){ + var result = + History.isInternetExplorer.cached = + (typeof History.isInternetExplorer.cached !== 'undefined') + ? History.isInternetExplorer.cached + : Boolean(History.getInternetExplorerMajorVersion()) + ; + return result; + }; + + /** + * History.emulated + * Which features require emulating? + */ + + if (History.options.html4Mode) { + History.emulated = { + pushState : true, + hashChange: true + }; + } + + else { + + History.emulated = { + pushState: !Boolean( + window.history && window.history.pushState && window.history.replaceState + && !( + (/ Mobile\/([1-7][a-z]|(8([abcde]|f(1[0-8]))))/i).test(navigator.userAgent) /* disable for versions of iOS before version 4.3 (8F190) */ + || (/AppleWebKit\/5([0-2]|3[0-2])/i).test(navigator.userAgent) /* disable for the mercury iOS browser, or at least older versions of the webkit engine */ + ) + ), + hashChange: Boolean( + !(('onhashchange' in window) || ('onhashchange' in document)) + || + (History.isInternetExplorer() && History.getInternetExplorerMajorVersion() < 8) + ) + }; + } + + /** + * History.enabled + * Is History enabled? + */ + History.enabled = !History.emulated.pushState; + + /** + * History.bugs + * Which bugs are present + */ + History.bugs = { + /** + * Safari 5 and Safari iOS 4 fail to return to the correct state once a hash is replaced by a `replaceState` call + * https://bugs.webkit.org/show_bug.cgi?id=56249 + */ + setHash: Boolean(!History.emulated.pushState && navigator.vendor === 'Apple Computer, Inc.' && /AppleWebKit\/5([0-2]|3[0-3])/.test(navigator.userAgent)), + + /** + * Safari 5 and Safari iOS 4 sometimes fail to apply the state change under busy conditions + * https://bugs.webkit.org/show_bug.cgi?id=42940 + */ + safariPoll: Boolean(!History.emulated.pushState && navigator.vendor === 'Apple Computer, Inc.' && /AppleWebKit\/5([0-2]|3[0-3])/.test(navigator.userAgent)), + + /** + * MSIE 6 and 7 sometimes do not apply a hash even it was told to (requiring a second call to the apply function) + */ + ieDoubleCheck: Boolean(History.isInternetExplorer() && History.getInternetExplorerMajorVersion() < 8), + + /** + * MSIE 6 requires the entire hash to be encoded for the hashes to trigger the onHashChange event + */ + hashEscape: Boolean(History.isInternetExplorer() && History.getInternetExplorerMajorVersion() < 7) + }; + + /** + * History.isEmptyObject(obj) + * Checks to see if the Object is Empty + * @param {Object} obj + * @return {boolean} + */ + History.isEmptyObject = function(obj) { + for ( var name in obj ) { + if ( obj.hasOwnProperty(name) ) { + return false; + } + } + return true; + }; + + /** + * History.cloneObject(obj) + * Clones a object and eliminate all references to the original contexts + * @param {Object} obj + * @return {Object} + */ + History.cloneObject = function(obj) { + var hash,newObj; + if ( obj ) { + hash = JSON.stringify(obj); + newObj = JSON.parse(hash); + } + else { + newObj = {}; + } + return newObj; + }; + + + // ==================================================================== + // URL Helpers + + /** + * History.getRootUrl() + * Turns "http://mysite.com/dir/page.html?asd" into "http://mysite.com" + * @return {String} rootUrl + */ + History.getRootUrl = function(){ + // Create + var rootUrl = document.location.protocol+'//'+(document.location.hostname||document.location.host); + if ( document.location.port||false ) { + rootUrl += ':'+document.location.port; + } + rootUrl += '/'; + + // Return + return rootUrl; + }; + + /** + * History.getBaseHref() + * Fetches the `href` attribute of the `` element if it exists + * @return {String} baseHref + */ + History.getBaseHref = function(){ + // Create + var + baseElements = document.getElementsByTagName('base'), + baseElement = null, + baseHref = ''; + + // Test for Base Element + if ( baseElements.length === 1 ) { + // Prepare for Base Element + baseElement = baseElements[0]; + baseHref = baseElement.href.replace(/[^\/]+$/,''); + } + + // Adjust trailing slash + baseHref = baseHref.replace(/\/+$/,''); + if ( baseHref ) baseHref += '/'; + + // Return + return baseHref; + }; + + /** + * History.getBaseUrl() + * Fetches the baseHref or basePageUrl or rootUrl (whichever one exists first) + * @return {String} baseUrl + */ + History.getBaseUrl = function(){ + // Create + var baseUrl = History.getBaseHref()||History.getBasePageUrl()||History.getRootUrl(); + + // Return + return baseUrl; + }; + + /** + * History.getPageUrl() + * Fetches the URL of the current page + * @return {String} pageUrl + */ + History.getPageUrl = function(){ + // Fetch + var + State = History.getState(false,false), + stateUrl = (State||{}).url||History.getLocationHref(), + pageUrl; + + // Create + pageUrl = stateUrl.replace(/\/+$/,'').replace(/[^\/]+$/,function(part,index,string){ + return (/\./).test(part) ? part : part+'/'; + }); + + // Return + return pageUrl; + }; + + /** + * History.getBasePageUrl() + * Fetches the Url of the directory of the current page + * @return {String} basePageUrl + */ + History.getBasePageUrl = function(){ + // Create + var basePageUrl = (History.getLocationHref()).replace(/[#\?].*/,'').replace(/[^\/]+$/,function(part,index,string){ + return (/[^\/]$/).test(part) ? '' : part; + }).replace(/\/+$/,'')+'/'; + + // Return + return basePageUrl; + }; + + /** + * History.getFullUrl(url) + * Ensures that we have an absolute URL and not a relative URL + * @param {string} url + * @param {Boolean} allowBaseHref + * @return {string} fullUrl + */ + History.getFullUrl = function(url,allowBaseHref){ + // Prepare + var fullUrl = url, firstChar = url.substring(0,1); + allowBaseHref = (typeof allowBaseHref === 'undefined') ? true : allowBaseHref; + + // Check + if ( /[a-z]+\:\/\//.test(url) ) { + // Full URL + } + else if ( firstChar === '/' ) { + // Root URL + fullUrl = History.getRootUrl()+url.replace(/^\/+/,''); + } + else if ( firstChar === '#' ) { + // Anchor URL + fullUrl = History.getPageUrl().replace(/#.*/,'')+url; + } + else if ( firstChar === '?' ) { + // Query URL + fullUrl = History.getPageUrl().replace(/[\?#].*/,'')+url; + } + else { + // Relative URL + if ( allowBaseHref ) { + fullUrl = History.getBaseUrl()+url.replace(/^(\.\/)+/,''); + } else { + fullUrl = History.getBasePageUrl()+url.replace(/^(\.\/)+/,''); + } + // We have an if condition above as we do not want hashes + // which are relative to the baseHref in our URLs + // as if the baseHref changes, then all our bookmarks + // would now point to different locations + // whereas the basePageUrl will always stay the same + } + + // Return + return fullUrl.replace(/\#$/,''); + }; + + /** + * History.getShortUrl(url) + * Ensures that we have a relative URL and not a absolute URL + * @param {string} url + * @return {string} url + */ + History.getShortUrl = function(url){ + // Prepare + var shortUrl = url, baseUrl = History.getBaseUrl(), rootUrl = History.getRootUrl(); + + // Trim baseUrl + if ( History.emulated.pushState ) { + // We are in a if statement as when pushState is not emulated + // The actual url these short urls are relative to can change + // So within the same session, we the url may end up somewhere different + shortUrl = shortUrl.replace(baseUrl,''); + } + + // Trim rootUrl + shortUrl = shortUrl.replace(rootUrl,'/'); + + // Ensure we can still detect it as a state + if ( History.isTraditionalAnchor(shortUrl) ) { + shortUrl = './'+shortUrl; + } + + // Clean It + shortUrl = shortUrl.replace(/^(\.\/)+/g,'./').replace(/\#$/,''); + + // Return + return shortUrl; + }; + + /** + * History.getLocationHref(document) + * Returns a normalized version of document.location.href + * accounting for browser inconsistencies, etc. + * + * This URL will be URI-encoded and will include the hash + * + * @param {object} document + * @return {string} url + */ + History.getLocationHref = function(doc) { + doc = doc || document; + + // most of the time, this will be true + if (doc.URL === doc.location.href) + return doc.location.href; + + // some versions of webkit URI-decode document.location.href + // but they leave document.URL in an encoded state + if (doc.location.href === decodeURIComponent(doc.URL)) + return doc.URL; + + // FF 3.6 only updates document.URL when a page is reloaded + // document.location.href is updated correctly + if (doc.location.hash && decodeURIComponent(doc.location.href.replace(/^[^#]+/, "")) === doc.location.hash) + return doc.location.href; + + if (doc.URL.indexOf('#') == -1 && doc.location.href.indexOf('#') != -1) + return doc.location.href; + + return doc.URL || doc.location.href; + }; + + + // ==================================================================== + // State Storage + + /** + * History.store + * The store for all session specific data + */ + History.store = {}; + + /** + * History.idToState + * 1-1: State ID to State Object + */ + History.idToState = History.idToState||{}; + + /** + * History.stateToId + * 1-1: State String to State ID + */ + History.stateToId = History.stateToId||{}; + + /** + * History.urlToId + * 1-1: State URL to State ID + */ + History.urlToId = History.urlToId||{}; + + /** + * History.storedStates + * Store the states in an array + */ + History.storedStates = History.storedStates||[]; + + /** + * History.savedStates + * Saved the states in an array + */ + History.savedStates = History.savedStates||[]; + + /** + * History.noramlizeStore() + * Noramlize the store by adding necessary values + */ + History.normalizeStore = function(){ + History.store.idToState = History.store.idToState||{}; + History.store.urlToId = History.store.urlToId||{}; + History.store.stateToId = History.store.stateToId||{}; + }; + + /** + * History.getState() + * Get an object containing the data, title and url of the current state + * @param {Boolean} friendly + * @param {Boolean} create + * @return {Object} State + */ + History.getState = function(friendly,create){ + // Prepare + if ( typeof friendly === 'undefined' ) { friendly = true; } + if ( typeof create === 'undefined' ) { create = true; } + + // Fetch + var State = History.getLastSavedState(); + + // Create + if ( !State && create ) { + State = History.createStateObject(); + } + + // Adjust + if ( friendly ) { + State = History.cloneObject(State); + State.url = State.cleanUrl||State.url; + } + + // Return + return State; + }; + + /** + * History.getIdByState(State) + * Gets a ID for a State + * @param {State} newState + * @return {String} id + */ + History.getIdByState = function(newState){ + + // Fetch ID + var id = History.extractId(newState.url), + str; + + if ( !id ) { + // Find ID via State String + str = History.getStateString(newState); + if ( typeof History.stateToId[str] !== 'undefined' ) { + id = History.stateToId[str]; + } + else if ( typeof History.store.stateToId[str] !== 'undefined' ) { + id = History.store.stateToId[str]; + } + else { + // Generate a new ID + while ( true ) { + id = (new Date()).getTime() + String(Math.random()).replace(/\D/g,''); + if ( typeof History.idToState[id] === 'undefined' && typeof History.store.idToState[id] === 'undefined' ) { + break; + } + } + + // Apply the new State to the ID + History.stateToId[str] = id; + History.idToState[id] = newState; + } + } + + // Return ID + return id; + }; + + /** + * History.normalizeState(State) + * Expands a State Object + * @param {object} State + * @return {object} + */ + History.normalizeState = function(oldState){ + // Variables + var newState, dataNotEmpty; + + // Prepare + if ( !oldState || (typeof oldState !== 'object') ) { + oldState = {}; + } + + // Check + if ( typeof oldState.normalized !== 'undefined' ) { + return oldState; + } + + // Adjust + if ( !oldState.data || (typeof oldState.data !== 'object') ) { + oldState.data = {}; + } + + // ---------------------------------------------------------------- + + // Create + newState = {}; + newState.normalized = true; + newState.title = oldState.title||''; + newState.url = History.getFullUrl(oldState.url?oldState.url:(History.getLocationHref())); + newState.hash = History.getShortUrl(newState.url); + newState.data = History.cloneObject(oldState.data); + + // Fetch ID + newState.id = History.getIdByState(newState); + + // ---------------------------------------------------------------- + + // Clean the URL + newState.cleanUrl = newState.url.replace(/\??\&_suid.*/,''); + newState.url = newState.cleanUrl; + + // Check to see if we have more than just a url + dataNotEmpty = !History.isEmptyObject(newState.data); + + // Apply + if ( (newState.title || dataNotEmpty) && History.options.disableSuid !== true ) { + // Add ID to Hash + newState.hash = History.getShortUrl(newState.url).replace(/\??\&_suid.*/,''); + if ( !/\?/.test(newState.hash) ) { + newState.hash += '?'; + } + newState.hash += '&_suid='+newState.id; + } + + // Create the Hashed URL + newState.hashedUrl = History.getFullUrl(newState.hash); + + // ---------------------------------------------------------------- + + // Update the URL if we have a duplicate + if ( (History.emulated.pushState || History.bugs.safariPoll) && History.hasUrlDuplicate(newState) ) { + newState.url = newState.hashedUrl; + } + + // ---------------------------------------------------------------- + + // Return + return newState; + }; + + /** + * History.createStateObject(data,title,url) + * Creates a object based on the data, title and url state params + * @param {object} data + * @param {string} title + * @param {string} url + * @return {object} + */ + History.createStateObject = function(data,title,url){ + // Hashify + var State = { + 'data': data, + 'title': title, + 'url': url + }; + + // Expand the State + State = History.normalizeState(State); + + // Return object + return State; + }; + + /** + * History.getStateById(id) + * Get a state by it's UID + * @param {String} id + */ + History.getStateById = function(id){ + // Prepare + id = String(id); + + // Retrieve + var State = History.idToState[id] || History.store.idToState[id] || undefined; + + // Return State + return State; + }; + + /** + * Get a State's String + * @param {State} passedState + */ + History.getStateString = function(passedState){ + // Prepare + var State, cleanedState, str; + + // Fetch + State = History.normalizeState(passedState); + + // Clean + cleanedState = { + data: State.data, + title: passedState.title, + url: passedState.url + }; + + // Fetch + str = JSON.stringify(cleanedState); + + // Return + return str; + }; + + /** + * Get a State's ID + * @param {State} passedState + * @return {String} id + */ + History.getStateId = function(passedState){ + // Prepare + var State, id; + + // Fetch + State = History.normalizeState(passedState); + + // Fetch + id = State.id; + + // Return + return id; + }; + + /** + * History.getHashByState(State) + * Creates a Hash for the State Object + * @param {State} passedState + * @return {String} hash + */ + History.getHashByState = function(passedState){ + // Prepare + var State, hash; + + // Fetch + State = History.normalizeState(passedState); + + // Hash + hash = State.hash; + + // Return + return hash; + }; + + /** + * History.extractId(url_or_hash) + * Get a State ID by it's URL or Hash + * @param {string} url_or_hash + * @return {string} id + */ + History.extractId = function ( url_or_hash ) { + // Prepare + var id,parts,url, tmp; + + // Extract + + // If the URL has a #, use the id from before the # + if (url_or_hash.indexOf('#') != -1) + { + tmp = url_or_hash.split("#")[0]; + } + else + { + tmp = url_or_hash; + } + + parts = /(.*)\&_suid=([0-9]+)$/.exec(tmp); + url = parts ? (parts[1]||url_or_hash) : url_or_hash; + id = parts ? String(parts[2]||'') : ''; + + // Return + return id||false; + }; + + /** + * History.isTraditionalAnchor + * Checks to see if the url is a traditional anchor or not + * @param {String} url_or_hash + * @return {Boolean} + */ + History.isTraditionalAnchor = function(url_or_hash){ + // Check + var isTraditional = !(/[\/\?\.]/.test(url_or_hash)); + + // Return + return isTraditional; + }; + + /** + * History.extractState + * Get a State by it's URL or Hash + * @param {String} url_or_hash + * @return {State|null} + */ + History.extractState = function(url_or_hash,create){ + // Prepare + var State = null, id, url; + create = create||false; + + // Fetch SUID + id = History.extractId(url_or_hash); + if ( id ) { + State = History.getStateById(id); + } + + // Fetch SUID returned no State + if ( !State ) { + // Fetch URL + url = History.getFullUrl(url_or_hash); + + // Check URL + id = History.getIdByUrl(url)||false; + if ( id ) { + State = History.getStateById(id); + } + + // Create State + if ( !State && create && !History.isTraditionalAnchor(url_or_hash) ) { + State = History.createStateObject(null,null,url); + } + } + + // Return + return State; + }; + + /** + * History.getIdByUrl() + * Get a State ID by a State URL + */ + History.getIdByUrl = function(url){ + // Fetch + var id = History.urlToId[url] || History.store.urlToId[url] || undefined; + + // Return + return id; + }; + + /** + * History.getLastSavedState() + * Get an object containing the data, title and url of the current state + * @return {Object} State + */ + History.getLastSavedState = function(){ + return History.savedStates[History.savedStates.length-1]||undefined; + }; + + /** + * History.getLastStoredState() + * Get an object containing the data, title and url of the current state + * @return {Object} State + */ + History.getLastStoredState = function(){ + return History.storedStates[History.storedStates.length-1]||undefined; + }; + + /** + * History.hasUrlDuplicate + * Checks if a Url will have a url conflict + * @param {Object} newState + * @return {Boolean} hasDuplicate + */ + History.hasUrlDuplicate = function(newState) { + // Prepare + var hasDuplicate = false, + oldState; + + // Fetch + oldState = History.extractState(newState.url); + + // Check + hasDuplicate = oldState && oldState.id !== newState.id; + + // Return + return hasDuplicate; + }; + + /** + * History.storeState + * Store a State + * @param {Object} newState + * @return {Object} newState + */ + History.storeState = function(newState){ + // Store the State + History.urlToId[newState.url] = newState.id; + + // Push the State + History.storedStates.push(History.cloneObject(newState)); + + // Return newState + return newState; + }; + + /** + * History.isLastSavedState(newState) + * Tests to see if the state is the last state + * @param {Object} newState + * @return {boolean} isLast + */ + History.isLastSavedState = function(newState){ + // Prepare + var isLast = false, + newId, oldState, oldId; + + // Check + if ( History.savedStates.length ) { + newId = newState.id; + oldState = History.getLastSavedState(); + oldId = oldState.id; + + // Check + isLast = (newId === oldId); + } + + // Return + return isLast; + }; + + /** + * History.saveState + * Push a State + * @param {Object} newState + * @return {boolean} changed + */ + History.saveState = function(newState){ + // Check Hash + if ( History.isLastSavedState(newState) ) { + return false; + } + + // Push the State + History.savedStates.push(History.cloneObject(newState)); + + // Return true + return true; + }; + + /** + * History.getStateByIndex() + * Gets a state by the index + * @param {integer} index + * @return {Object} + */ + History.getStateByIndex = function(index){ + // Prepare + var State = null; + + // Handle + if ( typeof index === 'undefined' ) { + // Get the last inserted + State = History.savedStates[History.savedStates.length-1]; + } + else if ( index < 0 ) { + // Get from the end + State = History.savedStates[History.savedStates.length+index]; + } + else { + // Get from the beginning + State = History.savedStates[index]; + } + + // Return State + return State; + }; + + /** + * History.getCurrentIndex() + * Gets the current index + * @return (integer) + */ + History.getCurrentIndex = function(){ + // Prepare + var index = null; + + // No states saved + if(History.savedStates.length < 1) { + index = 0; + } + else { + index = History.savedStates.length-1; + } + return index; + }; + + // ==================================================================== + // Hash Helpers + + /** + * History.getHash() + * @param {Location=} location + * Gets the current document hash + * Note: unlike location.hash, this is guaranteed to return the escaped hash in all browsers + * @return {string} + */ + History.getHash = function(doc){ + var url = History.getLocationHref(doc), + hash; + hash = History.getHashByUrl(url); + return hash; + }; + + /** + * History.unescapeHash() + * normalize and Unescape a Hash + * @param {String} hash + * @return {string} + */ + History.unescapeHash = function(hash){ + // Prepare + var result = History.normalizeHash(hash); + + // Unescape hash + result = decodeURIComponent(result); + + // Return result + return result; + }; + + /** + * History.normalizeHash() + * normalize a hash across browsers + * @return {string} + */ + History.normalizeHash = function(hash){ + // Prepare + var result = hash.replace(/[^#]*#/,'').replace(/#.*/, ''); + + // Return result + return result; + }; + + /** + * History.setHash(hash) + * Sets the document hash + * @param {string} hash + * @return {History} + */ + History.setHash = function(hash,queue){ + // Prepare + var State, pageUrl; + + // Handle Queueing + if ( queue !== false && History.busy() ) { + // Wait + Push to Queue + //History.debug('History.setHash: we must wait', arguments); + History.pushQueue({ + scope: History, + callback: History.setHash, + args: arguments, + queue: queue + }); + return false; + } + + // Log + //History.debug('History.setHash: called',hash); + + // Make Busy + Continue + History.busy(true); + + // Check if hash is a state + State = History.extractState(hash,true); + if ( State && !History.emulated.pushState ) { + // Hash is a state so skip the setHash + //History.debug('History.setHash: Hash is a state so skipping the hash set with a direct pushState call',arguments); + + // PushState + History.pushState(State.data,State.title,State.url,false); + } + else if ( History.getHash() !== hash ) { + // Hash is a proper hash, so apply it + + // Handle browser bugs + if ( History.bugs.setHash ) { + // Fix Safari Bug https://bugs.webkit.org/show_bug.cgi?id=56249 + + // Fetch the base page + pageUrl = History.getPageUrl(); + + // Safari hash apply + History.pushState(null,null,pageUrl+'#'+hash,false); + } + else { + // Normal hash apply + document.location.hash = hash; + } + } + + // Chain + return History; + }; + + /** + * History.escape() + * normalize and Escape a Hash + * @return {string} + */ + History.escapeHash = function(hash){ + // Prepare + var result = History.normalizeHash(hash); + + // Escape hash + result = window.encodeURIComponent(result); + + // IE6 Escape Bug + if ( !History.bugs.hashEscape ) { + // Restore common parts + result = result + .replace(/\%21/g,'!') + .replace(/\%26/g,'&') + .replace(/\%3D/g,'=') + .replace(/\%3F/g,'?'); + } + + // Return result + return result; + }; + + /** + * History.getHashByUrl(url) + * Extracts the Hash from a URL + * @param {string} url + * @return {string} url + */ + History.getHashByUrl = function(url){ + // Extract the hash + var hash = String(url) + .replace(/([^#]*)#?([^#]*)#?(.*)/, '$2') + ; + + // Unescape hash + hash = History.unescapeHash(hash); + + // Return hash + return hash; + }; + + /** + * History.setTitle(title) + * Applies the title to the document + * @param {State} newState + * @return {Boolean} + */ + History.setTitle = function(newState){ + // Prepare + var title = newState.title, + firstState; + + // Initial + if ( !title ) { + firstState = History.getStateByIndex(0); + if ( firstState && firstState.url === newState.url ) { + title = firstState.title||History.options.initialTitle; + } + } + + // Apply + try { + document.getElementsByTagName('title')[0].innerHTML = title.replace('<','<').replace('>','>').replace(' & ',' & '); + } + catch ( Exception ) { } + document.title = title; + + // Chain + return History; + }; + + + // ==================================================================== + // Queueing + + /** + * History.queues + * The list of queues to use + * First In, First Out + */ + History.queues = []; + + /** + * History.busy(value) + * @param {boolean} value [optional] + * @return {boolean} busy + */ + History.busy = function(value){ + // Apply + if ( typeof value !== 'undefined' ) { + //History.debug('History.busy: changing ['+(History.busy.flag||false)+'] to ['+(value||false)+']', History.queues.length); + History.busy.flag = value; + } + // Default + else if ( typeof History.busy.flag === 'undefined' ) { + History.busy.flag = false; + } + + // Queue + if ( !History.busy.flag ) { + // Execute the next item in the queue + clearTimeout(History.busy.timeout); + var fireNext = function(){ + var i, queue, item; + if ( History.busy.flag ) return; + for ( i=History.queues.length-1; i >= 0; --i ) { + queue = History.queues[i]; + if ( queue.length === 0 ) continue; + item = queue.shift(); + History.fireQueueItem(item); + History.busy.timeout = setTimeout(fireNext,History.options.busyDelay); + } + }; + History.busy.timeout = setTimeout(fireNext,History.options.busyDelay); + } + + // Return + return History.busy.flag; + }; + + /** + * History.busy.flag + */ + History.busy.flag = false; + + /** + * History.fireQueueItem(item) + * Fire a Queue Item + * @param {Object} item + * @return {Mixed} result + */ + History.fireQueueItem = function(item){ + return item.callback.apply(item.scope||History,item.args||[]); + }; + + /** + * History.pushQueue(callback,args) + * Add an item to the queue + * @param {Object} item [scope,callback,args,queue] + */ + History.pushQueue = function(item){ + // Prepare the queue + History.queues[item.queue||0] = History.queues[item.queue||0]||[]; + + // Add to the queue + History.queues[item.queue||0].push(item); + + // Chain + return History; + }; + + /** + * History.queue (item,queue), (func,queue), (func), (item) + * Either firs the item now if not busy, or adds it to the queue + */ + History.queue = function(item,queue){ + // Prepare + if ( typeof item === 'function' ) { + item = { + callback: item + }; + } + if ( typeof queue !== 'undefined' ) { + item.queue = queue; + } + + // Handle + if ( History.busy() ) { + History.pushQueue(item); + } else { + History.fireQueueItem(item); + } + + // Chain + return History; + }; + + /** + * History.clearQueue() + * Clears the Queue + */ + History.clearQueue = function(){ + History.busy.flag = false; + History.queues = []; + return History; + }; + + + // ==================================================================== + // IE Bug Fix + + /** + * History.stateChanged + * States whether or not the state has changed since the last double check was initialised + */ + History.stateChanged = false; + + /** + * History.doubleChecker + * Contains the timeout used for the double checks + */ + History.doubleChecker = false; + + /** + * History.doubleCheckComplete() + * Complete a double check + * @return {History} + */ + History.doubleCheckComplete = function(){ + // Update + History.stateChanged = true; + + // Clear + History.doubleCheckClear(); + + // Chain + return History; + }; + + /** + * History.doubleCheckClear() + * Clear a double check + * @return {History} + */ + History.doubleCheckClear = function(){ + // Clear + if ( History.doubleChecker ) { + clearTimeout(History.doubleChecker); + History.doubleChecker = false; + } + + // Chain + return History; + }; + + /** + * History.doubleCheck() + * Create a double check + * @return {History} + */ + History.doubleCheck = function(tryAgain){ + // Reset + History.stateChanged = false; + History.doubleCheckClear(); + + // Fix IE6,IE7 bug where calling history.back or history.forward does not actually change the hash (whereas doing it manually does) + // Fix Safari 5 bug where sometimes the state does not change: https://bugs.webkit.org/show_bug.cgi?id=42940 + if ( History.bugs.ieDoubleCheck ) { + // Apply Check + History.doubleChecker = setTimeout( + function(){ + History.doubleCheckClear(); + if ( !History.stateChanged ) { + //History.debug('History.doubleCheck: State has not yet changed, trying again', arguments); + // Re-Attempt + tryAgain(); + } + return true; + }, + History.options.doubleCheckInterval + ); + } + + // Chain + return History; + }; + + + // ==================================================================== + // Safari Bug Fix + + /** + * History.safariStatePoll() + * Poll the current state + * @return {History} + */ + History.safariStatePoll = function(){ + // Poll the URL + + // Get the Last State which has the new URL + var + urlState = History.extractState(History.getLocationHref()), + newState; + + // Check for a difference + if ( !History.isLastSavedState(urlState) ) { + newState = urlState; + } + else { + return; + } + + // Check if we have a state with that url + // If not create it + if ( !newState ) { + //History.debug('History.safariStatePoll: new'); + newState = History.createStateObject(); + } + + // Apply the New State + //History.debug('History.safariStatePoll: trigger'); + History.Adapter.trigger(window,'popstate'); + + // Chain + return History; + }; + + + // ==================================================================== + // State Aliases + + /** + * History.back(queue) + * Send the browser history back one item + * @param {Integer} queue [optional] + */ + History.back = function(queue){ + //History.debug('History.back: called', arguments); + + // Handle Queueing + if ( queue !== false && History.busy() ) { + // Wait + Push to Queue + //History.debug('History.back: we must wait', arguments); + History.pushQueue({ + scope: History, + callback: History.back, + args: arguments, + queue: queue + }); + return false; + } + + // Make Busy + Continue + History.busy(true); + + // Fix certain browser bugs that prevent the state from changing + History.doubleCheck(function(){ + History.back(false); + }); + + // Go back + history.go(-1); + + // End back closure + return true; + }; + + /** + * History.forward(queue) + * Send the browser history forward one item + * @param {Integer} queue [optional] + */ + History.forward = function(queue){ + //History.debug('History.forward: called', arguments); + + // Handle Queueing + if ( queue !== false && History.busy() ) { + // Wait + Push to Queue + //History.debug('History.forward: we must wait', arguments); + History.pushQueue({ + scope: History, + callback: History.forward, + args: arguments, + queue: queue + }); + return false; + } + + // Make Busy + Continue + History.busy(true); + + // Fix certain browser bugs that prevent the state from changing + History.doubleCheck(function(){ + History.forward(false); + }); + + // Go forward + history.go(1); + + // End forward closure + return true; + }; + + /** + * History.go(index,queue) + * Send the browser history back or forward index times + * @param {Integer} queue [optional] + */ + History.go = function(index,queue){ + //History.debug('History.go: called', arguments); + + // Prepare + var i; + + // Handle + if ( index > 0 ) { + // Forward + for ( i=1; i<=index; ++i ) { + History.forward(queue); + } + } + else if ( index < 0 ) { + // Backward + for ( i=-1; i>=index; --i ) { + History.back(queue); + } + } + else { + throw new Error('History.go: History.go requires a positive or negative integer passed.'); + } + + // Chain + return History; + }; + + + // ==================================================================== + // HTML5 State Support + + // Non-Native pushState Implementation + if ( History.emulated.pushState ) { + /* + * Provide Skeleton for HTML4 Browsers + */ + + // Prepare + var emptyFunction = function(){}; + History.pushState = History.pushState||emptyFunction; + History.replaceState = History.replaceState||emptyFunction; + } // History.emulated.pushState + + // Native pushState Implementation + else { + /* + * Use native HTML5 History API Implementation + */ + + /** + * History.onPopState(event,extra) + * Refresh the Current State + */ + History.onPopState = function(event,extra){ + // Prepare + var stateId = false, newState = false, currentHash, currentState; + + // Reset the double check + History.doubleCheckComplete(); + + // Check for a Hash, and handle apporiatly + currentHash = History.getHash(); + if ( currentHash ) { + // Expand Hash + currentState = History.extractState(currentHash||History.getLocationHref(),true); + if ( currentState ) { + // We were able to parse it, it must be a State! + // Let's forward to replaceState + //History.debug('History.onPopState: state anchor', currentHash, currentState); + History.replaceState(currentState.data, currentState.title, currentState.url, false); + } + else { + // Traditional Anchor + //History.debug('History.onPopState: traditional anchor', currentHash); + History.Adapter.trigger(window,'anchorchange'); + History.busy(false); + } + + // We don't care for hashes + History.expectedStateId = false; + return false; + } + + // Ensure + stateId = History.Adapter.extractEventData('state',event,extra) || false; + + // Fetch State + if ( stateId ) { + // Vanilla: Back/forward button was used + newState = History.getStateById(stateId); + } + else if ( History.expectedStateId ) { + // Vanilla: A new state was pushed, and popstate was called manually + newState = History.getStateById(History.expectedStateId); + } + else { + // Initial State + newState = History.extractState(History.getLocationHref()); + } + + // The State did not exist in our store + if ( !newState ) { + // Regenerate the State + newState = History.createStateObject(null,null,History.getLocationHref()); + } + + // Clean + History.expectedStateId = false; + + // Check if we are the same state + if ( History.isLastSavedState(newState) ) { + // There has been no change (just the page's hash has finally propagated) + //History.debug('History.onPopState: no change', newState, History.savedStates); + History.busy(false); + return false; + } + + // Store the State + History.storeState(newState); + History.saveState(newState); + + // Force update of the title + History.setTitle(newState); + + // Fire Our Event + History.Adapter.trigger(window,'statechange'); + History.busy(false); + + // Return true + return true; + }; + History.Adapter.bind(window,'popstate',History.onPopState); + + /** + * History.pushState(data,title,url) + * Add a new State to the history object, become it, and trigger onpopstate + * We have to trigger for HTML4 compatibility + * @param {object} data + * @param {string} title + * @param {string} url + * @return {true} + */ + History.pushState = function(data,title,url,queue){ + //History.debug('History.pushState: called', arguments); + + // Check the State + if ( History.getHashByUrl(url) && History.emulated.pushState ) { + throw new Error('History.js does not support states with fragement-identifiers (hashes/anchors).'); + } + + // Handle Queueing + if ( queue !== false && History.busy() ) { + // Wait + Push to Queue + //History.debug('History.pushState: we must wait', arguments); + History.pushQueue({ + scope: History, + callback: History.pushState, + args: arguments, + queue: queue + }); + return false; + } + + // Make Busy + Continue + History.busy(true); + + // Create the newState + var newState = History.createStateObject(data,title,url); + + // Check it + if ( History.isLastSavedState(newState) ) { + // Won't be a change + History.busy(false); + } + else { + // Store the newState + History.storeState(newState); + History.expectedStateId = newState.id; + + // Push the newState + history.pushState(newState.id,newState.title,newState.url); + + // Fire HTML5 Event + History.Adapter.trigger(window,'popstate'); + } + + // End pushState closure + return true; + }; + + /** + * History.replaceState(data,title,url) + * Replace the State and trigger onpopstate + * We have to trigger for HTML4 compatibility + * @param {object} data + * @param {string} title + * @param {string} url + * @return {true} + */ + History.replaceState = function(data,title,url,queue){ + //History.debug('History.replaceState: called', arguments); + + // Check the State + if ( History.getHashByUrl(url) && History.emulated.pushState ) { + throw new Error('History.js does not support states with fragement-identifiers (hashes/anchors).'); + } + + // Handle Queueing + if ( queue !== false && History.busy() ) { + // Wait + Push to Queue + //History.debug('History.replaceState: we must wait', arguments); + History.pushQueue({ + scope: History, + callback: History.replaceState, + args: arguments, + queue: queue + }); + return false; + } + + // Make Busy + Continue + History.busy(true); + + // Create the newState + var newState = History.createStateObject(data,title,url); + + // Check it + if ( History.isLastSavedState(newState) ) { + // Won't be a change + History.busy(false); + } + else { + // Store the newState + History.storeState(newState); + History.expectedStateId = newState.id; + + // Push the newState + history.replaceState(newState.id,newState.title,newState.url); + + // Fire HTML5 Event + History.Adapter.trigger(window,'popstate'); + } + + // End replaceState closure + return true; + }; + + } // !History.emulated.pushState + + + // ==================================================================== + // Initialise + + /** + * Load the Store + */ + if ( sessionStorage ) { + // Fetch + try { + History.store = JSON.parse(sessionStorage.getItem('History.store'))||{}; + } + catch ( err ) { + History.store = {}; + } + + // Normalize + History.normalizeStore(); + } + else { + // Default Load + History.store = {}; + History.normalizeStore(); + } + + /** + * Clear Intervals on exit to prevent memory leaks + */ + History.Adapter.bind(window,"unload",History.clearAllIntervals); + + /** + * Create the initial State + */ + History.saveState(History.storeState(History.extractState(History.getLocationHref(),true))); + + /** + * Bind for Saving Store + */ + if ( sessionStorage ) { + // When the page is closed + History.onUnload = function(){ + // Prepare + var currentStore, item, currentStoreString; + + // Fetch + try { + currentStore = JSON.parse(sessionStorage.getItem('History.store'))||{}; + } + catch ( err ) { + currentStore = {}; + } + + // Ensure + currentStore.idToState = currentStore.idToState || {}; + currentStore.urlToId = currentStore.urlToId || {}; + currentStore.stateToId = currentStore.stateToId || {}; + + // Sync + for ( item in History.idToState ) { + if ( !History.idToState.hasOwnProperty(item) ) { + continue; + } + currentStore.idToState[item] = History.idToState[item]; + } + for ( item in History.urlToId ) { + if ( !History.urlToId.hasOwnProperty(item) ) { + continue; + } + currentStore.urlToId[item] = History.urlToId[item]; + } + for ( item in History.stateToId ) { + if ( !History.stateToId.hasOwnProperty(item) ) { + continue; + } + currentStore.stateToId[item] = History.stateToId[item]; + } + + // Update + History.store = currentStore; + History.normalizeStore(); + + // In Safari, going into Private Browsing mode causes the + // Session Storage object to still exist but if you try and use + // or set any property/function of it it throws the exception + // "QUOTA_EXCEEDED_ERR: DOM Exception 22: An attempt was made to + // add something to storage that exceeded the quota." infinitely + // every second. + currentStoreString = JSON.stringify(currentStore); + try { + // Store + sessionStorage.setItem('History.store', currentStoreString); + } + catch (e) { + if (e.code === DOMException.QUOTA_EXCEEDED_ERR) { + if (sessionStorage.length) { + // Workaround for a bug seen on iPads. Sometimes the quota exceeded error comes up and simply + // removing/resetting the storage can work. + sessionStorage.removeItem('History.store'); + sessionStorage.setItem('History.store', currentStoreString); + } else { + // Otherwise, we're probably private browsing in Safari, so we'll ignore the exception. + } + } else { + throw e; + } + } + }; + + // For Internet Explorer + History.intervalList.push(setInterval(History.onUnload,History.options.storeInterval)); + + // For Other Browsers + History.Adapter.bind(window,'beforeunload',History.onUnload); + History.Adapter.bind(window,'unload',History.onUnload); + + // Both are enabled for consistency + } + + // Non-Native pushState Implementation + if ( !History.emulated.pushState ) { + // Be aware, the following is only for native pushState implementations + // If you are wanting to include something for all browsers + // Then include it above this if block + + /** + * Setup Safari Fix + */ + if ( History.bugs.safariPoll ) { + History.intervalList.push(setInterval(History.safariStatePoll, History.options.safariPollInterval)); + } + + /** + * Ensure Cross Browser Compatibility + */ + if ( navigator.vendor === 'Apple Computer, Inc.' || (navigator.appCodeName||'') === 'Mozilla' ) { + /** + * Fix Safari HashChange Issue + */ + + // Setup Alias + History.Adapter.bind(window,'hashchange',function(){ + History.Adapter.trigger(window,'popstate'); + }); + + // Initialise Alias + if ( History.getHash() ) { + History.Adapter.onDomLoad(function(){ + History.Adapter.trigger(window,'hashchange'); + }); + } + } + + } // !History.emulated.pushState + + + }; // History.initCore + + // Try to Initialise History + if (!History.options || !History.options.delayInit) { + History.init(); + } + +})(window); diff --git a/sites/all/themes/gui/materiobasetheme/bower_components/history.js/scripts/bundled-uncompressed/html5/zepto.history.js b/sites/all/themes/gui/materiobasetheme/bower_components/history.js/scripts/bundled-uncompressed/html5/zepto.history.js new file mode 100644 index 00000000..f35ea195 --- /dev/null +++ b/sites/all/themes/gui/materiobasetheme/bower_components/history.js/scripts/bundled-uncompressed/html5/zepto.history.js @@ -0,0 +1,2118 @@ +/** + * History.js Zepto Adapter + * @author Benjamin Arthur Lupton + * @copyright 2010-2011 Benjamin Arthur Lupton + * @license New BSD License + */ + +// Closure +(function(window,undefined){ + "use strict"; + + // Localise Globals + var + History = window.History = window.History||{}, + Zepto = window.Zepto; + + // Check Existence + if ( typeof History.Adapter !== 'undefined' ) { + throw new Error('History.js Adapter has already been loaded...'); + } + + // Add the Adapter + History.Adapter = { + /** + * History.Adapter.bind(el,event,callback) + * @param {Element|string} el + * @param {string} event - custom and standard events + * @param {function} callback + * @return {void} + */ + bind: function(el,event,callback){ + new Zepto(el).bind(event,callback); + }, + + /** + * History.Adapter.trigger(el,event) + * @param {Element|string} el + * @param {string} event - custom and standard events + * @return {void} + */ + trigger: function(el,event){ + new Zepto(el).trigger(event); + }, + + /** + * History.Adapter.extractEventData(key,event,extra) + * @param {string} key - key for the event data to extract + * @param {string} event - custom and standard events + * @return {mixed} + */ + extractEventData: function(key,event){ + // Zepto Native + var result = (event && event[key]) || undefined; + + // Return + return result; + }, + + /** + * History.Adapter.onDomLoad(callback) + * @param {function} callback + * @return {void} + */ + onDomLoad: function(callback) { + new Zepto(callback); + } + }; + + // Try and Initialise History + if ( typeof History.init !== 'undefined' ) { + History.init(); + } + +})(window); +/** + * History.js Core + * @author Benjamin Arthur Lupton + * @copyright 2010-2011 Benjamin Arthur Lupton + * @license New BSD License + */ + +(function(window,undefined){ + "use strict"; + + // ======================================================================== + // Initialise + + // Localise Globals + var + console = window.console||undefined, // Prevent a JSLint complain + document = window.document, // Make sure we are using the correct document + navigator = window.navigator, // Make sure we are using the correct navigator + sessionStorage = window.sessionStorage||false, // sessionStorage + setTimeout = window.setTimeout, + clearTimeout = window.clearTimeout, + setInterval = window.setInterval, + clearInterval = window.clearInterval, + JSON = window.JSON, + alert = window.alert, + History = window.History = window.History||{}, // Public History Object + history = window.history; // Old History Object + + try { + sessionStorage.setItem('TEST', '1'); + sessionStorage.removeItem('TEST'); + } catch(e) { + sessionStorage = false; + } + + // MooTools Compatibility + JSON.stringify = JSON.stringify||JSON.encode; + JSON.parse = JSON.parse||JSON.decode; + + // Check Existence + if ( typeof History.init !== 'undefined' ) { + throw new Error('History.js Core has already been loaded...'); + } + + // Initialise History + History.init = function(options){ + // Check Load Status of Adapter + if ( typeof History.Adapter === 'undefined' ) { + return false; + } + + // Check Load Status of Core + if ( typeof History.initCore !== 'undefined' ) { + History.initCore(); + } + + // Check Load Status of HTML4 Support + if ( typeof History.initHtml4 !== 'undefined' ) { + History.initHtml4(); + } + + // Return true + return true; + }; + + + // ======================================================================== + // Initialise Core + + // Initialise Core + History.initCore = function(options){ + // Initialise + if ( typeof History.initCore.initialized !== 'undefined' ) { + // Already Loaded + return false; + } + else { + History.initCore.initialized = true; + } + + + // ==================================================================== + // Options + + /** + * History.options + * Configurable options + */ + History.options = History.options||{}; + + /** + * History.options.hashChangeInterval + * How long should the interval be before hashchange checks + */ + History.options.hashChangeInterval = History.options.hashChangeInterval || 100; + + /** + * History.options.safariPollInterval + * How long should the interval be before safari poll checks + */ + History.options.safariPollInterval = History.options.safariPollInterval || 500; + + /** + * History.options.doubleCheckInterval + * How long should the interval be before we perform a double check + */ + History.options.doubleCheckInterval = History.options.doubleCheckInterval || 500; + + /** + * History.options.disableSuid + * Force History not to append suid + */ + History.options.disableSuid = History.options.disableSuid || false; + + /** + * History.options.storeInterval + * How long should we wait between store calls + */ + History.options.storeInterval = History.options.storeInterval || 1000; + + /** + * History.options.busyDelay + * How long should we wait between busy events + */ + History.options.busyDelay = History.options.busyDelay || 250; + + /** + * History.options.debug + * If true will enable debug messages to be logged + */ + History.options.debug = History.options.debug || false; + + /** + * History.options.initialTitle + * What is the title of the initial state + */ + History.options.initialTitle = History.options.initialTitle || document.title; + + /** + * History.options.html4Mode + * If true, will force HTMl4 mode (hashtags) + */ + History.options.html4Mode = History.options.html4Mode || false; + + /** + * History.options.delayInit + * Want to override default options and call init manually. + */ + History.options.delayInit = History.options.delayInit || false; + + + // ==================================================================== + // Interval record + + /** + * History.intervalList + * List of intervals set, to be cleared when document is unloaded. + */ + History.intervalList = []; + + /** + * History.clearAllIntervals + * Clears all setInterval instances. + */ + History.clearAllIntervals = function(){ + var i, il = History.intervalList; + if (typeof il !== "undefined" && il !== null) { + for (i = 0; i < il.length; i++) { + clearInterval(il[i]); + } + History.intervalList = null; + } + }; + + + // ==================================================================== + // Debug + + /** + * History.debug(message,...) + * Logs the passed arguments if debug enabled + */ + History.debug = function(){ + if ( (History.options.debug||false) ) { + History.log.apply(History,arguments); + } + }; + + /** + * History.log(message,...) + * Logs the passed arguments + */ + History.log = function(){ + // Prepare + var + consoleExists = !(typeof console === 'undefined' || typeof console.log === 'undefined' || typeof console.log.apply === 'undefined'), + textarea = document.getElementById('log'), + message, + i,n, + args,arg + ; + + // Write to Console + if ( consoleExists ) { + args = Array.prototype.slice.call(arguments); + message = args.shift(); + if ( typeof console.debug !== 'undefined' ) { + console.debug.apply(console,[message,args]); + } + else { + console.log.apply(console,[message,args]); + } + } + else { + message = ("\n"+arguments[0]+"\n"); + } + + // Write to log + for ( i=1,n=arguments.length; i + * @author James Padolsey + */ + History.getInternetExplorerMajorVersion = function(){ + var result = History.getInternetExplorerMajorVersion.cached = + (typeof History.getInternetExplorerMajorVersion.cached !== 'undefined') + ? History.getInternetExplorerMajorVersion.cached + : (function(){ + var v = 3, + div = document.createElement('div'), + all = div.getElementsByTagName('i'); + while ( (div.innerHTML = '') && all[0] ) {} + return (v > 4) ? v : false; + })() + ; + return result; + }; + + /** + * History.isInternetExplorer() + * Are we using Internet Explorer? + * @return {boolean} + * @license Public Domain + * @author Benjamin Arthur Lupton + */ + History.isInternetExplorer = function(){ + var result = + History.isInternetExplorer.cached = + (typeof History.isInternetExplorer.cached !== 'undefined') + ? History.isInternetExplorer.cached + : Boolean(History.getInternetExplorerMajorVersion()) + ; + return result; + }; + + /** + * History.emulated + * Which features require emulating? + */ + + if (History.options.html4Mode) { + History.emulated = { + pushState : true, + hashChange: true + }; + } + + else { + + History.emulated = { + pushState: !Boolean( + window.history && window.history.pushState && window.history.replaceState + && !( + (/ Mobile\/([1-7][a-z]|(8([abcde]|f(1[0-8]))))/i).test(navigator.userAgent) /* disable for versions of iOS before version 4.3 (8F190) */ + || (/AppleWebKit\/5([0-2]|3[0-2])/i).test(navigator.userAgent) /* disable for the mercury iOS browser, or at least older versions of the webkit engine */ + ) + ), + hashChange: Boolean( + !(('onhashchange' in window) || ('onhashchange' in document)) + || + (History.isInternetExplorer() && History.getInternetExplorerMajorVersion() < 8) + ) + }; + } + + /** + * History.enabled + * Is History enabled? + */ + History.enabled = !History.emulated.pushState; + + /** + * History.bugs + * Which bugs are present + */ + History.bugs = { + /** + * Safari 5 and Safari iOS 4 fail to return to the correct state once a hash is replaced by a `replaceState` call + * https://bugs.webkit.org/show_bug.cgi?id=56249 + */ + setHash: Boolean(!History.emulated.pushState && navigator.vendor === 'Apple Computer, Inc.' && /AppleWebKit\/5([0-2]|3[0-3])/.test(navigator.userAgent)), + + /** + * Safari 5 and Safari iOS 4 sometimes fail to apply the state change under busy conditions + * https://bugs.webkit.org/show_bug.cgi?id=42940 + */ + safariPoll: Boolean(!History.emulated.pushState && navigator.vendor === 'Apple Computer, Inc.' && /AppleWebKit\/5([0-2]|3[0-3])/.test(navigator.userAgent)), + + /** + * MSIE 6 and 7 sometimes do not apply a hash even it was told to (requiring a second call to the apply function) + */ + ieDoubleCheck: Boolean(History.isInternetExplorer() && History.getInternetExplorerMajorVersion() < 8), + + /** + * MSIE 6 requires the entire hash to be encoded for the hashes to trigger the onHashChange event + */ + hashEscape: Boolean(History.isInternetExplorer() && History.getInternetExplorerMajorVersion() < 7) + }; + + /** + * History.isEmptyObject(obj) + * Checks to see if the Object is Empty + * @param {Object} obj + * @return {boolean} + */ + History.isEmptyObject = function(obj) { + for ( var name in obj ) { + if ( obj.hasOwnProperty(name) ) { + return false; + } + } + return true; + }; + + /** + * History.cloneObject(obj) + * Clones a object and eliminate all references to the original contexts + * @param {Object} obj + * @return {Object} + */ + History.cloneObject = function(obj) { + var hash,newObj; + if ( obj ) { + hash = JSON.stringify(obj); + newObj = JSON.parse(hash); + } + else { + newObj = {}; + } + return newObj; + }; + + + // ==================================================================== + // URL Helpers + + /** + * History.getRootUrl() + * Turns "http://mysite.com/dir/page.html?asd" into "http://mysite.com" + * @return {String} rootUrl + */ + History.getRootUrl = function(){ + // Create + var rootUrl = document.location.protocol+'//'+(document.location.hostname||document.location.host); + if ( document.location.port||false ) { + rootUrl += ':'+document.location.port; + } + rootUrl += '/'; + + // Return + return rootUrl; + }; + + /** + * History.getBaseHref() + * Fetches the `href` attribute of the `` element if it exists + * @return {String} baseHref + */ + History.getBaseHref = function(){ + // Create + var + baseElements = document.getElementsByTagName('base'), + baseElement = null, + baseHref = ''; + + // Test for Base Element + if ( baseElements.length === 1 ) { + // Prepare for Base Element + baseElement = baseElements[0]; + baseHref = baseElement.href.replace(/[^\/]+$/,''); + } + + // Adjust trailing slash + baseHref = baseHref.replace(/\/+$/,''); + if ( baseHref ) baseHref += '/'; + + // Return + return baseHref; + }; + + /** + * History.getBaseUrl() + * Fetches the baseHref or basePageUrl or rootUrl (whichever one exists first) + * @return {String} baseUrl + */ + History.getBaseUrl = function(){ + // Create + var baseUrl = History.getBaseHref()||History.getBasePageUrl()||History.getRootUrl(); + + // Return + return baseUrl; + }; + + /** + * History.getPageUrl() + * Fetches the URL of the current page + * @return {String} pageUrl + */ + History.getPageUrl = function(){ + // Fetch + var + State = History.getState(false,false), + stateUrl = (State||{}).url||History.getLocationHref(), + pageUrl; + + // Create + pageUrl = stateUrl.replace(/\/+$/,'').replace(/[^\/]+$/,function(part,index,string){ + return (/\./).test(part) ? part : part+'/'; + }); + + // Return + return pageUrl; + }; + + /** + * History.getBasePageUrl() + * Fetches the Url of the directory of the current page + * @return {String} basePageUrl + */ + History.getBasePageUrl = function(){ + // Create + var basePageUrl = (History.getLocationHref()).replace(/[#\?].*/,'').replace(/[^\/]+$/,function(part,index,string){ + return (/[^\/]$/).test(part) ? '' : part; + }).replace(/\/+$/,'')+'/'; + + // Return + return basePageUrl; + }; + + /** + * History.getFullUrl(url) + * Ensures that we have an absolute URL and not a relative URL + * @param {string} url + * @param {Boolean} allowBaseHref + * @return {string} fullUrl + */ + History.getFullUrl = function(url,allowBaseHref){ + // Prepare + var fullUrl = url, firstChar = url.substring(0,1); + allowBaseHref = (typeof allowBaseHref === 'undefined') ? true : allowBaseHref; + + // Check + if ( /[a-z]+\:\/\//.test(url) ) { + // Full URL + } + else if ( firstChar === '/' ) { + // Root URL + fullUrl = History.getRootUrl()+url.replace(/^\/+/,''); + } + else if ( firstChar === '#' ) { + // Anchor URL + fullUrl = History.getPageUrl().replace(/#.*/,'')+url; + } + else if ( firstChar === '?' ) { + // Query URL + fullUrl = History.getPageUrl().replace(/[\?#].*/,'')+url; + } + else { + // Relative URL + if ( allowBaseHref ) { + fullUrl = History.getBaseUrl()+url.replace(/^(\.\/)+/,''); + } else { + fullUrl = History.getBasePageUrl()+url.replace(/^(\.\/)+/,''); + } + // We have an if condition above as we do not want hashes + // which are relative to the baseHref in our URLs + // as if the baseHref changes, then all our bookmarks + // would now point to different locations + // whereas the basePageUrl will always stay the same + } + + // Return + return fullUrl.replace(/\#$/,''); + }; + + /** + * History.getShortUrl(url) + * Ensures that we have a relative URL and not a absolute URL + * @param {string} url + * @return {string} url + */ + History.getShortUrl = function(url){ + // Prepare + var shortUrl = url, baseUrl = History.getBaseUrl(), rootUrl = History.getRootUrl(); + + // Trim baseUrl + if ( History.emulated.pushState ) { + // We are in a if statement as when pushState is not emulated + // The actual url these short urls are relative to can change + // So within the same session, we the url may end up somewhere different + shortUrl = shortUrl.replace(baseUrl,''); + } + + // Trim rootUrl + shortUrl = shortUrl.replace(rootUrl,'/'); + + // Ensure we can still detect it as a state + if ( History.isTraditionalAnchor(shortUrl) ) { + shortUrl = './'+shortUrl; + } + + // Clean It + shortUrl = shortUrl.replace(/^(\.\/)+/g,'./').replace(/\#$/,''); + + // Return + return shortUrl; + }; + + /** + * History.getLocationHref(document) + * Returns a normalized version of document.location.href + * accounting for browser inconsistencies, etc. + * + * This URL will be URI-encoded and will include the hash + * + * @param {object} document + * @return {string} url + */ + History.getLocationHref = function(doc) { + doc = doc || document; + + // most of the time, this will be true + if (doc.URL === doc.location.href) + return doc.location.href; + + // some versions of webkit URI-decode document.location.href + // but they leave document.URL in an encoded state + if (doc.location.href === decodeURIComponent(doc.URL)) + return doc.URL; + + // FF 3.6 only updates document.URL when a page is reloaded + // document.location.href is updated correctly + if (doc.location.hash && decodeURIComponent(doc.location.href.replace(/^[^#]+/, "")) === doc.location.hash) + return doc.location.href; + + if (doc.URL.indexOf('#') == -1 && doc.location.href.indexOf('#') != -1) + return doc.location.href; + + return doc.URL || doc.location.href; + }; + + + // ==================================================================== + // State Storage + + /** + * History.store + * The store for all session specific data + */ + History.store = {}; + + /** + * History.idToState + * 1-1: State ID to State Object + */ + History.idToState = History.idToState||{}; + + /** + * History.stateToId + * 1-1: State String to State ID + */ + History.stateToId = History.stateToId||{}; + + /** + * History.urlToId + * 1-1: State URL to State ID + */ + History.urlToId = History.urlToId||{}; + + /** + * History.storedStates + * Store the states in an array + */ + History.storedStates = History.storedStates||[]; + + /** + * History.savedStates + * Saved the states in an array + */ + History.savedStates = History.savedStates||[]; + + /** + * History.noramlizeStore() + * Noramlize the store by adding necessary values + */ + History.normalizeStore = function(){ + History.store.idToState = History.store.idToState||{}; + History.store.urlToId = History.store.urlToId||{}; + History.store.stateToId = History.store.stateToId||{}; + }; + + /** + * History.getState() + * Get an object containing the data, title and url of the current state + * @param {Boolean} friendly + * @param {Boolean} create + * @return {Object} State + */ + History.getState = function(friendly,create){ + // Prepare + if ( typeof friendly === 'undefined' ) { friendly = true; } + if ( typeof create === 'undefined' ) { create = true; } + + // Fetch + var State = History.getLastSavedState(); + + // Create + if ( !State && create ) { + State = History.createStateObject(); + } + + // Adjust + if ( friendly ) { + State = History.cloneObject(State); + State.url = State.cleanUrl||State.url; + } + + // Return + return State; + }; + + /** + * History.getIdByState(State) + * Gets a ID for a State + * @param {State} newState + * @return {String} id + */ + History.getIdByState = function(newState){ + + // Fetch ID + var id = History.extractId(newState.url), + str; + + if ( !id ) { + // Find ID via State String + str = History.getStateString(newState); + if ( typeof History.stateToId[str] !== 'undefined' ) { + id = History.stateToId[str]; + } + else if ( typeof History.store.stateToId[str] !== 'undefined' ) { + id = History.store.stateToId[str]; + } + else { + // Generate a new ID + while ( true ) { + id = (new Date()).getTime() + String(Math.random()).replace(/\D/g,''); + if ( typeof History.idToState[id] === 'undefined' && typeof History.store.idToState[id] === 'undefined' ) { + break; + } + } + + // Apply the new State to the ID + History.stateToId[str] = id; + History.idToState[id] = newState; + } + } + + // Return ID + return id; + }; + + /** + * History.normalizeState(State) + * Expands a State Object + * @param {object} State + * @return {object} + */ + History.normalizeState = function(oldState){ + // Variables + var newState, dataNotEmpty; + + // Prepare + if ( !oldState || (typeof oldState !== 'object') ) { + oldState = {}; + } + + // Check + if ( typeof oldState.normalized !== 'undefined' ) { + return oldState; + } + + // Adjust + if ( !oldState.data || (typeof oldState.data !== 'object') ) { + oldState.data = {}; + } + + // ---------------------------------------------------------------- + + // Create + newState = {}; + newState.normalized = true; + newState.title = oldState.title||''; + newState.url = History.getFullUrl(oldState.url?oldState.url:(History.getLocationHref())); + newState.hash = History.getShortUrl(newState.url); + newState.data = History.cloneObject(oldState.data); + + // Fetch ID + newState.id = History.getIdByState(newState); + + // ---------------------------------------------------------------- + + // Clean the URL + newState.cleanUrl = newState.url.replace(/\??\&_suid.*/,''); + newState.url = newState.cleanUrl; + + // Check to see if we have more than just a url + dataNotEmpty = !History.isEmptyObject(newState.data); + + // Apply + if ( (newState.title || dataNotEmpty) && History.options.disableSuid !== true ) { + // Add ID to Hash + newState.hash = History.getShortUrl(newState.url).replace(/\??\&_suid.*/,''); + if ( !/\?/.test(newState.hash) ) { + newState.hash += '?'; + } + newState.hash += '&_suid='+newState.id; + } + + // Create the Hashed URL + newState.hashedUrl = History.getFullUrl(newState.hash); + + // ---------------------------------------------------------------- + + // Update the URL if we have a duplicate + if ( (History.emulated.pushState || History.bugs.safariPoll) && History.hasUrlDuplicate(newState) ) { + newState.url = newState.hashedUrl; + } + + // ---------------------------------------------------------------- + + // Return + return newState; + }; + + /** + * History.createStateObject(data,title,url) + * Creates a object based on the data, title and url state params + * @param {object} data + * @param {string} title + * @param {string} url + * @return {object} + */ + History.createStateObject = function(data,title,url){ + // Hashify + var State = { + 'data': data, + 'title': title, + 'url': url + }; + + // Expand the State + State = History.normalizeState(State); + + // Return object + return State; + }; + + /** + * History.getStateById(id) + * Get a state by it's UID + * @param {String} id + */ + History.getStateById = function(id){ + // Prepare + id = String(id); + + // Retrieve + var State = History.idToState[id] || History.store.idToState[id] || undefined; + + // Return State + return State; + }; + + /** + * Get a State's String + * @param {State} passedState + */ + History.getStateString = function(passedState){ + // Prepare + var State, cleanedState, str; + + // Fetch + State = History.normalizeState(passedState); + + // Clean + cleanedState = { + data: State.data, + title: passedState.title, + url: passedState.url + }; + + // Fetch + str = JSON.stringify(cleanedState); + + // Return + return str; + }; + + /** + * Get a State's ID + * @param {State} passedState + * @return {String} id + */ + History.getStateId = function(passedState){ + // Prepare + var State, id; + + // Fetch + State = History.normalizeState(passedState); + + // Fetch + id = State.id; + + // Return + return id; + }; + + /** + * History.getHashByState(State) + * Creates a Hash for the State Object + * @param {State} passedState + * @return {String} hash + */ + History.getHashByState = function(passedState){ + // Prepare + var State, hash; + + // Fetch + State = History.normalizeState(passedState); + + // Hash + hash = State.hash; + + // Return + return hash; + }; + + /** + * History.extractId(url_or_hash) + * Get a State ID by it's URL or Hash + * @param {string} url_or_hash + * @return {string} id + */ + History.extractId = function ( url_or_hash ) { + // Prepare + var id,parts,url, tmp; + + // Extract + + // If the URL has a #, use the id from before the # + if (url_or_hash.indexOf('#') != -1) + { + tmp = url_or_hash.split("#")[0]; + } + else + { + tmp = url_or_hash; + } + + parts = /(.*)\&_suid=([0-9]+)$/.exec(tmp); + url = parts ? (parts[1]||url_or_hash) : url_or_hash; + id = parts ? String(parts[2]||'') : ''; + + // Return + return id||false; + }; + + /** + * History.isTraditionalAnchor + * Checks to see if the url is a traditional anchor or not + * @param {String} url_or_hash + * @return {Boolean} + */ + History.isTraditionalAnchor = function(url_or_hash){ + // Check + var isTraditional = !(/[\/\?\.]/.test(url_or_hash)); + + // Return + return isTraditional; + }; + + /** + * History.extractState + * Get a State by it's URL or Hash + * @param {String} url_or_hash + * @return {State|null} + */ + History.extractState = function(url_or_hash,create){ + // Prepare + var State = null, id, url; + create = create||false; + + // Fetch SUID + id = History.extractId(url_or_hash); + if ( id ) { + State = History.getStateById(id); + } + + // Fetch SUID returned no State + if ( !State ) { + // Fetch URL + url = History.getFullUrl(url_or_hash); + + // Check URL + id = History.getIdByUrl(url)||false; + if ( id ) { + State = History.getStateById(id); + } + + // Create State + if ( !State && create && !History.isTraditionalAnchor(url_or_hash) ) { + State = History.createStateObject(null,null,url); + } + } + + // Return + return State; + }; + + /** + * History.getIdByUrl() + * Get a State ID by a State URL + */ + History.getIdByUrl = function(url){ + // Fetch + var id = History.urlToId[url] || History.store.urlToId[url] || undefined; + + // Return + return id; + }; + + /** + * History.getLastSavedState() + * Get an object containing the data, title and url of the current state + * @return {Object} State + */ + History.getLastSavedState = function(){ + return History.savedStates[History.savedStates.length-1]||undefined; + }; + + /** + * History.getLastStoredState() + * Get an object containing the data, title and url of the current state + * @return {Object} State + */ + History.getLastStoredState = function(){ + return History.storedStates[History.storedStates.length-1]||undefined; + }; + + /** + * History.hasUrlDuplicate + * Checks if a Url will have a url conflict + * @param {Object} newState + * @return {Boolean} hasDuplicate + */ + History.hasUrlDuplicate = function(newState) { + // Prepare + var hasDuplicate = false, + oldState; + + // Fetch + oldState = History.extractState(newState.url); + + // Check + hasDuplicate = oldState && oldState.id !== newState.id; + + // Return + return hasDuplicate; + }; + + /** + * History.storeState + * Store a State + * @param {Object} newState + * @return {Object} newState + */ + History.storeState = function(newState){ + // Store the State + History.urlToId[newState.url] = newState.id; + + // Push the State + History.storedStates.push(History.cloneObject(newState)); + + // Return newState + return newState; + }; + + /** + * History.isLastSavedState(newState) + * Tests to see if the state is the last state + * @param {Object} newState + * @return {boolean} isLast + */ + History.isLastSavedState = function(newState){ + // Prepare + var isLast = false, + newId, oldState, oldId; + + // Check + if ( History.savedStates.length ) { + newId = newState.id; + oldState = History.getLastSavedState(); + oldId = oldState.id; + + // Check + isLast = (newId === oldId); + } + + // Return + return isLast; + }; + + /** + * History.saveState + * Push a State + * @param {Object} newState + * @return {boolean} changed + */ + History.saveState = function(newState){ + // Check Hash + if ( History.isLastSavedState(newState) ) { + return false; + } + + // Push the State + History.savedStates.push(History.cloneObject(newState)); + + // Return true + return true; + }; + + /** + * History.getStateByIndex() + * Gets a state by the index + * @param {integer} index + * @return {Object} + */ + History.getStateByIndex = function(index){ + // Prepare + var State = null; + + // Handle + if ( typeof index === 'undefined' ) { + // Get the last inserted + State = History.savedStates[History.savedStates.length-1]; + } + else if ( index < 0 ) { + // Get from the end + State = History.savedStates[History.savedStates.length+index]; + } + else { + // Get from the beginning + State = History.savedStates[index]; + } + + // Return State + return State; + }; + + /** + * History.getCurrentIndex() + * Gets the current index + * @return (integer) + */ + History.getCurrentIndex = function(){ + // Prepare + var index = null; + + // No states saved + if(History.savedStates.length < 1) { + index = 0; + } + else { + index = History.savedStates.length-1; + } + return index; + }; + + // ==================================================================== + // Hash Helpers + + /** + * History.getHash() + * @param {Location=} location + * Gets the current document hash + * Note: unlike location.hash, this is guaranteed to return the escaped hash in all browsers + * @return {string} + */ + History.getHash = function(doc){ + var url = History.getLocationHref(doc), + hash; + hash = History.getHashByUrl(url); + return hash; + }; + + /** + * History.unescapeHash() + * normalize and Unescape a Hash + * @param {String} hash + * @return {string} + */ + History.unescapeHash = function(hash){ + // Prepare + var result = History.normalizeHash(hash); + + // Unescape hash + result = decodeURIComponent(result); + + // Return result + return result; + }; + + /** + * History.normalizeHash() + * normalize a hash across browsers + * @return {string} + */ + History.normalizeHash = function(hash){ + // Prepare + var result = hash.replace(/[^#]*#/,'').replace(/#.*/, ''); + + // Return result + return result; + }; + + /** + * History.setHash(hash) + * Sets the document hash + * @param {string} hash + * @return {History} + */ + History.setHash = function(hash,queue){ + // Prepare + var State, pageUrl; + + // Handle Queueing + if ( queue !== false && History.busy() ) { + // Wait + Push to Queue + //History.debug('History.setHash: we must wait', arguments); + History.pushQueue({ + scope: History, + callback: History.setHash, + args: arguments, + queue: queue + }); + return false; + } + + // Log + //History.debug('History.setHash: called',hash); + + // Make Busy + Continue + History.busy(true); + + // Check if hash is a state + State = History.extractState(hash,true); + if ( State && !History.emulated.pushState ) { + // Hash is a state so skip the setHash + //History.debug('History.setHash: Hash is a state so skipping the hash set with a direct pushState call',arguments); + + // PushState + History.pushState(State.data,State.title,State.url,false); + } + else if ( History.getHash() !== hash ) { + // Hash is a proper hash, so apply it + + // Handle browser bugs + if ( History.bugs.setHash ) { + // Fix Safari Bug https://bugs.webkit.org/show_bug.cgi?id=56249 + + // Fetch the base page + pageUrl = History.getPageUrl(); + + // Safari hash apply + History.pushState(null,null,pageUrl+'#'+hash,false); + } + else { + // Normal hash apply + document.location.hash = hash; + } + } + + // Chain + return History; + }; + + /** + * History.escape() + * normalize and Escape a Hash + * @return {string} + */ + History.escapeHash = function(hash){ + // Prepare + var result = History.normalizeHash(hash); + + // Escape hash + result = window.encodeURIComponent(result); + + // IE6 Escape Bug + if ( !History.bugs.hashEscape ) { + // Restore common parts + result = result + .replace(/\%21/g,'!') + .replace(/\%26/g,'&') + .replace(/\%3D/g,'=') + .replace(/\%3F/g,'?'); + } + + // Return result + return result; + }; + + /** + * History.getHashByUrl(url) + * Extracts the Hash from a URL + * @param {string} url + * @return {string} url + */ + History.getHashByUrl = function(url){ + // Extract the hash + var hash = String(url) + .replace(/([^#]*)#?([^#]*)#?(.*)/, '$2') + ; + + // Unescape hash + hash = History.unescapeHash(hash); + + // Return hash + return hash; + }; + + /** + * History.setTitle(title) + * Applies the title to the document + * @param {State} newState + * @return {Boolean} + */ + History.setTitle = function(newState){ + // Prepare + var title = newState.title, + firstState; + + // Initial + if ( !title ) { + firstState = History.getStateByIndex(0); + if ( firstState && firstState.url === newState.url ) { + title = firstState.title||History.options.initialTitle; + } + } + + // Apply + try { + document.getElementsByTagName('title')[0].innerHTML = title.replace('<','<').replace('>','>').replace(' & ',' & '); + } + catch ( Exception ) { } + document.title = title; + + // Chain + return History; + }; + + + // ==================================================================== + // Queueing + + /** + * History.queues + * The list of queues to use + * First In, First Out + */ + History.queues = []; + + /** + * History.busy(value) + * @param {boolean} value [optional] + * @return {boolean} busy + */ + History.busy = function(value){ + // Apply + if ( typeof value !== 'undefined' ) { + //History.debug('History.busy: changing ['+(History.busy.flag||false)+'] to ['+(value||false)+']', History.queues.length); + History.busy.flag = value; + } + // Default + else if ( typeof History.busy.flag === 'undefined' ) { + History.busy.flag = false; + } + + // Queue + if ( !History.busy.flag ) { + // Execute the next item in the queue + clearTimeout(History.busy.timeout); + var fireNext = function(){ + var i, queue, item; + if ( History.busy.flag ) return; + for ( i=History.queues.length-1; i >= 0; --i ) { + queue = History.queues[i]; + if ( queue.length === 0 ) continue; + item = queue.shift(); + History.fireQueueItem(item); + History.busy.timeout = setTimeout(fireNext,History.options.busyDelay); + } + }; + History.busy.timeout = setTimeout(fireNext,History.options.busyDelay); + } + + // Return + return History.busy.flag; + }; + + /** + * History.busy.flag + */ + History.busy.flag = false; + + /** + * History.fireQueueItem(item) + * Fire a Queue Item + * @param {Object} item + * @return {Mixed} result + */ + History.fireQueueItem = function(item){ + return item.callback.apply(item.scope||History,item.args||[]); + }; + + /** + * History.pushQueue(callback,args) + * Add an item to the queue + * @param {Object} item [scope,callback,args,queue] + */ + History.pushQueue = function(item){ + // Prepare the queue + History.queues[item.queue||0] = History.queues[item.queue||0]||[]; + + // Add to the queue + History.queues[item.queue||0].push(item); + + // Chain + return History; + }; + + /** + * History.queue (item,queue), (func,queue), (func), (item) + * Either firs the item now if not busy, or adds it to the queue + */ + History.queue = function(item,queue){ + // Prepare + if ( typeof item === 'function' ) { + item = { + callback: item + }; + } + if ( typeof queue !== 'undefined' ) { + item.queue = queue; + } + + // Handle + if ( History.busy() ) { + History.pushQueue(item); + } else { + History.fireQueueItem(item); + } + + // Chain + return History; + }; + + /** + * History.clearQueue() + * Clears the Queue + */ + History.clearQueue = function(){ + History.busy.flag = false; + History.queues = []; + return History; + }; + + + // ==================================================================== + // IE Bug Fix + + /** + * History.stateChanged + * States whether or not the state has changed since the last double check was initialised + */ + History.stateChanged = false; + + /** + * History.doubleChecker + * Contains the timeout used for the double checks + */ + History.doubleChecker = false; + + /** + * History.doubleCheckComplete() + * Complete a double check + * @return {History} + */ + History.doubleCheckComplete = function(){ + // Update + History.stateChanged = true; + + // Clear + History.doubleCheckClear(); + + // Chain + return History; + }; + + /** + * History.doubleCheckClear() + * Clear a double check + * @return {History} + */ + History.doubleCheckClear = function(){ + // Clear + if ( History.doubleChecker ) { + clearTimeout(History.doubleChecker); + History.doubleChecker = false; + } + + // Chain + return History; + }; + + /** + * History.doubleCheck() + * Create a double check + * @return {History} + */ + History.doubleCheck = function(tryAgain){ + // Reset + History.stateChanged = false; + History.doubleCheckClear(); + + // Fix IE6,IE7 bug where calling history.back or history.forward does not actually change the hash (whereas doing it manually does) + // Fix Safari 5 bug where sometimes the state does not change: https://bugs.webkit.org/show_bug.cgi?id=42940 + if ( History.bugs.ieDoubleCheck ) { + // Apply Check + History.doubleChecker = setTimeout( + function(){ + History.doubleCheckClear(); + if ( !History.stateChanged ) { + //History.debug('History.doubleCheck: State has not yet changed, trying again', arguments); + // Re-Attempt + tryAgain(); + } + return true; + }, + History.options.doubleCheckInterval + ); + } + + // Chain + return History; + }; + + + // ==================================================================== + // Safari Bug Fix + + /** + * History.safariStatePoll() + * Poll the current state + * @return {History} + */ + History.safariStatePoll = function(){ + // Poll the URL + + // Get the Last State which has the new URL + var + urlState = History.extractState(History.getLocationHref()), + newState; + + // Check for a difference + if ( !History.isLastSavedState(urlState) ) { + newState = urlState; + } + else { + return; + } + + // Check if we have a state with that url + // If not create it + if ( !newState ) { + //History.debug('History.safariStatePoll: new'); + newState = History.createStateObject(); + } + + // Apply the New State + //History.debug('History.safariStatePoll: trigger'); + History.Adapter.trigger(window,'popstate'); + + // Chain + return History; + }; + + + // ==================================================================== + // State Aliases + + /** + * History.back(queue) + * Send the browser history back one item + * @param {Integer} queue [optional] + */ + History.back = function(queue){ + //History.debug('History.back: called', arguments); + + // Handle Queueing + if ( queue !== false && History.busy() ) { + // Wait + Push to Queue + //History.debug('History.back: we must wait', arguments); + History.pushQueue({ + scope: History, + callback: History.back, + args: arguments, + queue: queue + }); + return false; + } + + // Make Busy + Continue + History.busy(true); + + // Fix certain browser bugs that prevent the state from changing + History.doubleCheck(function(){ + History.back(false); + }); + + // Go back + history.go(-1); + + // End back closure + return true; + }; + + /** + * History.forward(queue) + * Send the browser history forward one item + * @param {Integer} queue [optional] + */ + History.forward = function(queue){ + //History.debug('History.forward: called', arguments); + + // Handle Queueing + if ( queue !== false && History.busy() ) { + // Wait + Push to Queue + //History.debug('History.forward: we must wait', arguments); + History.pushQueue({ + scope: History, + callback: History.forward, + args: arguments, + queue: queue + }); + return false; + } + + // Make Busy + Continue + History.busy(true); + + // Fix certain browser bugs that prevent the state from changing + History.doubleCheck(function(){ + History.forward(false); + }); + + // Go forward + history.go(1); + + // End forward closure + return true; + }; + + /** + * History.go(index,queue) + * Send the browser history back or forward index times + * @param {Integer} queue [optional] + */ + History.go = function(index,queue){ + //History.debug('History.go: called', arguments); + + // Prepare + var i; + + // Handle + if ( index > 0 ) { + // Forward + for ( i=1; i<=index; ++i ) { + History.forward(queue); + } + } + else if ( index < 0 ) { + // Backward + for ( i=-1; i>=index; --i ) { + History.back(queue); + } + } + else { + throw new Error('History.go: History.go requires a positive or negative integer passed.'); + } + + // Chain + return History; + }; + + + // ==================================================================== + // HTML5 State Support + + // Non-Native pushState Implementation + if ( History.emulated.pushState ) { + /* + * Provide Skeleton for HTML4 Browsers + */ + + // Prepare + var emptyFunction = function(){}; + History.pushState = History.pushState||emptyFunction; + History.replaceState = History.replaceState||emptyFunction; + } // History.emulated.pushState + + // Native pushState Implementation + else { + /* + * Use native HTML5 History API Implementation + */ + + /** + * History.onPopState(event,extra) + * Refresh the Current State + */ + History.onPopState = function(event,extra){ + // Prepare + var stateId = false, newState = false, currentHash, currentState; + + // Reset the double check + History.doubleCheckComplete(); + + // Check for a Hash, and handle apporiatly + currentHash = History.getHash(); + if ( currentHash ) { + // Expand Hash + currentState = History.extractState(currentHash||History.getLocationHref(),true); + if ( currentState ) { + // We were able to parse it, it must be a State! + // Let's forward to replaceState + //History.debug('History.onPopState: state anchor', currentHash, currentState); + History.replaceState(currentState.data, currentState.title, currentState.url, false); + } + else { + // Traditional Anchor + //History.debug('History.onPopState: traditional anchor', currentHash); + History.Adapter.trigger(window,'anchorchange'); + History.busy(false); + } + + // We don't care for hashes + History.expectedStateId = false; + return false; + } + + // Ensure + stateId = History.Adapter.extractEventData('state',event,extra) || false; + + // Fetch State + if ( stateId ) { + // Vanilla: Back/forward button was used + newState = History.getStateById(stateId); + } + else if ( History.expectedStateId ) { + // Vanilla: A new state was pushed, and popstate was called manually + newState = History.getStateById(History.expectedStateId); + } + else { + // Initial State + newState = History.extractState(History.getLocationHref()); + } + + // The State did not exist in our store + if ( !newState ) { + // Regenerate the State + newState = History.createStateObject(null,null,History.getLocationHref()); + } + + // Clean + History.expectedStateId = false; + + // Check if we are the same state + if ( History.isLastSavedState(newState) ) { + // There has been no change (just the page's hash has finally propagated) + //History.debug('History.onPopState: no change', newState, History.savedStates); + History.busy(false); + return false; + } + + // Store the State + History.storeState(newState); + History.saveState(newState); + + // Force update of the title + History.setTitle(newState); + + // Fire Our Event + History.Adapter.trigger(window,'statechange'); + History.busy(false); + + // Return true + return true; + }; + History.Adapter.bind(window,'popstate',History.onPopState); + + /** + * History.pushState(data,title,url) + * Add a new State to the history object, become it, and trigger onpopstate + * We have to trigger for HTML4 compatibility + * @param {object} data + * @param {string} title + * @param {string} url + * @return {true} + */ + History.pushState = function(data,title,url,queue){ + //History.debug('History.pushState: called', arguments); + + // Check the State + if ( History.getHashByUrl(url) && History.emulated.pushState ) { + throw new Error('History.js does not support states with fragement-identifiers (hashes/anchors).'); + } + + // Handle Queueing + if ( queue !== false && History.busy() ) { + // Wait + Push to Queue + //History.debug('History.pushState: we must wait', arguments); + History.pushQueue({ + scope: History, + callback: History.pushState, + args: arguments, + queue: queue + }); + return false; + } + + // Make Busy + Continue + History.busy(true); + + // Create the newState + var newState = History.createStateObject(data,title,url); + + // Check it + if ( History.isLastSavedState(newState) ) { + // Won't be a change + History.busy(false); + } + else { + // Store the newState + History.storeState(newState); + History.expectedStateId = newState.id; + + // Push the newState + history.pushState(newState.id,newState.title,newState.url); + + // Fire HTML5 Event + History.Adapter.trigger(window,'popstate'); + } + + // End pushState closure + return true; + }; + + /** + * History.replaceState(data,title,url) + * Replace the State and trigger onpopstate + * We have to trigger for HTML4 compatibility + * @param {object} data + * @param {string} title + * @param {string} url + * @return {true} + */ + History.replaceState = function(data,title,url,queue){ + //History.debug('History.replaceState: called', arguments); + + // Check the State + if ( History.getHashByUrl(url) && History.emulated.pushState ) { + throw new Error('History.js does not support states with fragement-identifiers (hashes/anchors).'); + } + + // Handle Queueing + if ( queue !== false && History.busy() ) { + // Wait + Push to Queue + //History.debug('History.replaceState: we must wait', arguments); + History.pushQueue({ + scope: History, + callback: History.replaceState, + args: arguments, + queue: queue + }); + return false; + } + + // Make Busy + Continue + History.busy(true); + + // Create the newState + var newState = History.createStateObject(data,title,url); + + // Check it + if ( History.isLastSavedState(newState) ) { + // Won't be a change + History.busy(false); + } + else { + // Store the newState + History.storeState(newState); + History.expectedStateId = newState.id; + + // Push the newState + history.replaceState(newState.id,newState.title,newState.url); + + // Fire HTML5 Event + History.Adapter.trigger(window,'popstate'); + } + + // End replaceState closure + return true; + }; + + } // !History.emulated.pushState + + + // ==================================================================== + // Initialise + + /** + * Load the Store + */ + if ( sessionStorage ) { + // Fetch + try { + History.store = JSON.parse(sessionStorage.getItem('History.store'))||{}; + } + catch ( err ) { + History.store = {}; + } + + // Normalize + History.normalizeStore(); + } + else { + // Default Load + History.store = {}; + History.normalizeStore(); + } + + /** + * Clear Intervals on exit to prevent memory leaks + */ + History.Adapter.bind(window,"unload",History.clearAllIntervals); + + /** + * Create the initial State + */ + History.saveState(History.storeState(History.extractState(History.getLocationHref(),true))); + + /** + * Bind for Saving Store + */ + if ( sessionStorage ) { + // When the page is closed + History.onUnload = function(){ + // Prepare + var currentStore, item, currentStoreString; + + // Fetch + try { + currentStore = JSON.parse(sessionStorage.getItem('History.store'))||{}; + } + catch ( err ) { + currentStore = {}; + } + + // Ensure + currentStore.idToState = currentStore.idToState || {}; + currentStore.urlToId = currentStore.urlToId || {}; + currentStore.stateToId = currentStore.stateToId || {}; + + // Sync + for ( item in History.idToState ) { + if ( !History.idToState.hasOwnProperty(item) ) { + continue; + } + currentStore.idToState[item] = History.idToState[item]; + } + for ( item in History.urlToId ) { + if ( !History.urlToId.hasOwnProperty(item) ) { + continue; + } + currentStore.urlToId[item] = History.urlToId[item]; + } + for ( item in History.stateToId ) { + if ( !History.stateToId.hasOwnProperty(item) ) { + continue; + } + currentStore.stateToId[item] = History.stateToId[item]; + } + + // Update + History.store = currentStore; + History.normalizeStore(); + + // In Safari, going into Private Browsing mode causes the + // Session Storage object to still exist but if you try and use + // or set any property/function of it it throws the exception + // "QUOTA_EXCEEDED_ERR: DOM Exception 22: An attempt was made to + // add something to storage that exceeded the quota." infinitely + // every second. + currentStoreString = JSON.stringify(currentStore); + try { + // Store + sessionStorage.setItem('History.store', currentStoreString); + } + catch (e) { + if (e.code === DOMException.QUOTA_EXCEEDED_ERR) { + if (sessionStorage.length) { + // Workaround for a bug seen on iPads. Sometimes the quota exceeded error comes up and simply + // removing/resetting the storage can work. + sessionStorage.removeItem('History.store'); + sessionStorage.setItem('History.store', currentStoreString); + } else { + // Otherwise, we're probably private browsing in Safari, so we'll ignore the exception. + } + } else { + throw e; + } + } + }; + + // For Internet Explorer + History.intervalList.push(setInterval(History.onUnload,History.options.storeInterval)); + + // For Other Browsers + History.Adapter.bind(window,'beforeunload',History.onUnload); + History.Adapter.bind(window,'unload',History.onUnload); + + // Both are enabled for consistency + } + + // Non-Native pushState Implementation + if ( !History.emulated.pushState ) { + // Be aware, the following is only for native pushState implementations + // If you are wanting to include something for all browsers + // Then include it above this if block + + /** + * Setup Safari Fix + */ + if ( History.bugs.safariPoll ) { + History.intervalList.push(setInterval(History.safariStatePoll, History.options.safariPollInterval)); + } + + /** + * Ensure Cross Browser Compatibility + */ + if ( navigator.vendor === 'Apple Computer, Inc.' || (navigator.appCodeName||'') === 'Mozilla' ) { + /** + * Fix Safari HashChange Issue + */ + + // Setup Alias + History.Adapter.bind(window,'hashchange',function(){ + History.Adapter.trigger(window,'popstate'); + }); + + // Initialise Alias + if ( History.getHash() ) { + History.Adapter.onDomLoad(function(){ + History.Adapter.trigger(window,'hashchange'); + }); + } + } + + } // !History.emulated.pushState + + + }; // History.initCore + + // Try to Initialise History + if (!History.options || !History.options.delayInit) { + History.init(); + } + +})(window); diff --git a/sites/all/themes/gui/materiobasetheme/bower_components/history.js/scripts/bundled/html4+html5/dojo.history.js b/sites/all/themes/gui/materiobasetheme/bower_components/history.js/scripts/bundled/html4+html5/dojo.history.js new file mode 100644 index 00000000..3ac2c663 --- /dev/null +++ b/sites/all/themes/gui/materiobasetheme/bower_components/history.js/scripts/bundled/html4+html5/dojo.history.js @@ -0,0 +1 @@ +typeof JSON!="object"&&(JSON={}),function(){"use strict";function f(e){return e<10?"0"+e:e}function quote(e){return escapable.lastIndex=0,escapable.test(e)?'"'+e.replace(escapable,function(e){var t=meta[e];return typeof t=="string"?t:"\\u"+("0000"+e.charCodeAt(0).toString(16)).slice(-4)})+'"':'"'+e+'"'}function str(e,t){var n,r,i,s,o=gap,u,a=t[e];a&&typeof a=="object"&&typeof a.toJSON=="function"&&(a=a.toJSON(e)),typeof rep=="function"&&(a=rep.call(t,e,a));switch(typeof a){case"string":return quote(a);case"number":return isFinite(a)?String(a):"null";case"boolean":case"null":return String(a);case"object":if(!a)return"null";gap+=indent,u=[];if(Object.prototype.toString.apply(a)==="[object Array]"){s=a.length;for(n=0;n")&&n[0]);return e>4?e:!1}();return e},h.isInternetExplorer=function(){var e=h.isInternetExplorer.cached=typeof h.isInternetExplorer.cached!="undefined"?h.isInternetExplorer.cached:Boolean(h.getInternetExplorerMajorVersion());return e},h.options.html4Mode?h.emulated={pushState:!0,hashChange:!0}:h.emulated={pushState:!Boolean(e.history&&e.history.pushState&&e.history.replaceState&&!/ Mobile\/([1-7][a-z]|(8([abcde]|f(1[0-8]))))/i.test(i.userAgent)&&!/AppleWebKit\/5([0-2]|3[0-2])/i.test(i.userAgent)),hashChange:Boolean(!("onhashchange"in e||"onhashchange"in r)||h.isInternetExplorer()&&h.getInternetExplorerMajorVersion()<8)},h.enabled=!h.emulated.pushState,h.bugs={setHash:Boolean(!h.emulated.pushState&&i.vendor==="Apple Computer, Inc."&&/AppleWebKit\/5([0-2]|3[0-3])/.test(i.userAgent)),safariPoll:Boolean(!h.emulated.pushState&&i.vendor==="Apple Computer, Inc."&&/AppleWebKit\/5([0-2]|3[0-3])/.test(i.userAgent)),ieDoubleCheck:Boolean(h.isInternetExplorer()&&h.getInternetExplorerMajorVersion()<8),hashEscape:Boolean(h.isInternetExplorer()&&h.getInternetExplorerMajorVersion()<7)},h.isEmptyObject=function(e){for(var t in e)if(e.hasOwnProperty(t))return!1;return!0},h.cloneObject=function(e){var t,n;return e?(t=l.stringify(e),n=l.parse(t)):n={},n},h.getRootUrl=function(){var e=r.location.protocol+"//"+(r.location.hostname||r.location.host);if(r.location.port||!1)e+=":"+r.location.port;return e+="/",e},h.getBaseHref=function(){var e=r.getElementsByTagName("base"),t=null,n="";return e.length===1&&(t=e[0],n=t.href.replace(/[^\/]+$/,"")),n=n.replace(/\/+$/,""),n&&(n+="/"),n},h.getBaseUrl=function(){var e=h.getBaseHref()||h.getBasePageUrl()||h.getRootUrl();return e},h.getPageUrl=function(){var e=h.getState(!1,!1),t=(e||{}).url||h.getLocationHref(),n;return n=t.replace(/\/+$/,"").replace(/[^\/]+$/,function(e,t,n){return/\./.test(e)?e:e+"/"}),n},h.getBasePageUrl=function(){var e=h.getLocationHref().replace(/[#\?].*/,"").replace(/[^\/]+$/,function(e,t,n){return/[^\/]$/.test(e)?"":e}).replace(/\/+$/,"")+"/";return e},h.getFullUrl=function(e,t){var n=e,r=e.substring(0,1);return t=typeof t=="undefined"?!0:t,/[a-z]+\:\/\//.test(e)||(r==="/"?n=h.getRootUrl()+e.replace(/^\/+/,""):r==="#"?n=h.getPageUrl().replace(/#.*/,"")+e:r==="?"?n=h.getPageUrl().replace(/[\?#].*/,"")+e:t?n=h.getBaseUrl()+e.replace(/^(\.\/)+/,""):n=h.getBasePageUrl()+e.replace(/^(\.\/)+/,"")),n.replace(/\#$/,"")},h.getShortUrl=function(e){var t=e,n=h.getBaseUrl(),r=h.getRootUrl();return h.emulated.pushState&&(t=t.replace(n,"")),t=t.replace(r,"/"),h.isTraditionalAnchor(t)&&(t="./"+t),t=t.replace(/^(\.\/)+/g,"./").replace(/\#$/,""),t},h.getLocationHref=function(e){return e=e||r,e.URL===e.location.href?e.location.href:e.location.href===decodeURIComponent(e.URL)?e.URL:e.location.hash&&decodeURIComponent(e.location.href.replace(/^[^#]+/,""))===e.location.hash?e.location.href:e.URL.indexOf("#")==-1&&e.location.href.indexOf("#")!=-1?e.location.href:e.URL||e.location.href},h.store={},h.idToState=h.idToState||{},h.stateToId=h.stateToId||{},h.urlToId=h.urlToId||{},h.storedStates=h.storedStates||[],h.savedStates=h.savedStates||[],h.normalizeStore=function(){h.store.idToState=h.store.idToState||{},h.store.urlToId=h.store.urlToId||{},h.store.stateToId=h.store.stateToId||{}},h.getState=function(e,t){typeof e=="undefined"&&(e=!0),typeof t=="undefined"&&(t=!0);var n=h.getLastSavedState();return!n&&t&&(n=h.createStateObject()),e&&(n=h.cloneObject(n),n.url=n.cleanUrl||n.url),n},h.getIdByState=function(e){var t=h.extractId(e.url),n;if(!t){n=h.getStateString(e);if(typeof h.stateToId[n]!="undefined")t=h.stateToId[n];else if(typeof h.store.stateToId[n]!="undefined")t=h.store.stateToId[n];else{for(;;){t=(new Date).getTime()+String(Math.random()).replace(/\D/g,"");if(typeof h.idToState[t]=="undefined"&&typeof h.store.idToState[t]=="undefined")break}h.stateToId[n]=t,h.idToState[t]=e}}return t},h.normalizeState=function(e){var t,n;if(!e||typeof e!="object")e={};if(typeof e.normalized!="undefined")return e;if(!e.data||typeof e.data!="object")e.data={};return t={},t.normalized=!0,t.title=e.title||"",t.url=h.getFullUrl(e.url?e.url:h.getLocationHref()),t.hash=h.getShortUrl(t.url),t.data=h.cloneObject(e.data),t.id=h.getIdByState(t),t.cleanUrl=t.url.replace(/\??\&_suid.*/,""),t.url=t.cleanUrl,n=!h.isEmptyObject(t.data),(t.title||n)&&h.options.disableSuid!==!0&&(t.hash=h.getShortUrl(t.url).replace(/\??\&_suid.*/,""),/\?/.test(t.hash)||(t.hash+="?"),t.hash+="&_suid="+t.id),t.hashedUrl=h.getFullUrl(t.hash),(h.emulated.pushState||h.bugs.safariPoll)&&h.hasUrlDuplicate(t)&&(t.url=t.hashedUrl),t},h.createStateObject=function(e,t,n){var r={data:e,title:t,url:n};return r=h.normalizeState(r),r},h.getStateById=function(e){e=String(e);var n=h.idToState[e]||h.store.idToState[e]||t;return n},h.getStateString=function(e){var t,n,r;return t=h.normalizeState(e),n={data:t.data,title:e.title,url:e.url},r=l.stringify(n),r},h.getStateId=function(e){var t,n;return t=h.normalizeState(e),n=t.id,n},h.getHashByState=function(e){var t,n;return t=h.normalizeState(e),n=t.hash,n},h.extractId=function(e){var t,n,r,i;return e.indexOf("#")!=-1?i=e.split("#")[0]:i=e,n=/(.*)\&_suid=([0-9]+)$/.exec(i),r=n?n[1]||e:e,t=n?String(n[2]||""):"",t||!1},h.isTraditionalAnchor=function(e){var t=!/[\/\?\.]/.test(e);return t},h.extractState=function(e,t){var n=null,r,i;return t=t||!1,r=h.extractId(e),r&&(n=h.getStateById(r)),n||(i=h.getFullUrl(e),r=h.getIdByUrl(i)||!1,r&&(n=h.getStateById(r)),!n&&t&&!h.isTraditionalAnchor(e)&&(n=h.createStateObject(null,null,i))),n},h.getIdByUrl=function(e){var n=h.urlToId[e]||h.store.urlToId[e]||t;return n},h.getLastSavedState=function(){return h.savedStates[h.savedStates.length-1]||t},h.getLastStoredState=function(){return h.storedStates[h.storedStates.length-1]||t},h.hasUrlDuplicate=function(e){var t=!1,n;return n=h.extractState(e.url),t=n&&n.id!==e.id,t},h.storeState=function(e){return h.urlToId[e.url]=e.id,h.storedStates.push(h.cloneObject(e)),e},h.isLastSavedState=function(e){var t=!1,n,r,i;return h.savedStates.length&&(n=e.id,r=h.getLastSavedState(),i=r.id,t=n===i),t},h.saveState=function(e){return h.isLastSavedState(e)?!1:(h.savedStates.push(h.cloneObject(e)),!0)},h.getStateByIndex=function(e){var t=null;return typeof e=="undefined"?t=h.savedStates[h.savedStates.length-1]:e<0?t=h.savedStates[h.savedStates.length+e]:t=h.savedStates[e],t},h.getCurrentIndex=function(){var e=null;return h.savedStates.length<1?e=0:e=h.savedStates.length-1,e},h.getHash=function(e){var t=h.getLocationHref(e),n;return n=h.getHashByUrl(t),n},h.unescapeHash=function(e){var t=h.normalizeHash(e);return t=decodeURIComponent(t),t},h.normalizeHash=function(e){var t=e.replace(/[^#]*#/,"").replace(/#.*/,"");return t},h.setHash=function(e,t){var n,i;return t!==!1&&h.busy()?(h.pushQueue({scope:h,callback:h.setHash,args:arguments,queue:t}),!1):(h.busy(!0),n=h.extractState(e,!0),n&&!h.emulated.pushState?h.pushState(n.data,n.title,n.url,!1):h.getHash()!==e&&(h.bugs.setHash?(i=h.getPageUrl(),h.pushState(null,null,i+"#"+e,!1)):r.location.hash=e),h)},h.escapeHash=function(t){var n=h.normalizeHash(t);return n=e.encodeURIComponent(n),h.bugs.hashEscape||(n=n.replace(/\%21/g,"!").replace(/\%26/g,"&").replace(/\%3D/g,"=").replace(/\%3F/g,"?")),n},h.getHashByUrl=function(e){var t=String(e).replace(/([^#]*)#?([^#]*)#?(.*)/,"$2");return t=h.unescapeHash(t),t},h.setTitle=function(e){var t=e.title,n;t||(n=h.getStateByIndex(0),n&&n.url===e.url&&(t=n.title||h.options.initialTitle));try{r.getElementsByTagName("title")[0].innerHTML=t.replace("<","<").replace(">",">").replace(" & "," & ")}catch(i){}return r.title=t,h},h.queues=[],h.busy=function(e){typeof e!="undefined"?h.busy.flag=e:typeof h.busy.flag=="undefined"&&(h.busy.flag=!1);if(!h.busy.flag){u(h.busy.timeout);var t=function(){var e,n,r;if(h.busy.flag)return;for(e=h.queues.length-1;e>=0;--e){n=h.queues[e];if(n.length===0)continue;r=n.shift(),h.fireQueueItem(r),h.busy.timeout=o(t,h.options.busyDelay)}};h.busy.timeout=o(t,h.options.busyDelay)}return h.busy.flag},h.busy.flag=!1,h.fireQueueItem=function(e){return e.callback.apply(e.scope||h,e.args||[])},h.pushQueue=function(e){return h.queues[e.queue||0]=h.queues[e.queue||0]||[],h.queues[e.queue||0].push(e),h},h.queue=function(e,t){return typeof e=="function"&&(e={callback:e}),typeof t!="undefined"&&(e.queue=t),h.busy()?h.pushQueue(e):h.fireQueueItem(e),h},h.clearQueue=function(){return h.busy.flag=!1,h.queues=[],h},h.stateChanged=!1,h.doubleChecker=!1,h.doubleCheckComplete=function(){return h.stateChanged=!0,h.doubleCheckClear(),h},h.doubleCheckClear=function(){return h.doubleChecker&&(u(h.doubleChecker),h.doubleChecker=!1),h},h.doubleCheck=function(e){return h.stateChanged=!1,h.doubleCheckClear(),h.bugs.ieDoubleCheck&&(h.doubleChecker=o(function(){return h.doubleCheckClear(),h.stateChanged||e(),!0},h.options.doubleCheckInterval)),h},h.safariStatePoll=function(){var t=h.extractState(h.getLocationHref()),n;if(!h.isLastSavedState(t))return n=t,n||(n=h.createStateObject()),h.Adapter.trigger(e,"popstate"),h;return},h.back=function(e){return e!==!1&&h.busy()?(h.pushQueue({scope:h,callback:h.back,args:arguments,queue:e}),!1):(h.busy(!0),h.doubleCheck(function(){h.back(!1)}),p.go(-1),!0)},h.forward=function(e){return e!==!1&&h.busy()?(h.pushQueue({scope:h,callback:h.forward,args:arguments,queue:e}),!1):(h.busy(!0),h.doubleCheck(function(){h.forward(!1)}),p.go(1),!0)},h.go=function(e,t){var n;if(e>0)for(n=1;n<=e;++n)h.forward(t);else{if(!(e<0))throw new Error("History.go: History.go requires a positive or negative integer passed.");for(n=-1;n>=e;--n)h.back(t)}return h};if(h.emulated.pushState){var v=function(){};h.pushState=h.pushState||v,h.replaceState=h.replaceState||v}else h.onPopState=function(t,n){var r=!1,i=!1,s,o;return h.doubleCheckComplete(),s=h.getHash(),s?(o=h.extractState(s||h.getLocationHref(),!0),o?h.replaceState(o.data,o.title,o.url,!1):(h.Adapter.trigger(e,"anchorchange"),h.busy(!1)),h.expectedStateId=!1,!1):(r=h.Adapter.extractEventData("state",t,n)||!1,r?i=h.getStateById(r):h.expectedStateId?i=h.getStateById(h.expectedStateId):i=h.extractState(h.getLocationHref()),i||(i=h.createStateObject(null,null,h.getLocationHref())),h.expectedStateId=!1,h.isLastSavedState(i)?(h.busy(!1),!1):(h.storeState(i),h.saveState(i),h.setTitle(i),h.Adapter.trigger(e,"statechange"),h.busy(!1),!0))},h.Adapter.bind(e,"popstate",h.onPopState),h.pushState=function(t,n,r,i){if(h.getHashByUrl(r)&&h.emulated.pushState)throw new Error("History.js does not support states with fragement-identifiers (hashes/anchors).");if(i!==!1&&h.busy())return h.pushQueue({scope:h,callback:h.pushState,args:arguments,queue:i}),!1;h.busy(!0);var s=h.createStateObject(t,n,r);return h.isLastSavedState(s)?h.busy(!1):(h.storeState(s),h.expectedStateId=s.id,p.pushState(s.id,s.title,s.url),h.Adapter.trigger(e,"popstate")),!0},h.replaceState=function(t,n,r,i){if(h.getHashByUrl(r)&&h.emulated.pushState)throw new Error("History.js does not support states with fragement-identifiers (hashes/anchors).");if(i!==!1&&h.busy())return h.pushQueue({scope:h,callback:h.replaceState,args:arguments,queue:i}),!1;h.busy(!0);var s=h.createStateObject(t,n,r);return h.isLastSavedState(s)?h.busy(!1):(h.storeState(s),h.expectedStateId=s.id,p.replaceState(s.id,s.title,s.url),h.Adapter.trigger(e,"popstate")),!0};if(s){try{h.store=l.parse(s.getItem("History.store"))||{}}catch(m){h.store={}}h.normalizeStore()}else h.store={},h.normalizeStore();h.Adapter.bind(e,"unload",h.clearAllIntervals),h.saveState(h.storeState(h.extractState(h.getLocationHref(),!0))),s&&(h.onUnload=function(){var e,t,n;try{e=l.parse(s.getItem("History.store"))||{}}catch(r){e={}}e.idToState=e.idToState||{},e.urlToId=e.urlToId||{},e.stateToId=e.stateToId||{};for(t in h.idToState){if(!h.idToState.hasOwnProperty(t))continue;e.idToState[t]=h.idToState[t]}for(t in h.urlToId){if(!h.urlToId.hasOwnProperty(t))continue;e.urlToId[t]=h.urlToId[t]}for(t in h.stateToId){if(!h.stateToId.hasOwnProperty(t))continue;e.stateToId[t]=h.stateToId[t]}h.store=e,h.normalizeStore(),n=l.stringify(e);try{s.setItem("History.store",n)}catch(i){if(i.code!==DOMException.QUOTA_EXCEEDED_ERR)throw i;s.length&&(s.removeItem("History.store"),s.setItem("History.store",n))}},h.intervalList.push(a(h.onUnload,h.options.storeInterval)),h.Adapter.bind(e,"beforeunload",h.onUnload),h.Adapter.bind(e,"unload",h.onUnload));if(!h.emulated.pushState){h.bugs.safariPoll&&h.intervalList.push(a(h.safariStatePoll,h.options.safariPollInterval));if(i.vendor==="Apple Computer, Inc."||(i.appCodeName||"")==="Mozilla")h.Adapter.bind(e,"hashchange",function(){h.Adapter.trigger(e,"popstate")}),h.getHash()&&h.Adapter.onDomLoad(function(){h.Adapter.trigger(e,"hashchange")})}},(!h.options||!h.options.delayInit)&&h.init()}(window) \ No newline at end of file diff --git a/sites/all/themes/gui/materiobasetheme/bower_components/history.js/scripts/bundled/html4+html5/extjs.history.js b/sites/all/themes/gui/materiobasetheme/bower_components/history.js/scripts/bundled/html4+html5/extjs.history.js new file mode 100644 index 00000000..c546f51d --- /dev/null +++ b/sites/all/themes/gui/materiobasetheme/bower_components/history.js/scripts/bundled/html4+html5/extjs.history.js @@ -0,0 +1 @@ +typeof JSON!="object"&&(JSON={}),function(){"use strict";function f(e){return e<10?"0"+e:e}function quote(e){return escapable.lastIndex=0,escapable.test(e)?'"'+e.replace(escapable,function(e){var t=meta[e];return typeof t=="string"?t:"\\u"+("0000"+e.charCodeAt(0).toString(16)).slice(-4)})+'"':'"'+e+'"'}function str(e,t){var n,r,i,s,o=gap,u,a=t[e];a&&typeof a=="object"&&typeof a.toJSON=="function"&&(a=a.toJSON(e)),typeof rep=="function"&&(a=rep.call(t,e,a));switch(typeof a){case"string":return quote(a);case"number":return isFinite(a)?String(a):"null";case"boolean":case"null":return String(a);case"object":if(!a)return"null";gap+=indent,u=[];if(Object.prototype.toString.apply(a)==="[object Array]"){s=a.length;for(n=0;n")&&n[0]);return e>4?e:!1}();return e},h.isInternetExplorer=function(){var e=h.isInternetExplorer.cached=typeof h.isInternetExplorer.cached!="undefined"?h.isInternetExplorer.cached:Boolean(h.getInternetExplorerMajorVersion());return e},h.options.html4Mode?h.emulated={pushState:!0,hashChange:!0}:h.emulated={pushState:!Boolean(e.history&&e.history.pushState&&e.history.replaceState&&!/ Mobile\/([1-7][a-z]|(8([abcde]|f(1[0-8]))))/i.test(i.userAgent)&&!/AppleWebKit\/5([0-2]|3[0-2])/i.test(i.userAgent)),hashChange:Boolean(!("onhashchange"in e||"onhashchange"in r)||h.isInternetExplorer()&&h.getInternetExplorerMajorVersion()<8)},h.enabled=!h.emulated.pushState,h.bugs={setHash:Boolean(!h.emulated.pushState&&i.vendor==="Apple Computer, Inc."&&/AppleWebKit\/5([0-2]|3[0-3])/.test(i.userAgent)),safariPoll:Boolean(!h.emulated.pushState&&i.vendor==="Apple Computer, Inc."&&/AppleWebKit\/5([0-2]|3[0-3])/.test(i.userAgent)),ieDoubleCheck:Boolean(h.isInternetExplorer()&&h.getInternetExplorerMajorVersion()<8),hashEscape:Boolean(h.isInternetExplorer()&&h.getInternetExplorerMajorVersion()<7)},h.isEmptyObject=function(e){for(var t in e)if(e.hasOwnProperty(t))return!1;return!0},h.cloneObject=function(e){var t,n;return e?(t=l.stringify(e),n=l.parse(t)):n={},n},h.getRootUrl=function(){var e=r.location.protocol+"//"+(r.location.hostname||r.location.host);if(r.location.port||!1)e+=":"+r.location.port;return e+="/",e},h.getBaseHref=function(){var e=r.getElementsByTagName("base"),t=null,n="";return e.length===1&&(t=e[0],n=t.href.replace(/[^\/]+$/,"")),n=n.replace(/\/+$/,""),n&&(n+="/"),n},h.getBaseUrl=function(){var e=h.getBaseHref()||h.getBasePageUrl()||h.getRootUrl();return e},h.getPageUrl=function(){var e=h.getState(!1,!1),t=(e||{}).url||h.getLocationHref(),n;return n=t.replace(/\/+$/,"").replace(/[^\/]+$/,function(e,t,n){return/\./.test(e)?e:e+"/"}),n},h.getBasePageUrl=function(){var e=h.getLocationHref().replace(/[#\?].*/,"").replace(/[^\/]+$/,function(e,t,n){return/[^\/]$/.test(e)?"":e}).replace(/\/+$/,"")+"/";return e},h.getFullUrl=function(e,t){var n=e,r=e.substring(0,1);return t=typeof t=="undefined"?!0:t,/[a-z]+\:\/\//.test(e)||(r==="/"?n=h.getRootUrl()+e.replace(/^\/+/,""):r==="#"?n=h.getPageUrl().replace(/#.*/,"")+e:r==="?"?n=h.getPageUrl().replace(/[\?#].*/,"")+e:t?n=h.getBaseUrl()+e.replace(/^(\.\/)+/,""):n=h.getBasePageUrl()+e.replace(/^(\.\/)+/,"")),n.replace(/\#$/,"")},h.getShortUrl=function(e){var t=e,n=h.getBaseUrl(),r=h.getRootUrl();return h.emulated.pushState&&(t=t.replace(n,"")),t=t.replace(r,"/"),h.isTraditionalAnchor(t)&&(t="./"+t),t=t.replace(/^(\.\/)+/g,"./").replace(/\#$/,""),t},h.getLocationHref=function(e){return e=e||r,e.URL===e.location.href?e.location.href:e.location.href===decodeURIComponent(e.URL)?e.URL:e.location.hash&&decodeURIComponent(e.location.href.replace(/^[^#]+/,""))===e.location.hash?e.location.href:e.URL.indexOf("#")==-1&&e.location.href.indexOf("#")!=-1?e.location.href:e.URL||e.location.href},h.store={},h.idToState=h.idToState||{},h.stateToId=h.stateToId||{},h.urlToId=h.urlToId||{},h.storedStates=h.storedStates||[],h.savedStates=h.savedStates||[],h.normalizeStore=function(){h.store.idToState=h.store.idToState||{},h.store.urlToId=h.store.urlToId||{},h.store.stateToId=h.store.stateToId||{}},h.getState=function(e,t){typeof e=="undefined"&&(e=!0),typeof t=="undefined"&&(t=!0);var n=h.getLastSavedState();return!n&&t&&(n=h.createStateObject()),e&&(n=h.cloneObject(n),n.url=n.cleanUrl||n.url),n},h.getIdByState=function(e){var t=h.extractId(e.url),n;if(!t){n=h.getStateString(e);if(typeof h.stateToId[n]!="undefined")t=h.stateToId[n];else if(typeof h.store.stateToId[n]!="undefined")t=h.store.stateToId[n];else{for(;;){t=(new Date).getTime()+String(Math.random()).replace(/\D/g,"");if(typeof h.idToState[t]=="undefined"&&typeof h.store.idToState[t]=="undefined")break}h.stateToId[n]=t,h.idToState[t]=e}}return t},h.normalizeState=function(e){var t,n;if(!e||typeof e!="object")e={};if(typeof e.normalized!="undefined")return e;if(!e.data||typeof e.data!="object")e.data={};return t={},t.normalized=!0,t.title=e.title||"",t.url=h.getFullUrl(e.url?e.url:h.getLocationHref()),t.hash=h.getShortUrl(t.url),t.data=h.cloneObject(e.data),t.id=h.getIdByState(t),t.cleanUrl=t.url.replace(/\??\&_suid.*/,""),t.url=t.cleanUrl,n=!h.isEmptyObject(t.data),(t.title||n)&&h.options.disableSuid!==!0&&(t.hash=h.getShortUrl(t.url).replace(/\??\&_suid.*/,""),/\?/.test(t.hash)||(t.hash+="?"),t.hash+="&_suid="+t.id),t.hashedUrl=h.getFullUrl(t.hash),(h.emulated.pushState||h.bugs.safariPoll)&&h.hasUrlDuplicate(t)&&(t.url=t.hashedUrl),t},h.createStateObject=function(e,t,n){var r={data:e,title:t,url:n};return r=h.normalizeState(r),r},h.getStateById=function(e){e=String(e);var n=h.idToState[e]||h.store.idToState[e]||t;return n},h.getStateString=function(e){var t,n,r;return t=h.normalizeState(e),n={data:t.data,title:e.title,url:e.url},r=l.stringify(n),r},h.getStateId=function(e){var t,n;return t=h.normalizeState(e),n=t.id,n},h.getHashByState=function(e){var t,n;return t=h.normalizeState(e),n=t.hash,n},h.extractId=function(e){var t,n,r,i;return e.indexOf("#")!=-1?i=e.split("#")[0]:i=e,n=/(.*)\&_suid=([0-9]+)$/.exec(i),r=n?n[1]||e:e,t=n?String(n[2]||""):"",t||!1},h.isTraditionalAnchor=function(e){var t=!/[\/\?\.]/.test(e);return t},h.extractState=function(e,t){var n=null,r,i;return t=t||!1,r=h.extractId(e),r&&(n=h.getStateById(r)),n||(i=h.getFullUrl(e),r=h.getIdByUrl(i)||!1,r&&(n=h.getStateById(r)),!n&&t&&!h.isTraditionalAnchor(e)&&(n=h.createStateObject(null,null,i))),n},h.getIdByUrl=function(e){var n=h.urlToId[e]||h.store.urlToId[e]||t;return n},h.getLastSavedState=function(){return h.savedStates[h.savedStates.length-1]||t},h.getLastStoredState=function(){return h.storedStates[h.storedStates.length-1]||t},h.hasUrlDuplicate=function(e){var t=!1,n;return n=h.extractState(e.url),t=n&&n.id!==e.id,t},h.storeState=function(e){return h.urlToId[e.url]=e.id,h.storedStates.push(h.cloneObject(e)),e},h.isLastSavedState=function(e){var t=!1,n,r,i;return h.savedStates.length&&(n=e.id,r=h.getLastSavedState(),i=r.id,t=n===i),t},h.saveState=function(e){return h.isLastSavedState(e)?!1:(h.savedStates.push(h.cloneObject(e)),!0)},h.getStateByIndex=function(e){var t=null;return typeof e=="undefined"?t=h.savedStates[h.savedStates.length-1]:e<0?t=h.savedStates[h.savedStates.length+e]:t=h.savedStates[e],t},h.getCurrentIndex=function(){var e=null;return h.savedStates.length<1?e=0:e=h.savedStates.length-1,e},h.getHash=function(e){var t=h.getLocationHref(e),n;return n=h.getHashByUrl(t),n},h.unescapeHash=function(e){var t=h.normalizeHash(e);return t=decodeURIComponent(t),t},h.normalizeHash=function(e){var t=e.replace(/[^#]*#/,"").replace(/#.*/,"");return t},h.setHash=function(e,t){var n,i;return t!==!1&&h.busy()?(h.pushQueue({scope:h,callback:h.setHash,args:arguments,queue:t}),!1):(h.busy(!0),n=h.extractState(e,!0),n&&!h.emulated.pushState?h.pushState(n.data,n.title,n.url,!1):h.getHash()!==e&&(h.bugs.setHash?(i=h.getPageUrl(),h.pushState(null,null,i+"#"+e,!1)):r.location.hash=e),h)},h.escapeHash=function(t){var n=h.normalizeHash(t);return n=e.encodeURIComponent(n),h.bugs.hashEscape||(n=n.replace(/\%21/g,"!").replace(/\%26/g,"&").replace(/\%3D/g,"=").replace(/\%3F/g,"?")),n},h.getHashByUrl=function(e){var t=String(e).replace(/([^#]*)#?([^#]*)#?(.*)/,"$2");return t=h.unescapeHash(t),t},h.setTitle=function(e){var t=e.title,n;t||(n=h.getStateByIndex(0),n&&n.url===e.url&&(t=n.title||h.options.initialTitle));try{r.getElementsByTagName("title")[0].innerHTML=t.replace("<","<").replace(">",">").replace(" & "," & ")}catch(i){}return r.title=t,h},h.queues=[],h.busy=function(e){typeof e!="undefined"?h.busy.flag=e:typeof h.busy.flag=="undefined"&&(h.busy.flag=!1);if(!h.busy.flag){u(h.busy.timeout);var t=function(){var e,n,r;if(h.busy.flag)return;for(e=h.queues.length-1;e>=0;--e){n=h.queues[e];if(n.length===0)continue;r=n.shift(),h.fireQueueItem(r),h.busy.timeout=o(t,h.options.busyDelay)}};h.busy.timeout=o(t,h.options.busyDelay)}return h.busy.flag},h.busy.flag=!1,h.fireQueueItem=function(e){return e.callback.apply(e.scope||h,e.args||[])},h.pushQueue=function(e){return h.queues[e.queue||0]=h.queues[e.queue||0]||[],h.queues[e.queue||0].push(e),h},h.queue=function(e,t){return typeof e=="function"&&(e={callback:e}),typeof t!="undefined"&&(e.queue=t),h.busy()?h.pushQueue(e):h.fireQueueItem(e),h},h.clearQueue=function(){return h.busy.flag=!1,h.queues=[],h},h.stateChanged=!1,h.doubleChecker=!1,h.doubleCheckComplete=function(){return h.stateChanged=!0,h.doubleCheckClear(),h},h.doubleCheckClear=function(){return h.doubleChecker&&(u(h.doubleChecker),h.doubleChecker=!1),h},h.doubleCheck=function(e){return h.stateChanged=!1,h.doubleCheckClear(),h.bugs.ieDoubleCheck&&(h.doubleChecker=o(function(){return h.doubleCheckClear(),h.stateChanged||e(),!0},h.options.doubleCheckInterval)),h},h.safariStatePoll=function(){var t=h.extractState(h.getLocationHref()),n;if(!h.isLastSavedState(t))return n=t,n||(n=h.createStateObject()),h.Adapter.trigger(e,"popstate"),h;return},h.back=function(e){return e!==!1&&h.busy()?(h.pushQueue({scope:h,callback:h.back,args:arguments,queue:e}),!1):(h.busy(!0),h.doubleCheck(function(){h.back(!1)}),p.go(-1),!0)},h.forward=function(e){return e!==!1&&h.busy()?(h.pushQueue({scope:h,callback:h.forward,args:arguments,queue:e}),!1):(h.busy(!0),h.doubleCheck(function(){h.forward(!1)}),p.go(1),!0)},h.go=function(e,t){var n;if(e>0)for(n=1;n<=e;++n)h.forward(t);else{if(!(e<0))throw new Error("History.go: History.go requires a positive or negative integer passed.");for(n=-1;n>=e;--n)h.back(t)}return h};if(h.emulated.pushState){var v=function(){};h.pushState=h.pushState||v,h.replaceState=h.replaceState||v}else h.onPopState=function(t,n){var r=!1,i=!1,s,o;return h.doubleCheckComplete(),s=h.getHash(),s?(o=h.extractState(s||h.getLocationHref(),!0),o?h.replaceState(o.data,o.title,o.url,!1):(h.Adapter.trigger(e,"anchorchange"),h.busy(!1)),h.expectedStateId=!1,!1):(r=h.Adapter.extractEventData("state",t,n)||!1,r?i=h.getStateById(r):h.expectedStateId?i=h.getStateById(h.expectedStateId):i=h.extractState(h.getLocationHref()),i||(i=h.createStateObject(null,null,h.getLocationHref())),h.expectedStateId=!1,h.isLastSavedState(i)?(h.busy(!1),!1):(h.storeState(i),h.saveState(i),h.setTitle(i),h.Adapter.trigger(e,"statechange"),h.busy(!1),!0))},h.Adapter.bind(e,"popstate",h.onPopState),h.pushState=function(t,n,r,i){if(h.getHashByUrl(r)&&h.emulated.pushState)throw new Error("History.js does not support states with fragement-identifiers (hashes/anchors).");if(i!==!1&&h.busy())return h.pushQueue({scope:h,callback:h.pushState,args:arguments,queue:i}),!1;h.busy(!0);var s=h.createStateObject(t,n,r);return h.isLastSavedState(s)?h.busy(!1):(h.storeState(s),h.expectedStateId=s.id,p.pushState(s.id,s.title,s.url),h.Adapter.trigger(e,"popstate")),!0},h.replaceState=function(t,n,r,i){if(h.getHashByUrl(r)&&h.emulated.pushState)throw new Error("History.js does not support states with fragement-identifiers (hashes/anchors).");if(i!==!1&&h.busy())return h.pushQueue({scope:h,callback:h.replaceState,args:arguments,queue:i}),!1;h.busy(!0);var s=h.createStateObject(t,n,r);return h.isLastSavedState(s)?h.busy(!1):(h.storeState(s),h.expectedStateId=s.id,p.replaceState(s.id,s.title,s.url),h.Adapter.trigger(e,"popstate")),!0};if(s){try{h.store=l.parse(s.getItem("History.store"))||{}}catch(m){h.store={}}h.normalizeStore()}else h.store={},h.normalizeStore();h.Adapter.bind(e,"unload",h.clearAllIntervals),h.saveState(h.storeState(h.extractState(h.getLocationHref(),!0))),s&&(h.onUnload=function(){var e,t,n;try{e=l.parse(s.getItem("History.store"))||{}}catch(r){e={}}e.idToState=e.idToState||{},e.urlToId=e.urlToId||{},e.stateToId=e.stateToId||{};for(t in h.idToState){if(!h.idToState.hasOwnProperty(t))continue;e.idToState[t]=h.idToState[t]}for(t in h.urlToId){if(!h.urlToId.hasOwnProperty(t))continue;e.urlToId[t]=h.urlToId[t]}for(t in h.stateToId){if(!h.stateToId.hasOwnProperty(t))continue;e.stateToId[t]=h.stateToId[t]}h.store=e,h.normalizeStore(),n=l.stringify(e);try{s.setItem("History.store",n)}catch(i){if(i.code!==DOMException.QUOTA_EXCEEDED_ERR)throw i;s.length&&(s.removeItem("History.store"),s.setItem("History.store",n))}},h.intervalList.push(a(h.onUnload,h.options.storeInterval)),h.Adapter.bind(e,"beforeunload",h.onUnload),h.Adapter.bind(e,"unload",h.onUnload));if(!h.emulated.pushState){h.bugs.safariPoll&&h.intervalList.push(a(h.safariStatePoll,h.options.safariPollInterval));if(i.vendor==="Apple Computer, Inc."||(i.appCodeName||"")==="Mozilla")h.Adapter.bind(e,"hashchange",function(){h.Adapter.trigger(e,"popstate")}),h.getHash()&&h.Adapter.onDomLoad(function(){h.Adapter.trigger(e,"hashchange")})}},(!h.options||!h.options.delayInit)&&h.init()}(window) \ No newline at end of file diff --git a/sites/all/themes/gui/materiobasetheme/bower_components/history.js/scripts/bundled/html4+html5/jquery.history.js b/sites/all/themes/gui/materiobasetheme/bower_components/history.js/scripts/bundled/html4+html5/jquery.history.js new file mode 100644 index 00000000..20f8c9e0 --- /dev/null +++ b/sites/all/themes/gui/materiobasetheme/bower_components/history.js/scripts/bundled/html4+html5/jquery.history.js @@ -0,0 +1 @@ +typeof JSON!="object"&&(JSON={}),function(){"use strict";function f(e){return e<10?"0"+e:e}function quote(e){return escapable.lastIndex=0,escapable.test(e)?'"'+e.replace(escapable,function(e){var t=meta[e];return typeof t=="string"?t:"\\u"+("0000"+e.charCodeAt(0).toString(16)).slice(-4)})+'"':'"'+e+'"'}function str(e,t){var n,r,i,s,o=gap,u,a=t[e];a&&typeof a=="object"&&typeof a.toJSON=="function"&&(a=a.toJSON(e)),typeof rep=="function"&&(a=rep.call(t,e,a));switch(typeof a){case"string":return quote(a);case"number":return isFinite(a)?String(a):"null";case"boolean":case"null":return String(a);case"object":if(!a)return"null";gap+=indent,u=[];if(Object.prototype.toString.apply(a)==="[object Array]"){s=a.length;for(n=0;n")&&n[0]);return e>4?e:!1}();return e},h.isInternetExplorer=function(){var e=h.isInternetExplorer.cached=typeof h.isInternetExplorer.cached!="undefined"?h.isInternetExplorer.cached:Boolean(h.getInternetExplorerMajorVersion());return e},h.options.html4Mode?h.emulated={pushState:!0,hashChange:!0}:h.emulated={pushState:!Boolean(e.history&&e.history.pushState&&e.history.replaceState&&!/ Mobile\/([1-7][a-z]|(8([abcde]|f(1[0-8]))))/i.test(i.userAgent)&&!/AppleWebKit\/5([0-2]|3[0-2])/i.test(i.userAgent)),hashChange:Boolean(!("onhashchange"in e||"onhashchange"in r)||h.isInternetExplorer()&&h.getInternetExplorerMajorVersion()<8)},h.enabled=!h.emulated.pushState,h.bugs={setHash:Boolean(!h.emulated.pushState&&i.vendor==="Apple Computer, Inc."&&/AppleWebKit\/5([0-2]|3[0-3])/.test(i.userAgent)),safariPoll:Boolean(!h.emulated.pushState&&i.vendor==="Apple Computer, Inc."&&/AppleWebKit\/5([0-2]|3[0-3])/.test(i.userAgent)),ieDoubleCheck:Boolean(h.isInternetExplorer()&&h.getInternetExplorerMajorVersion()<8),hashEscape:Boolean(h.isInternetExplorer()&&h.getInternetExplorerMajorVersion()<7)},h.isEmptyObject=function(e){for(var t in e)if(e.hasOwnProperty(t))return!1;return!0},h.cloneObject=function(e){var t,n;return e?(t=l.stringify(e),n=l.parse(t)):n={},n},h.getRootUrl=function(){var e=r.location.protocol+"//"+(r.location.hostname||r.location.host);if(r.location.port||!1)e+=":"+r.location.port;return e+="/",e},h.getBaseHref=function(){var e=r.getElementsByTagName("base"),t=null,n="";return e.length===1&&(t=e[0],n=t.href.replace(/[^\/]+$/,"")),n=n.replace(/\/+$/,""),n&&(n+="/"),n},h.getBaseUrl=function(){var e=h.getBaseHref()||h.getBasePageUrl()||h.getRootUrl();return e},h.getPageUrl=function(){var e=h.getState(!1,!1),t=(e||{}).url||h.getLocationHref(),n;return n=t.replace(/\/+$/,"").replace(/[^\/]+$/,function(e,t,n){return/\./.test(e)?e:e+"/"}),n},h.getBasePageUrl=function(){var e=h.getLocationHref().replace(/[#\?].*/,"").replace(/[^\/]+$/,function(e,t,n){return/[^\/]$/.test(e)?"":e}).replace(/\/+$/,"")+"/";return e},h.getFullUrl=function(e,t){var n=e,r=e.substring(0,1);return t=typeof t=="undefined"?!0:t,/[a-z]+\:\/\//.test(e)||(r==="/"?n=h.getRootUrl()+e.replace(/^\/+/,""):r==="#"?n=h.getPageUrl().replace(/#.*/,"")+e:r==="?"?n=h.getPageUrl().replace(/[\?#].*/,"")+e:t?n=h.getBaseUrl()+e.replace(/^(\.\/)+/,""):n=h.getBasePageUrl()+e.replace(/^(\.\/)+/,"")),n.replace(/\#$/,"")},h.getShortUrl=function(e){var t=e,n=h.getBaseUrl(),r=h.getRootUrl();return h.emulated.pushState&&(t=t.replace(n,"")),t=t.replace(r,"/"),h.isTraditionalAnchor(t)&&(t="./"+t),t=t.replace(/^(\.\/)+/g,"./").replace(/\#$/,""),t},h.getLocationHref=function(e){return e=e||r,e.URL===e.location.href?e.location.href:e.location.href===decodeURIComponent(e.URL)?e.URL:e.location.hash&&decodeURIComponent(e.location.href.replace(/^[^#]+/,""))===e.location.hash?e.location.href:e.URL.indexOf("#")==-1&&e.location.href.indexOf("#")!=-1?e.location.href:e.URL||e.location.href},h.store={},h.idToState=h.idToState||{},h.stateToId=h.stateToId||{},h.urlToId=h.urlToId||{},h.storedStates=h.storedStates||[],h.savedStates=h.savedStates||[],h.normalizeStore=function(){h.store.idToState=h.store.idToState||{},h.store.urlToId=h.store.urlToId||{},h.store.stateToId=h.store.stateToId||{}},h.getState=function(e,t){typeof e=="undefined"&&(e=!0),typeof t=="undefined"&&(t=!0);var n=h.getLastSavedState();return!n&&t&&(n=h.createStateObject()),e&&(n=h.cloneObject(n),n.url=n.cleanUrl||n.url),n},h.getIdByState=function(e){var t=h.extractId(e.url),n;if(!t){n=h.getStateString(e);if(typeof h.stateToId[n]!="undefined")t=h.stateToId[n];else if(typeof h.store.stateToId[n]!="undefined")t=h.store.stateToId[n];else{for(;;){t=(new Date).getTime()+String(Math.random()).replace(/\D/g,"");if(typeof h.idToState[t]=="undefined"&&typeof h.store.idToState[t]=="undefined")break}h.stateToId[n]=t,h.idToState[t]=e}}return t},h.normalizeState=function(e){var t,n;if(!e||typeof e!="object")e={};if(typeof e.normalized!="undefined")return e;if(!e.data||typeof e.data!="object")e.data={};return t={},t.normalized=!0,t.title=e.title||"",t.url=h.getFullUrl(e.url?e.url:h.getLocationHref()),t.hash=h.getShortUrl(t.url),t.data=h.cloneObject(e.data),t.id=h.getIdByState(t),t.cleanUrl=t.url.replace(/\??\&_suid.*/,""),t.url=t.cleanUrl,n=!h.isEmptyObject(t.data),(t.title||n)&&h.options.disableSuid!==!0&&(t.hash=h.getShortUrl(t.url).replace(/\??\&_suid.*/,""),/\?/.test(t.hash)||(t.hash+="?"),t.hash+="&_suid="+t.id),t.hashedUrl=h.getFullUrl(t.hash),(h.emulated.pushState||h.bugs.safariPoll)&&h.hasUrlDuplicate(t)&&(t.url=t.hashedUrl),t},h.createStateObject=function(e,t,n){var r={data:e,title:t,url:n};return r=h.normalizeState(r),r},h.getStateById=function(e){e=String(e);var n=h.idToState[e]||h.store.idToState[e]||t;return n},h.getStateString=function(e){var t,n,r;return t=h.normalizeState(e),n={data:t.data,title:e.title,url:e.url},r=l.stringify(n),r},h.getStateId=function(e){var t,n;return t=h.normalizeState(e),n=t.id,n},h.getHashByState=function(e){var t,n;return t=h.normalizeState(e),n=t.hash,n},h.extractId=function(e){var t,n,r,i;return e.indexOf("#")!=-1?i=e.split("#")[0]:i=e,n=/(.*)\&_suid=([0-9]+)$/.exec(i),r=n?n[1]||e:e,t=n?String(n[2]||""):"",t||!1},h.isTraditionalAnchor=function(e){var t=!/[\/\?\.]/.test(e);return t},h.extractState=function(e,t){var n=null,r,i;return t=t||!1,r=h.extractId(e),r&&(n=h.getStateById(r)),n||(i=h.getFullUrl(e),r=h.getIdByUrl(i)||!1,r&&(n=h.getStateById(r)),!n&&t&&!h.isTraditionalAnchor(e)&&(n=h.createStateObject(null,null,i))),n},h.getIdByUrl=function(e){var n=h.urlToId[e]||h.store.urlToId[e]||t;return n},h.getLastSavedState=function(){return h.savedStates[h.savedStates.length-1]||t},h.getLastStoredState=function(){return h.storedStates[h.storedStates.length-1]||t},h.hasUrlDuplicate=function(e){var t=!1,n;return n=h.extractState(e.url),t=n&&n.id!==e.id,t},h.storeState=function(e){return h.urlToId[e.url]=e.id,h.storedStates.push(h.cloneObject(e)),e},h.isLastSavedState=function(e){var t=!1,n,r,i;return h.savedStates.length&&(n=e.id,r=h.getLastSavedState(),i=r.id,t=n===i),t},h.saveState=function(e){return h.isLastSavedState(e)?!1:(h.savedStates.push(h.cloneObject(e)),!0)},h.getStateByIndex=function(e){var t=null;return typeof e=="undefined"?t=h.savedStates[h.savedStates.length-1]:e<0?t=h.savedStates[h.savedStates.length+e]:t=h.savedStates[e],t},h.getCurrentIndex=function(){var e=null;return h.savedStates.length<1?e=0:e=h.savedStates.length-1,e},h.getHash=function(e){var t=h.getLocationHref(e),n;return n=h.getHashByUrl(t),n},h.unescapeHash=function(e){var t=h.normalizeHash(e);return t=decodeURIComponent(t),t},h.normalizeHash=function(e){var t=e.replace(/[^#]*#/,"").replace(/#.*/,"");return t},h.setHash=function(e,t){var n,i;return t!==!1&&h.busy()?(h.pushQueue({scope:h,callback:h.setHash,args:arguments,queue:t}),!1):(h.busy(!0),n=h.extractState(e,!0),n&&!h.emulated.pushState?h.pushState(n.data,n.title,n.url,!1):h.getHash()!==e&&(h.bugs.setHash?(i=h.getPageUrl(),h.pushState(null,null,i+"#"+e,!1)):r.location.hash=e),h)},h.escapeHash=function(t){var n=h.normalizeHash(t);return n=e.encodeURIComponent(n),h.bugs.hashEscape||(n=n.replace(/\%21/g,"!").replace(/\%26/g,"&").replace(/\%3D/g,"=").replace(/\%3F/g,"?")),n},h.getHashByUrl=function(e){var t=String(e).replace(/([^#]*)#?([^#]*)#?(.*)/,"$2");return t=h.unescapeHash(t),t},h.setTitle=function(e){var t=e.title,n;t||(n=h.getStateByIndex(0),n&&n.url===e.url&&(t=n.title||h.options.initialTitle));try{r.getElementsByTagName("title")[0].innerHTML=t.replace("<","<").replace(">",">").replace(" & "," & ")}catch(i){}return r.title=t,h},h.queues=[],h.busy=function(e){typeof e!="undefined"?h.busy.flag=e:typeof h.busy.flag=="undefined"&&(h.busy.flag=!1);if(!h.busy.flag){u(h.busy.timeout);var t=function(){var e,n,r;if(h.busy.flag)return;for(e=h.queues.length-1;e>=0;--e){n=h.queues[e];if(n.length===0)continue;r=n.shift(),h.fireQueueItem(r),h.busy.timeout=o(t,h.options.busyDelay)}};h.busy.timeout=o(t,h.options.busyDelay)}return h.busy.flag},h.busy.flag=!1,h.fireQueueItem=function(e){return e.callback.apply(e.scope||h,e.args||[])},h.pushQueue=function(e){return h.queues[e.queue||0]=h.queues[e.queue||0]||[],h.queues[e.queue||0].push(e),h},h.queue=function(e,t){return typeof e=="function"&&(e={callback:e}),typeof t!="undefined"&&(e.queue=t),h.busy()?h.pushQueue(e):h.fireQueueItem(e),h},h.clearQueue=function(){return h.busy.flag=!1,h.queues=[],h},h.stateChanged=!1,h.doubleChecker=!1,h.doubleCheckComplete=function(){return h.stateChanged=!0,h.doubleCheckClear(),h},h.doubleCheckClear=function(){return h.doubleChecker&&(u(h.doubleChecker),h.doubleChecker=!1),h},h.doubleCheck=function(e){return h.stateChanged=!1,h.doubleCheckClear(),h.bugs.ieDoubleCheck&&(h.doubleChecker=o(function(){return h.doubleCheckClear(),h.stateChanged||e(),!0},h.options.doubleCheckInterval)),h},h.safariStatePoll=function(){var t=h.extractState(h.getLocationHref()),n;if(!h.isLastSavedState(t))return n=t,n||(n=h.createStateObject()),h.Adapter.trigger(e,"popstate"),h;return},h.back=function(e){return e!==!1&&h.busy()?(h.pushQueue({scope:h,callback:h.back,args:arguments,queue:e}),!1):(h.busy(!0),h.doubleCheck(function(){h.back(!1)}),p.go(-1),!0)},h.forward=function(e){return e!==!1&&h.busy()?(h.pushQueue({scope:h,callback:h.forward,args:arguments,queue:e}),!1):(h.busy(!0),h.doubleCheck(function(){h.forward(!1)}),p.go(1),!0)},h.go=function(e,t){var n;if(e>0)for(n=1;n<=e;++n)h.forward(t);else{if(!(e<0))throw new Error("History.go: History.go requires a positive or negative integer passed.");for(n=-1;n>=e;--n)h.back(t)}return h};if(h.emulated.pushState){var v=function(){};h.pushState=h.pushState||v,h.replaceState=h.replaceState||v}else h.onPopState=function(t,n){var r=!1,i=!1,s,o;return h.doubleCheckComplete(),s=h.getHash(),s?(o=h.extractState(s||h.getLocationHref(),!0),o?h.replaceState(o.data,o.title,o.url,!1):(h.Adapter.trigger(e,"anchorchange"),h.busy(!1)),h.expectedStateId=!1,!1):(r=h.Adapter.extractEventData("state",t,n)||!1,r?i=h.getStateById(r):h.expectedStateId?i=h.getStateById(h.expectedStateId):i=h.extractState(h.getLocationHref()),i||(i=h.createStateObject(null,null,h.getLocationHref())),h.expectedStateId=!1,h.isLastSavedState(i)?(h.busy(!1),!1):(h.storeState(i),h.saveState(i),h.setTitle(i),h.Adapter.trigger(e,"statechange"),h.busy(!1),!0))},h.Adapter.bind(e,"popstate",h.onPopState),h.pushState=function(t,n,r,i){if(h.getHashByUrl(r)&&h.emulated.pushState)throw new Error("History.js does not support states with fragement-identifiers (hashes/anchors).");if(i!==!1&&h.busy())return h.pushQueue({scope:h,callback:h.pushState,args:arguments,queue:i}),!1;h.busy(!0);var s=h.createStateObject(t,n,r);return h.isLastSavedState(s)?h.busy(!1):(h.storeState(s),h.expectedStateId=s.id,p.pushState(s.id,s.title,s.url),h.Adapter.trigger(e,"popstate")),!0},h.replaceState=function(t,n,r,i){if(h.getHashByUrl(r)&&h.emulated.pushState)throw new Error("History.js does not support states with fragement-identifiers (hashes/anchors).");if(i!==!1&&h.busy())return h.pushQueue({scope:h,callback:h.replaceState,args:arguments,queue:i}),!1;h.busy(!0);var s=h.createStateObject(t,n,r);return h.isLastSavedState(s)?h.busy(!1):(h.storeState(s),h.expectedStateId=s.id,p.replaceState(s.id,s.title,s.url),h.Adapter.trigger(e,"popstate")),!0};if(s){try{h.store=l.parse(s.getItem("History.store"))||{}}catch(m){h.store={}}h.normalizeStore()}else h.store={},h.normalizeStore();h.Adapter.bind(e,"unload",h.clearAllIntervals),h.saveState(h.storeState(h.extractState(h.getLocationHref(),!0))),s&&(h.onUnload=function(){var e,t,n;try{e=l.parse(s.getItem("History.store"))||{}}catch(r){e={}}e.idToState=e.idToState||{},e.urlToId=e.urlToId||{},e.stateToId=e.stateToId||{};for(t in h.idToState){if(!h.idToState.hasOwnProperty(t))continue;e.idToState[t]=h.idToState[t]}for(t in h.urlToId){if(!h.urlToId.hasOwnProperty(t))continue;e.urlToId[t]=h.urlToId[t]}for(t in h.stateToId){if(!h.stateToId.hasOwnProperty(t))continue;e.stateToId[t]=h.stateToId[t]}h.store=e,h.normalizeStore(),n=l.stringify(e);try{s.setItem("History.store",n)}catch(i){if(i.code!==DOMException.QUOTA_EXCEEDED_ERR)throw i;s.length&&(s.removeItem("History.store"),s.setItem("History.store",n))}},h.intervalList.push(a(h.onUnload,h.options.storeInterval)),h.Adapter.bind(e,"beforeunload",h.onUnload),h.Adapter.bind(e,"unload",h.onUnload));if(!h.emulated.pushState){h.bugs.safariPoll&&h.intervalList.push(a(h.safariStatePoll,h.options.safariPollInterval));if(i.vendor==="Apple Computer, Inc."||(i.appCodeName||"")==="Mozilla")h.Adapter.bind(e,"hashchange",function(){h.Adapter.trigger(e,"popstate")}),h.getHash()&&h.Adapter.onDomLoad(function(){h.Adapter.trigger(e,"hashchange")})}},(!h.options||!h.options.delayInit)&&h.init()}(window) \ No newline at end of file diff --git a/sites/all/themes/gui/materiobasetheme/bower_components/history.js/scripts/bundled/html4+html5/mootools.history.js b/sites/all/themes/gui/materiobasetheme/bower_components/history.js/scripts/bundled/html4+html5/mootools.history.js new file mode 100644 index 00000000..2e699f2b --- /dev/null +++ b/sites/all/themes/gui/materiobasetheme/bower_components/history.js/scripts/bundled/html4+html5/mootools.history.js @@ -0,0 +1 @@ +typeof JSON!="object"&&(JSON={}),function(){"use strict";function f(e){return e<10?"0"+e:e}function quote(e){return escapable.lastIndex=0,escapable.test(e)?'"'+e.replace(escapable,function(e){var t=meta[e];return typeof t=="string"?t:"\\u"+("0000"+e.charCodeAt(0).toString(16)).slice(-4)})+'"':'"'+e+'"'}function str(e,t){var n,r,i,s,o=gap,u,a=t[e];a&&typeof a=="object"&&typeof a.toJSON=="function"&&(a=a.toJSON(e)),typeof rep=="function"&&(a=rep.call(t,e,a));switch(typeof a){case"string":return quote(a);case"number":return isFinite(a)?String(a):"null";case"boolean":case"null":return String(a);case"object":if(!a)return"null";gap+=indent,u=[];if(Object.prototype.toString.apply(a)==="[object Array]"){s=a.length;for(n=0;n")&&n[0]);return e>4?e:!1}();return e},h.isInternetExplorer=function(){var e=h.isInternetExplorer.cached=typeof h.isInternetExplorer.cached!="undefined"?h.isInternetExplorer.cached:Boolean(h.getInternetExplorerMajorVersion());return e},h.options.html4Mode?h.emulated={pushState:!0,hashChange:!0}:h.emulated={pushState:!Boolean(e.history&&e.history.pushState&&e.history.replaceState&&!/ Mobile\/([1-7][a-z]|(8([abcde]|f(1[0-8]))))/i.test(i.userAgent)&&!/AppleWebKit\/5([0-2]|3[0-2])/i.test(i.userAgent)),hashChange:Boolean(!("onhashchange"in e||"onhashchange"in r)||h.isInternetExplorer()&&h.getInternetExplorerMajorVersion()<8)},h.enabled=!h.emulated.pushState,h.bugs={setHash:Boolean(!h.emulated.pushState&&i.vendor==="Apple Computer, Inc."&&/AppleWebKit\/5([0-2]|3[0-3])/.test(i.userAgent)),safariPoll:Boolean(!h.emulated.pushState&&i.vendor==="Apple Computer, Inc."&&/AppleWebKit\/5([0-2]|3[0-3])/.test(i.userAgent)),ieDoubleCheck:Boolean(h.isInternetExplorer()&&h.getInternetExplorerMajorVersion()<8),hashEscape:Boolean(h.isInternetExplorer()&&h.getInternetExplorerMajorVersion()<7)},h.isEmptyObject=function(e){for(var t in e)if(e.hasOwnProperty(t))return!1;return!0},h.cloneObject=function(e){var t,n;return e?(t=l.stringify(e),n=l.parse(t)):n={},n},h.getRootUrl=function(){var e=r.location.protocol+"//"+(r.location.hostname||r.location.host);if(r.location.port||!1)e+=":"+r.location.port;return e+="/",e},h.getBaseHref=function(){var e=r.getElementsByTagName("base"),t=null,n="";return e.length===1&&(t=e[0],n=t.href.replace(/[^\/]+$/,"")),n=n.replace(/\/+$/,""),n&&(n+="/"),n},h.getBaseUrl=function(){var e=h.getBaseHref()||h.getBasePageUrl()||h.getRootUrl();return e},h.getPageUrl=function(){var e=h.getState(!1,!1),t=(e||{}).url||h.getLocationHref(),n;return n=t.replace(/\/+$/,"").replace(/[^\/]+$/,function(e,t,n){return/\./.test(e)?e:e+"/"}),n},h.getBasePageUrl=function(){var e=h.getLocationHref().replace(/[#\?].*/,"").replace(/[^\/]+$/,function(e,t,n){return/[^\/]$/.test(e)?"":e}).replace(/\/+$/,"")+"/";return e},h.getFullUrl=function(e,t){var n=e,r=e.substring(0,1);return t=typeof t=="undefined"?!0:t,/[a-z]+\:\/\//.test(e)||(r==="/"?n=h.getRootUrl()+e.replace(/^\/+/,""):r==="#"?n=h.getPageUrl().replace(/#.*/,"")+e:r==="?"?n=h.getPageUrl().replace(/[\?#].*/,"")+e:t?n=h.getBaseUrl()+e.replace(/^(\.\/)+/,""):n=h.getBasePageUrl()+e.replace(/^(\.\/)+/,"")),n.replace(/\#$/,"")},h.getShortUrl=function(e){var t=e,n=h.getBaseUrl(),r=h.getRootUrl();return h.emulated.pushState&&(t=t.replace(n,"")),t=t.replace(r,"/"),h.isTraditionalAnchor(t)&&(t="./"+t),t=t.replace(/^(\.\/)+/g,"./").replace(/\#$/,""),t},h.getLocationHref=function(e){return e=e||r,e.URL===e.location.href?e.location.href:e.location.href===decodeURIComponent(e.URL)?e.URL:e.location.hash&&decodeURIComponent(e.location.href.replace(/^[^#]+/,""))===e.location.hash?e.location.href:e.URL.indexOf("#")==-1&&e.location.href.indexOf("#")!=-1?e.location.href:e.URL||e.location.href},h.store={},h.idToState=h.idToState||{},h.stateToId=h.stateToId||{},h.urlToId=h.urlToId||{},h.storedStates=h.storedStates||[],h.savedStates=h.savedStates||[],h.normalizeStore=function(){h.store.idToState=h.store.idToState||{},h.store.urlToId=h.store.urlToId||{},h.store.stateToId=h.store.stateToId||{}},h.getState=function(e,t){typeof e=="undefined"&&(e=!0),typeof t=="undefined"&&(t=!0);var n=h.getLastSavedState();return!n&&t&&(n=h.createStateObject()),e&&(n=h.cloneObject(n),n.url=n.cleanUrl||n.url),n},h.getIdByState=function(e){var t=h.extractId(e.url),n;if(!t){n=h.getStateString(e);if(typeof h.stateToId[n]!="undefined")t=h.stateToId[n];else if(typeof h.store.stateToId[n]!="undefined")t=h.store.stateToId[n];else{for(;;){t=(new Date).getTime()+String(Math.random()).replace(/\D/g,"");if(typeof h.idToState[t]=="undefined"&&typeof h.store.idToState[t]=="undefined")break}h.stateToId[n]=t,h.idToState[t]=e}}return t},h.normalizeState=function(e){var t,n;if(!e||typeof e!="object")e={};if(typeof e.normalized!="undefined")return e;if(!e.data||typeof e.data!="object")e.data={};return t={},t.normalized=!0,t.title=e.title||"",t.url=h.getFullUrl(e.url?e.url:h.getLocationHref()),t.hash=h.getShortUrl(t.url),t.data=h.cloneObject(e.data),t.id=h.getIdByState(t),t.cleanUrl=t.url.replace(/\??\&_suid.*/,""),t.url=t.cleanUrl,n=!h.isEmptyObject(t.data),(t.title||n)&&h.options.disableSuid!==!0&&(t.hash=h.getShortUrl(t.url).replace(/\??\&_suid.*/,""),/\?/.test(t.hash)||(t.hash+="?"),t.hash+="&_suid="+t.id),t.hashedUrl=h.getFullUrl(t.hash),(h.emulated.pushState||h.bugs.safariPoll)&&h.hasUrlDuplicate(t)&&(t.url=t.hashedUrl),t},h.createStateObject=function(e,t,n){var r={data:e,title:t,url:n};return r=h.normalizeState(r),r},h.getStateById=function(e){e=String(e);var n=h.idToState[e]||h.store.idToState[e]||t;return n},h.getStateString=function(e){var t,n,r;return t=h.normalizeState(e),n={data:t.data,title:e.title,url:e.url},r=l.stringify(n),r},h.getStateId=function(e){var t,n;return t=h.normalizeState(e),n=t.id,n},h.getHashByState=function(e){var t,n;return t=h.normalizeState(e),n=t.hash,n},h.extractId=function(e){var t,n,r,i;return e.indexOf("#")!=-1?i=e.split("#")[0]:i=e,n=/(.*)\&_suid=([0-9]+)$/.exec(i),r=n?n[1]||e:e,t=n?String(n[2]||""):"",t||!1},h.isTraditionalAnchor=function(e){var t=!/[\/\?\.]/.test(e);return t},h.extractState=function(e,t){var n=null,r,i;return t=t||!1,r=h.extractId(e),r&&(n=h.getStateById(r)),n||(i=h.getFullUrl(e),r=h.getIdByUrl(i)||!1,r&&(n=h.getStateById(r)),!n&&t&&!h.isTraditionalAnchor(e)&&(n=h.createStateObject(null,null,i))),n},h.getIdByUrl=function(e){var n=h.urlToId[e]||h.store.urlToId[e]||t;return n},h.getLastSavedState=function(){return h.savedStates[h.savedStates.length-1]||t},h.getLastStoredState=function(){return h.storedStates[h.storedStates.length-1]||t},h.hasUrlDuplicate=function(e){var t=!1,n;return n=h.extractState(e.url),t=n&&n.id!==e.id,t},h.storeState=function(e){return h.urlToId[e.url]=e.id,h.storedStates.push(h.cloneObject(e)),e},h.isLastSavedState=function(e){var t=!1,n,r,i;return h.savedStates.length&&(n=e.id,r=h.getLastSavedState(),i=r.id,t=n===i),t},h.saveState=function(e){return h.isLastSavedState(e)?!1:(h.savedStates.push(h.cloneObject(e)),!0)},h.getStateByIndex=function(e){var t=null;return typeof e=="undefined"?t=h.savedStates[h.savedStates.length-1]:e<0?t=h.savedStates[h.savedStates.length+e]:t=h.savedStates[e],t},h.getCurrentIndex=function(){var e=null;return h.savedStates.length<1?e=0:e=h.savedStates.length-1,e},h.getHash=function(e){var t=h.getLocationHref(e),n;return n=h.getHashByUrl(t),n},h.unescapeHash=function(e){var t=h.normalizeHash(e);return t=decodeURIComponent(t),t},h.normalizeHash=function(e){var t=e.replace(/[^#]*#/,"").replace(/#.*/,"");return t},h.setHash=function(e,t){var n,i;return t!==!1&&h.busy()?(h.pushQueue({scope:h,callback:h.setHash,args:arguments,queue:t}),!1):(h.busy(!0),n=h.extractState(e,!0),n&&!h.emulated.pushState?h.pushState(n.data,n.title,n.url,!1):h.getHash()!==e&&(h.bugs.setHash?(i=h.getPageUrl(),h.pushState(null,null,i+"#"+e,!1)):r.location.hash=e),h)},h.escapeHash=function(t){var n=h.normalizeHash(t);return n=e.encodeURIComponent(n),h.bugs.hashEscape||(n=n.replace(/\%21/g,"!").replace(/\%26/g,"&").replace(/\%3D/g,"=").replace(/\%3F/g,"?")),n},h.getHashByUrl=function(e){var t=String(e).replace(/([^#]*)#?([^#]*)#?(.*)/,"$2");return t=h.unescapeHash(t),t},h.setTitle=function(e){var t=e.title,n;t||(n=h.getStateByIndex(0),n&&n.url===e.url&&(t=n.title||h.options.initialTitle));try{r.getElementsByTagName("title")[0].innerHTML=t.replace("<","<").replace(">",">").replace(" & "," & ")}catch(i){}return r.title=t,h},h.queues=[],h.busy=function(e){typeof e!="undefined"?h.busy.flag=e:typeof h.busy.flag=="undefined"&&(h.busy.flag=!1);if(!h.busy.flag){u(h.busy.timeout);var t=function(){var e,n,r;if(h.busy.flag)return;for(e=h.queues.length-1;e>=0;--e){n=h.queues[e];if(n.length===0)continue;r=n.shift(),h.fireQueueItem(r),h.busy.timeout=o(t,h.options.busyDelay)}};h.busy.timeout=o(t,h.options.busyDelay)}return h.busy.flag},h.busy.flag=!1,h.fireQueueItem=function(e){return e.callback.apply(e.scope||h,e.args||[])},h.pushQueue=function(e){return h.queues[e.queue||0]=h.queues[e.queue||0]||[],h.queues[e.queue||0].push(e),h},h.queue=function(e,t){return typeof e=="function"&&(e={callback:e}),typeof t!="undefined"&&(e.queue=t),h.busy()?h.pushQueue(e):h.fireQueueItem(e),h},h.clearQueue=function(){return h.busy.flag=!1,h.queues=[],h},h.stateChanged=!1,h.doubleChecker=!1,h.doubleCheckComplete=function(){return h.stateChanged=!0,h.doubleCheckClear(),h},h.doubleCheckClear=function(){return h.doubleChecker&&(u(h.doubleChecker),h.doubleChecker=!1),h},h.doubleCheck=function(e){return h.stateChanged=!1,h.doubleCheckClear(),h.bugs.ieDoubleCheck&&(h.doubleChecker=o(function(){return h.doubleCheckClear(),h.stateChanged||e(),!0},h.options.doubleCheckInterval)),h},h.safariStatePoll=function(){var t=h.extractState(h.getLocationHref()),n;if(!h.isLastSavedState(t))return n=t,n||(n=h.createStateObject()),h.Adapter.trigger(e,"popstate"),h;return},h.back=function(e){return e!==!1&&h.busy()?(h.pushQueue({scope:h,callback:h.back,args:arguments,queue:e}),!1):(h.busy(!0),h.doubleCheck(function(){h.back(!1)}),p.go(-1),!0)},h.forward=function(e){return e!==!1&&h.busy()?(h.pushQueue({scope:h,callback:h.forward,args:arguments,queue:e}),!1):(h.busy(!0),h.doubleCheck(function(){h.forward(!1)}),p.go(1),!0)},h.go=function(e,t){var n;if(e>0)for(n=1;n<=e;++n)h.forward(t);else{if(!(e<0))throw new Error("History.go: History.go requires a positive or negative integer passed.");for(n=-1;n>=e;--n)h.back(t)}return h};if(h.emulated.pushState){var v=function(){};h.pushState=h.pushState||v,h.replaceState=h.replaceState||v}else h.onPopState=function(t,n){var r=!1,i=!1,s,o;return h.doubleCheckComplete(),s=h.getHash(),s?(o=h.extractState(s||h.getLocationHref(),!0),o?h.replaceState(o.data,o.title,o.url,!1):(h.Adapter.trigger(e,"anchorchange"),h.busy(!1)),h.expectedStateId=!1,!1):(r=h.Adapter.extractEventData("state",t,n)||!1,r?i=h.getStateById(r):h.expectedStateId?i=h.getStateById(h.expectedStateId):i=h.extractState(h.getLocationHref()),i||(i=h.createStateObject(null,null,h.getLocationHref())),h.expectedStateId=!1,h.isLastSavedState(i)?(h.busy(!1),!1):(h.storeState(i),h.saveState(i),h.setTitle(i),h.Adapter.trigger(e,"statechange"),h.busy(!1),!0))},h.Adapter.bind(e,"popstate",h.onPopState),h.pushState=function(t,n,r,i){if(h.getHashByUrl(r)&&h.emulated.pushState)throw new Error("History.js does not support states with fragement-identifiers (hashes/anchors).");if(i!==!1&&h.busy())return h.pushQueue({scope:h,callback:h.pushState,args:arguments,queue:i}),!1;h.busy(!0);var s=h.createStateObject(t,n,r);return h.isLastSavedState(s)?h.busy(!1):(h.storeState(s),h.expectedStateId=s.id,p.pushState(s.id,s.title,s.url),h.Adapter.trigger(e,"popstate")),!0},h.replaceState=function(t,n,r,i){if(h.getHashByUrl(r)&&h.emulated.pushState)throw new Error("History.js does not support states with fragement-identifiers (hashes/anchors).");if(i!==!1&&h.busy())return h.pushQueue({scope:h,callback:h.replaceState,args:arguments,queue:i}),!1;h.busy(!0);var s=h.createStateObject(t,n,r);return h.isLastSavedState(s)?h.busy(!1):(h.storeState(s),h.expectedStateId=s.id,p.replaceState(s.id,s.title,s.url),h.Adapter.trigger(e,"popstate")),!0};if(s){try{h.store=l.parse(s.getItem("History.store"))||{}}catch(m){h.store={}}h.normalizeStore()}else h.store={},h.normalizeStore();h.Adapter.bind(e,"unload",h.clearAllIntervals),h.saveState(h.storeState(h.extractState(h.getLocationHref(),!0))),s&&(h.onUnload=function(){var e,t,n;try{e=l.parse(s.getItem("History.store"))||{}}catch(r){e={}}e.idToState=e.idToState||{},e.urlToId=e.urlToId||{},e.stateToId=e.stateToId||{};for(t in h.idToState){if(!h.idToState.hasOwnProperty(t))continue;e.idToState[t]=h.idToState[t]}for(t in h.urlToId){if(!h.urlToId.hasOwnProperty(t))continue;e.urlToId[t]=h.urlToId[t]}for(t in h.stateToId){if(!h.stateToId.hasOwnProperty(t))continue;e.stateToId[t]=h.stateToId[t]}h.store=e,h.normalizeStore(),n=l.stringify(e);try{s.setItem("History.store",n)}catch(i){if(i.code!==DOMException.QUOTA_EXCEEDED_ERR)throw i;s.length&&(s.removeItem("History.store"),s.setItem("History.store",n))}},h.intervalList.push(a(h.onUnload,h.options.storeInterval)),h.Adapter.bind(e,"beforeunload",h.onUnload),h.Adapter.bind(e,"unload",h.onUnload));if(!h.emulated.pushState){h.bugs.safariPoll&&h.intervalList.push(a(h.safariStatePoll,h.options.safariPollInterval));if(i.vendor==="Apple Computer, Inc."||(i.appCodeName||"")==="Mozilla")h.Adapter.bind(e,"hashchange",function(){h.Adapter.trigger(e,"popstate")}),h.getHash()&&h.Adapter.onDomLoad(function(){h.Adapter.trigger(e,"hashchange")})}},(!h.options||!h.options.delayInit)&&h.init()}(window) \ No newline at end of file diff --git a/sites/all/themes/gui/materiobasetheme/bower_components/history.js/scripts/bundled/html4+html5/native.history.js b/sites/all/themes/gui/materiobasetheme/bower_components/history.js/scripts/bundled/html4+html5/native.history.js new file mode 100644 index 00000000..649fc35c --- /dev/null +++ b/sites/all/themes/gui/materiobasetheme/bower_components/history.js/scripts/bundled/html4+html5/native.history.js @@ -0,0 +1 @@ +typeof JSON!="object"&&(JSON={}),function(){"use strict";function f(e){return e<10?"0"+e:e}function quote(e){return escapable.lastIndex=0,escapable.test(e)?'"'+e.replace(escapable,function(e){var t=meta[e];return typeof t=="string"?t:"\\u"+("0000"+e.charCodeAt(0).toString(16)).slice(-4)})+'"':'"'+e+'"'}function str(e,t){var n,r,i,s,o=gap,u,a=t[e];a&&typeof a=="object"&&typeof a.toJSON=="function"&&(a=a.toJSON(e)),typeof rep=="function"&&(a=rep.call(t,e,a));switch(typeof a){case"string":return quote(a);case"number":return isFinite(a)?String(a):"null";case"boolean":case"null":return String(a);case"object":if(!a)return"null";gap+=indent,u=[];if(Object.prototype.toString.apply(a)==="[object Array]"){s=a.length;for(n=0;n")&&n[0]);return e>4?e:!1}();return e},h.isInternetExplorer=function(){var e=h.isInternetExplorer.cached=typeof h.isInternetExplorer.cached!="undefined"?h.isInternetExplorer.cached:Boolean(h.getInternetExplorerMajorVersion());return e},h.options.html4Mode?h.emulated={pushState:!0,hashChange:!0}:h.emulated={pushState:!Boolean(e.history&&e.history.pushState&&e.history.replaceState&&!/ Mobile\/([1-7][a-z]|(8([abcde]|f(1[0-8]))))/i.test(i.userAgent)&&!/AppleWebKit\/5([0-2]|3[0-2])/i.test(i.userAgent)),hashChange:Boolean(!("onhashchange"in e||"onhashchange"in r)||h.isInternetExplorer()&&h.getInternetExplorerMajorVersion()<8)},h.enabled=!h.emulated.pushState,h.bugs={setHash:Boolean(!h.emulated.pushState&&i.vendor==="Apple Computer, Inc."&&/AppleWebKit\/5([0-2]|3[0-3])/.test(i.userAgent)),safariPoll:Boolean(!h.emulated.pushState&&i.vendor==="Apple Computer, Inc."&&/AppleWebKit\/5([0-2]|3[0-3])/.test(i.userAgent)),ieDoubleCheck:Boolean(h.isInternetExplorer()&&h.getInternetExplorerMajorVersion()<8),hashEscape:Boolean(h.isInternetExplorer()&&h.getInternetExplorerMajorVersion()<7)},h.isEmptyObject=function(e){for(var t in e)if(e.hasOwnProperty(t))return!1;return!0},h.cloneObject=function(e){var t,n;return e?(t=l.stringify(e),n=l.parse(t)):n={},n},h.getRootUrl=function(){var e=r.location.protocol+"//"+(r.location.hostname||r.location.host);if(r.location.port||!1)e+=":"+r.location.port;return e+="/",e},h.getBaseHref=function(){var e=r.getElementsByTagName("base"),t=null,n="";return e.length===1&&(t=e[0],n=t.href.replace(/[^\/]+$/,"")),n=n.replace(/\/+$/,""),n&&(n+="/"),n},h.getBaseUrl=function(){var e=h.getBaseHref()||h.getBasePageUrl()||h.getRootUrl();return e},h.getPageUrl=function(){var e=h.getState(!1,!1),t=(e||{}).url||h.getLocationHref(),n;return n=t.replace(/\/+$/,"").replace(/[^\/]+$/,function(e,t,n){return/\./.test(e)?e:e+"/"}),n},h.getBasePageUrl=function(){var e=h.getLocationHref().replace(/[#\?].*/,"").replace(/[^\/]+$/,function(e,t,n){return/[^\/]$/.test(e)?"":e}).replace(/\/+$/,"")+"/";return e},h.getFullUrl=function(e,t){var n=e,r=e.substring(0,1);return t=typeof t=="undefined"?!0:t,/[a-z]+\:\/\//.test(e)||(r==="/"?n=h.getRootUrl()+e.replace(/^\/+/,""):r==="#"?n=h.getPageUrl().replace(/#.*/,"")+e:r==="?"?n=h.getPageUrl().replace(/[\?#].*/,"")+e:t?n=h.getBaseUrl()+e.replace(/^(\.\/)+/,""):n=h.getBasePageUrl()+e.replace(/^(\.\/)+/,"")),n.replace(/\#$/,"")},h.getShortUrl=function(e){var t=e,n=h.getBaseUrl(),r=h.getRootUrl();return h.emulated.pushState&&(t=t.replace(n,"")),t=t.replace(r,"/"),h.isTraditionalAnchor(t)&&(t="./"+t),t=t.replace(/^(\.\/)+/g,"./").replace(/\#$/,""),t},h.getLocationHref=function(e){return e=e||r,e.URL===e.location.href?e.location.href:e.location.href===decodeURIComponent(e.URL)?e.URL:e.location.hash&&decodeURIComponent(e.location.href.replace(/^[^#]+/,""))===e.location.hash?e.location.href:e.URL.indexOf("#")==-1&&e.location.href.indexOf("#")!=-1?e.location.href:e.URL||e.location.href},h.store={},h.idToState=h.idToState||{},h.stateToId=h.stateToId||{},h.urlToId=h.urlToId||{},h.storedStates=h.storedStates||[],h.savedStates=h.savedStates||[],h.normalizeStore=function(){h.store.idToState=h.store.idToState||{},h.store.urlToId=h.store.urlToId||{},h.store.stateToId=h.store.stateToId||{}},h.getState=function(e,t){typeof e=="undefined"&&(e=!0),typeof t=="undefined"&&(t=!0);var n=h.getLastSavedState();return!n&&t&&(n=h.createStateObject()),e&&(n=h.cloneObject(n),n.url=n.cleanUrl||n.url),n},h.getIdByState=function(e){var t=h.extractId(e.url),n;if(!t){n=h.getStateString(e);if(typeof h.stateToId[n]!="undefined")t=h.stateToId[n];else if(typeof h.store.stateToId[n]!="undefined")t=h.store.stateToId[n];else{for(;;){t=(new Date).getTime()+String(Math.random()).replace(/\D/g,"");if(typeof h.idToState[t]=="undefined"&&typeof h.store.idToState[t]=="undefined")break}h.stateToId[n]=t,h.idToState[t]=e}}return t},h.normalizeState=function(e){var t,n;if(!e||typeof e!="object")e={};if(typeof e.normalized!="undefined")return e;if(!e.data||typeof e.data!="object")e.data={};return t={},t.normalized=!0,t.title=e.title||"",t.url=h.getFullUrl(e.url?e.url:h.getLocationHref()),t.hash=h.getShortUrl(t.url),t.data=h.cloneObject(e.data),t.id=h.getIdByState(t),t.cleanUrl=t.url.replace(/\??\&_suid.*/,""),t.url=t.cleanUrl,n=!h.isEmptyObject(t.data),(t.title||n)&&h.options.disableSuid!==!0&&(t.hash=h.getShortUrl(t.url).replace(/\??\&_suid.*/,""),/\?/.test(t.hash)||(t.hash+="?"),t.hash+="&_suid="+t.id),t.hashedUrl=h.getFullUrl(t.hash),(h.emulated.pushState||h.bugs.safariPoll)&&h.hasUrlDuplicate(t)&&(t.url=t.hashedUrl),t},h.createStateObject=function(e,t,n){var r={data:e,title:t,url:n};return r=h.normalizeState(r),r},h.getStateById=function(e){e=String(e);var n=h.idToState[e]||h.store.idToState[e]||t;return n},h.getStateString=function(e){var t,n,r;return t=h.normalizeState(e),n={data:t.data,title:e.title,url:e.url},r=l.stringify(n),r},h.getStateId=function(e){var t,n;return t=h.normalizeState(e),n=t.id,n},h.getHashByState=function(e){var t,n;return t=h.normalizeState(e),n=t.hash,n},h.extractId=function(e){var t,n,r,i;return e.indexOf("#")!=-1?i=e.split("#")[0]:i=e,n=/(.*)\&_suid=([0-9]+)$/.exec(i),r=n?n[1]||e:e,t=n?String(n[2]||""):"",t||!1},h.isTraditionalAnchor=function(e){var t=!/[\/\?\.]/.test(e);return t},h.extractState=function(e,t){var n=null,r,i;return t=t||!1,r=h.extractId(e),r&&(n=h.getStateById(r)),n||(i=h.getFullUrl(e),r=h.getIdByUrl(i)||!1,r&&(n=h.getStateById(r)),!n&&t&&!h.isTraditionalAnchor(e)&&(n=h.createStateObject(null,null,i))),n},h.getIdByUrl=function(e){var n=h.urlToId[e]||h.store.urlToId[e]||t;return n},h.getLastSavedState=function(){return h.savedStates[h.savedStates.length-1]||t},h.getLastStoredState=function(){return h.storedStates[h.storedStates.length-1]||t},h.hasUrlDuplicate=function(e){var t=!1,n;return n=h.extractState(e.url),t=n&&n.id!==e.id,t},h.storeState=function(e){return h.urlToId[e.url]=e.id,h.storedStates.push(h.cloneObject(e)),e},h.isLastSavedState=function(e){var t=!1,n,r,i;return h.savedStates.length&&(n=e.id,r=h.getLastSavedState(),i=r.id,t=n===i),t},h.saveState=function(e){return h.isLastSavedState(e)?!1:(h.savedStates.push(h.cloneObject(e)),!0)},h.getStateByIndex=function(e){var t=null;return typeof e=="undefined"?t=h.savedStates[h.savedStates.length-1]:e<0?t=h.savedStates[h.savedStates.length+e]:t=h.savedStates[e],t},h.getCurrentIndex=function(){var e=null;return h.savedStates.length<1?e=0:e=h.savedStates.length-1,e},h.getHash=function(e){var t=h.getLocationHref(e),n;return n=h.getHashByUrl(t),n},h.unescapeHash=function(e){var t=h.normalizeHash(e);return t=decodeURIComponent(t),t},h.normalizeHash=function(e){var t=e.replace(/[^#]*#/,"").replace(/#.*/,"");return t},h.setHash=function(e,t){var n,i;return t!==!1&&h.busy()?(h.pushQueue({scope:h,callback:h.setHash,args:arguments,queue:t}),!1):(h.busy(!0),n=h.extractState(e,!0),n&&!h.emulated.pushState?h.pushState(n.data,n.title,n.url,!1):h.getHash()!==e&&(h.bugs.setHash?(i=h.getPageUrl(),h.pushState(null,null,i+"#"+e,!1)):r.location.hash=e),h)},h.escapeHash=function(t){var n=h.normalizeHash(t);return n=e.encodeURIComponent(n),h.bugs.hashEscape||(n=n.replace(/\%21/g,"!").replace(/\%26/g,"&").replace(/\%3D/g,"=").replace(/\%3F/g,"?")),n},h.getHashByUrl=function(e){var t=String(e).replace(/([^#]*)#?([^#]*)#?(.*)/,"$2");return t=h.unescapeHash(t),t},h.setTitle=function(e){var t=e.title,n;t||(n=h.getStateByIndex(0),n&&n.url===e.url&&(t=n.title||h.options.initialTitle));try{r.getElementsByTagName("title")[0].innerHTML=t.replace("<","<").replace(">",">").replace(" & "," & ")}catch(i){}return r.title=t,h},h.queues=[],h.busy=function(e){typeof e!="undefined"?h.busy.flag=e:typeof h.busy.flag=="undefined"&&(h.busy.flag=!1);if(!h.busy.flag){u(h.busy.timeout);var t=function(){var e,n,r;if(h.busy.flag)return;for(e=h.queues.length-1;e>=0;--e){n=h.queues[e];if(n.length===0)continue;r=n.shift(),h.fireQueueItem(r),h.busy.timeout=o(t,h.options.busyDelay)}};h.busy.timeout=o(t,h.options.busyDelay)}return h.busy.flag},h.busy.flag=!1,h.fireQueueItem=function(e){return e.callback.apply(e.scope||h,e.args||[])},h.pushQueue=function(e){return h.queues[e.queue||0]=h.queues[e.queue||0]||[],h.queues[e.queue||0].push(e),h},h.queue=function(e,t){return typeof e=="function"&&(e={callback:e}),typeof t!="undefined"&&(e.queue=t),h.busy()?h.pushQueue(e):h.fireQueueItem(e),h},h.clearQueue=function(){return h.busy.flag=!1,h.queues=[],h},h.stateChanged=!1,h.doubleChecker=!1,h.doubleCheckComplete=function(){return h.stateChanged=!0,h.doubleCheckClear(),h},h.doubleCheckClear=function(){return h.doubleChecker&&(u(h.doubleChecker),h.doubleChecker=!1),h},h.doubleCheck=function(e){return h.stateChanged=!1,h.doubleCheckClear(),h.bugs.ieDoubleCheck&&(h.doubleChecker=o(function(){return h.doubleCheckClear(),h.stateChanged||e(),!0},h.options.doubleCheckInterval)),h},h.safariStatePoll=function(){var t=h.extractState(h.getLocationHref()),n;if(!h.isLastSavedState(t))return n=t,n||(n=h.createStateObject()),h.Adapter.trigger(e,"popstate"),h;return},h.back=function(e){return e!==!1&&h.busy()?(h.pushQueue({scope:h,callback:h.back,args:arguments,queue:e}),!1):(h.busy(!0),h.doubleCheck(function(){h.back(!1)}),p.go(-1),!0)},h.forward=function(e){return e!==!1&&h.busy()?(h.pushQueue({scope:h,callback:h.forward,args:arguments,queue:e}),!1):(h.busy(!0),h.doubleCheck(function(){h.forward(!1)}),p.go(1),!0)},h.go=function(e,t){var n;if(e>0)for(n=1;n<=e;++n)h.forward(t);else{if(!(e<0))throw new Error("History.go: History.go requires a positive or negative integer passed.");for(n=-1;n>=e;--n)h.back(t)}return h};if(h.emulated.pushState){var v=function(){};h.pushState=h.pushState||v,h.replaceState=h.replaceState||v}else h.onPopState=function(t,n){var r=!1,i=!1,s,o;return h.doubleCheckComplete(),s=h.getHash(),s?(o=h.extractState(s||h.getLocationHref(),!0),o?h.replaceState(o.data,o.title,o.url,!1):(h.Adapter.trigger(e,"anchorchange"),h.busy(!1)),h.expectedStateId=!1,!1):(r=h.Adapter.extractEventData("state",t,n)||!1,r?i=h.getStateById(r):h.expectedStateId?i=h.getStateById(h.expectedStateId):i=h.extractState(h.getLocationHref()),i||(i=h.createStateObject(null,null,h.getLocationHref())),h.expectedStateId=!1,h.isLastSavedState(i)?(h.busy(!1),!1):(h.storeState(i),h.saveState(i),h.setTitle(i),h.Adapter.trigger(e,"statechange"),h.busy(!1),!0))},h.Adapter.bind(e,"popstate",h.onPopState),h.pushState=function(t,n,r,i){if(h.getHashByUrl(r)&&h.emulated.pushState)throw new Error("History.js does not support states with fragement-identifiers (hashes/anchors).");if(i!==!1&&h.busy())return h.pushQueue({scope:h,callback:h.pushState,args:arguments,queue:i}),!1;h.busy(!0);var s=h.createStateObject(t,n,r);return h.isLastSavedState(s)?h.busy(!1):(h.storeState(s),h.expectedStateId=s.id,p.pushState(s.id,s.title,s.url),h.Adapter.trigger(e,"popstate")),!0},h.replaceState=function(t,n,r,i){if(h.getHashByUrl(r)&&h.emulated.pushState)throw new Error("History.js does not support states with fragement-identifiers (hashes/anchors).");if(i!==!1&&h.busy())return h.pushQueue({scope:h,callback:h.replaceState,args:arguments,queue:i}),!1;h.busy(!0);var s=h.createStateObject(t,n,r);return h.isLastSavedState(s)?h.busy(!1):(h.storeState(s),h.expectedStateId=s.id,p.replaceState(s.id,s.title,s.url),h.Adapter.trigger(e,"popstate")),!0};if(s){try{h.store=l.parse(s.getItem("History.store"))||{}}catch(m){h.store={}}h.normalizeStore()}else h.store={},h.normalizeStore();h.Adapter.bind(e,"unload",h.clearAllIntervals),h.saveState(h.storeState(h.extractState(h.getLocationHref(),!0))),s&&(h.onUnload=function(){var e,t,n;try{e=l.parse(s.getItem("History.store"))||{}}catch(r){e={}}e.idToState=e.idToState||{},e.urlToId=e.urlToId||{},e.stateToId=e.stateToId||{};for(t in h.idToState){if(!h.idToState.hasOwnProperty(t))continue;e.idToState[t]=h.idToState[t]}for(t in h.urlToId){if(!h.urlToId.hasOwnProperty(t))continue;e.urlToId[t]=h.urlToId[t]}for(t in h.stateToId){if(!h.stateToId.hasOwnProperty(t))continue;e.stateToId[t]=h.stateToId[t]}h.store=e,h.normalizeStore(),n=l.stringify(e);try{s.setItem("History.store",n)}catch(i){if(i.code!==DOMException.QUOTA_EXCEEDED_ERR)throw i;s.length&&(s.removeItem("History.store"),s.setItem("History.store",n))}},h.intervalList.push(a(h.onUnload,h.options.storeInterval)),h.Adapter.bind(e,"beforeunload",h.onUnload),h.Adapter.bind(e,"unload",h.onUnload));if(!h.emulated.pushState){h.bugs.safariPoll&&h.intervalList.push(a(h.safariStatePoll,h.options.safariPollInterval));if(i.vendor==="Apple Computer, Inc."||(i.appCodeName||"")==="Mozilla")h.Adapter.bind(e,"hashchange",function(){h.Adapter.trigger(e,"popstate")}),h.getHash()&&h.Adapter.onDomLoad(function(){h.Adapter.trigger(e,"hashchange")})}},(!h.options||!h.options.delayInit)&&h.init()}(window) \ No newline at end of file diff --git a/sites/all/themes/gui/materiobasetheme/bower_components/history.js/scripts/bundled/html4+html5/right.history.js b/sites/all/themes/gui/materiobasetheme/bower_components/history.js/scripts/bundled/html4+html5/right.history.js new file mode 100644 index 00000000..64087af2 --- /dev/null +++ b/sites/all/themes/gui/materiobasetheme/bower_components/history.js/scripts/bundled/html4+html5/right.history.js @@ -0,0 +1 @@ +typeof JSON!="object"&&(JSON={}),function(){"use strict";function f(e){return e<10?"0"+e:e}function quote(e){return escapable.lastIndex=0,escapable.test(e)?'"'+e.replace(escapable,function(e){var t=meta[e];return typeof t=="string"?t:"\\u"+("0000"+e.charCodeAt(0).toString(16)).slice(-4)})+'"':'"'+e+'"'}function str(e,t){var n,r,i,s,o=gap,u,a=t[e];a&&typeof a=="object"&&typeof a.toJSON=="function"&&(a=a.toJSON(e)),typeof rep=="function"&&(a=rep.call(t,e,a));switch(typeof a){case"string":return quote(a);case"number":return isFinite(a)?String(a):"null";case"boolean":case"null":return String(a);case"object":if(!a)return"null";gap+=indent,u=[];if(Object.prototype.toString.apply(a)==="[object Array]"){s=a.length;for(n=0;n")&&n[0]);return e>4?e:!1}();return e},h.isInternetExplorer=function(){var e=h.isInternetExplorer.cached=typeof h.isInternetExplorer.cached!="undefined"?h.isInternetExplorer.cached:Boolean(h.getInternetExplorerMajorVersion());return e},h.options.html4Mode?h.emulated={pushState:!0,hashChange:!0}:h.emulated={pushState:!Boolean(e.history&&e.history.pushState&&e.history.replaceState&&!/ Mobile\/([1-7][a-z]|(8([abcde]|f(1[0-8]))))/i.test(i.userAgent)&&!/AppleWebKit\/5([0-2]|3[0-2])/i.test(i.userAgent)),hashChange:Boolean(!("onhashchange"in e||"onhashchange"in r)||h.isInternetExplorer()&&h.getInternetExplorerMajorVersion()<8)},h.enabled=!h.emulated.pushState,h.bugs={setHash:Boolean(!h.emulated.pushState&&i.vendor==="Apple Computer, Inc."&&/AppleWebKit\/5([0-2]|3[0-3])/.test(i.userAgent)),safariPoll:Boolean(!h.emulated.pushState&&i.vendor==="Apple Computer, Inc."&&/AppleWebKit\/5([0-2]|3[0-3])/.test(i.userAgent)),ieDoubleCheck:Boolean(h.isInternetExplorer()&&h.getInternetExplorerMajorVersion()<8),hashEscape:Boolean(h.isInternetExplorer()&&h.getInternetExplorerMajorVersion()<7)},h.isEmptyObject=function(e){for(var t in e)if(e.hasOwnProperty(t))return!1;return!0},h.cloneObject=function(e){var t,n;return e?(t=l.stringify(e),n=l.parse(t)):n={},n},h.getRootUrl=function(){var e=r.location.protocol+"//"+(r.location.hostname||r.location.host);if(r.location.port||!1)e+=":"+r.location.port;return e+="/",e},h.getBaseHref=function(){var e=r.getElementsByTagName("base"),t=null,n="";return e.length===1&&(t=e[0],n=t.href.replace(/[^\/]+$/,"")),n=n.replace(/\/+$/,""),n&&(n+="/"),n},h.getBaseUrl=function(){var e=h.getBaseHref()||h.getBasePageUrl()||h.getRootUrl();return e},h.getPageUrl=function(){var e=h.getState(!1,!1),t=(e||{}).url||h.getLocationHref(),n;return n=t.replace(/\/+$/,"").replace(/[^\/]+$/,function(e,t,n){return/\./.test(e)?e:e+"/"}),n},h.getBasePageUrl=function(){var e=h.getLocationHref().replace(/[#\?].*/,"").replace(/[^\/]+$/,function(e,t,n){return/[^\/]$/.test(e)?"":e}).replace(/\/+$/,"")+"/";return e},h.getFullUrl=function(e,t){var n=e,r=e.substring(0,1);return t=typeof t=="undefined"?!0:t,/[a-z]+\:\/\//.test(e)||(r==="/"?n=h.getRootUrl()+e.replace(/^\/+/,""):r==="#"?n=h.getPageUrl().replace(/#.*/,"")+e:r==="?"?n=h.getPageUrl().replace(/[\?#].*/,"")+e:t?n=h.getBaseUrl()+e.replace(/^(\.\/)+/,""):n=h.getBasePageUrl()+e.replace(/^(\.\/)+/,"")),n.replace(/\#$/,"")},h.getShortUrl=function(e){var t=e,n=h.getBaseUrl(),r=h.getRootUrl();return h.emulated.pushState&&(t=t.replace(n,"")),t=t.replace(r,"/"),h.isTraditionalAnchor(t)&&(t="./"+t),t=t.replace(/^(\.\/)+/g,"./").replace(/\#$/,""),t},h.getLocationHref=function(e){return e=e||r,e.URL===e.location.href?e.location.href:e.location.href===decodeURIComponent(e.URL)?e.URL:e.location.hash&&decodeURIComponent(e.location.href.replace(/^[^#]+/,""))===e.location.hash?e.location.href:e.URL.indexOf("#")==-1&&e.location.href.indexOf("#")!=-1?e.location.href:e.URL||e.location.href},h.store={},h.idToState=h.idToState||{},h.stateToId=h.stateToId||{},h.urlToId=h.urlToId||{},h.storedStates=h.storedStates||[],h.savedStates=h.savedStates||[],h.normalizeStore=function(){h.store.idToState=h.store.idToState||{},h.store.urlToId=h.store.urlToId||{},h.store.stateToId=h.store.stateToId||{}},h.getState=function(e,t){typeof e=="undefined"&&(e=!0),typeof t=="undefined"&&(t=!0);var n=h.getLastSavedState();return!n&&t&&(n=h.createStateObject()),e&&(n=h.cloneObject(n),n.url=n.cleanUrl||n.url),n},h.getIdByState=function(e){var t=h.extractId(e.url),n;if(!t){n=h.getStateString(e);if(typeof h.stateToId[n]!="undefined")t=h.stateToId[n];else if(typeof h.store.stateToId[n]!="undefined")t=h.store.stateToId[n];else{for(;;){t=(new Date).getTime()+String(Math.random()).replace(/\D/g,"");if(typeof h.idToState[t]=="undefined"&&typeof h.store.idToState[t]=="undefined")break}h.stateToId[n]=t,h.idToState[t]=e}}return t},h.normalizeState=function(e){var t,n;if(!e||typeof e!="object")e={};if(typeof e.normalized!="undefined")return e;if(!e.data||typeof e.data!="object")e.data={};return t={},t.normalized=!0,t.title=e.title||"",t.url=h.getFullUrl(e.url?e.url:h.getLocationHref()),t.hash=h.getShortUrl(t.url),t.data=h.cloneObject(e.data),t.id=h.getIdByState(t),t.cleanUrl=t.url.replace(/\??\&_suid.*/,""),t.url=t.cleanUrl,n=!h.isEmptyObject(t.data),(t.title||n)&&h.options.disableSuid!==!0&&(t.hash=h.getShortUrl(t.url).replace(/\??\&_suid.*/,""),/\?/.test(t.hash)||(t.hash+="?"),t.hash+="&_suid="+t.id),t.hashedUrl=h.getFullUrl(t.hash),(h.emulated.pushState||h.bugs.safariPoll)&&h.hasUrlDuplicate(t)&&(t.url=t.hashedUrl),t},h.createStateObject=function(e,t,n){var r={data:e,title:t,url:n};return r=h.normalizeState(r),r},h.getStateById=function(e){e=String(e);var n=h.idToState[e]||h.store.idToState[e]||t;return n},h.getStateString=function(e){var t,n,r;return t=h.normalizeState(e),n={data:t.data,title:e.title,url:e.url},r=l.stringify(n),r},h.getStateId=function(e){var t,n;return t=h.normalizeState(e),n=t.id,n},h.getHashByState=function(e){var t,n;return t=h.normalizeState(e),n=t.hash,n},h.extractId=function(e){var t,n,r,i;return e.indexOf("#")!=-1?i=e.split("#")[0]:i=e,n=/(.*)\&_suid=([0-9]+)$/.exec(i),r=n?n[1]||e:e,t=n?String(n[2]||""):"",t||!1},h.isTraditionalAnchor=function(e){var t=!/[\/\?\.]/.test(e);return t},h.extractState=function(e,t){var n=null,r,i;return t=t||!1,r=h.extractId(e),r&&(n=h.getStateById(r)),n||(i=h.getFullUrl(e),r=h.getIdByUrl(i)||!1,r&&(n=h.getStateById(r)),!n&&t&&!h.isTraditionalAnchor(e)&&(n=h.createStateObject(null,null,i))),n},h.getIdByUrl=function(e){var n=h.urlToId[e]||h.store.urlToId[e]||t;return n},h.getLastSavedState=function(){return h.savedStates[h.savedStates.length-1]||t},h.getLastStoredState=function(){return h.storedStates[h.storedStates.length-1]||t},h.hasUrlDuplicate=function(e){var t=!1,n;return n=h.extractState(e.url),t=n&&n.id!==e.id,t},h.storeState=function(e){return h.urlToId[e.url]=e.id,h.storedStates.push(h.cloneObject(e)),e},h.isLastSavedState=function(e){var t=!1,n,r,i;return h.savedStates.length&&(n=e.id,r=h.getLastSavedState(),i=r.id,t=n===i),t},h.saveState=function(e){return h.isLastSavedState(e)?!1:(h.savedStates.push(h.cloneObject(e)),!0)},h.getStateByIndex=function(e){var t=null;return typeof e=="undefined"?t=h.savedStates[h.savedStates.length-1]:e<0?t=h.savedStates[h.savedStates.length+e]:t=h.savedStates[e],t},h.getCurrentIndex=function(){var e=null;return h.savedStates.length<1?e=0:e=h.savedStates.length-1,e},h.getHash=function(e){var t=h.getLocationHref(e),n;return n=h.getHashByUrl(t),n},h.unescapeHash=function(e){var t=h.normalizeHash(e);return t=decodeURIComponent(t),t},h.normalizeHash=function(e){var t=e.replace(/[^#]*#/,"").replace(/#.*/,"");return t},h.setHash=function(e,t){var n,i;return t!==!1&&h.busy()?(h.pushQueue({scope:h,callback:h.setHash,args:arguments,queue:t}),!1):(h.busy(!0),n=h.extractState(e,!0),n&&!h.emulated.pushState?h.pushState(n.data,n.title,n.url,!1):h.getHash()!==e&&(h.bugs.setHash?(i=h.getPageUrl(),h.pushState(null,null,i+"#"+e,!1)):r.location.hash=e),h)},h.escapeHash=function(t){var n=h.normalizeHash(t);return n=e.encodeURIComponent(n),h.bugs.hashEscape||(n=n.replace(/\%21/g,"!").replace(/\%26/g,"&").replace(/\%3D/g,"=").replace(/\%3F/g,"?")),n},h.getHashByUrl=function(e){var t=String(e).replace(/([^#]*)#?([^#]*)#?(.*)/,"$2");return t=h.unescapeHash(t),t},h.setTitle=function(e){var t=e.title,n;t||(n=h.getStateByIndex(0),n&&n.url===e.url&&(t=n.title||h.options.initialTitle));try{r.getElementsByTagName("title")[0].innerHTML=t.replace("<","<").replace(">",">").replace(" & "," & ")}catch(i){}return r.title=t,h},h.queues=[],h.busy=function(e){typeof e!="undefined"?h.busy.flag=e:typeof h.busy.flag=="undefined"&&(h.busy.flag=!1);if(!h.busy.flag){u(h.busy.timeout);var t=function(){var e,n,r;if(h.busy.flag)return;for(e=h.queues.length-1;e>=0;--e){n=h.queues[e];if(n.length===0)continue;r=n.shift(),h.fireQueueItem(r),h.busy.timeout=o(t,h.options.busyDelay)}};h.busy.timeout=o(t,h.options.busyDelay)}return h.busy.flag},h.busy.flag=!1,h.fireQueueItem=function(e){return e.callback.apply(e.scope||h,e.args||[])},h.pushQueue=function(e){return h.queues[e.queue||0]=h.queues[e.queue||0]||[],h.queues[e.queue||0].push(e),h},h.queue=function(e,t){return typeof e=="function"&&(e={callback:e}),typeof t!="undefined"&&(e.queue=t),h.busy()?h.pushQueue(e):h.fireQueueItem(e),h},h.clearQueue=function(){return h.busy.flag=!1,h.queues=[],h},h.stateChanged=!1,h.doubleChecker=!1,h.doubleCheckComplete=function(){return h.stateChanged=!0,h.doubleCheckClear(),h},h.doubleCheckClear=function(){return h.doubleChecker&&(u(h.doubleChecker),h.doubleChecker=!1),h},h.doubleCheck=function(e){return h.stateChanged=!1,h.doubleCheckClear(),h.bugs.ieDoubleCheck&&(h.doubleChecker=o(function(){return h.doubleCheckClear(),h.stateChanged||e(),!0},h.options.doubleCheckInterval)),h},h.safariStatePoll=function(){var t=h.extractState(h.getLocationHref()),n;if(!h.isLastSavedState(t))return n=t,n||(n=h.createStateObject()),h.Adapter.trigger(e,"popstate"),h;return},h.back=function(e){return e!==!1&&h.busy()?(h.pushQueue({scope:h,callback:h.back,args:arguments,queue:e}),!1):(h.busy(!0),h.doubleCheck(function(){h.back(!1)}),p.go(-1),!0)},h.forward=function(e){return e!==!1&&h.busy()?(h.pushQueue({scope:h,callback:h.forward,args:arguments,queue:e}),!1):(h.busy(!0),h.doubleCheck(function(){h.forward(!1)}),p.go(1),!0)},h.go=function(e,t){var n;if(e>0)for(n=1;n<=e;++n)h.forward(t);else{if(!(e<0))throw new Error("History.go: History.go requires a positive or negative integer passed.");for(n=-1;n>=e;--n)h.back(t)}return h};if(h.emulated.pushState){var v=function(){};h.pushState=h.pushState||v,h.replaceState=h.replaceState||v}else h.onPopState=function(t,n){var r=!1,i=!1,s,o;return h.doubleCheckComplete(),s=h.getHash(),s?(o=h.extractState(s||h.getLocationHref(),!0),o?h.replaceState(o.data,o.title,o.url,!1):(h.Adapter.trigger(e,"anchorchange"),h.busy(!1)),h.expectedStateId=!1,!1):(r=h.Adapter.extractEventData("state",t,n)||!1,r?i=h.getStateById(r):h.expectedStateId?i=h.getStateById(h.expectedStateId):i=h.extractState(h.getLocationHref()),i||(i=h.createStateObject(null,null,h.getLocationHref())),h.expectedStateId=!1,h.isLastSavedState(i)?(h.busy(!1),!1):(h.storeState(i),h.saveState(i),h.setTitle(i),h.Adapter.trigger(e,"statechange"),h.busy(!1),!0))},h.Adapter.bind(e,"popstate",h.onPopState),h.pushState=function(t,n,r,i){if(h.getHashByUrl(r)&&h.emulated.pushState)throw new Error("History.js does not support states with fragement-identifiers (hashes/anchors).");if(i!==!1&&h.busy())return h.pushQueue({scope:h,callback:h.pushState,args:arguments,queue:i}),!1;h.busy(!0);var s=h.createStateObject(t,n,r);return h.isLastSavedState(s)?h.busy(!1):(h.storeState(s),h.expectedStateId=s.id,p.pushState(s.id,s.title,s.url),h.Adapter.trigger(e,"popstate")),!0},h.replaceState=function(t,n,r,i){if(h.getHashByUrl(r)&&h.emulated.pushState)throw new Error("History.js does not support states with fragement-identifiers (hashes/anchors).");if(i!==!1&&h.busy())return h.pushQueue({scope:h,callback:h.replaceState,args:arguments,queue:i}),!1;h.busy(!0);var s=h.createStateObject(t,n,r);return h.isLastSavedState(s)?h.busy(!1):(h.storeState(s),h.expectedStateId=s.id,p.replaceState(s.id,s.title,s.url),h.Adapter.trigger(e,"popstate")),!0};if(s){try{h.store=l.parse(s.getItem("History.store"))||{}}catch(m){h.store={}}h.normalizeStore()}else h.store={},h.normalizeStore();h.Adapter.bind(e,"unload",h.clearAllIntervals),h.saveState(h.storeState(h.extractState(h.getLocationHref(),!0))),s&&(h.onUnload=function(){var e,t,n;try{e=l.parse(s.getItem("History.store"))||{}}catch(r){e={}}e.idToState=e.idToState||{},e.urlToId=e.urlToId||{},e.stateToId=e.stateToId||{};for(t in h.idToState){if(!h.idToState.hasOwnProperty(t))continue;e.idToState[t]=h.idToState[t]}for(t in h.urlToId){if(!h.urlToId.hasOwnProperty(t))continue;e.urlToId[t]=h.urlToId[t]}for(t in h.stateToId){if(!h.stateToId.hasOwnProperty(t))continue;e.stateToId[t]=h.stateToId[t]}h.store=e,h.normalizeStore(),n=l.stringify(e);try{s.setItem("History.store",n)}catch(i){if(i.code!==DOMException.QUOTA_EXCEEDED_ERR)throw i;s.length&&(s.removeItem("History.store"),s.setItem("History.store",n))}},h.intervalList.push(a(h.onUnload,h.options.storeInterval)),h.Adapter.bind(e,"beforeunload",h.onUnload),h.Adapter.bind(e,"unload",h.onUnload));if(!h.emulated.pushState){h.bugs.safariPoll&&h.intervalList.push(a(h.safariStatePoll,h.options.safariPollInterval));if(i.vendor==="Apple Computer, Inc."||(i.appCodeName||"")==="Mozilla")h.Adapter.bind(e,"hashchange",function(){h.Adapter.trigger(e,"popstate")}),h.getHash()&&h.Adapter.onDomLoad(function(){h.Adapter.trigger(e,"hashchange")})}},(!h.options||!h.options.delayInit)&&h.init()}(window) \ No newline at end of file diff --git a/sites/all/themes/gui/materiobasetheme/bower_components/history.js/scripts/bundled/html4+html5/zepto.history.js b/sites/all/themes/gui/materiobasetheme/bower_components/history.js/scripts/bundled/html4+html5/zepto.history.js new file mode 100644 index 00000000..ffc67e40 --- /dev/null +++ b/sites/all/themes/gui/materiobasetheme/bower_components/history.js/scripts/bundled/html4+html5/zepto.history.js @@ -0,0 +1 @@ +typeof JSON!="object"&&(JSON={}),function(){"use strict";function f(e){return e<10?"0"+e:e}function quote(e){return escapable.lastIndex=0,escapable.test(e)?'"'+e.replace(escapable,function(e){var t=meta[e];return typeof t=="string"?t:"\\u"+("0000"+e.charCodeAt(0).toString(16)).slice(-4)})+'"':'"'+e+'"'}function str(e,t){var n,r,i,s,o=gap,u,a=t[e];a&&typeof a=="object"&&typeof a.toJSON=="function"&&(a=a.toJSON(e)),typeof rep=="function"&&(a=rep.call(t,e,a));switch(typeof a){case"string":return quote(a);case"number":return isFinite(a)?String(a):"null";case"boolean":case"null":return String(a);case"object":if(!a)return"null";gap+=indent,u=[];if(Object.prototype.toString.apply(a)==="[object Array]"){s=a.length;for(n=0;n")&&n[0]);return e>4?e:!1}();return e},h.isInternetExplorer=function(){var e=h.isInternetExplorer.cached=typeof h.isInternetExplorer.cached!="undefined"?h.isInternetExplorer.cached:Boolean(h.getInternetExplorerMajorVersion());return e},h.options.html4Mode?h.emulated={pushState:!0,hashChange:!0}:h.emulated={pushState:!Boolean(e.history&&e.history.pushState&&e.history.replaceState&&!/ Mobile\/([1-7][a-z]|(8([abcde]|f(1[0-8]))))/i.test(i.userAgent)&&!/AppleWebKit\/5([0-2]|3[0-2])/i.test(i.userAgent)),hashChange:Boolean(!("onhashchange"in e||"onhashchange"in r)||h.isInternetExplorer()&&h.getInternetExplorerMajorVersion()<8)},h.enabled=!h.emulated.pushState,h.bugs={setHash:Boolean(!h.emulated.pushState&&i.vendor==="Apple Computer, Inc."&&/AppleWebKit\/5([0-2]|3[0-3])/.test(i.userAgent)),safariPoll:Boolean(!h.emulated.pushState&&i.vendor==="Apple Computer, Inc."&&/AppleWebKit\/5([0-2]|3[0-3])/.test(i.userAgent)),ieDoubleCheck:Boolean(h.isInternetExplorer()&&h.getInternetExplorerMajorVersion()<8),hashEscape:Boolean(h.isInternetExplorer()&&h.getInternetExplorerMajorVersion()<7)},h.isEmptyObject=function(e){for(var t in e)if(e.hasOwnProperty(t))return!1;return!0},h.cloneObject=function(e){var t,n;return e?(t=l.stringify(e),n=l.parse(t)):n={},n},h.getRootUrl=function(){var e=r.location.protocol+"//"+(r.location.hostname||r.location.host);if(r.location.port||!1)e+=":"+r.location.port;return e+="/",e},h.getBaseHref=function(){var e=r.getElementsByTagName("base"),t=null,n="";return e.length===1&&(t=e[0],n=t.href.replace(/[^\/]+$/,"")),n=n.replace(/\/+$/,""),n&&(n+="/"),n},h.getBaseUrl=function(){var e=h.getBaseHref()||h.getBasePageUrl()||h.getRootUrl();return e},h.getPageUrl=function(){var e=h.getState(!1,!1),t=(e||{}).url||h.getLocationHref(),n;return n=t.replace(/\/+$/,"").replace(/[^\/]+$/,function(e,t,n){return/\./.test(e)?e:e+"/"}),n},h.getBasePageUrl=function(){var e=h.getLocationHref().replace(/[#\?].*/,"").replace(/[^\/]+$/,function(e,t,n){return/[^\/]$/.test(e)?"":e}).replace(/\/+$/,"")+"/";return e},h.getFullUrl=function(e,t){var n=e,r=e.substring(0,1);return t=typeof t=="undefined"?!0:t,/[a-z]+\:\/\//.test(e)||(r==="/"?n=h.getRootUrl()+e.replace(/^\/+/,""):r==="#"?n=h.getPageUrl().replace(/#.*/,"")+e:r==="?"?n=h.getPageUrl().replace(/[\?#].*/,"")+e:t?n=h.getBaseUrl()+e.replace(/^(\.\/)+/,""):n=h.getBasePageUrl()+e.replace(/^(\.\/)+/,"")),n.replace(/\#$/,"")},h.getShortUrl=function(e){var t=e,n=h.getBaseUrl(),r=h.getRootUrl();return h.emulated.pushState&&(t=t.replace(n,"")),t=t.replace(r,"/"),h.isTraditionalAnchor(t)&&(t="./"+t),t=t.replace(/^(\.\/)+/g,"./").replace(/\#$/,""),t},h.getLocationHref=function(e){return e=e||r,e.URL===e.location.href?e.location.href:e.location.href===decodeURIComponent(e.URL)?e.URL:e.location.hash&&decodeURIComponent(e.location.href.replace(/^[^#]+/,""))===e.location.hash?e.location.href:e.URL.indexOf("#")==-1&&e.location.href.indexOf("#")!=-1?e.location.href:e.URL||e.location.href},h.store={},h.idToState=h.idToState||{},h.stateToId=h.stateToId||{},h.urlToId=h.urlToId||{},h.storedStates=h.storedStates||[],h.savedStates=h.savedStates||[],h.normalizeStore=function(){h.store.idToState=h.store.idToState||{},h.store.urlToId=h.store.urlToId||{},h.store.stateToId=h.store.stateToId||{}},h.getState=function(e,t){typeof e=="undefined"&&(e=!0),typeof t=="undefined"&&(t=!0);var n=h.getLastSavedState();return!n&&t&&(n=h.createStateObject()),e&&(n=h.cloneObject(n),n.url=n.cleanUrl||n.url),n},h.getIdByState=function(e){var t=h.extractId(e.url),n;if(!t){n=h.getStateString(e);if(typeof h.stateToId[n]!="undefined")t=h.stateToId[n];else if(typeof h.store.stateToId[n]!="undefined")t=h.store.stateToId[n];else{for(;;){t=(new Date).getTime()+String(Math.random()).replace(/\D/g,"");if(typeof h.idToState[t]=="undefined"&&typeof h.store.idToState[t]=="undefined")break}h.stateToId[n]=t,h.idToState[t]=e}}return t},h.normalizeState=function(e){var t,n;if(!e||typeof e!="object")e={};if(typeof e.normalized!="undefined")return e;if(!e.data||typeof e.data!="object")e.data={};return t={},t.normalized=!0,t.title=e.title||"",t.url=h.getFullUrl(e.url?e.url:h.getLocationHref()),t.hash=h.getShortUrl(t.url),t.data=h.cloneObject(e.data),t.id=h.getIdByState(t),t.cleanUrl=t.url.replace(/\??\&_suid.*/,""),t.url=t.cleanUrl,n=!h.isEmptyObject(t.data),(t.title||n)&&h.options.disableSuid!==!0&&(t.hash=h.getShortUrl(t.url).replace(/\??\&_suid.*/,""),/\?/.test(t.hash)||(t.hash+="?"),t.hash+="&_suid="+t.id),t.hashedUrl=h.getFullUrl(t.hash),(h.emulated.pushState||h.bugs.safariPoll)&&h.hasUrlDuplicate(t)&&(t.url=t.hashedUrl),t},h.createStateObject=function(e,t,n){var r={data:e,title:t,url:n};return r=h.normalizeState(r),r},h.getStateById=function(e){e=String(e);var n=h.idToState[e]||h.store.idToState[e]||t;return n},h.getStateString=function(e){var t,n,r;return t=h.normalizeState(e),n={data:t.data,title:e.title,url:e.url},r=l.stringify(n),r},h.getStateId=function(e){var t,n;return t=h.normalizeState(e),n=t.id,n},h.getHashByState=function(e){var t,n;return t=h.normalizeState(e),n=t.hash,n},h.extractId=function(e){var t,n,r,i;return e.indexOf("#")!=-1?i=e.split("#")[0]:i=e,n=/(.*)\&_suid=([0-9]+)$/.exec(i),r=n?n[1]||e:e,t=n?String(n[2]||""):"",t||!1},h.isTraditionalAnchor=function(e){var t=!/[\/\?\.]/.test(e);return t},h.extractState=function(e,t){var n=null,r,i;return t=t||!1,r=h.extractId(e),r&&(n=h.getStateById(r)),n||(i=h.getFullUrl(e),r=h.getIdByUrl(i)||!1,r&&(n=h.getStateById(r)),!n&&t&&!h.isTraditionalAnchor(e)&&(n=h.createStateObject(null,null,i))),n},h.getIdByUrl=function(e){var n=h.urlToId[e]||h.store.urlToId[e]||t;return n},h.getLastSavedState=function(){return h.savedStates[h.savedStates.length-1]||t},h.getLastStoredState=function(){return h.storedStates[h.storedStates.length-1]||t},h.hasUrlDuplicate=function(e){var t=!1,n;return n=h.extractState(e.url),t=n&&n.id!==e.id,t},h.storeState=function(e){return h.urlToId[e.url]=e.id,h.storedStates.push(h.cloneObject(e)),e},h.isLastSavedState=function(e){var t=!1,n,r,i;return h.savedStates.length&&(n=e.id,r=h.getLastSavedState(),i=r.id,t=n===i),t},h.saveState=function(e){return h.isLastSavedState(e)?!1:(h.savedStates.push(h.cloneObject(e)),!0)},h.getStateByIndex=function(e){var t=null;return typeof e=="undefined"?t=h.savedStates[h.savedStates.length-1]:e<0?t=h.savedStates[h.savedStates.length+e]:t=h.savedStates[e],t},h.getCurrentIndex=function(){var e=null;return h.savedStates.length<1?e=0:e=h.savedStates.length-1,e},h.getHash=function(e){var t=h.getLocationHref(e),n;return n=h.getHashByUrl(t),n},h.unescapeHash=function(e){var t=h.normalizeHash(e);return t=decodeURIComponent(t),t},h.normalizeHash=function(e){var t=e.replace(/[^#]*#/,"").replace(/#.*/,"");return t},h.setHash=function(e,t){var n,i;return t!==!1&&h.busy()?(h.pushQueue({scope:h,callback:h.setHash,args:arguments,queue:t}),!1):(h.busy(!0),n=h.extractState(e,!0),n&&!h.emulated.pushState?h.pushState(n.data,n.title,n.url,!1):h.getHash()!==e&&(h.bugs.setHash?(i=h.getPageUrl(),h.pushState(null,null,i+"#"+e,!1)):r.location.hash=e),h)},h.escapeHash=function(t){var n=h.normalizeHash(t);return n=e.encodeURIComponent(n),h.bugs.hashEscape||(n=n.replace(/\%21/g,"!").replace(/\%26/g,"&").replace(/\%3D/g,"=").replace(/\%3F/g,"?")),n},h.getHashByUrl=function(e){var t=String(e).replace(/([^#]*)#?([^#]*)#?(.*)/,"$2");return t=h.unescapeHash(t),t},h.setTitle=function(e){var t=e.title,n;t||(n=h.getStateByIndex(0),n&&n.url===e.url&&(t=n.title||h.options.initialTitle));try{r.getElementsByTagName("title")[0].innerHTML=t.replace("<","<").replace(">",">").replace(" & "," & ")}catch(i){}return r.title=t,h},h.queues=[],h.busy=function(e){typeof e!="undefined"?h.busy.flag=e:typeof h.busy.flag=="undefined"&&(h.busy.flag=!1);if(!h.busy.flag){u(h.busy.timeout);var t=function(){var e,n,r;if(h.busy.flag)return;for(e=h.queues.length-1;e>=0;--e){n=h.queues[e];if(n.length===0)continue;r=n.shift(),h.fireQueueItem(r),h.busy.timeout=o(t,h.options.busyDelay)}};h.busy.timeout=o(t,h.options.busyDelay)}return h.busy.flag},h.busy.flag=!1,h.fireQueueItem=function(e){return e.callback.apply(e.scope||h,e.args||[])},h.pushQueue=function(e){return h.queues[e.queue||0]=h.queues[e.queue||0]||[],h.queues[e.queue||0].push(e),h},h.queue=function(e,t){return typeof e=="function"&&(e={callback:e}),typeof t!="undefined"&&(e.queue=t),h.busy()?h.pushQueue(e):h.fireQueueItem(e),h},h.clearQueue=function(){return h.busy.flag=!1,h.queues=[],h},h.stateChanged=!1,h.doubleChecker=!1,h.doubleCheckComplete=function(){return h.stateChanged=!0,h.doubleCheckClear(),h},h.doubleCheckClear=function(){return h.doubleChecker&&(u(h.doubleChecker),h.doubleChecker=!1),h},h.doubleCheck=function(e){return h.stateChanged=!1,h.doubleCheckClear(),h.bugs.ieDoubleCheck&&(h.doubleChecker=o(function(){return h.doubleCheckClear(),h.stateChanged||e(),!0},h.options.doubleCheckInterval)),h},h.safariStatePoll=function(){var t=h.extractState(h.getLocationHref()),n;if(!h.isLastSavedState(t))return n=t,n||(n=h.createStateObject()),h.Adapter.trigger(e,"popstate"),h;return},h.back=function(e){return e!==!1&&h.busy()?(h.pushQueue({scope:h,callback:h.back,args:arguments,queue:e}),!1):(h.busy(!0),h.doubleCheck(function(){h.back(!1)}),p.go(-1),!0)},h.forward=function(e){return e!==!1&&h.busy()?(h.pushQueue({scope:h,callback:h.forward,args:arguments,queue:e}),!1):(h.busy(!0),h.doubleCheck(function(){h.forward(!1)}),p.go(1),!0)},h.go=function(e,t){var n;if(e>0)for(n=1;n<=e;++n)h.forward(t);else{if(!(e<0))throw new Error("History.go: History.go requires a positive or negative integer passed.");for(n=-1;n>=e;--n)h.back(t)}return h};if(h.emulated.pushState){var v=function(){};h.pushState=h.pushState||v,h.replaceState=h.replaceState||v}else h.onPopState=function(t,n){var r=!1,i=!1,s,o;return h.doubleCheckComplete(),s=h.getHash(),s?(o=h.extractState(s||h.getLocationHref(),!0),o?h.replaceState(o.data,o.title,o.url,!1):(h.Adapter.trigger(e,"anchorchange"),h.busy(!1)),h.expectedStateId=!1,!1):(r=h.Adapter.extractEventData("state",t,n)||!1,r?i=h.getStateById(r):h.expectedStateId?i=h.getStateById(h.expectedStateId):i=h.extractState(h.getLocationHref()),i||(i=h.createStateObject(null,null,h.getLocationHref())),h.expectedStateId=!1,h.isLastSavedState(i)?(h.busy(!1),!1):(h.storeState(i),h.saveState(i),h.setTitle(i),h.Adapter.trigger(e,"statechange"),h.busy(!1),!0))},h.Adapter.bind(e,"popstate",h.onPopState),h.pushState=function(t,n,r,i){if(h.getHashByUrl(r)&&h.emulated.pushState)throw new Error("History.js does not support states with fragement-identifiers (hashes/anchors).");if(i!==!1&&h.busy())return h.pushQueue({scope:h,callback:h.pushState,args:arguments,queue:i}),!1;h.busy(!0);var s=h.createStateObject(t,n,r);return h.isLastSavedState(s)?h.busy(!1):(h.storeState(s),h.expectedStateId=s.id,p.pushState(s.id,s.title,s.url),h.Adapter.trigger(e,"popstate")),!0},h.replaceState=function(t,n,r,i){if(h.getHashByUrl(r)&&h.emulated.pushState)throw new Error("History.js does not support states with fragement-identifiers (hashes/anchors).");if(i!==!1&&h.busy())return h.pushQueue({scope:h,callback:h.replaceState,args:arguments,queue:i}),!1;h.busy(!0);var s=h.createStateObject(t,n,r);return h.isLastSavedState(s)?h.busy(!1):(h.storeState(s),h.expectedStateId=s.id,p.replaceState(s.id,s.title,s.url),h.Adapter.trigger(e,"popstate")),!0};if(s){try{h.store=l.parse(s.getItem("History.store"))||{}}catch(m){h.store={}}h.normalizeStore()}else h.store={},h.normalizeStore();h.Adapter.bind(e,"unload",h.clearAllIntervals),h.saveState(h.storeState(h.extractState(h.getLocationHref(),!0))),s&&(h.onUnload=function(){var e,t,n;try{e=l.parse(s.getItem("History.store"))||{}}catch(r){e={}}e.idToState=e.idToState||{},e.urlToId=e.urlToId||{},e.stateToId=e.stateToId||{};for(t in h.idToState){if(!h.idToState.hasOwnProperty(t))continue;e.idToState[t]=h.idToState[t]}for(t in h.urlToId){if(!h.urlToId.hasOwnProperty(t))continue;e.urlToId[t]=h.urlToId[t]}for(t in h.stateToId){if(!h.stateToId.hasOwnProperty(t))continue;e.stateToId[t]=h.stateToId[t]}h.store=e,h.normalizeStore(),n=l.stringify(e);try{s.setItem("History.store",n)}catch(i){if(i.code!==DOMException.QUOTA_EXCEEDED_ERR)throw i;s.length&&(s.removeItem("History.store"),s.setItem("History.store",n))}},h.intervalList.push(a(h.onUnload,h.options.storeInterval)),h.Adapter.bind(e,"beforeunload",h.onUnload),h.Adapter.bind(e,"unload",h.onUnload));if(!h.emulated.pushState){h.bugs.safariPoll&&h.intervalList.push(a(h.safariStatePoll,h.options.safariPollInterval));if(i.vendor==="Apple Computer, Inc."||(i.appCodeName||"")==="Mozilla")h.Adapter.bind(e,"hashchange",function(){h.Adapter.trigger(e,"popstate")}),h.getHash()&&h.Adapter.onDomLoad(function(){h.Adapter.trigger(e,"hashchange")})}},(!h.options||!h.options.delayInit)&&h.init()}(window) \ No newline at end of file diff --git a/sites/all/themes/gui/materiobasetheme/bower_components/history.js/scripts/bundled/html5/dojo.history.js b/sites/all/themes/gui/materiobasetheme/bower_components/history.js/scripts/bundled/html5/dojo.history.js new file mode 100644 index 00000000..c879d4f1 --- /dev/null +++ b/sites/all/themes/gui/materiobasetheme/bower_components/history.js/scripts/bundled/html5/dojo.history.js @@ -0,0 +1 @@ +(function(e,t){"use strict";var n=e.History=e.History||{},r=e.require;if(typeof n.Adapter!="undefined")throw new Error("History.js Adapter has already been loaded...");n.Adapter={handlers:{},_uid:1,uid:function(e){return e._uid||(e._uid=n.Adapter._uid++)},bind:function(e,t,r){var i=n.Adapter.uid(e);n.Adapter.handlers[i]=n.Adapter.handlers[i]||{},n.Adapter.handlers[i][t]=n.Adapter.handlers[i][t]||[],n.Adapter.handlers[i][t].push(r),e["on"+t]=function(e,t){return function(r){n.Adapter.trigger(e,t,r)}}(e,t)},trigger:function(e,t,r){r=r||{};var i=n.Adapter.uid(e),s,o;n.Adapter.handlers[i]=n.Adapter.handlers[i]||{},n.Adapter.handlers[i][t]=n.Adapter.handlers[i][t]||[];for(s=0,o=n.Adapter.handlers[i][t].length;s")&&n[0]);return e>4?e:!1}();return e},h.isInternetExplorer=function(){var e=h.isInternetExplorer.cached=typeof h.isInternetExplorer.cached!="undefined"?h.isInternetExplorer.cached:Boolean(h.getInternetExplorerMajorVersion());return e},h.options.html4Mode?h.emulated={pushState:!0,hashChange:!0}:h.emulated={pushState:!Boolean(e.history&&e.history.pushState&&e.history.replaceState&&!/ Mobile\/([1-7][a-z]|(8([abcde]|f(1[0-8]))))/i.test(i.userAgent)&&!/AppleWebKit\/5([0-2]|3[0-2])/i.test(i.userAgent)),hashChange:Boolean(!("onhashchange"in e||"onhashchange"in r)||h.isInternetExplorer()&&h.getInternetExplorerMajorVersion()<8)},h.enabled=!h.emulated.pushState,h.bugs={setHash:Boolean(!h.emulated.pushState&&i.vendor==="Apple Computer, Inc."&&/AppleWebKit\/5([0-2]|3[0-3])/.test(i.userAgent)),safariPoll:Boolean(!h.emulated.pushState&&i.vendor==="Apple Computer, Inc."&&/AppleWebKit\/5([0-2]|3[0-3])/.test(i.userAgent)),ieDoubleCheck:Boolean(h.isInternetExplorer()&&h.getInternetExplorerMajorVersion()<8),hashEscape:Boolean(h.isInternetExplorer()&&h.getInternetExplorerMajorVersion()<7)},h.isEmptyObject=function(e){for(var t in e)if(e.hasOwnProperty(t))return!1;return!0},h.cloneObject=function(e){var t,n;return e?(t=l.stringify(e),n=l.parse(t)):n={},n},h.getRootUrl=function(){var e=r.location.protocol+"//"+(r.location.hostname||r.location.host);if(r.location.port||!1)e+=":"+r.location.port;return e+="/",e},h.getBaseHref=function(){var e=r.getElementsByTagName("base"),t=null,n="";return e.length===1&&(t=e[0],n=t.href.replace(/[^\/]+$/,"")),n=n.replace(/\/+$/,""),n&&(n+="/"),n},h.getBaseUrl=function(){var e=h.getBaseHref()||h.getBasePageUrl()||h.getRootUrl();return e},h.getPageUrl=function(){var e=h.getState(!1,!1),t=(e||{}).url||h.getLocationHref(),n;return n=t.replace(/\/+$/,"").replace(/[^\/]+$/,function(e,t,n){return/\./.test(e)?e:e+"/"}),n},h.getBasePageUrl=function(){var e=h.getLocationHref().replace(/[#\?].*/,"").replace(/[^\/]+$/,function(e,t,n){return/[^\/]$/.test(e)?"":e}).replace(/\/+$/,"")+"/";return e},h.getFullUrl=function(e,t){var n=e,r=e.substring(0,1);return t=typeof t=="undefined"?!0:t,/[a-z]+\:\/\//.test(e)||(r==="/"?n=h.getRootUrl()+e.replace(/^\/+/,""):r==="#"?n=h.getPageUrl().replace(/#.*/,"")+e:r==="?"?n=h.getPageUrl().replace(/[\?#].*/,"")+e:t?n=h.getBaseUrl()+e.replace(/^(\.\/)+/,""):n=h.getBasePageUrl()+e.replace(/^(\.\/)+/,"")),n.replace(/\#$/,"")},h.getShortUrl=function(e){var t=e,n=h.getBaseUrl(),r=h.getRootUrl();return h.emulated.pushState&&(t=t.replace(n,"")),t=t.replace(r,"/"),h.isTraditionalAnchor(t)&&(t="./"+t),t=t.replace(/^(\.\/)+/g,"./").replace(/\#$/,""),t},h.getLocationHref=function(e){return e=e||r,e.URL===e.location.href?e.location.href:e.location.href===decodeURIComponent(e.URL)?e.URL:e.location.hash&&decodeURIComponent(e.location.href.replace(/^[^#]+/,""))===e.location.hash?e.location.href:e.URL.indexOf("#")==-1&&e.location.href.indexOf("#")!=-1?e.location.href:e.URL||e.location.href},h.store={},h.idToState=h.idToState||{},h.stateToId=h.stateToId||{},h.urlToId=h.urlToId||{},h.storedStates=h.storedStates||[],h.savedStates=h.savedStates||[],h.normalizeStore=function(){h.store.idToState=h.store.idToState||{},h.store.urlToId=h.store.urlToId||{},h.store.stateToId=h.store.stateToId||{}},h.getState=function(e,t){typeof e=="undefined"&&(e=!0),typeof t=="undefined"&&(t=!0);var n=h.getLastSavedState();return!n&&t&&(n=h.createStateObject()),e&&(n=h.cloneObject(n),n.url=n.cleanUrl||n.url),n},h.getIdByState=function(e){var t=h.extractId(e.url),n;if(!t){n=h.getStateString(e);if(typeof h.stateToId[n]!="undefined")t=h.stateToId[n];else if(typeof h.store.stateToId[n]!="undefined")t=h.store.stateToId[n];else{for(;;){t=(new Date).getTime()+String(Math.random()).replace(/\D/g,"");if(typeof h.idToState[t]=="undefined"&&typeof h.store.idToState[t]=="undefined")break}h.stateToId[n]=t,h.idToState[t]=e}}return t},h.normalizeState=function(e){var t,n;if(!e||typeof e!="object")e={};if(typeof e.normalized!="undefined")return e;if(!e.data||typeof e.data!="object")e.data={};return t={},t.normalized=!0,t.title=e.title||"",t.url=h.getFullUrl(e.url?e.url:h.getLocationHref()),t.hash=h.getShortUrl(t.url),t.data=h.cloneObject(e.data),t.id=h.getIdByState(t),t.cleanUrl=t.url.replace(/\??\&_suid.*/,""),t.url=t.cleanUrl,n=!h.isEmptyObject(t.data),(t.title||n)&&h.options.disableSuid!==!0&&(t.hash=h.getShortUrl(t.url).replace(/\??\&_suid.*/,""),/\?/.test(t.hash)||(t.hash+="?"),t.hash+="&_suid="+t.id),t.hashedUrl=h.getFullUrl(t.hash),(h.emulated.pushState||h.bugs.safariPoll)&&h.hasUrlDuplicate(t)&&(t.url=t.hashedUrl),t},h.createStateObject=function(e,t,n){var r={data:e,title:t,url:n};return r=h.normalizeState(r),r},h.getStateById=function(e){e=String(e);var n=h.idToState[e]||h.store.idToState[e]||t;return n},h.getStateString=function(e){var t,n,r;return t=h.normalizeState(e),n={data:t.data,title:e.title,url:e.url},r=l.stringify(n),r},h.getStateId=function(e){var t,n;return t=h.normalizeState(e),n=t.id,n},h.getHashByState=function(e){var t,n;return t=h.normalizeState(e),n=t.hash,n},h.extractId=function(e){var t,n,r,i;return e.indexOf("#")!=-1?i=e.split("#")[0]:i=e,n=/(.*)\&_suid=([0-9]+)$/.exec(i),r=n?n[1]||e:e,t=n?String(n[2]||""):"",t||!1},h.isTraditionalAnchor=function(e){var t=!/[\/\?\.]/.test(e);return t},h.extractState=function(e,t){var n=null,r,i;return t=t||!1,r=h.extractId(e),r&&(n=h.getStateById(r)),n||(i=h.getFullUrl(e),r=h.getIdByUrl(i)||!1,r&&(n=h.getStateById(r)),!n&&t&&!h.isTraditionalAnchor(e)&&(n=h.createStateObject(null,null,i))),n},h.getIdByUrl=function(e){var n=h.urlToId[e]||h.store.urlToId[e]||t;return n},h.getLastSavedState=function(){return h.savedStates[h.savedStates.length-1]||t},h.getLastStoredState=function(){return h.storedStates[h.storedStates.length-1]||t},h.hasUrlDuplicate=function(e){var t=!1,n;return n=h.extractState(e.url),t=n&&n.id!==e.id,t},h.storeState=function(e){return h.urlToId[e.url]=e.id,h.storedStates.push(h.cloneObject(e)),e},h.isLastSavedState=function(e){var t=!1,n,r,i;return h.savedStates.length&&(n=e.id,r=h.getLastSavedState(),i=r.id,t=n===i),t},h.saveState=function(e){return h.isLastSavedState(e)?!1:(h.savedStates.push(h.cloneObject(e)),!0)},h.getStateByIndex=function(e){var t=null;return typeof e=="undefined"?t=h.savedStates[h.savedStates.length-1]:e<0?t=h.savedStates[h.savedStates.length+e]:t=h.savedStates[e],t},h.getCurrentIndex=function(){var e=null;return h.savedStates.length<1?e=0:e=h.savedStates.length-1,e},h.getHash=function(e){var t=h.getLocationHref(e),n;return n=h.getHashByUrl(t),n},h.unescapeHash=function(e){var t=h.normalizeHash(e);return t=decodeURIComponent(t),t},h.normalizeHash=function(e){var t=e.replace(/[^#]*#/,"").replace(/#.*/,"");return t},h.setHash=function(e,t){var n,i;return t!==!1&&h.busy()?(h.pushQueue({scope:h,callback:h.setHash,args:arguments,queue:t}),!1):(h.busy(!0),n=h.extractState(e,!0),n&&!h.emulated.pushState?h.pushState(n.data,n.title,n.url,!1):h.getHash()!==e&&(h.bugs.setHash?(i=h.getPageUrl(),h.pushState(null,null,i+"#"+e,!1)):r.location.hash=e),h)},h.escapeHash=function(t){var n=h.normalizeHash(t);return n=e.encodeURIComponent(n),h.bugs.hashEscape||(n=n.replace(/\%21/g,"!").replace(/\%26/g,"&").replace(/\%3D/g,"=").replace(/\%3F/g,"?")),n},h.getHashByUrl=function(e){var t=String(e).replace(/([^#]*)#?([^#]*)#?(.*)/,"$2");return t=h.unescapeHash(t),t},h.setTitle=function(e){var t=e.title,n;t||(n=h.getStateByIndex(0),n&&n.url===e.url&&(t=n.title||h.options.initialTitle));try{r.getElementsByTagName("title")[0].innerHTML=t.replace("<","<").replace(">",">").replace(" & "," & ")}catch(i){}return r.title=t,h},h.queues=[],h.busy=function(e){typeof e!="undefined"?h.busy.flag=e:typeof h.busy.flag=="undefined"&&(h.busy.flag=!1);if(!h.busy.flag){u(h.busy.timeout);var t=function(){var e,n,r;if(h.busy.flag)return;for(e=h.queues.length-1;e>=0;--e){n=h.queues[e];if(n.length===0)continue;r=n.shift(),h.fireQueueItem(r),h.busy.timeout=o(t,h.options.busyDelay)}};h.busy.timeout=o(t,h.options.busyDelay)}return h.busy.flag},h.busy.flag=!1,h.fireQueueItem=function(e){return e.callback.apply(e.scope||h,e.args||[])},h.pushQueue=function(e){return h.queues[e.queue||0]=h.queues[e.queue||0]||[],h.queues[e.queue||0].push(e),h},h.queue=function(e,t){return typeof e=="function"&&(e={callback:e}),typeof t!="undefined"&&(e.queue=t),h.busy()?h.pushQueue(e):h.fireQueueItem(e),h},h.clearQueue=function(){return h.busy.flag=!1,h.queues=[],h},h.stateChanged=!1,h.doubleChecker=!1,h.doubleCheckComplete=function(){return h.stateChanged=!0,h.doubleCheckClear(),h},h.doubleCheckClear=function(){return h.doubleChecker&&(u(h.doubleChecker),h.doubleChecker=!1),h},h.doubleCheck=function(e){return h.stateChanged=!1,h.doubleCheckClear(),h.bugs.ieDoubleCheck&&(h.doubleChecker=o(function(){return h.doubleCheckClear(),h.stateChanged||e(),!0},h.options.doubleCheckInterval)),h},h.safariStatePoll=function(){var t=h.extractState(h.getLocationHref()),n;if(!h.isLastSavedState(t))return n=t,n||(n=h.createStateObject()),h.Adapter.trigger(e,"popstate"),h;return},h.back=function(e){return e!==!1&&h.busy()?(h.pushQueue({scope:h,callback:h.back,args:arguments,queue:e}),!1):(h.busy(!0),h.doubleCheck(function(){h.back(!1)}),p.go(-1),!0)},h.forward=function(e){return e!==!1&&h.busy()?(h.pushQueue({scope:h,callback:h.forward,args:arguments,queue:e}),!1):(h.busy(!0),h.doubleCheck(function(){h.forward(!1)}),p.go(1),!0)},h.go=function(e,t){var n;if(e>0)for(n=1;n<=e;++n)h.forward(t);else{if(!(e<0))throw new Error("History.go: History.go requires a positive or negative integer passed.");for(n=-1;n>=e;--n)h.back(t)}return h};if(h.emulated.pushState){var v=function(){};h.pushState=h.pushState||v,h.replaceState=h.replaceState||v}else h.onPopState=function(t,n){var r=!1,i=!1,s,o;return h.doubleCheckComplete(),s=h.getHash(),s?(o=h.extractState(s||h.getLocationHref(),!0),o?h.replaceState(o.data,o.title,o.url,!1):(h.Adapter.trigger(e,"anchorchange"),h.busy(!1)),h.expectedStateId=!1,!1):(r=h.Adapter.extractEventData("state",t,n)||!1,r?i=h.getStateById(r):h.expectedStateId?i=h.getStateById(h.expectedStateId):i=h.extractState(h.getLocationHref()),i||(i=h.createStateObject(null,null,h.getLocationHref())),h.expectedStateId=!1,h.isLastSavedState(i)?(h.busy(!1),!1):(h.storeState(i),h.saveState(i),h.setTitle(i),h.Adapter.trigger(e,"statechange"),h.busy(!1),!0))},h.Adapter.bind(e,"popstate",h.onPopState),h.pushState=function(t,n,r,i){if(h.getHashByUrl(r)&&h.emulated.pushState)throw new Error("History.js does not support states with fragement-identifiers (hashes/anchors).");if(i!==!1&&h.busy())return h.pushQueue({scope:h,callback:h.pushState,args:arguments,queue:i}),!1;h.busy(!0);var s=h.createStateObject(t,n,r);return h.isLastSavedState(s)?h.busy(!1):(h.storeState(s),h.expectedStateId=s.id,p.pushState(s.id,s.title,s.url),h.Adapter.trigger(e,"popstate")),!0},h.replaceState=function(t,n,r,i){if(h.getHashByUrl(r)&&h.emulated.pushState)throw new Error("History.js does not support states with fragement-identifiers (hashes/anchors).");if(i!==!1&&h.busy())return h.pushQueue({scope:h,callback:h.replaceState,args:arguments,queue:i}),!1;h.busy(!0);var s=h.createStateObject(t,n,r);return h.isLastSavedState(s)?h.busy(!1):(h.storeState(s),h.expectedStateId=s.id,p.replaceState(s.id,s.title,s.url),h.Adapter.trigger(e,"popstate")),!0};if(s){try{h.store=l.parse(s.getItem("History.store"))||{}}catch(m){h.store={}}h.normalizeStore()}else h.store={},h.normalizeStore();h.Adapter.bind(e,"unload",h.clearAllIntervals),h.saveState(h.storeState(h.extractState(h.getLocationHref(),!0))),s&&(h.onUnload=function(){var e,t,n;try{e=l.parse(s.getItem("History.store"))||{}}catch(r){e={}}e.idToState=e.idToState||{},e.urlToId=e.urlToId||{},e.stateToId=e.stateToId||{};for(t in h.idToState){if(!h.idToState.hasOwnProperty(t))continue;e.idToState[t]=h.idToState[t]}for(t in h.urlToId){if(!h.urlToId.hasOwnProperty(t))continue;e.urlToId[t]=h.urlToId[t]}for(t in h.stateToId){if(!h.stateToId.hasOwnProperty(t))continue;e.stateToId[t]=h.stateToId[t]}h.store=e,h.normalizeStore(),n=l.stringify(e);try{s.setItem("History.store",n)}catch(i){if(i.code!==DOMException.QUOTA_EXCEEDED_ERR)throw i;s.length&&(s.removeItem("History.store"),s.setItem("History.store",n))}},h.intervalList.push(a(h.onUnload,h.options.storeInterval)),h.Adapter.bind(e,"beforeunload",h.onUnload),h.Adapter.bind(e,"unload",h.onUnload));if(!h.emulated.pushState){h.bugs.safariPoll&&h.intervalList.push(a(h.safariStatePoll,h.options.safariPollInterval));if(i.vendor==="Apple Computer, Inc."||(i.appCodeName||"")==="Mozilla")h.Adapter.bind(e,"hashchange",function(){h.Adapter.trigger(e,"popstate")}),h.getHash()&&h.Adapter.onDomLoad(function(){h.Adapter.trigger(e,"hashchange")})}},(!h.options||!h.options.delayInit)&&h.init()}(window) \ No newline at end of file diff --git a/sites/all/themes/gui/materiobasetheme/bower_components/history.js/scripts/bundled/html5/extjs.history.js b/sites/all/themes/gui/materiobasetheme/bower_components/history.js/scripts/bundled/html5/extjs.history.js new file mode 100644 index 00000000..a9ee3ffb --- /dev/null +++ b/sites/all/themes/gui/materiobasetheme/bower_components/history.js/scripts/bundled/html5/extjs.history.js @@ -0,0 +1 @@ +(function(e,t){"use strict";var n=e.History=e.History||{},r=e.Ext;e.JSON={stringify:r.JSON.encode,parse:r.JSON.decode};if(typeof n.Adapter!="undefined")throw new Error("History.js Adapter has already been loaded...");n.Adapter={observables:{},bind:function(e,t,n,i){r.EventManager.addListener(e,t,n,i);var s=r.id(e,"history-"),o=this.observables[s];o||(o=r.create("Ext.util.Observable"),this.observables[s]=o),o.on(t,n,i)},trigger:function(e,t,n){var i=r.id(e,"history-"),s=this.observables[i];s&&s.fireEvent(t,n)},extractEventData:function(e,n,r){var i=n&&n.browserEvent&&n.browserEvent[e]||r&&r[e]||t;return i},onDomLoad:function(e){r.onReady(e)}},typeof n.init!="undefined"&&n.init()})(window),function(e,t){"use strict";var n=e.console||t,r=e.document,i=e.navigator,s=e.sessionStorage||!1,o=e.setTimeout,u=e.clearTimeout,a=e.setInterval,f=e.clearInterval,l=e.JSON,c=e.alert,h=e.History=e.History||{},p=e.history;try{s.setItem("TEST","1"),s.removeItem("TEST")}catch(d){s=!1}l.stringify=l.stringify||l.encode,l.parse=l.parse||l.decode;if(typeof h.init!="undefined")throw new Error("History.js Core has already been loaded...");h.init=function(e){return typeof h.Adapter=="undefined"?!1:(typeof h.initCore!="undefined"&&h.initCore(),typeof h.initHtml4!="undefined"&&h.initHtml4(),!0)},h.initCore=function(d){if(typeof h.initCore.initialized!="undefined")return!1;h.initCore.initialized=!0,h.options=h.options||{},h.options.hashChangeInterval=h.options.hashChangeInterval||100,h.options.safariPollInterval=h.options.safariPollInterval||500,h.options.doubleCheckInterval=h.options.doubleCheckInterval||500,h.options.disableSuid=h.options.disableSuid||!1,h.options.storeInterval=h.options.storeInterval||1e3,h.options.busyDelay=h.options.busyDelay||250,h.options.debug=h.options.debug||!1,h.options.initialTitle=h.options.initialTitle||r.title,h.options.html4Mode=h.options.html4Mode||!1,h.options.delayInit=h.options.delayInit||!1,h.intervalList=[],h.clearAllIntervals=function(){var e,t=h.intervalList;if(typeof t!="undefined"&&t!==null){for(e=0;e")&&n[0]);return e>4?e:!1}();return e},h.isInternetExplorer=function(){var e=h.isInternetExplorer.cached=typeof h.isInternetExplorer.cached!="undefined"?h.isInternetExplorer.cached:Boolean(h.getInternetExplorerMajorVersion());return e},h.options.html4Mode?h.emulated={pushState:!0,hashChange:!0}:h.emulated={pushState:!Boolean(e.history&&e.history.pushState&&e.history.replaceState&&!/ Mobile\/([1-7][a-z]|(8([abcde]|f(1[0-8]))))/i.test(i.userAgent)&&!/AppleWebKit\/5([0-2]|3[0-2])/i.test(i.userAgent)),hashChange:Boolean(!("onhashchange"in e||"onhashchange"in r)||h.isInternetExplorer()&&h.getInternetExplorerMajorVersion()<8)},h.enabled=!h.emulated.pushState,h.bugs={setHash:Boolean(!h.emulated.pushState&&i.vendor==="Apple Computer, Inc."&&/AppleWebKit\/5([0-2]|3[0-3])/.test(i.userAgent)),safariPoll:Boolean(!h.emulated.pushState&&i.vendor==="Apple Computer, Inc."&&/AppleWebKit\/5([0-2]|3[0-3])/.test(i.userAgent)),ieDoubleCheck:Boolean(h.isInternetExplorer()&&h.getInternetExplorerMajorVersion()<8),hashEscape:Boolean(h.isInternetExplorer()&&h.getInternetExplorerMajorVersion()<7)},h.isEmptyObject=function(e){for(var t in e)if(e.hasOwnProperty(t))return!1;return!0},h.cloneObject=function(e){var t,n;return e?(t=l.stringify(e),n=l.parse(t)):n={},n},h.getRootUrl=function(){var e=r.location.protocol+"//"+(r.location.hostname||r.location.host);if(r.location.port||!1)e+=":"+r.location.port;return e+="/",e},h.getBaseHref=function(){var e=r.getElementsByTagName("base"),t=null,n="";return e.length===1&&(t=e[0],n=t.href.replace(/[^\/]+$/,"")),n=n.replace(/\/+$/,""),n&&(n+="/"),n},h.getBaseUrl=function(){var e=h.getBaseHref()||h.getBasePageUrl()||h.getRootUrl();return e},h.getPageUrl=function(){var e=h.getState(!1,!1),t=(e||{}).url||h.getLocationHref(),n;return n=t.replace(/\/+$/,"").replace(/[^\/]+$/,function(e,t,n){return/\./.test(e)?e:e+"/"}),n},h.getBasePageUrl=function(){var e=h.getLocationHref().replace(/[#\?].*/,"").replace(/[^\/]+$/,function(e,t,n){return/[^\/]$/.test(e)?"":e}).replace(/\/+$/,"")+"/";return e},h.getFullUrl=function(e,t){var n=e,r=e.substring(0,1);return t=typeof t=="undefined"?!0:t,/[a-z]+\:\/\//.test(e)||(r==="/"?n=h.getRootUrl()+e.replace(/^\/+/,""):r==="#"?n=h.getPageUrl().replace(/#.*/,"")+e:r==="?"?n=h.getPageUrl().replace(/[\?#].*/,"")+e:t?n=h.getBaseUrl()+e.replace(/^(\.\/)+/,""):n=h.getBasePageUrl()+e.replace(/^(\.\/)+/,"")),n.replace(/\#$/,"")},h.getShortUrl=function(e){var t=e,n=h.getBaseUrl(),r=h.getRootUrl();return h.emulated.pushState&&(t=t.replace(n,"")),t=t.replace(r,"/"),h.isTraditionalAnchor(t)&&(t="./"+t),t=t.replace(/^(\.\/)+/g,"./").replace(/\#$/,""),t},h.getLocationHref=function(e){return e=e||r,e.URL===e.location.href?e.location.href:e.location.href===decodeURIComponent(e.URL)?e.URL:e.location.hash&&decodeURIComponent(e.location.href.replace(/^[^#]+/,""))===e.location.hash?e.location.href:e.URL.indexOf("#")==-1&&e.location.href.indexOf("#")!=-1?e.location.href:e.URL||e.location.href},h.store={},h.idToState=h.idToState||{},h.stateToId=h.stateToId||{},h.urlToId=h.urlToId||{},h.storedStates=h.storedStates||[],h.savedStates=h.savedStates||[],h.normalizeStore=function(){h.store.idToState=h.store.idToState||{},h.store.urlToId=h.store.urlToId||{},h.store.stateToId=h.store.stateToId||{}},h.getState=function(e,t){typeof e=="undefined"&&(e=!0),typeof t=="undefined"&&(t=!0);var n=h.getLastSavedState();return!n&&t&&(n=h.createStateObject()),e&&(n=h.cloneObject(n),n.url=n.cleanUrl||n.url),n},h.getIdByState=function(e){var t=h.extractId(e.url),n;if(!t){n=h.getStateString(e);if(typeof h.stateToId[n]!="undefined")t=h.stateToId[n];else if(typeof h.store.stateToId[n]!="undefined")t=h.store.stateToId[n];else{for(;;){t=(new Date).getTime()+String(Math.random()).replace(/\D/g,"");if(typeof h.idToState[t]=="undefined"&&typeof h.store.idToState[t]=="undefined")break}h.stateToId[n]=t,h.idToState[t]=e}}return t},h.normalizeState=function(e){var t,n;if(!e||typeof e!="object")e={};if(typeof e.normalized!="undefined")return e;if(!e.data||typeof e.data!="object")e.data={};return t={},t.normalized=!0,t.title=e.title||"",t.url=h.getFullUrl(e.url?e.url:h.getLocationHref()),t.hash=h.getShortUrl(t.url),t.data=h.cloneObject(e.data),t.id=h.getIdByState(t),t.cleanUrl=t.url.replace(/\??\&_suid.*/,""),t.url=t.cleanUrl,n=!h.isEmptyObject(t.data),(t.title||n)&&h.options.disableSuid!==!0&&(t.hash=h.getShortUrl(t.url).replace(/\??\&_suid.*/,""),/\?/.test(t.hash)||(t.hash+="?"),t.hash+="&_suid="+t.id),t.hashedUrl=h.getFullUrl(t.hash),(h.emulated.pushState||h.bugs.safariPoll)&&h.hasUrlDuplicate(t)&&(t.url=t.hashedUrl),t},h.createStateObject=function(e,t,n){var r={data:e,title:t,url:n};return r=h.normalizeState(r),r},h.getStateById=function(e){e=String(e);var n=h.idToState[e]||h.store.idToState[e]||t;return n},h.getStateString=function(e){var t,n,r;return t=h.normalizeState(e),n={data:t.data,title:e.title,url:e.url},r=l.stringify(n),r},h.getStateId=function(e){var t,n;return t=h.normalizeState(e),n=t.id,n},h.getHashByState=function(e){var t,n;return t=h.normalizeState(e),n=t.hash,n},h.extractId=function(e){var t,n,r,i;return e.indexOf("#")!=-1?i=e.split("#")[0]:i=e,n=/(.*)\&_suid=([0-9]+)$/.exec(i),r=n?n[1]||e:e,t=n?String(n[2]||""):"",t||!1},h.isTraditionalAnchor=function(e){var t=!/[\/\?\.]/.test(e);return t},h.extractState=function(e,t){var n=null,r,i;return t=t||!1,r=h.extractId(e),r&&(n=h.getStateById(r)),n||(i=h.getFullUrl(e),r=h.getIdByUrl(i)||!1,r&&(n=h.getStateById(r)),!n&&t&&!h.isTraditionalAnchor(e)&&(n=h.createStateObject(null,null,i))),n},h.getIdByUrl=function(e){var n=h.urlToId[e]||h.store.urlToId[e]||t;return n},h.getLastSavedState=function(){return h.savedStates[h.savedStates.length-1]||t},h.getLastStoredState=function(){return h.storedStates[h.storedStates.length-1]||t},h.hasUrlDuplicate=function(e){var t=!1,n;return n=h.extractState(e.url),t=n&&n.id!==e.id,t},h.storeState=function(e){return h.urlToId[e.url]=e.id,h.storedStates.push(h.cloneObject(e)),e},h.isLastSavedState=function(e){var t=!1,n,r,i;return h.savedStates.length&&(n=e.id,r=h.getLastSavedState(),i=r.id,t=n===i),t},h.saveState=function(e){return h.isLastSavedState(e)?!1:(h.savedStates.push(h.cloneObject(e)),!0)},h.getStateByIndex=function(e){var t=null;return typeof e=="undefined"?t=h.savedStates[h.savedStates.length-1]:e<0?t=h.savedStates[h.savedStates.length+e]:t=h.savedStates[e],t},h.getCurrentIndex=function(){var e=null;return h.savedStates.length<1?e=0:e=h.savedStates.length-1,e},h.getHash=function(e){var t=h.getLocationHref(e),n;return n=h.getHashByUrl(t),n},h.unescapeHash=function(e){var t=h.normalizeHash(e);return t=decodeURIComponent(t),t},h.normalizeHash=function(e){var t=e.replace(/[^#]*#/,"").replace(/#.*/,"");return t},h.setHash=function(e,t){var n,i;return t!==!1&&h.busy()?(h.pushQueue({scope:h,callback:h.setHash,args:arguments,queue:t}),!1):(h.busy(!0),n=h.extractState(e,!0),n&&!h.emulated.pushState?h.pushState(n.data,n.title,n.url,!1):h.getHash()!==e&&(h.bugs.setHash?(i=h.getPageUrl(),h.pushState(null,null,i+"#"+e,!1)):r.location.hash=e),h)},h.escapeHash=function(t){var n=h.normalizeHash(t);return n=e.encodeURIComponent(n),h.bugs.hashEscape||(n=n.replace(/\%21/g,"!").replace(/\%26/g,"&").replace(/\%3D/g,"=").replace(/\%3F/g,"?")),n},h.getHashByUrl=function(e){var t=String(e).replace(/([^#]*)#?([^#]*)#?(.*)/,"$2");return t=h.unescapeHash(t),t},h.setTitle=function(e){var t=e.title,n;t||(n=h.getStateByIndex(0),n&&n.url===e.url&&(t=n.title||h.options.initialTitle));try{r.getElementsByTagName("title")[0].innerHTML=t.replace("<","<").replace(">",">").replace(" & "," & ")}catch(i){}return r.title=t,h},h.queues=[],h.busy=function(e){typeof e!="undefined"?h.busy.flag=e:typeof h.busy.flag=="undefined"&&(h.busy.flag=!1);if(!h.busy.flag){u(h.busy.timeout);var t=function(){var e,n,r;if(h.busy.flag)return;for(e=h.queues.length-1;e>=0;--e){n=h.queues[e];if(n.length===0)continue;r=n.shift(),h.fireQueueItem(r),h.busy.timeout=o(t,h.options.busyDelay)}};h.busy.timeout=o(t,h.options.busyDelay)}return h.busy.flag},h.busy.flag=!1,h.fireQueueItem=function(e){return e.callback.apply(e.scope||h,e.args||[])},h.pushQueue=function(e){return h.queues[e.queue||0]=h.queues[e.queue||0]||[],h.queues[e.queue||0].push(e),h},h.queue=function(e,t){return typeof e=="function"&&(e={callback:e}),typeof t!="undefined"&&(e.queue=t),h.busy()?h.pushQueue(e):h.fireQueueItem(e),h},h.clearQueue=function(){return h.busy.flag=!1,h.queues=[],h},h.stateChanged=!1,h.doubleChecker=!1,h.doubleCheckComplete=function(){return h.stateChanged=!0,h.doubleCheckClear(),h},h.doubleCheckClear=function(){return h.doubleChecker&&(u(h.doubleChecker),h.doubleChecker=!1),h},h.doubleCheck=function(e){return h.stateChanged=!1,h.doubleCheckClear(),h.bugs.ieDoubleCheck&&(h.doubleChecker=o(function(){return h.doubleCheckClear(),h.stateChanged||e(),!0},h.options.doubleCheckInterval)),h},h.safariStatePoll=function(){var t=h.extractState(h.getLocationHref()),n;if(!h.isLastSavedState(t))return n=t,n||(n=h.createStateObject()),h.Adapter.trigger(e,"popstate"),h;return},h.back=function(e){return e!==!1&&h.busy()?(h.pushQueue({scope:h,callback:h.back,args:arguments,queue:e}),!1):(h.busy(!0),h.doubleCheck(function(){h.back(!1)}),p.go(-1),!0)},h.forward=function(e){return e!==!1&&h.busy()?(h.pushQueue({scope:h,callback:h.forward,args:arguments,queue:e}),!1):(h.busy(!0),h.doubleCheck(function(){h.forward(!1)}),p.go(1),!0)},h.go=function(e,t){var n;if(e>0)for(n=1;n<=e;++n)h.forward(t);else{if(!(e<0))throw new Error("History.go: History.go requires a positive or negative integer passed.");for(n=-1;n>=e;--n)h.back(t)}return h};if(h.emulated.pushState){var v=function(){};h.pushState=h.pushState||v,h.replaceState=h.replaceState||v}else h.onPopState=function(t,n){var r=!1,i=!1,s,o;return h.doubleCheckComplete(),s=h.getHash(),s?(o=h.extractState(s||h.getLocationHref(),!0),o?h.replaceState(o.data,o.title,o.url,!1):(h.Adapter.trigger(e,"anchorchange"),h.busy(!1)),h.expectedStateId=!1,!1):(r=h.Adapter.extractEventData("state",t,n)||!1,r?i=h.getStateById(r):h.expectedStateId?i=h.getStateById(h.expectedStateId):i=h.extractState(h.getLocationHref()),i||(i=h.createStateObject(null,null,h.getLocationHref())),h.expectedStateId=!1,h.isLastSavedState(i)?(h.busy(!1),!1):(h.storeState(i),h.saveState(i),h.setTitle(i),h.Adapter.trigger(e,"statechange"),h.busy(!1),!0))},h.Adapter.bind(e,"popstate",h.onPopState),h.pushState=function(t,n,r,i){if(h.getHashByUrl(r)&&h.emulated.pushState)throw new Error("History.js does not support states with fragement-identifiers (hashes/anchors).");if(i!==!1&&h.busy())return h.pushQueue({scope:h,callback:h.pushState,args:arguments,queue:i}),!1;h.busy(!0);var s=h.createStateObject(t,n,r);return h.isLastSavedState(s)?h.busy(!1):(h.storeState(s),h.expectedStateId=s.id,p.pushState(s.id,s.title,s.url),h.Adapter.trigger(e,"popstate")),!0},h.replaceState=function(t,n,r,i){if(h.getHashByUrl(r)&&h.emulated.pushState)throw new Error("History.js does not support states with fragement-identifiers (hashes/anchors).");if(i!==!1&&h.busy())return h.pushQueue({scope:h,callback:h.replaceState,args:arguments,queue:i}),!1;h.busy(!0);var s=h.createStateObject(t,n,r);return h.isLastSavedState(s)?h.busy(!1):(h.storeState(s),h.expectedStateId=s.id,p.replaceState(s.id,s.title,s.url),h.Adapter.trigger(e,"popstate")),!0};if(s){try{h.store=l.parse(s.getItem("History.store"))||{}}catch(m){h.store={}}h.normalizeStore()}else h.store={},h.normalizeStore();h.Adapter.bind(e,"unload",h.clearAllIntervals),h.saveState(h.storeState(h.extractState(h.getLocationHref(),!0))),s&&(h.onUnload=function(){var e,t,n;try{e=l.parse(s.getItem("History.store"))||{}}catch(r){e={}}e.idToState=e.idToState||{},e.urlToId=e.urlToId||{},e.stateToId=e.stateToId||{};for(t in h.idToState){if(!h.idToState.hasOwnProperty(t))continue;e.idToState[t]=h.idToState[t]}for(t in h.urlToId){if(!h.urlToId.hasOwnProperty(t))continue;e.urlToId[t]=h.urlToId[t]}for(t in h.stateToId){if(!h.stateToId.hasOwnProperty(t))continue;e.stateToId[t]=h.stateToId[t]}h.store=e,h.normalizeStore(),n=l.stringify(e);try{s.setItem("History.store",n)}catch(i){if(i.code!==DOMException.QUOTA_EXCEEDED_ERR)throw i;s.length&&(s.removeItem("History.store"),s.setItem("History.store",n))}},h.intervalList.push(a(h.onUnload,h.options.storeInterval)),h.Adapter.bind(e,"beforeunload",h.onUnload),h.Adapter.bind(e,"unload",h.onUnload));if(!h.emulated.pushState){h.bugs.safariPoll&&h.intervalList.push(a(h.safariStatePoll,h.options.safariPollInterval));if(i.vendor==="Apple Computer, Inc."||(i.appCodeName||"")==="Mozilla")h.Adapter.bind(e,"hashchange",function(){h.Adapter.trigger(e,"popstate")}),h.getHash()&&h.Adapter.onDomLoad(function(){h.Adapter.trigger(e,"hashchange")})}},(!h.options||!h.options.delayInit)&&h.init()}(window) \ No newline at end of file diff --git a/sites/all/themes/gui/materiobasetheme/bower_components/history.js/scripts/bundled/html5/jquery.history.js b/sites/all/themes/gui/materiobasetheme/bower_components/history.js/scripts/bundled/html5/jquery.history.js new file mode 100644 index 00000000..caeb7aa4 --- /dev/null +++ b/sites/all/themes/gui/materiobasetheme/bower_components/history.js/scripts/bundled/html5/jquery.history.js @@ -0,0 +1 @@ +(function(e,t){"use strict";var n=e.History=e.History||{},r=e.jQuery;if(typeof n.Adapter!="undefined")throw new Error("History.js Adapter has already been loaded...");n.Adapter={bind:function(e,t,n){r(e).bind(t,n)},trigger:function(e,t,n){r(e).trigger(t,n)},extractEventData:function(e,n,r){var i=n&&n.originalEvent&&n.originalEvent[e]||r&&r[e]||t;return i},onDomLoad:function(e){r(e)}},typeof n.init!="undefined"&&n.init()})(window),function(e,t){"use strict";var n=e.console||t,r=e.document,i=e.navigator,s=e.sessionStorage||!1,o=e.setTimeout,u=e.clearTimeout,a=e.setInterval,f=e.clearInterval,l=e.JSON,c=e.alert,h=e.History=e.History||{},p=e.history;try{s.setItem("TEST","1"),s.removeItem("TEST")}catch(d){s=!1}l.stringify=l.stringify||l.encode,l.parse=l.parse||l.decode;if(typeof h.init!="undefined")throw new Error("History.js Core has already been loaded...");h.init=function(e){return typeof h.Adapter=="undefined"?!1:(typeof h.initCore!="undefined"&&h.initCore(),typeof h.initHtml4!="undefined"&&h.initHtml4(),!0)},h.initCore=function(d){if(typeof h.initCore.initialized!="undefined")return!1;h.initCore.initialized=!0,h.options=h.options||{},h.options.hashChangeInterval=h.options.hashChangeInterval||100,h.options.safariPollInterval=h.options.safariPollInterval||500,h.options.doubleCheckInterval=h.options.doubleCheckInterval||500,h.options.disableSuid=h.options.disableSuid||!1,h.options.storeInterval=h.options.storeInterval||1e3,h.options.busyDelay=h.options.busyDelay||250,h.options.debug=h.options.debug||!1,h.options.initialTitle=h.options.initialTitle||r.title,h.options.html4Mode=h.options.html4Mode||!1,h.options.delayInit=h.options.delayInit||!1,h.intervalList=[],h.clearAllIntervals=function(){var e,t=h.intervalList;if(typeof t!="undefined"&&t!==null){for(e=0;e")&&n[0]);return e>4?e:!1}();return e},h.isInternetExplorer=function(){var e=h.isInternetExplorer.cached=typeof h.isInternetExplorer.cached!="undefined"?h.isInternetExplorer.cached:Boolean(h.getInternetExplorerMajorVersion());return e},h.options.html4Mode?h.emulated={pushState:!0,hashChange:!0}:h.emulated={pushState:!Boolean(e.history&&e.history.pushState&&e.history.replaceState&&!/ Mobile\/([1-7][a-z]|(8([abcde]|f(1[0-8]))))/i.test(i.userAgent)&&!/AppleWebKit\/5([0-2]|3[0-2])/i.test(i.userAgent)),hashChange:Boolean(!("onhashchange"in e||"onhashchange"in r)||h.isInternetExplorer()&&h.getInternetExplorerMajorVersion()<8)},h.enabled=!h.emulated.pushState,h.bugs={setHash:Boolean(!h.emulated.pushState&&i.vendor==="Apple Computer, Inc."&&/AppleWebKit\/5([0-2]|3[0-3])/.test(i.userAgent)),safariPoll:Boolean(!h.emulated.pushState&&i.vendor==="Apple Computer, Inc."&&/AppleWebKit\/5([0-2]|3[0-3])/.test(i.userAgent)),ieDoubleCheck:Boolean(h.isInternetExplorer()&&h.getInternetExplorerMajorVersion()<8),hashEscape:Boolean(h.isInternetExplorer()&&h.getInternetExplorerMajorVersion()<7)},h.isEmptyObject=function(e){for(var t in e)if(e.hasOwnProperty(t))return!1;return!0},h.cloneObject=function(e){var t,n;return e?(t=l.stringify(e),n=l.parse(t)):n={},n},h.getRootUrl=function(){var e=r.location.protocol+"//"+(r.location.hostname||r.location.host);if(r.location.port||!1)e+=":"+r.location.port;return e+="/",e},h.getBaseHref=function(){var e=r.getElementsByTagName("base"),t=null,n="";return e.length===1&&(t=e[0],n=t.href.replace(/[^\/]+$/,"")),n=n.replace(/\/+$/,""),n&&(n+="/"),n},h.getBaseUrl=function(){var e=h.getBaseHref()||h.getBasePageUrl()||h.getRootUrl();return e},h.getPageUrl=function(){var e=h.getState(!1,!1),t=(e||{}).url||h.getLocationHref(),n;return n=t.replace(/\/+$/,"").replace(/[^\/]+$/,function(e,t,n){return/\./.test(e)?e:e+"/"}),n},h.getBasePageUrl=function(){var e=h.getLocationHref().replace(/[#\?].*/,"").replace(/[^\/]+$/,function(e,t,n){return/[^\/]$/.test(e)?"":e}).replace(/\/+$/,"")+"/";return e},h.getFullUrl=function(e,t){var n=e,r=e.substring(0,1);return t=typeof t=="undefined"?!0:t,/[a-z]+\:\/\//.test(e)||(r==="/"?n=h.getRootUrl()+e.replace(/^\/+/,""):r==="#"?n=h.getPageUrl().replace(/#.*/,"")+e:r==="?"?n=h.getPageUrl().replace(/[\?#].*/,"")+e:t?n=h.getBaseUrl()+e.replace(/^(\.\/)+/,""):n=h.getBasePageUrl()+e.replace(/^(\.\/)+/,"")),n.replace(/\#$/,"")},h.getShortUrl=function(e){var t=e,n=h.getBaseUrl(),r=h.getRootUrl();return h.emulated.pushState&&(t=t.replace(n,"")),t=t.replace(r,"/"),h.isTraditionalAnchor(t)&&(t="./"+t),t=t.replace(/^(\.\/)+/g,"./").replace(/\#$/,""),t},h.getLocationHref=function(e){return e=e||r,e.URL===e.location.href?e.location.href:e.location.href===decodeURIComponent(e.URL)?e.URL:e.location.hash&&decodeURIComponent(e.location.href.replace(/^[^#]+/,""))===e.location.hash?e.location.href:e.URL.indexOf("#")==-1&&e.location.href.indexOf("#")!=-1?e.location.href:e.URL||e.location.href},h.store={},h.idToState=h.idToState||{},h.stateToId=h.stateToId||{},h.urlToId=h.urlToId||{},h.storedStates=h.storedStates||[],h.savedStates=h.savedStates||[],h.normalizeStore=function(){h.store.idToState=h.store.idToState||{},h.store.urlToId=h.store.urlToId||{},h.store.stateToId=h.store.stateToId||{}},h.getState=function(e,t){typeof e=="undefined"&&(e=!0),typeof t=="undefined"&&(t=!0);var n=h.getLastSavedState();return!n&&t&&(n=h.createStateObject()),e&&(n=h.cloneObject(n),n.url=n.cleanUrl||n.url),n},h.getIdByState=function(e){var t=h.extractId(e.url),n;if(!t){n=h.getStateString(e);if(typeof h.stateToId[n]!="undefined")t=h.stateToId[n];else if(typeof h.store.stateToId[n]!="undefined")t=h.store.stateToId[n];else{for(;;){t=(new Date).getTime()+String(Math.random()).replace(/\D/g,"");if(typeof h.idToState[t]=="undefined"&&typeof h.store.idToState[t]=="undefined")break}h.stateToId[n]=t,h.idToState[t]=e}}return t},h.normalizeState=function(e){var t,n;if(!e||typeof e!="object")e={};if(typeof e.normalized!="undefined")return e;if(!e.data||typeof e.data!="object")e.data={};return t={},t.normalized=!0,t.title=e.title||"",t.url=h.getFullUrl(e.url?e.url:h.getLocationHref()),t.hash=h.getShortUrl(t.url),t.data=h.cloneObject(e.data),t.id=h.getIdByState(t),t.cleanUrl=t.url.replace(/\??\&_suid.*/,""),t.url=t.cleanUrl,n=!h.isEmptyObject(t.data),(t.title||n)&&h.options.disableSuid!==!0&&(t.hash=h.getShortUrl(t.url).replace(/\??\&_suid.*/,""),/\?/.test(t.hash)||(t.hash+="?"),t.hash+="&_suid="+t.id),t.hashedUrl=h.getFullUrl(t.hash),(h.emulated.pushState||h.bugs.safariPoll)&&h.hasUrlDuplicate(t)&&(t.url=t.hashedUrl),t},h.createStateObject=function(e,t,n){var r={data:e,title:t,url:n};return r=h.normalizeState(r),r},h.getStateById=function(e){e=String(e);var n=h.idToState[e]||h.store.idToState[e]||t;return n},h.getStateString=function(e){var t,n,r;return t=h.normalizeState(e),n={data:t.data,title:e.title,url:e.url},r=l.stringify(n),r},h.getStateId=function(e){var t,n;return t=h.normalizeState(e),n=t.id,n},h.getHashByState=function(e){var t,n;return t=h.normalizeState(e),n=t.hash,n},h.extractId=function(e){var t,n,r,i;return e.indexOf("#")!=-1?i=e.split("#")[0]:i=e,n=/(.*)\&_suid=([0-9]+)$/.exec(i),r=n?n[1]||e:e,t=n?String(n[2]||""):"",t||!1},h.isTraditionalAnchor=function(e){var t=!/[\/\?\.]/.test(e);return t},h.extractState=function(e,t){var n=null,r,i;return t=t||!1,r=h.extractId(e),r&&(n=h.getStateById(r)),n||(i=h.getFullUrl(e),r=h.getIdByUrl(i)||!1,r&&(n=h.getStateById(r)),!n&&t&&!h.isTraditionalAnchor(e)&&(n=h.createStateObject(null,null,i))),n},h.getIdByUrl=function(e){var n=h.urlToId[e]||h.store.urlToId[e]||t;return n},h.getLastSavedState=function(){return h.savedStates[h.savedStates.length-1]||t},h.getLastStoredState=function(){return h.storedStates[h.storedStates.length-1]||t},h.hasUrlDuplicate=function(e){var t=!1,n;return n=h.extractState(e.url),t=n&&n.id!==e.id,t},h.storeState=function(e){return h.urlToId[e.url]=e.id,h.storedStates.push(h.cloneObject(e)),e},h.isLastSavedState=function(e){var t=!1,n,r,i;return h.savedStates.length&&(n=e.id,r=h.getLastSavedState(),i=r.id,t=n===i),t},h.saveState=function(e){return h.isLastSavedState(e)?!1:(h.savedStates.push(h.cloneObject(e)),!0)},h.getStateByIndex=function(e){var t=null;return typeof e=="undefined"?t=h.savedStates[h.savedStates.length-1]:e<0?t=h.savedStates[h.savedStates.length+e]:t=h.savedStates[e],t},h.getCurrentIndex=function(){var e=null;return h.savedStates.length<1?e=0:e=h.savedStates.length-1,e},h.getHash=function(e){var t=h.getLocationHref(e),n;return n=h.getHashByUrl(t),n},h.unescapeHash=function(e){var t=h.normalizeHash(e);return t=decodeURIComponent(t),t},h.normalizeHash=function(e){var t=e.replace(/[^#]*#/,"").replace(/#.*/,"");return t},h.setHash=function(e,t){var n,i;return t!==!1&&h.busy()?(h.pushQueue({scope:h,callback:h.setHash,args:arguments,queue:t}),!1):(h.busy(!0),n=h.extractState(e,!0),n&&!h.emulated.pushState?h.pushState(n.data,n.title,n.url,!1):h.getHash()!==e&&(h.bugs.setHash?(i=h.getPageUrl(),h.pushState(null,null,i+"#"+e,!1)):r.location.hash=e),h)},h.escapeHash=function(t){var n=h.normalizeHash(t);return n=e.encodeURIComponent(n),h.bugs.hashEscape||(n=n.replace(/\%21/g,"!").replace(/\%26/g,"&").replace(/\%3D/g,"=").replace(/\%3F/g,"?")),n},h.getHashByUrl=function(e){var t=String(e).replace(/([^#]*)#?([^#]*)#?(.*)/,"$2");return t=h.unescapeHash(t),t},h.setTitle=function(e){var t=e.title,n;t||(n=h.getStateByIndex(0),n&&n.url===e.url&&(t=n.title||h.options.initialTitle));try{r.getElementsByTagName("title")[0].innerHTML=t.replace("<","<").replace(">",">").replace(" & "," & ")}catch(i){}return r.title=t,h},h.queues=[],h.busy=function(e){typeof e!="undefined"?h.busy.flag=e:typeof h.busy.flag=="undefined"&&(h.busy.flag=!1);if(!h.busy.flag){u(h.busy.timeout);var t=function(){var e,n,r;if(h.busy.flag)return;for(e=h.queues.length-1;e>=0;--e){n=h.queues[e];if(n.length===0)continue;r=n.shift(),h.fireQueueItem(r),h.busy.timeout=o(t,h.options.busyDelay)}};h.busy.timeout=o(t,h.options.busyDelay)}return h.busy.flag},h.busy.flag=!1,h.fireQueueItem=function(e){return e.callback.apply(e.scope||h,e.args||[])},h.pushQueue=function(e){return h.queues[e.queue||0]=h.queues[e.queue||0]||[],h.queues[e.queue||0].push(e),h},h.queue=function(e,t){return typeof e=="function"&&(e={callback:e}),typeof t!="undefined"&&(e.queue=t),h.busy()?h.pushQueue(e):h.fireQueueItem(e),h},h.clearQueue=function(){return h.busy.flag=!1,h.queues=[],h},h.stateChanged=!1,h.doubleChecker=!1,h.doubleCheckComplete=function(){return h.stateChanged=!0,h.doubleCheckClear(),h},h.doubleCheckClear=function(){return h.doubleChecker&&(u(h.doubleChecker),h.doubleChecker=!1),h},h.doubleCheck=function(e){return h.stateChanged=!1,h.doubleCheckClear(),h.bugs.ieDoubleCheck&&(h.doubleChecker=o(function(){return h.doubleCheckClear(),h.stateChanged||e(),!0},h.options.doubleCheckInterval)),h},h.safariStatePoll=function(){var t=h.extractState(h.getLocationHref()),n;if(!h.isLastSavedState(t))return n=t,n||(n=h.createStateObject()),h.Adapter.trigger(e,"popstate"),h;return},h.back=function(e){return e!==!1&&h.busy()?(h.pushQueue({scope:h,callback:h.back,args:arguments,queue:e}),!1):(h.busy(!0),h.doubleCheck(function(){h.back(!1)}),p.go(-1),!0)},h.forward=function(e){return e!==!1&&h.busy()?(h.pushQueue({scope:h,callback:h.forward,args:arguments,queue:e}),!1):(h.busy(!0),h.doubleCheck(function(){h.forward(!1)}),p.go(1),!0)},h.go=function(e,t){var n;if(e>0)for(n=1;n<=e;++n)h.forward(t);else{if(!(e<0))throw new Error("History.go: History.go requires a positive or negative integer passed.");for(n=-1;n>=e;--n)h.back(t)}return h};if(h.emulated.pushState){var v=function(){};h.pushState=h.pushState||v,h.replaceState=h.replaceState||v}else h.onPopState=function(t,n){var r=!1,i=!1,s,o;return h.doubleCheckComplete(),s=h.getHash(),s?(o=h.extractState(s||h.getLocationHref(),!0),o?h.replaceState(o.data,o.title,o.url,!1):(h.Adapter.trigger(e,"anchorchange"),h.busy(!1)),h.expectedStateId=!1,!1):(r=h.Adapter.extractEventData("state",t,n)||!1,r?i=h.getStateById(r):h.expectedStateId?i=h.getStateById(h.expectedStateId):i=h.extractState(h.getLocationHref()),i||(i=h.createStateObject(null,null,h.getLocationHref())),h.expectedStateId=!1,h.isLastSavedState(i)?(h.busy(!1),!1):(h.storeState(i),h.saveState(i),h.setTitle(i),h.Adapter.trigger(e,"statechange"),h.busy(!1),!0))},h.Adapter.bind(e,"popstate",h.onPopState),h.pushState=function(t,n,r,i){if(h.getHashByUrl(r)&&h.emulated.pushState)throw new Error("History.js does not support states with fragement-identifiers (hashes/anchors).");if(i!==!1&&h.busy())return h.pushQueue({scope:h,callback:h.pushState,args:arguments,queue:i}),!1;h.busy(!0);var s=h.createStateObject(t,n,r);return h.isLastSavedState(s)?h.busy(!1):(h.storeState(s),h.expectedStateId=s.id,p.pushState(s.id,s.title,s.url),h.Adapter.trigger(e,"popstate")),!0},h.replaceState=function(t,n,r,i){if(h.getHashByUrl(r)&&h.emulated.pushState)throw new Error("History.js does not support states with fragement-identifiers (hashes/anchors).");if(i!==!1&&h.busy())return h.pushQueue({scope:h,callback:h.replaceState,args:arguments,queue:i}),!1;h.busy(!0);var s=h.createStateObject(t,n,r);return h.isLastSavedState(s)?h.busy(!1):(h.storeState(s),h.expectedStateId=s.id,p.replaceState(s.id,s.title,s.url),h.Adapter.trigger(e,"popstate")),!0};if(s){try{h.store=l.parse(s.getItem("History.store"))||{}}catch(m){h.store={}}h.normalizeStore()}else h.store={},h.normalizeStore();h.Adapter.bind(e,"unload",h.clearAllIntervals),h.saveState(h.storeState(h.extractState(h.getLocationHref(),!0))),s&&(h.onUnload=function(){var e,t,n;try{e=l.parse(s.getItem("History.store"))||{}}catch(r){e={}}e.idToState=e.idToState||{},e.urlToId=e.urlToId||{},e.stateToId=e.stateToId||{};for(t in h.idToState){if(!h.idToState.hasOwnProperty(t))continue;e.idToState[t]=h.idToState[t]}for(t in h.urlToId){if(!h.urlToId.hasOwnProperty(t))continue;e.urlToId[t]=h.urlToId[t]}for(t in h.stateToId){if(!h.stateToId.hasOwnProperty(t))continue;e.stateToId[t]=h.stateToId[t]}h.store=e,h.normalizeStore(),n=l.stringify(e);try{s.setItem("History.store",n)}catch(i){if(i.code!==DOMException.QUOTA_EXCEEDED_ERR)throw i;s.length&&(s.removeItem("History.store"),s.setItem("History.store",n))}},h.intervalList.push(a(h.onUnload,h.options.storeInterval)),h.Adapter.bind(e,"beforeunload",h.onUnload),h.Adapter.bind(e,"unload",h.onUnload));if(!h.emulated.pushState){h.bugs.safariPoll&&h.intervalList.push(a(h.safariStatePoll,h.options.safariPollInterval));if(i.vendor==="Apple Computer, Inc."||(i.appCodeName||"")==="Mozilla")h.Adapter.bind(e,"hashchange",function(){h.Adapter.trigger(e,"popstate")}),h.getHash()&&h.Adapter.onDomLoad(function(){h.Adapter.trigger(e,"hashchange")})}},(!h.options||!h.options.delayInit)&&h.init()}(window) \ No newline at end of file diff --git a/sites/all/themes/gui/materiobasetheme/bower_components/history.js/scripts/bundled/html5/mootools.history.js b/sites/all/themes/gui/materiobasetheme/bower_components/history.js/scripts/bundled/html5/mootools.history.js new file mode 100644 index 00000000..5082b839 --- /dev/null +++ b/sites/all/themes/gui/materiobasetheme/bower_components/history.js/scripts/bundled/html5/mootools.history.js @@ -0,0 +1 @@ +(function(e,t){"use strict";var n=e.History=e.History||{},r=e.MooTools,i=e.Element;if(typeof n.Adapter!="undefined")throw new Error("History.js Adapter has already been loaded...");Object.append(i.NativeEvents,{popstate:2,hashchange:2}),n.Adapter={bind:function(e,t,n){var r=typeof e=="string"?document.id(e):e;r.addEvent(t,n)},trigger:function(e,t,n){var r=typeof e=="string"?document.id(e):e;r.fireEvent(t,n)},extractEventData:function(e,n){var r=n&&n.event&&n.event[e]||n&&n[e]||t;return r},onDomLoad:function(t){e.addEvent("domready",t)}},typeof n.init!="undefined"&&n.init()})(window),function(e,t){"use strict";var n=e.console||t,r=e.document,i=e.navigator,s=e.sessionStorage||!1,o=e.setTimeout,u=e.clearTimeout,a=e.setInterval,f=e.clearInterval,l=e.JSON,c=e.alert,h=e.History=e.History||{},p=e.history;try{s.setItem("TEST","1"),s.removeItem("TEST")}catch(d){s=!1}l.stringify=l.stringify||l.encode,l.parse=l.parse||l.decode;if(typeof h.init!="undefined")throw new Error("History.js Core has already been loaded...");h.init=function(e){return typeof h.Adapter=="undefined"?!1:(typeof h.initCore!="undefined"&&h.initCore(),typeof h.initHtml4!="undefined"&&h.initHtml4(),!0)},h.initCore=function(d){if(typeof h.initCore.initialized!="undefined")return!1;h.initCore.initialized=!0,h.options=h.options||{},h.options.hashChangeInterval=h.options.hashChangeInterval||100,h.options.safariPollInterval=h.options.safariPollInterval||500,h.options.doubleCheckInterval=h.options.doubleCheckInterval||500,h.options.disableSuid=h.options.disableSuid||!1,h.options.storeInterval=h.options.storeInterval||1e3,h.options.busyDelay=h.options.busyDelay||250,h.options.debug=h.options.debug||!1,h.options.initialTitle=h.options.initialTitle||r.title,h.options.html4Mode=h.options.html4Mode||!1,h.options.delayInit=h.options.delayInit||!1,h.intervalList=[],h.clearAllIntervals=function(){var e,t=h.intervalList;if(typeof t!="undefined"&&t!==null){for(e=0;e")&&n[0]);return e>4?e:!1}();return e},h.isInternetExplorer=function(){var e=h.isInternetExplorer.cached=typeof h.isInternetExplorer.cached!="undefined"?h.isInternetExplorer.cached:Boolean(h.getInternetExplorerMajorVersion());return e},h.options.html4Mode?h.emulated={pushState:!0,hashChange:!0}:h.emulated={pushState:!Boolean(e.history&&e.history.pushState&&e.history.replaceState&&!/ Mobile\/([1-7][a-z]|(8([abcde]|f(1[0-8]))))/i.test(i.userAgent)&&!/AppleWebKit\/5([0-2]|3[0-2])/i.test(i.userAgent)),hashChange:Boolean(!("onhashchange"in e||"onhashchange"in r)||h.isInternetExplorer()&&h.getInternetExplorerMajorVersion()<8)},h.enabled=!h.emulated.pushState,h.bugs={setHash:Boolean(!h.emulated.pushState&&i.vendor==="Apple Computer, Inc."&&/AppleWebKit\/5([0-2]|3[0-3])/.test(i.userAgent)),safariPoll:Boolean(!h.emulated.pushState&&i.vendor==="Apple Computer, Inc."&&/AppleWebKit\/5([0-2]|3[0-3])/.test(i.userAgent)),ieDoubleCheck:Boolean(h.isInternetExplorer()&&h.getInternetExplorerMajorVersion()<8),hashEscape:Boolean(h.isInternetExplorer()&&h.getInternetExplorerMajorVersion()<7)},h.isEmptyObject=function(e){for(var t in e)if(e.hasOwnProperty(t))return!1;return!0},h.cloneObject=function(e){var t,n;return e?(t=l.stringify(e),n=l.parse(t)):n={},n},h.getRootUrl=function(){var e=r.location.protocol+"//"+(r.location.hostname||r.location.host);if(r.location.port||!1)e+=":"+r.location.port;return e+="/",e},h.getBaseHref=function(){var e=r.getElementsByTagName("base"),t=null,n="";return e.length===1&&(t=e[0],n=t.href.replace(/[^\/]+$/,"")),n=n.replace(/\/+$/,""),n&&(n+="/"),n},h.getBaseUrl=function(){var e=h.getBaseHref()||h.getBasePageUrl()||h.getRootUrl();return e},h.getPageUrl=function(){var e=h.getState(!1,!1),t=(e||{}).url||h.getLocationHref(),n;return n=t.replace(/\/+$/,"").replace(/[^\/]+$/,function(e,t,n){return/\./.test(e)?e:e+"/"}),n},h.getBasePageUrl=function(){var e=h.getLocationHref().replace(/[#\?].*/,"").replace(/[^\/]+$/,function(e,t,n){return/[^\/]$/.test(e)?"":e}).replace(/\/+$/,"")+"/";return e},h.getFullUrl=function(e,t){var n=e,r=e.substring(0,1);return t=typeof t=="undefined"?!0:t,/[a-z]+\:\/\//.test(e)||(r==="/"?n=h.getRootUrl()+e.replace(/^\/+/,""):r==="#"?n=h.getPageUrl().replace(/#.*/,"")+e:r==="?"?n=h.getPageUrl().replace(/[\?#].*/,"")+e:t?n=h.getBaseUrl()+e.replace(/^(\.\/)+/,""):n=h.getBasePageUrl()+e.replace(/^(\.\/)+/,"")),n.replace(/\#$/,"")},h.getShortUrl=function(e){var t=e,n=h.getBaseUrl(),r=h.getRootUrl();return h.emulated.pushState&&(t=t.replace(n,"")),t=t.replace(r,"/"),h.isTraditionalAnchor(t)&&(t="./"+t),t=t.replace(/^(\.\/)+/g,"./").replace(/\#$/,""),t},h.getLocationHref=function(e){return e=e||r,e.URL===e.location.href?e.location.href:e.location.href===decodeURIComponent(e.URL)?e.URL:e.location.hash&&decodeURIComponent(e.location.href.replace(/^[^#]+/,""))===e.location.hash?e.location.href:e.URL.indexOf("#")==-1&&e.location.href.indexOf("#")!=-1?e.location.href:e.URL||e.location.href},h.store={},h.idToState=h.idToState||{},h.stateToId=h.stateToId||{},h.urlToId=h.urlToId||{},h.storedStates=h.storedStates||[],h.savedStates=h.savedStates||[],h.normalizeStore=function(){h.store.idToState=h.store.idToState||{},h.store.urlToId=h.store.urlToId||{},h.store.stateToId=h.store.stateToId||{}},h.getState=function(e,t){typeof e=="undefined"&&(e=!0),typeof t=="undefined"&&(t=!0);var n=h.getLastSavedState();return!n&&t&&(n=h.createStateObject()),e&&(n=h.cloneObject(n),n.url=n.cleanUrl||n.url),n},h.getIdByState=function(e){var t=h.extractId(e.url),n;if(!t){n=h.getStateString(e);if(typeof h.stateToId[n]!="undefined")t=h.stateToId[n];else if(typeof h.store.stateToId[n]!="undefined")t=h.store.stateToId[n];else{for(;;){t=(new Date).getTime()+String(Math.random()).replace(/\D/g,"");if(typeof h.idToState[t]=="undefined"&&typeof h.store.idToState[t]=="undefined")break}h.stateToId[n]=t,h.idToState[t]=e}}return t},h.normalizeState=function(e){var t,n;if(!e||typeof e!="object")e={};if(typeof e.normalized!="undefined")return e;if(!e.data||typeof e.data!="object")e.data={};return t={},t.normalized=!0,t.title=e.title||"",t.url=h.getFullUrl(e.url?e.url:h.getLocationHref()),t.hash=h.getShortUrl(t.url),t.data=h.cloneObject(e.data),t.id=h.getIdByState(t),t.cleanUrl=t.url.replace(/\??\&_suid.*/,""),t.url=t.cleanUrl,n=!h.isEmptyObject(t.data),(t.title||n)&&h.options.disableSuid!==!0&&(t.hash=h.getShortUrl(t.url).replace(/\??\&_suid.*/,""),/\?/.test(t.hash)||(t.hash+="?"),t.hash+="&_suid="+t.id),t.hashedUrl=h.getFullUrl(t.hash),(h.emulated.pushState||h.bugs.safariPoll)&&h.hasUrlDuplicate(t)&&(t.url=t.hashedUrl),t},h.createStateObject=function(e,t,n){var r={data:e,title:t,url:n};return r=h.normalizeState(r),r},h.getStateById=function(e){e=String(e);var n=h.idToState[e]||h.store.idToState[e]||t;return n},h.getStateString=function(e){var t,n,r;return t=h.normalizeState(e),n={data:t.data,title:e.title,url:e.url},r=l.stringify(n),r},h.getStateId=function(e){var t,n;return t=h.normalizeState(e),n=t.id,n},h.getHashByState=function(e){var t,n;return t=h.normalizeState(e),n=t.hash,n},h.extractId=function(e){var t,n,r,i;return e.indexOf("#")!=-1?i=e.split("#")[0]:i=e,n=/(.*)\&_suid=([0-9]+)$/.exec(i),r=n?n[1]||e:e,t=n?String(n[2]||""):"",t||!1},h.isTraditionalAnchor=function(e){var t=!/[\/\?\.]/.test(e);return t},h.extractState=function(e,t){var n=null,r,i;return t=t||!1,r=h.extractId(e),r&&(n=h.getStateById(r)),n||(i=h.getFullUrl(e),r=h.getIdByUrl(i)||!1,r&&(n=h.getStateById(r)),!n&&t&&!h.isTraditionalAnchor(e)&&(n=h.createStateObject(null,null,i))),n},h.getIdByUrl=function(e){var n=h.urlToId[e]||h.store.urlToId[e]||t;return n},h.getLastSavedState=function(){return h.savedStates[h.savedStates.length-1]||t},h.getLastStoredState=function(){return h.storedStates[h.storedStates.length-1]||t},h.hasUrlDuplicate=function(e){var t=!1,n;return n=h.extractState(e.url),t=n&&n.id!==e.id,t},h.storeState=function(e){return h.urlToId[e.url]=e.id,h.storedStates.push(h.cloneObject(e)),e},h.isLastSavedState=function(e){var t=!1,n,r,i;return h.savedStates.length&&(n=e.id,r=h.getLastSavedState(),i=r.id,t=n===i),t},h.saveState=function(e){return h.isLastSavedState(e)?!1:(h.savedStates.push(h.cloneObject(e)),!0)},h.getStateByIndex=function(e){var t=null;return typeof e=="undefined"?t=h.savedStates[h.savedStates.length-1]:e<0?t=h.savedStates[h.savedStates.length+e]:t=h.savedStates[e],t},h.getCurrentIndex=function(){var e=null;return h.savedStates.length<1?e=0:e=h.savedStates.length-1,e},h.getHash=function(e){var t=h.getLocationHref(e),n;return n=h.getHashByUrl(t),n},h.unescapeHash=function(e){var t=h.normalizeHash(e);return t=decodeURIComponent(t),t},h.normalizeHash=function(e){var t=e.replace(/[^#]*#/,"").replace(/#.*/,"");return t},h.setHash=function(e,t){var n,i;return t!==!1&&h.busy()?(h.pushQueue({scope:h,callback:h.setHash,args:arguments,queue:t}),!1):(h.busy(!0),n=h.extractState(e,!0),n&&!h.emulated.pushState?h.pushState(n.data,n.title,n.url,!1):h.getHash()!==e&&(h.bugs.setHash?(i=h.getPageUrl(),h.pushState(null,null,i+"#"+e,!1)):r.location.hash=e),h)},h.escapeHash=function(t){var n=h.normalizeHash(t);return n=e.encodeURIComponent(n),h.bugs.hashEscape||(n=n.replace(/\%21/g,"!").replace(/\%26/g,"&").replace(/\%3D/g,"=").replace(/\%3F/g,"?")),n},h.getHashByUrl=function(e){var t=String(e).replace(/([^#]*)#?([^#]*)#?(.*)/,"$2");return t=h.unescapeHash(t),t},h.setTitle=function(e){var t=e.title,n;t||(n=h.getStateByIndex(0),n&&n.url===e.url&&(t=n.title||h.options.initialTitle));try{r.getElementsByTagName("title")[0].innerHTML=t.replace("<","<").replace(">",">").replace(" & "," & ")}catch(i){}return r.title=t,h},h.queues=[],h.busy=function(e){typeof e!="undefined"?h.busy.flag=e:typeof h.busy.flag=="undefined"&&(h.busy.flag=!1);if(!h.busy.flag){u(h.busy.timeout);var t=function(){var e,n,r;if(h.busy.flag)return;for(e=h.queues.length-1;e>=0;--e){n=h.queues[e];if(n.length===0)continue;r=n.shift(),h.fireQueueItem(r),h.busy.timeout=o(t,h.options.busyDelay)}};h.busy.timeout=o(t,h.options.busyDelay)}return h.busy.flag},h.busy.flag=!1,h.fireQueueItem=function(e){return e.callback.apply(e.scope||h,e.args||[])},h.pushQueue=function(e){return h.queues[e.queue||0]=h.queues[e.queue||0]||[],h.queues[e.queue||0].push(e),h},h.queue=function(e,t){return typeof e=="function"&&(e={callback:e}),typeof t!="undefined"&&(e.queue=t),h.busy()?h.pushQueue(e):h.fireQueueItem(e),h},h.clearQueue=function(){return h.busy.flag=!1,h.queues=[],h},h.stateChanged=!1,h.doubleChecker=!1,h.doubleCheckComplete=function(){return h.stateChanged=!0,h.doubleCheckClear(),h},h.doubleCheckClear=function(){return h.doubleChecker&&(u(h.doubleChecker),h.doubleChecker=!1),h},h.doubleCheck=function(e){return h.stateChanged=!1,h.doubleCheckClear(),h.bugs.ieDoubleCheck&&(h.doubleChecker=o(function(){return h.doubleCheckClear(),h.stateChanged||e(),!0},h.options.doubleCheckInterval)),h},h.safariStatePoll=function(){var t=h.extractState(h.getLocationHref()),n;if(!h.isLastSavedState(t))return n=t,n||(n=h.createStateObject()),h.Adapter.trigger(e,"popstate"),h;return},h.back=function(e){return e!==!1&&h.busy()?(h.pushQueue({scope:h,callback:h.back,args:arguments,queue:e}),!1):(h.busy(!0),h.doubleCheck(function(){h.back(!1)}),p.go(-1),!0)},h.forward=function(e){return e!==!1&&h.busy()?(h.pushQueue({scope:h,callback:h.forward,args:arguments,queue:e}),!1):(h.busy(!0),h.doubleCheck(function(){h.forward(!1)}),p.go(1),!0)},h.go=function(e,t){var n;if(e>0)for(n=1;n<=e;++n)h.forward(t);else{if(!(e<0))throw new Error("History.go: History.go requires a positive or negative integer passed.");for(n=-1;n>=e;--n)h.back(t)}return h};if(h.emulated.pushState){var v=function(){};h.pushState=h.pushState||v,h.replaceState=h.replaceState||v}else h.onPopState=function(t,n){var r=!1,i=!1,s,o;return h.doubleCheckComplete(),s=h.getHash(),s?(o=h.extractState(s||h.getLocationHref(),!0),o?h.replaceState(o.data,o.title,o.url,!1):(h.Adapter.trigger(e,"anchorchange"),h.busy(!1)),h.expectedStateId=!1,!1):(r=h.Adapter.extractEventData("state",t,n)||!1,r?i=h.getStateById(r):h.expectedStateId?i=h.getStateById(h.expectedStateId):i=h.extractState(h.getLocationHref()),i||(i=h.createStateObject(null,null,h.getLocationHref())),h.expectedStateId=!1,h.isLastSavedState(i)?(h.busy(!1),!1):(h.storeState(i),h.saveState(i),h.setTitle(i),h.Adapter.trigger(e,"statechange"),h.busy(!1),!0))},h.Adapter.bind(e,"popstate",h.onPopState),h.pushState=function(t,n,r,i){if(h.getHashByUrl(r)&&h.emulated.pushState)throw new Error("History.js does not support states with fragement-identifiers (hashes/anchors).");if(i!==!1&&h.busy())return h.pushQueue({scope:h,callback:h.pushState,args:arguments,queue:i}),!1;h.busy(!0);var s=h.createStateObject(t,n,r);return h.isLastSavedState(s)?h.busy(!1):(h.storeState(s),h.expectedStateId=s.id,p.pushState(s.id,s.title,s.url),h.Adapter.trigger(e,"popstate")),!0},h.replaceState=function(t,n,r,i){if(h.getHashByUrl(r)&&h.emulated.pushState)throw new Error("History.js does not support states with fragement-identifiers (hashes/anchors).");if(i!==!1&&h.busy())return h.pushQueue({scope:h,callback:h.replaceState,args:arguments,queue:i}),!1;h.busy(!0);var s=h.createStateObject(t,n,r);return h.isLastSavedState(s)?h.busy(!1):(h.storeState(s),h.expectedStateId=s.id,p.replaceState(s.id,s.title,s.url),h.Adapter.trigger(e,"popstate")),!0};if(s){try{h.store=l.parse(s.getItem("History.store"))||{}}catch(m){h.store={}}h.normalizeStore()}else h.store={},h.normalizeStore();h.Adapter.bind(e,"unload",h.clearAllIntervals),h.saveState(h.storeState(h.extractState(h.getLocationHref(),!0))),s&&(h.onUnload=function(){var e,t,n;try{e=l.parse(s.getItem("History.store"))||{}}catch(r){e={}}e.idToState=e.idToState||{},e.urlToId=e.urlToId||{},e.stateToId=e.stateToId||{};for(t in h.idToState){if(!h.idToState.hasOwnProperty(t))continue;e.idToState[t]=h.idToState[t]}for(t in h.urlToId){if(!h.urlToId.hasOwnProperty(t))continue;e.urlToId[t]=h.urlToId[t]}for(t in h.stateToId){if(!h.stateToId.hasOwnProperty(t))continue;e.stateToId[t]=h.stateToId[t]}h.store=e,h.normalizeStore(),n=l.stringify(e);try{s.setItem("History.store",n)}catch(i){if(i.code!==DOMException.QUOTA_EXCEEDED_ERR)throw i;s.length&&(s.removeItem("History.store"),s.setItem("History.store",n))}},h.intervalList.push(a(h.onUnload,h.options.storeInterval)),h.Adapter.bind(e,"beforeunload",h.onUnload),h.Adapter.bind(e,"unload",h.onUnload));if(!h.emulated.pushState){h.bugs.safariPoll&&h.intervalList.push(a(h.safariStatePoll,h.options.safariPollInterval));if(i.vendor==="Apple Computer, Inc."||(i.appCodeName||"")==="Mozilla")h.Adapter.bind(e,"hashchange",function(){h.Adapter.trigger(e,"popstate")}),h.getHash()&&h.Adapter.onDomLoad(function(){h.Adapter.trigger(e,"hashchange")})}},(!h.options||!h.options.delayInit)&&h.init()}(window) \ No newline at end of file diff --git a/sites/all/themes/gui/materiobasetheme/bower_components/history.js/scripts/bundled/html5/native.history.js b/sites/all/themes/gui/materiobasetheme/bower_components/history.js/scripts/bundled/html5/native.history.js new file mode 100644 index 00000000..3da05c27 --- /dev/null +++ b/sites/all/themes/gui/materiobasetheme/bower_components/history.js/scripts/bundled/html5/native.history.js @@ -0,0 +1 @@ +(function(e,t){"use strict";var n=e.History=e.History||{};if(typeof n.Adapter!="undefined")throw new Error("History.js Adapter has already been loaded...");n.Adapter={handlers:{},_uid:1,uid:function(e){return e._uid||(e._uid=n.Adapter._uid++)},bind:function(e,t,r){var i=n.Adapter.uid(e);n.Adapter.handlers[i]=n.Adapter.handlers[i]||{},n.Adapter.handlers[i][t]=n.Adapter.handlers[i][t]||[],n.Adapter.handlers[i][t].push(r),e["on"+t]=function(e,t){return function(r){n.Adapter.trigger(e,t,r)}}(e,t)},trigger:function(e,t,r){r=r||{};var i=n.Adapter.uid(e),s,o;n.Adapter.handlers[i]=n.Adapter.handlers[i]||{},n.Adapter.handlers[i][t]=n.Adapter.handlers[i][t]||[];for(s=0,o=n.Adapter.handlers[i][t].length;s")&&n[0]);return e>4?e:!1}();return e},h.isInternetExplorer=function(){var e=h.isInternetExplorer.cached=typeof h.isInternetExplorer.cached!="undefined"?h.isInternetExplorer.cached:Boolean(h.getInternetExplorerMajorVersion());return e},h.options.html4Mode?h.emulated={pushState:!0,hashChange:!0}:h.emulated={pushState:!Boolean(e.history&&e.history.pushState&&e.history.replaceState&&!/ Mobile\/([1-7][a-z]|(8([abcde]|f(1[0-8]))))/i.test(i.userAgent)&&!/AppleWebKit\/5([0-2]|3[0-2])/i.test(i.userAgent)),hashChange:Boolean(!("onhashchange"in e||"onhashchange"in r)||h.isInternetExplorer()&&h.getInternetExplorerMajorVersion()<8)},h.enabled=!h.emulated.pushState,h.bugs={setHash:Boolean(!h.emulated.pushState&&i.vendor==="Apple Computer, Inc."&&/AppleWebKit\/5([0-2]|3[0-3])/.test(i.userAgent)),safariPoll:Boolean(!h.emulated.pushState&&i.vendor==="Apple Computer, Inc."&&/AppleWebKit\/5([0-2]|3[0-3])/.test(i.userAgent)),ieDoubleCheck:Boolean(h.isInternetExplorer()&&h.getInternetExplorerMajorVersion()<8),hashEscape:Boolean(h.isInternetExplorer()&&h.getInternetExplorerMajorVersion()<7)},h.isEmptyObject=function(e){for(var t in e)if(e.hasOwnProperty(t))return!1;return!0},h.cloneObject=function(e){var t,n;return e?(t=l.stringify(e),n=l.parse(t)):n={},n},h.getRootUrl=function(){var e=r.location.protocol+"//"+(r.location.hostname||r.location.host);if(r.location.port||!1)e+=":"+r.location.port;return e+="/",e},h.getBaseHref=function(){var e=r.getElementsByTagName("base"),t=null,n="";return e.length===1&&(t=e[0],n=t.href.replace(/[^\/]+$/,"")),n=n.replace(/\/+$/,""),n&&(n+="/"),n},h.getBaseUrl=function(){var e=h.getBaseHref()||h.getBasePageUrl()||h.getRootUrl();return e},h.getPageUrl=function(){var e=h.getState(!1,!1),t=(e||{}).url||h.getLocationHref(),n;return n=t.replace(/\/+$/,"").replace(/[^\/]+$/,function(e,t,n){return/\./.test(e)?e:e+"/"}),n},h.getBasePageUrl=function(){var e=h.getLocationHref().replace(/[#\?].*/,"").replace(/[^\/]+$/,function(e,t,n){return/[^\/]$/.test(e)?"":e}).replace(/\/+$/,"")+"/";return e},h.getFullUrl=function(e,t){var n=e,r=e.substring(0,1);return t=typeof t=="undefined"?!0:t,/[a-z]+\:\/\//.test(e)||(r==="/"?n=h.getRootUrl()+e.replace(/^\/+/,""):r==="#"?n=h.getPageUrl().replace(/#.*/,"")+e:r==="?"?n=h.getPageUrl().replace(/[\?#].*/,"")+e:t?n=h.getBaseUrl()+e.replace(/^(\.\/)+/,""):n=h.getBasePageUrl()+e.replace(/^(\.\/)+/,"")),n.replace(/\#$/,"")},h.getShortUrl=function(e){var t=e,n=h.getBaseUrl(),r=h.getRootUrl();return h.emulated.pushState&&(t=t.replace(n,"")),t=t.replace(r,"/"),h.isTraditionalAnchor(t)&&(t="./"+t),t=t.replace(/^(\.\/)+/g,"./").replace(/\#$/,""),t},h.getLocationHref=function(e){return e=e||r,e.URL===e.location.href?e.location.href:e.location.href===decodeURIComponent(e.URL)?e.URL:e.location.hash&&decodeURIComponent(e.location.href.replace(/^[^#]+/,""))===e.location.hash?e.location.href:e.URL.indexOf("#")==-1&&e.location.href.indexOf("#")!=-1?e.location.href:e.URL||e.location.href},h.store={},h.idToState=h.idToState||{},h.stateToId=h.stateToId||{},h.urlToId=h.urlToId||{},h.storedStates=h.storedStates||[],h.savedStates=h.savedStates||[],h.normalizeStore=function(){h.store.idToState=h.store.idToState||{},h.store.urlToId=h.store.urlToId||{},h.store.stateToId=h.store.stateToId||{}},h.getState=function(e,t){typeof e=="undefined"&&(e=!0),typeof t=="undefined"&&(t=!0);var n=h.getLastSavedState();return!n&&t&&(n=h.createStateObject()),e&&(n=h.cloneObject(n),n.url=n.cleanUrl||n.url),n},h.getIdByState=function(e){var t=h.extractId(e.url),n;if(!t){n=h.getStateString(e);if(typeof h.stateToId[n]!="undefined")t=h.stateToId[n];else if(typeof h.store.stateToId[n]!="undefined")t=h.store.stateToId[n];else{for(;;){t=(new Date).getTime()+String(Math.random()).replace(/\D/g,"");if(typeof h.idToState[t]=="undefined"&&typeof h.store.idToState[t]=="undefined")break}h.stateToId[n]=t,h.idToState[t]=e}}return t},h.normalizeState=function(e){var t,n;if(!e||typeof e!="object")e={};if(typeof e.normalized!="undefined")return e;if(!e.data||typeof e.data!="object")e.data={};return t={},t.normalized=!0,t.title=e.title||"",t.url=h.getFullUrl(e.url?e.url:h.getLocationHref()),t.hash=h.getShortUrl(t.url),t.data=h.cloneObject(e.data),t.id=h.getIdByState(t),t.cleanUrl=t.url.replace(/\??\&_suid.*/,""),t.url=t.cleanUrl,n=!h.isEmptyObject(t.data),(t.title||n)&&h.options.disableSuid!==!0&&(t.hash=h.getShortUrl(t.url).replace(/\??\&_suid.*/,""),/\?/.test(t.hash)||(t.hash+="?"),t.hash+="&_suid="+t.id),t.hashedUrl=h.getFullUrl(t.hash),(h.emulated.pushState||h.bugs.safariPoll)&&h.hasUrlDuplicate(t)&&(t.url=t.hashedUrl),t},h.createStateObject=function(e,t,n){var r={data:e,title:t,url:n};return r=h.normalizeState(r),r},h.getStateById=function(e){e=String(e);var n=h.idToState[e]||h.store.idToState[e]||t;return n},h.getStateString=function(e){var t,n,r;return t=h.normalizeState(e),n={data:t.data,title:e.title,url:e.url},r=l.stringify(n),r},h.getStateId=function(e){var t,n;return t=h.normalizeState(e),n=t.id,n},h.getHashByState=function(e){var t,n;return t=h.normalizeState(e),n=t.hash,n},h.extractId=function(e){var t,n,r,i;return e.indexOf("#")!=-1?i=e.split("#")[0]:i=e,n=/(.*)\&_suid=([0-9]+)$/.exec(i),r=n?n[1]||e:e,t=n?String(n[2]||""):"",t||!1},h.isTraditionalAnchor=function(e){var t=!/[\/\?\.]/.test(e);return t},h.extractState=function(e,t){var n=null,r,i;return t=t||!1,r=h.extractId(e),r&&(n=h.getStateById(r)),n||(i=h.getFullUrl(e),r=h.getIdByUrl(i)||!1,r&&(n=h.getStateById(r)),!n&&t&&!h.isTraditionalAnchor(e)&&(n=h.createStateObject(null,null,i))),n},h.getIdByUrl=function(e){var n=h.urlToId[e]||h.store.urlToId[e]||t;return n},h.getLastSavedState=function(){return h.savedStates[h.savedStates.length-1]||t},h.getLastStoredState=function(){return h.storedStates[h.storedStates.length-1]||t},h.hasUrlDuplicate=function(e){var t=!1,n;return n=h.extractState(e.url),t=n&&n.id!==e.id,t},h.storeState=function(e){return h.urlToId[e.url]=e.id,h.storedStates.push(h.cloneObject(e)),e},h.isLastSavedState=function(e){var t=!1,n,r,i;return h.savedStates.length&&(n=e.id,r=h.getLastSavedState(),i=r.id,t=n===i),t},h.saveState=function(e){return h.isLastSavedState(e)?!1:(h.savedStates.push(h.cloneObject(e)),!0)},h.getStateByIndex=function(e){var t=null;return typeof e=="undefined"?t=h.savedStates[h.savedStates.length-1]:e<0?t=h.savedStates[h.savedStates.length+e]:t=h.savedStates[e],t},h.getCurrentIndex=function(){var e=null;return h.savedStates.length<1?e=0:e=h.savedStates.length-1,e},h.getHash=function(e){var t=h.getLocationHref(e),n;return n=h.getHashByUrl(t),n},h.unescapeHash=function(e){var t=h.normalizeHash(e);return t=decodeURIComponent(t),t},h.normalizeHash=function(e){var t=e.replace(/[^#]*#/,"").replace(/#.*/,"");return t},h.setHash=function(e,t){var n,i;return t!==!1&&h.busy()?(h.pushQueue({scope:h,callback:h.setHash,args:arguments,queue:t}),!1):(h.busy(!0),n=h.extractState(e,!0),n&&!h.emulated.pushState?h.pushState(n.data,n.title,n.url,!1):h.getHash()!==e&&(h.bugs.setHash?(i=h.getPageUrl(),h.pushState(null,null,i+"#"+e,!1)):r.location.hash=e),h)},h.escapeHash=function(t){var n=h.normalizeHash(t);return n=e.encodeURIComponent(n),h.bugs.hashEscape||(n=n.replace(/\%21/g,"!").replace(/\%26/g,"&").replace(/\%3D/g,"=").replace(/\%3F/g,"?")),n},h.getHashByUrl=function(e){var t=String(e).replace(/([^#]*)#?([^#]*)#?(.*)/,"$2");return t=h.unescapeHash(t),t},h.setTitle=function(e){var t=e.title,n;t||(n=h.getStateByIndex(0),n&&n.url===e.url&&(t=n.title||h.options.initialTitle));try{r.getElementsByTagName("title")[0].innerHTML=t.replace("<","<").replace(">",">").replace(" & "," & ")}catch(i){}return r.title=t,h},h.queues=[],h.busy=function(e){typeof e!="undefined"?h.busy.flag=e:typeof h.busy.flag=="undefined"&&(h.busy.flag=!1);if(!h.busy.flag){u(h.busy.timeout);var t=function(){var e,n,r;if(h.busy.flag)return;for(e=h.queues.length-1;e>=0;--e){n=h.queues[e];if(n.length===0)continue;r=n.shift(),h.fireQueueItem(r),h.busy.timeout=o(t,h.options.busyDelay)}};h.busy.timeout=o(t,h.options.busyDelay)}return h.busy.flag},h.busy.flag=!1,h.fireQueueItem=function(e){return e.callback.apply(e.scope||h,e.args||[])},h.pushQueue=function(e){return h.queues[e.queue||0]=h.queues[e.queue||0]||[],h.queues[e.queue||0].push(e),h},h.queue=function(e,t){return typeof e=="function"&&(e={callback:e}),typeof t!="undefined"&&(e.queue=t),h.busy()?h.pushQueue(e):h.fireQueueItem(e),h},h.clearQueue=function(){return h.busy.flag=!1,h.queues=[],h},h.stateChanged=!1,h.doubleChecker=!1,h.doubleCheckComplete=function(){return h.stateChanged=!0,h.doubleCheckClear(),h},h.doubleCheckClear=function(){return h.doubleChecker&&(u(h.doubleChecker),h.doubleChecker=!1),h},h.doubleCheck=function(e){return h.stateChanged=!1,h.doubleCheckClear(),h.bugs.ieDoubleCheck&&(h.doubleChecker=o(function(){return h.doubleCheckClear(),h.stateChanged||e(),!0},h.options.doubleCheckInterval)),h},h.safariStatePoll=function(){var t=h.extractState(h.getLocationHref()),n;if(!h.isLastSavedState(t))return n=t,n||(n=h.createStateObject()),h.Adapter.trigger(e,"popstate"),h;return},h.back=function(e){return e!==!1&&h.busy()?(h.pushQueue({scope:h,callback:h.back,args:arguments,queue:e}),!1):(h.busy(!0),h.doubleCheck(function(){h.back(!1)}),p.go(-1),!0)},h.forward=function(e){return e!==!1&&h.busy()?(h.pushQueue({scope:h,callback:h.forward,args:arguments,queue:e}),!1):(h.busy(!0),h.doubleCheck(function(){h.forward(!1)}),p.go(1),!0)},h.go=function(e,t){var n;if(e>0)for(n=1;n<=e;++n)h.forward(t);else{if(!(e<0))throw new Error("History.go: History.go requires a positive or negative integer passed.");for(n=-1;n>=e;--n)h.back(t)}return h};if(h.emulated.pushState){var v=function(){};h.pushState=h.pushState||v,h.replaceState=h.replaceState||v}else h.onPopState=function(t,n){var r=!1,i=!1,s,o;return h.doubleCheckComplete(),s=h.getHash(),s?(o=h.extractState(s||h.getLocationHref(),!0),o?h.replaceState(o.data,o.title,o.url,!1):(h.Adapter.trigger(e,"anchorchange"),h.busy(!1)),h.expectedStateId=!1,!1):(r=h.Adapter.extractEventData("state",t,n)||!1,r?i=h.getStateById(r):h.expectedStateId?i=h.getStateById(h.expectedStateId):i=h.extractState(h.getLocationHref()),i||(i=h.createStateObject(null,null,h.getLocationHref())),h.expectedStateId=!1,h.isLastSavedState(i)?(h.busy(!1),!1):(h.storeState(i),h.saveState(i),h.setTitle(i),h.Adapter.trigger(e,"statechange"),h.busy(!1),!0))},h.Adapter.bind(e,"popstate",h.onPopState),h.pushState=function(t,n,r,i){if(h.getHashByUrl(r)&&h.emulated.pushState)throw new Error("History.js does not support states with fragement-identifiers (hashes/anchors).");if(i!==!1&&h.busy())return h.pushQueue({scope:h,callback:h.pushState,args:arguments,queue:i}),!1;h.busy(!0);var s=h.createStateObject(t,n,r);return h.isLastSavedState(s)?h.busy(!1):(h.storeState(s),h.expectedStateId=s.id,p.pushState(s.id,s.title,s.url),h.Adapter.trigger(e,"popstate")),!0},h.replaceState=function(t,n,r,i){if(h.getHashByUrl(r)&&h.emulated.pushState)throw new Error("History.js does not support states with fragement-identifiers (hashes/anchors).");if(i!==!1&&h.busy())return h.pushQueue({scope:h,callback:h.replaceState,args:arguments,queue:i}),!1;h.busy(!0);var s=h.createStateObject(t,n,r);return h.isLastSavedState(s)?h.busy(!1):(h.storeState(s),h.expectedStateId=s.id,p.replaceState(s.id,s.title,s.url),h.Adapter.trigger(e,"popstate")),!0};if(s){try{h.store=l.parse(s.getItem("History.store"))||{}}catch(m){h.store={}}h.normalizeStore()}else h.store={},h.normalizeStore();h.Adapter.bind(e,"unload",h.clearAllIntervals),h.saveState(h.storeState(h.extractState(h.getLocationHref(),!0))),s&&(h.onUnload=function(){var e,t,n;try{e=l.parse(s.getItem("History.store"))||{}}catch(r){e={}}e.idToState=e.idToState||{},e.urlToId=e.urlToId||{},e.stateToId=e.stateToId||{};for(t in h.idToState){if(!h.idToState.hasOwnProperty(t))continue;e.idToState[t]=h.idToState[t]}for(t in h.urlToId){if(!h.urlToId.hasOwnProperty(t))continue;e.urlToId[t]=h.urlToId[t]}for(t in h.stateToId){if(!h.stateToId.hasOwnProperty(t))continue;e.stateToId[t]=h.stateToId[t]}h.store=e,h.normalizeStore(),n=l.stringify(e);try{s.setItem("History.store",n)}catch(i){if(i.code!==DOMException.QUOTA_EXCEEDED_ERR)throw i;s.length&&(s.removeItem("History.store"),s.setItem("History.store",n))}},h.intervalList.push(a(h.onUnload,h.options.storeInterval)),h.Adapter.bind(e,"beforeunload",h.onUnload),h.Adapter.bind(e,"unload",h.onUnload));if(!h.emulated.pushState){h.bugs.safariPoll&&h.intervalList.push(a(h.safariStatePoll,h.options.safariPollInterval));if(i.vendor==="Apple Computer, Inc."||(i.appCodeName||"")==="Mozilla")h.Adapter.bind(e,"hashchange",function(){h.Adapter.trigger(e,"popstate")}),h.getHash()&&h.Adapter.onDomLoad(function(){h.Adapter.trigger(e,"hashchange")})}},(!h.options||!h.options.delayInit)&&h.init()}(window) \ No newline at end of file diff --git a/sites/all/themes/gui/materiobasetheme/bower_components/history.js/scripts/bundled/html5/right.history.js b/sites/all/themes/gui/materiobasetheme/bower_components/history.js/scripts/bundled/html5/right.history.js new file mode 100644 index 00000000..80cf820f --- /dev/null +++ b/sites/all/themes/gui/materiobasetheme/bower_components/history.js/scripts/bundled/html5/right.history.js @@ -0,0 +1 @@ +(function(e,t){"use strict";var n=e.History=e.History||{},r=e.document,i=e.RightJS,s=i.$;if(typeof n.Adapter!="undefined")throw new Error("History.js Adapter has already been loaded...");n.Adapter={bind:function(e,t,n){s(e).on(t,n)},trigger:function(e,t,n){s(e).fire(t,n)},extractEventData:function(e,n){var r=n&&n._&&n._[e]||t;return r},onDomLoad:function(e){s(r).onReady(e)}},typeof n.init!="undefined"&&n.init()})(window),function(e,t){"use strict";var n=e.console||t,r=e.document,i=e.navigator,s=e.sessionStorage||!1,o=e.setTimeout,u=e.clearTimeout,a=e.setInterval,f=e.clearInterval,l=e.JSON,c=e.alert,h=e.History=e.History||{},p=e.history;try{s.setItem("TEST","1"),s.removeItem("TEST")}catch(d){s=!1}l.stringify=l.stringify||l.encode,l.parse=l.parse||l.decode;if(typeof h.init!="undefined")throw new Error("History.js Core has already been loaded...");h.init=function(e){return typeof h.Adapter=="undefined"?!1:(typeof h.initCore!="undefined"&&h.initCore(),typeof h.initHtml4!="undefined"&&h.initHtml4(),!0)},h.initCore=function(d){if(typeof h.initCore.initialized!="undefined")return!1;h.initCore.initialized=!0,h.options=h.options||{},h.options.hashChangeInterval=h.options.hashChangeInterval||100,h.options.safariPollInterval=h.options.safariPollInterval||500,h.options.doubleCheckInterval=h.options.doubleCheckInterval||500,h.options.disableSuid=h.options.disableSuid||!1,h.options.storeInterval=h.options.storeInterval||1e3,h.options.busyDelay=h.options.busyDelay||250,h.options.debug=h.options.debug||!1,h.options.initialTitle=h.options.initialTitle||r.title,h.options.html4Mode=h.options.html4Mode||!1,h.options.delayInit=h.options.delayInit||!1,h.intervalList=[],h.clearAllIntervals=function(){var e,t=h.intervalList;if(typeof t!="undefined"&&t!==null){for(e=0;e")&&n[0]);return e>4?e:!1}();return e},h.isInternetExplorer=function(){var e=h.isInternetExplorer.cached=typeof h.isInternetExplorer.cached!="undefined"?h.isInternetExplorer.cached:Boolean(h.getInternetExplorerMajorVersion());return e},h.options.html4Mode?h.emulated={pushState:!0,hashChange:!0}:h.emulated={pushState:!Boolean(e.history&&e.history.pushState&&e.history.replaceState&&!/ Mobile\/([1-7][a-z]|(8([abcde]|f(1[0-8]))))/i.test(i.userAgent)&&!/AppleWebKit\/5([0-2]|3[0-2])/i.test(i.userAgent)),hashChange:Boolean(!("onhashchange"in e||"onhashchange"in r)||h.isInternetExplorer()&&h.getInternetExplorerMajorVersion()<8)},h.enabled=!h.emulated.pushState,h.bugs={setHash:Boolean(!h.emulated.pushState&&i.vendor==="Apple Computer, Inc."&&/AppleWebKit\/5([0-2]|3[0-3])/.test(i.userAgent)),safariPoll:Boolean(!h.emulated.pushState&&i.vendor==="Apple Computer, Inc."&&/AppleWebKit\/5([0-2]|3[0-3])/.test(i.userAgent)),ieDoubleCheck:Boolean(h.isInternetExplorer()&&h.getInternetExplorerMajorVersion()<8),hashEscape:Boolean(h.isInternetExplorer()&&h.getInternetExplorerMajorVersion()<7)},h.isEmptyObject=function(e){for(var t in e)if(e.hasOwnProperty(t))return!1;return!0},h.cloneObject=function(e){var t,n;return e?(t=l.stringify(e),n=l.parse(t)):n={},n},h.getRootUrl=function(){var e=r.location.protocol+"//"+(r.location.hostname||r.location.host);if(r.location.port||!1)e+=":"+r.location.port;return e+="/",e},h.getBaseHref=function(){var e=r.getElementsByTagName("base"),t=null,n="";return e.length===1&&(t=e[0],n=t.href.replace(/[^\/]+$/,"")),n=n.replace(/\/+$/,""),n&&(n+="/"),n},h.getBaseUrl=function(){var e=h.getBaseHref()||h.getBasePageUrl()||h.getRootUrl();return e},h.getPageUrl=function(){var e=h.getState(!1,!1),t=(e||{}).url||h.getLocationHref(),n;return n=t.replace(/\/+$/,"").replace(/[^\/]+$/,function(e,t,n){return/\./.test(e)?e:e+"/"}),n},h.getBasePageUrl=function(){var e=h.getLocationHref().replace(/[#\?].*/,"").replace(/[^\/]+$/,function(e,t,n){return/[^\/]$/.test(e)?"":e}).replace(/\/+$/,"")+"/";return e},h.getFullUrl=function(e,t){var n=e,r=e.substring(0,1);return t=typeof t=="undefined"?!0:t,/[a-z]+\:\/\//.test(e)||(r==="/"?n=h.getRootUrl()+e.replace(/^\/+/,""):r==="#"?n=h.getPageUrl().replace(/#.*/,"")+e:r==="?"?n=h.getPageUrl().replace(/[\?#].*/,"")+e:t?n=h.getBaseUrl()+e.replace(/^(\.\/)+/,""):n=h.getBasePageUrl()+e.replace(/^(\.\/)+/,"")),n.replace(/\#$/,"")},h.getShortUrl=function(e){var t=e,n=h.getBaseUrl(),r=h.getRootUrl();return h.emulated.pushState&&(t=t.replace(n,"")),t=t.replace(r,"/"),h.isTraditionalAnchor(t)&&(t="./"+t),t=t.replace(/^(\.\/)+/g,"./").replace(/\#$/,""),t},h.getLocationHref=function(e){return e=e||r,e.URL===e.location.href?e.location.href:e.location.href===decodeURIComponent(e.URL)?e.URL:e.location.hash&&decodeURIComponent(e.location.href.replace(/^[^#]+/,""))===e.location.hash?e.location.href:e.URL.indexOf("#")==-1&&e.location.href.indexOf("#")!=-1?e.location.href:e.URL||e.location.href},h.store={},h.idToState=h.idToState||{},h.stateToId=h.stateToId||{},h.urlToId=h.urlToId||{},h.storedStates=h.storedStates||[],h.savedStates=h.savedStates||[],h.normalizeStore=function(){h.store.idToState=h.store.idToState||{},h.store.urlToId=h.store.urlToId||{},h.store.stateToId=h.store.stateToId||{}},h.getState=function(e,t){typeof e=="undefined"&&(e=!0),typeof t=="undefined"&&(t=!0);var n=h.getLastSavedState();return!n&&t&&(n=h.createStateObject()),e&&(n=h.cloneObject(n),n.url=n.cleanUrl||n.url),n},h.getIdByState=function(e){var t=h.extractId(e.url),n;if(!t){n=h.getStateString(e);if(typeof h.stateToId[n]!="undefined")t=h.stateToId[n];else if(typeof h.store.stateToId[n]!="undefined")t=h.store.stateToId[n];else{for(;;){t=(new Date).getTime()+String(Math.random()).replace(/\D/g,"");if(typeof h.idToState[t]=="undefined"&&typeof h.store.idToState[t]=="undefined")break}h.stateToId[n]=t,h.idToState[t]=e}}return t},h.normalizeState=function(e){var t,n;if(!e||typeof e!="object")e={};if(typeof e.normalized!="undefined")return e;if(!e.data||typeof e.data!="object")e.data={};return t={},t.normalized=!0,t.title=e.title||"",t.url=h.getFullUrl(e.url?e.url:h.getLocationHref()),t.hash=h.getShortUrl(t.url),t.data=h.cloneObject(e.data),t.id=h.getIdByState(t),t.cleanUrl=t.url.replace(/\??\&_suid.*/,""),t.url=t.cleanUrl,n=!h.isEmptyObject(t.data),(t.title||n)&&h.options.disableSuid!==!0&&(t.hash=h.getShortUrl(t.url).replace(/\??\&_suid.*/,""),/\?/.test(t.hash)||(t.hash+="?"),t.hash+="&_suid="+t.id),t.hashedUrl=h.getFullUrl(t.hash),(h.emulated.pushState||h.bugs.safariPoll)&&h.hasUrlDuplicate(t)&&(t.url=t.hashedUrl),t},h.createStateObject=function(e,t,n){var r={data:e,title:t,url:n};return r=h.normalizeState(r),r},h.getStateById=function(e){e=String(e);var n=h.idToState[e]||h.store.idToState[e]||t;return n},h.getStateString=function(e){var t,n,r;return t=h.normalizeState(e),n={data:t.data,title:e.title,url:e.url},r=l.stringify(n),r},h.getStateId=function(e){var t,n;return t=h.normalizeState(e),n=t.id,n},h.getHashByState=function(e){var t,n;return t=h.normalizeState(e),n=t.hash,n},h.extractId=function(e){var t,n,r,i;return e.indexOf("#")!=-1?i=e.split("#")[0]:i=e,n=/(.*)\&_suid=([0-9]+)$/.exec(i),r=n?n[1]||e:e,t=n?String(n[2]||""):"",t||!1},h.isTraditionalAnchor=function(e){var t=!/[\/\?\.]/.test(e);return t},h.extractState=function(e,t){var n=null,r,i;return t=t||!1,r=h.extractId(e),r&&(n=h.getStateById(r)),n||(i=h.getFullUrl(e),r=h.getIdByUrl(i)||!1,r&&(n=h.getStateById(r)),!n&&t&&!h.isTraditionalAnchor(e)&&(n=h.createStateObject(null,null,i))),n},h.getIdByUrl=function(e){var n=h.urlToId[e]||h.store.urlToId[e]||t;return n},h.getLastSavedState=function(){return h.savedStates[h.savedStates.length-1]||t},h.getLastStoredState=function(){return h.storedStates[h.storedStates.length-1]||t},h.hasUrlDuplicate=function(e){var t=!1,n;return n=h.extractState(e.url),t=n&&n.id!==e.id,t},h.storeState=function(e){return h.urlToId[e.url]=e.id,h.storedStates.push(h.cloneObject(e)),e},h.isLastSavedState=function(e){var t=!1,n,r,i;return h.savedStates.length&&(n=e.id,r=h.getLastSavedState(),i=r.id,t=n===i),t},h.saveState=function(e){return h.isLastSavedState(e)?!1:(h.savedStates.push(h.cloneObject(e)),!0)},h.getStateByIndex=function(e){var t=null;return typeof e=="undefined"?t=h.savedStates[h.savedStates.length-1]:e<0?t=h.savedStates[h.savedStates.length+e]:t=h.savedStates[e],t},h.getCurrentIndex=function(){var e=null;return h.savedStates.length<1?e=0:e=h.savedStates.length-1,e},h.getHash=function(e){var t=h.getLocationHref(e),n;return n=h.getHashByUrl(t),n},h.unescapeHash=function(e){var t=h.normalizeHash(e);return t=decodeURIComponent(t),t},h.normalizeHash=function(e){var t=e.replace(/[^#]*#/,"").replace(/#.*/,"");return t},h.setHash=function(e,t){var n,i;return t!==!1&&h.busy()?(h.pushQueue({scope:h,callback:h.setHash,args:arguments,queue:t}),!1):(h.busy(!0),n=h.extractState(e,!0),n&&!h.emulated.pushState?h.pushState(n.data,n.title,n.url,!1):h.getHash()!==e&&(h.bugs.setHash?(i=h.getPageUrl(),h.pushState(null,null,i+"#"+e,!1)):r.location.hash=e),h)},h.escapeHash=function(t){var n=h.normalizeHash(t);return n=e.encodeURIComponent(n),h.bugs.hashEscape||(n=n.replace(/\%21/g,"!").replace(/\%26/g,"&").replace(/\%3D/g,"=").replace(/\%3F/g,"?")),n},h.getHashByUrl=function(e){var t=String(e).replace(/([^#]*)#?([^#]*)#?(.*)/,"$2");return t=h.unescapeHash(t),t},h.setTitle=function(e){var t=e.title,n;t||(n=h.getStateByIndex(0),n&&n.url===e.url&&(t=n.title||h.options.initialTitle));try{r.getElementsByTagName("title")[0].innerHTML=t.replace("<","<").replace(">",">").replace(" & "," & ")}catch(i){}return r.title=t,h},h.queues=[],h.busy=function(e){typeof e!="undefined"?h.busy.flag=e:typeof h.busy.flag=="undefined"&&(h.busy.flag=!1);if(!h.busy.flag){u(h.busy.timeout);var t=function(){var e,n,r;if(h.busy.flag)return;for(e=h.queues.length-1;e>=0;--e){n=h.queues[e];if(n.length===0)continue;r=n.shift(),h.fireQueueItem(r),h.busy.timeout=o(t,h.options.busyDelay)}};h.busy.timeout=o(t,h.options.busyDelay)}return h.busy.flag},h.busy.flag=!1,h.fireQueueItem=function(e){return e.callback.apply(e.scope||h,e.args||[])},h.pushQueue=function(e){return h.queues[e.queue||0]=h.queues[e.queue||0]||[],h.queues[e.queue||0].push(e),h},h.queue=function(e,t){return typeof e=="function"&&(e={callback:e}),typeof t!="undefined"&&(e.queue=t),h.busy()?h.pushQueue(e):h.fireQueueItem(e),h},h.clearQueue=function(){return h.busy.flag=!1,h.queues=[],h},h.stateChanged=!1,h.doubleChecker=!1,h.doubleCheckComplete=function(){return h.stateChanged=!0,h.doubleCheckClear(),h},h.doubleCheckClear=function(){return h.doubleChecker&&(u(h.doubleChecker),h.doubleChecker=!1),h},h.doubleCheck=function(e){return h.stateChanged=!1,h.doubleCheckClear(),h.bugs.ieDoubleCheck&&(h.doubleChecker=o(function(){return h.doubleCheckClear(),h.stateChanged||e(),!0},h.options.doubleCheckInterval)),h},h.safariStatePoll=function(){var t=h.extractState(h.getLocationHref()),n;if(!h.isLastSavedState(t))return n=t,n||(n=h.createStateObject()),h.Adapter.trigger(e,"popstate"),h;return},h.back=function(e){return e!==!1&&h.busy()?(h.pushQueue({scope:h,callback:h.back,args:arguments,queue:e}),!1):(h.busy(!0),h.doubleCheck(function(){h.back(!1)}),p.go(-1),!0)},h.forward=function(e){return e!==!1&&h.busy()?(h.pushQueue({scope:h,callback:h.forward,args:arguments,queue:e}),!1):(h.busy(!0),h.doubleCheck(function(){h.forward(!1)}),p.go(1),!0)},h.go=function(e,t){var n;if(e>0)for(n=1;n<=e;++n)h.forward(t);else{if(!(e<0))throw new Error("History.go: History.go requires a positive or negative integer passed.");for(n=-1;n>=e;--n)h.back(t)}return h};if(h.emulated.pushState){var v=function(){};h.pushState=h.pushState||v,h.replaceState=h.replaceState||v}else h.onPopState=function(t,n){var r=!1,i=!1,s,o;return h.doubleCheckComplete(),s=h.getHash(),s?(o=h.extractState(s||h.getLocationHref(),!0),o?h.replaceState(o.data,o.title,o.url,!1):(h.Adapter.trigger(e,"anchorchange"),h.busy(!1)),h.expectedStateId=!1,!1):(r=h.Adapter.extractEventData("state",t,n)||!1,r?i=h.getStateById(r):h.expectedStateId?i=h.getStateById(h.expectedStateId):i=h.extractState(h.getLocationHref()),i||(i=h.createStateObject(null,null,h.getLocationHref())),h.expectedStateId=!1,h.isLastSavedState(i)?(h.busy(!1),!1):(h.storeState(i),h.saveState(i),h.setTitle(i),h.Adapter.trigger(e,"statechange"),h.busy(!1),!0))},h.Adapter.bind(e,"popstate",h.onPopState),h.pushState=function(t,n,r,i){if(h.getHashByUrl(r)&&h.emulated.pushState)throw new Error("History.js does not support states with fragement-identifiers (hashes/anchors).");if(i!==!1&&h.busy())return h.pushQueue({scope:h,callback:h.pushState,args:arguments,queue:i}),!1;h.busy(!0);var s=h.createStateObject(t,n,r);return h.isLastSavedState(s)?h.busy(!1):(h.storeState(s),h.expectedStateId=s.id,p.pushState(s.id,s.title,s.url),h.Adapter.trigger(e,"popstate")),!0},h.replaceState=function(t,n,r,i){if(h.getHashByUrl(r)&&h.emulated.pushState)throw new Error("History.js does not support states with fragement-identifiers (hashes/anchors).");if(i!==!1&&h.busy())return h.pushQueue({scope:h,callback:h.replaceState,args:arguments,queue:i}),!1;h.busy(!0);var s=h.createStateObject(t,n,r);return h.isLastSavedState(s)?h.busy(!1):(h.storeState(s),h.expectedStateId=s.id,p.replaceState(s.id,s.title,s.url),h.Adapter.trigger(e,"popstate")),!0};if(s){try{h.store=l.parse(s.getItem("History.store"))||{}}catch(m){h.store={}}h.normalizeStore()}else h.store={},h.normalizeStore();h.Adapter.bind(e,"unload",h.clearAllIntervals),h.saveState(h.storeState(h.extractState(h.getLocationHref(),!0))),s&&(h.onUnload=function(){var e,t,n;try{e=l.parse(s.getItem("History.store"))||{}}catch(r){e={}}e.idToState=e.idToState||{},e.urlToId=e.urlToId||{},e.stateToId=e.stateToId||{};for(t in h.idToState){if(!h.idToState.hasOwnProperty(t))continue;e.idToState[t]=h.idToState[t]}for(t in h.urlToId){if(!h.urlToId.hasOwnProperty(t))continue;e.urlToId[t]=h.urlToId[t]}for(t in h.stateToId){if(!h.stateToId.hasOwnProperty(t))continue;e.stateToId[t]=h.stateToId[t]}h.store=e,h.normalizeStore(),n=l.stringify(e);try{s.setItem("History.store",n)}catch(i){if(i.code!==DOMException.QUOTA_EXCEEDED_ERR)throw i;s.length&&(s.removeItem("History.store"),s.setItem("History.store",n))}},h.intervalList.push(a(h.onUnload,h.options.storeInterval)),h.Adapter.bind(e,"beforeunload",h.onUnload),h.Adapter.bind(e,"unload",h.onUnload));if(!h.emulated.pushState){h.bugs.safariPoll&&h.intervalList.push(a(h.safariStatePoll,h.options.safariPollInterval));if(i.vendor==="Apple Computer, Inc."||(i.appCodeName||"")==="Mozilla")h.Adapter.bind(e,"hashchange",function(){h.Adapter.trigger(e,"popstate")}),h.getHash()&&h.Adapter.onDomLoad(function(){h.Adapter.trigger(e,"hashchange")})}},(!h.options||!h.options.delayInit)&&h.init()}(window) \ No newline at end of file diff --git a/sites/all/themes/gui/materiobasetheme/bower_components/history.js/scripts/bundled/html5/zepto.history.js b/sites/all/themes/gui/materiobasetheme/bower_components/history.js/scripts/bundled/html5/zepto.history.js new file mode 100644 index 00000000..07b366d8 --- /dev/null +++ b/sites/all/themes/gui/materiobasetheme/bower_components/history.js/scripts/bundled/html5/zepto.history.js @@ -0,0 +1 @@ +(function(e,t){"use strict";var n=e.History=e.History||{},r=e.Zepto;if(typeof n.Adapter!="undefined")throw new Error("History.js Adapter has already been loaded...");n.Adapter={bind:function(e,t,n){(new r(e)).bind(t,n)},trigger:function(e,t){(new r(e)).trigger(t)},extractEventData:function(e,n){var r=n&&n[e]||t;return r},onDomLoad:function(e){new r(e)}},typeof n.init!="undefined"&&n.init()})(window),function(e,t){"use strict";var n=e.console||t,r=e.document,i=e.navigator,s=e.sessionStorage||!1,o=e.setTimeout,u=e.clearTimeout,a=e.setInterval,f=e.clearInterval,l=e.JSON,c=e.alert,h=e.History=e.History||{},p=e.history;try{s.setItem("TEST","1"),s.removeItem("TEST")}catch(d){s=!1}l.stringify=l.stringify||l.encode,l.parse=l.parse||l.decode;if(typeof h.init!="undefined")throw new Error("History.js Core has already been loaded...");h.init=function(e){return typeof h.Adapter=="undefined"?!1:(typeof h.initCore!="undefined"&&h.initCore(),typeof h.initHtml4!="undefined"&&h.initHtml4(),!0)},h.initCore=function(d){if(typeof h.initCore.initialized!="undefined")return!1;h.initCore.initialized=!0,h.options=h.options||{},h.options.hashChangeInterval=h.options.hashChangeInterval||100,h.options.safariPollInterval=h.options.safariPollInterval||500,h.options.doubleCheckInterval=h.options.doubleCheckInterval||500,h.options.disableSuid=h.options.disableSuid||!1,h.options.storeInterval=h.options.storeInterval||1e3,h.options.busyDelay=h.options.busyDelay||250,h.options.debug=h.options.debug||!1,h.options.initialTitle=h.options.initialTitle||r.title,h.options.html4Mode=h.options.html4Mode||!1,h.options.delayInit=h.options.delayInit||!1,h.intervalList=[],h.clearAllIntervals=function(){var e,t=h.intervalList;if(typeof t!="undefined"&&t!==null){for(e=0;e")&&n[0]);return e>4?e:!1}();return e},h.isInternetExplorer=function(){var e=h.isInternetExplorer.cached=typeof h.isInternetExplorer.cached!="undefined"?h.isInternetExplorer.cached:Boolean(h.getInternetExplorerMajorVersion());return e},h.options.html4Mode?h.emulated={pushState:!0,hashChange:!0}:h.emulated={pushState:!Boolean(e.history&&e.history.pushState&&e.history.replaceState&&!/ Mobile\/([1-7][a-z]|(8([abcde]|f(1[0-8]))))/i.test(i.userAgent)&&!/AppleWebKit\/5([0-2]|3[0-2])/i.test(i.userAgent)),hashChange:Boolean(!("onhashchange"in e||"onhashchange"in r)||h.isInternetExplorer()&&h.getInternetExplorerMajorVersion()<8)},h.enabled=!h.emulated.pushState,h.bugs={setHash:Boolean(!h.emulated.pushState&&i.vendor==="Apple Computer, Inc."&&/AppleWebKit\/5([0-2]|3[0-3])/.test(i.userAgent)),safariPoll:Boolean(!h.emulated.pushState&&i.vendor==="Apple Computer, Inc."&&/AppleWebKit\/5([0-2]|3[0-3])/.test(i.userAgent)),ieDoubleCheck:Boolean(h.isInternetExplorer()&&h.getInternetExplorerMajorVersion()<8),hashEscape:Boolean(h.isInternetExplorer()&&h.getInternetExplorerMajorVersion()<7)},h.isEmptyObject=function(e){for(var t in e)if(e.hasOwnProperty(t))return!1;return!0},h.cloneObject=function(e){var t,n;return e?(t=l.stringify(e),n=l.parse(t)):n={},n},h.getRootUrl=function(){var e=r.location.protocol+"//"+(r.location.hostname||r.location.host);if(r.location.port||!1)e+=":"+r.location.port;return e+="/",e},h.getBaseHref=function(){var e=r.getElementsByTagName("base"),t=null,n="";return e.length===1&&(t=e[0],n=t.href.replace(/[^\/]+$/,"")),n=n.replace(/\/+$/,""),n&&(n+="/"),n},h.getBaseUrl=function(){var e=h.getBaseHref()||h.getBasePageUrl()||h.getRootUrl();return e},h.getPageUrl=function(){var e=h.getState(!1,!1),t=(e||{}).url||h.getLocationHref(),n;return n=t.replace(/\/+$/,"").replace(/[^\/]+$/,function(e,t,n){return/\./.test(e)?e:e+"/"}),n},h.getBasePageUrl=function(){var e=h.getLocationHref().replace(/[#\?].*/,"").replace(/[^\/]+$/,function(e,t,n){return/[^\/]$/.test(e)?"":e}).replace(/\/+$/,"")+"/";return e},h.getFullUrl=function(e,t){var n=e,r=e.substring(0,1);return t=typeof t=="undefined"?!0:t,/[a-z]+\:\/\//.test(e)||(r==="/"?n=h.getRootUrl()+e.replace(/^\/+/,""):r==="#"?n=h.getPageUrl().replace(/#.*/,"")+e:r==="?"?n=h.getPageUrl().replace(/[\?#].*/,"")+e:t?n=h.getBaseUrl()+e.replace(/^(\.\/)+/,""):n=h.getBasePageUrl()+e.replace(/^(\.\/)+/,"")),n.replace(/\#$/,"")},h.getShortUrl=function(e){var t=e,n=h.getBaseUrl(),r=h.getRootUrl();return h.emulated.pushState&&(t=t.replace(n,"")),t=t.replace(r,"/"),h.isTraditionalAnchor(t)&&(t="./"+t),t=t.replace(/^(\.\/)+/g,"./").replace(/\#$/,""),t},h.getLocationHref=function(e){return e=e||r,e.URL===e.location.href?e.location.href:e.location.href===decodeURIComponent(e.URL)?e.URL:e.location.hash&&decodeURIComponent(e.location.href.replace(/^[^#]+/,""))===e.location.hash?e.location.href:e.URL.indexOf("#")==-1&&e.location.href.indexOf("#")!=-1?e.location.href:e.URL||e.location.href},h.store={},h.idToState=h.idToState||{},h.stateToId=h.stateToId||{},h.urlToId=h.urlToId||{},h.storedStates=h.storedStates||[],h.savedStates=h.savedStates||[],h.normalizeStore=function(){h.store.idToState=h.store.idToState||{},h.store.urlToId=h.store.urlToId||{},h.store.stateToId=h.store.stateToId||{}},h.getState=function(e,t){typeof e=="undefined"&&(e=!0),typeof t=="undefined"&&(t=!0);var n=h.getLastSavedState();return!n&&t&&(n=h.createStateObject()),e&&(n=h.cloneObject(n),n.url=n.cleanUrl||n.url),n},h.getIdByState=function(e){var t=h.extractId(e.url),n;if(!t){n=h.getStateString(e);if(typeof h.stateToId[n]!="undefined")t=h.stateToId[n];else if(typeof h.store.stateToId[n]!="undefined")t=h.store.stateToId[n];else{for(;;){t=(new Date).getTime()+String(Math.random()).replace(/\D/g,"");if(typeof h.idToState[t]=="undefined"&&typeof h.store.idToState[t]=="undefined")break}h.stateToId[n]=t,h.idToState[t]=e}}return t},h.normalizeState=function(e){var t,n;if(!e||typeof e!="object")e={};if(typeof e.normalized!="undefined")return e;if(!e.data||typeof e.data!="object")e.data={};return t={},t.normalized=!0,t.title=e.title||"",t.url=h.getFullUrl(e.url?e.url:h.getLocationHref()),t.hash=h.getShortUrl(t.url),t.data=h.cloneObject(e.data),t.id=h.getIdByState(t),t.cleanUrl=t.url.replace(/\??\&_suid.*/,""),t.url=t.cleanUrl,n=!h.isEmptyObject(t.data),(t.title||n)&&h.options.disableSuid!==!0&&(t.hash=h.getShortUrl(t.url).replace(/\??\&_suid.*/,""),/\?/.test(t.hash)||(t.hash+="?"),t.hash+="&_suid="+t.id),t.hashedUrl=h.getFullUrl(t.hash),(h.emulated.pushState||h.bugs.safariPoll)&&h.hasUrlDuplicate(t)&&(t.url=t.hashedUrl),t},h.createStateObject=function(e,t,n){var r={data:e,title:t,url:n};return r=h.normalizeState(r),r},h.getStateById=function(e){e=String(e);var n=h.idToState[e]||h.store.idToState[e]||t;return n},h.getStateString=function(e){var t,n,r;return t=h.normalizeState(e),n={data:t.data,title:e.title,url:e.url},r=l.stringify(n),r},h.getStateId=function(e){var t,n;return t=h.normalizeState(e),n=t.id,n},h.getHashByState=function(e){var t,n;return t=h.normalizeState(e),n=t.hash,n},h.extractId=function(e){var t,n,r,i;return e.indexOf("#")!=-1?i=e.split("#")[0]:i=e,n=/(.*)\&_suid=([0-9]+)$/.exec(i),r=n?n[1]||e:e,t=n?String(n[2]||""):"",t||!1},h.isTraditionalAnchor=function(e){var t=!/[\/\?\.]/.test(e);return t},h.extractState=function(e,t){var n=null,r,i;return t=t||!1,r=h.extractId(e),r&&(n=h.getStateById(r)),n||(i=h.getFullUrl(e),r=h.getIdByUrl(i)||!1,r&&(n=h.getStateById(r)),!n&&t&&!h.isTraditionalAnchor(e)&&(n=h.createStateObject(null,null,i))),n},h.getIdByUrl=function(e){var n=h.urlToId[e]||h.store.urlToId[e]||t;return n},h.getLastSavedState=function(){return h.savedStates[h.savedStates.length-1]||t},h.getLastStoredState=function(){return h.storedStates[h.storedStates.length-1]||t},h.hasUrlDuplicate=function(e){var t=!1,n;return n=h.extractState(e.url),t=n&&n.id!==e.id,t},h.storeState=function(e){return h.urlToId[e.url]=e.id,h.storedStates.push(h.cloneObject(e)),e},h.isLastSavedState=function(e){var t=!1,n,r,i;return h.savedStates.length&&(n=e.id,r=h.getLastSavedState(),i=r.id,t=n===i),t},h.saveState=function(e){return h.isLastSavedState(e)?!1:(h.savedStates.push(h.cloneObject(e)),!0)},h.getStateByIndex=function(e){var t=null;return typeof e=="undefined"?t=h.savedStates[h.savedStates.length-1]:e<0?t=h.savedStates[h.savedStates.length+e]:t=h.savedStates[e],t},h.getCurrentIndex=function(){var e=null;return h.savedStates.length<1?e=0:e=h.savedStates.length-1,e},h.getHash=function(e){var t=h.getLocationHref(e),n;return n=h.getHashByUrl(t),n},h.unescapeHash=function(e){var t=h.normalizeHash(e);return t=decodeURIComponent(t),t},h.normalizeHash=function(e){var t=e.replace(/[^#]*#/,"").replace(/#.*/,"");return t},h.setHash=function(e,t){var n,i;return t!==!1&&h.busy()?(h.pushQueue({scope:h,callback:h.setHash,args:arguments,queue:t}),!1):(h.busy(!0),n=h.extractState(e,!0),n&&!h.emulated.pushState?h.pushState(n.data,n.title,n.url,!1):h.getHash()!==e&&(h.bugs.setHash?(i=h.getPageUrl(),h.pushState(null,null,i+"#"+e,!1)):r.location.hash=e),h)},h.escapeHash=function(t){var n=h.normalizeHash(t);return n=e.encodeURIComponent(n),h.bugs.hashEscape||(n=n.replace(/\%21/g,"!").replace(/\%26/g,"&").replace(/\%3D/g,"=").replace(/\%3F/g,"?")),n},h.getHashByUrl=function(e){var t=String(e).replace(/([^#]*)#?([^#]*)#?(.*)/,"$2");return t=h.unescapeHash(t),t},h.setTitle=function(e){var t=e.title,n;t||(n=h.getStateByIndex(0),n&&n.url===e.url&&(t=n.title||h.options.initialTitle));try{r.getElementsByTagName("title")[0].innerHTML=t.replace("<","<").replace(">",">").replace(" & "," & ")}catch(i){}return r.title=t,h},h.queues=[],h.busy=function(e){typeof e!="undefined"?h.busy.flag=e:typeof h.busy.flag=="undefined"&&(h.busy.flag=!1);if(!h.busy.flag){u(h.busy.timeout);var t=function(){var e,n,r;if(h.busy.flag)return;for(e=h.queues.length-1;e>=0;--e){n=h.queues[e];if(n.length===0)continue;r=n.shift(),h.fireQueueItem(r),h.busy.timeout=o(t,h.options.busyDelay)}};h.busy.timeout=o(t,h.options.busyDelay)}return h.busy.flag},h.busy.flag=!1,h.fireQueueItem=function(e){return e.callback.apply(e.scope||h,e.args||[])},h.pushQueue=function(e){return h.queues[e.queue||0]=h.queues[e.queue||0]||[],h.queues[e.queue||0].push(e),h},h.queue=function(e,t){return typeof e=="function"&&(e={callback:e}),typeof t!="undefined"&&(e.queue=t),h.busy()?h.pushQueue(e):h.fireQueueItem(e),h},h.clearQueue=function(){return h.busy.flag=!1,h.queues=[],h},h.stateChanged=!1,h.doubleChecker=!1,h.doubleCheckComplete=function(){return h.stateChanged=!0,h.doubleCheckClear(),h},h.doubleCheckClear=function(){return h.doubleChecker&&(u(h.doubleChecker),h.doubleChecker=!1),h},h.doubleCheck=function(e){return h.stateChanged=!1,h.doubleCheckClear(),h.bugs.ieDoubleCheck&&(h.doubleChecker=o(function(){return h.doubleCheckClear(),h.stateChanged||e(),!0},h.options.doubleCheckInterval)),h},h.safariStatePoll=function(){var t=h.extractState(h.getLocationHref()),n;if(!h.isLastSavedState(t))return n=t,n||(n=h.createStateObject()),h.Adapter.trigger(e,"popstate"),h;return},h.back=function(e){return e!==!1&&h.busy()?(h.pushQueue({scope:h,callback:h.back,args:arguments,queue:e}),!1):(h.busy(!0),h.doubleCheck(function(){h.back(!1)}),p.go(-1),!0)},h.forward=function(e){return e!==!1&&h.busy()?(h.pushQueue({scope:h,callback:h.forward,args:arguments,queue:e}),!1):(h.busy(!0),h.doubleCheck(function(){h.forward(!1)}),p.go(1),!0)},h.go=function(e,t){var n;if(e>0)for(n=1;n<=e;++n)h.forward(t);else{if(!(e<0))throw new Error("History.go: History.go requires a positive or negative integer passed.");for(n=-1;n>=e;--n)h.back(t)}return h};if(h.emulated.pushState){var v=function(){};h.pushState=h.pushState||v,h.replaceState=h.replaceState||v}else h.onPopState=function(t,n){var r=!1,i=!1,s,o;return h.doubleCheckComplete(),s=h.getHash(),s?(o=h.extractState(s||h.getLocationHref(),!0),o?h.replaceState(o.data,o.title,o.url,!1):(h.Adapter.trigger(e,"anchorchange"),h.busy(!1)),h.expectedStateId=!1,!1):(r=h.Adapter.extractEventData("state",t,n)||!1,r?i=h.getStateById(r):h.expectedStateId?i=h.getStateById(h.expectedStateId):i=h.extractState(h.getLocationHref()),i||(i=h.createStateObject(null,null,h.getLocationHref())),h.expectedStateId=!1,h.isLastSavedState(i)?(h.busy(!1),!1):(h.storeState(i),h.saveState(i),h.setTitle(i),h.Adapter.trigger(e,"statechange"),h.busy(!1),!0))},h.Adapter.bind(e,"popstate",h.onPopState),h.pushState=function(t,n,r,i){if(h.getHashByUrl(r)&&h.emulated.pushState)throw new Error("History.js does not support states with fragement-identifiers (hashes/anchors).");if(i!==!1&&h.busy())return h.pushQueue({scope:h,callback:h.pushState,args:arguments,queue:i}),!1;h.busy(!0);var s=h.createStateObject(t,n,r);return h.isLastSavedState(s)?h.busy(!1):(h.storeState(s),h.expectedStateId=s.id,p.pushState(s.id,s.title,s.url),h.Adapter.trigger(e,"popstate")),!0},h.replaceState=function(t,n,r,i){if(h.getHashByUrl(r)&&h.emulated.pushState)throw new Error("History.js does not support states with fragement-identifiers (hashes/anchors).");if(i!==!1&&h.busy())return h.pushQueue({scope:h,callback:h.replaceState,args:arguments,queue:i}),!1;h.busy(!0);var s=h.createStateObject(t,n,r);return h.isLastSavedState(s)?h.busy(!1):(h.storeState(s),h.expectedStateId=s.id,p.replaceState(s.id,s.title,s.url),h.Adapter.trigger(e,"popstate")),!0};if(s){try{h.store=l.parse(s.getItem("History.store"))||{}}catch(m){h.store={}}h.normalizeStore()}else h.store={},h.normalizeStore();h.Adapter.bind(e,"unload",h.clearAllIntervals),h.saveState(h.storeState(h.extractState(h.getLocationHref(),!0))),s&&(h.onUnload=function(){var e,t,n;try{e=l.parse(s.getItem("History.store"))||{}}catch(r){e={}}e.idToState=e.idToState||{},e.urlToId=e.urlToId||{},e.stateToId=e.stateToId||{};for(t in h.idToState){if(!h.idToState.hasOwnProperty(t))continue;e.idToState[t]=h.idToState[t]}for(t in h.urlToId){if(!h.urlToId.hasOwnProperty(t))continue;e.urlToId[t]=h.urlToId[t]}for(t in h.stateToId){if(!h.stateToId.hasOwnProperty(t))continue;e.stateToId[t]=h.stateToId[t]}h.store=e,h.normalizeStore(),n=l.stringify(e);try{s.setItem("History.store",n)}catch(i){if(i.code!==DOMException.QUOTA_EXCEEDED_ERR)throw i;s.length&&(s.removeItem("History.store"),s.setItem("History.store",n))}},h.intervalList.push(a(h.onUnload,h.options.storeInterval)),h.Adapter.bind(e,"beforeunload",h.onUnload),h.Adapter.bind(e,"unload",h.onUnload));if(!h.emulated.pushState){h.bugs.safariPoll&&h.intervalList.push(a(h.safariStatePoll,h.options.safariPollInterval));if(i.vendor==="Apple Computer, Inc."||(i.appCodeName||"")==="Mozilla")h.Adapter.bind(e,"hashchange",function(){h.Adapter.trigger(e,"popstate")}),h.getHash()&&h.Adapter.onDomLoad(function(){h.Adapter.trigger(e,"hashchange")})}},(!h.options||!h.options.delayInit)&&h.init()}(window) \ No newline at end of file diff --git a/sites/all/themes/gui/materiobasetheme/bower_components/history.js/scripts/compressed/history.adapter.dojo.js b/sites/all/themes/gui/materiobasetheme/bower_components/history.js/scripts/compressed/history.adapter.dojo.js new file mode 100644 index 00000000..f0ac1ca1 --- /dev/null +++ b/sites/all/themes/gui/materiobasetheme/bower_components/history.js/scripts/compressed/history.adapter.dojo.js @@ -0,0 +1 @@ +(function(e,t){"use strict";var n=e.History=e.History||{},r=e.require;if(typeof n.Adapter!="undefined")throw new Error("History.js Adapter has already been loaded...");n.Adapter={handlers:{},_uid:1,uid:function(e){return e._uid||(e._uid=n.Adapter._uid++)},bind:function(e,t,r){var i=n.Adapter.uid(e);n.Adapter.handlers[i]=n.Adapter.handlers[i]||{},n.Adapter.handlers[i][t]=n.Adapter.handlers[i][t]||[],n.Adapter.handlers[i][t].push(r),e["on"+t]=function(e,t){return function(r){n.Adapter.trigger(e,t,r)}}(e,t)},trigger:function(e,t,r){r=r||{};var i=n.Adapter.uid(e),s,o;n.Adapter.handlers[i]=n.Adapter.handlers[i]||{},n.Adapter.handlers[i][t]=n.Adapter.handlers[i][t]||[];for(s=0,o=n.Adapter.handlers[i][t].length;s")&&n[0]);return e>4?e:!1}();return e},h.isInternetExplorer=function(){var e=h.isInternetExplorer.cached=typeof h.isInternetExplorer.cached!="undefined"?h.isInternetExplorer.cached:Boolean(h.getInternetExplorerMajorVersion());return e},h.options.html4Mode?h.emulated={pushState:!0,hashChange:!0}:h.emulated={pushState:!Boolean(e.history&&e.history.pushState&&e.history.replaceState&&!/ Mobile\/([1-7][a-z]|(8([abcde]|f(1[0-8]))))/i.test(i.userAgent)&&!/AppleWebKit\/5([0-2]|3[0-2])/i.test(i.userAgent)),hashChange:Boolean(!("onhashchange"in e||"onhashchange"in r)||h.isInternetExplorer()&&h.getInternetExplorerMajorVersion()<8)},h.enabled=!h.emulated.pushState,h.bugs={setHash:Boolean(!h.emulated.pushState&&i.vendor==="Apple Computer, Inc."&&/AppleWebKit\/5([0-2]|3[0-3])/.test(i.userAgent)),safariPoll:Boolean(!h.emulated.pushState&&i.vendor==="Apple Computer, Inc."&&/AppleWebKit\/5([0-2]|3[0-3])/.test(i.userAgent)),ieDoubleCheck:Boolean(h.isInternetExplorer()&&h.getInternetExplorerMajorVersion()<8),hashEscape:Boolean(h.isInternetExplorer()&&h.getInternetExplorerMajorVersion()<7)},h.isEmptyObject=function(e){for(var t in e)if(e.hasOwnProperty(t))return!1;return!0},h.cloneObject=function(e){var t,n;return e?(t=l.stringify(e),n=l.parse(t)):n={},n},h.getRootUrl=function(){var e=r.location.protocol+"//"+(r.location.hostname||r.location.host);if(r.location.port||!1)e+=":"+r.location.port;return e+="/",e},h.getBaseHref=function(){var e=r.getElementsByTagName("base"),t=null,n="";return e.length===1&&(t=e[0],n=t.href.replace(/[^\/]+$/,"")),n=n.replace(/\/+$/,""),n&&(n+="/"),n},h.getBaseUrl=function(){var e=h.getBaseHref()||h.getBasePageUrl()||h.getRootUrl();return e},h.getPageUrl=function(){var e=h.getState(!1,!1),t=(e||{}).url||h.getLocationHref(),n;return n=t.replace(/\/+$/,"").replace(/[^\/]+$/,function(e,t,n){return/\./.test(e)?e:e+"/"}),n},h.getBasePageUrl=function(){var e=h.getLocationHref().replace(/[#\?].*/,"").replace(/[^\/]+$/,function(e,t,n){return/[^\/]$/.test(e)?"":e}).replace(/\/+$/,"")+"/";return e},h.getFullUrl=function(e,t){var n=e,r=e.substring(0,1);return t=typeof t=="undefined"?!0:t,/[a-z]+\:\/\//.test(e)||(r==="/"?n=h.getRootUrl()+e.replace(/^\/+/,""):r==="#"?n=h.getPageUrl().replace(/#.*/,"")+e:r==="?"?n=h.getPageUrl().replace(/[\?#].*/,"")+e:t?n=h.getBaseUrl()+e.replace(/^(\.\/)+/,""):n=h.getBasePageUrl()+e.replace(/^(\.\/)+/,"")),n.replace(/\#$/,"")},h.getShortUrl=function(e){var t=e,n=h.getBaseUrl(),r=h.getRootUrl();return h.emulated.pushState&&(t=t.replace(n,"")),t=t.replace(r,"/"),h.isTraditionalAnchor(t)&&(t="./"+t),t=t.replace(/^(\.\/)+/g,"./").replace(/\#$/,""),t},h.getLocationHref=function(e){return e=e||r,e.URL===e.location.href?e.location.href:e.location.href===decodeURIComponent(e.URL)?e.URL:e.location.hash&&decodeURIComponent(e.location.href.replace(/^[^#]+/,""))===e.location.hash?e.location.href:e.URL.indexOf("#")==-1&&e.location.href.indexOf("#")!=-1?e.location.href:e.URL||e.location.href},h.store={},h.idToState=h.idToState||{},h.stateToId=h.stateToId||{},h.urlToId=h.urlToId||{},h.storedStates=h.storedStates||[],h.savedStates=h.savedStates||[],h.normalizeStore=function(){h.store.idToState=h.store.idToState||{},h.store.urlToId=h.store.urlToId||{},h.store.stateToId=h.store.stateToId||{}},h.getState=function(e,t){typeof e=="undefined"&&(e=!0),typeof t=="undefined"&&(t=!0);var n=h.getLastSavedState();return!n&&t&&(n=h.createStateObject()),e&&(n=h.cloneObject(n),n.url=n.cleanUrl||n.url),n},h.getIdByState=function(e){var t=h.extractId(e.url),n;if(!t){n=h.getStateString(e);if(typeof h.stateToId[n]!="undefined")t=h.stateToId[n];else if(typeof h.store.stateToId[n]!="undefined")t=h.store.stateToId[n];else{for(;;){t=(new Date).getTime()+String(Math.random()).replace(/\D/g,"");if(typeof h.idToState[t]=="undefined"&&typeof h.store.idToState[t]=="undefined")break}h.stateToId[n]=t,h.idToState[t]=e}}return t},h.normalizeState=function(e){var t,n;if(!e||typeof e!="object")e={};if(typeof e.normalized!="undefined")return e;if(!e.data||typeof e.data!="object")e.data={};return t={},t.normalized=!0,t.title=e.title||"",t.url=h.getFullUrl(e.url?e.url:h.getLocationHref()),t.hash=h.getShortUrl(t.url),t.data=h.cloneObject(e.data),t.id=h.getIdByState(t),t.cleanUrl=t.url.replace(/\??\&_suid.*/,""),t.url=t.cleanUrl,n=!h.isEmptyObject(t.data),(t.title||n)&&h.options.disableSuid!==!0&&(t.hash=h.getShortUrl(t.url).replace(/\??\&_suid.*/,""),/\?/.test(t.hash)||(t.hash+="?"),t.hash+="&_suid="+t.id),t.hashedUrl=h.getFullUrl(t.hash),(h.emulated.pushState||h.bugs.safariPoll)&&h.hasUrlDuplicate(t)&&(t.url=t.hashedUrl),t},h.createStateObject=function(e,t,n){var r={data:e,title:t,url:n};return r=h.normalizeState(r),r},h.getStateById=function(e){e=String(e);var n=h.idToState[e]||h.store.idToState[e]||t;return n},h.getStateString=function(e){var t,n,r;return t=h.normalizeState(e),n={data:t.data,title:e.title,url:e.url},r=l.stringify(n),r},h.getStateId=function(e){var t,n;return t=h.normalizeState(e),n=t.id,n},h.getHashByState=function(e){var t,n;return t=h.normalizeState(e),n=t.hash,n},h.extractId=function(e){var t,n,r,i;return e.indexOf("#")!=-1?i=e.split("#")[0]:i=e,n=/(.*)\&_suid=([0-9]+)$/.exec(i),r=n?n[1]||e:e,t=n?String(n[2]||""):"",t||!1},h.isTraditionalAnchor=function(e){var t=!/[\/\?\.]/.test(e);return t},h.extractState=function(e,t){var n=null,r,i;return t=t||!1,r=h.extractId(e),r&&(n=h.getStateById(r)),n||(i=h.getFullUrl(e),r=h.getIdByUrl(i)||!1,r&&(n=h.getStateById(r)),!n&&t&&!h.isTraditionalAnchor(e)&&(n=h.createStateObject(null,null,i))),n},h.getIdByUrl=function(e){var n=h.urlToId[e]||h.store.urlToId[e]||t;return n},h.getLastSavedState=function(){return h.savedStates[h.savedStates.length-1]||t},h.getLastStoredState=function(){return h.storedStates[h.storedStates.length-1]||t},h.hasUrlDuplicate=function(e){var t=!1,n;return n=h.extractState(e.url),t=n&&n.id!==e.id,t},h.storeState=function(e){return h.urlToId[e.url]=e.id,h.storedStates.push(h.cloneObject(e)),e},h.isLastSavedState=function(e){var t=!1,n,r,i;return h.savedStates.length&&(n=e.id,r=h.getLastSavedState(),i=r.id,t=n===i),t},h.saveState=function(e){return h.isLastSavedState(e)?!1:(h.savedStates.push(h.cloneObject(e)),!0)},h.getStateByIndex=function(e){var t=null;return typeof e=="undefined"?t=h.savedStates[h.savedStates.length-1]:e<0?t=h.savedStates[h.savedStates.length+e]:t=h.savedStates[e],t},h.getCurrentIndex=function(){var e=null;return h.savedStates.length<1?e=0:e=h.savedStates.length-1,e},h.getHash=function(e){var t=h.getLocationHref(e),n;return n=h.getHashByUrl(t),n},h.unescapeHash=function(e){var t=h.normalizeHash(e);return t=decodeURIComponent(t),t},h.normalizeHash=function(e){var t=e.replace(/[^#]*#/,"").replace(/#.*/,"");return t},h.setHash=function(e,t){var n,i;return t!==!1&&h.busy()?(h.pushQueue({scope:h,callback:h.setHash,args:arguments,queue:t}),!1):(h.busy(!0),n=h.extractState(e,!0),n&&!h.emulated.pushState?h.pushState(n.data,n.title,n.url,!1):h.getHash()!==e&&(h.bugs.setHash?(i=h.getPageUrl(),h.pushState(null,null,i+"#"+e,!1)):r.location.hash=e),h)},h.escapeHash=function(t){var n=h.normalizeHash(t);return n=e.encodeURIComponent(n),h.bugs.hashEscape||(n=n.replace(/\%21/g,"!").replace(/\%26/g,"&").replace(/\%3D/g,"=").replace(/\%3F/g,"?")),n},h.getHashByUrl=function(e){var t=String(e).replace(/([^#]*)#?([^#]*)#?(.*)/,"$2");return t=h.unescapeHash(t),t},h.setTitle=function(e){var t=e.title,n;t||(n=h.getStateByIndex(0),n&&n.url===e.url&&(t=n.title||h.options.initialTitle));try{r.getElementsByTagName("title")[0].innerHTML=t.replace("<","<").replace(">",">").replace(" & "," & ")}catch(i){}return r.title=t,h},h.queues=[],h.busy=function(e){typeof e!="undefined"?h.busy.flag=e:typeof h.busy.flag=="undefined"&&(h.busy.flag=!1);if(!h.busy.flag){u(h.busy.timeout);var t=function(){var e,n,r;if(h.busy.flag)return;for(e=h.queues.length-1;e>=0;--e){n=h.queues[e];if(n.length===0)continue;r=n.shift(),h.fireQueueItem(r),h.busy.timeout=o(t,h.options.busyDelay)}};h.busy.timeout=o(t,h.options.busyDelay)}return h.busy.flag},h.busy.flag=!1,h.fireQueueItem=function(e){return e.callback.apply(e.scope||h,e.args||[])},h.pushQueue=function(e){return h.queues[e.queue||0]=h.queues[e.queue||0]||[],h.queues[e.queue||0].push(e),h},h.queue=function(e,t){return typeof e=="function"&&(e={callback:e}),typeof t!="undefined"&&(e.queue=t),h.busy()?h.pushQueue(e):h.fireQueueItem(e),h},h.clearQueue=function(){return h.busy.flag=!1,h.queues=[],h},h.stateChanged=!1,h.doubleChecker=!1,h.doubleCheckComplete=function(){return h.stateChanged=!0,h.doubleCheckClear(),h},h.doubleCheckClear=function(){return h.doubleChecker&&(u(h.doubleChecker),h.doubleChecker=!1),h},h.doubleCheck=function(e){return h.stateChanged=!1,h.doubleCheckClear(),h.bugs.ieDoubleCheck&&(h.doubleChecker=o(function(){return h.doubleCheckClear(),h.stateChanged||e(),!0},h.options.doubleCheckInterval)),h},h.safariStatePoll=function(){var t=h.extractState(h.getLocationHref()),n;if(!h.isLastSavedState(t))return n=t,n||(n=h.createStateObject()),h.Adapter.trigger(e,"popstate"),h;return},h.back=function(e){return e!==!1&&h.busy()?(h.pushQueue({scope:h,callback:h.back,args:arguments,queue:e}),!1):(h.busy(!0),h.doubleCheck(function(){h.back(!1)}),p.go(-1),!0)},h.forward=function(e){return e!==!1&&h.busy()?(h.pushQueue({scope:h,callback:h.forward,args:arguments,queue:e}),!1):(h.busy(!0),h.doubleCheck(function(){h.forward(!1)}),p.go(1),!0)},h.go=function(e,t){var n;if(e>0)for(n=1;n<=e;++n)h.forward(t);else{if(!(e<0))throw new Error("History.go: History.go requires a positive or negative integer passed.");for(n=-1;n>=e;--n)h.back(t)}return h};if(h.emulated.pushState){var v=function(){};h.pushState=h.pushState||v,h.replaceState=h.replaceState||v}else h.onPopState=function(t,n){var r=!1,i=!1,s,o;return h.doubleCheckComplete(),s=h.getHash(),s?(o=h.extractState(s||h.getLocationHref(),!0),o?h.replaceState(o.data,o.title,o.url,!1):(h.Adapter.trigger(e,"anchorchange"),h.busy(!1)),h.expectedStateId=!1,!1):(r=h.Adapter.extractEventData("state",t,n)||!1,r?i=h.getStateById(r):h.expectedStateId?i=h.getStateById(h.expectedStateId):i=h.extractState(h.getLocationHref()),i||(i=h.createStateObject(null,null,h.getLocationHref())),h.expectedStateId=!1,h.isLastSavedState(i)?(h.busy(!1),!1):(h.storeState(i),h.saveState(i),h.setTitle(i),h.Adapter.trigger(e,"statechange"),h.busy(!1),!0))},h.Adapter.bind(e,"popstate",h.onPopState),h.pushState=function(t,n,r,i){if(h.getHashByUrl(r)&&h.emulated.pushState)throw new Error("History.js does not support states with fragement-identifiers (hashes/anchors).");if(i!==!1&&h.busy())return h.pushQueue({scope:h,callback:h.pushState,args:arguments,queue:i}),!1;h.busy(!0);var s=h.createStateObject(t,n,r);return h.isLastSavedState(s)?h.busy(!1):(h.storeState(s),h.expectedStateId=s.id,p.pushState(s.id,s.title,s.url),h.Adapter.trigger(e,"popstate")),!0},h.replaceState=function(t,n,r,i){if(h.getHashByUrl(r)&&h.emulated.pushState)throw new Error("History.js does not support states with fragement-identifiers (hashes/anchors).");if(i!==!1&&h.busy())return h.pushQueue({scope:h,callback:h.replaceState,args:arguments,queue:i}),!1;h.busy(!0);var s=h.createStateObject(t,n,r);return h.isLastSavedState(s)?h.busy(!1):(h.storeState(s),h.expectedStateId=s.id,p.replaceState(s.id,s.title,s.url),h.Adapter.trigger(e,"popstate")),!0};if(s){try{h.store=l.parse(s.getItem("History.store"))||{}}catch(m){h.store={}}h.normalizeStore()}else h.store={},h.normalizeStore();h.Adapter.bind(e,"unload",h.clearAllIntervals),h.saveState(h.storeState(h.extractState(h.getLocationHref(),!0))),s&&(h.onUnload=function(){var e,t,n;try{e=l.parse(s.getItem("History.store"))||{}}catch(r){e={}}e.idToState=e.idToState||{},e.urlToId=e.urlToId||{},e.stateToId=e.stateToId||{};for(t in h.idToState){if(!h.idToState.hasOwnProperty(t))continue;e.idToState[t]=h.idToState[t]}for(t in h.urlToId){if(!h.urlToId.hasOwnProperty(t))continue;e.urlToId[t]=h.urlToId[t]}for(t in h.stateToId){if(!h.stateToId.hasOwnProperty(t))continue;e.stateToId[t]=h.stateToId[t]}h.store=e,h.normalizeStore(),n=l.stringify(e);try{s.setItem("History.store",n)}catch(i){if(i.code!==DOMException.QUOTA_EXCEEDED_ERR)throw i;s.length&&(s.removeItem("History.store"),s.setItem("History.store",n))}},h.intervalList.push(a(h.onUnload,h.options.storeInterval)),h.Adapter.bind(e,"beforeunload",h.onUnload),h.Adapter.bind(e,"unload",h.onUnload));if(!h.emulated.pushState){h.bugs.safariPoll&&h.intervalList.push(a(h.safariStatePoll,h.options.safariPollInterval));if(i.vendor==="Apple Computer, Inc."||(i.appCodeName||"")==="Mozilla")h.Adapter.bind(e,"hashchange",function(){h.Adapter.trigger(e,"popstate")}),h.getHash()&&h.Adapter.onDomLoad(function(){h.Adapter.trigger(e,"hashchange")})}},(!h.options||!h.options.delayInit)&&h.init()})(window) \ No newline at end of file diff --git a/sites/all/themes/gui/materiobasetheme/bower_components/history.js/scripts/compressed/json2.js b/sites/all/themes/gui/materiobasetheme/bower_components/history.js/scripts/compressed/json2.js new file mode 100644 index 00000000..0eb302e6 --- /dev/null +++ b/sites/all/themes/gui/materiobasetheme/bower_components/history.js/scripts/compressed/json2.js @@ -0,0 +1 @@ +typeof JSON!="object"&&(JSON={}),function(){"use strict";function f(e){return e<10?"0"+e:e}function quote(e){return escapable.lastIndex=0,escapable.test(e)?'"'+e.replace(escapable,function(e){var t=meta[e];return typeof t=="string"?t:"\\u"+("0000"+e.charCodeAt(0).toString(16)).slice(-4)})+'"':'"'+e+'"'}function str(e,t){var n,r,i,s,o=gap,u,a=t[e];a&&typeof a=="object"&&typeof a.toJSON=="function"&&(a=a.toJSON(e)),typeof rep=="function"&&(a=rep.call(t,e,a));switch(typeof a){case"string":return quote(a);case"number":return isFinite(a)?String(a):"null";case"boolean":case"null":return String(a);case"object":if(!a)return"null";gap+=indent,u=[];if(Object.prototype.toString.apply(a)==="[object Array]"){s=a.length;for(n=0;n + * @copyright 2010-2011 Benjamin Arthur Lupton + * @license New BSD License + */ + +// Closure +(function(window,undefined){ + "use strict"; + + // Localise Globals + var History = window.History = window.History||{}, + require = window.require; + + // Check Existence + if ( typeof History.Adapter !== 'undefined' ) { + throw new Error('History.js Adapter has already been loaded...'); + } + + // Add the Adapter + History.Adapter = { + /** + * History.Adapter.handlers[uid][eventName] = Array + */ + handlers: {}, + + /** + * History.Adapter._uid + * The current element unique identifier + */ + _uid: 1, + + /** + * History.Adapter.uid(element) + * @param {Element} element + * @return {String} uid + */ + uid: function(element){ + return element._uid || (element._uid = History.Adapter._uid++); + }, + + /** + * History.Adapter.bind(el,event,callback) + * @param {Element} element + * @param {String} eventName - custom and standard events + * @param {Function} callback + * @return + */ + bind: function(element,eventName,callback){ + // Prepare + var uid = History.Adapter.uid(element); + + // Apply Listener + History.Adapter.handlers[uid] = History.Adapter.handlers[uid] || {}; + History.Adapter.handlers[uid][eventName] = History.Adapter.handlers[uid][eventName] || []; + History.Adapter.handlers[uid][eventName].push(callback); + + // Bind Global Listener + element['on'+eventName] = (function(element,eventName){ + return function(event){ + History.Adapter.trigger(element,eventName,event); + }; + })(element,eventName); + }, + + /** + * History.Adapter.trigger(el,event) + * @param {Element} element + * @param {String} eventName - custom and standard events + * @param {Object} event - a object of event data + * @return + */ + trigger: function(element,eventName,event){ + // Prepare + event = event || {}; + var uid = History.Adapter.uid(element), + i,n; + + // Apply Listener + History.Adapter.handlers[uid] = History.Adapter.handlers[uid] || {}; + History.Adapter.handlers[uid][eventName] = History.Adapter.handlers[uid][eventName] || []; + + // Fire Listeners + for ( i=0,n=History.Adapter.handlers[uid][eventName].length; i + * @copyright 2012 Sean Adkinson + * @license New BSD License + */ + +// Closure +(function(window,undefined){ + "use strict"; + + // Localise Globals + var + History = window.History = window.History||{}, + Ext = window.Ext; + + window.JSON = { + stringify: Ext.JSON.encode, + parse: Ext.JSON.decode + }; + + // Check Existence + if ( typeof History.Adapter !== 'undefined' ) { + throw new Error('History.js Adapter has already been loaded...'); + } + + // Add the Adapter + History.Adapter = { + observables: {}, + + /** + * History.Adapter.bind(el,event,callback) + * @param {Element|string} el + * @param {string} event - custom and standard events + * @param {function} callback + * @param {Object} scope + * @return {void} + */ + bind: function(element,eventName,callback,scope){ + Ext.EventManager.addListener(element, eventName, callback, scope); + + //bind an observable to the element that will let us "trigger" events on it + var id = Ext.id(element, 'history-'), observable = this.observables[id]; + if (!observable) { + observable = Ext.create('Ext.util.Observable'); + this.observables[id] = observable; + } + observable.on(eventName, callback, scope); + }, + + /** + * History.Adapter.trigger(el,event) + * @param {Element|string} el + * @param {string} event - custom and standard events + * @param {Object=} extra - a object of extra event data (optional) + * @return {void} + */ + trigger: function(element,eventName,extra){ + var id = Ext.id(element, 'history-'), observable = this.observables[id]; + if (observable) { + observable.fireEvent(eventName, extra); + } + }, + + /** + * History.Adapter.extractEventData(key,event,extra) + * @param {string} key - key for the event data to extract + * @param {string} event - custom and standard events + * @param {Object=} extra - a object of extra event data (optional) + * @return {mixed} + */ + extractEventData: function(key,event,extra){ + var result = (event && event.browserEvent && event.browserEvent[key]) || (extra && extra[key]) || undefined; + return result; + }, + + /** + * History.Adapter.onDomLoad(callback) + * @param {function} callback + * @return {void} + */ + onDomLoad: function(callback) { + Ext.onReady(callback); + } + }; + + // Try and Initialise History + if ( typeof History.init !== 'undefined' ) { + History.init(); + } + +})(window); \ No newline at end of file diff --git a/sites/all/themes/gui/materiobasetheme/bower_components/history.js/scripts/uncompressed/history.adapter.jquery.js b/sites/all/themes/gui/materiobasetheme/bower_components/history.js/scripts/uncompressed/history.adapter.jquery.js new file mode 100644 index 00000000..8c252d5b --- /dev/null +++ b/sites/all/themes/gui/materiobasetheme/bower_components/history.js/scripts/uncompressed/history.adapter.jquery.js @@ -0,0 +1,77 @@ +/** + * History.js jQuery Adapter + * @author Benjamin Arthur Lupton + * @copyright 2010-2011 Benjamin Arthur Lupton + * @license New BSD License + */ + +// Closure +(function(window,undefined){ + "use strict"; + + // Localise Globals + var + History = window.History = window.History||{}, + jQuery = window.jQuery; + + // Check Existence + if ( typeof History.Adapter !== 'undefined' ) { + throw new Error('History.js Adapter has already been loaded...'); + } + + // Add the Adapter + History.Adapter = { + /** + * History.Adapter.bind(el,event,callback) + * @param {Element|string} el + * @param {string} event - custom and standard events + * @param {function} callback + * @return {void} + */ + bind: function(el,event,callback){ + jQuery(el).bind(event,callback); + }, + + /** + * History.Adapter.trigger(el,event) + * @param {Element|string} el + * @param {string} event - custom and standard events + * @param {Object=} extra - a object of extra event data (optional) + * @return {void} + */ + trigger: function(el,event,extra){ + jQuery(el).trigger(event,extra); + }, + + /** + * History.Adapter.extractEventData(key,event,extra) + * @param {string} key - key for the event data to extract + * @param {string} event - custom and standard events + * @param {Object=} extra - a object of extra event data (optional) + * @return {mixed} + */ + extractEventData: function(key,event,extra){ + // jQuery Native then jQuery Custom + var result = (event && event.originalEvent && event.originalEvent[key]) || (extra && extra[key]) || undefined; + + // Return + return result; + }, + + /** + * History.Adapter.onDomLoad(callback) + * @param {function} callback + * @return {void} + */ + onDomLoad: function(callback) { + jQuery(callback); + } + }; + + // Try and Initialise History + if ( typeof History.init !== 'undefined' ) { + History.init(); + } + +})(window); + diff --git a/sites/all/themes/gui/materiobasetheme/bower_components/history.js/scripts/uncompressed/history.adapter.mootools.js b/sites/all/themes/gui/materiobasetheme/bower_components/history.js/scripts/uncompressed/history.adapter.mootools.js new file mode 100644 index 00000000..404425c4 --- /dev/null +++ b/sites/all/themes/gui/materiobasetheme/bower_components/history.js/scripts/uncompressed/history.adapter.mootools.js @@ -0,0 +1,84 @@ +/** + * History.js MooTools Adapter + * @author Benjamin Arthur Lupton + * @copyright 2010-2011 Benjamin Arthur Lupton + * @license New BSD License + */ + +// Closure +(function(window,undefined){ + "use strict"; + + // Localise Globals + var + History = window.History = window.History||{}, + MooTools = window.MooTools, + Element = window.Element; + + // Check Existence + if ( typeof History.Adapter !== 'undefined' ) { + throw new Error('History.js Adapter has already been loaded...'); + } + + // Make MooTools aware of History.js Events + Object.append(Element.NativeEvents,{ + 'popstate':2, + 'hashchange':2 + }); + + // Add the Adapter + History.Adapter = { + /** + * History.Adapter.bind(el,event,callback) + * @param {Element|string} el + * @param {string} event - custom and standard events + * @param {function} callback + * @return {void} + */ + bind: function(el,event,callback){ + var El = typeof el === 'string' ? document.id(el) : el; + El.addEvent(event,callback); + }, + + /** + * History.Adapter.trigger(el,event) + * @param {Element|string} el + * @param {string} event - custom and standard events + * @param {Object=} extra - a object of extra event data (optional) + * @return void + */ + trigger: function(el,event,extra){ + var El = typeof el === 'string' ? document.id(el) : el; + El.fireEvent(event,extra); + }, + + /** + * History.Adapter.extractEventData(key,event,extra) + * @param {string} key - key for the event data to extract + * @param {string} event - custom and standard events + * @return {mixed} + */ + extractEventData: function(key,event){ + // MooTools Native then MooTools Custom + var result = (event && event.event && event.event[key]) || (event && event[key]) || undefined; + + // Return + return result; + }, + + /** + * History.Adapter.onDomLoad(callback) + * @param {function} callback + * @return {void} + */ + onDomLoad: function(callback) { + window.addEvent('domready',callback); + } + }; + + // Try and Initialise History + if ( typeof History.init !== 'undefined' ) { + History.init(); + } + +})(window); diff --git a/sites/all/themes/gui/materiobasetheme/bower_components/history.js/scripts/uncompressed/history.adapter.native.js b/sites/all/themes/gui/materiobasetheme/bower_components/history.js/scripts/uncompressed/history.adapter.native.js new file mode 100644 index 00000000..cb42fbd6 --- /dev/null +++ b/sites/all/themes/gui/materiobasetheme/bower_components/history.js/scripts/uncompressed/history.adapter.native.js @@ -0,0 +1,121 @@ +/** + * History.js Native Adapter + * @author Benjamin Arthur Lupton + * @copyright 2010-2011 Benjamin Arthur Lupton + * @license New BSD License + */ + +// Closure +(function(window,undefined){ + "use strict"; + + // Localise Globals + var History = window.History = window.History||{}; + + // Check Existence + if ( typeof History.Adapter !== 'undefined' ) { + throw new Error('History.js Adapter has already been loaded...'); + } + + // Add the Adapter + History.Adapter = { + /** + * History.Adapter.handlers[uid][eventName] = Array + */ + handlers: {}, + + /** + * History.Adapter._uid + * The current element unique identifier + */ + _uid: 1, + + /** + * History.Adapter.uid(element) + * @param {Element} element + * @return {String} uid + */ + uid: function(element){ + return element._uid || (element._uid = History.Adapter._uid++); + }, + + /** + * History.Adapter.bind(el,event,callback) + * @param {Element} element + * @param {String} eventName - custom and standard events + * @param {Function} callback + * @return + */ + bind: function(element,eventName,callback){ + // Prepare + var uid = History.Adapter.uid(element); + + // Apply Listener + History.Adapter.handlers[uid] = History.Adapter.handlers[uid] || {}; + History.Adapter.handlers[uid][eventName] = History.Adapter.handlers[uid][eventName] || []; + History.Adapter.handlers[uid][eventName].push(callback); + + // Bind Global Listener + element['on'+eventName] = (function(element,eventName){ + return function(event){ + History.Adapter.trigger(element,eventName,event); + }; + })(element,eventName); + }, + + /** + * History.Adapter.trigger(el,event) + * @param {Element} element + * @param {String} eventName - custom and standard events + * @param {Object} event - a object of event data + * @return + */ + trigger: function(element,eventName,event){ + // Prepare + event = event || {}; + var uid = History.Adapter.uid(element), + i,n; + + // Apply Listener + History.Adapter.handlers[uid] = History.Adapter.handlers[uid] || {}; + History.Adapter.handlers[uid][eventName] = History.Adapter.handlers[uid][eventName] || []; + + // Fire Listeners + for ( i=0,n=History.Adapter.handlers[uid][eventName].length; i + * @copyright 2010-2011 Benjamin Arthur Lupton + * @license New BSD License + */ + +// Closure +(function(window,undefined){ + "use strict"; + + // Localise Globals + var + History = window.History = window.History||{}, + document = window.document, + RightJS = window.RightJS, + $ = RightJS.$; + + // Check Existence + if ( typeof History.Adapter !== 'undefined' ) { + throw new Error('History.js Adapter has already been loaded...'); + } + + // Add the Adapter + History.Adapter = { + /** + * History.Adapter.bind(el,event,callback) + * @param {Element|Selector} el + * @param {String} event - custom and standard events + * @param {Function} callback + * @return + */ + bind: function(el,event,callback){ + $(el).on(event,callback); + }, + + /** + * History.Adapter.trigger(el,event) + * @param {Element|Selector} el + * @param {String} event - custom and standard events + * @param {Object} extraEventData - a object of extra event data + * @return + */ + trigger: function(el,event,extraEventData){ + $(el).fire(event,extraEventData); + }, + + /** + * History.Adapter.extractEventData(key,event,extra) + * @param {String} key - key for the event data to extract + * @param {String} event - custom and standard events + * @return {mixed} + */ + extractEventData: function(key,event){ + // Right.js Native + // Right.js Custom + var result = (event && event._ && event._[key]) || undefined; + + // Return + return result; + }, + + /** + * History.Adapter.onDomLoad(callback) + * @param {Function} callback + * @return + */ + onDomLoad: function(callback) { + $(document).onReady(callback); + } + }; + + // Try and Initialise History + if ( typeof History.init !== 'undefined' ) { + History.init(); + } + +})(window); diff --git a/sites/all/themes/gui/materiobasetheme/bower_components/history.js/scripts/uncompressed/history.adapter.zepto.js b/sites/all/themes/gui/materiobasetheme/bower_components/history.js/scripts/uncompressed/history.adapter.zepto.js new file mode 100644 index 00000000..f1295f9d --- /dev/null +++ b/sites/all/themes/gui/materiobasetheme/bower_components/history.js/scripts/uncompressed/history.adapter.zepto.js @@ -0,0 +1,74 @@ +/** + * History.js Zepto Adapter + * @author Benjamin Arthur Lupton + * @copyright 2010-2011 Benjamin Arthur Lupton + * @license New BSD License + */ + +// Closure +(function(window,undefined){ + "use strict"; + + // Localise Globals + var + History = window.History = window.History||{}, + Zepto = window.Zepto; + + // Check Existence + if ( typeof History.Adapter !== 'undefined' ) { + throw new Error('History.js Adapter has already been loaded...'); + } + + // Add the Adapter + History.Adapter = { + /** + * History.Adapter.bind(el,event,callback) + * @param {Element|string} el + * @param {string} event - custom and standard events + * @param {function} callback + * @return {void} + */ + bind: function(el,event,callback){ + new Zepto(el).bind(event,callback); + }, + + /** + * History.Adapter.trigger(el,event) + * @param {Element|string} el + * @param {string} event - custom and standard events + * @return {void} + */ + trigger: function(el,event){ + new Zepto(el).trigger(event); + }, + + /** + * History.Adapter.extractEventData(key,event,extra) + * @param {string} key - key for the event data to extract + * @param {string} event - custom and standard events + * @return {mixed} + */ + extractEventData: function(key,event){ + // Zepto Native + var result = (event && event[key]) || undefined; + + // Return + return result; + }, + + /** + * History.Adapter.onDomLoad(callback) + * @param {function} callback + * @return {void} + */ + onDomLoad: function(callback) { + new Zepto(callback); + } + }; + + // Try and Initialise History + if ( typeof History.init !== 'undefined' ) { + History.init(); + } + +})(window); diff --git a/sites/all/themes/gui/materiobasetheme/bower_components/history.js/scripts/uncompressed/history.html4.js b/sites/all/themes/gui/materiobasetheme/bower_components/history.js/scripts/uncompressed/history.html4.js new file mode 100644 index 00000000..610c8ee6 --- /dev/null +++ b/sites/all/themes/gui/materiobasetheme/bower_components/history.js/scripts/uncompressed/history.html4.js @@ -0,0 +1,685 @@ +/** + * History.js HTML4 Support + * Depends on the HTML5 Support + * @author Benjamin Arthur Lupton + * @copyright 2010-2011 Benjamin Arthur Lupton + * @license New BSD License + */ + +(function(window,undefined){ + "use strict"; + + // ======================================================================== + // Initialise + + // Localise Globals + var + document = window.document, // Make sure we are using the correct document + setTimeout = window.setTimeout||setTimeout, + clearTimeout = window.clearTimeout||clearTimeout, + setInterval = window.setInterval||setInterval, + History = window.History = window.History||{}; // Public History Object + + // Check Existence + if ( typeof History.initHtml4 !== 'undefined' ) { + throw new Error('History.js HTML4 Support has already been loaded...'); + } + + + // ======================================================================== + // Initialise HTML4 Support + + // Initialise HTML4 Support + History.initHtml4 = function(){ + // Initialise + if ( typeof History.initHtml4.initialized !== 'undefined' ) { + // Already Loaded + return false; + } + else { + History.initHtml4.initialized = true; + } + + + // ==================================================================== + // Properties + + /** + * History.enabled + * Is History enabled? + */ + History.enabled = true; + + + // ==================================================================== + // Hash Storage + + /** + * History.savedHashes + * Store the hashes in an array + */ + History.savedHashes = []; + + /** + * History.isLastHash(newHash) + * Checks if the hash is the last hash + * @param {string} newHash + * @return {boolean} true + */ + History.isLastHash = function(newHash){ + // Prepare + var oldHash = History.getHashByIndex(), + isLast; + + // Check + isLast = newHash === oldHash; + + // Return isLast + return isLast; + }; + + /** + * History.isHashEqual(newHash, oldHash) + * Checks to see if two hashes are functionally equal + * @param {string} newHash + * @param {string} oldHash + * @return {boolean} true + */ + History.isHashEqual = function(newHash, oldHash){ + newHash = encodeURIComponent(newHash).replace(/%25/g, "%"); + oldHash = encodeURIComponent(oldHash).replace(/%25/g, "%"); + return newHash === oldHash; + }; + + /** + * History.saveHash(newHash) + * Push a Hash + * @param {string} newHash + * @return {boolean} true + */ + History.saveHash = function(newHash){ + // Check Hash + if ( History.isLastHash(newHash) ) { + return false; + } + + // Push the Hash + History.savedHashes.push(newHash); + + // Return true + return true; + }; + + /** + * History.getHashByIndex() + * Gets a hash by the index + * @param {integer} index + * @return {string} + */ + History.getHashByIndex = function(index){ + // Prepare + var hash = null; + + // Handle + if ( typeof index === 'undefined' ) { + // Get the last inserted + hash = History.savedHashes[History.savedHashes.length-1]; + } + else if ( index < 0 ) { + // Get from the end + hash = History.savedHashes[History.savedHashes.length+index]; + } + else { + // Get from the beginning + hash = History.savedHashes[index]; + } + + // Return hash + return hash; + }; + + + // ==================================================================== + // Discarded States + + /** + * History.discardedHashes + * A hashed array of discarded hashes + */ + History.discardedHashes = {}; + + /** + * History.discardedStates + * A hashed array of discarded states + */ + History.discardedStates = {}; + + /** + * History.discardState(State) + * Discards the state by ignoring it through History + * @param {object} State + * @return {true} + */ + History.discardState = function(discardedState,forwardState,backState){ + //History.debug('History.discardState', arguments); + // Prepare + var discardedStateHash = History.getHashByState(discardedState), + discardObject; + + // Create Discard Object + discardObject = { + 'discardedState': discardedState, + 'backState': backState, + 'forwardState': forwardState + }; + + // Add to DiscardedStates + History.discardedStates[discardedStateHash] = discardObject; + + // Return true + return true; + }; + + /** + * History.discardHash(hash) + * Discards the hash by ignoring it through History + * @param {string} hash + * @return {true} + */ + History.discardHash = function(discardedHash,forwardState,backState){ + //History.debug('History.discardState', arguments); + // Create Discard Object + var discardObject = { + 'discardedHash': discardedHash, + 'backState': backState, + 'forwardState': forwardState + }; + + // Add to discardedHash + History.discardedHashes[discardedHash] = discardObject; + + // Return true + return true; + }; + + /** + * History.discardedState(State) + * Checks to see if the state is discarded + * @param {object} State + * @return {bool} + */ + History.discardedState = function(State){ + // Prepare + var StateHash = History.getHashByState(State), + discarded; + + // Check + discarded = History.discardedStates[StateHash]||false; + + // Return true + return discarded; + }; + + /** + * History.discardedHash(hash) + * Checks to see if the state is discarded + * @param {string} State + * @return {bool} + */ + History.discardedHash = function(hash){ + // Check + var discarded = History.discardedHashes[hash]||false; + + // Return true + return discarded; + }; + + /** + * History.recycleState(State) + * Allows a discarded state to be used again + * @param {object} data + * @param {string} title + * @param {string} url + * @return {true} + */ + History.recycleState = function(State){ + //History.debug('History.recycleState', arguments); + // Prepare + var StateHash = History.getHashByState(State); + + // Remove from DiscardedStates + if ( History.discardedState(State) ) { + delete History.discardedStates[StateHash]; + } + + // Return true + return true; + }; + + + // ==================================================================== + // HTML4 HashChange Support + + if ( History.emulated.hashChange ) { + /* + * We must emulate the HTML4 HashChange Support by manually checking for hash changes + */ + + /** + * History.hashChangeInit() + * Init the HashChange Emulation + */ + History.hashChangeInit = function(){ + // Define our Checker Function + History.checkerFunction = null; + + // Define some variables that will help in our checker function + var lastDocumentHash = '', + iframeId, iframe, + lastIframeHash, checkerRunning, + startedWithHash = Boolean(History.getHash()); + + // Handle depending on the browser + if ( History.isInternetExplorer() ) { + // IE6 and IE7 + // We need to use an iframe to emulate the back and forward buttons + + // Create iFrame + iframeId = 'historyjs-iframe'; + iframe = document.createElement('iframe'); + + // Adjust iFarme + // IE 6 requires iframe to have a src on HTTPS pages, otherwise it will throw a + // "This page contains both secure and nonsecure items" warning. + iframe.setAttribute('id', iframeId); + iframe.setAttribute('src', '#'); + iframe.style.display = 'none'; + + // Append iFrame + document.body.appendChild(iframe); + + // Create initial history entry + iframe.contentWindow.document.open(); + iframe.contentWindow.document.close(); + + // Define some variables that will help in our checker function + lastIframeHash = ''; + checkerRunning = false; + + // Define the checker function + History.checkerFunction = function(){ + // Check Running + if ( checkerRunning ) { + return false; + } + + // Update Running + checkerRunning = true; + + // Fetch + var + documentHash = History.getHash(), + iframeHash = History.getHash(iframe.contentWindow.document); + + // The Document Hash has changed (application caused) + if ( documentHash !== lastDocumentHash ) { + // Equalise + lastDocumentHash = documentHash; + + // Create a history entry in the iframe + if ( iframeHash !== documentHash ) { + //History.debug('hashchange.checker: iframe hash change', 'documentHash (new):', documentHash, 'iframeHash (old):', iframeHash); + + // Equalise + lastIframeHash = iframeHash = documentHash; + + // Create History Entry + iframe.contentWindow.document.open(); + iframe.contentWindow.document.close(); + + // Update the iframe's hash + iframe.contentWindow.document.location.hash = History.escapeHash(documentHash); + } + + // Trigger Hashchange Event + History.Adapter.trigger(window,'hashchange'); + } + + // The iFrame Hash has changed (back button caused) + else if ( iframeHash !== lastIframeHash ) { + //History.debug('hashchange.checker: iframe hash out of sync', 'iframeHash (new):', iframeHash, 'documentHash (old):', documentHash); + + // Equalise + lastIframeHash = iframeHash; + + // If there is no iframe hash that means we're at the original + // iframe state. + // And if there was a hash on the original request, the original + // iframe state was replaced instantly, so skip this state and take + // the user back to where they came from. + if (startedWithHash && iframeHash === '') { + History.back(); + } + else { + // Update the Hash + History.setHash(iframeHash,false); + } + } + + // Reset Running + checkerRunning = false; + + // Return true + return true; + }; + } + else { + // We are not IE + // Firefox 1 or 2, Opera + + // Define the checker function + History.checkerFunction = function(){ + // Prepare + var documentHash = History.getHash()||''; + + // The Document Hash has changed (application caused) + if ( documentHash !== lastDocumentHash ) { + // Equalise + lastDocumentHash = documentHash; + + // Trigger Hashchange Event + History.Adapter.trigger(window,'hashchange'); + } + + // Return true + return true; + }; + } + + // Apply the checker function + History.intervalList.push(setInterval(History.checkerFunction, History.options.hashChangeInterval)); + + // Done + return true; + }; // History.hashChangeInit + + // Bind hashChangeInit + History.Adapter.onDomLoad(History.hashChangeInit); + + } // History.emulated.hashChange + + + // ==================================================================== + // HTML5 State Support + + // Non-Native pushState Implementation + if ( History.emulated.pushState ) { + /* + * We must emulate the HTML5 State Management by using HTML4 HashChange + */ + + /** + * History.onHashChange(event) + * Trigger HTML5's window.onpopstate via HTML4 HashChange Support + */ + History.onHashChange = function(event){ + //History.debug('History.onHashChange', arguments); + + // Prepare + var currentUrl = ((event && event.newURL) || History.getLocationHref()), + currentHash = History.getHashByUrl(currentUrl), + currentState = null, + currentStateHash = null, + currentStateHashExits = null, + discardObject; + + // Check if we are the same state + if ( History.isLastHash(currentHash) ) { + // There has been no change (just the page's hash has finally propagated) + //History.debug('History.onHashChange: no change'); + History.busy(false); + return false; + } + + // Reset the double check + History.doubleCheckComplete(); + + // Store our location for use in detecting back/forward direction + History.saveHash(currentHash); + + // Expand Hash + if ( currentHash && History.isTraditionalAnchor(currentHash) ) { + //History.debug('History.onHashChange: traditional anchor', currentHash); + // Traditional Anchor Hash + History.Adapter.trigger(window,'anchorchange'); + History.busy(false); + return false; + } + + // Create State + currentState = History.extractState(History.getFullUrl(currentHash||History.getLocationHref()),true); + + // Check if we are the same state + if ( History.isLastSavedState(currentState) ) { + //History.debug('History.onHashChange: no change'); + // There has been no change (just the page's hash has finally propagated) + History.busy(false); + return false; + } + + // Create the state Hash + currentStateHash = History.getHashByState(currentState); + + // Check if we are DiscardedState + discardObject = History.discardedState(currentState); + if ( discardObject ) { + // Ignore this state as it has been discarded and go back to the state before it + if ( History.getHashByIndex(-2) === History.getHashByState(discardObject.forwardState) ) { + // We are going backwards + //History.debug('History.onHashChange: go backwards'); + History.back(false); + } else { + // We are going forwards + //History.debug('History.onHashChange: go forwards'); + History.forward(false); + } + return false; + } + + // Push the new HTML5 State + //History.debug('History.onHashChange: success hashchange'); + History.pushState(currentState.data,currentState.title,encodeURI(currentState.url),false); + + // End onHashChange closure + return true; + }; + History.Adapter.bind(window,'hashchange',History.onHashChange); + + /** + * History.pushState(data,title,url) + * Add a new State to the history object, become it, and trigger onpopstate + * We have to trigger for HTML4 compatibility + * @param {object} data + * @param {string} title + * @param {string} url + * @return {true} + */ + History.pushState = function(data,title,url,queue){ + //History.debug('History.pushState: called', arguments); + + // We assume that the URL passed in is URI-encoded, but this makes + // sure that it's fully URI encoded; any '%'s that are encoded are + // converted back into '%'s + url = encodeURI(url).replace(/%25/g, "%"); + + // Check the State + if ( History.getHashByUrl(url) ) { + throw new Error('History.js does not support states with fragment-identifiers (hashes/anchors).'); + } + + // Handle Queueing + if ( queue !== false && History.busy() ) { + // Wait + Push to Queue + //History.debug('History.pushState: we must wait', arguments); + History.pushQueue({ + scope: History, + callback: History.pushState, + args: arguments, + queue: queue + }); + return false; + } + + // Make Busy + History.busy(true); + + // Fetch the State Object + var newState = History.createStateObject(data,title,url), + newStateHash = History.getHashByState(newState), + oldState = History.getState(false), + oldStateHash = History.getHashByState(oldState), + html4Hash = History.getHash(), + wasExpected = History.expectedStateId == newState.id; + + // Store the newState + History.storeState(newState); + History.expectedStateId = newState.id; + + // Recycle the State + History.recycleState(newState); + + // Force update of the title + History.setTitle(newState); + + // Check if we are the same State + if ( newStateHash === oldStateHash ) { + //History.debug('History.pushState: no change', newStateHash); + History.busy(false); + return false; + } + + // Update HTML5 State + History.saveState(newState); + + // Fire HTML5 Event + if(!wasExpected) + History.Adapter.trigger(window,'statechange'); + + // Update HTML4 Hash + if ( !History.isHashEqual(newStateHash, html4Hash) && !History.isHashEqual(newStateHash, History.getShortUrl(History.getLocationHref())) ) { + History.setHash(newStateHash,false); + } + + History.busy(false); + + // End pushState closure + return true; + }; + + /** + * History.replaceState(data,title,url) + * Replace the State and trigger onpopstate + * We have to trigger for HTML4 compatibility + * @param {object} data + * @param {string} title + * @param {string} url + * @return {true} + */ + History.replaceState = function(data,title,url,queue){ + //History.debug('History.replaceState: called', arguments); + + // We assume that the URL passed in is URI-encoded, but this makes + // sure that it's fully URI encoded; any '%'s that are encoded are + // converted back into '%'s + url = encodeURI(url).replace(/%25/g, "%"); + + // Check the State + if ( History.getHashByUrl(url) ) { + throw new Error('History.js does not support states with fragment-identifiers (hashes/anchors).'); + } + + // Handle Queueing + if ( queue !== false && History.busy() ) { + // Wait + Push to Queue + //History.debug('History.replaceState: we must wait', arguments); + History.pushQueue({ + scope: History, + callback: History.replaceState, + args: arguments, + queue: queue + }); + return false; + } + + // Make Busy + History.busy(true); + + // Fetch the State Objects + var newState = History.createStateObject(data,title,url), + newStateHash = History.getHashByState(newState), + oldState = History.getState(false), + oldStateHash = History.getHashByState(oldState), + previousState = History.getStateByIndex(-2); + + // Discard Old State + History.discardState(oldState,newState,previousState); + + // If the url hasn't changed, just store and save the state + // and fire a statechange event to be consistent with the + // html 5 api + if ( newStateHash === oldStateHash ) { + // Store the newState + History.storeState(newState); + History.expectedStateId = newState.id; + + // Recycle the State + History.recycleState(newState); + + // Force update of the title + History.setTitle(newState); + + // Update HTML5 State + History.saveState(newState); + + // Fire HTML5 Event + //History.debug('History.pushState: trigger popstate'); + History.Adapter.trigger(window,'statechange'); + History.busy(false); + } + else { + // Alias to PushState + History.pushState(newState.data,newState.title,newState.url,false); + } + + // End replaceState closure + return true; + }; + + } // History.emulated.pushState + + + + // ==================================================================== + // Initialise + + // Non-Native pushState Implementation + if ( History.emulated.pushState ) { + /** + * Ensure initial state is handled correctly + */ + if ( History.getHash() && !History.emulated.hashChange ) { + History.Adapter.onDomLoad(function(){ + History.Adapter.trigger(window,'hashchange'); + }); + } + + } // History.emulated.pushState + + }; // History.initHtml4 + + // Try to Initialise History + if ( typeof History.init !== 'undefined' ) { + History.init(); + } + +})(window); diff --git a/sites/all/themes/gui/materiobasetheme/bower_components/history.js/scripts/uncompressed/history.js b/sites/all/themes/gui/materiobasetheme/bower_components/history.js/scripts/uncompressed/history.js new file mode 100644 index 00000000..299e7721 --- /dev/null +++ b/sites/all/themes/gui/materiobasetheme/bower_components/history.js/scripts/uncompressed/history.js @@ -0,0 +1,2044 @@ +/** + * History.js Core + * @author Benjamin Arthur Lupton + * @copyright 2010-2011 Benjamin Arthur Lupton + * @license New BSD License + */ + +(function(window,undefined){ + "use strict"; + + // ======================================================================== + // Initialise + + // Localise Globals + var + console = window.console||undefined, // Prevent a JSLint complain + document = window.document, // Make sure we are using the correct document + navigator = window.navigator, // Make sure we are using the correct navigator + sessionStorage = window.sessionStorage||false, // sessionStorage + setTimeout = window.setTimeout, + clearTimeout = window.clearTimeout, + setInterval = window.setInterval, + clearInterval = window.clearInterval, + JSON = window.JSON, + alert = window.alert, + History = window.History = window.History||{}, // Public History Object + history = window.history; // Old History Object + + try { + sessionStorage.setItem('TEST', '1'); + sessionStorage.removeItem('TEST'); + } catch(e) { + sessionStorage = false; + } + + // MooTools Compatibility + JSON.stringify = JSON.stringify||JSON.encode; + JSON.parse = JSON.parse||JSON.decode; + + // Check Existence + if ( typeof History.init !== 'undefined' ) { + throw new Error('History.js Core has already been loaded...'); + } + + // Initialise History + History.init = function(options){ + // Check Load Status of Adapter + if ( typeof History.Adapter === 'undefined' ) { + return false; + } + + // Check Load Status of Core + if ( typeof History.initCore !== 'undefined' ) { + History.initCore(); + } + + // Check Load Status of HTML4 Support + if ( typeof History.initHtml4 !== 'undefined' ) { + History.initHtml4(); + } + + // Return true + return true; + }; + + + // ======================================================================== + // Initialise Core + + // Initialise Core + History.initCore = function(options){ + // Initialise + if ( typeof History.initCore.initialized !== 'undefined' ) { + // Already Loaded + return false; + } + else { + History.initCore.initialized = true; + } + + + // ==================================================================== + // Options + + /** + * History.options + * Configurable options + */ + History.options = History.options||{}; + + /** + * History.options.hashChangeInterval + * How long should the interval be before hashchange checks + */ + History.options.hashChangeInterval = History.options.hashChangeInterval || 100; + + /** + * History.options.safariPollInterval + * How long should the interval be before safari poll checks + */ + History.options.safariPollInterval = History.options.safariPollInterval || 500; + + /** + * History.options.doubleCheckInterval + * How long should the interval be before we perform a double check + */ + History.options.doubleCheckInterval = History.options.doubleCheckInterval || 500; + + /** + * History.options.disableSuid + * Force History not to append suid + */ + History.options.disableSuid = History.options.disableSuid || false; + + /** + * History.options.storeInterval + * How long should we wait between store calls + */ + History.options.storeInterval = History.options.storeInterval || 1000; + + /** + * History.options.busyDelay + * How long should we wait between busy events + */ + History.options.busyDelay = History.options.busyDelay || 250; + + /** + * History.options.debug + * If true will enable debug messages to be logged + */ + History.options.debug = History.options.debug || false; + + /** + * History.options.initialTitle + * What is the title of the initial state + */ + History.options.initialTitle = History.options.initialTitle || document.title; + + /** + * History.options.html4Mode + * If true, will force HTMl4 mode (hashtags) + */ + History.options.html4Mode = History.options.html4Mode || false; + + /** + * History.options.delayInit + * Want to override default options and call init manually. + */ + History.options.delayInit = History.options.delayInit || false; + + + // ==================================================================== + // Interval record + + /** + * History.intervalList + * List of intervals set, to be cleared when document is unloaded. + */ + History.intervalList = []; + + /** + * History.clearAllIntervals + * Clears all setInterval instances. + */ + History.clearAllIntervals = function(){ + var i, il = History.intervalList; + if (typeof il !== "undefined" && il !== null) { + for (i = 0; i < il.length; i++) { + clearInterval(il[i]); + } + History.intervalList = null; + } + }; + + + // ==================================================================== + // Debug + + /** + * History.debug(message,...) + * Logs the passed arguments if debug enabled + */ + History.debug = function(){ + if ( (History.options.debug||false) ) { + History.log.apply(History,arguments); + } + }; + + /** + * History.log(message,...) + * Logs the passed arguments + */ + History.log = function(){ + // Prepare + var + consoleExists = !(typeof console === 'undefined' || typeof console.log === 'undefined' || typeof console.log.apply === 'undefined'), + textarea = document.getElementById('log'), + message, + i,n, + args,arg + ; + + // Write to Console + if ( consoleExists ) { + args = Array.prototype.slice.call(arguments); + message = args.shift(); + if ( typeof console.debug !== 'undefined' ) { + console.debug.apply(console,[message,args]); + } + else { + console.log.apply(console,[message,args]); + } + } + else { + message = ("\n"+arguments[0]+"\n"); + } + + // Write to log + for ( i=1,n=arguments.length; i + * @author James Padolsey + */ + History.getInternetExplorerMajorVersion = function(){ + var result = History.getInternetExplorerMajorVersion.cached = + (typeof History.getInternetExplorerMajorVersion.cached !== 'undefined') + ? History.getInternetExplorerMajorVersion.cached + : (function(){ + var v = 3, + div = document.createElement('div'), + all = div.getElementsByTagName('i'); + while ( (div.innerHTML = '') && all[0] ) {} + return (v > 4) ? v : false; + })() + ; + return result; + }; + + /** + * History.isInternetExplorer() + * Are we using Internet Explorer? + * @return {boolean} + * @license Public Domain + * @author Benjamin Arthur Lupton + */ + History.isInternetExplorer = function(){ + var result = + History.isInternetExplorer.cached = + (typeof History.isInternetExplorer.cached !== 'undefined') + ? History.isInternetExplorer.cached + : Boolean(History.getInternetExplorerMajorVersion()) + ; + return result; + }; + + /** + * History.emulated + * Which features require emulating? + */ + + if (History.options.html4Mode) { + History.emulated = { + pushState : true, + hashChange: true + }; + } + + else { + + History.emulated = { + pushState: !Boolean( + window.history && window.history.pushState && window.history.replaceState + && !( + (/ Mobile\/([1-7][a-z]|(8([abcde]|f(1[0-8]))))/i).test(navigator.userAgent) /* disable for versions of iOS before version 4.3 (8F190) */ + || (/AppleWebKit\/5([0-2]|3[0-2])/i).test(navigator.userAgent) /* disable for the mercury iOS browser, or at least older versions of the webkit engine */ + ) + ), + hashChange: Boolean( + !(('onhashchange' in window) || ('onhashchange' in document)) + || + (History.isInternetExplorer() && History.getInternetExplorerMajorVersion() < 8) + ) + }; + } + + /** + * History.enabled + * Is History enabled? + */ + History.enabled = !History.emulated.pushState; + + /** + * History.bugs + * Which bugs are present + */ + History.bugs = { + /** + * Safari 5 and Safari iOS 4 fail to return to the correct state once a hash is replaced by a `replaceState` call + * https://bugs.webkit.org/show_bug.cgi?id=56249 + */ + setHash: Boolean(!History.emulated.pushState && navigator.vendor === 'Apple Computer, Inc.' && /AppleWebKit\/5([0-2]|3[0-3])/.test(navigator.userAgent)), + + /** + * Safari 5 and Safari iOS 4 sometimes fail to apply the state change under busy conditions + * https://bugs.webkit.org/show_bug.cgi?id=42940 + */ + safariPoll: Boolean(!History.emulated.pushState && navigator.vendor === 'Apple Computer, Inc.' && /AppleWebKit\/5([0-2]|3[0-3])/.test(navigator.userAgent)), + + /** + * MSIE 6 and 7 sometimes do not apply a hash even it was told to (requiring a second call to the apply function) + */ + ieDoubleCheck: Boolean(History.isInternetExplorer() && History.getInternetExplorerMajorVersion() < 8), + + /** + * MSIE 6 requires the entire hash to be encoded for the hashes to trigger the onHashChange event + */ + hashEscape: Boolean(History.isInternetExplorer() && History.getInternetExplorerMajorVersion() < 7) + }; + + /** + * History.isEmptyObject(obj) + * Checks to see if the Object is Empty + * @param {Object} obj + * @return {boolean} + */ + History.isEmptyObject = function(obj) { + for ( var name in obj ) { + if ( obj.hasOwnProperty(name) ) { + return false; + } + } + return true; + }; + + /** + * History.cloneObject(obj) + * Clones a object and eliminate all references to the original contexts + * @param {Object} obj + * @return {Object} + */ + History.cloneObject = function(obj) { + var hash,newObj; + if ( obj ) { + hash = JSON.stringify(obj); + newObj = JSON.parse(hash); + } + else { + newObj = {}; + } + return newObj; + }; + + + // ==================================================================== + // URL Helpers + + /** + * History.getRootUrl() + * Turns "http://mysite.com/dir/page.html?asd" into "http://mysite.com" + * @return {String} rootUrl + */ + History.getRootUrl = function(){ + // Create + var rootUrl = document.location.protocol+'//'+(document.location.hostname||document.location.host); + if ( document.location.port||false ) { + rootUrl += ':'+document.location.port; + } + rootUrl += '/'; + + // Return + return rootUrl; + }; + + /** + * History.getBaseHref() + * Fetches the `href` attribute of the `` element if it exists + * @return {String} baseHref + */ + History.getBaseHref = function(){ + // Create + var + baseElements = document.getElementsByTagName('base'), + baseElement = null, + baseHref = ''; + + // Test for Base Element + if ( baseElements.length === 1 ) { + // Prepare for Base Element + baseElement = baseElements[0]; + baseHref = baseElement.href.replace(/[^\/]+$/,''); + } + + // Adjust trailing slash + baseHref = baseHref.replace(/\/+$/,''); + if ( baseHref ) baseHref += '/'; + + // Return + return baseHref; + }; + + /** + * History.getBaseUrl() + * Fetches the baseHref or basePageUrl or rootUrl (whichever one exists first) + * @return {String} baseUrl + */ + History.getBaseUrl = function(){ + // Create + var baseUrl = History.getBaseHref()||History.getBasePageUrl()||History.getRootUrl(); + + // Return + return baseUrl; + }; + + /** + * History.getPageUrl() + * Fetches the URL of the current page + * @return {String} pageUrl + */ + History.getPageUrl = function(){ + // Fetch + var + State = History.getState(false,false), + stateUrl = (State||{}).url||History.getLocationHref(), + pageUrl; + + // Create + pageUrl = stateUrl.replace(/\/+$/,'').replace(/[^\/]+$/,function(part,index,string){ + return (/\./).test(part) ? part : part+'/'; + }); + + // Return + return pageUrl; + }; + + /** + * History.getBasePageUrl() + * Fetches the Url of the directory of the current page + * @return {String} basePageUrl + */ + History.getBasePageUrl = function(){ + // Create + var basePageUrl = (History.getLocationHref()).replace(/[#\?].*/,'').replace(/[^\/]+$/,function(part,index,string){ + return (/[^\/]$/).test(part) ? '' : part; + }).replace(/\/+$/,'')+'/'; + + // Return + return basePageUrl; + }; + + /** + * History.getFullUrl(url) + * Ensures that we have an absolute URL and not a relative URL + * @param {string} url + * @param {Boolean} allowBaseHref + * @return {string} fullUrl + */ + History.getFullUrl = function(url,allowBaseHref){ + // Prepare + var fullUrl = url, firstChar = url.substring(0,1); + allowBaseHref = (typeof allowBaseHref === 'undefined') ? true : allowBaseHref; + + // Check + if ( /[a-z]+\:\/\//.test(url) ) { + // Full URL + } + else if ( firstChar === '/' ) { + // Root URL + fullUrl = History.getRootUrl()+url.replace(/^\/+/,''); + } + else if ( firstChar === '#' ) { + // Anchor URL + fullUrl = History.getPageUrl().replace(/#.*/,'')+url; + } + else if ( firstChar === '?' ) { + // Query URL + fullUrl = History.getPageUrl().replace(/[\?#].*/,'')+url; + } + else { + // Relative URL + if ( allowBaseHref ) { + fullUrl = History.getBaseUrl()+url.replace(/^(\.\/)+/,''); + } else { + fullUrl = History.getBasePageUrl()+url.replace(/^(\.\/)+/,''); + } + // We have an if condition above as we do not want hashes + // which are relative to the baseHref in our URLs + // as if the baseHref changes, then all our bookmarks + // would now point to different locations + // whereas the basePageUrl will always stay the same + } + + // Return + return fullUrl.replace(/\#$/,''); + }; + + /** + * History.getShortUrl(url) + * Ensures that we have a relative URL and not a absolute URL + * @param {string} url + * @return {string} url + */ + History.getShortUrl = function(url){ + // Prepare + var shortUrl = url, baseUrl = History.getBaseUrl(), rootUrl = History.getRootUrl(); + + // Trim baseUrl + if ( History.emulated.pushState ) { + // We are in a if statement as when pushState is not emulated + // The actual url these short urls are relative to can change + // So within the same session, we the url may end up somewhere different + shortUrl = shortUrl.replace(baseUrl,''); + } + + // Trim rootUrl + shortUrl = shortUrl.replace(rootUrl,'/'); + + // Ensure we can still detect it as a state + if ( History.isTraditionalAnchor(shortUrl) ) { + shortUrl = './'+shortUrl; + } + + // Clean It + shortUrl = shortUrl.replace(/^(\.\/)+/g,'./').replace(/\#$/,''); + + // Return + return shortUrl; + }; + + /** + * History.getLocationHref(document) + * Returns a normalized version of document.location.href + * accounting for browser inconsistencies, etc. + * + * This URL will be URI-encoded and will include the hash + * + * @param {object} document + * @return {string} url + */ + History.getLocationHref = function(doc) { + doc = doc || document; + + // most of the time, this will be true + if (doc.URL === doc.location.href) + return doc.location.href; + + // some versions of webkit URI-decode document.location.href + // but they leave document.URL in an encoded state + if (doc.location.href === decodeURIComponent(doc.URL)) + return doc.URL; + + // FF 3.6 only updates document.URL when a page is reloaded + // document.location.href is updated correctly + if (doc.location.hash && decodeURIComponent(doc.location.href.replace(/^[^#]+/, "")) === doc.location.hash) + return doc.location.href; + + if (doc.URL.indexOf('#') == -1 && doc.location.href.indexOf('#') != -1) + return doc.location.href; + + return doc.URL || doc.location.href; + }; + + + // ==================================================================== + // State Storage + + /** + * History.store + * The store for all session specific data + */ + History.store = {}; + + /** + * History.idToState + * 1-1: State ID to State Object + */ + History.idToState = History.idToState||{}; + + /** + * History.stateToId + * 1-1: State String to State ID + */ + History.stateToId = History.stateToId||{}; + + /** + * History.urlToId + * 1-1: State URL to State ID + */ + History.urlToId = History.urlToId||{}; + + /** + * History.storedStates + * Store the states in an array + */ + History.storedStates = History.storedStates||[]; + + /** + * History.savedStates + * Saved the states in an array + */ + History.savedStates = History.savedStates||[]; + + /** + * History.noramlizeStore() + * Noramlize the store by adding necessary values + */ + History.normalizeStore = function(){ + History.store.idToState = History.store.idToState||{}; + History.store.urlToId = History.store.urlToId||{}; + History.store.stateToId = History.store.stateToId||{}; + }; + + /** + * History.getState() + * Get an object containing the data, title and url of the current state + * @param {Boolean} friendly + * @param {Boolean} create + * @return {Object} State + */ + History.getState = function(friendly,create){ + // Prepare + if ( typeof friendly === 'undefined' ) { friendly = true; } + if ( typeof create === 'undefined' ) { create = true; } + + // Fetch + var State = History.getLastSavedState(); + + // Create + if ( !State && create ) { + State = History.createStateObject(); + } + + // Adjust + if ( friendly ) { + State = History.cloneObject(State); + State.url = State.cleanUrl||State.url; + } + + // Return + return State; + }; + + /** + * History.getIdByState(State) + * Gets a ID for a State + * @param {State} newState + * @return {String} id + */ + History.getIdByState = function(newState){ + + // Fetch ID + var id = History.extractId(newState.url), + str; + + if ( !id ) { + // Find ID via State String + str = History.getStateString(newState); + if ( typeof History.stateToId[str] !== 'undefined' ) { + id = History.stateToId[str]; + } + else if ( typeof History.store.stateToId[str] !== 'undefined' ) { + id = History.store.stateToId[str]; + } + else { + // Generate a new ID + while ( true ) { + id = (new Date()).getTime() + String(Math.random()).replace(/\D/g,''); + if ( typeof History.idToState[id] === 'undefined' && typeof History.store.idToState[id] === 'undefined' ) { + break; + } + } + + // Apply the new State to the ID + History.stateToId[str] = id; + History.idToState[id] = newState; + } + } + + // Return ID + return id; + }; + + /** + * History.normalizeState(State) + * Expands a State Object + * @param {object} State + * @return {object} + */ + History.normalizeState = function(oldState){ + // Variables + var newState, dataNotEmpty; + + // Prepare + if ( !oldState || (typeof oldState !== 'object') ) { + oldState = {}; + } + + // Check + if ( typeof oldState.normalized !== 'undefined' ) { + return oldState; + } + + // Adjust + if ( !oldState.data || (typeof oldState.data !== 'object') ) { + oldState.data = {}; + } + + // ---------------------------------------------------------------- + + // Create + newState = {}; + newState.normalized = true; + newState.title = oldState.title||''; + newState.url = History.getFullUrl(oldState.url?oldState.url:(History.getLocationHref())); + newState.hash = History.getShortUrl(newState.url); + newState.data = History.cloneObject(oldState.data); + + // Fetch ID + newState.id = History.getIdByState(newState); + + // ---------------------------------------------------------------- + + // Clean the URL + newState.cleanUrl = newState.url.replace(/\??\&_suid.*/,''); + newState.url = newState.cleanUrl; + + // Check to see if we have more than just a url + dataNotEmpty = !History.isEmptyObject(newState.data); + + // Apply + if ( (newState.title || dataNotEmpty) && History.options.disableSuid !== true ) { + // Add ID to Hash + newState.hash = History.getShortUrl(newState.url).replace(/\??\&_suid.*/,''); + if ( !/\?/.test(newState.hash) ) { + newState.hash += '?'; + } + newState.hash += '&_suid='+newState.id; + } + + // Create the Hashed URL + newState.hashedUrl = History.getFullUrl(newState.hash); + + // ---------------------------------------------------------------- + + // Update the URL if we have a duplicate + if ( (History.emulated.pushState || History.bugs.safariPoll) && History.hasUrlDuplicate(newState) ) { + newState.url = newState.hashedUrl; + } + + // ---------------------------------------------------------------- + + // Return + return newState; + }; + + /** + * History.createStateObject(data,title,url) + * Creates a object based on the data, title and url state params + * @param {object} data + * @param {string} title + * @param {string} url + * @return {object} + */ + History.createStateObject = function(data,title,url){ + // Hashify + var State = { + 'data': data, + 'title': title, + 'url': url + }; + + // Expand the State + State = History.normalizeState(State); + + // Return object + return State; + }; + + /** + * History.getStateById(id) + * Get a state by it's UID + * @param {String} id + */ + History.getStateById = function(id){ + // Prepare + id = String(id); + + // Retrieve + var State = History.idToState[id] || History.store.idToState[id] || undefined; + + // Return State + return State; + }; + + /** + * Get a State's String + * @param {State} passedState + */ + History.getStateString = function(passedState){ + // Prepare + var State, cleanedState, str; + + // Fetch + State = History.normalizeState(passedState); + + // Clean + cleanedState = { + data: State.data, + title: passedState.title, + url: passedState.url + }; + + // Fetch + str = JSON.stringify(cleanedState); + + // Return + return str; + }; + + /** + * Get a State's ID + * @param {State} passedState + * @return {String} id + */ + History.getStateId = function(passedState){ + // Prepare + var State, id; + + // Fetch + State = History.normalizeState(passedState); + + // Fetch + id = State.id; + + // Return + return id; + }; + + /** + * History.getHashByState(State) + * Creates a Hash for the State Object + * @param {State} passedState + * @return {String} hash + */ + History.getHashByState = function(passedState){ + // Prepare + var State, hash; + + // Fetch + State = History.normalizeState(passedState); + + // Hash + hash = State.hash; + + // Return + return hash; + }; + + /** + * History.extractId(url_or_hash) + * Get a State ID by it's URL or Hash + * @param {string} url_or_hash + * @return {string} id + */ + History.extractId = function ( url_or_hash ) { + // Prepare + var id,parts,url, tmp; + + // Extract + + // If the URL has a #, use the id from before the # + if (url_or_hash.indexOf('#') != -1) + { + tmp = url_or_hash.split("#")[0]; + } + else + { + tmp = url_or_hash; + } + + parts = /(.*)\&_suid=([0-9]+)$/.exec(tmp); + url = parts ? (parts[1]||url_or_hash) : url_or_hash; + id = parts ? String(parts[2]||'') : ''; + + // Return + return id||false; + }; + + /** + * History.isTraditionalAnchor + * Checks to see if the url is a traditional anchor or not + * @param {String} url_or_hash + * @return {Boolean} + */ + History.isTraditionalAnchor = function(url_or_hash){ + // Check + var isTraditional = !(/[\/\?\.]/.test(url_or_hash)); + + // Return + return isTraditional; + }; + + /** + * History.extractState + * Get a State by it's URL or Hash + * @param {String} url_or_hash + * @return {State|null} + */ + History.extractState = function(url_or_hash,create){ + // Prepare + var State = null, id, url; + create = create||false; + + // Fetch SUID + id = History.extractId(url_or_hash); + if ( id ) { + State = History.getStateById(id); + } + + // Fetch SUID returned no State + if ( !State ) { + // Fetch URL + url = History.getFullUrl(url_or_hash); + + // Check URL + id = History.getIdByUrl(url)||false; + if ( id ) { + State = History.getStateById(id); + } + + // Create State + if ( !State && create && !History.isTraditionalAnchor(url_or_hash) ) { + State = History.createStateObject(null,null,url); + } + } + + // Return + return State; + }; + + /** + * History.getIdByUrl() + * Get a State ID by a State URL + */ + History.getIdByUrl = function(url){ + // Fetch + var id = History.urlToId[url] || History.store.urlToId[url] || undefined; + + // Return + return id; + }; + + /** + * History.getLastSavedState() + * Get an object containing the data, title and url of the current state + * @return {Object} State + */ + History.getLastSavedState = function(){ + return History.savedStates[History.savedStates.length-1]||undefined; + }; + + /** + * History.getLastStoredState() + * Get an object containing the data, title and url of the current state + * @return {Object} State + */ + History.getLastStoredState = function(){ + return History.storedStates[History.storedStates.length-1]||undefined; + }; + + /** + * History.hasUrlDuplicate + * Checks if a Url will have a url conflict + * @param {Object} newState + * @return {Boolean} hasDuplicate + */ + History.hasUrlDuplicate = function(newState) { + // Prepare + var hasDuplicate = false, + oldState; + + // Fetch + oldState = History.extractState(newState.url); + + // Check + hasDuplicate = oldState && oldState.id !== newState.id; + + // Return + return hasDuplicate; + }; + + /** + * History.storeState + * Store a State + * @param {Object} newState + * @return {Object} newState + */ + History.storeState = function(newState){ + // Store the State + History.urlToId[newState.url] = newState.id; + + // Push the State + History.storedStates.push(History.cloneObject(newState)); + + // Return newState + return newState; + }; + + /** + * History.isLastSavedState(newState) + * Tests to see if the state is the last state + * @param {Object} newState + * @return {boolean} isLast + */ + History.isLastSavedState = function(newState){ + // Prepare + var isLast = false, + newId, oldState, oldId; + + // Check + if ( History.savedStates.length ) { + newId = newState.id; + oldState = History.getLastSavedState(); + oldId = oldState.id; + + // Check + isLast = (newId === oldId); + } + + // Return + return isLast; + }; + + /** + * History.saveState + * Push a State + * @param {Object} newState + * @return {boolean} changed + */ + History.saveState = function(newState){ + // Check Hash + if ( History.isLastSavedState(newState) ) { + return false; + } + + // Push the State + History.savedStates.push(History.cloneObject(newState)); + + // Return true + return true; + }; + + /** + * History.getStateByIndex() + * Gets a state by the index + * @param {integer} index + * @return {Object} + */ + History.getStateByIndex = function(index){ + // Prepare + var State = null; + + // Handle + if ( typeof index === 'undefined' ) { + // Get the last inserted + State = History.savedStates[History.savedStates.length-1]; + } + else if ( index < 0 ) { + // Get from the end + State = History.savedStates[History.savedStates.length+index]; + } + else { + // Get from the beginning + State = History.savedStates[index]; + } + + // Return State + return State; + }; + + /** + * History.getCurrentIndex() + * Gets the current index + * @return (integer) + */ + History.getCurrentIndex = function(){ + // Prepare + var index = null; + + // No states saved + if(History.savedStates.length < 1) { + index = 0; + } + else { + index = History.savedStates.length-1; + } + return index; + }; + + // ==================================================================== + // Hash Helpers + + /** + * History.getHash() + * @param {Location=} location + * Gets the current document hash + * Note: unlike location.hash, this is guaranteed to return the escaped hash in all browsers + * @return {string} + */ + History.getHash = function(doc){ + var url = History.getLocationHref(doc), + hash; + hash = History.getHashByUrl(url); + return hash; + }; + + /** + * History.unescapeHash() + * normalize and Unescape a Hash + * @param {String} hash + * @return {string} + */ + History.unescapeHash = function(hash){ + // Prepare + var result = History.normalizeHash(hash); + + // Unescape hash + result = decodeURIComponent(result); + + // Return result + return result; + }; + + /** + * History.normalizeHash() + * normalize a hash across browsers + * @return {string} + */ + History.normalizeHash = function(hash){ + // Prepare + var result = hash.replace(/[^#]*#/,'').replace(/#.*/, ''); + + // Return result + return result; + }; + + /** + * History.setHash(hash) + * Sets the document hash + * @param {string} hash + * @return {History} + */ + History.setHash = function(hash,queue){ + // Prepare + var State, pageUrl; + + // Handle Queueing + if ( queue !== false && History.busy() ) { + // Wait + Push to Queue + //History.debug('History.setHash: we must wait', arguments); + History.pushQueue({ + scope: History, + callback: History.setHash, + args: arguments, + queue: queue + }); + return false; + } + + // Log + //History.debug('History.setHash: called',hash); + + // Make Busy + Continue + History.busy(true); + + // Check if hash is a state + State = History.extractState(hash,true); + if ( State && !History.emulated.pushState ) { + // Hash is a state so skip the setHash + //History.debug('History.setHash: Hash is a state so skipping the hash set with a direct pushState call',arguments); + + // PushState + History.pushState(State.data,State.title,State.url,false); + } + else if ( History.getHash() !== hash ) { + // Hash is a proper hash, so apply it + + // Handle browser bugs + if ( History.bugs.setHash ) { + // Fix Safari Bug https://bugs.webkit.org/show_bug.cgi?id=56249 + + // Fetch the base page + pageUrl = History.getPageUrl(); + + // Safari hash apply + History.pushState(null,null,pageUrl+'#'+hash,false); + } + else { + // Normal hash apply + document.location.hash = hash; + } + } + + // Chain + return History; + }; + + /** + * History.escape() + * normalize and Escape a Hash + * @return {string} + */ + History.escapeHash = function(hash){ + // Prepare + var result = History.normalizeHash(hash); + + // Escape hash + result = window.encodeURIComponent(result); + + // IE6 Escape Bug + if ( !History.bugs.hashEscape ) { + // Restore common parts + result = result + .replace(/\%21/g,'!') + .replace(/\%26/g,'&') + .replace(/\%3D/g,'=') + .replace(/\%3F/g,'?'); + } + + // Return result + return result; + }; + + /** + * History.getHashByUrl(url) + * Extracts the Hash from a URL + * @param {string} url + * @return {string} url + */ + History.getHashByUrl = function(url){ + // Extract the hash + var hash = String(url) + .replace(/([^#]*)#?([^#]*)#?(.*)/, '$2') + ; + + // Unescape hash + hash = History.unescapeHash(hash); + + // Return hash + return hash; + }; + + /** + * History.setTitle(title) + * Applies the title to the document + * @param {State} newState + * @return {Boolean} + */ + History.setTitle = function(newState){ + // Prepare + var title = newState.title, + firstState; + + // Initial + if ( !title ) { + firstState = History.getStateByIndex(0); + if ( firstState && firstState.url === newState.url ) { + title = firstState.title||History.options.initialTitle; + } + } + + // Apply + try { + document.getElementsByTagName('title')[0].innerHTML = title.replace('<','<').replace('>','>').replace(' & ',' & '); + } + catch ( Exception ) { } + document.title = title; + + // Chain + return History; + }; + + + // ==================================================================== + // Queueing + + /** + * History.queues + * The list of queues to use + * First In, First Out + */ + History.queues = []; + + /** + * History.busy(value) + * @param {boolean} value [optional] + * @return {boolean} busy + */ + History.busy = function(value){ + // Apply + if ( typeof value !== 'undefined' ) { + //History.debug('History.busy: changing ['+(History.busy.flag||false)+'] to ['+(value||false)+']', History.queues.length); + History.busy.flag = value; + } + // Default + else if ( typeof History.busy.flag === 'undefined' ) { + History.busy.flag = false; + } + + // Queue + if ( !History.busy.flag ) { + // Execute the next item in the queue + clearTimeout(History.busy.timeout); + var fireNext = function(){ + var i, queue, item; + if ( History.busy.flag ) return; + for ( i=History.queues.length-1; i >= 0; --i ) { + queue = History.queues[i]; + if ( queue.length === 0 ) continue; + item = queue.shift(); + History.fireQueueItem(item); + History.busy.timeout = setTimeout(fireNext,History.options.busyDelay); + } + }; + History.busy.timeout = setTimeout(fireNext,History.options.busyDelay); + } + + // Return + return History.busy.flag; + }; + + /** + * History.busy.flag + */ + History.busy.flag = false; + + /** + * History.fireQueueItem(item) + * Fire a Queue Item + * @param {Object} item + * @return {Mixed} result + */ + History.fireQueueItem = function(item){ + return item.callback.apply(item.scope||History,item.args||[]); + }; + + /** + * History.pushQueue(callback,args) + * Add an item to the queue + * @param {Object} item [scope,callback,args,queue] + */ + History.pushQueue = function(item){ + // Prepare the queue + History.queues[item.queue||0] = History.queues[item.queue||0]||[]; + + // Add to the queue + History.queues[item.queue||0].push(item); + + // Chain + return History; + }; + + /** + * History.queue (item,queue), (func,queue), (func), (item) + * Either firs the item now if not busy, or adds it to the queue + */ + History.queue = function(item,queue){ + // Prepare + if ( typeof item === 'function' ) { + item = { + callback: item + }; + } + if ( typeof queue !== 'undefined' ) { + item.queue = queue; + } + + // Handle + if ( History.busy() ) { + History.pushQueue(item); + } else { + History.fireQueueItem(item); + } + + // Chain + return History; + }; + + /** + * History.clearQueue() + * Clears the Queue + */ + History.clearQueue = function(){ + History.busy.flag = false; + History.queues = []; + return History; + }; + + + // ==================================================================== + // IE Bug Fix + + /** + * History.stateChanged + * States whether or not the state has changed since the last double check was initialised + */ + History.stateChanged = false; + + /** + * History.doubleChecker + * Contains the timeout used for the double checks + */ + History.doubleChecker = false; + + /** + * History.doubleCheckComplete() + * Complete a double check + * @return {History} + */ + History.doubleCheckComplete = function(){ + // Update + History.stateChanged = true; + + // Clear + History.doubleCheckClear(); + + // Chain + return History; + }; + + /** + * History.doubleCheckClear() + * Clear a double check + * @return {History} + */ + History.doubleCheckClear = function(){ + // Clear + if ( History.doubleChecker ) { + clearTimeout(History.doubleChecker); + History.doubleChecker = false; + } + + // Chain + return History; + }; + + /** + * History.doubleCheck() + * Create a double check + * @return {History} + */ + History.doubleCheck = function(tryAgain){ + // Reset + History.stateChanged = false; + History.doubleCheckClear(); + + // Fix IE6,IE7 bug where calling history.back or history.forward does not actually change the hash (whereas doing it manually does) + // Fix Safari 5 bug where sometimes the state does not change: https://bugs.webkit.org/show_bug.cgi?id=42940 + if ( History.bugs.ieDoubleCheck ) { + // Apply Check + History.doubleChecker = setTimeout( + function(){ + History.doubleCheckClear(); + if ( !History.stateChanged ) { + //History.debug('History.doubleCheck: State has not yet changed, trying again', arguments); + // Re-Attempt + tryAgain(); + } + return true; + }, + History.options.doubleCheckInterval + ); + } + + // Chain + return History; + }; + + + // ==================================================================== + // Safari Bug Fix + + /** + * History.safariStatePoll() + * Poll the current state + * @return {History} + */ + History.safariStatePoll = function(){ + // Poll the URL + + // Get the Last State which has the new URL + var + urlState = History.extractState(History.getLocationHref()), + newState; + + // Check for a difference + if ( !History.isLastSavedState(urlState) ) { + newState = urlState; + } + else { + return; + } + + // Check if we have a state with that url + // If not create it + if ( !newState ) { + //History.debug('History.safariStatePoll: new'); + newState = History.createStateObject(); + } + + // Apply the New State + //History.debug('History.safariStatePoll: trigger'); + History.Adapter.trigger(window,'popstate'); + + // Chain + return History; + }; + + + // ==================================================================== + // State Aliases + + /** + * History.back(queue) + * Send the browser history back one item + * @param {Integer} queue [optional] + */ + History.back = function(queue){ + //History.debug('History.back: called', arguments); + + // Handle Queueing + if ( queue !== false && History.busy() ) { + // Wait + Push to Queue + //History.debug('History.back: we must wait', arguments); + History.pushQueue({ + scope: History, + callback: History.back, + args: arguments, + queue: queue + }); + return false; + } + + // Make Busy + Continue + History.busy(true); + + // Fix certain browser bugs that prevent the state from changing + History.doubleCheck(function(){ + History.back(false); + }); + + // Go back + history.go(-1); + + // End back closure + return true; + }; + + /** + * History.forward(queue) + * Send the browser history forward one item + * @param {Integer} queue [optional] + */ + History.forward = function(queue){ + //History.debug('History.forward: called', arguments); + + // Handle Queueing + if ( queue !== false && History.busy() ) { + // Wait + Push to Queue + //History.debug('History.forward: we must wait', arguments); + History.pushQueue({ + scope: History, + callback: History.forward, + args: arguments, + queue: queue + }); + return false; + } + + // Make Busy + Continue + History.busy(true); + + // Fix certain browser bugs that prevent the state from changing + History.doubleCheck(function(){ + History.forward(false); + }); + + // Go forward + history.go(1); + + // End forward closure + return true; + }; + + /** + * History.go(index,queue) + * Send the browser history back or forward index times + * @param {Integer} queue [optional] + */ + History.go = function(index,queue){ + //History.debug('History.go: called', arguments); + + // Prepare + var i; + + // Handle + if ( index > 0 ) { + // Forward + for ( i=1; i<=index; ++i ) { + History.forward(queue); + } + } + else if ( index < 0 ) { + // Backward + for ( i=-1; i>=index; --i ) { + History.back(queue); + } + } + else { + throw new Error('History.go: History.go requires a positive or negative integer passed.'); + } + + // Chain + return History; + }; + + + // ==================================================================== + // HTML5 State Support + + // Non-Native pushState Implementation + if ( History.emulated.pushState ) { + /* + * Provide Skeleton for HTML4 Browsers + */ + + // Prepare + var emptyFunction = function(){}; + History.pushState = History.pushState||emptyFunction; + History.replaceState = History.replaceState||emptyFunction; + } // History.emulated.pushState + + // Native pushState Implementation + else { + /* + * Use native HTML5 History API Implementation + */ + + /** + * History.onPopState(event,extra) + * Refresh the Current State + */ + History.onPopState = function(event,extra){ + // Prepare + var stateId = false, newState = false, currentHash, currentState; + + // Reset the double check + History.doubleCheckComplete(); + + // Check for a Hash, and handle apporiatly + currentHash = History.getHash(); + if ( currentHash ) { + // Expand Hash + currentState = History.extractState(currentHash||History.getLocationHref(),true); + if ( currentState ) { + // We were able to parse it, it must be a State! + // Let's forward to replaceState + //History.debug('History.onPopState: state anchor', currentHash, currentState); + History.replaceState(currentState.data, currentState.title, currentState.url, false); + } + else { + // Traditional Anchor + //History.debug('History.onPopState: traditional anchor', currentHash); + History.Adapter.trigger(window,'anchorchange'); + History.busy(false); + } + + // We don't care for hashes + History.expectedStateId = false; + return false; + } + + // Ensure + stateId = History.Adapter.extractEventData('state',event,extra) || false; + + // Fetch State + if ( stateId ) { + // Vanilla: Back/forward button was used + newState = History.getStateById(stateId); + } + else if ( History.expectedStateId ) { + // Vanilla: A new state was pushed, and popstate was called manually + newState = History.getStateById(History.expectedStateId); + } + else { + // Initial State + newState = History.extractState(History.getLocationHref()); + } + + // The State did not exist in our store + if ( !newState ) { + // Regenerate the State + newState = History.createStateObject(null,null,History.getLocationHref()); + } + + // Clean + History.expectedStateId = false; + + // Check if we are the same state + if ( History.isLastSavedState(newState) ) { + // There has been no change (just the page's hash has finally propagated) + //History.debug('History.onPopState: no change', newState, History.savedStates); + History.busy(false); + return false; + } + + // Store the State + History.storeState(newState); + History.saveState(newState); + + // Force update of the title + History.setTitle(newState); + + // Fire Our Event + History.Adapter.trigger(window,'statechange'); + History.busy(false); + + // Return true + return true; + }; + History.Adapter.bind(window,'popstate',History.onPopState); + + /** + * History.pushState(data,title,url) + * Add a new State to the history object, become it, and trigger onpopstate + * We have to trigger for HTML4 compatibility + * @param {object} data + * @param {string} title + * @param {string} url + * @return {true} + */ + History.pushState = function(data,title,url,queue){ + //History.debug('History.pushState: called', arguments); + + // Check the State + if ( History.getHashByUrl(url) && History.emulated.pushState ) { + throw new Error('History.js does not support states with fragement-identifiers (hashes/anchors).'); + } + + // Handle Queueing + if ( queue !== false && History.busy() ) { + // Wait + Push to Queue + //History.debug('History.pushState: we must wait', arguments); + History.pushQueue({ + scope: History, + callback: History.pushState, + args: arguments, + queue: queue + }); + return false; + } + + // Make Busy + Continue + History.busy(true); + + // Create the newState + var newState = History.createStateObject(data,title,url); + + // Check it + if ( History.isLastSavedState(newState) ) { + // Won't be a change + History.busy(false); + } + else { + // Store the newState + History.storeState(newState); + History.expectedStateId = newState.id; + + // Push the newState + history.pushState(newState.id,newState.title,newState.url); + + // Fire HTML5 Event + History.Adapter.trigger(window,'popstate'); + } + + // End pushState closure + return true; + }; + + /** + * History.replaceState(data,title,url) + * Replace the State and trigger onpopstate + * We have to trigger for HTML4 compatibility + * @param {object} data + * @param {string} title + * @param {string} url + * @return {true} + */ + History.replaceState = function(data,title,url,queue){ + //History.debug('History.replaceState: called', arguments); + + // Check the State + if ( History.getHashByUrl(url) && History.emulated.pushState ) { + throw new Error('History.js does not support states with fragement-identifiers (hashes/anchors).'); + } + + // Handle Queueing + if ( queue !== false && History.busy() ) { + // Wait + Push to Queue + //History.debug('History.replaceState: we must wait', arguments); + History.pushQueue({ + scope: History, + callback: History.replaceState, + args: arguments, + queue: queue + }); + return false; + } + + // Make Busy + Continue + History.busy(true); + + // Create the newState + var newState = History.createStateObject(data,title,url); + + // Check it + if ( History.isLastSavedState(newState) ) { + // Won't be a change + History.busy(false); + } + else { + // Store the newState + History.storeState(newState); + History.expectedStateId = newState.id; + + // Push the newState + history.replaceState(newState.id,newState.title,newState.url); + + // Fire HTML5 Event + History.Adapter.trigger(window,'popstate'); + } + + // End replaceState closure + return true; + }; + + } // !History.emulated.pushState + + + // ==================================================================== + // Initialise + + /** + * Load the Store + */ + if ( sessionStorage ) { + // Fetch + try { + History.store = JSON.parse(sessionStorage.getItem('History.store'))||{}; + } + catch ( err ) { + History.store = {}; + } + + // Normalize + History.normalizeStore(); + } + else { + // Default Load + History.store = {}; + History.normalizeStore(); + } + + /** + * Clear Intervals on exit to prevent memory leaks + */ + History.Adapter.bind(window,"unload",History.clearAllIntervals); + + /** + * Create the initial State + */ + History.saveState(History.storeState(History.extractState(History.getLocationHref(),true))); + + /** + * Bind for Saving Store + */ + if ( sessionStorage ) { + // When the page is closed + History.onUnload = function(){ + // Prepare + var currentStore, item, currentStoreString; + + // Fetch + try { + currentStore = JSON.parse(sessionStorage.getItem('History.store'))||{}; + } + catch ( err ) { + currentStore = {}; + } + + // Ensure + currentStore.idToState = currentStore.idToState || {}; + currentStore.urlToId = currentStore.urlToId || {}; + currentStore.stateToId = currentStore.stateToId || {}; + + // Sync + for ( item in History.idToState ) { + if ( !History.idToState.hasOwnProperty(item) ) { + continue; + } + currentStore.idToState[item] = History.idToState[item]; + } + for ( item in History.urlToId ) { + if ( !History.urlToId.hasOwnProperty(item) ) { + continue; + } + currentStore.urlToId[item] = History.urlToId[item]; + } + for ( item in History.stateToId ) { + if ( !History.stateToId.hasOwnProperty(item) ) { + continue; + } + currentStore.stateToId[item] = History.stateToId[item]; + } + + // Update + History.store = currentStore; + History.normalizeStore(); + + // In Safari, going into Private Browsing mode causes the + // Session Storage object to still exist but if you try and use + // or set any property/function of it it throws the exception + // "QUOTA_EXCEEDED_ERR: DOM Exception 22: An attempt was made to + // add something to storage that exceeded the quota." infinitely + // every second. + currentStoreString = JSON.stringify(currentStore); + try { + // Store + sessionStorage.setItem('History.store', currentStoreString); + } + catch (e) { + if (e.code === DOMException.QUOTA_EXCEEDED_ERR) { + if (sessionStorage.length) { + // Workaround for a bug seen on iPads. Sometimes the quota exceeded error comes up and simply + // removing/resetting the storage can work. + sessionStorage.removeItem('History.store'); + sessionStorage.setItem('History.store', currentStoreString); + } else { + // Otherwise, we're probably private browsing in Safari, so we'll ignore the exception. + } + } else { + throw e; + } + } + }; + + // For Internet Explorer + History.intervalList.push(setInterval(History.onUnload,History.options.storeInterval)); + + // For Other Browsers + History.Adapter.bind(window,'beforeunload',History.onUnload); + History.Adapter.bind(window,'unload',History.onUnload); + + // Both are enabled for consistency + } + + // Non-Native pushState Implementation + if ( !History.emulated.pushState ) { + // Be aware, the following is only for native pushState implementations + // If you are wanting to include something for all browsers + // Then include it above this if block + + /** + * Setup Safari Fix + */ + if ( History.bugs.safariPoll ) { + History.intervalList.push(setInterval(History.safariStatePoll, History.options.safariPollInterval)); + } + + /** + * Ensure Cross Browser Compatibility + */ + if ( navigator.vendor === 'Apple Computer, Inc.' || (navigator.appCodeName||'') === 'Mozilla' ) { + /** + * Fix Safari HashChange Issue + */ + + // Setup Alias + History.Adapter.bind(window,'hashchange',function(){ + History.Adapter.trigger(window,'popstate'); + }); + + // Initialise Alias + if ( History.getHash() ) { + History.Adapter.onDomLoad(function(){ + History.Adapter.trigger(window,'hashchange'); + }); + } + } + + } // !History.emulated.pushState + + + }; // History.initCore + + // Try to Initialise History + if (!History.options || !History.options.delayInit) { + History.init(); + } + +})(window); diff --git a/sites/all/themes/gui/materiobasetheme/bower_components/history.js/scripts/uncompressed/json2.js b/sites/all/themes/gui/materiobasetheme/bower_components/history.js/scripts/uncompressed/json2.js new file mode 100644 index 00000000..9317ae8b --- /dev/null +++ b/sites/all/themes/gui/materiobasetheme/bower_components/history.js/scripts/uncompressed/json2.js @@ -0,0 +1,486 @@ +/* + json2.js + 2012-10-08 + + Public Domain. + + NO WARRANTY EXPRESSED OR IMPLIED. USE AT YOUR OWN RISK. + + See http://www.JSON.org/js.html + + + This code should be minified before deployment. + See http://javascript.crockford.com/jsmin.html + + USE YOUR OWN COPY. IT IS EXTREMELY UNWISE TO LOAD CODE FROM SERVERS YOU DO + NOT CONTROL. + + + This file creates a global JSON object containing two methods: stringify + and parse. + + JSON.stringify(value, replacer, space) + value any JavaScript value, usually an object or array. + + replacer an optional parameter that determines how object + values are stringified for objects. It can be a + function or an array of strings. + + space an optional parameter that specifies the indentation + of nested structures. If it is omitted, the text will + be packed without extra whitespace. If it is a number, + it will specify the number of spaces to indent at each + level. If it is a string (such as '\t' or ' '), + it contains the characters used to indent at each level. + + This method produces a JSON text from a JavaScript value. + + When an object value is found, if the object contains a toJSON + method, its toJSON method will be called and the result will be + stringified. A toJSON method does not serialize: it returns the + value represented by the name/value pair that should be serialized, + or undefined if nothing should be serialized. The toJSON method + will be passed the key associated with the value, and this will be + bound to the value + + For example, this would serialize Dates as ISO strings. + + Date.prototype.toJSON = function (key) { + function f(n) { + // Format integers to have at least two digits. + return n < 10 ? '0' + n : n; + } + + return this.getUTCFullYear() + '-' + + f(this.getUTCMonth() + 1) + '-' + + f(this.getUTCDate()) + 'T' + + f(this.getUTCHours()) + ':' + + f(this.getUTCMinutes()) + ':' + + f(this.getUTCSeconds()) + 'Z'; + }; + + You can provide an optional replacer method. It will be passed the + key and value of each member, with this bound to the containing + object. The value that is returned from your method will be + serialized. If your method returns undefined, then the member will + be excluded from the serialization. + + If the replacer parameter is an array of strings, then it will be + used to select the members to be serialized. It filters the results + such that only members with keys listed in the replacer array are + stringified. + + Values that do not have JSON representations, such as undefined or + functions, will not be serialized. Such values in objects will be + dropped; in arrays they will be replaced with null. You can use + a replacer function to replace those with JSON values. + JSON.stringify(undefined) returns undefined. + + The optional space parameter produces a stringification of the + value that is filled with line breaks and indentation to make it + easier to read. + + If the space parameter is a non-empty string, then that string will + be used for indentation. If the space parameter is a number, then + the indentation will be that many spaces. + + Example: + + text = JSON.stringify(['e', {pluribus: 'unum'}]); + // text is '["e",{"pluribus":"unum"}]' + + + text = JSON.stringify(['e', {pluribus: 'unum'}], null, '\t'); + // text is '[\n\t"e",\n\t{\n\t\t"pluribus": "unum"\n\t}\n]' + + text = JSON.stringify([new Date()], function (key, value) { + return this[key] instanceof Date ? + 'Date(' + this[key] + ')' : value; + }); + // text is '["Date(---current time---)"]' + + + JSON.parse(text, reviver) + This method parses a JSON text to produce an object or array. + It can throw a SyntaxError exception. + + The optional reviver parameter is a function that can filter and + transform the results. It receives each of the keys and values, + and its return value is used instead of the original value. + If it returns what it received, then the structure is not modified. + If it returns undefined then the member is deleted. + + Example: + + // Parse the text. Values that look like ISO date strings will + // be converted to Date objects. + + myData = JSON.parse(text, function (key, value) { + var a; + if (typeof value === 'string') { + a = +/^(\d{4})-(\d{2})-(\d{2})T(\d{2}):(\d{2}):(\d{2}(?:\.\d*)?)Z$/.exec(value); + if (a) { + return new Date(Date.UTC(+a[1], +a[2] - 1, +a[3], +a[4], + +a[5], +a[6])); + } + } + return value; + }); + + myData = JSON.parse('["Date(09/09/2001)"]', function (key, value) { + var d; + if (typeof value === 'string' && + value.slice(0, 5) === 'Date(' && + value.slice(-1) === ')') { + d = new Date(value.slice(5, -1)); + if (d) { + return d; + } + } + return value; + }); + + + This is a reference implementation. You are free to copy, modify, or + redistribute. +*/ + +/*jslint evil: true, regexp: true */ + +/*members "", "\b", "\t", "\n", "\f", "\r", "\"", JSON, "\\", apply, + call, charCodeAt, getUTCDate, getUTCFullYear, getUTCHours, + getUTCMinutes, getUTCMonth, getUTCSeconds, hasOwnProperty, join, + lastIndex, length, parse, prototype, push, replace, slice, stringify, + test, toJSON, toString, valueOf +*/ + + +// Create a JSON object only if one does not already exist. We create the +// methods in a closure to avoid creating global variables. + +if (typeof JSON !== 'object') { + JSON = {}; +} + +(function () { + 'use strict'; + + function f(n) { + // Format integers to have at least two digits. + return n < 10 ? '0' + n : n; + } + + if (typeof Date.prototype.toJSON !== 'function') { + + Date.prototype.toJSON = function (key) { + + return isFinite(this.valueOf()) + ? this.getUTCFullYear() + '-' + + f(this.getUTCMonth() + 1) + '-' + + f(this.getUTCDate()) + 'T' + + f(this.getUTCHours()) + ':' + + f(this.getUTCMinutes()) + ':' + + f(this.getUTCSeconds()) + 'Z' + : null; + }; + + String.prototype.toJSON = + Number.prototype.toJSON = + Boolean.prototype.toJSON = function (key) { + return this.valueOf(); + }; + } + + var cx = /[\u0000\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g, + escapable = /[\\\"\x00-\x1f\x7f-\x9f\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g, + gap, + indent, + meta = { // table of character substitutions + '\b': '\\b', + '\t': '\\t', + '\n': '\\n', + '\f': '\\f', + '\r': '\\r', + '"' : '\\"', + '\\': '\\\\' + }, + rep; + + + function quote(string) { + +// If the string contains no control characters, no quote characters, and no +// backslash characters, then we can safely slap some quotes around it. +// Otherwise we must also replace the offending characters with safe escape +// sequences. + + escapable.lastIndex = 0; + return escapable.test(string) ? '"' + string.replace(escapable, function (a) { + var c = meta[a]; + return typeof c === 'string' + ? c + : '\\u' + ('0000' + a.charCodeAt(0).toString(16)).slice(-4); + }) + '"' : '"' + string + '"'; + } + + + function str(key, holder) { + +// Produce a string from holder[key]. + + var i, // The loop counter. + k, // The member key. + v, // The member value. + length, + mind = gap, + partial, + value = holder[key]; + +// If the value has a toJSON method, call it to obtain a replacement value. + + if (value && typeof value === 'object' && + typeof value.toJSON === 'function') { + value = value.toJSON(key); + } + +// If we were called with a replacer function, then call the replacer to +// obtain a replacement value. + + if (typeof rep === 'function') { + value = rep.call(holder, key, value); + } + +// What happens next depends on the value's type. + + switch (typeof value) { + case 'string': + return quote(value); + + case 'number': + +// JSON numbers must be finite. Encode non-finite numbers as null. + + return isFinite(value) ? String(value) : 'null'; + + case 'boolean': + case 'null': + +// If the value is a boolean or null, convert it to a string. Note: +// typeof null does not produce 'null'. The case is included here in +// the remote chance that this gets fixed someday. + + return String(value); + +// If the type is 'object', we might be dealing with an object or an array or +// null. + + case 'object': + +// Due to a specification blunder in ECMAScript, typeof null is 'object', +// so watch out for that case. + + if (!value) { + return 'null'; + } + +// Make an array to hold the partial results of stringifying this object value. + + gap += indent; + partial = []; + +// Is the value an array? + + if (Object.prototype.toString.apply(value) === '[object Array]') { + +// The value is an array. Stringify every element. Use null as a placeholder +// for non-JSON values. + + length = value.length; + for (i = 0; i < length; i += 1) { + partial[i] = str(i, value) || 'null'; + } + +// Join all of the elements together, separated with commas, and wrap them in +// brackets. + + v = partial.length === 0 + ? '[]' + : gap + ? '[\n' + gap + partial.join(',\n' + gap) + '\n' + mind + ']' + : '[' + partial.join(',') + ']'; + gap = mind; + return v; + } + +// If the replacer is an array, use it to select the members to be stringified. + + if (rep && typeof rep === 'object') { + length = rep.length; + for (i = 0; i < length; i += 1) { + if (typeof rep[i] === 'string') { + k = rep[i]; + v = str(k, value); + if (v) { + partial.push(quote(k) + (gap ? ': ' : ':') + v); + } + } + } + } else { + +// Otherwise, iterate through all of the keys in the object. + + for (k in value) { + if (Object.prototype.hasOwnProperty.call(value, k)) { + v = str(k, value); + if (v) { + partial.push(quote(k) + (gap ? ': ' : ':') + v); + } + } + } + } + +// Join all of the member texts together, separated with commas, +// and wrap them in braces. + + v = partial.length === 0 + ? '{}' + : gap + ? '{\n' + gap + partial.join(',\n' + gap) + '\n' + mind + '}' + : '{' + partial.join(',') + '}'; + gap = mind; + return v; + } + } + +// If the JSON object does not yet have a stringify method, give it one. + + if (typeof JSON.stringify !== 'function') { + JSON.stringify = function (value, replacer, space) { + +// The stringify method takes a value and an optional replacer, and an optional +// space parameter, and returns a JSON text. The replacer can be a function +// that can replace values, or an array of strings that will select the keys. +// A default replacer method can be provided. Use of the space parameter can +// produce text that is more easily readable. + + var i; + gap = ''; + indent = ''; + +// If the space parameter is a number, make an indent string containing that +// many spaces. + + if (typeof space === 'number') { + for (i = 0; i < space; i += 1) { + indent += ' '; + } + +// If the space parameter is a string, it will be used as the indent string. + + } else if (typeof space === 'string') { + indent = space; + } + +// If there is a replacer, it must be a function or an array. +// Otherwise, throw an error. + + rep = replacer; + if (replacer && typeof replacer !== 'function' && + (typeof replacer !== 'object' || + typeof replacer.length !== 'number')) { + throw new Error('JSON.stringify'); + } + +// Make a fake root object containing our value under the key of ''. +// Return the result of stringifying the value. + + return str('', {'': value}); + }; + } + + +// If the JSON object does not yet have a parse method, give it one. + + if (typeof JSON.parse !== 'function') { + JSON.parse = function (text, reviver) { + +// The parse method takes a text and an optional reviver function, and returns +// a JavaScript value if the text is a valid JSON text. + + var j; + + function walk(holder, key) { + +// The walk method is used to recursively walk the resulting structure so +// that modifications can be made. + + var k, v, value = holder[key]; + if (value && typeof value === 'object') { + for (k in value) { + if (Object.prototype.hasOwnProperty.call(value, k)) { + v = walk(value, k); + if (v !== undefined) { + value[k] = v; + } else { + delete value[k]; + } + } + } + } + return reviver.call(holder, key, value); + } + + +// Parsing happens in four stages. In the first stage, we replace certain +// Unicode characters with escape sequences. JavaScript handles many characters +// incorrectly, either silently deleting them, or treating them as line endings. + + text = String(text); + cx.lastIndex = 0; + if (cx.test(text)) { + text = text.replace(cx, function (a) { + return '\\u' + + ('0000' + a.charCodeAt(0).toString(16)).slice(-4); + }); + } + +// In the second stage, we run the text against regular expressions that look +// for non-JSON patterns. We are especially concerned with '()' and 'new' +// because they can cause invocation, and '=' because it can cause mutation. +// But just to be safe, we want to reject all unexpected forms. + +// We split the second stage into 4 regexp operations in order to work around +// crippling inefficiencies in IE's and Safari's regexp engines. First we +// replace the JSON backslash pairs with '@' (a non-JSON character). Second, we +// replace all simple value tokens with ']' characters. Third, we delete all +// open brackets that follow a colon or comma or that begin the text. Finally, +// we look to see that the remaining characters are only whitespace or ']' or +// ',' or ':' or '{' or '}'. If that is so, then the text is safe for eval. + + if (/^[\],:{}\s]*$/ + .test(text.replace(/\\(?:["\\\/bfnrt]|u[0-9a-fA-F]{4})/g, '@') + .replace(/"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g, ']') + .replace(/(?:^|:|,)(?:\s*\[)+/g, ''))) { + +// In the third stage we use the eval function to compile the text into a +// JavaScript structure. The '{' operator is subject to a syntactic ambiguity +// in JavaScript: it can begin a block or an object literal. We wrap the text +// in parens to eliminate the ambiguity. + + j = eval('(' + text + ')'); + +// In the optional fourth stage, we recursively walk the new structure, passing +// each name/value pair to a reviver function for possible transformation. + + return typeof reviver === 'function' + ? walk({'': j}, '') + : j; + } + +// If the text is not JSON parseable, then a SyntaxError is thrown. + + throw new SyntaxError('JSON.parse'); + }; + } +}()); \ No newline at end of file diff --git a/sites/all/themes/gui/materiobasetheme/bower_components/history.js/tests.src/_header.php b/sites/all/themes/gui/materiobasetheme/bower_components/history.js/tests.src/_header.php new file mode 100644 index 00000000..9b085101 --- /dev/null +++ b/sites/all/themes/gui/materiobasetheme/bower_components/history.js/tests.src/_header.php @@ -0,0 +1,22 @@ + + + + History.js Test Suite + + + +

History.js Test Suite

+

HTML5 Browsers must pass the HTML4+HTML5 tests

+

HTML4 Browsers must pass the HTML4 tests and should fail the HTML5 tests

+ '; + foreach ( $adapters as $adapter ) : + echo '
'; + # Url + $url = "${browser}.${adapter}.html"; + + # Title + $Browser = ucwords($browser); + $Adapter = ucwords($adapter); + $title = "History.js ${Browser} ${Adapter} Test Suite"; + + # Render + ?>'; + endforeach; + echo '
'; + endforeach; + ?> + + diff --git a/sites/all/themes/gui/materiobasetheme/bower_components/history.js/tests.src/each.php b/sites/all/themes/gui/materiobasetheme/bower_components/history.js/tests.src/each.php new file mode 100644 index 00000000..22f7b683 --- /dev/null +++ b/sites/all/themes/gui/materiobasetheme/bower_components/history.js/tests.src/each.php @@ -0,0 +1,51 @@ + + + + + + + + <?=$title?> + + + + + + + + + + + + + +

+

+
+

+
    +
    test markup
    + + + + + + + + + + \ No newline at end of file diff --git a/sites/all/themes/gui/materiobasetheme/bower_components/history.js/tests.src/index.php b/sites/all/themes/gui/materiobasetheme/bower_components/history.js/tests.src/index.php new file mode 100644 index 00000000..44495d3e --- /dev/null +++ b/sites/all/themes/gui/materiobasetheme/bower_components/history.js/tests.src/index.php @@ -0,0 +1,23 @@ +Tests diff --git a/sites/all/themes/gui/materiobasetheme/bower_components/history.js/tests/.htaccess b/sites/all/themes/gui/materiobasetheme/bower_components/history.js/tests/.htaccess new file mode 100644 index 00000000..2f7dbdde --- /dev/null +++ b/sites/all/themes/gui/materiobasetheme/bower_components/history.js/tests/.htaccess @@ -0,0 +1,13 @@ +Options +FollowSymlinks +RewriteEngine On + +# Clean Adapter +RewriteCond %{REQUEST_FILENAME} !-f +RewriteCond %{REQUEST_FILENAME} !-d +RewriteRule ([^\.]+)$ $1.html [NC,L,QSA] + +# Can someone smarter than me make it so: +# http://localhost/history.js/tests/uncompressed-html5-persistant-jquery +# Does not redirect to: +# http://localhost/history.js/tests/uncompressed-html5-persistant-jquery.html +# But still accesses that url diff --git a/sites/all/themes/gui/materiobasetheme/bower_components/history.js/tests/html4+html5.dojo.html b/sites/all/themes/gui/materiobasetheme/bower_components/history.js/tests/html4+html5.dojo.html new file mode 100644 index 00000000..af5f4d8b --- /dev/null +++ b/sites/all/themes/gui/materiobasetheme/bower_components/history.js/tests/html4+html5.dojo.html @@ -0,0 +1,55 @@ + + + + + + + + History.js HTML4+HTML5 Dojo Test Suite + + + + + + + + + + + + + + +

    History.js HTML4+HTML5 Dojo Test Suite

    +

    +
    +

    +
      +
      test markup
      + + + + + + + + + + + + + + + + + diff --git a/sites/all/themes/gui/materiobasetheme/bower_components/history.js/tests/html4+html5.extjs.html b/sites/all/themes/gui/materiobasetheme/bower_components/history.js/tests/html4+html5.extjs.html new file mode 100644 index 00000000..e82577a8 --- /dev/null +++ b/sites/all/themes/gui/materiobasetheme/bower_components/history.js/tests/html4+html5.extjs.html @@ -0,0 +1,55 @@ + + + + + + + + History.js HTML4+HTML5 ExtJS Test Suite + + + + + + + + + + + + + + +

      History.js HTML4+HTML5 ExtJS Test Suite

      +

      +
      +

      +
        +
        test markup
        + + + + + + + + + + + + + + + + + diff --git a/sites/all/themes/gui/materiobasetheme/bower_components/history.js/tests/html4+html5.jquery.html b/sites/all/themes/gui/materiobasetheme/bower_components/history.js/tests/html4+html5.jquery.html new file mode 100644 index 00000000..a99b9569 --- /dev/null +++ b/sites/all/themes/gui/materiobasetheme/bower_components/history.js/tests/html4+html5.jquery.html @@ -0,0 +1,43 @@ + + + + + + + + History.js HTML4+HTML5 Jquery Test Suite + + + + + + + + + + + + + +

        History.js HTML4+HTML5 Jquery Test Suite

        +

        +
        +

        +
          +
          test markup
          + + + + + + + + + + \ No newline at end of file diff --git a/sites/all/themes/gui/materiobasetheme/bower_components/history.js/tests/html4+html5.mootools.html b/sites/all/themes/gui/materiobasetheme/bower_components/history.js/tests/html4+html5.mootools.html new file mode 100644 index 00000000..792f9752 --- /dev/null +++ b/sites/all/themes/gui/materiobasetheme/bower_components/history.js/tests/html4+html5.mootools.html @@ -0,0 +1,43 @@ + + + + + + + + History.js HTML4+HTML5 Mootools Test Suite + + + + + + + + + + + + + +

          History.js HTML4+HTML5 Mootools Test Suite

          +

          +
          +

          +
            +
            test markup
            + + + + + + + + + + \ No newline at end of file diff --git a/sites/all/themes/gui/materiobasetheme/bower_components/history.js/tests/html4+html5.native.html b/sites/all/themes/gui/materiobasetheme/bower_components/history.js/tests/html4+html5.native.html new file mode 100644 index 00000000..c4fd8522 --- /dev/null +++ b/sites/all/themes/gui/materiobasetheme/bower_components/history.js/tests/html4+html5.native.html @@ -0,0 +1,43 @@ + + + + + + + + History.js HTML4+HTML5 Native Test Suite + + + + + + + + + + + + + +

            History.js HTML4+HTML5 Native Test Suite

            +

            +
            +

            +
              +
              test markup
              + + + + + + + + + + \ No newline at end of file diff --git a/sites/all/themes/gui/materiobasetheme/bower_components/history.js/tests/html4+html5.right.html b/sites/all/themes/gui/materiobasetheme/bower_components/history.js/tests/html4+html5.right.html new file mode 100644 index 00000000..ae4fb036 --- /dev/null +++ b/sites/all/themes/gui/materiobasetheme/bower_components/history.js/tests/html4+html5.right.html @@ -0,0 +1,43 @@ + + + + + + + + History.js HTML4+HTML5 Right Test Suite + + + + + + + + + + + + + +

              History.js HTML4+HTML5 Right Test Suite

              +

              +
              +

              +
                +
                test markup
                + + + + + + + + + + \ No newline at end of file diff --git a/sites/all/themes/gui/materiobasetheme/bower_components/history.js/tests/html4+html5.zepto.html b/sites/all/themes/gui/materiobasetheme/bower_components/history.js/tests/html4+html5.zepto.html new file mode 100644 index 00000000..71a6b7c9 --- /dev/null +++ b/sites/all/themes/gui/materiobasetheme/bower_components/history.js/tests/html4+html5.zepto.html @@ -0,0 +1,43 @@ + + + + + + + + History.js HTML4+HTML5 Zepto Test Suite + + + + + + + + + + + + + +

                History.js HTML4+HTML5 Zepto Test Suite

                +

                +
                +

                +
                  +
                  test markup
                  + + + + + + + + + + \ No newline at end of file diff --git a/sites/all/themes/gui/materiobasetheme/bower_components/history.js/tests/html5.dojo.html b/sites/all/themes/gui/materiobasetheme/bower_components/history.js/tests/html5.dojo.html new file mode 100644 index 00000000..3e222753 --- /dev/null +++ b/sites/all/themes/gui/materiobasetheme/bower_components/history.js/tests/html5.dojo.html @@ -0,0 +1,43 @@ + + + + + + + + History.js HTML5 Dojo Test Suite + + + + + + + + + + + + + +

                  History.js HTML5 Dojo Test Suite

                  +

                  +
                  +

                  +
                    +
                    test markup
                    + + + + + + + + + + diff --git a/sites/all/themes/gui/materiobasetheme/bower_components/history.js/tests/html5.extjs.html b/sites/all/themes/gui/materiobasetheme/bower_components/history.js/tests/html5.extjs.html new file mode 100644 index 00000000..2446b72c --- /dev/null +++ b/sites/all/themes/gui/materiobasetheme/bower_components/history.js/tests/html5.extjs.html @@ -0,0 +1,43 @@ + + + + + + + + History.js HTML5 ExtJS Test Suite + + + + + + + + + + + + + +

                    History.js HTML5 ExtJS Test Suite

                    +

                    +
                    +

                    +
                      +
                      test markup
                      + + + + + + + + + + diff --git a/sites/all/themes/gui/materiobasetheme/bower_components/history.js/tests/html5.jquery.html b/sites/all/themes/gui/materiobasetheme/bower_components/history.js/tests/html5.jquery.html new file mode 100644 index 00000000..977b8fed --- /dev/null +++ b/sites/all/themes/gui/materiobasetheme/bower_components/history.js/tests/html5.jquery.html @@ -0,0 +1,43 @@ + + + + + + + + History.js HTML5 Jquery Test Suite + + + + + + + + + + + + + +

                      History.js HTML5 Jquery Test Suite

                      +

                      +
                      +

                      +
                        +
                        test markup
                        + + + + + + + + + + \ No newline at end of file diff --git a/sites/all/themes/gui/materiobasetheme/bower_components/history.js/tests/html5.mootools.html b/sites/all/themes/gui/materiobasetheme/bower_components/history.js/tests/html5.mootools.html new file mode 100644 index 00000000..30ee7892 --- /dev/null +++ b/sites/all/themes/gui/materiobasetheme/bower_components/history.js/tests/html5.mootools.html @@ -0,0 +1,43 @@ + + + + + + + + History.js HTML5 Mootools Test Suite + + + + + + + + + + + + + +

                        History.js HTML5 Mootools Test Suite

                        +

                        +
                        +

                        +
                          +
                          test markup
                          + + + + + + + + + + \ No newline at end of file diff --git a/sites/all/themes/gui/materiobasetheme/bower_components/history.js/tests/html5.native.html b/sites/all/themes/gui/materiobasetheme/bower_components/history.js/tests/html5.native.html new file mode 100644 index 00000000..8ffc4c34 --- /dev/null +++ b/sites/all/themes/gui/materiobasetheme/bower_components/history.js/tests/html5.native.html @@ -0,0 +1,43 @@ + + + + + + + + History.js HTML5 Native Test Suite + + + + + + + + + + + + + +

                          History.js HTML5 Native Test Suite

                          +

                          +
                          +

                          +
                            +
                            test markup
                            + + + + + + + + + + \ No newline at end of file diff --git a/sites/all/themes/gui/materiobasetheme/bower_components/history.js/tests/html5.right.html b/sites/all/themes/gui/materiobasetheme/bower_components/history.js/tests/html5.right.html new file mode 100644 index 00000000..7a2c08b5 --- /dev/null +++ b/sites/all/themes/gui/materiobasetheme/bower_components/history.js/tests/html5.right.html @@ -0,0 +1,43 @@ + + + + + + + + History.js HTML5 Right Test Suite + + + + + + + + + + + + + +

                            History.js HTML5 Right Test Suite

                            +

                            +
                            +

                            +
                              +
                              test markup
                              + + + + + + + + + + \ No newline at end of file diff --git a/sites/all/themes/gui/materiobasetheme/bower_components/history.js/tests/html5.zepto.html b/sites/all/themes/gui/materiobasetheme/bower_components/history.js/tests/html5.zepto.html new file mode 100644 index 00000000..d6657091 --- /dev/null +++ b/sites/all/themes/gui/materiobasetheme/bower_components/history.js/tests/html5.zepto.html @@ -0,0 +1,43 @@ + + + + + + + + History.js HTML5 Zepto Test Suite + + + + + + + + + + + + + +

                              History.js HTML5 Zepto Test Suite

                              +

                              +
                              +

                              +
                                +
                                test markup
                                + + + + + + + + + + \ No newline at end of file diff --git a/sites/all/themes/gui/materiobasetheme/bower_components/history.js/tests/image.php b/sites/all/themes/gui/materiobasetheme/bower_components/history.js/tests/image.php new file mode 100644 index 00000000..5e7bfc9e --- /dev/null +++ b/sites/all/themes/gui/materiobasetheme/bower_components/history.js/tests/image.php @@ -0,0 +1,3 @@ + + + + History.js Test Suite + + + +

                                History.js Test Suite

                                +

                                HTML5 Browsers must pass the HTML4+HTML5 tests, HTML4 Browsers must pass the HTML4 tests and should fail the HTML5 tests.

                                + + + + + diff --git a/sites/all/themes/gui/materiobasetheme/bower_components/history.js/tests/tests.js b/sites/all/themes/gui/materiobasetheme/bower_components/history.js/tests/tests.js new file mode 100644 index 00000000..9dfc7382 --- /dev/null +++ b/sites/all/themes/gui/materiobasetheme/bower_components/history.js/tests/tests.js @@ -0,0 +1,254 @@ +(function(){ + +var + History = window.History, + document = window.document, + test = window.test, + deepEqual = window.deepEqual; + +// Check +if ( !History.enabled ) { + throw new Error('History.js is disabled'); +} + +// Prepare +History.options.debug = false; + +// Variables +var + States = { + // Home + 0: { + 'url': document.location.href.replace(/#.*$/,''), + 'title': '' + }, + // One + 1: { + 'data': { + 'state': 1, + 'rand': Math.random() + }, + 'title': 'State 1', + 'url': '?state=1' + }, + // Two + 2: { + 'data': { + 'state': 2, + 'rand': Math.random() + }, + 'title': 'State 2', + 'url': '?state=2&asd=%20asd%2520asd' + }, + // Three + 3: { + 'url': '?state=3' + }, + // Four + 4: { + 'data': { + 'state': 4, + 'trick': true, + 'rand': Math.random() + }, + 'title': 'State 4', + 'url': '?state=3' + }, + // Log + 5: { + 'url': '?state=1#log' + }, + // Six + 6: { + 'data': { + 'state': 6, + 'rand': Math.random() + }, + 'url': 'six.html' + }, + // Seven + 7: { + 'url': 'seven' + }, + // Eight + 8: { + 'url': '/eight' + } + }, + stateOrder = [0,1,2,3,4,3,1,0,1,3,4,3,1,0,6,7,8,1,8,7,6,0], + currentTest = 0; + +// Original Title +var title = document.title; + +var banner; + +var checkStatus = function(){ + banner = banner || document.getElementById('qunit-banner'); + var status = banner.className !== 'qunit-fail'; + return status; +}; + +// Check State +var checkState = function(){ + if ( !checkStatus() ) { + throw new Error('A test has failed'); + } + + var + stateIndex = stateOrder[currentTest], + expectedState = History.normalizeState(States[stateIndex]), + actualState = History.getState(false); + + ++currentTest; + + document.title = title+': '+actualState.url; + + var + testName = 'Test '+currentTest, + stateName = 'State '+stateIndex; + + test(testName,function(){ + History.log('Completed: '+testName +' / '+ stateName); + deepEqual(actualState,expectedState,stateName); + }); + + // Image Load to Stress Test Safari and Opera + (new Image()).src = "image.php"; +}; + +// Check the Initial State +checkState(); + +// State Change +History.Adapter.bind(window,'statechange',checkState); + +// Log +var addLog = function(){ + var args = arguments; + History.queue(function(){ + History.log.apply(History,args); + }); +}; + +// Dom Load +History.Adapter.onDomLoad(function(){ + setTimeout(function(){ + + // ---------------------------------------------------------------------- + // Test State Functionality: Adding + + // Test 2 / State 1 (0 -> 1) + // Tests HTML4 -> HTML5 Graceful Upgrade + addLog('Test 2',History.queues.length,History.busy.flag); + History.setHash(History.getHashByState(States[1])); + + // Test 3 / State 2 (1 -> 2) + addLog('Test 3',History.queues.length,History.busy.flag); + History.pushState(States[2].data, States[2].title, States[2].url); + + // Test 3-2 / State 2 (2 -> 2) / No Change + addLog('Test 3-2',History.queues.length,History.busy.flag); + History.pushState(States[2].data, States[2].title, States[2].url); + + // Test 3-3 / State 2 (2 -> 2) / No Change + addLog('Test 3-3',History.queues.length,History.busy.flag); + History.replaceState(States[2].data, States[2].title, States[2].url); + + // Test 4 / State 3 (2 -> 3) + addLog('Test 4',History.queues.length,History.busy.flag); + History.replaceState(States[3].data, States[3].title, States[3].url); + + // Test 5 / State 4 (3 -> 4) + addLog('Test 5',History.queues.length,History.busy.flag); + History.pushState(States[4].data, States[4].title, States[4].url); + + // ---------------------------------------------------------------------- + // Test State Functionality: Traversing + + // Test 6 / State 3 (4 -> 3) + // Test 7 / State 1 (3 -> 2 -> 1) + addLog('Test 6,7',History.queues.length,History.busy.flag); + History.go(-2); + + // Test 8 / State 0 (1 -> 0) + // Tests Default State + addLog('Test 8',History.queues.length,History.busy.flag); + History.back(); + + // Test 9 / State 1 (0 -> 1) + // Test 10 / State 3 (1 -> 2 -> 3) + addLog('Test 9,10',History.queues.length,History.busy.flag); + History.go(2); + + // Test 11 / State 4 (3 -> 4) + addLog('Test 11',History.queues.length,History.busy.flag); + History.forward(); + + // Test 12 / State 3 (4 -> 3) + addLog('Test 12',History.queues.length,History.busy.flag); + History.back(); + + // Test 13 / State 1 (3 -> 2 -> 1) + addLog('Test 13',History.queues.length,History.busy.flag); + History.back(); + + // ---------------------------------------------------------------------- + // Test State Functionality: Traditional Anchors + + // Test 13-2 / State 1 (1 -> #log) / No Change + addLog('Test 13-2',History.queues.length,History.busy.flag); + History.setHash('log'); + + // Test 13-3 / State 1 (#log -> 1) / No Change + addLog('Test 13-3',History.queues.length,History.busy.flag); + History.back(); + + // Test 14 / State 0 (1 -> 0) + addLog('Test 14',History.queues.length,History.busy.flag); + History.back(); + + // ---------------------------------------------------------------------- + // Test URL Handling: Adding + + // Test 15 / State 6 (1 -> 6) + // Also tests data with no title + addLog('Test 15',History.queues.length,History.busy.flag); + History.pushState(States[6].data, States[6].title, States[6].url); + + // Test 16 / State 7 (6 -> 7) + addLog('Test 16',History.queues.length,History.busy.flag); + History.pushState(States[7].data, States[7].title, States[7].url); + + // Test 17 / State 7 (7 -> 8) + addLog('Test 17',History.queues.length,History.busy.flag); + History.pushState(States[8].data, States[8].title, States[8].url); + + // Test 18 / State 1 (8 -> 1) + // Should be /eight?state=1 + addLog('Test 18',History.queues.length,History.busy.flag); + History.pushState(States[1].data, States[1].title, States[1].url); + + // ---------------------------------------------------------------------- + // Test URL Handling: Traversing + + // Test 19 / State 8 (1 -> 8) + addLog('Test 19',History.queues.length,History.busy.flag); + History.back(); + + // Test 20 / State 7 (8 -> 7) + addLog('Test 20',History.queues.length,History.busy.flag); + History.back(); + + // Test 21 / State 6 (7 -> 6) + addLog('Test 21',History.queues.length,History.busy.flag); + History.back(); + + // Test 22 / State 0 (6 -> 0) + addLog('Test 22',History.queues.length,History.busy.flag); + History.back(); + + },1000); // wait for test one to complete +}); + +})(); diff --git a/sites/all/themes/gui/materiobasetheme/bower_components/history.js/vendor/dojo.js b/sites/all/themes/gui/materiobasetheme/bower_components/history.js/vendor/dojo.js new file mode 100644 index 00000000..f66b95f4 --- /dev/null +++ b/sites/all/themes/gui/materiobasetheme/bower_components/history.js/vendor/dojo.js @@ -0,0 +1,17737 @@ +/* + Copyright (c) 2004-2012, The Dojo Foundation All Rights Reserved. + Available via Academic Free License >= 2.1 OR the modified BSD license. + see: http://dojotoolkit.org/license for details +*/ + +/* + This is an optimized version of Dojo, built for deployment and not for + development. To get sources and documentation, please visit: + + http://dojotoolkit.org +*/ + +(function( + userConfig, + defaultConfig +){ + // summary: + // This is the "source loader" and is the entry point for Dojo during development. You may also load Dojo with + // any AMD-compliant loader via the package main module dojo/main. + // description: + // This is the "source loader" for Dojo. It provides an AMD-compliant loader that can be configured + // to operate in either synchronous or asynchronous modes. After the loader is defined, dojo is loaded + // IAW the package main module dojo/main. In the event you wish to use a foreign loader, you may load dojo as a package + // via the package main module dojo/main and this loader is not required; see dojo/package.json for details. + // + // In order to keep compatibility with the v1.x line, this loader includes additional machinery that enables + // the dojo.provide, dojo.require et al API. This machinery is loaded by default, but may be dynamically removed + // via the has.js API and statically removed via the build system. + // + // This loader includes sniffing machinery to determine the environment; the following environments are supported: + // + // - browser + // - node.js + // - rhino + // + // This is the so-called "source loader". As such, it includes many optional features that may be discadred by + // building a customized verion with the build system. + + // Design and Implementation Notes + // + // This is a dojo-specific adaption of bdLoad, donated to the dojo foundation by Altoviso LLC. + // + // This function defines an AMD-compliant (http://wiki.commonjs.org/wiki/Modules/AsynchronousDefinition) + // loader that can be configured to operate in either synchronous or asynchronous modes. + // + // Since this machinery implements a loader, it does not have the luxury of using a load system and/or + // leveraging a utility library. This results in an unpleasantly long file; here is a road map of the contents: + // + // 1. Small library for use implementing the loader. + // 2. Define the has.js API; this is used throughout the loader to bracket features. + // 3. Define the node.js and rhino sniffs and sniff. + // 4. Define the loader's data. + // 5. Define the configuration machinery. + // 6. Define the script element sniffing machinery and sniff for configuration data. + // 7. Configure the loader IAW the provided user, default, and sniffing data. + // 8. Define the global require function. + // 9. Define the module resolution machinery. + // 10. Define the module and plugin module definition machinery + // 11. Define the script injection machinery. + // 12. Define the window load detection. + // 13. Define the logging API. + // 14. Define the tracing API. + // 16. Define the AMD define function. + // 17. Define the dojo v1.x provide/require machinery--so called "legacy" modes. + // 18. Publish global variables. + // + // Language and Acronyms and Idioms + // + // moduleId: a CJS module identifier, (used for public APIs) + // mid: moduleId (used internally) + // packageId: a package identifier (used for public APIs) + // pid: packageId (used internally); the implied system or default package has pid==="" + // pack: package is used internally to reference a package object (since javascript has reserved words including "package") + // prid: plugin resource identifier + // The integer constant 1 is used in place of true and 0 in place of false. + + // define a minimal library to help build the loader + var noop = function(){ + }, + + isEmpty = function(it){ + for(var p in it){ + return 0; + } + return 1; + }, + + toString = {}.toString, + + isFunction = function(it){ + return toString.call(it) == "[object Function]"; + }, + + isString = function(it){ + return toString.call(it) == "[object String]"; + }, + + isArray = function(it){ + return toString.call(it) == "[object Array]"; + }, + + forEach = function(vector, callback){ + if(vector){ + for(var i = 0; i < vector.length;){ + callback(vector[i++]); + } + } + }, + + mix = function(dest, src){ + for(var p in src){ + dest[p] = src[p]; + } + return dest; + }, + + makeError = function(error, info){ + return mix(new Error(error), {src:"dojoLoader", info:info}); + }, + + uidSeed = 1, + + uid = function(){ + // Returns a unique indentifier (within the lifetime of the document) of the form /_d+/. + return "_" + uidSeed++; + }, + + // FIXME: how to doc window.require() api + + // this will be the global require function; define it immediately so we can start hanging things off of it + req = function( + config, //(object, optional) hash of configuration properties + dependencies, //(array of commonjs.moduleId, optional) list of modules to be loaded before applying callback + callback //(function, optional) lamda expression to apply to module values implied by dependencies + ){ + return contextRequire(config, dependencies, callback, 0, req); + }, + + // the loader uses the has.js API to control feature inclusion/exclusion; define then use throughout + global = this, + + doc = global.document, + + element = doc && doc.createElement("DiV"), + + has = req.has = function(name){ + return isFunction(hasCache[name]) ? (hasCache[name] = hasCache[name](global, doc, element)) : hasCache[name]; + }, + + hasCache = has.cache = defaultConfig.hasCache; + + has.add = function(name, test, now, force){ + (hasCache[name]===undefined || force) && (hasCache[name] = test); + return now && has(name); + }; + + 0 && has.add("host-node", userConfig.has && "host-node" in userConfig.has ? + userConfig.has["host-node"] : + (typeof process == "object" && process.versions && process.versions.node && process.versions.v8)); + if( 0 ){ + // fixup the default config for node.js environment + require("./_base/configNode.js").config(defaultConfig); + // remember node's require (with respect to baseUrl==dojo's root) + defaultConfig.loaderPatch.nodeRequire = require; + } + + 0 && has.add("host-rhino", userConfig.has && "host-rhino" in userConfig.has ? + userConfig.has["host-rhino"] : + (typeof load == "function" && (typeof Packages == "function" || typeof Packages == "object"))); + if( 0 ){ + // owing to rhino's lame feature that hides the source of the script, give the user a way to specify the baseUrl... + for(var baseUrl = userConfig.baseUrl || ".", arg, rhinoArgs = this.arguments, i = 0; i < rhinoArgs.length;){ + arg = (rhinoArgs[i++] + "").split("="); + if(arg[0] == "baseUrl"){ + baseUrl = arg[1]; + break; + } + } + load(baseUrl + "/_base/configRhino.js"); + rhinoDojoConfig(defaultConfig, baseUrl, rhinoArgs); + } + + // userConfig has tests override defaultConfig has tests; do this after the environment detection because + // the environment detection usually sets some has feature values in the hasCache. + for(var p in userConfig.has){ + has.add(p, userConfig.has[p], 0, 1); + } + + // + // define the loader data + // + + // the loader will use these like symbols if the loader has the traceApi; otherwise + // define magic numbers so that modules can be provided as part of defaultConfig + var requested = 1, + arrived = 2, + nonmodule = 3, + executing = 4, + executed = 5; + + if( 0 ){ + // these make debugging nice; but using strings for symbols is a gross rookie error; don't do it for production code + requested = "requested"; + arrived = "arrived"; + nonmodule = "not-a-module"; + executing = "executing"; + executed = "executed"; + } + + var legacyMode = 0, + sync = "sync", + xd = "xd", + syncExecStack = [], + dojoRequirePlugin = 0, + checkDojoRequirePlugin = noop, + transformToAmd = noop, + getXhr; + if( 1 ){ + req.isXdUrl = noop; + + req.initSyncLoader = function(dojoRequirePlugin_, checkDojoRequirePlugin_, transformToAmd_){ + // the first dojo/_base/loader loaded gets to define these variables; they are designed to work + // in the presense of zero to many mapped dojo/_base/loaders + if(!dojoRequirePlugin){ + dojoRequirePlugin = dojoRequirePlugin_; + checkDojoRequirePlugin = checkDojoRequirePlugin_; + transformToAmd = transformToAmd_; + } + + return { + sync:sync, + requested:requested, + arrived:arrived, + nonmodule:nonmodule, + executing:executing, + executed:executed, + syncExecStack:syncExecStack, + modules:modules, + execQ:execQ, + getModule:getModule, + injectModule:injectModule, + setArrived:setArrived, + signal:signal, + finishExec:finishExec, + execModule:execModule, + dojoRequirePlugin:dojoRequirePlugin, + getLegacyMode:function(){return legacyMode;}, + guardCheckComplete:guardCheckComplete + }; + }; + + if( 1 ){ + // in legacy sync mode, the loader needs a minimal XHR library + + var locationProtocol = location.protocol, + locationHost = location.host; + req.isXdUrl = function(url){ + if(/^\./.test(url)){ + // begins with a dot is always relative to page URL; therefore not xdomain + return false; + } + if(/^\/\//.test(url)){ + // for v1.6- backcompat, url starting with // indicates xdomain + return true; + } + // get protocol and host + // \/+ takes care of the typical file protocol that looks like file:///drive/path/to/file + // locationHost is falsy if file protocol => if locationProtocol matches and is "file:", || will return false + var match = url.match(/^([^\/\:]+\:)\/+([^\/]+)/); + return match && (match[1] != locationProtocol || (locationHost && match[2] != locationHost)); + }; + + + // note: to get the file:// protocol to work in FF, you must set security.fileuri.strict_origin_policy to false in about:config + 1 || has.add("dojo-xhr-factory", 1); + has.add("dojo-force-activex-xhr", 1 && !doc.addEventListener && window.location.protocol == "file:"); + has.add("native-xhr", typeof XMLHttpRequest != "undefined"); + if(has("native-xhr") && !has("dojo-force-activex-xhr")){ + getXhr = function(){ + return new XMLHttpRequest(); + }; + }else{ + // if in the browser an old IE; find an xhr + for(var XMLHTTP_PROGIDS = ['Msxml2.XMLHTTP', 'Microsoft.XMLHTTP', 'Msxml2.XMLHTTP.4.0'], progid, i = 0; i < 3;){ + try{ + progid = XMLHTTP_PROGIDS[i++]; + if(new ActiveXObject(progid)){ + // this progid works; therefore, use it from now on + break; + } + }catch(e){ + // squelch; we're just trying to find a good ActiveX progid + // if they all fail, then progid ends up as the last attempt and that will signal the error + // the first time the client actually tries to exec an xhr + } + } + getXhr = function(){ + return new ActiveXObject(progid); + }; + } + req.getXhr = getXhr; + + has.add("dojo-gettext-api", 1); + req.getText = function(url, async, onLoad){ + var xhr = getXhr(); + xhr.open('GET', fixupUrl(url), false); + xhr.send(null); + if(xhr.status == 200 || (!location.host && !xhr.status)){ + if(onLoad){ + onLoad(xhr.responseText, async); + } + }else{ + throw makeError("xhrFailed", xhr.status); + } + return xhr.responseText; + }; + } + }else{ + req.async = 1; + } + + // + // loader eval + // + var eval_ = + // use the function constructor so our eval is scoped close to (but not in) in the global space with minimal pollution + new Function('return eval(arguments[0]);'); + + req.eval = + function(text, hint){ + return eval_(text + "\r\n////@ sourceURL=" + hint); + }; + + // + // loader micro events API + // + var listenerQueues = {}, + error = "error", + signal = req.signal = function(type, args){ + var queue = listenerQueues[type]; + // notice we run a copy of the queue; this allows listeners to add/remove + // other listeners without affecting this particular signal + forEach(queue && queue.slice(0), function(listener){ + listener.apply(null, isArray(args) ? args : [args]); + }); + }, + on = req.on = function(type, listener){ + // notice a queue is not created until a client actually connects + var queue = listenerQueues[type] || (listenerQueues[type] = []); + queue.push(listener); + return { + remove:function(){ + for(var i = 0; i (alias, actual) + = [], + + paths + // CommonJS paths + = {}, + + pathsMapProg + // list of (from-path, to-path, regex, length) derived from paths; + // a "program" to apply paths; see computeMapProg + = [], + + packs + // a map from packageId to package configuration object; see fixupPackageInfo + = {}, + + map = req.map + // AMD map config variable; dojo/_base/kernel needs req.map to figure out the scope map + = {}, + + mapProgs + // vector of quads as described by computeMapProg; map-key is AMD map key, map-value is AMD map value + = [], + + modules + // A hash:(mid) --> (module-object) the module namespace + // + // pid: the package identifier to which the module belongs (e.g., "dojo"); "" indicates the system or default package + // mid: the fully-resolved (i.e., mappings have been applied) module identifier without the package identifier (e.g., "dojo/io/script") + // url: the URL from which the module was retrieved + // pack: the package object of the package to which the module belongs + // executed: 0 => not executed; executing => in the process of tranversing deps and running factory; executed => factory has been executed + // deps: the dependency vector for this module (vector of modules objects) + // def: the factory for this module + // result: the result of the running the factory for this module + // injected: (0 | requested | arrived) the status of the module; nonmodule means the resource did not call define + // load: plugin load function; applicable only for plugins + // + // Modules go through several phases in creation: + // + // 1. Requested: some other module's definition or a require application contained the requested module in + // its dependency vector or executing code explicitly demands a module via req.require. + // + // 2. Injected: a script element has been appended to the insert-point element demanding the resource implied by the URL + // + // 3. Loaded: the resource injected in [2] has been evalated. + // + // 4. Defined: the resource contained a define statement that advised the loader about the module. Notice that some + // resources may just contain a bundle of code and never formally define a module via define + // + // 5. Evaluated: the module was defined via define and the loader has evaluated the factory and computed a result. + = {}, + + cacheBust + // query string to append to module URLs to bust browser cache + = "", + + cache + // hash:(mid | url)-->(function | string) + // + // A cache of resources. The resources arrive via a config.cache object, which is a hash from either mid --> function or + // url --> string. The url key is distinguished from the mid key by always containing the prefix "url:". url keys as provided + // by config.cache always have a string value that represents the contents of the resource at the given url. mid keys as provided + // by configl.cache always have a function value that causes the same code to execute as if the module was script injected. + // + // Both kinds of key-value pairs are entered into cache via the function consumePendingCache, which may relocate keys as given + // by any mappings *iff* the config.cache was received as part of a module resource request. + // + // Further, for mid keys, the implied url is computed and the value is entered into that key as well. This allows mapped modules + // to retrieve cached items that may have arrived consequent to another namespace. + // + = {}, + + urlKeyPrefix + // the prefix to prepend to a URL key in the cache. + = "url:", + + pendingCacheInsert + // hash:(mid)-->(function) + // + // Gives a set of cache modules pending entry into cache. When cached modules are published to the loader, they are + // entered into pendingCacheInsert; modules are then pressed into cache upon (1) AMD define or (2) upon receiving another + // independent set of cached modules. (1) is the usual case, and this case allows normalizing mids given in the pending + // cache for the local configuration, possibly relocating modules. + = {}, + + dojoSniffConfig + // map of configuration variables + // give the data-dojo-config as sniffed from the document (if any) + = {}; + + if( 1 ){ + var consumePendingCacheInsert = function(referenceModule){ + var p, item, match, now, m; + for(p in pendingCacheInsert){ + item = pendingCacheInsert[p]; + match = p.match(/^url\:(.+)/); + if(match){ + cache[urlKeyPrefix + toUrl(match[1], referenceModule)] = item; + }else if(p=="*now"){ + now = item; + }else if(p!="*noref"){ + m = getModuleInfo(p, referenceModule); + cache[m.mid] = cache[urlKeyPrefix + m.url] = item; + } + } + if(now){ + now(createRequire(referenceModule)); + } + pendingCacheInsert = {}; + }, + + escapeString = function(s){ + return s.replace(/([\.$?*|{}\(\)\[\]\\\/\+^])/g, function(c){ return "\\" + c; }); + }, + + computeMapProg = function(map, dest){ + // This routine takes a map as represented by a JavaScript object and initializes dest, a vector of + // quads of (map-key, map-value, refex-for-map-key, length-of-map-key), sorted decreasing by length- + // of-map-key. The regex looks for the map-key followed by either "/" or end-of-string at the beginning + // of a the search source. Notice the map-value is irrelevent to the algorithm + dest.splice(0, dest.length); + for(var p in map){ + dest.push([ + p, + map[p], + new RegExp("^" + escapeString(p) + "(\/|$)"), + p.length]); + } + dest.sort(function(lhs, rhs){ return rhs[3] - lhs[3]; }); + return dest; + }, + + fixupPackageInfo = function(packageInfo){ + // calculate the precise (name, location, main, mappings) for a package + var name = packageInfo.name; + if(!name){ + // packageInfo must be a string that gives the name + name = packageInfo; + packageInfo = {name:name}; + } + packageInfo = mix({main:"main"}, packageInfo); + packageInfo.location = packageInfo.location ? packageInfo.location : name; + + // packageMap is depricated in favor of AMD map + if(packageInfo.packageMap){ + map[name] = packageInfo.packageMap; + } + + if(!packageInfo.main.indexOf("./")){ + packageInfo.main = packageInfo.main.substring(2); + } + + // now that we've got a fully-resolved package object, push it into the configuration + packs[name] = packageInfo; + }, + + delayedModuleConfig + // module config cannot be consummed until the loader is completely initialized; therefore, all + // module config detected during booting is memorized and applied at the end of loader initialization + // TODO: this is a bit of a kludge; all config should be moved to end of loader initialization, but + // we'll delay this chore and do it with a final loader 1.x cleanup after the 2.x loader prototyping is complete + = [], + + + config = function(config, booting, referenceModule){ + for(var p in config){ + if(p=="waitSeconds"){ + req.waitms = (config[p] || 0) * 1000; + } + if(p=="cacheBust"){ + cacheBust = config[p] ? (isString(config[p]) ? config[p] : (new Date()).getTime() + "") : ""; + } + if(p=="baseUrl" || p=="combo"){ + req[p] = config[p]; + } + if( 1 && p=="async"){ + // falsy or "sync" => legacy sync loader + // "xd" => sync but loading xdomain tree and therefore loading asynchronously (not configurable, set automatically by the loader) + // "legacyAsync" => permanently in "xd" by choice + // "debugAtAllCosts" => trying to load everything via script injection (not implemented) + // otherwise, must be truthy => AMD + // legacyMode: sync | legacyAsync | xd | false + var mode = config[p]; + req.legacyMode = legacyMode = (isString(mode) && /sync|legacyAsync/.test(mode) ? mode : (!mode ? sync : false)); + req.async = !legacyMode; + } + if(config[p]!==hasCache){ + // accumulate raw config info for client apps which can use this to pass their own config + req.rawConfig[p] = config[p]; + p!="has" && has.add("config-"+p, config[p], 0, booting); + } + } + + // make sure baseUrl exists + if(!req.baseUrl){ + req.baseUrl = "./"; + } + // make sure baseUrl ends with a slash + if(!/\/$/.test(req.baseUrl)){ + req.baseUrl += "/"; + } + + // now do the special work for has, packages, packagePaths, paths, aliases, and cache + + for(p in config.has){ + has.add(p, config.has[p], 0, booting); + } + + // for each package found in any packages config item, augment the packs map owned by the loader + forEach(config.packages, fixupPackageInfo); + + // for each packagePath found in any packagePaths config item, augment the packageConfig + // packagePaths is depricated; remove in 2.0 + for(baseUrl in config.packagePaths){ + forEach(config.packagePaths[baseUrl], function(packageInfo){ + var location = baseUrl + "/" + packageInfo; + if(isString(packageInfo)){ + packageInfo = {name:packageInfo}; + } + packageInfo.location = location; + fixupPackageInfo(packageInfo); + }); + } + + // notice that computeMapProg treats the dest as a reference; therefore, if/when that variable + // is published (see dojo-publish-privates), the published variable will always hold a valid value. + + // this must come after all package processing since package processing may mutate map + computeMapProg(mix(map, config.map), mapProgs); + forEach(mapProgs, function(item){ + item[1] = computeMapProg(item[1], []); + if(item[0]=="*"){ + mapProgs.star = item[1]; + } + }); + + // push in any paths and recompute the internal pathmap + computeMapProg(mix(paths, config.paths), pathsMapProg); + + // aliases + forEach(config.aliases, function(pair){ + if(isString(pair[0])){ + pair[0] = new RegExp("^" + escapeString(pair[0]) + "$"); + } + aliases.push(pair); + }); + + if(booting){ + delayedModuleConfig.push({config:config.config}); + }else{ + for(p in config.config){ + var module = getModule(p, referenceModule); + module.config = mix(module.config || {}, config.config[p]); + } + } + + // push in any new cache values + if(config.cache){ + consumePendingCacheInsert(); + pendingCacheInsert = config.cache; + if(config.cache["*noref"]){ + consumePendingCacheInsert(); + } + } + + signal("config", [config, req.rawConfig]); + }; + + // + // execute the various sniffs; userConfig can override and value + // + + if(has("dojo-cdn") || 1 ){ + // the sniff regex looks for a src attribute ending in dojo.js, optionally preceeded with a path. + // match[3] returns the path to dojo.js (if any) without the trailing slash. This is used for the + // dojo location on CDN deployments and baseUrl when either/both of these are not provided + // explicitly in the config data; this is the 1.6- behavior. + + var scripts = doc.getElementsByTagName("script"), + i = 0, + script, dojoDir, src, match; + while(i < scripts.length){ + script = scripts[i++]; + if((src = script.getAttribute("src")) && (match = src.match(/(((.*)\/)|^)dojo\.js(\W|$)/i))){ + // sniff dojoDir and baseUrl + dojoDir = match[3] || ""; + defaultConfig.baseUrl = defaultConfig.baseUrl || dojoDir; + + // sniff configuration on attribute in script element + src = (script.getAttribute("data-dojo-config") || script.getAttribute("djConfig")); + if(src){ + dojoSniffConfig = req.eval("({ " + src + " })", "data-dojo-config"); + } + + // sniff requirejs attribute + if( 0 ){ + var dataMain = script.getAttribute("data-main"); + if(dataMain){ + dojoSniffConfig.deps = dojoSniffConfig.deps || [dataMain]; + } + } + break; + } + } + } + + if( 0 ){ + // pass down doh.testConfig from parent as if it were a data-dojo-config + try{ + if(window.parent != window && window.parent.require){ + var doh = window.parent.require("doh"); + doh && mix(dojoSniffConfig, doh.testConfig); + } + }catch(e){} + } + + // configure the loader; let the user override defaults + req.rawConfig = {}; + config(defaultConfig, 1); + + // do this before setting userConfig/sniffConfig to allow userConfig/sniff overrides + if(has("dojo-cdn")){ + packs.dojo.location = dojoDir; + if(dojoDir){ + dojoDir += "/"; + } + packs.dijit.location = dojoDir + "../dijit/"; + packs.dojox.location = dojoDir + "../dojox/"; + } + + config(userConfig, 1); + config(dojoSniffConfig, 1); + + }else{ + // no config API, assume defaultConfig has everything the loader needs...for the entire lifetime of the application + paths = defaultConfig.paths; + pathsMapProg = defaultConfig.pathsMapProg; + packs = defaultConfig.packs; + aliases = defaultConfig.aliases; + mapProgs = defaultConfig.mapProgs; + modules = defaultConfig.modules; + cache = defaultConfig.cache; + cacheBust = defaultConfig.cacheBust; + + // remember the default config for other processes (e.g., dojo/config) + req.rawConfig = defaultConfig; + } + + + if( 0 ){ + req.combo = req.combo || {add:noop}; + var comboPending = 0, + combosPending = [], + comboPendingTimer = null; + } + + + // build the loader machinery iaw configuration, including has feature tests + var injectDependencies = function(module){ + // checkComplete!=0 holds the idle signal; we're not idle if we're injecting dependencies + guardCheckComplete(function(){ + forEach(module.deps, injectModule); + if( 0 && comboPending && !comboPendingTimer){ + comboPendingTimer = setTimeout(function() { + comboPending = 0; + comboPendingTimer = null; + req.combo.done(function(mids, url) { + var onLoadCallback= function(){ + // defQ is a vector of module definitions 1-to-1, onto mids + runDefQ(0, mids); + checkComplete(); + }; + combosPending.push(mids); + injectingModule = mids; + req.injectUrl(url, onLoadCallback, mids); + injectingModule = 0; + }, req); + }, 0); + } + }); + }, + + contextRequire = function(a1, a2, a3, referenceModule, contextRequire){ + var module, syntheticMid; + if(isString(a1)){ + // signature is (moduleId) + module = getModule(a1, referenceModule, true); + if(module && module.executed){ + return module.result; + } + throw makeError("undefinedModule", a1); + } + if(!isArray(a1)){ + // a1 is a configuration + config(a1, 0, referenceModule); + + // juggle args; (a2, a3) may be (dependencies, callback) + a1 = a2; + a2 = a3; + } + if(isArray(a1)){ + // signature is (requestList [,callback]) + if(!a1.length){ + a2 && a2(); + }else{ + syntheticMid = "require*" + uid(); + + // resolve the request list with respect to the reference module + for(var mid, deps = [], i = 0; i < a1.length;){ + mid = a1[i++]; + deps.push(getModule(mid, referenceModule)); + } + + // construct a synthetic module to control execution of the requestList, and, optionally, callback + module = mix(makeModuleInfo("", syntheticMid, 0, ""), { + injected: arrived, + deps: deps, + def: a2 || noop, + require: referenceModule ? referenceModule.require : req, + gc: 1 //garbage collect + }); + modules[module.mid] = module; + + // checkComplete!=0 holds the idle signal; we're not idle if we're injecting dependencies + injectDependencies(module); + + // try to immediately execute + // if already traversing a factory tree, then strict causes circular dependency to abort the execution; maybe + // it's possible to execute this require later after the current traversal completes and avoid the circular dependency. + // ...but *always* insist on immediate in synch mode + var strict = checkCompleteGuard && legacyMode!=sync; + guardCheckComplete(function(){ + execModule(module, strict); + }); + if(!module.executed){ + // some deps weren't on board or circular dependency detected and strict; therefore, push into the execQ + execQ.push(module); + } + checkComplete(); + } + } + return contextRequire; + }, + + createRequire = function(module){ + if(!module){ + return req; + } + var result = module.require; + if(!result){ + result = function(a1, a2, a3){ + return contextRequire(a1, a2, a3, module, result); + }; + module.require = mix(result, req); + result.module = module; + result.toUrl = function(name){ + return toUrl(name, module); + }; + result.toAbsMid = function(mid){ + return toAbsMid(mid, module); + }; + if( 0 ){ + result.undef = function(mid){ + req.undef(mid, module); + }; + } + if( 1 ){ + result.syncLoadNls = function(mid){ + var nlsModuleInfo = getModuleInfo(mid, module), + nlsModule = modules[nlsModuleInfo.mid]; + if(!nlsModule || !nlsModule.executed){ + cached = cache[nlsModuleInfo.mid] || cache[urlKeyPrefix + nlsModuleInfo.url]; + if(cached){ + evalModuleText(cached); + nlsModule = modules[nlsModuleInfo.mid]; + } + } + return nlsModule && nlsModule.executed && nlsModule.result; + }; + } + + } + return result; + }, + + execQ = + // The list of modules that need to be evaluated. + [], + + defQ = + // The queue of define arguments sent to loader. + [], + + waiting = + // The set of modules upon which the loader is waiting for definition to arrive + {}, + + setRequested = function(module){ + module.injected = requested; + waiting[module.mid] = 1; + if(module.url){ + waiting[module.url] = module.pack || 1; + } + startTimer(); + }, + + setArrived = function(module){ + module.injected = arrived; + delete waiting[module.mid]; + if(module.url){ + delete waiting[module.url]; + } + if(isEmpty(waiting)){ + clearTimer(); + 1 && legacyMode==xd && (legacyMode = sync); + } + }, + + execComplete = req.idle = + // says the loader has completed (or not) its work + function(){ + return !defQ.length && isEmpty(waiting) && !execQ.length && !checkCompleteGuard; + }, + + runMapProg = function(targetMid, map){ + // search for targetMid in map; return the map item if found; falsy otherwise + if(map){ + for(var i = 0; i < map.length; i++){ + if(map[i][2].test(targetMid)){ + return map[i]; + } + } + } + return 0; + }, + + compactPath = function(path){ + var result = [], + segment, lastSegment; + path = path.replace(/\\/g, '/').split('/'); + while(path.length){ + segment = path.shift(); + if(segment==".." && result.length && lastSegment!=".."){ + result.pop(); + lastSegment = result[result.length - 1]; + }else if(segment!="."){ + result.push(lastSegment= segment); + } // else ignore "." + } + return result.join("/"); + }, + + makeModuleInfo = function(pid, mid, pack, url){ + if( 1 ){ + var xd= req.isXdUrl(url); + return {pid:pid, mid:mid, pack:pack, url:url, executed:0, def:0, isXd:xd, isAmd:!!(xd || (packs[pid] && packs[pid].isAmd))}; + }else{ + return {pid:pid, mid:mid, pack:pack, url:url, executed:0, def:0}; + } + }, + + getModuleInfo_ = function(mid, referenceModule, packs, modules, baseUrl, mapProgs, pathsMapProg, alwaysCreate){ + // arguments are passed instead of using lexical variables so that this function my be used independent of the loader (e.g., the builder) + // alwaysCreate is useful in this case so that getModuleInfo never returns references to real modules owned by the loader + var pid, pack, midInPackage, mapProg, mapItem, url, result, isRelative, requestedMid; + requestedMid = mid; + isRelative = /^\./.test(mid); + if(/(^\/)|(\:)|(\.js$)/.test(mid) || (isRelative && !referenceModule)){ + // absolute path or protocol of .js filetype, or relative path but no reference module and therefore relative to page + // whatever it is, it's not a module but just a URL of some sort + // note: pid===0 indicates the routine is returning an unmodified mid + + return makeModuleInfo(0, mid, 0, mid); + }else{ + // relative module ids are relative to the referenceModule; get rid of any dots + mid = compactPath(isRelative ? (referenceModule.mid + "/../" + mid) : mid); + if(/^\./.test(mid)){ + throw makeError("irrationalPath", mid); + } + // at this point, mid is an absolute mid + + // map the mid + if(referenceModule){ + mapItem = runMapProg(referenceModule.mid, mapProgs); + } + mapItem = mapItem || mapProgs.star; + mapItem = mapItem && runMapProg(mid, mapItem[1]); + + if(mapItem){ + mid = mapItem[1] + mid.substring(mapItem[3]); + } + + match = mid.match(/^([^\/]+)(\/(.+))?$/); + pid = match ? match[1] : ""; + if((pack = packs[pid])){ + mid = pid + "/" + (midInPackage = (match[3] || pack.main)); + }else{ + pid = ""; + } + + // search aliases + var candidateLength = 0, + candidate = 0; + forEach(aliases, function(pair){ + var match = mid.match(pair[0]); + if(match && match.length>candidateLength){ + candidate = isFunction(pair[1]) ? mid.replace(pair[0], pair[1]) : pair[1]; + } + }); + if(candidate){ + return getModuleInfo_(candidate, 0, packs, modules, baseUrl, mapProgs, pathsMapProg, alwaysCreate); + } + + result = modules[mid]; + if(result){ + return alwaysCreate ? makeModuleInfo(result.pid, result.mid, result.pack, result.url) : modules[mid]; + } + } + // get here iff the sought-after module does not yet exist; therefore, we need to compute the URL given the + // fully resolved (i.e., all relative indicators and package mapping resolved) module id + + // note: pid!==0 indicates the routine is returning a url that has .js appended unmodified mid + mapItem = runMapProg(mid, pathsMapProg); + if(mapItem){ + url = mapItem[1] + mid.substring(mapItem[3]); + }else if(pid){ + url = pack.location + "/" + midInPackage; + }else if(has("config-tlmSiblingOfDojo")){ + url = "../" + mid; + }else{ + url = mid; + } + // if result is not absolute, add baseUrl + if(!(/(^\/)|(\:)/.test(url))){ + url = baseUrl + url; + } + url += ".js"; + return makeModuleInfo(pid, mid, pack, compactPath(url)); + }, + + getModuleInfo = function(mid, referenceModule){ + return getModuleInfo_(mid, referenceModule, packs, modules, req.baseUrl, mapProgs, pathsMapProg); + }, + + resolvePluginResourceId = function(plugin, prid, referenceModule){ + return plugin.normalize ? plugin.normalize(prid, function(mid){return toAbsMid(mid, referenceModule);}) : toAbsMid(prid, referenceModule); + }, + + dynamicPluginUidGenerator = 0, + + getModule = function(mid, referenceModule, immediate){ + // compute and optionally construct (if necessary) the module implied by the mid with respect to referenceModule + var match, plugin, prid, result; + match = mid.match(/^(.+?)\!(.*)$/); + if(match){ + // name was ! + plugin = getModule(match[1], referenceModule, immediate); + + if( 1 && legacyMode == sync && !plugin.executed){ + injectModule(plugin); + if(plugin.injected===arrived && !plugin.executed){ + guardCheckComplete(function(){ + execModule(plugin); + }); + } + if(plugin.executed){ + promoteModuleToPlugin(plugin); + }else{ + // we are in xdomain mode for some reason + execQ.unshift(plugin); + } + } + + + + if(plugin.executed === executed && !plugin.load){ + // executed the module not knowing it was a plugin + promoteModuleToPlugin(plugin); + } + + // if the plugin has not been loaded, then can't resolve the prid and must assume this plugin is dynamic until we find out otherwise + if(plugin.load){ + prid = resolvePluginResourceId(plugin, match[2], referenceModule); + mid = (plugin.mid + "!" + (plugin.dynamic ? ++dynamicPluginUidGenerator + "!" : "") + prid); + }else{ + prid = match[2]; + mid = plugin.mid + "!" + (++dynamicPluginUidGenerator) + "!waitingForPlugin"; + } + result = {plugin:plugin, mid:mid, req:createRequire(referenceModule), prid:prid}; + }else{ + result = getModuleInfo(mid, referenceModule); + } + return modules[result.mid] || (!immediate && (modules[result.mid] = result)); + }, + + toAbsMid = req.toAbsMid = function(mid, referenceModule){ + return getModuleInfo(mid, referenceModule).mid; + }, + + toUrl = req.toUrl = function(name, referenceModule){ + var moduleInfo = getModuleInfo(name+"/x", referenceModule), + url= moduleInfo.url; + return fixupUrl(moduleInfo.pid===0 ? + // if pid===0, then name had a protocol or absolute path; either way, toUrl is the identify function in such cases + name : + // "/x.js" since getModuleInfo automatically appends ".js" and we appended "/x" to make name look likde a module id + url.substring(0, url.length-5) + ); + }, + + nonModuleProps = { + injected: arrived, + executed: executed, + def: nonmodule, + result: nonmodule + }, + + makeCjs = function(mid){ + return modules[mid] = mix({mid:mid}, nonModuleProps); + }, + + cjsRequireModule = makeCjs("require"), + cjsExportsModule = makeCjs("exports"), + cjsModuleModule = makeCjs("module"), + + runFactory = function(module, args){ + req.trace("loader-run-factory", [module.mid]); + var factory = module.def, + result; + 1 && syncExecStack.unshift(module); + if(has("config-dojo-loader-catches")){ + try{ + result= isFunction(factory) ? factory.apply(null, args) : factory; + }catch(e){ + signal(error, module.result = makeError("factoryThrew", [module, e])); + } + }else{ + result= isFunction(factory) ? factory.apply(null, args) : factory; + } + module.result = result===undefined && module.cjs ? module.cjs.exports : result; + 1 && syncExecStack.shift(module); + }, + + abortExec = {}, + + defOrder = 0, + + promoteModuleToPlugin = function(pluginModule){ + var plugin = pluginModule.result; + pluginModule.dynamic = plugin.dynamic; + pluginModule.normalize = plugin.normalize; + pluginModule.load = plugin.load; + return pluginModule; + }, + + resolvePluginLoadQ = function(plugin){ + // plugins is a newly executed module that has a loadQ waiting to run + + // step 1: traverse the loadQ and fixup the mid and prid; remember the map from original mid to new mid + // recall the original mid was created before the plugin was on board and therefore it was impossible to + // compute the final mid; accordingly, prid may or may not change, but the mid will definitely change + var map = {}; + forEach(plugin.loadQ, function(pseudoPluginResource){ + // manufacture and insert the real module in modules + var prid = resolvePluginResourceId(plugin, pseudoPluginResource.prid, pseudoPluginResource.req.module), + mid = plugin.dynamic ? pseudoPluginResource.mid.replace(/waitingForPlugin$/, prid) : (plugin.mid + "!" + prid), + pluginResource = mix(mix({}, pseudoPluginResource), {mid:mid, prid:prid, injected:0}); + if(!modules[mid]){ + // create a new (the real) plugin resource and inject it normally now that the plugin is on board + injectPlugin(modules[mid] = pluginResource); + } // else this was a duplicate request for the same (plugin, rid) for a nondynamic plugin + + // pluginResource is really just a placeholder with the wrong mid (because we couldn't calculate it until the plugin was on board) + // mark is as arrived and delete it from modules; the real module was requested above + map[pseudoPluginResource.mid] = modules[mid]; + setArrived(pseudoPluginResource); + delete modules[pseudoPluginResource.mid]; + }); + plugin.loadQ = 0; + + // step2: replace all references to any placeholder modules with real modules + var substituteModules = function(module){ + for(var replacement, deps = module.deps || [], i = 0; i")]); + return (!module.def || strict) ? abortExec : (module.cjs && module.cjs.exports); + } + // at this point the module is either not executed or fully executed + + + if(!module.executed){ + if(!module.def){ + return abortExec; + } + var mid = module.mid, + deps = module.deps || [], + arg, argResult, + args = [], + i = 0; + + if( 0 ){ + circleTrace.push(mid); + req.trace("loader-exec-module", ["exec", circleTrace.length, mid]); + } + + // for circular dependencies, assume the first module encountered was executed OK + // modules that circularly depend on a module that has not run its factory will get + // the premade cjs.exports===module.result. They can take a reference to this object and/or + // add properties to it. When the module finally runs its factory, the factory can + // read/write/replace this object. Notice that so long as the object isn't replaced, any + // reference taken earlier while walking the deps list is still valid. + module.executed = executing; + while(i < deps.length){ + arg = deps[i++]; + argResult = ((arg === cjsRequireModule) ? createRequire(module) : + ((arg === cjsExportsModule) ? module.cjs.exports : + ((arg === cjsModuleModule) ? module.cjs : + execModule(arg, strict)))); + if(argResult === abortExec){ + module.executed = 0; + req.trace("loader-exec-module", ["abort", mid]); + 0 && circleTrace.pop(); + return abortExec; + } + args.push(argResult); + } + runFactory(module, args); + finishExec(module); + 0 && circleTrace.pop(); + } + // at this point the module is guaranteed fully executed + + return module.result; + }, + + + checkCompleteGuard = 0, + + guardCheckComplete = function(proc){ + try{ + checkCompleteGuard++; + proc(); + }finally{ + checkCompleteGuard--; + } + if(execComplete()){ + signal("idle", []); + } + }, + + checkComplete = function(){ + // keep going through the execQ as long as at least one factory is executed + // plugins, recursion, cached modules all make for many execution path possibilities + if(checkCompleteGuard){ + return; + } + guardCheckComplete(function(){ + checkDojoRequirePlugin(); + for(var currentDefOrder, module, i = 0; i < execQ.length;){ + currentDefOrder = defOrder; + module = execQ[i]; + execModule(module); + if(currentDefOrder!=defOrder){ + // defOrder was bumped one or more times indicating something was executed (note, this indicates + // the execQ was modified, maybe a lot (for example a later module causes an earlier module to execute) + checkDojoRequirePlugin(); + i = 0; + }else{ + // nothing happened; check the next module in the exec queue + i++; + } + } + }); + }; + + + if( 0 ){ + req.undef = function(moduleId, referenceModule){ + // In order to reload a module, it must be undefined (this routine) and then re-requested. + // This is useful for testing frameworks (at least). + var module = getModule(moduleId, referenceModule); + setArrived(module); + delete modules[module.mid]; + }; + } + + if( 1 ){ + if(has("dojo-loader-eval-hint-url")===undefined){ + has.add("dojo-loader-eval-hint-url", 1); + } + + var fixupUrl= function(url){ + url += ""; // make sure url is a Javascript string (some paths may be a Java string) + return url + (cacheBust ? ((/\?/.test(url) ? "&" : "?") + cacheBust) : ""); + }, + + injectPlugin = function( + module + ){ + // injects the plugin module given by module; may have to inject the plugin itself + var plugin = module.plugin; + + if(plugin.executed === executed && !plugin.load){ + // executed the module not knowing it was a plugin + promoteModuleToPlugin(plugin); + } + + var onLoad = function(def){ + module.result = def; + setArrived(module); + finishExec(module); + checkComplete(); + }; + + if(plugin.load){ + plugin.load(module.prid, module.req, onLoad); + }else if(plugin.loadQ){ + plugin.loadQ.push(module); + }else{ + // the unshift instead of push is important: we don't want plugins to execute as + // dependencies of some other module because this may cause circles when the plugin + // loadQ is run; also, generally, we want plugins to run early since they may load + // several other modules and therefore can potentially unblock many modules + plugin.loadQ = [module]; + execQ.unshift(plugin); + injectModule(plugin); + } + }, + + // for IE, injecting a module may result in a recursive execution if the module is in the cache + + cached = 0, + + injectingModule = 0, + + injectingCachedModule = 0, + + evalModuleText = function(text, module){ + // see def() for the injectingCachedModule bracket; it simply causes a short, safe curcuit + if(has("config-stripStrict")){ + text = text.replace(/"use strict"/g, ''); + } + injectingCachedModule = 1; + if(has("config-dojo-loader-catches")){ + try{ + if(text===cached){ + cached.call(null); + }else{ + req.eval(text, has("dojo-loader-eval-hint-url") ? module.url : module.mid); + } + }catch(e){ + signal(error, makeError("evalModuleThrew", module)); + } + }else{ + if(text===cached){ + cached.call(null); + }else{ + req.eval(text, has("dojo-loader-eval-hint-url") ? module.url : module.mid); + } + } + injectingCachedModule = 0; + }, + + injectModule = function(module){ + // Inject the module. In the browser environment, this means appending a script element into + // the document; in other environments, it means loading a file. + // + // If in synchronous mode, then get the module synchronously if it's not xdomainLoading. + + var mid = module.mid, + url = module.url; + if(module.executed || module.injected || waiting[mid] || (module.url && ((module.pack && waiting[module.url]===module.pack) || waiting[module.url]==1))){ + return; + } + setRequested(module); + + if( 0 ){ + var viaCombo = 0; + if(module.plugin && module.plugin.isCombo){ + // a combo plugin; therefore, must be handled by combo service + // the prid should have already been converted to a URL (if required by the plugin) during + // the normalze process; in any event, there is no way for the loader to know how to + // to the conversion; therefore the third argument is zero + req.combo.add(module.plugin.mid, module.prid, 0, req); + viaCombo = 1; + }else if(!module.plugin){ + viaCombo = req.combo.add(0, module.mid, module.url, req); + } + if(viaCombo){ + comboPending= 1; + return; + } + } + + if(module.plugin){ + injectPlugin(module); + return; + } // else a normal module (not a plugin) + + + var onLoadCallback = function(){ + runDefQ(module); + if(module.injected !== arrived){ + // the script that contained the module arrived and has been executed yet + // nothing was added to the defQ (so it wasn't an AMD module) and the module + // wasn't marked as arrived by dojo.provide (so it wasn't a v1.6- module); + // therefore, it must not have been a module; adjust state accordingly + setArrived(module); + mix(module, nonModuleProps); + req.trace("loader-define-nonmodule", [module.url]); + } + + if( 1 && legacyMode){ + // must call checkComplete even in for sync loader because we may be in xdomainLoading mode; + // but, if xd loading, then don't call checkComplete until out of the current sync traversal + // in order to preserve order of execution of the dojo.required modules + !syncExecStack.length && checkComplete(); + }else{ + checkComplete(); + } + }; + cached = cache[mid] || cache[urlKeyPrefix + module.url]; + if(cached){ + req.trace("loader-inject", ["cache", module.mid, url]); + evalModuleText(cached, module); + onLoadCallback(); + return; + } + if( 1 && legacyMode){ + if(module.isXd){ + // switch to async mode temporarily; if current legacyMode!=sync, then is must be one of {legacyAsync, xd, false} + legacyMode==sync && (legacyMode = xd); + // fall through and load via script injection + }else if(module.isAmd && legacyMode!=sync){ + // fall through and load via script injection + }else{ + // mode may be sync, xd/legacyAsync, or async; module may be AMD or legacy; but module is always located on the same domain + var xhrCallback = function(text){ + if(legacyMode==sync){ + // the top of syncExecStack gives the current synchronously executing module; the loader needs + // to know this if it has to switch to async loading in the middle of evaluating a legacy module + // this happens when a modules dojo.require's a module that must be loaded async because it's xdomain + // (using unshift/shift because there is no back() methods for Javascript arrays) + syncExecStack.unshift(module); + evalModuleText(text, module); + syncExecStack.shift(); + + // maybe the module was an AMD module + runDefQ(module); + + // legacy modules never get to defineModule() => cjs and injected never set; also evaluation implies executing + if(!module.cjs){ + setArrived(module); + finishExec(module); + } + + if(module.finish){ + // while synchronously evaluating this module, dojo.require was applied referencing a module + // that had to be loaded async; therefore, the loader stopped answering all dojo.require + // requests so they could be answered completely in the correct sequence; module.finish gives + // the list of dojo.requires that must be re-applied once all target modules are available; + // make a synthetic module to execute the dojo.require's in the correct order + + // compute a guarnateed-unique mid for the synthetic finish module; remember the finish vector; remove it from the reference module + // TODO: can we just leave the module.finish...what's it hurting? + var finishMid = mid + "*finish", + finish = module.finish; + delete module.finish; + + def(finishMid, ["dojo", ("dojo/require!" + finish.join(",")).replace(/\./g, "/")], function(dojo){ + forEach(finish, function(mid){ dojo.require(mid); }); + }); + // unshift, not push, which causes the current traversal to be reattempted from the top + execQ.unshift(getModule(finishMid)); + } + onLoadCallback(); + }else{ + text = transformToAmd(module, text); + if(text){ + evalModuleText(text, module); + onLoadCallback(); + }else{ + // if transformToAmd returned falsy, then the module was already AMD and it can be script-injected + // do so to improve debugability(even though it means another download...which probably won't happen with a good browser cache) + injectingModule = module; + req.injectUrl(fixupUrl(url), onLoadCallback, module); + injectingModule = 0; + } + } + }; + + req.trace("loader-inject", ["xhr", module.mid, url, legacyMode!=sync]); + if(has("config-dojo-loader-catches")){ + try{ + req.getText(url, legacyMode!=sync, xhrCallback); + }catch(e){ + signal(error, makeError("xhrInjectFailed", [module, e])); + } + }else{ + req.getText(url, legacyMode!=sync, xhrCallback); + } + return; + } + } // else async mode or fell through in xdomain loading mode; either way, load by script injection + req.trace("loader-inject", ["script", module.mid, url]); + injectingModule = module; + req.injectUrl(fixupUrl(url), onLoadCallback, module); + injectingModule = 0; + }, + + defineModule = function(module, deps, def){ + req.trace("loader-define-module", [module.mid, deps]); + + if( 0 && module.plugin && module.plugin.isCombo){ + // the module is a plugin resource loaded by the combo service + // note: check for module.plugin should be enough since normal plugin resources should + // not follow this path; module.plugin.isCombo is future-proofing belt and suspenders + module.result = isFunction(def) ? def() : def; + setArrived(module); + finishExec(module); + return module; + }; + + var mid = module.mid; + if(module.injected === arrived){ + signal(error, makeError("multipleDefine", module)); + return module; + } + mix(module, { + deps: deps, + def: def, + cjs: { + id: module.mid, + uri: module.url, + exports: (module.result = {}), + setExports: function(exports){ + module.cjs.exports = exports; + }, + config:function(){ + return module.config; + } + } + }); + + // resolve deps with respect to this module + for(var i = 0; i < deps.length; i++){ + deps[i] = getModule(deps[i], module); + } + + if( 1 && legacyMode && !waiting[mid]){ + // the module showed up without being asked for; it was probably in a + // + return new NodeList(); // dojo/NodeList + }; + =====*/ + + // the query that is returned from this module is slightly different than dojo.query, + // because dojo.query has to maintain backwards compatibility with returning a + // true array which has performance problems. The query returned from the module + // does not use true arrays, but rather inherits from Array, making it much faster to + // instantiate. + dojo.query = queryForEngine(defaultEngine, function(array){ + // call it without the new operator to invoke the back-compat behavior that returns a true array + return NodeList(array); // dojo/NodeList + }); + + query.load = function(id, parentRequire, loaded){ + // summary: + // can be used as AMD plugin to conditionally load new query engine + // example: + // | require(["dojo/query!custom"], function(qsa){ + // | // loaded selector/custom.js as engine + // | qsa("#foobar").forEach(...); + // | }); + loader.load(id, parentRequire, function(engine){ + loaded(queryForEngine(engine, NodeList)); + }); + }; + + dojo._filterQueryResult = query._filterResult = function(nodes, selector, root){ + return new NodeList(query.filter(nodes, selector, root)); + }; + dojo.NodeList = query.NodeList = NodeList; + return query; +}); + +}, +'dojo/has':function(){ +define(["require", "module"], function(require, module){ + // module: + // dojo/has + // summary: + // Defines the has.js API and several feature tests used by dojo. + // description: + // This module defines the has API as described by the project has.js with the following additional features: + // + // - the has test cache is exposed at has.cache. + // - the method has.add includes a forth parameter that controls whether or not existing tests are replaced + // - the loader's has cache may be optionally copied into this module's has cahce. + // + // This module adopted from https://github.com/phiggins42/has.js; thanks has.js team! + + // try to pull the has implementation from the loader; both the dojo loader and bdLoad provide one + // if using a foreign loader, then the has cache may be initialized via the config object for this module + // WARNING: if a foreign loader defines require.has to be something other than the has.js API, then this implementation fail + var has = require.has || function(){}; + if(! 1 ){ + var + isBrowser = + // the most fundamental decision: are we in the browser? + typeof window != "undefined" && + typeof location != "undefined" && + typeof document != "undefined" && + window.location == location && window.document == document, + + // has API variables + global = this, + doc = isBrowser && document, + element = doc && doc.createElement("DiV"), + cache = (module.config && module.config()) || {}; + + has = function(name){ + // summary: + // Return the current value of the named feature. + // + // name: String|Integer + // The name (if a string) or identifier (if an integer) of the feature to test. + // + // description: + // Returns the value of the feature named by name. The feature must have been + // previously added to the cache by has.add. + + return typeof cache[name] == "function" ? (cache[name] = cache[name](global, doc, element)) : cache[name]; // Boolean + }; + + has.cache = cache; + + has.add = function(name, test, now, force){ + // summary: + // Register a new feature test for some named feature. + // name: String|Integer + // The name (if a string) or identifier (if an integer) of the feature to test. + // test: Function + // A test function to register. If a function, queued for testing until actually + // needed. The test function should return a boolean indicating + // the presence of a feature or bug. + // now: Boolean? + // Optional. Omit if `test` is not a function. Provides a way to immediately + // run the test and cache the result. + // force: Boolean? + // Optional. If the test already exists and force is truthy, then the existing + // test will be replaced; otherwise, add does not replace an existing test (that + // is, by default, the first test advice wins). + // example: + // A redundant test, testFn with immediate execution: + // | has.add("javascript", function(){ return true; }, true); + // + // example: + // Again with the redundantness. You can do this in your tests, but we should + // not be doing this in any internal has.js tests + // | has.add("javascript", true); + // + // example: + // Three things are passed to the testFunction. `global`, `document`, and a generic element + // from which to work your test should the need arise. + // | has.add("bug-byid", function(g, d, el){ + // | // g == global, typically window, yadda yadda + // | // d == document object + // | // el == the generic element. a `has` element. + // | return false; // fake test, byid-when-form-has-name-matching-an-id is slightly longer + // | }); + + (typeof cache[name]=="undefined" || force) && (cache[name]= test); + return now && has(name); + }; + + // since we're operating under a loader that doesn't provide a has API, we must explicitly initialize + // has as it would have otherwise been initialized by the dojo loader; use has.add to the builder + // can optimize these away iff desired + 1 || has.add("host-browser", isBrowser); + 1 || has.add("dom", isBrowser); + 1 || has.add("dojo-dom-ready-api", 1); + 1 || has.add("dojo-sniff", 1); + } + + if( 1 ){ + // Common application level tests + has.add("dom-addeventlistener", !!document.addEventListener); + has.add("touch", "ontouchstart" in document); + // I don't know if any of these tests are really correct, just a rough guess + has.add("device-width", screen.availWidth || innerWidth); + + // Tests for DOMNode.attributes[] behavior: + // - dom-attributes-explicit - attributes[] only lists explicitly user specified attributes + // - dom-attributes-specified-flag (IE8) - need to check attr.specified flag to skip attributes user didn't specify + // - Otherwise, in IE6-7. attributes[] will list hundreds of values, so need to do outerHTML to get attrs instead. + var form = document.createElement("form"); + has.add("dom-attributes-explicit", form.attributes.length == 0); // W3C + has.add("dom-attributes-specified-flag", form.attributes.length > 0 && form.attributes.length < 40); // IE8 + } + + has.clearElement = function(element){ + // summary: + // Deletes the contents of the element passed to test functions. + element.innerHTML= ""; + return element; + }; + + has.normalize = function(id, toAbsMid){ + // summary: + // Resolves id into a module id based on possibly-nested tenary expression that branches on has feature test value(s). + // + // toAbsMid: Function + // Resolves a relative module id into an absolute module id + var + tokens = id.match(/[\?:]|[^:\?]*/g), i = 0, + get = function(skip){ + var term = tokens[i++]; + if(term == ":"){ + // empty string module name, resolves to 0 + return 0; + }else{ + // postfixed with a ? means it is a feature to branch on, the term is the name of the feature + if(tokens[i++] == "?"){ + if(!skip && has(term)){ + // matched the feature, get the first value from the options + return get(); + }else{ + // did not match, get the second value, passing over the first + get(true); + return get(skip); + } + } + // a module + return term || 0; + } + }; + id = get(); + return id && toAbsMid(id); + }; + + has.load = function(id, parentRequire, loaded){ + // summary: + // Conditional loading of AMD modules based on a has feature test value. + // id: String + // Gives the resolved module id to load. + // parentRequire: Function + // The loader require function with respect to the module that contained the plugin resource in it's + // dependency list. + // loaded: Function + // Callback to loader that consumes result of plugin demand. + + if(id){ + parentRequire([id], loaded); + }else{ + loaded(); + } + }; + + return has; +}); + +}, +'dojo/_base/loader':function(){ +define(["./kernel", "../has", "require", "module", "./json", "./lang", "./array"], function(dojo, has, require, thisModule, json, lang, array) { + // module: + // dojo/_base/loader + + // This module defines the v1.x synchronous loader API. + + // signal the loader in sync mode... + //>>pure-amd + + if (! 1 ){ + console.error("cannot load the Dojo v1.x loader with a foreign loader"); + return 0; + } + + 1 || has.add("dojo-fast-sync-require", 1); + + + var makeErrorToken = function(id){ + return {src:thisModule.id, id:id}; + }, + + slashName = function(name){ + return name.replace(/\./g, "/"); + }, + + buildDetectRe = /\/\/>>built/, + + dojoRequireCallbacks = [], + dojoRequireModuleStack = [], + + dojoRequirePlugin = function(mid, require, loaded){ + dojoRequireCallbacks.push(loaded); + array.forEach(mid.split(","), function(mid){ + var module = getModule(mid, require.module); + dojoRequireModuleStack.push(module); + injectModule(module); + }); + checkDojoRequirePlugin(); + }, + + checkDojoRequirePlugin = ( 1 ? + // This version of checkDojoRequirePlugin makes the observation that all dojoRequireCallbacks can be released + // when all *non-dojo/require!, dojo/loadInit!* modules are either executed, not requested, or arrived. This is + // the case since there are no more modules the loader is waiting for, therefore, dojo/require! must have + // everything it needs on board. + // + // The potential weakness of this algorithm is that dojo/require will not execute callbacks until *all* dependency + // trees are ready. It is possible that some trees may be ready earlier than others, and this extra wait is non-optimal. + // Still, for big projects, this seems better than the original algorithm below that proved slow in some cases. + // Note, however, the original algorithm had the potential to execute partial trees, but that potential was never enabled. + // There are also other optimization available with the original algorithm that have not been explored. + function(){ + var module, mid; + for(mid in modules){ + module = modules[mid]; + if(module.noReqPluginCheck===undefined){ + // tag the module as either a loadInit or require plugin or not for future reference + module.noReqPluginCheck = /loadInit\!/.test(mid) || /require\!/.test(mid) ? 1 : 0; + } + if(!module.executed && !module.noReqPluginCheck && module.injected==requested){ + return; + } + } + + guardCheckComplete(function(){ + var oldCallbacks = dojoRequireCallbacks; + dojoRequireCallbacks = []; + array.forEach(oldCallbacks, function(cb){cb(1);}); + }); + } : (function(){ + // Note: this is the original checkDojoRequirePlugin that is much slower than the algorithm above. However, we know it + // works, so we leave it here in case the algorithm above fails in some corner case. + // + // checkDojoRequirePlugin inspects all of the modules demanded by a dojo/require! dependency + // to see if they have arrived. The loader does not release *any* of these modules to be instantiated + // until *all* of these modules are on board, thereby preventing the evaluation of a module with dojo.require's + // that reference modules that are not available. + // + // The algorithm works by traversing the dependency graphs (remember, there can be cycles so they are not trees) + // of each module in the dojoRequireModuleStack array (which contains the list of modules demanded by dojo/require!). + // The moment a single module is discovered that is missing, the algorithm gives up and indicates that not all + // modules are on board. dojo/loadInit! and dojo/require! are ignored because there dependencies are inserted + // directly in dojoRequireModuleStack. For example, if "your/module" module depends on "dojo/require!my/module", then + // *both* "dojo/require!my/module" and "my/module" will be in dojoRequireModuleStack. Obviously, if "my/module" + // is on board, then "dojo/require!my/module" is also satisfied, so the algorithm doesn't check for "dojo/require!my/module". + // + // Note: inserting a dojo/require! dependency in the dojoRequireModuleStack achieves nothing + // with the current algorithm; however, having such modules present makes it possible to optimize the algorithm + // + // Note: prior versions of this algorithm had an optimization that signaled loaded on dojo/require! dependencies + // individually (rather than waiting for them all to be resolved). The implementation proved problematic with cycles + // and plugins. However, it is possible to reattach that strategy in the future. + + // a set from module-id to {undefined | 1 | 0}, where... + // undefined => the module has not been inspected + // 0 => the module or at least one of its dependencies has not arrived + // 1 => the module is a loadInit! or require! plugin resource, or is currently being traversed (therefore, assume + // OK until proven otherwise), or has been completely traversed and all dependencies have arrived + + var touched, + traverse = function(m){ + touched[m.mid] = 1; + for(var t, module, deps = m.deps || [], i= 0; i a built module, always AMD + // extractResult==0 => no sync API + return 0; + } + + // manufacture a synthetic module id that can never be a real mdule id (just like require does) + id = module.mid + "-*loadInit"; + + // construct the dojo/loadInit names vector which causes any relocated names to be defined as lexical variables under their not-relocated name + // the dojo/loadInit plugin assumes the first name in names is "dojo" + + for(var p in getModule("dojo", module).result.scopeMap){ + names.push(p); + namesAsStrings.push('"' + p + '"'); + } + + // rewrite the module as a synthetic dojo/loadInit plugin resource + the module expressed as an AMD module that depends on this synthetic resource + // don't have to map dojo/init since that will occur when the dependency is resolved + return "// xdomain rewrite of " + module.mid + "\n" + + "define('" + id + "',{\n" + + "\tnames:" + dojo.toJson(names) + ",\n" + + "\tdef:function(" + names.join(",") + "){" + extractResult[1] + "}" + + "});\n\n" + + "define(" + dojo.toJson(names.concat(["dojo/loadInit!"+id])) + ", function(" + names.join(",") + "){\n" + extractResult[0] + "});"; + }, + + loaderVars = require.initSyncLoader(dojoRequirePlugin, checkDojoRequirePlugin, transformToAmd), + + sync = + loaderVars.sync, + + requested = + loaderVars.requested, + + arrived = + loaderVars.arrived, + + nonmodule = + loaderVars.nonmodule, + + executing = + loaderVars.executing, + + executed = + loaderVars.executed, + + syncExecStack = + loaderVars.syncExecStack, + + modules = + loaderVars.modules, + + execQ = + loaderVars.execQ, + + getModule = + loaderVars.getModule, + + injectModule = + loaderVars.injectModule, + + setArrived = + loaderVars.setArrived, + + signal = + loaderVars.signal, + + finishExec = + loaderVars.finishExec, + + execModule = + loaderVars.execModule, + + getLegacyMode = + loaderVars.getLegacyMode, + + guardCheckComplete = + loaderVars.guardCheckComplete; + + // there is exactly one dojoRequirePlugin among possibly-many dojo/_base/loader's (owing to mapping) + dojoRequirePlugin = loaderVars.dojoRequirePlugin; + + dojo.provide = function(mid){ + var executingModule = syncExecStack[0], + module = lang.mixin(getModule(slashName(mid), require.module), { + executed:executing, + result:lang.getObject(mid, true) + }); + setArrived(module); + if(executingModule){ + (executingModule.provides || (executingModule.provides = [])).push(function(){ + module.result = lang.getObject(mid); + delete module.provides; + module.executed!==executed && finishExec(module); + }); + }// else dojo.provide called not consequent to loading; therefore, give up trying to publish module value to loader namespace + return module.result; + }; + + has.add("config-publishRequireResult", 1, 0, 0); + + dojo.require = function(moduleName, omitModuleCheck) { + // summary: + // loads a Javascript module from the appropriate URI + // + // moduleName: String + // module name to load, using periods for separators, + // e.g. "dojo.date.locale". Module paths are de-referenced by dojo's + // internal mapping of locations to names and are disambiguated by + // longest prefix. See `dojo.registerModulePath()` for details on + // registering new modules. + // + // omitModuleCheck: Boolean? + // if `true`, omitModuleCheck skips the step of ensuring that the + // loaded file actually defines the symbol it is referenced by. + // For example if it called as `dojo.require("a.b.c")` and the + // file located at `a/b/c.js` does not define an object `a.b.c`, + // and exception will be throws whereas no exception is raised + // when called as `dojo.require("a.b.c", true)` + // + // description: + // Modules are loaded via dojo.require by using one of two loaders: the normal loader + // and the xdomain loader. The xdomain loader is used when dojo was built with a + // custom build that specified loader=xdomain and the module lives on a modulePath + // that is a whole URL, with protocol and a domain. The versions of Dojo that are on + // the Google and AOL CDNs use the xdomain loader. + // + // If the module is loaded via the xdomain loader, it is an asynchronous load, since + // the module is added via a dynamically created script tag. This + // means that dojo.require() can return before the module has loaded. However, this + // should only happen in the case where you do dojo.require calls in the top-level + // HTML page, or if you purposely avoid the loader checking for dojo.require + // dependencies in your module by using a syntax like dojo["require"] to load the module. + // + // Sometimes it is useful to not have the loader detect the dojo.require calls in the + // module so that you can dynamically load the modules as a result of an action on the + // page, instead of right at module load time. + // + // Also, for script blocks in an HTML page, the loader does not pre-process them, so + // it does not know to download the modules before the dojo.require calls occur. + // + // So, in those two cases, when you want on-the-fly module loading or for script blocks + // in the HTML page, special care must be taken if the dojo.required code is loaded + // asynchronously. To make sure you can execute code that depends on the dojo.required + // modules, be sure to add the code that depends on the modules in a dojo.addOnLoad() + // callback. dojo.addOnLoad waits for all outstanding modules to finish loading before + // executing. + // + // This type of syntax works with both xdomain and normal loaders, so it is good + // practice to always use this idiom for on-the-fly code loading and in HTML script + // blocks. If at some point you change loaders and where the code is loaded from, + // it will all still work. + // + // More on how dojo.require + // `dojo.require("A.B")` first checks to see if symbol A.B is + // defined. If it is, it is simply returned (nothing to do). + // + // If it is not defined, it will look for `A/B.js` in the script root + // directory. + // + // `dojo.require` throws an exception if it cannot find a file + // to load, or if the symbol `A.B` is not defined after loading. + // + // It returns the object `A.B`, but note the caveats above about on-the-fly loading and + // HTML script blocks when the xdomain loader is loading a module. + // + // `dojo.require()` does nothing about importing symbols into + // the current namespace. It is presumed that the caller will + // take care of that. + // + // example: + // To use dojo.require in conjunction with dojo.ready: + // + // | dojo.require("foo"); + // | dojo.require("bar"); + // | dojo.addOnLoad(function(){ + // | //you can now safely do something with foo and bar + // | }); + // + // example: + // For example, to import all symbols into a local block, you might write: + // + // | with (dojo.require("A.B")) { + // | ... + // | } + // + // And to import just the leaf symbol to a local variable: + // + // | var B = dojo.require("A.B"); + // | ... + // + // returns: + // the required namespace object + function doRequire(mid, omitModuleCheck){ + var module = getModule(slashName(mid), require.module); + if(syncExecStack.length && syncExecStack[0].finish){ + // switched to async loading in the middle of evaluating a legacy module; stop + // applying dojo.require so the remaining dojo.requires are applied in order + syncExecStack[0].finish.push(mid); + return undefined; + } + + // recall module.executed has values {0, executing, executed}; therefore, truthy indicates executing or executed + if(module.executed){ + return module.result; + } + omitModuleCheck && (module.result = nonmodule); + + // rcg...why here and in two lines?? + var currentMode = getLegacyMode(); + + // recall, in sync mode to inject is to *eval* the module text + // if the module is a legacy module, this is the same as executing + // but if the module is an AMD module, this means defining, not executing + injectModule(module); + // the inject may have changed the mode + currentMode = getLegacyMode(); + + // in sync mode to dojo.require is to execute + if(module.executed!==executed && module.injected===arrived){ + // the module was already here before injectModule was called probably finishing up a xdomain + // load, but maybe a module given to the loader directly rather than having the loader retrieve it + + loaderVars.guardCheckComplete(function(){ + execModule(module); + }); + } + if(module.executed){ + return module.result; + } + + if(currentMode==sync){ + // the only way to get here is in sync mode and dojo.required a module that + // * was loaded async in the injectModule application a few lines up + // * was an AMD module that had deps that are being loaded async and therefore couldn't execute + if(module.cjs){ + // the module was an AMD module; unshift, not push, which causes the current traversal to be reattempted from the top + execQ.unshift(module); + }else{ + // the module was a legacy module + syncExecStack.length && (syncExecStack[0].finish= [mid]); + } + }else{ + // the loader wasn't in sync mode on entry; probably async mode; therefore, no expectation of getting + // the module value synchronously; make sure it gets executed though + execQ.push(module); + } + + return undefined; + } + + var result = doRequire(moduleName, omitModuleCheck); + if(has("config-publishRequireResult") && !lang.exists(moduleName) && result!==undefined){ + lang.setObject(moduleName, result); + } + return result; + }; + + dojo.loadInit = function(f) { + f(); + }; + + dojo.registerModulePath = function(/*String*/moduleName, /*String*/prefix){ + // summary: + // Maps a module name to a path + // description: + // An unregistered module is given the default path of ../[module], + // relative to Dojo root. For example, module acme is mapped to + // ../acme. If you want to use a different module name, use + // dojo.registerModulePath. + // example: + // If your dojo.js is located at this location in the web root: + // | /myapp/js/dojo/dojo/dojo.js + // and your modules are located at: + // | /myapp/js/foo/bar.js + // | /myapp/js/foo/baz.js + // | /myapp/js/foo/thud/xyzzy.js + // Your application can tell Dojo to locate the "foo" namespace by calling: + // | dojo.registerModulePath("foo", "../../foo"); + // At which point you can then use dojo.require() to load the + // modules (assuming they provide() the same things which are + // required). The full code might be: + // | + // | + + var paths = {}; + paths[moduleName.replace(/\./g, "/")] = prefix; + require({paths:paths}); + }; + + dojo.platformRequire = function(/*Object*/modMap){ + // summary: + // require one or more modules based on which host environment + // Dojo is currently operating in + // description: + // This method takes a "map" of arrays which one can use to + // optionally load dojo modules. The map is indexed by the + // possible dojo.name_ values, with two additional values: + // "default" and "common". The items in the "default" array will + // be loaded if none of the other items have been choosen based on + // dojo.name_, set by your host environment. The items in the + // "common" array will *always* be loaded, regardless of which + // list is chosen. + // example: + // | dojo.platformRequire({ + // | browser: [ + // | "foo.sample", // simple module + // | "foo.test", + // | ["foo.bar.baz", true] // skip object check in _loadModule (dojo.require) + // | ], + // | default: [ "foo.sample._base" ], + // | common: [ "important.module.common" ] + // | }); + + var result = (modMap.common || []).concat(modMap[dojo._name] || modMap["default"] || []), + temp; + while(result.length){ + if(lang.isArray(temp = result.shift())){ + dojo.require.apply(dojo, temp); + }else{ + dojo.require(temp); + } + } + }; + + dojo.requireIf = dojo.requireAfterIf = function(/*Boolean*/ condition, /*String*/ moduleName, /*Boolean?*/omitModuleCheck){ + // summary: + // If the condition is true then call `dojo.require()` for the specified + // resource + // + // example: + // | dojo.requireIf(dojo.isBrowser, "my.special.Module"); + + if(condition){ + dojo.require(moduleName, omitModuleCheck); + } + }; + + dojo.requireLocalization = function(/*String*/moduleName, /*String*/bundleName, /*String?*/locale){ + require(["../i18n"], function(i18n){ + i18n.getLocalization(moduleName, bundleName, locale); + }); + }; + + return { + // summary: + // This module defines the v1.x synchronous loader API. + + extractLegacyApiApplications:extractLegacyApiApplications, + require:dojoRequirePlugin, + loadInit:dojoLoadInitPlugin + }; +}); + +}, +'dojo/json':function(){ +define(["./has"], function(has){ + "use strict"; + var hasJSON = typeof JSON != "undefined"; + has.add("json-parse", hasJSON); // all the parsers work fine + // Firefox 3.5/Gecko 1.9 fails to use replacer in stringify properly https://bugzilla.mozilla.org/show_bug.cgi?id=509184 + has.add("json-stringify", hasJSON && JSON.stringify({a:0}, function(k,v){return v||1;}) == '{"a":1}'); + + /*===== + return { + // summary: + // Functions to parse and serialize JSON + + parse: function(str, strict){ + // summary: + // Parses a [JSON](http://json.org) string to return a JavaScript object. + // description: + // This function follows [native JSON API](https://developer.mozilla.org/en/JSON) + // Throws for invalid JSON strings. This delegates to eval() if native JSON + // support is not available. By default this will evaluate any valid JS expression. + // With the strict parameter set to true, the parser will ensure that only + // valid JSON strings are parsed (otherwise throwing an error). Without the strict + // parameter, the content passed to this method must come + // from a trusted source. + // str: + // a string literal of a JSON item, for instance: + // `'{ "foo": [ "bar", 1, { "baz": "thud" } ] }'` + // strict: + // When set to true, this will ensure that only valid, secure JSON is ever parsed. + // Make sure this is set to true for untrusted content. Note that on browsers/engines + // without native JSON support, setting this to true will run slower. + }, + stringify: function(value, replacer, spacer){ + // summary: + // Returns a [JSON](http://json.org) serialization of an object. + // description: + // Returns a [JSON](http://json.org) serialization of an object. + // This function follows [native JSON API](https://developer.mozilla.org/en/JSON) + // Note that this doesn't check for infinite recursion, so don't do that! + // value: + // A value to be serialized. + // replacer: + // A replacer function that is called for each value and can return a replacement + // spacer: + // A spacer string to be used for pretty printing of JSON + // example: + // simple serialization of a trivial object + // | define(["dojo/json"], function(JSON){ + // | var jsonStr = JSON.stringify({ howdy: "stranger!", isStrange: true }); + // | doh.is('{"howdy":"stranger!","isStrange":true}', jsonStr); + } + }; + =====*/ + + if(has("json-stringify")){ + return JSON; + }else{ + var escapeString = function(/*String*/str){ + // summary: + // Adds escape sequences for non-visual characters, double quote and + // backslash and surrounds with double quotes to form a valid string + // literal. + return ('"' + str.replace(/(["\\])/g, '\\$1') + '"'). + replace(/[\f]/g, "\\f").replace(/[\b]/g, "\\b").replace(/[\n]/g, "\\n"). + replace(/[\t]/g, "\\t").replace(/[\r]/g, "\\r"); // string + }; + return { + parse: has("json-parse") ? JSON.parse : function(str, strict){ + if(strict && !/^([\s\[\{]*(?:"(?:\\.|[^"])+"|-?\d[\d\.]*(?:[Ee][+-]?\d+)?|null|true|false|)[\s\]\}]*(?:,|:|$))+$/.test(str)){ + throw new SyntaxError("Invalid characters in JSON"); + } + return eval('(' + str + ')'); + }, + stringify: function(value, replacer, spacer){ + var undef; + if(typeof replacer == "string"){ + spacer = replacer; + replacer = null; + } + function stringify(it, indent, key){ + if(replacer){ + it = replacer(key, it); + } + var val, objtype = typeof it; + if(objtype == "number"){ + return isFinite(it) ? it + "" : "null"; + } + if(objtype == "boolean"){ + return it + ""; + } + if(it === null){ + return "null"; + } + if(typeof it == "string"){ + return escapeString(it); + } + if(objtype == "function" || objtype == "undefined"){ + return undef; // undefined + } + // short-circuit for objects that support "json" serialization + // if they return "self" then just pass-through... + if(typeof it.toJSON == "function"){ + return stringify(it.toJSON(key), indent, key); + } + if(it instanceof Date){ + return '"{FullYear}-{Month+}-{Date}T{Hours}:{Minutes}:{Seconds}Z"'.replace(/\{(\w+)(\+)?\}/g, function(t, prop, plus){ + var num = it["getUTC" + prop]() + (plus ? 1 : 0); + return num < 10 ? "0" + num : num; + }); + } + if(it.valueOf() !== it){ + // primitive wrapper, try again unwrapped: + return stringify(it.valueOf(), indent, key); + } + var nextIndent= spacer ? (indent + spacer) : ""; + /* we used to test for DOM nodes and throw, but FF serializes them as {}, so cross-browser consistency is probably not efficiently attainable */ + + var sep = spacer ? " " : ""; + var newLine = spacer ? "\n" : ""; + + // array + if(it instanceof Array){ + var itl = it.length, res = []; + for(key = 0; key < itl; key++){ + var obj = it[key]; + val = stringify(obj, nextIndent, key); + if(typeof val != "string"){ + val = "null"; + } + res.push(newLine + nextIndent + val); + } + return "[" + res.join(",") + newLine + indent + "]"; + } + // generic object code path + var output = []; + for(key in it){ + var keyStr; + if(it.hasOwnProperty(key)){ + if(typeof key == "number"){ + keyStr = '"' + key + '"'; + }else if(typeof key == "string"){ + keyStr = escapeString(key); + }else{ + // skip non-string or number keys + continue; + } + val = stringify(it[key], nextIndent, key); + if(typeof val != "string"){ + // skip non-serializable values + continue; + } + // At this point, the most non-IE browsers don't get in this branch + // (they have native JSON), so push is definitely the way to + output.push(newLine + nextIndent + keyStr + ":" + sep + val); + } + } + return "{" + output.join(",") + newLine + indent + "}"; // String + } + return stringify(value, "", ""); + } + }; + } +}); + +}, +'dojo/_base/declare':function(){ +define(["./kernel", "../has", "./lang"], function(dojo, has, lang){ + // module: + // dojo/_base/declare + + var mix = lang.mixin, op = Object.prototype, opts = op.toString, + xtor = new Function, counter = 0, cname = "constructor"; + + function err(msg, cls){ throw new Error("declare" + (cls ? " " + cls : "") + ": " + msg); } + + // C3 Method Resolution Order (see http://www.python.org/download/releases/2.3/mro/) + function c3mro(bases, className){ + var result = [], roots = [{cls: 0, refs: []}], nameMap = {}, clsCount = 1, + l = bases.length, i = 0, j, lin, base, top, proto, rec, name, refs; + + // build a list of bases naming them if needed + for(; i < l; ++i){ + base = bases[i]; + if(!base){ + err("mixin #" + i + " is unknown. Did you use dojo.require to pull it in?", className); + }else if(opts.call(base) != "[object Function]"){ + err("mixin #" + i + " is not a callable constructor.", className); + } + lin = base._meta ? base._meta.bases : [base]; + top = 0; + // add bases to the name map + for(j = lin.length - 1; j >= 0; --j){ + proto = lin[j].prototype; + if(!proto.hasOwnProperty("declaredClass")){ + proto.declaredClass = "uniqName_" + (counter++); + } + name = proto.declaredClass; + if(!nameMap.hasOwnProperty(name)){ + nameMap[name] = {count: 0, refs: [], cls: lin[j]}; + ++clsCount; + } + rec = nameMap[name]; + if(top && top !== rec){ + rec.refs.push(top); + ++top.count; + } + top = rec; + } + ++top.count; + roots[0].refs.push(top); + } + + // remove classes without external references recursively + while(roots.length){ + top = roots.pop(); + result.push(top.cls); + --clsCount; + // optimization: follow a single-linked chain + while(refs = top.refs, refs.length == 1){ + top = refs[0]; + if(!top || --top.count){ + // branch or end of chain => do not end to roots + top = 0; + break; + } + result.push(top.cls); + --clsCount; + } + if(top){ + // branch + for(i = 0, l = refs.length; i < l; ++i){ + top = refs[i]; + if(!--top.count){ + roots.push(top); + } + } + } + } + if(clsCount){ + err("can't build consistent linearization", className); + } + + // calculate the superclass offset + base = bases[0]; + result[0] = base ? + base._meta && base === result[result.length - base._meta.bases.length] ? + base._meta.bases.length : 1 : 0; + + return result; + } + + function inherited(args, a, f){ + var name, chains, bases, caller, meta, base, proto, opf, pos, + cache = this._inherited = this._inherited || {}; + + // crack arguments + if(typeof args == "string"){ + name = args; + args = a; + a = f; + } + f = 0; + + caller = args.callee; + name = name || caller.nom; + if(!name){ + err("can't deduce a name to call inherited()", this.declaredClass); + } + + meta = this.constructor._meta; + bases = meta.bases; + + pos = cache.p; + if(name != cname){ + // method + if(cache.c !== caller){ + // cache bust + pos = 0; + base = bases[0]; + meta = base._meta; + if(meta.hidden[name] !== caller){ + // error detection + chains = meta.chains; + if(chains && typeof chains[name] == "string"){ + err("calling chained method with inherited: " + name, this.declaredClass); + } + // find caller + do{ + meta = base._meta; + proto = base.prototype; + if(meta && (proto[name] === caller && proto.hasOwnProperty(name) || meta.hidden[name] === caller)){ + break; + } + }while(base = bases[++pos]); // intentional assignment + pos = base ? pos : -1; + } + } + // find next + base = bases[++pos]; + if(base){ + proto = base.prototype; + if(base._meta && proto.hasOwnProperty(name)){ + f = proto[name]; + }else{ + opf = op[name]; + do{ + proto = base.prototype; + f = proto[name]; + if(f && (base._meta ? proto.hasOwnProperty(name) : f !== opf)){ + break; + } + }while(base = bases[++pos]); // intentional assignment + } + } + f = base && f || op[name]; + }else{ + // constructor + if(cache.c !== caller){ + // cache bust + pos = 0; + meta = bases[0]._meta; + if(meta && meta.ctor !== caller){ + // error detection + chains = meta.chains; + if(!chains || chains.constructor !== "manual"){ + err("calling chained constructor with inherited", this.declaredClass); + } + // find caller + while(base = bases[++pos]){ // intentional assignment + meta = base._meta; + if(meta && meta.ctor === caller){ + break; + } + } + pos = base ? pos : -1; + } + } + // find next + while(base = bases[++pos]){ // intentional assignment + meta = base._meta; + f = meta ? meta.ctor : base; + if(f){ + break; + } + } + f = base && f; + } + + // cache the found super method + cache.c = f; + cache.p = pos; + + // now we have the result + if(f){ + return a === true ? f : f.apply(this, a || args); + } + // intentionally no return if a super method was not found + } + + function getInherited(name, args){ + if(typeof name == "string"){ + return this.__inherited(name, args, true); + } + return this.__inherited(name, true); + } + + function inherited__debug(args, a1, a2){ + var f = this.getInherited(args, a1); + if(f){ return f.apply(this, a2 || a1 || args); } + // intentionally no return if a super method was not found + } + + var inheritedImpl = dojo.config.isDebug ? inherited__debug : inherited; + + // emulation of "instanceof" + function isInstanceOf(cls){ + var bases = this.constructor._meta.bases; + for(var i = 0, l = bases.length; i < l; ++i){ + if(bases[i] === cls){ + return true; + } + } + return this instanceof cls; + } + + function mixOwn(target, source){ + // add props adding metadata for incoming functions skipping a constructor + for(var name in source){ + if(name != cname && source.hasOwnProperty(name)){ + target[name] = source[name]; + } + } + if(has("bug-for-in-skips-shadowed")){ + for(var extraNames= lang._extraNames, i= extraNames.length; i;){ + name = extraNames[--i]; + if(name != cname && source.hasOwnProperty(name)){ + target[name] = source[name]; + } + } + } + } + + // implementation of safe mixin function + function safeMixin(target, source){ + // summary: + // Mix in properties skipping a constructor and decorating functions + // like it is done by declare(). + // target: Object + // Target object to accept new properties. + // source: Object + // Source object for new properties. + // description: + // This function is used to mix in properties like lang.mixin does, + // but it skips a constructor property and decorates functions like + // declare() does. + // + // It is meant to be used with classes and objects produced with + // declare. Functions mixed in with dojo.safeMixin can use + // this.inherited() like normal methods. + // + // This function is used to implement extend() method of a constructor + // produced with declare(). + // + // example: + // | var A = declare(null, { + // | m1: function(){ + // | console.log("A.m1"); + // | }, + // | m2: function(){ + // | console.log("A.m2"); + // | } + // | }); + // | var B = declare(A, { + // | m1: function(){ + // | this.inherited(arguments); + // | console.log("B.m1"); + // | } + // | }); + // | B.extend({ + // | m2: function(){ + // | this.inherited(arguments); + // | console.log("B.m2"); + // | } + // | }); + // | var x = new B(); + // | dojo.safeMixin(x, { + // | m1: function(){ + // | this.inherited(arguments); + // | console.log("X.m1"); + // | }, + // | m2: function(){ + // | this.inherited(arguments); + // | console.log("X.m2"); + // | } + // | }); + // | x.m2(); + // | // prints: + // | // A.m1 + // | // B.m1 + // | // X.m1 + + var name, t; + // add props adding metadata for incoming functions skipping a constructor + for(name in source){ + t = source[name]; + if((t !== op[name] || !(name in op)) && name != cname){ + if(opts.call(t) == "[object Function]"){ + // non-trivial function method => attach its name + t.nom = name; + } + target[name] = t; + } + } + if(has("bug-for-in-skips-shadowed")){ + for(var extraNames= lang._extraNames, i= extraNames.length; i;){ + name = extraNames[--i]; + t = source[name]; + if((t !== op[name] || !(name in op)) && name != cname){ + if(opts.call(t) == "[object Function]"){ + // non-trivial function method => attach its name + t.nom = name; + } + target[name] = t; + } + } + } + return target; + } + + function extend(source){ + declare.safeMixin(this.prototype, source); + return this; + } + + function createSubclass(mixins){ + return declare([this].concat(mixins)); + } + + // chained constructor compatible with the legacy declare() + function chainedConstructor(bases, ctorSpecial){ + return function(){ + var a = arguments, args = a, a0 = a[0], f, i, m, + l = bases.length, preArgs; + + if(!(this instanceof a.callee)){ + // not called via new, so force it + return applyNew(a); + } + + //this._inherited = {}; + // perform the shaman's rituals of the original declare() + // 1) call two types of the preamble + if(ctorSpecial && (a0 && a0.preamble || this.preamble)){ + // full blown ritual + preArgs = new Array(bases.length); + // prepare parameters + preArgs[0] = a; + for(i = 0;;){ + // process the preamble of the 1st argument + a0 = a[0]; + if(a0){ + f = a0.preamble; + if(f){ + a = f.apply(this, a) || a; + } + } + // process the preamble of this class + f = bases[i].prototype; + f = f.hasOwnProperty("preamble") && f.preamble; + if(f){ + a = f.apply(this, a) || a; + } + // one peculiarity of the preamble: + // it is called if it is not needed, + // e.g., there is no constructor to call + // let's watch for the last constructor + // (see ticket #9795) + if(++i == l){ + break; + } + preArgs[i] = a; + } + } + // 2) call all non-trivial constructors using prepared arguments + for(i = l - 1; i >= 0; --i){ + f = bases[i]; + m = f._meta; + f = m ? m.ctor : f; + if(f){ + f.apply(this, preArgs ? preArgs[i] : a); + } + } + // 3) continue the original ritual: call the postscript + f = this.postscript; + if(f){ + f.apply(this, args); + } + }; + } + + + // chained constructor compatible with the legacy declare() + function singleConstructor(ctor, ctorSpecial){ + return function(){ + var a = arguments, t = a, a0 = a[0], f; + + if(!(this instanceof a.callee)){ + // not called via new, so force it + return applyNew(a); + } + + //this._inherited = {}; + // perform the shaman's rituals of the original declare() + // 1) call two types of the preamble + if(ctorSpecial){ + // full blown ritual + if(a0){ + // process the preamble of the 1st argument + f = a0.preamble; + if(f){ + t = f.apply(this, t) || t; + } + } + f = this.preamble; + if(f){ + // process the preamble of this class + f.apply(this, t); + // one peculiarity of the preamble: + // it is called even if it is not needed, + // e.g., there is no constructor to call + // let's watch for the last constructor + // (see ticket #9795) + } + } + // 2) call a constructor + if(ctor){ + ctor.apply(this, a); + } + // 3) continue the original ritual: call the postscript + f = this.postscript; + if(f){ + f.apply(this, a); + } + }; + } + + // plain vanilla constructor (can use inherited() to call its base constructor) + function simpleConstructor(bases){ + return function(){ + var a = arguments, i = 0, f, m; + + if(!(this instanceof a.callee)){ + // not called via new, so force it + return applyNew(a); + } + + //this._inherited = {}; + // perform the shaman's rituals of the original declare() + // 1) do not call the preamble + // 2) call the top constructor (it can use this.inherited()) + for(; f = bases[i]; ++i){ // intentional assignment + m = f._meta; + f = m ? m.ctor : f; + if(f){ + f.apply(this, a); + break; + } + } + // 3) call the postscript + f = this.postscript; + if(f){ + f.apply(this, a); + } + }; + } + + function chain(name, bases, reversed){ + return function(){ + var b, m, f, i = 0, step = 1; + if(reversed){ + i = bases.length - 1; + step = -1; + } + for(; b = bases[i]; i += step){ // intentional assignment + m = b._meta; + f = (m ? m.hidden : b.prototype)[name]; + if(f){ + f.apply(this, arguments); + } + } + }; + } + + // forceNew(ctor) + // return a new object that inherits from ctor.prototype but + // without actually running ctor on the object. + function forceNew(ctor){ + // create object with correct prototype using a do-nothing + // constructor + xtor.prototype = ctor.prototype; + var t = new xtor; + xtor.prototype = null; // clean up + return t; + } + + // applyNew(args) + // just like 'new ctor()' except that the constructor and its arguments come + // from args, which must be an array or an arguments object + function applyNew(args){ + // create an object with ctor's prototype but without + // calling ctor on it. + var ctor = args.callee, t = forceNew(ctor); + // execute the real constructor on the new object + ctor.apply(t, args); + return t; + } + + function declare(className, superclass, props){ + // summary: + // Create a feature-rich constructor from compact notation. + // className: String? + // The optional name of the constructor (loosely, a "class") + // stored in the "declaredClass" property in the created prototype. + // It will be used as a global name for a created constructor. + // superclass: Function|Function[] + // May be null, a Function, or an Array of Functions. This argument + // specifies a list of bases (the left-most one is the most deepest + // base). + // props: Object + // An object whose properties are copied to the created prototype. + // Add an instance-initialization function by making it a property + // named "constructor". + // returns: dojo/_base/declare.__DeclareCreatedObject + // New constructor function. + // description: + // Create a constructor using a compact notation for inheritance and + // prototype extension. + // + // Mixin ancestors provide a type of multiple inheritance. + // Prototypes of mixin ancestors are copied to the new class: + // changes to mixin prototypes will not affect classes to which + // they have been mixed in. + // + // Ancestors can be compound classes created by this version of + // declare(). In complex cases all base classes are going to be + // linearized according to C3 MRO algorithm + // (see http://www.python.org/download/releases/2.3/mro/ for more + // details). + // + // "className" is cached in "declaredClass" property of the new class, + // if it was supplied. The immediate super class will be cached in + // "superclass" property of the new class. + // + // Methods in "props" will be copied and modified: "nom" property + // (the declared name of the method) will be added to all copied + // functions to help identify them for the internal machinery. Be + // very careful, while reusing methods: if you use the same + // function under different names, it can produce errors in some + // cases. + // + // It is possible to use constructors created "manually" (without + // declare()) as bases. They will be called as usual during the + // creation of an instance, their methods will be chained, and even + // called by "this.inherited()". + // + // Special property "-chains-" governs how to chain methods. It is + // a dictionary, which uses method names as keys, and hint strings + // as values. If a hint string is "after", this method will be + // called after methods of its base classes. If a hint string is + // "before", this method will be called before methods of its base + // classes. + // + // If "constructor" is not mentioned in "-chains-" property, it will + // be chained using the legacy mode: using "after" chaining, + // calling preamble() method before each constructor, if available, + // and calling postscript() after all constructors were executed. + // If the hint is "after", it is chained as a regular method, but + // postscript() will be called after the chain of constructors. + // "constructor" cannot be chained "before", but it allows + // a special hint string: "manual", which means that constructors + // are not going to be chained in any way, and programmer will call + // them manually using this.inherited(). In the latter case + // postscript() will be called after the construction. + // + // All chaining hints are "inherited" from base classes and + // potentially can be overridden. Be very careful when overriding + // hints! Make sure that all chained methods can work in a proposed + // manner of chaining. + // + // Once a method was chained, it is impossible to unchain it. The + // only exception is "constructor". You don't need to define a + // method in order to supply a chaining hint. + // + // If a method is chained, it cannot use this.inherited() because + // all other methods in the hierarchy will be called automatically. + // + // Usually constructors and initializers of any kind are chained + // using "after" and destructors of any kind are chained as + // "before". Note that chaining assumes that chained methods do not + // return any value: any returned value will be discarded. + // + // example: + // | declare("my.classes.bar", my.classes.foo, { + // | // properties to be added to the class prototype + // | someValue: 2, + // | // initialization function + // | constructor: function(){ + // | this.myComplicatedObject = new ReallyComplicatedObject(); + // | }, + // | // other functions + // | someMethod: function(){ + // | doStuff(); + // | } + // | }); + // + // example: + // | var MyBase = declare(null, { + // | // constructor, properties, and methods go here + // | // ... + // | }); + // | var MyClass1 = declare(MyBase, { + // | // constructor, properties, and methods go here + // | // ... + // | }); + // | var MyClass2 = declare(MyBase, { + // | // constructor, properties, and methods go here + // | // ... + // | }); + // | var MyDiamond = declare([MyClass1, MyClass2], { + // | // constructor, properties, and methods go here + // | // ... + // | }); + // + // example: + // | var F = function(){ console.log("raw constructor"); }; + // | F.prototype.method = function(){ + // | console.log("raw method"); + // | }; + // | var A = declare(F, { + // | constructor: function(){ + // | console.log("A.constructor"); + // | }, + // | method: function(){ + // | console.log("before calling F.method..."); + // | this.inherited(arguments); + // | console.log("...back in A"); + // | } + // | }); + // | new A().method(); + // | // will print: + // | // raw constructor + // | // A.constructor + // | // before calling F.method... + // | // raw method + // | // ...back in A + // + // example: + // | var A = declare(null, { + // | "-chains-": { + // | destroy: "before" + // | } + // | }); + // | var B = declare(A, { + // | constructor: function(){ + // | console.log("B.constructor"); + // | }, + // | destroy: function(){ + // | console.log("B.destroy"); + // | } + // | }); + // | var C = declare(B, { + // | constructor: function(){ + // | console.log("C.constructor"); + // | }, + // | destroy: function(){ + // | console.log("C.destroy"); + // | } + // | }); + // | new C().destroy(); + // | // prints: + // | // B.constructor + // | // C.constructor + // | // C.destroy + // | // B.destroy + // + // example: + // | var A = declare(null, { + // | "-chains-": { + // | constructor: "manual" + // | } + // | }); + // | var B = declare(A, { + // | constructor: function(){ + // | // ... + // | // call the base constructor with new parameters + // | this.inherited(arguments, [1, 2, 3]); + // | // ... + // | } + // | }); + // + // example: + // | var A = declare(null, { + // | "-chains-": { + // | m1: "before" + // | }, + // | m1: function(){ + // | console.log("A.m1"); + // | }, + // | m2: function(){ + // | console.log("A.m2"); + // | } + // | }); + // | var B = declare(A, { + // | "-chains-": { + // | m2: "after" + // | }, + // | m1: function(){ + // | console.log("B.m1"); + // | }, + // | m2: function(){ + // | console.log("B.m2"); + // | } + // | }); + // | var x = new B(); + // | x.m1(); + // | // prints: + // | // B.m1 + // | // A.m1 + // | x.m2(); + // | // prints: + // | // A.m2 + // | // B.m2 + + // crack parameters + if(typeof className != "string"){ + props = superclass; + superclass = className; + className = ""; + } + props = props || {}; + + var proto, i, t, ctor, name, bases, chains, mixins = 1, parents = superclass; + + // build a prototype + if(opts.call(superclass) == "[object Array]"){ + // C3 MRO + bases = c3mro(superclass, className); + t = bases[0]; + mixins = bases.length - t; + superclass = bases[mixins]; + }else{ + bases = [0]; + if(superclass){ + if(opts.call(superclass) == "[object Function]"){ + t = superclass._meta; + bases = bases.concat(t ? t.bases : superclass); + }else{ + err("base class is not a callable constructor.", className); + } + }else if(superclass !== null){ + err("unknown base class. Did you use dojo.require to pull it in?", className); + } + } + if(superclass){ + for(i = mixins - 1;; --i){ + proto = forceNew(superclass); + if(!i){ + // stop if nothing to add (the last base) + break; + } + // mix in properties + t = bases[i]; + (t._meta ? mixOwn : mix)(proto, t.prototype); + // chain in new constructor + ctor = new Function; + ctor.superclass = superclass; + ctor.prototype = proto; + superclass = proto.constructor = ctor; + } + }else{ + proto = {}; + } + // add all properties + declare.safeMixin(proto, props); + // add constructor + t = props.constructor; + if(t !== op.constructor){ + t.nom = cname; + proto.constructor = t; + } + + // collect chains and flags + for(i = mixins - 1; i; --i){ // intentional assignment + t = bases[i]._meta; + if(t && t.chains){ + chains = mix(chains || {}, t.chains); + } + } + if(proto["-chains-"]){ + chains = mix(chains || {}, proto["-chains-"]); + } + + // build ctor + t = !chains || !chains.hasOwnProperty(cname); + bases[0] = ctor = (chains && chains.constructor === "manual") ? simpleConstructor(bases) : + (bases.length == 1 ? singleConstructor(props.constructor, t) : chainedConstructor(bases, t)); + + // add meta information to the constructor + ctor._meta = {bases: bases, hidden: props, chains: chains, + parents: parents, ctor: props.constructor}; + ctor.superclass = superclass && superclass.prototype; + ctor.extend = extend; + ctor.createSubclass = createSubclass; + ctor.prototype = proto; + proto.constructor = ctor; + + // add "standard" methods to the prototype + proto.getInherited = getInherited; + proto.isInstanceOf = isInstanceOf; + proto.inherited = inheritedImpl; + proto.__inherited = inherited; + + // add name if specified + if(className){ + proto.declaredClass = className; + lang.setObject(className, ctor); + } + + // build chains and add them to the prototype + if(chains){ + for(name in chains){ + if(proto[name] && typeof chains[name] == "string" && name != cname){ + t = proto[name] = chain(name, bases, chains[name] === "after"); + t.nom = name; + } + } + } + // chained methods do not return values + // no need to chain "invisible" functions + + return ctor; // Function + } + + /*===== + declare.__DeclareCreatedObject = { + // summary: + // dojo/_base/declare() returns a constructor `C`. `new C()` returns an Object with the following + // methods, in addition to the methods and properties specified via the arguments passed to declare(). + + inherited: function(name, args, newArgs){ + // summary: + // Calls a super method. + // name: String? + // The optional method name. Should be the same as the caller's + // name. Usually "name" is specified in complex dynamic cases, when + // the calling method was dynamically added, undecorated by + // declare(), and it cannot be determined. + // args: Arguments + // The caller supply this argument, which should be the original + // "arguments". + // newArgs: Object? + // If "true", the found function will be returned without + // executing it. + // If Array, it will be used to call a super method. Otherwise + // "args" will be used. + // returns: + // Whatever is returned by a super method, or a super method itself, + // if "true" was specified as newArgs. + // description: + // This method is used inside method of classes produced with + // declare() to call a super method (next in the chain). It is + // used for manually controlled chaining. Consider using the regular + // chaining, because it is faster. Use "this.inherited()" only in + // complex cases. + // + // This method cannot me called from automatically chained + // constructors including the case of a special (legacy) + // constructor chaining. It cannot be called from chained methods. + // + // If "this.inherited()" cannot find the next-in-chain method, it + // does nothing and returns "undefined". The last method in chain + // can be a default method implemented in Object, which will be + // called last. + // + // If "name" is specified, it is assumed that the method that + // received "args" is the parent method for this call. It is looked + // up in the chain list and if it is found the next-in-chain method + // is called. If it is not found, the first-in-chain method is + // called. + // + // If "name" is not specified, it will be derived from the calling + // method (using a methoid property "nom"). + // + // example: + // | var B = declare(A, { + // | method1: function(a, b, c){ + // | this.inherited(arguments); + // | }, + // | method2: function(a, b){ + // | return this.inherited(arguments, [a + b]); + // | } + // | }); + // | // next method is not in the chain list because it is added + // | // manually after the class was created. + // | B.prototype.method3 = function(){ + // | console.log("This is a dynamically-added method."); + // | this.inherited("method3", arguments); + // | }; + // example: + // | var B = declare(A, { + // | method: function(a, b){ + // | var super = this.inherited(arguments, true); + // | // ... + // | if(!super){ + // | console.log("there is no super method"); + // | return 0; + // | } + // | return super.apply(this, arguments); + // | } + // | }); + return {}; // Object + }, + + getInherited: function(name, args){ + // summary: + // Returns a super method. + // name: String? + // The optional method name. Should be the same as the caller's + // name. Usually "name" is specified in complex dynamic cases, when + // the calling method was dynamically added, undecorated by + // declare(), and it cannot be determined. + // args: Arguments + // The caller supply this argument, which should be the original + // "arguments". + // returns: + // Returns a super method (Function) or "undefined". + // description: + // This method is a convenience method for "this.inherited()". + // It uses the same algorithm but instead of executing a super + // method, it returns it, or "undefined" if not found. + // + // example: + // | var B = declare(A, { + // | method: function(a, b){ + // | var super = this.getInherited(arguments); + // | // ... + // | if(!super){ + // | console.log("there is no super method"); + // | return 0; + // | } + // | return super.apply(this, arguments); + // | } + // | }); + return {}; // Object + }, + + isInstanceOf: function(cls){ + // summary: + // Checks the inheritance chain to see if it is inherited from this + // class. + // cls: Function + // Class constructor. + // returns: + // "true", if this object is inherited from this class, "false" + // otherwise. + // description: + // This method is used with instances of classes produced with + // declare() to determine of they support a certain interface or + // not. It models "instanceof" operator. + // + // example: + // | var A = declare(null, { + // | // constructor, properties, and methods go here + // | // ... + // | }); + // | var B = declare(null, { + // | // constructor, properties, and methods go here + // | // ... + // | }); + // | var C = declare([A, B], { + // | // constructor, properties, and methods go here + // | // ... + // | }); + // | var D = declare(A, { + // | // constructor, properties, and methods go here + // | // ... + // | }); + // | + // | var a = new A(), b = new B(), c = new C(), d = new D(); + // | + // | console.log(a.isInstanceOf(A)); // true + // | console.log(b.isInstanceOf(A)); // false + // | console.log(c.isInstanceOf(A)); // true + // | console.log(d.isInstanceOf(A)); // true + // | + // | console.log(a.isInstanceOf(B)); // false + // | console.log(b.isInstanceOf(B)); // true + // | console.log(c.isInstanceOf(B)); // true + // | console.log(d.isInstanceOf(B)); // false + // | + // | console.log(a.isInstanceOf(C)); // false + // | console.log(b.isInstanceOf(C)); // false + // | console.log(c.isInstanceOf(C)); // true + // | console.log(d.isInstanceOf(C)); // false + // | + // | console.log(a.isInstanceOf(D)); // false + // | console.log(b.isInstanceOf(D)); // false + // | console.log(c.isInstanceOf(D)); // false + // | console.log(d.isInstanceOf(D)); // true + return {}; // Object + }, + + extend: function(source){ + // summary: + // Adds all properties and methods of source to constructor's + // prototype, making them available to all instances created with + // constructor. This method is specific to constructors created with + // declare(). + // source: Object + // Source object which properties are going to be copied to the + // constructor's prototype. + // description: + // Adds source properties to the constructor's prototype. It can + // override existing properties. + // + // This method is similar to dojo.extend function, but it is specific + // to constructors produced by declare(). It is implemented + // using dojo.safeMixin, and it skips a constructor property, + // and properly decorates copied functions. + // + // example: + // | var A = declare(null, { + // | m1: function(){}, + // | s1: "Popokatepetl" + // | }); + // | A.extend({ + // | m1: function(){}, + // | m2: function(){}, + // | f1: true, + // | d1: 42 + // | }); + } + }; + =====*/ + + // For back-compat, remove for 2.0 + dojo.safeMixin = declare.safeMixin = safeMixin; + dojo.declare = declare; + + return declare; +}); + +}, +'dojo/dom':function(){ +define(["./sniff", "./_base/lang", "./_base/window"], + function(has, lang, win){ + // module: + // dojo/dom + + // FIXME: need to add unit tests for all the semi-public methods + + if(has("ie") <= 7){ + try{ + document.execCommand("BackgroundImageCache", false, true); + }catch(e){ + // sane browsers don't have cache "issues" + } + } + + // ============================= + // DOM Functions + // ============================= + + // the result object + var dom = { + // summary: + // This module defines the core dojo DOM API. + }; + + if(has("ie")){ + dom.byId = function(id, doc){ + if(typeof id != "string"){ + return id; + } + var _d = doc || win.doc, te = id && _d.getElementById(id); + // attributes.id.value is better than just id in case the + // user has a name=id inside a form + if(te && (te.attributes.id.value == id || te.id == id)){ + return te; + }else{ + var eles = _d.all[id]; + if(!eles || eles.nodeName){ + eles = [eles]; + } + // if more than 1, choose first with the correct id + var i = 0; + while((te = eles[i++])){ + if((te.attributes && te.attributes.id && te.attributes.id.value == id) || te.id == id){ + return te; + } + } + } + }; + }else{ + dom.byId = function(id, doc){ + // inline'd type check. + // be sure to return null per documentation, to match IE branch. + return ((typeof id == "string") ? (doc || win.doc).getElementById(id) : id) || null; // DOMNode + }; + } + /*===== + dom.byId = function(id, doc){ + // summary: + // Returns DOM node with matching `id` attribute or falsy value (ex: null or undefined) + // if not found. If `id` is a DomNode, this function is a no-op. + // + // id: String|DOMNode + // A string to match an HTML id attribute or a reference to a DOM Node + // + // doc: Document? + // Document to work in. Defaults to the current value of + // dojo.doc. Can be used to retrieve + // node references from other documents. + // + // example: + // Look up a node by ID: + // | var n = dojo.byId("foo"); + // + // example: + // Check if a node exists, and use it. + // | var n = dojo.byId("bar"); + // | if(n){ doStuff() ... } + // + // example: + // Allow string or DomNode references to be passed to a custom function: + // | var foo = function(nodeOrId){ + // | nodeOrId = dojo.byId(nodeOrId); + // | // ... more stuff + // | } + }; + =====*/ + + dom.isDescendant = function(/*DOMNode|String*/ node, /*DOMNode|String*/ ancestor){ + // summary: + // Returns true if node is a descendant of ancestor + // node: DOMNode|String + // string id or node reference to test + // ancestor: DOMNode|String + // string id or node reference of potential parent to test against + // + // example: + // Test is node id="bar" is a descendant of node id="foo" + // | if(dojo.isDescendant("bar", "foo")){ ... } + + try{ + node = dom.byId(node); + ancestor = dom.byId(ancestor); + while(node){ + if(node == ancestor){ + return true; // Boolean + } + node = node.parentNode; + } + }catch(e){ /* squelch, return false */ } + return false; // Boolean + }; + + + // TODO: do we need this function in the base? + + dom.setSelectable = function(/*DOMNode|String*/ node, /*Boolean*/ selectable){ + // summary: + // Enable or disable selection on a node + // node: DOMNode|String + // id or reference to node + // selectable: Boolean + // state to put the node in. false indicates unselectable, true + // allows selection. + // example: + // Make the node id="bar" unselectable + // | dojo.setSelectable("bar"); + // example: + // Make the node id="bar" selectable + // | dojo.setSelectable("bar", true); + + node = dom.byId(node); + if(has("mozilla")){ + node.style.MozUserSelect = selectable ? "" : "none"; + }else if(has("khtml") || has("webkit")){ + node.style.KhtmlUserSelect = selectable ? "auto" : "none"; + }else if(has("ie")){ + var v = (node.unselectable = selectable ? "" : "on"), + cs = node.getElementsByTagName("*"), i = 0, l = cs.length; + for(; i < l; ++i){ + cs.item(i).unselectable = v; + } + } + //FIXME: else? Opera? + }; + + return dom; +}); + +}, +'dojo/_base/browser':function(){ +if(require.has){ + require.has.add("config-selectorEngine", "acme"); +} +define([ + "../ready", + "./kernel", + "./connect", // until we decide if connect is going back into non-browser environments + "./unload", + "./window", + "./event", + "./html", + "./NodeList", + "../query", + "./xhr", + "./fx"], function(dojo){ + + // module: + // dojo/_base/browser + + /*===== + return { + // summary: + // This module causes the browser-only base modules to be loaded. + }; + =====*/ + + return dojo; +}); + +}, +'dojo/selector/acme':function(){ +define([ + "../dom", "../sniff", "../_base/array", "../_base/lang", "../_base/window" +], function(dom, has, array, lang, win){ + + // module: + // dojo/selector/acme + +/* + acme architectural overview: + + acme is a relatively full-featured CSS3 query library. It is + designed to take any valid CSS3 selector and return the nodes matching + the selector. To do this quickly, it processes queries in several + steps, applying caching where profitable. + + The steps (roughly in reverse order of the way they appear in the code): + 1.) check to see if we already have a "query dispatcher" + - if so, use that with the given parameterization. Skip to step 4. + 2.) attempt to determine which branch to dispatch the query to: + - JS (optimized DOM iteration) + - native (FF3.1+, Safari 3.1+, IE 8+) + 3.) tokenize and convert to executable "query dispatcher" + - this is where the lion's share of the complexity in the + system lies. In the DOM version, the query dispatcher is + assembled as a chain of "yes/no" test functions pertaining to + a section of a simple query statement (".blah:nth-child(odd)" + but not "div div", which is 2 simple statements). Individual + statement dispatchers are cached (to prevent re-definition) + as are entire dispatch chains (to make re-execution of the + same query fast) + 4.) the resulting query dispatcher is called in the passed scope + (by default the top-level document) + - for DOM queries, this results in a recursive, top-down + evaluation of nodes based on each simple query section + - for native implementations, this may mean working around spec + bugs. So be it. + 5.) matched nodes are pruned to ensure they are unique (if necessary) +*/ + + + //////////////////////////////////////////////////////////////////////// + // Toolkit aliases + //////////////////////////////////////////////////////////////////////// + + // if you are extracting acme for use in your own system, you will + // need to provide these methods and properties. No other porting should be + // necessary, save for configuring the system to use a class other than + // dojo/NodeList as the return instance instantiator + var trim = lang.trim; + var each = array.forEach; + + var getDoc = function(){ return win.doc; }; + // NOTE(alex): the spec is idiotic. CSS queries should ALWAYS be case-sensitive, but nooooooo + var cssCaseBug = (getDoc().compatMode) == "BackCompat"; + + //////////////////////////////////////////////////////////////////////// + // Global utilities + //////////////////////////////////////////////////////////////////////// + + + var specials = ">~+"; + + // global thunk to determine whether we should treat the current query as + // case sensitive or not. This switch is flipped by the query evaluator + // based on the document passed as the context to search. + var caseSensitive = false; + + // how high? + var yesman = function(){ return true; }; + + //////////////////////////////////////////////////////////////////////// + // Tokenizer + //////////////////////////////////////////////////////////////////////// + + var getQueryParts = function(query){ + // summary: + // state machine for query tokenization + // description: + // instead of using a brittle and slow regex-based CSS parser, + // acme implements an AST-style query representation. This + // representation is only generated once per query. For example, + // the same query run multiple times or under different root nodes + // does not re-parse the selector expression but instead uses the + // cached data structure. The state machine implemented here + // terminates on the last " " (space) character and returns an + // ordered array of query component structures (or "parts"). Each + // part represents an operator or a simple CSS filtering + // expression. The structure for parts is documented in the code + // below. + + + // NOTE: + // this code is designed to run fast and compress well. Sacrifices + // to readability and maintainability have been made. Your best + // bet when hacking the tokenizer is to put The Donnas on *really* + // loud (may we recommend their "Spend The Night" release?) and + // just assume you're gonna make mistakes. Keep the unit tests + // open and run them frequently. Knowing is half the battle ;-) + if(specials.indexOf(query.slice(-1)) >= 0){ + // if we end with a ">", "+", or "~", that means we're implicitly + // searching all children, so make it explicit + query += " * "; + }else{ + // if you have not provided a terminator, one will be provided for + // you... + query += " "; + } + + var ts = function(/*Integer*/ s, /*Integer*/ e){ + // trim and slice. + + // take an index to start a string slice from and an end position + // and return a trimmed copy of that sub-string + return trim(query.slice(s, e)); + }; + + // the overall data graph of the full query, as represented by queryPart objects + var queryParts = []; + + + // state keeping vars + var inBrackets = -1, inParens = -1, inMatchFor = -1, + inPseudo = -1, inClass = -1, inId = -1, inTag = -1, currentQuoteChar, + lc = "", cc = "", pStart; + + // iteration vars + var x = 0, // index in the query + ql = query.length, + currentPart = null, // data structure representing the entire clause + _cp = null; // the current pseudo or attr matcher + + // several temporary variables are assigned to this structure during a + // potential sub-expression match: + // attr: + // a string representing the current full attribute match in a + // bracket expression + // type: + // if there's an operator in a bracket expression, this is + // used to keep track of it + // value: + // the internals of parenthetical expression for a pseudo. for + // :nth-child(2n+1), value might be "2n+1" + + var endTag = function(){ + // called when the tokenizer hits the end of a particular tag name. + // Re-sets state variables for tag matching and sets up the matcher + // to handle the next type of token (tag or operator). + if(inTag >= 0){ + var tv = (inTag == x) ? null : ts(inTag, x); // .toLowerCase(); + currentPart[ (specials.indexOf(tv) < 0) ? "tag" : "oper" ] = tv; + inTag = -1; + } + }; + + var endId = function(){ + // called when the tokenizer might be at the end of an ID portion of a match + if(inId >= 0){ + currentPart.id = ts(inId, x).replace(/\\/g, ""); + inId = -1; + } + }; + + var endClass = function(){ + // called when the tokenizer might be at the end of a class name + // match. CSS allows for multiple classes, so we augment the + // current item with another class in its list + if(inClass >= 0){ + currentPart.classes.push(ts(inClass + 1, x).replace(/\\/g, "")); + inClass = -1; + } + }; + + var endAll = function(){ + // at the end of a simple fragment, so wall off the matches + endId(); + endTag(); + endClass(); + }; + + var endPart = function(){ + endAll(); + if(inPseudo >= 0){ + currentPart.pseudos.push({ name: ts(inPseudo + 1, x) }); + } + // hint to the selector engine to tell it whether or not it + // needs to do any iteration. Many simple selectors don't, and + // we can avoid significant construction-time work by advising + // the system to skip them + currentPart.loops = ( + currentPart.pseudos.length || + currentPart.attrs.length || + currentPart.classes.length ); + + currentPart.oquery = currentPart.query = ts(pStart, x); // save the full expression as a string + + + // otag/tag are hints to suggest to the system whether or not + // it's an operator or a tag. We save a copy of otag since the + // tag name is cast to upper-case in regular HTML matches. The + // system has a global switch to figure out if the current + // expression needs to be case sensitive or not and it will use + // otag or tag accordingly + currentPart.otag = currentPart.tag = (currentPart["oper"]) ? null : (currentPart.tag || "*"); + + if(currentPart.tag){ + // if we're in a case-insensitive HTML doc, we likely want + // the toUpperCase when matching on element.tagName. If we + // do it here, we can skip the string op per node + // comparison + currentPart.tag = currentPart.tag.toUpperCase(); + } + + // add the part to the list + if(queryParts.length && (queryParts[queryParts.length-1].oper)){ + // operators are always infix, so we remove them from the + // list and attach them to the next match. The evaluator is + // responsible for sorting out how to handle them. + currentPart.infixOper = queryParts.pop(); + currentPart.query = currentPart.infixOper.query + " " + currentPart.query; + /* + console.debug( "swapping out the infix", + currentPart.infixOper, + "and attaching it to", + currentPart); + */ + } + queryParts.push(currentPart); + + currentPart = null; + }; + + // iterate over the query, character by character, building up a + // list of query part objects + for(; lc=cc, cc=query.charAt(x), x < ql; x++){ + // cc: the current character in the match + // lc: the last character (if any) + + // someone is trying to escape something, so don't try to match any + // fragments. We assume we're inside a literal. + if(lc == "\\"){ continue; } + if(!currentPart){ // a part was just ended or none has yet been created + // NOTE: I hate all this alloc, but it's shorter than writing tons of if's + pStart = x; + // rules describe full CSS sub-expressions, like: + // #someId + // .className:first-child + // but not: + // thinger > div.howdy[type=thinger] + // the indidual components of the previous query would be + // split into 3 parts that would be represented a structure like: + // [ + // { + // query: "thinger", + // tag: "thinger", + // }, + // { + // query: "div.howdy[type=thinger]", + // classes: ["howdy"], + // infixOper: { + // query: ">", + // oper: ">", + // } + // }, + // ] + currentPart = { + query: null, // the full text of the part's rule + pseudos: [], // CSS supports multiple pseud-class matches in a single rule + attrs: [], // CSS supports multi-attribute match, so we need an array + classes: [], // class matches may be additive, e.g.: .thinger.blah.howdy + tag: null, // only one tag... + oper: null, // ...or operator per component. Note that these wind up being exclusive. + id: null, // the id component of a rule + getTag: function(){ + return caseSensitive ? this.otag : this.tag; + } + }; + + // if we don't have a part, we assume we're going to start at + // the beginning of a match, which should be a tag name. This + // might fault a little later on, but we detect that and this + // iteration will still be fine. + inTag = x; + } + + // Skip processing all quoted characters. + // If we are inside quoted text then currentQuoteChar stores the character that began the quote, + // thus that character that will end it. + if(currentQuoteChar){ + if(cc == currentQuoteChar){ + currentQuoteChar = null; + } + continue; + }else if (cc == "'" || cc == '"'){ + currentQuoteChar = cc; + continue; + } + + if(inBrackets >= 0){ + // look for a the close first + if(cc == "]"){ // if we're in a [...] clause and we end, do assignment + if(!_cp.attr){ + // no attribute match was previously begun, so we + // assume this is an attribute existence match in the + // form of [someAttributeName] + _cp.attr = ts(inBrackets+1, x); + }else{ + // we had an attribute already, so we know that we're + // matching some sort of value, as in [attrName=howdy] + _cp.matchFor = ts((inMatchFor||inBrackets+1), x); + } + var cmf = _cp.matchFor; + if(cmf){ + // try to strip quotes from the matchFor value. We want + // [attrName=howdy] to match the same + // as [attrName = 'howdy' ] + if( (cmf.charAt(0) == '"') || (cmf.charAt(0) == "'") ){ + _cp.matchFor = cmf.slice(1, -1); + } + } + // remove backslash escapes from an attribute match, since DOM + // querying will get attribute values without backslashes + if(_cp.matchFor){ + _cp.matchFor = _cp.matchFor.replace(/\\/g, ""); + } + + // end the attribute by adding it to the list of attributes. + currentPart.attrs.push(_cp); + _cp = null; // necessary? + inBrackets = inMatchFor = -1; + }else if(cc == "="){ + // if the last char was an operator prefix, make sure we + // record it along with the "=" operator. + var addToCc = ("|~^$*".indexOf(lc) >=0 ) ? lc : ""; + _cp.type = addToCc+cc; + _cp.attr = ts(inBrackets+1, x-addToCc.length); + inMatchFor = x+1; + } + // now look for other clause parts + }else if(inParens >= 0){ + // if we're in a parenthetical expression, we need to figure + // out if it's attached to a pseudo-selector rule like + // :nth-child(1) + if(cc == ")"){ + if(inPseudo >= 0){ + _cp.value = ts(inParens+1, x); + } + inPseudo = inParens = -1; + } + }else if(cc == "#"){ + // start of an ID match + endAll(); + inId = x+1; + }else if(cc == "."){ + // start of a class match + endAll(); + inClass = x; + }else if(cc == ":"){ + // start of a pseudo-selector match + endAll(); + inPseudo = x; + }else if(cc == "["){ + // start of an attribute match. + endAll(); + inBrackets = x; + // provide a new structure for the attribute match to fill-in + _cp = { + /*===== + attr: null, type: null, matchFor: null + =====*/ + }; + }else if(cc == "("){ + // we really only care if we've entered a parenthetical + // expression if we're already inside a pseudo-selector match + if(inPseudo >= 0){ + // provide a new structure for the pseudo match to fill-in + _cp = { + name: ts(inPseudo+1, x), + value: null + }; + currentPart.pseudos.push(_cp); + } + inParens = x; + }else if( + (cc == " ") && + // if it's a space char and the last char is too, consume the + // current one without doing more work + (lc != cc) + ){ + endPart(); + } + } + return queryParts; + }; + + + //////////////////////////////////////////////////////////////////////// + // DOM query infrastructure + //////////////////////////////////////////////////////////////////////// + + var agree = function(first, second){ + // the basic building block of the yes/no chaining system. agree(f1, + // f2) generates a new function which returns the boolean results of + // both of the passed functions to a single logical-anded result. If + // either are not passed, the other is used exclusively. + if(!first){ return second; } + if(!second){ return first; } + + return function(){ + return first.apply(window, arguments) && second.apply(window, arguments); + }; + }; + + var getArr = function(i, arr){ + // helps us avoid array alloc when we don't need it + var r = arr||[]; // FIXME: should this be 'new d._NodeListCtor()' ? + if(i){ r.push(i); } + return r; + }; + + var _isElement = function(n){ return (1 == n.nodeType); }; + + // FIXME: need to coalesce _getAttr with defaultGetter + var blank = ""; + var _getAttr = function(elem, attr){ + if(!elem){ return blank; } + if(attr == "class"){ + return elem.className || blank; + } + if(attr == "for"){ + return elem.htmlFor || blank; + } + if(attr == "style"){ + return elem.style.cssText || blank; + } + return (caseSensitive ? elem.getAttribute(attr) : elem.getAttribute(attr, 2)) || blank; + }; + + var attrs = { + "*=": function(attr, value){ + return function(elem){ + // E[foo*="bar"] + // an E element whose "foo" attribute value contains + // the substring "bar" + return (_getAttr(elem, attr).indexOf(value)>=0); + }; + }, + "^=": function(attr, value){ + // E[foo^="bar"] + // an E element whose "foo" attribute value begins exactly + // with the string "bar" + return function(elem){ + return (_getAttr(elem, attr).indexOf(value)==0); + }; + }, + "$=": function(attr, value){ + // E[foo$="bar"] + // an E element whose "foo" attribute value ends exactly + // with the string "bar" + return function(elem){ + var ea = " "+_getAttr(elem, attr); + var lastIndex = ea.lastIndexOf(value); + return lastIndex > -1 && (lastIndex==(ea.length-value.length)); + }; + }, + "~=": function(attr, value){ + // E[foo~="bar"] + // an E element whose "foo" attribute value is a list of + // space-separated values, one of which is exactly equal + // to "bar" + + // return "[contains(concat(' ',@"+attr+",' '), ' "+ value +" ')]"; + var tval = " "+value+" "; + return function(elem){ + var ea = " "+_getAttr(elem, attr)+" "; + return (ea.indexOf(tval)>=0); + }; + }, + "|=": function(attr, value){ + // E[hreflang|="en"] + // an E element whose "hreflang" attribute has a + // hyphen-separated list of values beginning (from the + // left) with "en" + var valueDash = value+"-"; + return function(elem){ + var ea = _getAttr(elem, attr); + return ( + (ea == value) || + (ea.indexOf(valueDash)==0) + ); + }; + }, + "=": function(attr, value){ + return function(elem){ + return (_getAttr(elem, attr) == value); + }; + } + }; + + // avoid testing for node type if we can. Defining this in the negative + // here to avoid negation in the fast path. + var _noNES = (typeof getDoc().firstChild.nextElementSibling == "undefined"); + var _ns = !_noNES ? "nextElementSibling" : "nextSibling"; + var _ps = !_noNES ? "previousElementSibling" : "previousSibling"; + var _simpleNodeTest = (_noNES ? _isElement : yesman); + + var _lookLeft = function(node){ + // look left + while(node = node[_ps]){ + if(_simpleNodeTest(node)){ return false; } + } + return true; + }; + + var _lookRight = function(node){ + // look right + while(node = node[_ns]){ + if(_simpleNodeTest(node)){ return false; } + } + return true; + }; + + var getNodeIndex = function(node){ + var root = node.parentNode; + root = root.nodeType != 7 ? root : root.nextSibling; // PROCESSING_INSTRUCTION_NODE + var i = 0, + tret = root.children || root.childNodes, + ci = (node["_i"]||node.getAttribute("_i")||-1), + cl = (root["_l"]|| (typeof root.getAttribute !== "undefined" ? root.getAttribute("_l") : -1)); + + if(!tret){ return -1; } + var l = tret.length; + + // we calculate the parent length as a cheap way to invalidate the + // cache. It's not 100% accurate, but it's much more honest than what + // other libraries do + if( cl == l && ci >= 0 && cl >= 0 ){ + // if it's legit, tag and release + return ci; + } + + // else re-key things + if(has("ie") && typeof root.setAttribute !== "undefined"){ + root.setAttribute("_l", l); + }else{ + root["_l"] = l; + } + ci = -1; + for(var te = root["firstElementChild"]||root["firstChild"]; te; te = te[_ns]){ + if(_simpleNodeTest(te)){ + if(has("ie")){ + te.setAttribute("_i", ++i); + }else{ + te["_i"] = ++i; + } + if(node === te){ + // NOTE: + // shortcutting the return at this step in indexing works + // very well for benchmarking but we avoid it here since + // it leads to potential O(n^2) behavior in sequential + // getNodexIndex operations on a previously un-indexed + // parent. We may revisit this at a later time, but for + // now we just want to get the right answer more often + // than not. + ci = i; + } + } + } + return ci; + }; + + var isEven = function(elem){ + return !((getNodeIndex(elem)) % 2); + }; + + var isOdd = function(elem){ + return ((getNodeIndex(elem)) % 2); + }; + + var pseudos = { + "checked": function(name, condition){ + return function(elem){ + return !!("checked" in elem ? elem.checked : elem.selected); + }; + }, + "disabled": function(name, condition){ + return function(elem){ + return elem.disabled; + }; + }, + "enabled": function(name, condition){ + return function(elem){ + return !elem.disabled; + }; + }, + "first-child": function(){ return _lookLeft; }, + "last-child": function(){ return _lookRight; }, + "only-child": function(name, condition){ + return function(node){ + return _lookLeft(node) && _lookRight(node); + }; + }, + "empty": function(name, condition){ + return function(elem){ + // DomQuery and jQuery get this wrong, oddly enough. + // The CSS 3 selectors spec is pretty explicit about it, too. + var cn = elem.childNodes; + var cnl = elem.childNodes.length; + // if(!cnl){ return true; } + for(var x=cnl-1; x >= 0; x--){ + var nt = cn[x].nodeType; + if((nt === 1)||(nt == 3)){ return false; } + } + return true; + }; + }, + "contains": function(name, condition){ + var cz = condition.charAt(0); + if( cz == '"' || cz == "'" ){ //remove quote + condition = condition.slice(1, -1); + } + return function(elem){ + return (elem.innerHTML.indexOf(condition) >= 0); + }; + }, + "not": function(name, condition){ + var p = getQueryParts(condition)[0]; + var ignores = { el: 1 }; + if(p.tag != "*"){ + ignores.tag = 1; + } + if(!p.classes.length){ + ignores.classes = 1; + } + var ntf = getSimpleFilterFunc(p, ignores); + return function(elem){ + return (!ntf(elem)); + }; + }, + "nth-child": function(name, condition){ + var pi = parseInt; + // avoid re-defining function objects if we can + if(condition == "odd"){ + return isOdd; + }else if(condition == "even"){ + return isEven; + } + // FIXME: can we shorten this? + if(condition.indexOf("n") != -1){ + var tparts = condition.split("n", 2); + var pred = tparts[0] ? ((tparts[0] == '-') ? -1 : pi(tparts[0])) : 1; + var idx = tparts[1] ? pi(tparts[1]) : 0; + var lb = 0, ub = -1; + if(pred > 0){ + if(idx < 0){ + idx = (idx % pred) && (pred + (idx % pred)); + }else if(idx>0){ + if(idx >= pred){ + lb = idx - idx % pred; + } + idx = idx % pred; + } + }else if(pred<0){ + pred *= -1; + // idx has to be greater than 0 when pred is negative; + // shall we throw an error here? + if(idx > 0){ + ub = idx; + idx = idx % pred; + } + } + if(pred > 0){ + return function(elem){ + var i = getNodeIndex(elem); + return (i>=lb) && (ub<0 || i<=ub) && ((i % pred) == idx); + }; + }else{ + condition = idx; + } + } + var ncount = pi(condition); + return function(elem){ + return (getNodeIndex(elem) == ncount); + }; + } + }; + + var defaultGetter = (has("ie") && (has("ie") < 9 || has("quirks"))) ? function(cond){ + var clc = cond.toLowerCase(); + if(clc == "class"){ cond = "className"; } + return function(elem){ + return (caseSensitive ? elem.getAttribute(cond) : elem[cond]||elem[clc]); + }; + } : function(cond){ + return function(elem){ + return (elem && elem.getAttribute && elem.hasAttribute(cond)); + }; + }; + + var getSimpleFilterFunc = function(query, ignores){ + // generates a node tester function based on the passed query part. The + // query part is one of the structures generated by the query parser + // when it creates the query AST. The "ignores" object specifies which + // (if any) tests to skip, allowing the system to avoid duplicating + // work where it may have already been taken into account by other + // factors such as how the nodes to test were fetched in the first + // place + if(!query){ return yesman; } + ignores = ignores||{}; + + var ff = null; + + if(!("el" in ignores)){ + ff = agree(ff, _isElement); + } + + if(!("tag" in ignores)){ + if(query.tag != "*"){ + ff = agree(ff, function(elem){ + return (elem && ((caseSensitive ? elem.tagName : elem.tagName.toUpperCase()) == query.getTag())); + }); + } + } + + if(!("classes" in ignores)){ + each(query.classes, function(cname, idx, arr){ + // get the class name + /* + var isWildcard = cname.charAt(cname.length-1) == "*"; + if(isWildcard){ + cname = cname.substr(0, cname.length-1); + } + // I dislike the regex thing, even if memoized in a cache, but it's VERY short + var re = new RegExp("(?:^|\\s)" + cname + (isWildcard ? ".*" : "") + "(?:\\s|$)"); + */ + var re = new RegExp("(?:^|\\s)" + cname + "(?:\\s|$)"); + ff = agree(ff, function(elem){ + return re.test(elem.className); + }); + ff.count = idx; + }); + } + + if(!("pseudos" in ignores)){ + each(query.pseudos, function(pseudo){ + var pn = pseudo.name; + if(pseudos[pn]){ + ff = agree(ff, pseudos[pn](pn, pseudo.value)); + } + }); + } + + if(!("attrs" in ignores)){ + each(query.attrs, function(attr){ + var matcher; + var a = attr.attr; + // type, attr, matchFor + if(attr.type && attrs[attr.type]){ + matcher = attrs[attr.type](a, attr.matchFor); + }else if(a.length){ + matcher = defaultGetter(a); + } + if(matcher){ + ff = agree(ff, matcher); + } + }); + } + + if(!("id" in ignores)){ + if(query.id){ + ff = agree(ff, function(elem){ + return (!!elem && (elem.id == query.id)); + }); + } + } + + if(!ff){ + if(!("default" in ignores)){ + ff = yesman; + } + } + return ff; + }; + + var _nextSibling = function(filterFunc){ + return function(node, ret, bag){ + while(node = node[_ns]){ + if(_noNES && (!_isElement(node))){ continue; } + if( + (!bag || _isUnique(node, bag)) && + filterFunc(node) + ){ + ret.push(node); + } + break; + } + return ret; + }; + }; + + var _nextSiblings = function(filterFunc){ + return function(root, ret, bag){ + var te = root[_ns]; + while(te){ + if(_simpleNodeTest(te)){ + if(bag && !_isUnique(te, bag)){ + break; + } + if(filterFunc(te)){ + ret.push(te); + } + } + te = te[_ns]; + } + return ret; + }; + }; + + // get an array of child *elements*, skipping text and comment nodes + var _childElements = function(filterFunc){ + filterFunc = filterFunc||yesman; + return function(root, ret, bag){ + // get an array of child elements, skipping text and comment nodes + var te, x = 0, tret = root.children || root.childNodes; + while(te = tret[x++]){ + if( + _simpleNodeTest(te) && + (!bag || _isUnique(te, bag)) && + (filterFunc(te, x)) + ){ + ret.push(te); + } + } + return ret; + }; + }; + + // test to see if node is below root + var _isDescendant = function(node, root){ + var pn = node.parentNode; + while(pn){ + if(pn == root){ + break; + } + pn = pn.parentNode; + } + return !!pn; + }; + + var _getElementsFuncCache = {}; + + var getElementsFunc = function(query){ + var retFunc = _getElementsFuncCache[query.query]; + // if we've got a cached dispatcher, just use that + if(retFunc){ return retFunc; } + // else, generate a new on + + // NOTE: + // this function returns a function that searches for nodes and + // filters them. The search may be specialized by infix operators + // (">", "~", or "+") else it will default to searching all + // descendants (the " " selector). Once a group of children is + // found, a test function is applied to weed out the ones we + // don't want. Many common cases can be fast-pathed. We spend a + // lot of cycles to create a dispatcher that doesn't do more work + // than necessary at any point since, unlike this function, the + // dispatchers will be called every time. The logic of generating + // efficient dispatchers looks like this in pseudo code: + // + // # if it's a purely descendant query (no ">", "+", or "~" modifiers) + // if infixOperator == " ": + // if only(id): + // return def(root): + // return d.byId(id, root); + // + // elif id: + // return def(root): + // return filter(d.byId(id, root)); + // + // elif cssClass && getElementsByClassName: + // return def(root): + // return filter(root.getElementsByClassName(cssClass)); + // + // elif only(tag): + // return def(root): + // return root.getElementsByTagName(tagName); + // + // else: + // # search by tag name, then filter + // return def(root): + // return filter(root.getElementsByTagName(tagName||"*")); + // + // elif infixOperator == ">": + // # search direct children + // return def(root): + // return filter(root.children); + // + // elif infixOperator == "+": + // # search next sibling + // return def(root): + // return filter(root.nextElementSibling); + // + // elif infixOperator == "~": + // # search rightward siblings + // return def(root): + // return filter(nextSiblings(root)); + + var io = query.infixOper; + var oper = (io ? io.oper : ""); + // the default filter func which tests for all conditions in the query + // part. This is potentially inefficient, so some optimized paths may + // re-define it to test fewer things. + var filterFunc = getSimpleFilterFunc(query, { el: 1 }); + var qt = query.tag; + var wildcardTag = ("*" == qt); + var ecs = getDoc()["getElementsByClassName"]; + + if(!oper){ + // if there's no infix operator, then it's a descendant query. ID + // and "elements by class name" variants can be accelerated so we + // call them out explicitly: + if(query.id){ + // testing shows that the overhead of yesman() is acceptable + // and can save us some bytes vs. re-defining the function + // everywhere. + filterFunc = (!query.loops && wildcardTag) ? + yesman : + getSimpleFilterFunc(query, { el: 1, id: 1 }); + + retFunc = function(root, arr){ + var te = dom.byId(query.id, (root.ownerDocument||root)); + if(!te || !filterFunc(te)){ return; } + if(9 == root.nodeType){ // if root's a doc, we just return directly + return getArr(te, arr); + }else{ // otherwise check ancestry + if(_isDescendant(te, root)){ + return getArr(te, arr); + } + } + }; + }else if( + ecs && + // isAlien check. Workaround for Prototype.js being totally evil/dumb. + /\{\s*\[native code\]\s*\}/.test(String(ecs)) && + query.classes.length && + !cssCaseBug + ){ + // it's a class-based query and we've got a fast way to run it. + + // ignore class and ID filters since we will have handled both + filterFunc = getSimpleFilterFunc(query, { el: 1, classes: 1, id: 1 }); + var classesString = query.classes.join(" "); + retFunc = function(root, arr, bag){ + var ret = getArr(0, arr), te, x=0; + var tret = root.getElementsByClassName(classesString); + while((te = tret[x++])){ + if(filterFunc(te, root) && _isUnique(te, bag)){ + ret.push(te); + } + } + return ret; + }; + + }else if(!wildcardTag && !query.loops){ + // it's tag only. Fast-path it. + retFunc = function(root, arr, bag){ + var ret = getArr(0, arr), te, x=0; + var tag = query.getTag(), + tret = tag ? root.getElementsByTagName(tag) : []; + while((te = tret[x++])){ + if(_isUnique(te, bag)){ + ret.push(te); + } + } + return ret; + }; + }else{ + // the common case: + // a descendant selector without a fast path. By now it's got + // to have a tag selector, even if it's just "*" so we query + // by that and filter + filterFunc = getSimpleFilterFunc(query, { el: 1, tag: 1, id: 1 }); + retFunc = function(root, arr, bag){ + var ret = getArr(0, arr), te, x=0; + // we use getTag() to avoid case sensitivity issues + var tag = query.getTag(), + tret = tag ? root.getElementsByTagName(tag) : []; + while((te = tret[x++])){ + if(filterFunc(te, root) && _isUnique(te, bag)){ + ret.push(te); + } + } + return ret; + }; + } + }else{ + // the query is scoped in some way. Instead of querying by tag we + // use some other collection to find candidate nodes + var skipFilters = { el: 1 }; + if(wildcardTag){ + skipFilters.tag = 1; + } + filterFunc = getSimpleFilterFunc(query, skipFilters); + if("+" == oper){ + retFunc = _nextSibling(filterFunc); + }else if("~" == oper){ + retFunc = _nextSiblings(filterFunc); + }else if(">" == oper){ + retFunc = _childElements(filterFunc); + } + } + // cache it and return + return _getElementsFuncCache[query.query] = retFunc; + }; + + var filterDown = function(root, queryParts){ + // NOTE: + // this is the guts of the DOM query system. It takes a list of + // parsed query parts and a root and finds children which match + // the selector represented by the parts + var candidates = getArr(root), qp, x, te, qpl = queryParts.length, bag, ret; + + for(var i = 0; i < qpl; i++){ + ret = []; + qp = queryParts[i]; + x = candidates.length - 1; + if(x > 0){ + // if we have more than one root at this level, provide a new + // hash to use for checking group membership but tell the + // system not to post-filter us since we will already have been + // guaranteed to be unique + bag = {}; + ret.nozip = true; + } + var gef = getElementsFunc(qp); + for(var j = 0; (te = candidates[j]); j++){ + // for every root, get the elements that match the descendant + // selector, adding them to the "ret" array and filtering them + // via membership in this level's bag. If there are more query + // parts, then this level's return will be used as the next + // level's candidates + gef(te, ret, bag); + } + if(!ret.length){ break; } + candidates = ret; + } + return ret; + }; + + //////////////////////////////////////////////////////////////////////// + // the query runner + //////////////////////////////////////////////////////////////////////// + + // these are the primary caches for full-query results. The query + // dispatcher functions are generated then stored here for hash lookup in + // the future + var _queryFuncCacheDOM = {}, + _queryFuncCacheQSA = {}; + + // this is the second level of splitting, from full-length queries (e.g., + // "div.foo .bar") into simple query expressions (e.g., ["div.foo", + // ".bar"]) + var getStepQueryFunc = function(query){ + var qparts = getQueryParts(trim(query)); + + // if it's trivial, avoid iteration and zipping costs + if(qparts.length == 1){ + // we optimize this case here to prevent dispatch further down the + // chain, potentially slowing things down. We could more elegantly + // handle this in filterDown(), but it's slower for simple things + // that need to be fast (e.g., "#someId"). + var tef = getElementsFunc(qparts[0]); + return function(root){ + var r = tef(root, []); + if(r){ r.nozip = true; } + return r; + }; + } + + // otherwise, break it up and return a runner that iterates over the parts recursively + return function(root){ + return filterDown(root, qparts); + }; + }; + + // NOTES: + // * we can't trust QSA for anything but document-rooted queries, so + // caching is split into DOM query evaluators and QSA query evaluators + // * caching query results is dirty and leak-prone (or, at a minimum, + // prone to unbounded growth). Other toolkits may go this route, but + // they totally destroy their own ability to manage their memory + // footprint. If we implement it, it should only ever be with a fixed + // total element reference # limit and an LRU-style algorithm since JS + // has no weakref support. Caching compiled query evaluators is also + // potentially problematic, but even on large documents the size of the + // query evaluators is often < 100 function objects per evaluator (and + // LRU can be applied if it's ever shown to be an issue). + // * since IE's QSA support is currently only for HTML documents and even + // then only in IE 8's "standards mode", we have to detect our dispatch + // route at query time and keep 2 separate caches. Ugg. + + // we need to determine if we think we can run a given query via + // querySelectorAll or if we'll need to fall back on DOM queries to get + // there. We need a lot of information about the environment and the query + // to make the determination (e.g. does it support QSA, does the query in + // question work in the native QSA impl, etc.). + + // IE QSA queries may incorrectly include comment nodes, so we throw the + // zipping function into "remove" comments mode instead of the normal "skip + // it" which every other QSA-clued browser enjoys + var noZip = has("ie") ? "commentStrip" : "nozip"; + + var qsa = "querySelectorAll"; + var qsaAvail = !!getDoc()[qsa]; + + //Don't bother with n+3 type of matches, IE complains if we modify those. + var infixSpaceRe = /\\[>~+]|n\+\d|([^ \\])?([>~+])([^ =])?/g; + var infixSpaceFunc = function(match, pre, ch, post){ + return ch ? (pre ? pre + " " : "") + ch + (post ? " " + post : "") : /*n+3*/ match; + }; + + //Don't apply the infixSpaceRe to attribute value selectors + var attRe = /([^[]*)([^\]]*])?/g; + var attFunc = function(match, nonAtt, att){ + return nonAtt.replace(infixSpaceRe, infixSpaceFunc) + (att||""); + }; + var getQueryFunc = function(query, forceDOM){ + //Normalize query. The CSS3 selectors spec allows for omitting spaces around + //infix operators, >, ~ and + + //Do the work here since detection for spaces is used as a simple "not use QSA" + //test below. + query = query.replace(attRe, attFunc); + + if(qsaAvail){ + // if we've got a cached variant and we think we can do it, run it! + var qsaCached = _queryFuncCacheQSA[query]; + if(qsaCached && !forceDOM){ return qsaCached; } + } + + // else if we've got a DOM cached variant, assume that we already know + // all we need to and use it + var domCached = _queryFuncCacheDOM[query]; + if(domCached){ return domCached; } + + // TODO: + // today we're caching DOM and QSA branches separately so we + // recalc useQSA every time. If we had a way to tag root+query + // efficiently, we'd be in good shape to do a global cache. + + var qcz = query.charAt(0); + var nospace = (-1 == query.indexOf(" ")); + + // byId searches are wicked fast compared to QSA, even when filtering + // is required + if( (query.indexOf("#") >= 0) && (nospace) ){ + forceDOM = true; + } + + var useQSA = ( + qsaAvail && (!forceDOM) && + // as per CSS 3, we can't currently start w/ combinator: + // http://www.w3.org/TR/css3-selectors/#w3cselgrammar + (specials.indexOf(qcz) == -1) && + // IE's QSA impl sucks on pseudos + (!has("ie") || (query.indexOf(":") == -1)) && + + (!(cssCaseBug && (query.indexOf(".") >= 0))) && + + // FIXME: + // need to tighten up browser rules on ":contains" and "|=" to + // figure out which aren't good + // Latest webkit (around 531.21.8) does not seem to do well with :checked on option + // elements, even though according to spec, selected options should + // match :checked. So go nonQSA for it: + // http://bugs.dojotoolkit.org/ticket/5179 + (query.indexOf(":contains") == -1) && (query.indexOf(":checked") == -1) && + (query.indexOf("|=") == -1) // some browsers don't grok it + ); + + // TODO: + // if we've got a descendant query (e.g., "> .thinger" instead of + // just ".thinger") in a QSA-able doc, but are passed a child as a + // root, it should be possible to give the item a synthetic ID and + // trivially rewrite the query to the form "#synid > .thinger" to + // use the QSA branch + + + if(useQSA){ + var tq = (specials.indexOf(query.charAt(query.length-1)) >= 0) ? + (query + " *") : query; + return _queryFuncCacheQSA[query] = function(root){ + try{ + // the QSA system contains an egregious spec bug which + // limits us, effectively, to only running QSA queries over + // entire documents. See: + // http://ejohn.org/blog/thoughts-on-queryselectorall/ + // despite this, we can also handle QSA runs on simple + // selectors, but we don't want detection to be expensive + // so we're just checking for the presence of a space char + // right now. Not elegant, but it's cheaper than running + // the query parser when we might not need to + if(!((9 == root.nodeType) || nospace)){ throw ""; } + var r = root[qsa](tq); + // skip expensive duplication checks and just wrap in a NodeList + r[noZip] = true; + return r; + }catch(e){ + // else run the DOM branch on this query, ensuring that we + // default that way in the future + return getQueryFunc(query, true)(root); + } + }; + }else{ + // DOM branch + var parts = query.match(/([^\s,](?:"(?:\\.|[^"])+"|'(?:\\.|[^'])+'|[^,])*)/g); + return _queryFuncCacheDOM[query] = ((parts.length < 2) ? + // if not a compound query (e.g., ".foo, .bar"), cache and return a dispatcher + getStepQueryFunc(query) : + // if it *is* a complex query, break it up into its + // constituent parts and return a dispatcher that will + // merge the parts when run + function(root){ + var pindex = 0, // avoid array alloc for every invocation + ret = [], + tp; + while((tp = parts[pindex++])){ + ret = ret.concat(getStepQueryFunc(tp)(root)); + } + return ret; + } + ); + } + }; + + var _zipIdx = 0; + + // NOTE: + // this function is Moo inspired, but our own impl to deal correctly + // with XML in IE + var _nodeUID = has("ie") ? function(node){ + if(caseSensitive){ + // XML docs don't have uniqueID on their nodes + return (node.getAttribute("_uid") || node.setAttribute("_uid", ++_zipIdx) || _zipIdx); + + }else{ + return node.uniqueID; + } + } : + function(node){ + return (node._uid || (node._uid = ++_zipIdx)); + }; + + // determine if a node in is unique in a "bag". In this case we don't want + // to flatten a list of unique items, but rather just tell if the item in + // question is already in the bag. Normally we'd just use hash lookup to do + // this for us but IE's DOM is busted so we can't really count on that. On + // the upside, it gives us a built in unique ID function. + var _isUnique = function(node, bag){ + if(!bag){ return 1; } + var id = _nodeUID(node); + if(!bag[id]){ return bag[id] = 1; } + return 0; + }; + + // attempt to efficiently determine if an item in a list is a dupe, + // returning a list of "uniques", hopefully in document order + var _zipIdxName = "_zipIdx"; + var _zip = function(arr){ + if(arr && arr.nozip){ + return arr; + } + var ret = []; + if(!arr || !arr.length){ return ret; } + if(arr[0]){ + ret.push(arr[0]); + } + if(arr.length < 2){ return ret; } + + _zipIdx++; + + // we have to fork here for IE and XML docs because we can't set + // expandos on their nodes (apparently). *sigh* + var x, te; + if(has("ie") && caseSensitive){ + var szidx = _zipIdx+""; + arr[0].setAttribute(_zipIdxName, szidx); + for(x = 1; te = arr[x]; x++){ + if(arr[x].getAttribute(_zipIdxName) != szidx){ + ret.push(te); + } + te.setAttribute(_zipIdxName, szidx); + } + }else if(has("ie") && arr.commentStrip){ + try{ + for(x = 1; te = arr[x]; x++){ + if(_isElement(te)){ + ret.push(te); + } + } + }catch(e){ /* squelch */ } + }else{ + if(arr[0]){ arr[0][_zipIdxName] = _zipIdx; } + for(x = 1; te = arr[x]; x++){ + if(arr[x][_zipIdxName] != _zipIdx){ + ret.push(te); + } + te[_zipIdxName] = _zipIdx; + } + } + return ret; + }; + + // the main executor + var query = function(/*String*/ query, /*String|DOMNode?*/ root){ + // summary: + // Returns nodes which match the given CSS3 selector, searching the + // entire document by default but optionally taking a node to scope + // the search by. Returns an array. + // description: + // dojo.query() is the swiss army knife of DOM node manipulation in + // Dojo. Much like Prototype's "$$" (bling-bling) function or JQuery's + // "$" function, dojo.query provides robust, high-performance + // CSS-based node selector support with the option of scoping searches + // to a particular sub-tree of a document. + // + // Supported Selectors: + // -------------------- + // + // acme supports a rich set of CSS3 selectors, including: + // + // - class selectors (e.g., `.foo`) + // - node type selectors like `span` + // - ` ` descendant selectors + // - `>` child element selectors + // - `#foo` style ID selectors + // - `*` universal selector + // - `~`, the preceded-by sibling selector + // - `+`, the immediately preceded-by sibling selector + // - attribute queries: + // - `[foo]` attribute presence selector + // - `[foo='bar']` attribute value exact match + // - `[foo~='bar']` attribute value list item match + // - `[foo^='bar']` attribute start match + // - `[foo$='bar']` attribute end match + // - `[foo*='bar']` attribute substring match + // - `:first-child`, `:last-child`, and `:only-child` positional selectors + // - `:empty` content emtpy selector + // - `:checked` pseudo selector + // - `:nth-child(n)`, `:nth-child(2n+1)` style positional calculations + // - `:nth-child(even)`, `:nth-child(odd)` positional selectors + // - `:not(...)` negation pseudo selectors + // + // Any legal combination of these selectors will work with + // `dojo.query()`, including compound selectors ("," delimited). + // Very complex and useful searches can be constructed with this + // palette of selectors and when combined with functions for + // manipulation presented by dojo/NodeList, many types of DOM + // manipulation operations become very straightforward. + // + // Unsupported Selectors: + // ---------------------- + // + // While dojo.query handles many CSS3 selectors, some fall outside of + // what's reasonable for a programmatic node querying engine to + // handle. Currently unsupported selectors include: + // + // - namespace-differentiated selectors of any form + // - all `::` pseduo-element selectors + // - certain pseudo-selectors which don't get a lot of day-to-day use: + // - `:root`, `:lang()`, `:target`, `:focus` + // - all visual and state selectors: + // - `:root`, `:active`, `:hover`, `:visited`, `:link`, + // `:enabled`, `:disabled` + // - `:*-of-type` pseudo selectors + // + // dojo.query and XML Documents: + // ----------------------------- + // + // `dojo.query` (as of dojo 1.2) supports searching XML documents + // in a case-sensitive manner. If an HTML document is served with + // a doctype that forces case-sensitivity (e.g., XHTML 1.1 + // Strict), dojo.query() will detect this and "do the right + // thing". Case sensitivity is dependent upon the document being + // searched and not the query used. It is therefore possible to + // use case-sensitive queries on strict sub-documents (iframes, + // etc.) or XML documents while still assuming case-insensitivity + // for a host/root document. + // + // Non-selector Queries: + // --------------------- + // + // If something other than a String is passed for the query, + // `dojo.query` will return a new `dojo/NodeList` instance + // constructed from that parameter alone and all further + // processing will stop. This means that if you have a reference + // to a node or NodeList, you can quickly construct a new NodeList + // from the original by calling `dojo.query(node)` or + // `dojo.query(list)`. + // + // query: + // The CSS3 expression to match against. For details on the syntax of + // CSS3 selectors, see + // root: + // A DOMNode (or node id) to scope the search from. Optional. + // returns: Array + // example: + // search the entire document for elements with the class "foo": + // | dojo.query(".foo"); + // these elements will match: + // | + // | + // |

                                + // example: + // search the entire document for elements with the classes "foo" *and* "bar": + // | dojo.query(".foo.bar"); + // these elements will match: + // | + // while these will not: + // | + // |

                                + // example: + // find `` elements which are descendants of paragraphs and + // which have a "highlighted" class: + // | dojo.query("p span.highlighted"); + // the innermost span in this fragment matches: + // |

                                + // | ... + // | ... + // | + // |

                                + // example: + // set an "odd" class on all odd table rows inside of the table + // `#tabular_data`, using the `>` (direct child) selector to avoid + // affecting any nested tables: + // | dojo.query("#tabular_data > tbody > tr:nth-child(odd)").addClass("odd"); + // example: + // remove all elements with the class "error" from the document + // and store them in a list: + // | var errors = dojo.query(".error").orphan(); + // example: + // add an onclick handler to every submit button in the document + // which causes the form to be sent via Ajax instead: + // | dojo.query("input[type='submit']").onclick(function(e){ + // | dojo.stopEvent(e); // prevent sending the form + // | var btn = e.target; + // | dojo.xhrPost({ + // | form: btn.form, + // | load: function(data){ + // | // replace the form with the response + // | var div = dojo.doc.createElement("div"); + // | dojo.place(div, btn.form, "after"); + // | div.innerHTML = data; + // | dojo.style(btn.form, "display", "none"); + // | } + // | }); + // | }); + + root = root || getDoc(); + + // throw the big case sensitivity switch + var od = root.ownerDocument || root; // root is either Document or a node inside the document + caseSensitive = (od.createElement("div").tagName === "div"); + + // NOTE: + // adding "true" as the 2nd argument to getQueryFunc is useful for + // testing the DOM branch without worrying about the + // behavior/performance of the QSA branch. + var r = getQueryFunc(query)(root); + + // FIXME: + // need to investigate this branch WRT #8074 and #8075 + if(r && r.nozip){ + return r; + } + return _zip(r); // dojo/NodeList + }; + query.filter = function(/*Node[]*/ nodeList, /*String*/ filter, /*String|DOMNode?*/ root){ + // summary: + // function for filtering a NodeList based on a selector, optimized for simple selectors + var tmpNodeList = [], + parts = getQueryParts(filter), + filterFunc = + (parts.length == 1 && !/[^\w#\.]/.test(filter)) ? + getSimpleFilterFunc(parts[0]) : + function(node){ + return array.indexOf(query(filter, dom.byId(root)), node) != -1; + }; + for(var x = 0, te; te = nodeList[x]; x++){ + if(filterFunc(te)){ tmpNodeList.push(te); } + } + return tmpNodeList; + }; + return query; +}); + +}, +'dojo/errors/RequestTimeoutError':function(){ +define("dojo/errors/RequestTimeoutError", ['./create', './RequestError'], function(create, RequestError){ + // module: + // dojo/errors/RequestTimeoutError + + /*===== + return function(){ + // summary: + // TODOC + }; + =====*/ + + return create("RequestTimeoutError", null, RequestError, { + dojoType: "timeout" + }); +}); + +}, +'dojo/dom-style':function(){ +define("dojo/dom-style", ["./sniff", "./dom"], function(has, dom){ + // module: + // dojo/dom-style + + // ============================= + // Style Functions + // ============================= + + // getComputedStyle drives most of the style code. + // Wherever possible, reuse the returned object. + // + // API functions below that need to access computed styles accept an + // optional computedStyle parameter. + // If this parameter is omitted, the functions will call getComputedStyle themselves. + // This way, calling code can access computedStyle once, and then pass the reference to + // multiple API functions. + + // Although we normally eschew argument validation at this + // level, here we test argument 'node' for (duck)type, + // by testing nodeType, ecause 'document' is the 'parentNode' of 'body' + // it is frequently sent to this function even + // though it is not Element. + var getComputedStyle, style = { + // summary: + // This module defines the core dojo DOM style API. + }; + if(has("webkit")){ + getComputedStyle = function(/*DomNode*/ node){ + var s; + if(node.nodeType == 1){ + var dv = node.ownerDocument.defaultView; + s = dv.getComputedStyle(node, null); + if(!s && node.style){ + node.style.display = ""; + s = dv.getComputedStyle(node, null); + } + } + return s || {}; + }; + }else if(has("ie") && (has("ie") < 9 || has("quirks"))){ + getComputedStyle = function(node){ + // IE (as of 7) doesn't expose Element like sane browsers + // currentStyle can be null on IE8! + return node.nodeType == 1 /* ELEMENT_NODE*/ && node.currentStyle ? node.currentStyle : {}; + }; + }else{ + getComputedStyle = function(node){ + return node.nodeType == 1 /* ELEMENT_NODE*/ ? + node.ownerDocument.defaultView.getComputedStyle(node, null) : {}; + }; + } + style.getComputedStyle = getComputedStyle; + /*===== + style.getComputedStyle = function(node){ + // summary: + // Returns a "computed style" object. + // + // description: + // Gets a "computed style" object which can be used to gather + // information about the current state of the rendered node. + // + // Note that this may behave differently on different browsers. + // Values may have different formats and value encodings across + // browsers. + // + // Note also that this method is expensive. Wherever possible, + // reuse the returned object. + // + // Use the dojo.style() method for more consistent (pixelized) + // return values. + // + // node: DOMNode + // A reference to a DOM node. Does NOT support taking an + // ID string for speed reasons. + // example: + // | dojo.getComputedStyle(dojo.byId('foo')).borderWidth; + // + // example: + // Reusing the returned object, avoiding multiple lookups: + // | var cs = dojo.getComputedStyle(dojo.byId("someNode")); + // | var w = cs.width, h = cs.height; + return; // CSS2Properties + }; + =====*/ + + var toPixel; + if(!has("ie")){ + toPixel = function(element, value){ + // style values can be floats, client code may want + // to round for integer pixels. + return parseFloat(value) || 0; + }; + }else{ + toPixel = function(element, avalue){ + if(!avalue){ return 0; } + // on IE7, medium is usually 4 pixels + if(avalue == "medium"){ return 4; } + // style values can be floats, client code may + // want to round this value for integer pixels. + if(avalue.slice && avalue.slice(-2) == 'px'){ return parseFloat(avalue); } + var s = element.style, rs = element.runtimeStyle, cs = element.currentStyle, + sLeft = s.left, rsLeft = rs.left; + rs.left = cs.left; + try{ + // 'avalue' may be incompatible with style.left, which can cause IE to throw + // this has been observed for border widths using "thin", "medium", "thick" constants + // those particular constants could be trapped by a lookup + // but perhaps there are more + s.left = avalue; + avalue = s.pixelLeft; + }catch(e){ + avalue = 0; + } + s.left = sLeft; + rs.left = rsLeft; + return avalue; + }; + } + style.toPixelValue = toPixel; + /*===== + style.toPixelValue = function(node, value){ + // summary: + // converts style value to pixels on IE or return a numeric value. + // node: DOMNode + // value: String + // returns: Number + }; + =====*/ + + // FIXME: there opacity quirks on FF that we haven't ported over. Hrm. + + var astr = "DXImageTransform.Microsoft.Alpha"; + var af = function(n, f){ + try{ + return n.filters.item(astr); + }catch(e){ + return f ? {} : null; + } + }; + + var _getOpacity = + has("ie") < 9 || (has("ie") && has("quirks")) ? function(node){ + try{ + return af(node).Opacity / 100; // Number + }catch(e){ + return 1; // Number + } + } : + function(node){ + return getComputedStyle(node).opacity; + }; + + var _setOpacity = + has("ie") < 9 || (has("ie") && has("quirks")) ? function(/*DomNode*/ node, /*Number*/ opacity){ + var ov = opacity * 100, opaque = opacity == 1; + node.style.zoom = opaque ? "" : 1; + + if(!af(node)){ + if(opaque){ + return opacity; + } + node.style.filter += " progid:" + astr + "(Opacity=" + ov + ")"; + }else{ + af(node, 1).Opacity = ov; + } + + // on IE7 Alpha(Filter opacity=100) makes text look fuzzy so disable it altogether (bug #2661), + //but still update the opacity value so we can get a correct reading if it is read later. + af(node, 1).Enabled = !opaque; + + if(node.tagName.toLowerCase() == "tr"){ + for(var td = node.firstChild; td; td = td.nextSibling){ + if(td.tagName.toLowerCase() == "td"){ + _setOpacity(td, opacity); + } + } + } + return opacity; + } : + function(node, opacity){ + return node.style.opacity = opacity; + }; + + var _pixelNamesCache = { + left: true, top: true + }; + var _pixelRegExp = /margin|padding|width|height|max|min|offset/; // |border + function _toStyleValue(node, type, value){ + //TODO: should we really be doing string case conversion here? Should we cache it? Need to profile! + type = type.toLowerCase(); + if(has("ie")){ + if(value == "auto"){ + if(type == "height"){ return node.offsetHeight; } + if(type == "width"){ return node.offsetWidth; } + } + if(type == "fontweight"){ + switch(value){ + case 700: return "bold"; + case 400: + default: return "normal"; + } + } + } + if(!(type in _pixelNamesCache)){ + _pixelNamesCache[type] = _pixelRegExp.test(type); + } + return _pixelNamesCache[type] ? toPixel(node, value) : value; + } + + var _floatStyle = has("ie") ? "styleFloat" : "cssFloat", + _floatAliases = {"cssFloat": _floatStyle, "styleFloat": _floatStyle, "float": _floatStyle}; + + // public API + + style.get = function getStyle(/*DOMNode|String*/ node, /*String?*/ name){ + // summary: + // Accesses styles on a node. + // description: + // Getting the style value uses the computed style for the node, so the value + // will be a calculated value, not just the immediate node.style value. + // Also when getting values, use specific style names, + // like "borderBottomWidth" instead of "border" since compound values like + // "border" are not necessarily reflected as expected. + // If you want to get node dimensions, use `dojo.marginBox()`, + // `dojo.contentBox()` or `dojo.position()`. + // node: DOMNode|String + // id or reference to node to get style for + // name: String? + // the style property to get + // example: + // Passing only an ID or node returns the computed style object of + // the node: + // | dojo.getStyle("thinger"); + // example: + // Passing a node and a style property returns the current + // normalized, computed value for that property: + // | dojo.getStyle("thinger", "opacity"); // 1 by default + + var n = dom.byId(node), l = arguments.length, op = (name == "opacity"); + if(l == 2 && op){ + return _getOpacity(n); + } + name = _floatAliases[name] || name; + var s = style.getComputedStyle(n); + return (l == 1) ? s : _toStyleValue(n, name, s[name] || n.style[name]); /* CSS2Properties||String||Number */ + }; + + style.set = function setStyle(/*DOMNode|String*/ node, /*String|Object*/ name, /*String?*/ value){ + // summary: + // Sets styles on a node. + // node: DOMNode|String + // id or reference to node to set style for + // name: String|Object + // the style property to set in DOM-accessor format + // ("borderWidth", not "border-width") or an object with key/value + // pairs suitable for setting each property. + // value: String? + // If passed, sets value on the node for style, handling + // cross-browser concerns. When setting a pixel value, + // be sure to include "px" in the value. For instance, top: "200px". + // Otherwise, in some cases, some browsers will not apply the style. + // + // example: + // Passing a node, a style property, and a value changes the + // current display of the node and returns the new computed value + // | dojo.setStyle("thinger", "opacity", 0.5); // == 0.5 + // + // example: + // Passing a node, an object-style style property sets each of the values in turn and returns the computed style object of the node: + // | dojo.setStyle("thinger", { + // | "opacity": 0.5, + // | "border": "3px solid black", + // | "height": "300px" + // | }); + // + // example: + // When the CSS style property is hyphenated, the JavaScript property is camelCased. + // font-size becomes fontSize, and so on. + // | dojo.setStyle("thinger",{ + // | fontSize:"14pt", + // | letterSpacing:"1.2em" + // | }); + // + // example: + // dojo/NodeList implements .style() using the same syntax, omitting the "node" parameter, calling + // dojo.style() on every element of the list. See: `dojo.query()` and `dojo/NodeList` + // | dojo.query(".someClassName").style("visibility","hidden"); + // | // or + // | dojo.query("#baz > div").style({ + // | opacity:0.75, + // | fontSize:"13pt" + // | }); + + var n = dom.byId(node), l = arguments.length, op = (name == "opacity"); + name = _floatAliases[name] || name; + if(l == 3){ + return op ? _setOpacity(n, value) : n.style[name] = value; // Number + } + for(var x in name){ + style.set(node, x, name[x]); + } + return style.getComputedStyle(n); + }; + + return style; +}); + +}, +'dojo/dom-geometry':function(){ +define(["./sniff", "./_base/window","./dom", "./dom-style"], + function(has, win, dom, style){ + // module: + // dojo/dom-geometry + + // the result object + var geom = { + // summary: + // This module defines the core dojo DOM geometry API. + }; + + // Box functions will assume this model. + // On IE/Opera, BORDER_BOX will be set if the primary document is in quirks mode. + // Can be set to change behavior of box setters. + + // can be either: + // "border-box" + // "content-box" (default) + geom.boxModel = "content-box"; + + // We punt per-node box mode testing completely. + // If anybody cares, we can provide an additional (optional) unit + // that overrides existing code to include per-node box sensitivity. + + // Opera documentation claims that Opera 9 uses border-box in BackCompat mode. + // but experiments (Opera 9.10.8679 on Windows Vista) indicate that it actually continues to use content-box. + // IIRC, earlier versions of Opera did in fact use border-box. + // Opera guys, this is really confusing. Opera being broken in quirks mode is not our fault. + + if(has("ie") /*|| has("opera")*/){ + // client code may have to adjust if compatMode varies across iframes + geom.boxModel = document.compatMode == "BackCompat" ? "border-box" : "content-box"; + } + + geom.getPadExtents = function getPadExtents(/*DomNode*/ node, /*Object*/ computedStyle){ + // summary: + // Returns object with special values specifically useful for node + // fitting. + // description: + // Returns an object with `w`, `h`, `l`, `t` properties: + // | l/t/r/b = left/top/right/bottom padding (respectively) + // | w = the total of the left and right padding + // | h = the total of the top and bottom padding + // If 'node' has position, l/t forms the origin for child nodes. + // The w/h are used for calculating boxes. + // Normally application code will not need to invoke this + // directly, and will use the ...box... functions instead. + // node: DOMNode + // computedStyle: Object? + // This parameter accepts computed styles object. + // If this parameter is omitted, the functions will call + // dojo.getComputedStyle to get one. It is a better way, calling + // dojo.computedStyle once, and then pass the reference to this + // computedStyle parameter. Wherever possible, reuse the returned + // object of dojo/dom-style.getComputedStyle(). + + node = dom.byId(node); + var s = computedStyle || style.getComputedStyle(node), px = style.toPixelValue, + l = px(node, s.paddingLeft), t = px(node, s.paddingTop), r = px(node, s.paddingRight), b = px(node, s.paddingBottom); + return {l: l, t: t, r: r, b: b, w: l + r, h: t + b}; + }; + + var none = "none"; + + geom.getBorderExtents = function getBorderExtents(/*DomNode*/ node, /*Object*/ computedStyle){ + // summary: + // returns an object with properties useful for noting the border + // dimensions. + // description: + // - l/t/r/b = the sum of left/top/right/bottom border (respectively) + // - w = the sum of the left and right border + // - h = the sum of the top and bottom border + // + // The w/h are used for calculating boxes. + // Normally application code will not need to invoke this + // directly, and will use the ...box... functions instead. + // node: DOMNode + // computedStyle: Object? + // This parameter accepts computed styles object. + // If this parameter is omitted, the functions will call + // dojo.getComputedStyle to get one. It is a better way, calling + // dojo.computedStyle once, and then pass the reference to this + // computedStyle parameter. Wherever possible, reuse the returned + // object of dojo/dom-style.getComputedStyle(). + + node = dom.byId(node); + var px = style.toPixelValue, s = computedStyle || style.getComputedStyle(node), + l = s.borderLeftStyle != none ? px(node, s.borderLeftWidth) : 0, + t = s.borderTopStyle != none ? px(node, s.borderTopWidth) : 0, + r = s.borderRightStyle != none ? px(node, s.borderRightWidth) : 0, + b = s.borderBottomStyle != none ? px(node, s.borderBottomWidth) : 0; + return {l: l, t: t, r: r, b: b, w: l + r, h: t + b}; + }; + + geom.getPadBorderExtents = function getPadBorderExtents(/*DomNode*/ node, /*Object*/ computedStyle){ + // summary: + // Returns object with properties useful for box fitting with + // regards to padding. + // description: + // - l/t/r/b = the sum of left/top/right/bottom padding and left/top/right/bottom border (respectively) + // - w = the sum of the left and right padding and border + // - h = the sum of the top and bottom padding and border + // + // The w/h are used for calculating boxes. + // Normally application code will not need to invoke this + // directly, and will use the ...box... functions instead. + // node: DOMNode + // computedStyle: Object? + // This parameter accepts computed styles object. + // If this parameter is omitted, the functions will call + // dojo.getComputedStyle to get one. It is a better way, calling + // dojo.computedStyle once, and then pass the reference to this + // computedStyle parameter. Wherever possible, reuse the returned + // object of dojo/dom-style.getComputedStyle(). + + node = dom.byId(node); + var s = computedStyle || style.getComputedStyle(node), + p = geom.getPadExtents(node, s), + b = geom.getBorderExtents(node, s); + return { + l: p.l + b.l, + t: p.t + b.t, + r: p.r + b.r, + b: p.b + b.b, + w: p.w + b.w, + h: p.h + b.h + }; + }; + + geom.getMarginExtents = function getMarginExtents(node, computedStyle){ + // summary: + // returns object with properties useful for box fitting with + // regards to box margins (i.e., the outer-box). + // + // - l/t = marginLeft, marginTop, respectively + // - w = total width, margin inclusive + // - h = total height, margin inclusive + // + // The w/h are used for calculating boxes. + // Normally application code will not need to invoke this + // directly, and will use the ...box... functions instead. + // node: DOMNode + // computedStyle: Object? + // This parameter accepts computed styles object. + // If this parameter is omitted, the functions will call + // dojo.getComputedStyle to get one. It is a better way, calling + // dojo.computedStyle once, and then pass the reference to this + // computedStyle parameter. Wherever possible, reuse the returned + // object of dojo/dom-style.getComputedStyle(). + + node = dom.byId(node); + var s = computedStyle || style.getComputedStyle(node), px = style.toPixelValue, + l = px(node, s.marginLeft), t = px(node, s.marginTop), r = px(node, s.marginRight), b = px(node, s.marginBottom); + return {l: l, t: t, r: r, b: b, w: l + r, h: t + b}; + }; + + // Box getters work in any box context because offsetWidth/clientWidth + // are invariant wrt box context + // + // They do *not* work for display: inline objects that have padding styles + // because the user agent ignores padding (it's bogus styling in any case) + // + // Be careful with IMGs because they are inline or block depending on + // browser and browser mode. + + // Although it would be easier to read, there are not separate versions of + // _getMarginBox for each browser because: + // 1. the branching is not expensive + // 2. factoring the shared code wastes cycles (function call overhead) + // 3. duplicating the shared code wastes bytes + + geom.getMarginBox = function getMarginBox(/*DomNode*/ node, /*Object*/ computedStyle){ + // summary: + // returns an object that encodes the width, height, left and top + // positions of the node's margin box. + // node: DOMNode + // computedStyle: Object? + // This parameter accepts computed styles object. + // If this parameter is omitted, the functions will call + // dojo.getComputedStyle to get one. It is a better way, calling + // dojo.computedStyle once, and then pass the reference to this + // computedStyle parameter. Wherever possible, reuse the returned + // object of dojo/dom-style.getComputedStyle(). + + node = dom.byId(node); + var s = computedStyle || style.getComputedStyle(node), me = geom.getMarginExtents(node, s), + l = node.offsetLeft - me.l, t = node.offsetTop - me.t, p = node.parentNode, px = style.toPixelValue, pcs; + if(has("mozilla")){ + // Mozilla: + // If offsetParent has a computed overflow != visible, the offsetLeft is decreased + // by the parent's border. + // We don't want to compute the parent's style, so instead we examine node's + // computed left/top which is more stable. + var sl = parseFloat(s.left), st = parseFloat(s.top); + if(!isNaN(sl) && !isNaN(st)){ + l = sl; + t = st; + }else{ + // If child's computed left/top are not parseable as a number (e.g. "auto"), we + // have no choice but to examine the parent's computed style. + if(p && p.style){ + pcs = style.getComputedStyle(p); + if(pcs.overflow != "visible"){ + l += pcs.borderLeftStyle != none ? px(node, pcs.borderLeftWidth) : 0; + t += pcs.borderTopStyle != none ? px(node, pcs.borderTopWidth) : 0; + } + } + } + }else if(has("opera") || (has("ie") == 8 && !has("quirks"))){ + // On Opera and IE 8, offsetLeft/Top includes the parent's border + if(p){ + pcs = style.getComputedStyle(p); + l -= pcs.borderLeftStyle != none ? px(node, pcs.borderLeftWidth) : 0; + t -= pcs.borderTopStyle != none ? px(node, pcs.borderTopWidth) : 0; + } + } + return {l: l, t: t, w: node.offsetWidth + me.w, h: node.offsetHeight + me.h}; + }; + + geom.getContentBox = function getContentBox(node, computedStyle){ + // summary: + // Returns an object that encodes the width, height, left and top + // positions of the node's content box, irrespective of the + // current box model. + // node: DOMNode + // computedStyle: Object? + // This parameter accepts computed styles object. + // If this parameter is omitted, the functions will call + // dojo.getComputedStyle to get one. It is a better way, calling + // dojo.computedStyle once, and then pass the reference to this + // computedStyle parameter. Wherever possible, reuse the returned + // object of dojo/dom-style.getComputedStyle(). + + // clientWidth/Height are important since the automatically account for scrollbars + // fallback to offsetWidth/Height for special cases (see #3378) + node = dom.byId(node); + var s = computedStyle || style.getComputedStyle(node), w = node.clientWidth, h, + pe = geom.getPadExtents(node, s), be = geom.getBorderExtents(node, s); + if(!w){ + w = node.offsetWidth; + h = node.offsetHeight; + }else{ + h = node.clientHeight; + be.w = be.h = 0; + } + // On Opera, offsetLeft includes the parent's border + if(has("opera")){ + pe.l += be.l; + pe.t += be.t; + } + return {l: pe.l, t: pe.t, w: w - pe.w - be.w, h: h - pe.h - be.h}; + }; + + // Box setters depend on box context because interpretation of width/height styles + // vary wrt box context. + // + // The value of boxModel is used to determine box context. + // boxModel can be set directly to change behavior. + // + // Beware of display: inline objects that have padding styles + // because the user agent ignores padding (it's a bogus setup anyway) + // + // Be careful with IMGs because they are inline or block depending on + // browser and browser mode. + // + // Elements other than DIV may have special quirks, like built-in + // margins or padding, or values not detectable via computedStyle. + // In particular, margins on TABLE do not seems to appear + // at all in computedStyle on Mozilla. + + function setBox(/*DomNode*/ node, /*Number?*/ l, /*Number?*/ t, /*Number?*/ w, /*Number?*/ h, /*String?*/ u){ + // summary: + // sets width/height/left/top in the current (native) box-model + // dimensions. Uses the unit passed in u. + // node: + // DOM Node reference. Id string not supported for performance + // reasons. + // l: + // left offset from parent. + // t: + // top offset from parent. + // w: + // width in current box model. + // h: + // width in current box model. + // u: + // unit measure to use for other measures. Defaults to "px". + u = u || "px"; + var s = node.style; + if(!isNaN(l)){ + s.left = l + u; + } + if(!isNaN(t)){ + s.top = t + u; + } + if(w >= 0){ + s.width = w + u; + } + if(h >= 0){ + s.height = h + u; + } + } + + function isButtonTag(/*DomNode*/ node){ + // summary: + // True if the node is BUTTON or INPUT.type="button". + return node.tagName.toLowerCase() == "button" || + node.tagName.toLowerCase() == "input" && (node.getAttribute("type") || "").toLowerCase() == "button"; // boolean + } + + function usesBorderBox(/*DomNode*/ node){ + // summary: + // True if the node uses border-box layout. + + // We could test the computed style of node to see if a particular box + // has been specified, but there are details and we choose not to bother. + + // TABLE and BUTTON (and INPUT type=button) are always border-box by default. + // If you have assigned a different box to either one via CSS then + // box functions will break. + + return geom.boxModel == "border-box" || node.tagName.toLowerCase() == "table" || isButtonTag(node); // boolean + } + + geom.setContentSize = function setContentSize(/*DomNode*/ node, /*Object*/ box, /*Object*/ computedStyle){ + // summary: + // Sets the size of the node's contents, irrespective of margins, + // padding, or borders. + // node: DOMNode + // box: Object + // hash with optional "w", and "h" properties for "width", and "height" + // respectively. All specified properties should have numeric values in whole pixels. + // computedStyle: Object? + // This parameter accepts computed styles object. + // If this parameter is omitted, the functions will call + // dojo.getComputedStyle to get one. It is a better way, calling + // dojo.computedStyle once, and then pass the reference to this + // computedStyle parameter. Wherever possible, reuse the returned + // object of dojo/dom-style.getComputedStyle(). + + node = dom.byId(node); + var w = box.w, h = box.h; + if(usesBorderBox(node)){ + var pb = geom.getPadBorderExtents(node, computedStyle); + if(w >= 0){ + w += pb.w; + } + if(h >= 0){ + h += pb.h; + } + } + setBox(node, NaN, NaN, w, h); + }; + + var nilExtents = {l: 0, t: 0, w: 0, h: 0}; + + geom.setMarginBox = function setMarginBox(/*DomNode*/ node, /*Object*/ box, /*Object*/ computedStyle){ + // summary: + // sets the size of the node's margin box and placement + // (left/top), irrespective of box model. Think of it as a + // passthrough to setBox that handles box-model vagaries for + // you. + // node: DOMNode + // box: Object + // hash with optional "l", "t", "w", and "h" properties for "left", "right", "width", and "height" + // respectively. All specified properties should have numeric values in whole pixels. + // computedStyle: Object? + // This parameter accepts computed styles object. + // If this parameter is omitted, the functions will call + // dojo.getComputedStyle to get one. It is a better way, calling + // dojo.computedStyle once, and then pass the reference to this + // computedStyle parameter. Wherever possible, reuse the returned + // object of dojo/dom-style.getComputedStyle(). + + node = dom.byId(node); + var s = computedStyle || style.getComputedStyle(node), w = box.w, h = box.h, + // Some elements have special padding, margin, and box-model settings. + // To use box functions you may need to set padding, margin explicitly. + // Controlling box-model is harder, in a pinch you might set dojo/dom-geometry.boxModel. + pb = usesBorderBox(node) ? nilExtents : geom.getPadBorderExtents(node, s), + mb = geom.getMarginExtents(node, s); + if(has("webkit")){ + // on Safari (3.1.2), button nodes with no explicit size have a default margin + // setting an explicit size eliminates the margin. + // We have to swizzle the width to get correct margin reading. + if(isButtonTag(node)){ + var ns = node.style; + if(w >= 0 && !ns.width){ + ns.width = "4px"; + } + if(h >= 0 && !ns.height){ + ns.height = "4px"; + } + } + } + if(w >= 0){ + w = Math.max(w - pb.w - mb.w, 0); + } + if(h >= 0){ + h = Math.max(h - pb.h - mb.h, 0); + } + setBox(node, box.l, box.t, w, h); + }; + + // ============================= + // Positioning + // ============================= + + geom.isBodyLtr = function isBodyLtr(/*Document?*/ doc){ + // summary: + // Returns true if the current language is left-to-right, and false otherwise. + // doc: Document? + // Optional document to query. If unspecified, use win.doc. + // returns: Boolean + + doc = doc || win.doc; + return (win.body(doc).dir || doc.documentElement.dir || "ltr").toLowerCase() == "ltr"; // Boolean + }; + + geom.docScroll = function docScroll(/*Document?*/ doc){ + // summary: + // Returns an object with {node, x, y} with corresponding offsets. + // doc: Document? + // Optional document to query. If unspecified, use win.doc. + // returns: Object + + doc = doc || win.doc; + var node = win.doc.parentWindow || win.doc.defaultView; // use UI window, not dojo.global window. TODO: use dojo/window::get() except for circular dependency problem + return "pageXOffset" in node ? {x: node.pageXOffset, y: node.pageYOffset } : + (node = has("quirks") ? win.body(doc) : doc.documentElement) && + {x: geom.fixIeBiDiScrollLeft(node.scrollLeft || 0, doc), y: node.scrollTop || 0 }; + }; + + if(has("ie")){ + geom.getIeDocumentElementOffset = function getIeDocumentElementOffset(/*Document?*/ doc){ + // summary: + // returns the offset in x and y from the document body to the + // visual edge of the page for IE + // doc: Document? + // Optional document to query. If unspecified, use win.doc. + // description: + // The following values in IE contain an offset: + // | event.clientX + // | event.clientY + // | node.getBoundingClientRect().left + // | node.getBoundingClientRect().top + // But other position related values do not contain this offset, + // such as node.offsetLeft, node.offsetTop, node.style.left and + // node.style.top. The offset is always (2, 2) in LTR direction. + // When the body is in RTL direction, the offset counts the width + // of left scroll bar's width. This function computes the actual + // offset. + + //NOTE: assumes we're being called in an IE browser + + doc = doc || win.doc; + var de = doc.documentElement; // only deal with HTML element here, position() handles body/quirks + + if(has("ie") < 8){ + var r = de.getBoundingClientRect(), // works well for IE6+ + l = r.left, t = r.top; + if(has("ie") < 7){ + l += de.clientLeft; // scrollbar size in strict/RTL, or, + t += de.clientTop; // HTML border size in strict + } + return { + x: l < 0 ? 0 : l, // FRAME element border size can lead to inaccurate negative values + y: t < 0 ? 0 : t + }; + }else{ + return { + x: 0, + y: 0 + }; + } + }; + } + + geom.fixIeBiDiScrollLeft = function fixIeBiDiScrollLeft(/*Integer*/ scrollLeft, /*Document?*/ doc){ + // summary: + // In RTL direction, scrollLeft should be a negative value, but IE + // returns a positive one. All codes using documentElement.scrollLeft + // must call this function to fix this error, otherwise the position + // will offset to right when there is a horizontal scrollbar. + // scrollLeft: Number + // doc: Document? + // Optional document to query. If unspecified, use win.doc. + // returns: Number + + // In RTL direction, scrollLeft should be a negative value, but IE + // returns a positive one. All codes using documentElement.scrollLeft + // must call this function to fix this error, otherwise the position + // will offset to right when there is a horizontal scrollbar. + + doc = doc || win.doc; + var ie = has("ie"); + if(ie && !geom.isBodyLtr(doc)){ + var qk = has("quirks"), + de = qk ? win.body(doc) : doc.documentElement, + pwin = win.global; // TODO: use winUtils.get(doc) after resolving circular dependency b/w dom-geometry.js and dojo/window.js + if(ie == 6 && !qk && pwin.frameElement && de.scrollHeight > de.clientHeight){ + scrollLeft += de.clientLeft; // workaround ie6+strict+rtl+iframe+vertical-scrollbar bug where clientWidth is too small by clientLeft pixels + } + return (ie < 8 || qk) ? (scrollLeft + de.clientWidth - de.scrollWidth) : -scrollLeft; // Integer + } + return scrollLeft; // Integer + }; + + geom.position = function(/*DomNode*/ node, /*Boolean?*/ includeScroll){ + // summary: + // Gets the position and size of the passed element relative to + // the viewport (if includeScroll==false), or relative to the + // document root (if includeScroll==true). + // + // description: + // Returns an object of the form: + // `{ x: 100, y: 300, w: 20, h: 15 }`. + // If includeScroll==true, the x and y values will include any + // document offsets that may affect the position relative to the + // viewport. + // Uses the border-box model (inclusive of border and padding but + // not margin). Does not act as a setter. + // node: DOMNode|String + // includeScroll: Boolean? + // returns: Object + + node = dom.byId(node); + var db = win.body(node.ownerDocument), + ret = node.getBoundingClientRect(); + ret = {x: ret.left, y: ret.top, w: ret.right - ret.left, h: ret.bottom - ret.top}; + + if(has("ie")){ + // On IE there's a 2px offset that we need to adjust for, see dojo.getIeDocumentElementOffset() + var offset = geom.getIeDocumentElementOffset(node.ownerDocument); + + // fixes the position in IE, quirks mode + ret.x -= offset.x + (has("quirks") ? db.clientLeft + db.offsetLeft : 0); + ret.y -= offset.y + (has("quirks") ? db.clientTop + db.offsetTop : 0); + } + + // account for document scrolling + // if offsetParent is used, ret value already includes scroll position + // so we may have to actually remove that value if !includeScroll + if(includeScroll){ + var scroll = geom.docScroll(node.ownerDocument); + ret.x += scroll.x; + ret.y += scroll.y; + } + + return ret; // Object + }; + + // random "private" functions wildly used throughout the toolkit + + geom.getMarginSize = function getMarginSize(/*DomNode*/ node, /*Object*/ computedStyle){ + // summary: + // returns an object that encodes the width and height of + // the node's margin box + // node: DOMNode|String + // computedStyle: Object? + // This parameter accepts computed styles object. + // If this parameter is omitted, the functions will call + // dojo.getComputedStyle to get one. It is a better way, calling + // dojo.computedStyle once, and then pass the reference to this + // computedStyle parameter. Wherever possible, reuse the returned + // object of dojo/dom-style.getComputedStyle(). + + node = dom.byId(node); + var me = geom.getMarginExtents(node, computedStyle || style.getComputedStyle(node)); + var size = node.getBoundingClientRect(); + return { + w: (size.right - size.left) + me.w, + h: (size.bottom - size.top) + me.h + }; + }; + + geom.normalizeEvent = function(event){ + // summary: + // Normalizes the geometry of a DOM event, normalizing the pageX, pageY, + // offsetX, offsetY, layerX, and layerX properties + // event: Object + if(!("layerX" in event)){ + event.layerX = event.offsetX; + event.layerY = event.offsetY; + } + if(!has("dom-addeventlistener")){ + // old IE version + // FIXME: scroll position query is duped from dojo.html to + // avoid dependency on that entire module. Now that HTML is in + // Base, we should convert back to something similar there. + var se = event.target; + var doc = (se && se.ownerDocument) || document; + // DO NOT replace the following to use dojo.body(), in IE, document.documentElement should be used + // here rather than document.body + var docBody = has("quirks") ? doc.body : doc.documentElement; + var offset = geom.getIeDocumentElementOffset(doc); + event.pageX = event.clientX + geom.fixIeBiDiScrollLeft(docBody.scrollLeft || 0, doc) - offset.x; + event.pageY = event.clientY + (docBody.scrollTop || 0) - offset.y; + } + }; + + // TODO: evaluate separate getters/setters for position and sizes? + + return geom; +}); + +}, +'dojo/dom-prop':function(){ +define(["exports", "./_base/kernel", "./sniff", "./_base/lang", "./dom", "./dom-style", "./dom-construct", "./_base/connect"], + function(exports, dojo, has, lang, dom, style, ctr, conn){ + // module: + // dojo/dom-prop + // summary: + // This module defines the core dojo DOM properties API. + // Indirectly depends on dojo.empty() and dojo.toDom(). + + // TODOC: summary not showing up in output, see https://github.com/csnover/js-doc-parse/issues/42 + + // ============================= + // Element properties Functions + // ============================= + + // helper to connect events + var _evtHdlrMap = {}, _ctr = 0, _attrId = dojo._scopeName + "attrid"; + + exports.names = { + // properties renamed to avoid clashes with reserved words + "class": "className", + "for": "htmlFor", + // properties written as camelCase + tabindex: "tabIndex", + readonly: "readOnly", + colspan: "colSpan", + frameborder: "frameBorder", + rowspan: "rowSpan", + valuetype: "valueType" + }; + + exports.get = function getProp(/*DOMNode|String*/ node, /*String*/ name){ + // summary: + // Gets a property on an HTML element. + // description: + // Handles normalized getting of properties on DOM nodes. + // + // node: DOMNode|String + // id or reference to the element to get the property on + // name: String + // the name of the property to get. + // returns: + // the value of the requested property or its default value + // + // example: + // | // get the current value of the "foo" property on a node + // | dojo.getProp(dojo.byId("nodeId"), "foo"); + // | // or we can just pass the id: + // | dojo.getProp("nodeId", "foo"); + + node = dom.byId(node); + var lc = name.toLowerCase(), propName = exports.names[lc] || name; + return node[propName]; // Anything + }; + + exports.set = function setProp(/*DOMNode|String*/ node, /*String|Object*/ name, /*String?*/ value){ + // summary: + // Sets a property on an HTML element. + // description: + // Handles normalized setting of properties on DOM nodes. + // + // When passing functions as values, note that they will not be + // directly assigned to slots on the node, but rather the default + // behavior will be removed and the new behavior will be added + // using `dojo.connect()`, meaning that event handler properties + // will be normalized and that some caveats with regards to + // non-standard behaviors for onsubmit apply. Namely that you + // should cancel form submission using `dojo.stopEvent()` on the + // passed event object instead of returning a boolean value from + // the handler itself. + // node: DOMNode|String + // id or reference to the element to set the property on + // name: String|Object + // the name of the property to set, or a hash object to set + // multiple properties at once. + // value: String? + // The value to set for the property + // returns: + // the DOM node + // + // example: + // | // use prop() to set the tab index + // | dojo.setProp("nodeId", "tabIndex", 3); + // | + // + // example: + // Set multiple values at once, including event handlers: + // | dojo.setProp("formId", { + // | "foo": "bar", + // | "tabIndex": -1, + // | "method": "POST", + // | "onsubmit": function(e){ + // | // stop submitting the form. Note that the IE behavior + // | // of returning true or false will have no effect here + // | // since our handler is connect()ed to the built-in + // | // onsubmit behavior and so we need to use + // | // dojo.stopEvent() to ensure that the submission + // | // doesn't proceed. + // | dojo.stopEvent(e); + // | + // | // submit the form with Ajax + // | dojo.xhrPost({ form: "formId" }); + // | } + // | }); + // + // example: + // Style is s special case: Only set with an object hash of styles + // | dojo.setProp("someNode",{ + // | id:"bar", + // | style:{ + // | width:"200px", height:"100px", color:"#000" + // | } + // | }); + // + // example: + // Again, only set style as an object hash of styles: + // | var obj = { color:"#fff", backgroundColor:"#000" }; + // | dojo.setProp("someNode", "style", obj); + // | + // | // though shorter to use `dojo.style()` in this case: + // | dojo.style("someNode", obj); + + node = dom.byId(node); + var l = arguments.length; + if(l == 2 && typeof name != "string"){ // inline'd type check + // the object form of setter: the 2nd argument is a dictionary + for(var x in name){ + exports.set(node, x, name[x]); + } + return node; // DomNode + } + var lc = name.toLowerCase(), propName = exports.names[lc] || name; + if(propName == "style" && typeof value != "string"){ // inline'd type check + // special case: setting a style + style.set(node, value); + return node; // DomNode + } + if(propName == "innerHTML"){ + // special case: assigning HTML + // the hash lists elements with read-only innerHTML on IE + if(has("ie") && node.tagName.toLowerCase() in {col: 1, colgroup: 1, + table: 1, tbody: 1, tfoot: 1, thead: 1, tr: 1, title: 1}){ + ctr.empty(node); + node.appendChild(ctr.toDom(value, node.ownerDocument)); + }else{ + node[propName] = value; + } + return node; // DomNode + } + if(lang.isFunction(value)){ + // special case: assigning an event handler + // clobber if we can + var attrId = node[_attrId]; + if(!attrId){ + attrId = _ctr++; + node[_attrId] = attrId; + } + if(!_evtHdlrMap[attrId]){ + _evtHdlrMap[attrId] = {}; + } + var h = _evtHdlrMap[attrId][propName]; + if(h){ + //h.remove(); + conn.disconnect(h); + }else{ + try{ + delete node[propName]; + }catch(e){} + } + // ensure that event objects are normalized, etc. + if(value){ + //_evtHdlrMap[attrId][propName] = on(node, propName, value); + _evtHdlrMap[attrId][propName] = conn.connect(node, propName, value); + }else{ + node[propName] = null; + } + return node; // DomNode + } + node[propName] = value; + return node; // DomNode + }; +}); + +}, +'dojo/when':function(){ +define([ + "./Deferred", + "./promise/Promise" +], function(Deferred, Promise){ + "use strict"; + + // module: + // dojo/when + + return function when(valueOrPromise, callback, errback, progback){ + // summary: + // Transparently applies callbacks to values and/or promises. + // description: + // Accepts promises but also transparently handles non-promises. If no + // callbacks are provided returns a promise, regardless of the initial + // value. Foreign promises are converted. + // + // If callbacks are provided and the initial value is not a promise, + // the callback is executed immediately with no error handling. Returns + // a promise if the initial value is a promise, or the result of the + // callback otherwise. + // valueOrPromise: + // Either a regular value or an object with a `then()` method that + // follows the Promises/A specification. + // callback: Function? + // Callback to be invoked when the promise is resolved, or a non-promise + // is received. + // errback: Function? + // Callback to be invoked when the promise is rejected. + // progback: Function? + // Callback to be invoked when the promise emits a progress update. + // returns: dojo/promise/Promise + // Promise, or if a callback is provided, the result of the callback. + + var receivedPromise = valueOrPromise && typeof valueOrPromise.then === "function"; + var nativePromise = receivedPromise && valueOrPromise instanceof Promise; + + if(!receivedPromise){ + if(callback){ + return callback(valueOrPromise); + }else{ + return new Deferred().resolve(valueOrPromise); + } + }else if(!nativePromise){ + var deferred = new Deferred(valueOrPromise.cancel); + valueOrPromise.then(deferred.resolve, deferred.reject, deferred.progress); + valueOrPromise = deferred.promise; + } + + if(callback || errback || progback){ + return valueOrPromise.then(callback, errback, progback); + } + return valueOrPromise; + }; +}); + +}, +'dojo/dom-attr':function(){ +define(["exports", "./sniff", "./_base/lang", "./dom", "./dom-style", "./dom-prop"], + function(exports, has, lang, dom, style, prop){ + // module: + // dojo/dom-attr + // summary: + // This module defines the core dojo DOM attributes API. + + // TODOC: summary not showing up in output see https://github.com/csnover/js-doc-parse/issues/42 + + // ============================= + // Element attribute Functions + // ============================= + + // This module will be obsolete soon. Use dojo/prop instead. + + // dojo.attr() should conform to http://www.w3.org/TR/DOM-Level-2-Core/ + + // attribute-related functions (to be obsolete soon) + + var forcePropNames = { + innerHTML: 1, + className: 1, + htmlFor: has("ie"), + value: 1 + }, + attrNames = { + // original attribute names + classname: "class", + htmlfor: "for", + // for IE + tabindex: "tabIndex", + readonly: "readOnly" + }; + + function _hasAttr(node, name){ + var attr = node.getAttributeNode && node.getAttributeNode(name); + return attr && attr.specified; // Boolean + } + + // There is a difference in the presence of certain properties and their default values + // between browsers. For example, on IE "disabled" is present on all elements, + // but it is value is "false"; "tabIndex" of
                                returns 0 by default on IE, yet other browsers + // can return -1. + + exports.has = function hasAttr(/*DOMNode|String*/ node, /*String*/ name){ + // summary: + // Returns true if the requested attribute is specified on the + // given element, and false otherwise. + // node: DOMNode|String + // id or reference to the element to check + // name: String + // the name of the attribute + // returns: Boolean + // true if the requested attribute is specified on the + // given element, and false otherwise + + var lc = name.toLowerCase(); + return forcePropNames[prop.names[lc] || name] || _hasAttr(dom.byId(node), attrNames[lc] || name); // Boolean + }; + + exports.get = function getAttr(/*DOMNode|String*/ node, /*String*/ name){ + // summary: + // Gets an attribute on an HTML element. + // description: + // Handles normalized getting of attributes on DOM Nodes. + // node: DOMNode|String + // id or reference to the element to get the attribute on + // name: String + // the name of the attribute to get. + // returns: + // the value of the requested attribute or null if that attribute does not have a specified or + // default value; + // + // example: + // | // get the current value of the "foo" attribute on a node + // | dojo.getAttr(dojo.byId("nodeId"), "foo"); + // | // or we can just pass the id: + // | dojo.getAttr("nodeId", "foo"); + + node = dom.byId(node); + var lc = name.toLowerCase(), + propName = prop.names[lc] || name, + forceProp = forcePropNames[propName], + value = node[propName]; // should we access this attribute via a property or via getAttribute()? + + if(forceProp && typeof value != "undefined"){ + // node's property + return value; // Anything + } + if(propName != "href" && (typeof value == "boolean" || lang.isFunction(value))){ + // node's property + return value; // Anything + } + // node's attribute + // we need _hasAttr() here to guard against IE returning a default value + var attrName = attrNames[lc] || name; + return _hasAttr(node, attrName) ? node.getAttribute(attrName) : null; // Anything + }; + + exports.set = function setAttr(/*DOMNode|String*/ node, /*String|Object*/ name, /*String?*/ value){ + // summary: + // Sets an attribute on an HTML element. + // description: + // Handles normalized setting of attributes on DOM Nodes. + // + // When passing functions as values, note that they will not be + // directly assigned to slots on the node, but rather the default + // behavior will be removed and the new behavior will be added + // using `dojo.connect()`, meaning that event handler properties + // will be normalized and that some caveats with regards to + // non-standard behaviors for onsubmit apply. Namely that you + // should cancel form submission using `dojo.stopEvent()` on the + // passed event object instead of returning a boolean value from + // the handler itself. + // node: DOMNode|String + // id or reference to the element to set the attribute on + // name: String|Object + // the name of the attribute to set, or a hash of key-value pairs to set. + // value: String? + // the value to set for the attribute, if the name is a string. + // returns: + // the DOM node + // + // example: + // | // use attr() to set the tab index + // | dojo.setAttr("nodeId", "tabIndex", 3); + // + // example: + // Set multiple values at once, including event handlers: + // | dojo.setAttr("formId", { + // | "foo": "bar", + // | "tabIndex": -1, + // | "method": "POST", + // | "onsubmit": function(e){ + // | // stop submitting the form. Note that the IE behavior + // | // of returning true or false will have no effect here + // | // since our handler is connect()ed to the built-in + // | // onsubmit behavior and so we need to use + // | // dojo.stopEvent() to ensure that the submission + // | // doesn't proceed. + // | dojo.stopEvent(e); + // | + // | // submit the form with Ajax + // | dojo.xhrPost({ form: "formId" }); + // | } + // | }); + // + // example: + // Style is s special case: Only set with an object hash of styles + // | dojo.setAttr("someNode",{ + // | id:"bar", + // | style:{ + // | width:"200px", height:"100px", color:"#000" + // | } + // | }); + // + // example: + // Again, only set style as an object hash of styles: + // | var obj = { color:"#fff", backgroundColor:"#000" }; + // | dojo.setAttr("someNode", "style", obj); + // | + // | // though shorter to use `dojo.style()` in this case: + // | dojo.setStyle("someNode", obj); + + node = dom.byId(node); + if(arguments.length == 2){ // inline'd type check + // the object form of setter: the 2nd argument is a dictionary + for(var x in name){ + exports.set(node, x, name[x]); + } + return node; // DomNode + } + var lc = name.toLowerCase(), + propName = prop.names[lc] || name, + forceProp = forcePropNames[propName]; + if(propName == "style" && typeof value != "string"){ // inline'd type check + // special case: setting a style + style.set(node, value); + return node; // DomNode + } + if(forceProp || typeof value == "boolean" || lang.isFunction(value)){ + return prop.set(node, name, value); + } + // node's attribute + node.setAttribute(attrNames[lc] || name, value); + return node; // DomNode + }; + + exports.remove = function removeAttr(/*DOMNode|String*/ node, /*String*/ name){ + // summary: + // Removes an attribute from an HTML element. + // node: DOMNode|String + // id or reference to the element to remove the attribute from + // name: String + // the name of the attribute to remove + + dom.byId(node).removeAttribute(attrNames[name.toLowerCase()] || name); + }; + + exports.getNodeProp = function getNodeProp(/*DomNode|String*/ node, /*String*/ name){ + // summary: + // Returns an effective value of a property or an attribute. + // node: DOMNode|String + // id or reference to the element to remove the attribute from + // name: String + // the name of the attribute + // returns: + // the value of the attribute + + node = dom.byId(node); + var lc = name.toLowerCase(), propName = prop.names[lc] || name; + if((propName in node) && propName != "href"){ + // node's property + return node[propName]; // Anything + } + // node's attribute + var attrName = attrNames[lc] || name; + return _hasAttr(node, attrName) ? node.getAttribute(attrName) : null; // Anything + }; +}); + +}, +'dojo/dom-construct':function(){ +define(["exports", "./_base/kernel", "./sniff", "./_base/window", "./dom", "./dom-attr", "./on"], + function(exports, dojo, has, win, dom, attr, on){ + // module: + // dojo/dom-construct + // summary: + // This module defines the core dojo DOM construction API. + + // TODOC: summary not showing up in output, see https://github.com/csnover/js-doc-parse/issues/42 + + // support stuff for toDom() + var tagWrap = { + option: ["select"], + tbody: ["table"], + thead: ["table"], + tfoot: ["table"], + tr: ["table", "tbody"], + td: ["table", "tbody", "tr"], + th: ["table", "thead", "tr"], + legend: ["fieldset"], + caption: ["table"], + colgroup: ["table"], + col: ["table", "colgroup"], + li: ["ul"] + }, + reTag = /<\s*([\w\:]+)/, + masterNode = {}, masterNum = 0, + masterName = "__" + dojo._scopeName + "ToDomId"; + + // generate start/end tag strings to use + // for the injection for each special tag wrap case. + for(var param in tagWrap){ + if(tagWrap.hasOwnProperty(param)){ + var tw = tagWrap[param]; + tw.pre = param == "option" ? '` to create: submit, reset or button. + */ + type: 'button', + + /** + * @cfg {String} clickEvent + * The DOM event that will fire the handler of the button. This can be any valid event name (dblclick, contextmenu). + */ + clickEvent: 'click', + + /** + * @cfg {Boolean} preventDefault + * True to prevent the default action when the {@link #clickEvent} is processed. + */ + preventDefault: true, + + /** + * @cfg {Boolean} handleMouseEvents + * False to disable visual cues on mouseover, mouseout and mousedown. + */ + handleMouseEvents: true, + + /** + * @cfg {String} tooltipType + * The type of tooltip to use. Either 'qtip' for QuickTips or 'title' for title attribute. + */ + tooltipType: 'qtip', + + /** + * @cfg {String} [baseCls='x-btn'] + * The base CSS class to add to all buttons. + */ + baseCls: Ext.baseCSSPrefix + 'btn', + + /** + * @cfg {String} pressedCls + * The CSS class to add to a button when it is in the pressed state. + */ + pressedCls: 'pressed', + + /** + * @cfg {String} overCls + * The CSS class to add to a button when it is in the over (hovered) state. + */ + overCls: 'over', + + /** + * @cfg {String} focusCls + * The CSS class to add to a button when it is in the focussed state. + */ + focusCls: 'focus', + + /** + * @cfg {String} menuActiveCls + * The CSS class to add to a button when it's menu is active. + */ + menuActiveCls: 'menu-active', + + /** + * @cfg {String} href + * The URL to open when the button is clicked. Specifying this config causes the Button to be + * rendered with an anchor (An `` element) as its active element, referencing the specified URL. + * + * This is better than specifying a click handler of + * + * function() { window.location = "http://www.sencha.com" } + * + * because the UI will provide meaningful hints to the user as to what to expect upon clicking + * the button, and will also allow the user to open in a new tab or window, bookmark or drag the URL, or directly save + * the URL stream to disk. + * + * See also the {@link #hrefTarget} config. + */ + + /** + * @cfg {String} [hrefTarget="_blank"] + * The target attribute to use for the underlying anchor. Only used if the {@link #href} + * property is specified. + */ + hrefTarget: '_blank', + + border: true, + + /** + * @cfg {Object} baseParams + * An object literal of parameters to pass to the url when the {@link #href} property is specified. + */ + + /** + * @cfg {Object} params + * An object literal of parameters to pass to the url when the {@link #href} property is specified. Any params + * override {@link #baseParams}. New params can be set using the {@link #setParams} method. + */ + + childEls: [ + 'btnEl', 'btnWrap', 'btnInnerEl', 'btnIconEl' + ], + + renderTpl: [ + ' class="{splitCls}">', + '', + ' tabIndex="{tabIndex}"', + ' disabled="disabled"', + ' role="link">', + '', + '{text}', + '', + ' style="background-image:url({iconUrl})">', + '', + '', + '', + '', + '', + '', + '', + '' + ], + + /** + * @cfg {String} scale + * The size of the Button. Three values are allowed: + * + * - 'small' - Results in the button element being 16px high. + * - 'medium' - Results in the button element being 24px high. + * - 'large' - Results in the button element being 32px high. + */ + scale: 'small', + + /** + * @private + * An array of allowed scales. + */ + allowedScales: ['small', 'medium', 'large'], + + /** + * @cfg {Object} scope + * The scope (**this** reference) in which the `{@link #handler}` and `{@link #toggleHandler}` is executed. + * Defaults to this Button. + */ + + /** + * @cfg {String} iconAlign + * The side of the Button box to render the icon. Four values are allowed: + * + * - 'top' + * - 'right' + * - 'bottom' + * - 'left' + */ + iconAlign: 'left', + + /** + * @cfg {String} arrowAlign + * The side of the Button box to render the arrow if the button has an associated {@link #cfg-menu}. Two + * values are allowed: + * + * - 'right' + * - 'bottom' + */ + arrowAlign: 'right', + + /** + * @cfg {String} arrowCls + * The className used for the inner arrow element if the button has a menu. + */ + arrowCls: 'arrow', + + /** + * @property {Ext.Template} template + * A {@link Ext.Template Template} used to create the Button's DOM structure. + * + * Instances, or subclasses which need a different DOM structure may provide a different template layout in + * conjunction with an implementation of {@link #getTemplateArgs}. + */ + + /** + * @cfg {String} cls + * A CSS class string to apply to the button's main element. + */ + + /** + * @property {Ext.menu.Menu} menu + * The {@link Ext.menu.Menu Menu} object associated with this Button when configured with the {@link #cfg-menu} config + * option. + */ + + maskOnDisable: false, + + /** + * @private + * @property persistentPadding + * The padding spuriously added to a <button> element which must be accounted for in the margins of the innerEl. + * This is calculated at first render time by creating a hidden button and measuring its insides. + */ + persistentPadding: undefined, + + shrinkWrap: 3, + + frame: true, + + // inherit docs + initComponent: function() { + var me = this; + me.callParent(arguments); + + me.addEvents( + /** + * @event click + * Fires when this button is clicked, before the configured {@link #handler} is invoked. Execution of the + * {@link #handler} may be vetoed by returning false to this event. + * @param {Ext.button.Button} this + * @param {Event} e The click event + */ + 'click', + + /** + * @event toggle + * Fires when the 'pressed' state of this button changes (only if enableToggle = true) + * @param {Ext.button.Button} this + * @param {Boolean} pressed + */ + 'toggle', + + /** + * @event mouseover + * Fires when the mouse hovers over the button + * @param {Ext.button.Button} this + * @param {Event} e The event object + */ + 'mouseover', + + /** + * @event mouseout + * Fires when the mouse exits the button + * @param {Ext.button.Button} this + * @param {Event} e The event object + */ + 'mouseout', + + /** + * @event menushow + * If this button has a menu, this event fires when it is shown + * @param {Ext.button.Button} this + * @param {Ext.menu.Menu} menu + */ + 'menushow', + + /** + * @event menuhide + * If this button has a menu, this event fires when it is hidden + * @param {Ext.button.Button} this + * @param {Ext.menu.Menu} menu + */ + 'menuhide', + + /** + * @event menutriggerover + * If this button has a menu, this event fires when the mouse enters the menu triggering element + * @param {Ext.button.Button} this + * @param {Ext.menu.Menu} menu + * @param {Event} e + */ + 'menutriggerover', + + /** + * @event menutriggerout + * If this button has a menu, this event fires when the mouse leaves the menu triggering element + * @param {Ext.button.Button} this + * @param {Ext.menu.Menu} menu + * @param {Event} e + */ + 'menutriggerout' + ); + + if (me.menu) { + // Flag that we'll have a splitCls + me.split = true; + + // retrieve menu by id or instantiate instance if needed + me.menu = Ext.menu.Manager.get(me.menu); + me.menu.ownerButton = me; + } + + // Accept url as a synonym for href + if (me.url) { + me.href = me.url; + } + + // preventDefault defaults to false for links + if (me.href && !me.hasOwnProperty('preventDefault')) { + me.preventDefault = false; + } + + if (Ext.isString(me.toggleGroup) && me.toggleGroup !== '') { + me.enableToggle = true; + } + + if (me.html && !me.text) { + me.text = me.html; + delete me.html; + } + + }, + + // inherit docs + getActionEl: function() { + return this.btnEl; + }, + + // inherit docs + getFocusEl: function() { + return this.useElForFocus ? this.el : this.btnEl; + }, + + // Buttons add the focus class to the *outermost element*, not the focusEl! + onFocus: function(e) { + var me = this; + + // Set this flag, so that when AbstractComponent's onFocus gets the focusEl to add the focusCls + // to, it will get the encapsulating element - that's what the CSS rules for Button need right now + me.useElForFocus = true; + me.callParent(arguments); + me.useElForFocus = false; + }, + + // See comments in onFocus + onBlur : function(e) { + this.useElForFocus = true; + this.callParent(arguments); + this.useElForFocus = false; + }, + + // See comments in onFocus + onDisable: function(){ + this.useElForFocus = true; + this.callParent(arguments); + this.useElForFocus = false; + }, + + // private + setComponentCls: function() { + var me = this, + cls = me.getComponentCls(); + + if (!Ext.isEmpty(me.oldCls)) { + me.removeClsWithUI(me.oldCls); + me.removeClsWithUI(me.pressedCls); + } + + me.oldCls = cls; + me.addClsWithUI(cls); + }, + + getComponentCls: function() { + var me = this, + cls = []; + + // Check whether the button has an icon or not, and if it has an icon, what is the alignment + if (me.iconCls || me.icon) { + if (me.text) { + cls.push('icon-text-' + me.iconAlign); + } else { + cls.push('icon'); + } + } else if (me.text) { + cls.push('noicon'); + } + + if (me.pressed) { + cls.push(me.pressedCls); + } + return cls; + }, + + beforeRender: function () { + var me = this; + + me.callParent(); + + // Add all needed classes to the protoElement. + me.oldCls = me.getComponentCls(); + me.addClsWithUI(me.oldCls); + + // Apply the renderData to the template args + Ext.applyIf(me.renderData, me.getTemplateArgs()); + + if (me.scale) { + me.setScale(me.scale); + } + }, + + // private + onRender: function() { + var me = this, + addOnclick, + btn, + btnListeners; + + me.doc = Ext.getDoc(); + me.callParent(arguments); + + // If it is a split button + has a toolip for the arrow + if (me.split && me.arrowTooltip) { + me.arrowEl.dom.setAttribute(me.getTipAttr(), me.arrowTooltip); + } + + // Set btn as a local variable for easy access + btn = me.el; + + if (me.tooltip) { + me.setTooltip(me.tooltip, true); + } + + // Add the mouse events to the button + if (me.handleMouseEvents) { + btnListeners = { + scope: me, + mouseover: me.onMouseOver, + mouseout: me.onMouseOut, + mousedown: me.onMouseDown + }; + if (me.split) { + btnListeners.mousemove = me.onMouseMove; + } + } else { + btnListeners = { + scope: me + }; + } + + // Check if the button has a menu + if (me.menu) { + me.mon(me.menu, { + scope: me, + show: me.onMenuShow, + hide: me.onMenuHide + }); + + me.keyMap = new Ext.util.KeyMap({ + target: me.el, + key: Ext.EventObject.DOWN, + handler: me.onDownKey, + scope: me + }); + } + + // Check if it is a repeat button + if (me.repeat) { + me.mon(new Ext.util.ClickRepeater(btn, Ext.isObject(me.repeat) ? me.repeat: {}), 'click', me.onRepeatClick, me); + } else { + + // If the activation event already has a handler, make a note to add the handler later + if (btnListeners[me.clickEvent]) { + addOnclick = true; + } else { + btnListeners[me.clickEvent] = me.onClick; + } + } + + // Add whatever button listeners we need + me.mon(btn, btnListeners); + + // If the listeners object had an entry for our clickEvent, add a listener now + if (addOnclick) { + me.mon(btn, me.clickEvent, me.onClick, me); + } + + // Register the button in the toggle manager + Ext.ButtonToggleManager.register(me); + }, + + /** + * This method returns an object which provides substitution parameters for the {@link #renderTpl XTemplate} used to + * create this Button's DOM structure. + * + * Instances or subclasses which use a different Template to create a different DOM structure may need to provide + * their own implementation of this method. + * + * @return {Object} Substitution data for a Template. The default implementation which provides data for the default + * {@link #template} returns an Object containing the following properties: + * @return {String} return.type The `
                                -
                                -

                                Bordered with thead and caption

                                - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
                                Table caption
                                123
                                123
                                123
                                123
                                369
                                -

                                Bordered with rowspan and colspan

                                - - - - - - - - - - - - - - - - - - - - - - - - - - -
                                123
                                1 and 23
                                123
                                13
                                2 and 3
                                -
                                - - - -

                                Grid sizing

                                -
                                -
                                - - - - - - - - - - - - - - - - - - - - - - - - - - -
                                123
                                1 and 23
                                123
                                13
                                2 and 3
                                -
                                -
                                - -

                                Nesting and striping

                                - - - - - - - - - - - -
                                Test
                                - - - - - - - - - - - - - - - - - - - - - -
                                TestTest
                                - test - - test -
                                - test - - test -
                                - test - - test -
                                -
                                - -

                                Fluid grid sizing

                                -
                                -
                                - - - - - - - - - - - - - - - - - - - - - - - - - - -
                                123
                                1 and 23
                                123
                                13
                                2 and 3
                                -
                                -
                                - - - - - - - -

                                Buttons and button groups

                                -
                                - - - -
                                - -

                                Horizontal form errors

                                -
                                -
                                - -
                                - - Please correct the error -
                                -
                                -
                                - -
                                -
                                -

                                Prepend and append on inputs

                                -
                                -
                                -
                                - @ - -
                                -
                                -
                                -
                                - - @ -
                                -
                                -
                                -
                                - $ - - .00 -
                                -
                                -
                                -
                                -
                                -

                                Prepend and append with uneditable

                                -
                                -
                                - $ - Some value here -
                                -
                                - Some value here - .00 -
                                -
                                - $ - Some value here - .00 -
                                -
                                -
                                -
                                -

                                Prepend with type="submit"

                                - -
                                - - -
                                -
                                - - - -
                                -
                                -
                                - -

                                Fluid prepended and appended inputs

                                -
                                -
                                -
                                -
                                -
                                - @ -
                                -
                                -
                                -
                                - @ -
                                -
                                -
                                -
                                - $.00 -
                                -
                                -
                                -
                                -
                                - -

                                Fixed row with inputs

                                -

                                Inputs should not extend past the light red background, set on their parent, a .span* column.

                                - -
                                -
                                -
                                - -
                                -
                                -
                                -
                                - -
                                -
                                -
                                -
                                - -
                                -
                                -
                                -
                                - -
                                -
                                -
                                -
                                - -
                                -
                                -
                                -
                                - -
                                -
                                -
                                -
                                - -
                                -
                                -
                                -
                                - -
                                -
                                -
                                -
                                - -
                                -
                                -
                                -
                                - -
                                -
                                -
                                -
                                - -
                                -
                                -
                                -
                                - -
                                -
                                -
                                -
                                - -

                                Fluid row with inputs

                                -

                                Inputs should not extend past the light red background, set on their parent, a .span* column.

                                -
                                -
                                -
                                - -
                                -
                                -
                                -
                                - -
                                -
                                -
                                -
                                - -
                                -
                                -
                                -
                                - -
                                -
                                -
                                -
                                - -
                                -
                                -
                                -
                                - -
                                -
                                -
                                -
                                - -
                                -
                                -
                                -
                                - -
                                -
                                -
                                -
                                - -
                                -
                                -
                                -
                                - -
                                -
                                -
                                -
                                - -
                                -
                                -
                                -
                                - -
                                -
                                -
                                - -
                                - -

                                Inline form in fluid row

                                - -
                                -
                                -
                                - - - - -
                                -
                                -
                                - - -
                                - - -

                                Fluid textarea at .span12

                                -
                                -
                                - -
                                -
                                - - -
                                - - -

                                Selects

                                -
                                - -
                                - - -
                                - - - - - - - - -

                                Dropdown link with hash URL

                                - - -

                                Dropdown link with custom URL and data-target

                                - - -

                                Dropdown on a button

                                - - -
                                - - - - - - -

                                Default thumbnails (no grid sizing)

                                -
                                  -
                                • - -
                                • -
                                • - -
                                • -
                                • - -
                                • -
                                • - -
                                • -
                                - - - -

                                Standard grid sizing

                                - - -

                                Fluid thumbnails

                                -
                                -
                                - -
                                -
                                - - - - - - - -
                                - -
                                -
                                -

                                I'm in Section 1.

                                - -
                                - -
                                -
                                -

                                I'm in Section 1.1.

                                -
                                -
                                -

                                I'm in Section 1.2.

                                -
                                -
                                -

                                I'm in Section 1.3.

                                -
                                -
                                -
                                -
                                -
                                -

                                Howdy, I'm in Section 2.

                                -
                                -
                                -

                                What up girl, this is Section 3.

                                -
                                -
                                -
                                - -
                                - - - - - - -
                                -
                                -

                                Inline label

                                -

                                Cras justo odio, dapibus ac facilisis in, egestas eget quam. Maecenas sed diam Label name eget risus varius blandit sit amet non magna. Fusce .class-name dapibus, tellus ac cursus commodo, tortor mauris condimentum nibh, ut fermentum massa justo sit amet risus.

                                -
                                -
                                -
                                - - Hey! Read this. -
                                -
                                -
                                - - -
                                -
                                - -
                                - - - - - - - - - - - - - -
                                - Maecenas faucibus mollis interdum. Nulla vitae elit libero, a pharetra augue. Donec ullamcorper nulla non metus auctor fringilla. Fusce dapibus, tellus ac cursus commodo, tortor mauris condimentum nibh, ut fermentum massa justo sit amet risus. - -
                                - - - - -
                                -
                                - -

                                Mini buttons: text and icon

                                -
                                - - -
                                - -
                                - - - - - - - -

                                Visible on...

                                -
                                  -
                                • Phone✔ Phone
                                • -
                                • Tablet✔ Tablet
                                • -
                                • Desktop✔ Desktop
                                • -
                                -
                                  -
                                • Phone + Tablet✔ Phone + Tablet
                                • -
                                • Tablet + Desktop✔ Tablet + Desktop
                                • -
                                • All✔ All
                                • -
                                - -

                                Hidden on...

                                -
                                  -
                                • Phone✔ Phone
                                • -
                                • Tablet✔ Tablet
                                • -
                                • Desktop✔ Desktop
                                • -
                                -
                                  -
                                • Phone + Tablet✔ Phone + Tablet
                                • -
                                • Tablet + Desktop✔ Tablet + Desktop
                                • -
                                • All✔ All
                                • -
                                - - - - - - - -

                                Horizontal

                                -
                                - -

                                Vertical

                                -
                                - -

                                Directional

                                -
                                - -

                                Three colors

                                -
                                - -

                                Radial

                                -
                                - -

                                Striped

                                -
                                - -

                                Horizontal three colors

                                -
                                - - - - - -

                                Alert default

                                -
                                - - Alert! Best check yourself, you're not looking too good. -
                                -
                                - -

                                Alert! Best check yourself, you're not looking too good.

                                -
                                - -

                                Success

                                -
                                - - Success! Best check yourself, you're not looking too good. -
                                -
                                - -

                                Success! Best check yourself, you're not looking too good.

                                -
                                - -

                                Info

                                -
                                - - Info! Best check yourself, you're not looking too good. -
                                -
                                - -

                                Info! Best check yourself, you're not looking too good.

                                -
                                - -

                                Warning

                                -
                                - - Warning! Best check yourself, you're not looking too good. -
                                -
                                - -

                                Warning! Best check yourself, you're not looking too good.

                                -
                                - -

                                Error

                                -
                                - - Error! Best check yourself, you're not looking too good. -
                                -
                                - -

                                Error! Best check yourself, you're not looking too good.

                                -
                                - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/sites/all/themes/gui/materiobasetheme/components/bootstrap/less/tests/forms-responsive.html b/sites/all/themes/gui/materiobasetheme/components/bootstrap/less/tests/forms-responsive.html deleted file mode 100644 index c3e208d0..00000000 --- a/sites/all/themes/gui/materiobasetheme/components/bootstrap/less/tests/forms-responsive.html +++ /dev/null @@ -1,71 +0,0 @@ - - - - - Bootstrap, from Twitter - - - - - - - - - - - - - - - - - - - - - - -
                                - - - -

                                Vertical alignment

                                - - - span1 - -

                                Width across elements

                                -
                                - -
                                -
                                - -
                                -
                                - span2 -
                                - - - - -
                                - - - span1 -
                                - -
                                - - - diff --git a/sites/all/themes/gui/materiobasetheme/components/bootstrap/less/tests/forms.html b/sites/all/themes/gui/materiobasetheme/components/bootstrap/less/tests/forms.html deleted file mode 100644 index a63d728a..00000000 --- a/sites/all/themes/gui/materiobasetheme/components/bootstrap/less/tests/forms.html +++ /dev/null @@ -1,179 +0,0 @@ - - - - - Bootstrap, from Twitter - - - - - - - - - - - - - - - - - - - - - - -
                                - - - -
                                -
                                - - - - -
                                - - - - -
                                - - - - -
                                - - - - -
                                - - - - -
                                - - - - -
                                - - - - -
                                - - - - -
                                - - - - -
                                -
                                - - - - -
                                - - - - -
                                - - - - -
                                - - - - -
                                - - - - -
                                - - - - -
                                - - - - -
                                - - - - -
                                - - - - -
                                -
                                - - - - -
                                - - - - -
                                - - - - -
                                - - - - -
                                - - - - -
                                - - - - -
                                - - - - -
                                -
                                - -
                                - - - diff --git a/sites/all/themes/gui/materiobasetheme/components/bootstrap/less/tests/navbar-fixed-top.html b/sites/all/themes/gui/materiobasetheme/components/bootstrap/less/tests/navbar-fixed-top.html deleted file mode 100644 index 2d9a7a71..00000000 --- a/sites/all/themes/gui/materiobasetheme/components/bootstrap/less/tests/navbar-fixed-top.html +++ /dev/null @@ -1,104 +0,0 @@ - - - - - Bootstrap, from Twitter - - - - - - - - - - - - - - - - - - - - - - - - - -
                                - - -
                                -

                                Navbar example

                                -

                                This example is a quick exercise to illustrate how the default, static navbar and fixed to top navbar work. It includes the responsive CSS and HTML, so it also adapts to your viewport and device.

                                -

                                - View navbar docs » -

                                -
                                - -
                                - - - - - - - - - - - - - - - - - - - diff --git a/sites/all/themes/gui/materiobasetheme/components/bootstrap/less/tests/navbar-static-top.html b/sites/all/themes/gui/materiobasetheme/components/bootstrap/less/tests/navbar-static-top.html deleted file mode 100644 index 4bead8ec..00000000 --- a/sites/all/themes/gui/materiobasetheme/components/bootstrap/less/tests/navbar-static-top.html +++ /dev/null @@ -1,107 +0,0 @@ - - - - - Bootstrap, from Twitter - - - - - - - - - - - - - - - - - - - - - - - - - - -
                                - - -
                                -

                                Navbar example

                                -

                                This example is a quick exercise to illustrate how the default, static navbar and fixed to top navbar work. It includes the responsive CSS and HTML, so it also adapts to your viewport and device.

                                -

                                - View navbar docs » -

                                -
                                - -
                                - - - - - - - - - - - - - - - - - - - diff --git a/sites/all/themes/gui/materiobasetheme/components/bootstrap/less/tests/navbar.html b/sites/all/themes/gui/materiobasetheme/components/bootstrap/less/tests/navbar.html deleted file mode 100644 index d5ad4784..00000000 --- a/sites/all/themes/gui/materiobasetheme/components/bootstrap/less/tests/navbar.html +++ /dev/null @@ -1,107 +0,0 @@ - - - - - Bootstrap, from Twitter - - - - - - - - - - - - - - - - - - - - - - -
                                - - - - - -
                                -

                                Navbar example

                                -

                                This example is a quick exercise to illustrate how the default, static navbar and fixed to top navbar work. It includes the responsive CSS and HTML, so it also adapts to your viewport and device.

                                -

                                - View navbar docs » -

                                -
                                - -
                                - - - - - - - - - - - - - - - - - - - diff --git a/sites/all/themes/gui/materiobasetheme/components/bootstrap/less/thumbnails.less b/sites/all/themes/gui/materiobasetheme/components/bootstrap/less/thumbnails.less deleted file mode 100644 index 4fd07d25..00000000 --- a/sites/all/themes/gui/materiobasetheme/components/bootstrap/less/thumbnails.less +++ /dev/null @@ -1,53 +0,0 @@ -// -// Thumbnails -// -------------------------------------------------- - - -// Note: `.thumbnails` and `.thumbnails > li` are overriden in responsive files - -// Make wrapper ul behave like the grid -.thumbnails { - margin-left: -@gridGutterWidth; - list-style: none; - .clearfix(); -} -// Fluid rows have no left margin -.row-fluid .thumbnails { - margin-left: 0; -} - -// Float li to make thumbnails appear in a row -.thumbnails > li { - float: left; // Explicity set the float since we don't require .span* classes - margin-bottom: @baseLineHeight; - margin-left: @gridGutterWidth; -} - -// The actual thumbnail (can be `a` or `div`) -.thumbnail { - display: block; - padding: 4px; - line-height: @baseLineHeight; - border: 1px solid #ddd; - .border-radius(@baseBorderRadius); - .box-shadow(0 1px 3px rgba(0,0,0,.055)); - .transition(all .2s ease-in-out); -} -// Add a hover/focus state for linked versions only -a.thumbnail:hover, -a.thumbnail:focus { - border-color: @linkColor; - .box-shadow(0 1px 4px rgba(0,105,214,.25)); -} - -// Images and captions -.thumbnail > img { - display: block; - max-width: 100%; - margin-left: auto; - margin-right: auto; -} -.thumbnail .caption { - padding: 9px; - color: @gray; -} diff --git a/sites/all/themes/gui/materiobasetheme/components/bootstrap/less/tooltip.less b/sites/all/themes/gui/materiobasetheme/components/bootstrap/less/tooltip.less deleted file mode 100644 index 83d5f2bd..00000000 --- a/sites/all/themes/gui/materiobasetheme/components/bootstrap/less/tooltip.less +++ /dev/null @@ -1,70 +0,0 @@ -// -// Tooltips -// -------------------------------------------------- - - -// Base class -.tooltip { - position: absolute; - z-index: @zindexTooltip; - display: block; - visibility: visible; - font-size: 11px; - line-height: 1.4; - .opacity(0); - &.in { .opacity(80); } - &.top { margin-top: -3px; padding: 5px 0; } - &.right { margin-left: 3px; padding: 0 5px; } - &.bottom { margin-top: 3px; padding: 5px 0; } - &.left { margin-left: -3px; padding: 0 5px; } -} - -// Wrapper for the tooltip content -.tooltip-inner { - max-width: 200px; - padding: 8px; - color: @tooltipColor; - text-align: center; - text-decoration: none; - background-color: @tooltipBackground; - .border-radius(@baseBorderRadius); -} - -// Arrows -.tooltip-arrow { - position: absolute; - width: 0; - height: 0; - border-color: transparent; - border-style: solid; -} -.tooltip { - &.top .tooltip-arrow { - bottom: 0; - left: 50%; - margin-left: -@tooltipArrowWidth; - border-width: @tooltipArrowWidth @tooltipArrowWidth 0; - border-top-color: @tooltipArrowColor; - } - &.right .tooltip-arrow { - top: 50%; - left: 0; - margin-top: -@tooltipArrowWidth; - border-width: @tooltipArrowWidth @tooltipArrowWidth @tooltipArrowWidth 0; - border-right-color: @tooltipArrowColor; - } - &.left .tooltip-arrow { - top: 50%; - right: 0; - margin-top: -@tooltipArrowWidth; - border-width: @tooltipArrowWidth 0 @tooltipArrowWidth @tooltipArrowWidth; - border-left-color: @tooltipArrowColor; - } - &.bottom .tooltip-arrow { - top: 0; - left: 50%; - margin-left: -@tooltipArrowWidth; - border-width: 0 @tooltipArrowWidth @tooltipArrowWidth; - border-bottom-color: @tooltipArrowColor; - } -} diff --git a/sites/all/themes/gui/materiobasetheme/components/bootstrap/less/type.less b/sites/all/themes/gui/materiobasetheme/components/bootstrap/less/type.less deleted file mode 100644 index 337138ac..00000000 --- a/sites/all/themes/gui/materiobasetheme/components/bootstrap/less/type.less +++ /dev/null @@ -1,247 +0,0 @@ -// -// Typography -// -------------------------------------------------- - - -// Body text -// ------------------------- - -p { - margin: 0 0 @baseLineHeight / 2; -} -.lead { - margin-bottom: @baseLineHeight; - font-size: @baseFontSize * 1.5; - font-weight: 200; - line-height: @baseLineHeight * 1.5; -} - - -// Emphasis & misc -// ------------------------- - -// Ex: 14px base font * 85% = about 12px -small { font-size: 85%; } - -strong { font-weight: bold; } -em { font-style: italic; } -cite { font-style: normal; } - -// Utility classes -.muted { color: @grayLight; } -a.muted:hover, -a.muted:focus { color: darken(@grayLight, 10%); } - -.text-warning { color: @warningText; } -a.text-warning:hover, -a.text-warning:focus { color: darken(@warningText, 10%); } - -.text-error { color: @errorText; } -a.text-error:hover, -a.text-error:focus { color: darken(@errorText, 10%); } - -.text-info { color: @infoText; } -a.text-info:hover, -a.text-info:focus { color: darken(@infoText, 10%); } - -.text-success { color: @successText; } -a.text-success:hover, -a.text-success:focus { color: darken(@successText, 10%); } - -.text-left { text-align: left; } -.text-right { text-align: right; } -.text-center { text-align: center; } - - -// Headings -// ------------------------- - -h1, h2, h3, h4, h5, h6 { - margin: (@baseLineHeight / 2) 0; - font-family: @headingsFontFamily; - font-weight: @headingsFontWeight; - line-height: @baseLineHeight; - color: @headingsColor; - text-rendering: optimizelegibility; // Fix the character spacing for headings - small { - font-weight: normal; - line-height: 1; - color: @grayLight; - } -} - -h1, -h2, -h3 { line-height: @baseLineHeight * 2; } - -h1 { font-size: @baseFontSize * 2.75; } // ~38px -h2 { font-size: @baseFontSize * 2.25; } // ~32px -h3 { font-size: @baseFontSize * 1.75; } // ~24px -h4 { font-size: @baseFontSize * 1.25; } // ~18px -h5 { font-size: @baseFontSize; } -h6 { font-size: @baseFontSize * 0.85; } // ~12px - -h1 small { font-size: @baseFontSize * 1.75; } // ~24px -h2 small { font-size: @baseFontSize * 1.25; } // ~18px -h3 small { font-size: @baseFontSize; } -h4 small { font-size: @baseFontSize; } - - -// Page header -// ------------------------- - -.page-header { - padding-bottom: (@baseLineHeight / 2) - 1; - margin: @baseLineHeight 0 (@baseLineHeight * 1.5); - border-bottom: 1px solid @grayLighter; -} - - - -// Lists -// -------------------------------------------------- - -// Unordered and Ordered lists -ul, ol { - padding: 0; - margin: 0 0 @baseLineHeight / 2 25px; -} -ul ul, -ul ol, -ol ol, -ol ul { - margin-bottom: 0; -} -li { - line-height: @baseLineHeight; -} - -// Remove default list styles -ul.unstyled, -ol.unstyled { - margin-left: 0; - list-style: none; -} - -// Single-line list items -ul.inline, -ol.inline { - margin-left: 0; - list-style: none; - > li { - display: inline-block; - .ie7-inline-block(); - padding-left: 5px; - padding-right: 5px; - } -} - -// Description Lists -dl { - margin-bottom: @baseLineHeight; -} -dt, -dd { - line-height: @baseLineHeight; -} -dt { - font-weight: bold; -} -dd { - margin-left: @baseLineHeight / 2; -} -// Horizontal layout (like forms) -.dl-horizontal { - .clearfix(); // Ensure dl clears floats if empty dd elements present - dt { - float: left; - width: @horizontalComponentOffset - 20; - clear: left; - text-align: right; - .text-overflow(); - } - dd { - margin-left: @horizontalComponentOffset; - } -} - -// MISC -// ---- - -// Horizontal rules -hr { - margin: @baseLineHeight 0; - border: 0; - border-top: 1px solid @hrBorder; - border-bottom: 1px solid @white; -} - -// Abbreviations and acronyms -abbr[title], -// Added data-* attribute to help out our tooltip plugin, per https://github.com/twitter/bootstrap/issues/5257 -abbr[data-original-title] { - cursor: help; - border-bottom: 1px dotted @grayLight; -} -abbr.initialism { - font-size: 90%; - text-transform: uppercase; -} - -// Blockquotes -blockquote { - padding: 0 0 0 15px; - margin: 0 0 @baseLineHeight; - border-left: 5px solid @grayLighter; - p { - margin-bottom: 0; - font-size: @baseFontSize * 1.25; - font-weight: 300; - line-height: 1.25; - } - small { - display: block; - line-height: @baseLineHeight; - color: @grayLight; - &:before { - content: '\2014 \00A0'; - } - } - - // Float right with text-align: right - &.pull-right { - float: right; - padding-right: 15px; - padding-left: 0; - border-right: 5px solid @grayLighter; - border-left: 0; - p, - small { - text-align: right; - } - small { - &:before { - content: ''; - } - &:after { - content: '\00A0 \2014'; - } - } - } -} - -// Quotes -q:before, -q:after, -blockquote:before, -blockquote:after { - content: ""; -} - -// Addresses -address { - display: block; - margin-bottom: @baseLineHeight; - font-style: normal; - line-height: @baseLineHeight; -} diff --git a/sites/all/themes/gui/materiobasetheme/components/bootstrap/less/utilities.less b/sites/all/themes/gui/materiobasetheme/components/bootstrap/less/utilities.less deleted file mode 100644 index 314b4ffd..00000000 --- a/sites/all/themes/gui/materiobasetheme/components/bootstrap/less/utilities.less +++ /dev/null @@ -1,30 +0,0 @@ -// -// Utility classes -// -------------------------------------------------- - - -// Quick floats -.pull-right { - float: right; -} -.pull-left { - float: left; -} - -// Toggling content -.hide { - display: none; -} -.show { - display: block; -} - -// Visibility -.invisible { - visibility: hidden; -} - -// For Affix plugin -.affix { - position: fixed; -} diff --git a/sites/all/themes/gui/materiobasetheme/components/bootstrap/less/variables.less b/sites/all/themes/gui/materiobasetheme/components/bootstrap/less/variables.less deleted file mode 100644 index 31c131b1..00000000 --- a/sites/all/themes/gui/materiobasetheme/components/bootstrap/less/variables.less +++ /dev/null @@ -1,301 +0,0 @@ -// -// Variables -// -------------------------------------------------- - - -// Global values -// -------------------------------------------------- - - -// Grays -// ------------------------- -@black: #000; -@grayDarker: #222; -@grayDark: #333; -@gray: #555; -@grayLight: #999; -@grayLighter: #eee; -@white: #fff; - - -// Accent colors -// ------------------------- -@blue: #049cdb; -@blueDark: #0064cd; -@green: #46a546; -@red: #9d261d; -@yellow: #ffc40d; -@orange: #f89406; -@pink: #c3325f; -@purple: #7a43b6; - - -// Scaffolding -// ------------------------- -@bodyBackground: @white; -@textColor: @grayDark; - - -// Links -// ------------------------- -@linkColor: #08c; -@linkColorHover: darken(@linkColor, 15%); - - -// Typography -// ------------------------- -@sansFontFamily: "Helvetica Neue", Helvetica, Arial, sans-serif; -@serifFontFamily: Georgia, "Times New Roman", Times, serif; -@monoFontFamily: Monaco, Menlo, Consolas, "Courier New", monospace; - -@baseFontSize: 14px; -@baseFontFamily: @sansFontFamily; -@baseLineHeight: 20px; -@altFontFamily: @serifFontFamily; - -@headingsFontFamily: inherit; // empty to use BS default, @baseFontFamily -@headingsFontWeight: bold; // instead of browser default, bold -@headingsColor: inherit; // empty to use BS default, @textColor - - -// Component sizing -// ------------------------- -// Based on 14px font-size and 20px line-height - -@fontSizeLarge: @baseFontSize * 1.25; // ~18px -@fontSizeSmall: @baseFontSize * 0.85; // ~12px -@fontSizeMini: @baseFontSize * 0.75; // ~11px - -@paddingLarge: 11px 19px; // 44px -@paddingSmall: 2px 10px; // 26px -@paddingMini: 0 6px; // 22px - -@baseBorderRadius: 4px; -@borderRadiusLarge: 6px; -@borderRadiusSmall: 3px; - - -// Tables -// ------------------------- -@tableBackground: transparent; // overall background-color -@tableBackgroundAccent: #f9f9f9; // for striping -@tableBackgroundHover: #f5f5f5; // for hover -@tableBorder: #ddd; // table and cell border - -// Buttons -// ------------------------- -@btnBackground: @white; -@btnBackgroundHighlight: darken(@white, 10%); -@btnBorder: #ccc; - -@btnPrimaryBackground: @linkColor; -@btnPrimaryBackgroundHighlight: spin(@btnPrimaryBackground, 20%); - -@btnInfoBackground: #5bc0de; -@btnInfoBackgroundHighlight: #2f96b4; - -@btnSuccessBackground: #62c462; -@btnSuccessBackgroundHighlight: #51a351; - -@btnWarningBackground: lighten(@orange, 15%); -@btnWarningBackgroundHighlight: @orange; - -@btnDangerBackground: #ee5f5b; -@btnDangerBackgroundHighlight: #bd362f; - -@btnInverseBackground: #444; -@btnInverseBackgroundHighlight: @grayDarker; - - -// Forms -// ------------------------- -@inputBackground: @white; -@inputBorder: #ccc; -@inputBorderRadius: @baseBorderRadius; -@inputDisabledBackground: @grayLighter; -@formActionsBackground: #f5f5f5; -@inputHeight: @baseLineHeight + 10px; // base line-height + 8px vertical padding + 2px top/bottom border - - -// Dropdowns -// ------------------------- -@dropdownBackground: @white; -@dropdownBorder: rgba(0,0,0,.2); -@dropdownDividerTop: #e5e5e5; -@dropdownDividerBottom: @white; - -@dropdownLinkColor: @grayDark; -@dropdownLinkColorHover: @white; -@dropdownLinkColorActive: @white; - -@dropdownLinkBackgroundActive: @linkColor; -@dropdownLinkBackgroundHover: @dropdownLinkBackgroundActive; - - - -// COMPONENT VARIABLES -// -------------------------------------------------- - - -// Z-index master list -// ------------------------- -// Used for a bird's eye view of components dependent on the z-axis -// Try to avoid customizing these :) -@zindexDropdown: 1000; -@zindexPopover: 1010; -@zindexTooltip: 1030; -@zindexFixedNavbar: 1030; -@zindexModalBackdrop: 1040; -@zindexModal: 1050; - - -// Sprite icons path -// ------------------------- -@iconSpritePath: "../img/glyphicons-halflings.png"; -@iconWhiteSpritePath: "../img/glyphicons-halflings-white.png"; - - -// Input placeholder text color -// ------------------------- -@placeholderText: @grayLight; - - -// Hr border color -// ------------------------- -@hrBorder: @grayLighter; - - -// Horizontal forms & lists -// ------------------------- -@horizontalComponentOffset: 180px; - - -// Wells -// ------------------------- -@wellBackground: #f5f5f5; - - -// Navbar -// ------------------------- -@navbarCollapseWidth: 979px; -@navbarCollapseDesktopWidth: @navbarCollapseWidth + 1; - -@navbarHeight: 40px; -@navbarBackgroundHighlight: #ffffff; -@navbarBackground: darken(@navbarBackgroundHighlight, 5%); -@navbarBorder: darken(@navbarBackground, 12%); - -@navbarText: #777; -@navbarLinkColor: #777; -@navbarLinkColorHover: @grayDark; -@navbarLinkColorActive: @gray; -@navbarLinkBackgroundHover: transparent; -@navbarLinkBackgroundActive: darken(@navbarBackground, 5%); - -@navbarBrandColor: @navbarLinkColor; - -// Inverted navbar -@navbarInverseBackground: #111111; -@navbarInverseBackgroundHighlight: #222222; -@navbarInverseBorder: #252525; - -@navbarInverseText: @grayLight; -@navbarInverseLinkColor: @grayLight; -@navbarInverseLinkColorHover: @white; -@navbarInverseLinkColorActive: @navbarInverseLinkColorHover; -@navbarInverseLinkBackgroundHover: transparent; -@navbarInverseLinkBackgroundActive: @navbarInverseBackground; - -@navbarInverseSearchBackground: lighten(@navbarInverseBackground, 25%); -@navbarInverseSearchBackgroundFocus: @white; -@navbarInverseSearchBorder: @navbarInverseBackground; -@navbarInverseSearchPlaceholderColor: #ccc; - -@navbarInverseBrandColor: @navbarInverseLinkColor; - - -// Pagination -// ------------------------- -@paginationBackground: #fff; -@paginationBorder: #ddd; -@paginationActiveBackground: #f5f5f5; - - -// Hero unit -// ------------------------- -@heroUnitBackground: @grayLighter; -@heroUnitHeadingColor: inherit; -@heroUnitLeadColor: inherit; - - -// Form states and alerts -// ------------------------- -@warningText: #c09853; -@warningBackground: #fcf8e3; -@warningBorder: darken(spin(@warningBackground, -10), 3%); - -@errorText: #b94a48; -@errorBackground: #f2dede; -@errorBorder: darken(spin(@errorBackground, -10), 3%); - -@successText: #468847; -@successBackground: #dff0d8; -@successBorder: darken(spin(@successBackground, -10), 5%); - -@infoText: #3a87ad; -@infoBackground: #d9edf7; -@infoBorder: darken(spin(@infoBackground, -10), 7%); - - -// Tooltips and popovers -// ------------------------- -@tooltipColor: #fff; -@tooltipBackground: #000; -@tooltipArrowWidth: 5px; -@tooltipArrowColor: @tooltipBackground; - -@popoverBackground: #fff; -@popoverArrowWidth: 10px; -@popoverArrowColor: #fff; -@popoverTitleBackground: darken(@popoverBackground, 3%); - -// Special enhancement for popovers -@popoverArrowOuterWidth: @popoverArrowWidth + 1; -@popoverArrowOuterColor: rgba(0,0,0,.25); - - - -// GRID -// -------------------------------------------------- - - -// Default 940px grid -// ------------------------- -@gridColumns: 12; -@gridColumnWidth: 60px; -@gridGutterWidth: 20px; -@gridRowWidth: (@gridColumns * @gridColumnWidth) + (@gridGutterWidth * (@gridColumns - 1)); - -// 1200px min -@gridColumnWidth1200: 70px; -@gridGutterWidth1200: 30px; -@gridRowWidth1200: (@gridColumns * @gridColumnWidth1200) + (@gridGutterWidth1200 * (@gridColumns - 1)); - -// 768px-979px -@gridColumnWidth768: 42px; -@gridGutterWidth768: 20px; -@gridRowWidth768: (@gridColumns * @gridColumnWidth768) + (@gridGutterWidth768 * (@gridColumns - 1)); - - -// Fluid grid -// ------------------------- -@fluidGridColumnWidth: percentage(@gridColumnWidth/@gridRowWidth); -@fluidGridGutterWidth: percentage(@gridGutterWidth/@gridRowWidth); - -// 1200px min -@fluidGridColumnWidth1200: percentage(@gridColumnWidth1200/@gridRowWidth1200); -@fluidGridGutterWidth1200: percentage(@gridGutterWidth1200/@gridRowWidth1200); - -// 768px-979px -@fluidGridColumnWidth768: percentage(@gridColumnWidth768/@gridRowWidth768); -@fluidGridGutterWidth768: percentage(@gridGutterWidth768/@gridRowWidth768); diff --git a/sites/all/themes/gui/materiobasetheme/components/bootstrap/less/wells.less b/sites/all/themes/gui/materiobasetheme/components/bootstrap/less/wells.less deleted file mode 100644 index 84a744b1..00000000 --- a/sites/all/themes/gui/materiobasetheme/components/bootstrap/less/wells.less +++ /dev/null @@ -1,29 +0,0 @@ -// -// Wells -// -------------------------------------------------- - - -// Base class -.well { - min-height: 20px; - padding: 19px; - margin-bottom: 20px; - background-color: @wellBackground; - border: 1px solid darken(@wellBackground, 7%); - .border-radius(@baseBorderRadius); - .box-shadow(inset 0 1px 1px rgba(0,0,0,.05)); - blockquote { - border-color: #ddd; - border-color: rgba(0,0,0,.15); - } -} - -// Sizes -.well-large { - padding: 24px; - .border-radius(@borderRadiusLarge); -} -.well-small { - padding: 9px; - .border-radius(@borderRadiusSmall); -} diff --git a/sites/all/themes/gui/materiobasetheme/components/bootstrap/package.json b/sites/all/themes/gui/materiobasetheme/components/bootstrap/package.json deleted file mode 100644 index 4fc52ca0..00000000 --- a/sites/all/themes/gui/materiobasetheme/components/bootstrap/package.json +++ /dev/null @@ -1,26 +0,0 @@ -{ - "name": "bootstrap" - , "description": "Sleek, intuitive, and powerful front-end framework for faster and easier web development." - , "version": "2.3.2" - , "keywords": ["bootstrap", "css"] - , "homepage": "http://twitter.github.com/bootstrap/" - , "author": "Twitter Inc." - , "scripts": { "test": "make test" } - , "repository": { - "type": "git" - , "url": "https://github.com/twitter/bootstrap.git" - } - , "licenses": [ - { - "type": "Apache-2.0" - , "url": "http://www.apache.org/licenses/LICENSE-2.0" - } - ] - , "devDependencies": { - "uglify-js": "1.3.4" - , "jshint": "0.9.1" - , "recess": "1.1.8" - , "connect": "2.1.3" - , "hogan.js": "2.0.0" - } -} diff --git a/sites/all/themes/gui/materiobasetheme/components/gui/gui.js b/sites/all/themes/gui/materiobasetheme/components/gui/gui.js deleted file mode 100644 index afc2e35f..00000000 --- a/sites/all/themes/gui/materiobasetheme/components/gui/gui.js +++ /dev/null @@ -1,368 +0,0 @@ -// * date 2011/10/19 * - -/** -* misc -*/ - -// ------ TRACE ------ - -function trace(s,o){ - if(window.console && window.console.debug){ - arguments.length === 2 ? window.console.debug(s,o) : window.console.debug(s); - }else if(console && console.log){ - arguments.length === 2 ? console.log(s,o) : console.log(s); - } -}; - -// ------ LOADJSCSSFILE ------ - -function loadjscssfile(filename, filetype){ - if (filetype=="js"){ //if filename is a external JavaScript file - var fileref=document.createElement('script') - fileref.setAttribute("type","text/javascript") - fileref.setAttribute("src", filename) - } - else if (filetype=="css"){ //if filename is an external CSS file - var fileref=document.createElement("link") - fileref.setAttribute("rel", "stylesheet") - fileref.setAttribute("type", "text/css") - fileref.setAttribute("href", filename) - } - if (typeof fileref!="undefined") - document.getElementsByTagName("head")[0].appendChild(fileref) -}; - -// ------ TIMEOUT - -function Timeout(fn, interval) { - var id = setTimeout(fn, interval); - this.cleared = false; - this.clear = function () { - this.cleared = true; - clearTimeout(id); - }; -} - -// ------ HEXTORGB convert hex to rgb color ------ - -function HexToRGB(h){ - if(h.charAt(0)=="#"){ - var coul = h.substring(1,7); - var r = parseInt(coul.substring(0,2),16); - var g = parseInt(coul.substring(2,4),16); - var b = parseInt(coul.substring(4,6),16); - return 'rgb('+r+', '+g+', '+b+')'; - }else{ - return null; - } -} - -// ------ PAIR check if number is pair of impair ------ - -function pair(n){return typeof n=='number'?(n%2==0?true:false):null;} - -// ------ RANDOM ------ - -function random(n1,n2){ - return arguments.length === 1 && typeof n1 === 'number'? Math.random()*n1 : ( arguments.length === 2 && typeof n1 === typeof n2 && typeof n1 === 'number' ? n1 + Math.random()*(n2-n1) : NaN ); -} -function randomInt(n1,n2){ - var rand = arguments.length === 1 && typeof n1 === 'number'? Math.random()*n1 : ( arguments.length === 2 && typeof n1 === typeof n2 && typeof n1 === 'number' ? n1 + Math.random()*(n2-n1) : NaN ); - return parseInt(rand); -} - -// ------ ROUNDED ------ - -function round(n,granularity){ - if(arguments.length == 1){ - n = Math.round(n); - }else{ - granularity = granularity.toString(); - granularity = granularity.replace(/./gi, 0); - granularity = granularity.replace(/^./gi, 1); - granularity = parseInt(granularity); - n = Math.round(n*granularity)/granularity; - } - return n; -} - -// ------ FLOOR ------ - -function floor(n,granularity){ - if(arguments.length == 1){ - n = Math.floor(n); - }else{ - granularity = granularity.toString(); - granularity = granularity.replace(/./gi, 0); - granularity = granularity.replace(/^./gi, 1); - granularity = parseInt(granularity); - n = Math.floor(n*granularity)/granularity; - } - return n; -} - -// ------ CEIL ------ - -function ceil(n,granularity){ - if(arguments.length == 1){ - n = Math.ceil(n); - }else{ - granularity = granularity.toString(); - granularity = granularity.replace(/./gi, 0); - granularity = granularity.replace(/^./gi, 1); - granularity = parseInt(granularity); - n = Math.ceil(n*granularity)/granularity; - } - return n; -} - -/** -* String -*/ - -// ------ TRIM remove multiple, leading or trailing spaces ------ - -String.prototype.trim = function() { - return this.replace(/(^\s*)|(\s*$)/gi,"").replace(/[ ]{2,}/gi," ").replace(/\n /,"\n"); -} - -// ------ remove all accents, for sort() by example ------ - -var Latinise={};Latinise.latin_map={"Á":"A","Ă":"A","Ắ":"A","Ặ":"A","Ằ":"A","Ẳ":"A","Ẵ":"A","Ǎ":"A","Â":"A","Ấ":"A","Ậ":"A","Ầ":"A","Ẩ":"A","Ẫ":"A","Ä":"A","Ǟ":"A","Ȧ":"A","Ǡ":"A","Ạ":"A","Ȁ":"A","À":"A","Ả":"A","Ȃ":"A","Ā":"A","Ą":"A","Å":"A","Ǻ":"A","Ḁ":"A","Ⱥ":"A","Ã":"A","Ꜳ":"AA","Æ":"AE","Ǽ":"AE","Ǣ":"AE","Ꜵ":"AO","Ꜷ":"AU","Ꜹ":"AV","Ꜻ":"AV","Ꜽ":"AY","Ḃ":"B","Ḅ":"B","Ɓ":"B","Ḇ":"B","Ƀ":"B","Ƃ":"B","Ć":"C","Č":"C","Ç":"C","Ḉ":"C","Ĉ":"C","Ċ":"C","Ƈ":"C","Ȼ":"C","Ď":"D","Ḑ":"D","Ḓ":"D","Ḋ":"D","Ḍ":"D","Ɗ":"D","Ḏ":"D","Dz":"D","Dž":"D","Đ":"D","Ƌ":"D","DZ":"DZ","DŽ":"DZ","É":"E","Ĕ":"E","Ě":"E","Ȩ":"E","Ḝ":"E","Ê":"E","Ế":"E","Ệ":"E","Ề":"E","Ể":"E","Ễ":"E","Ḙ":"E","Ë":"E","Ė":"E","Ẹ":"E","Ȅ":"E","È":"E","Ẻ":"E","Ȇ":"E","Ē":"E","Ḗ":"E","Ḕ":"E","Ę":"E","Ɇ":"E","Ẽ":"E","Ḛ":"E","Ꝫ":"ET","Ḟ":"F","Ƒ":"F","Ǵ":"G","Ğ":"G","Ǧ":"G","Ģ":"G","Ĝ":"G","Ġ":"G","Ɠ":"G","Ḡ":"G","Ǥ":"G","Ḫ":"H","Ȟ":"H","Ḩ":"H","Ĥ":"H","Ⱨ":"H","Ḧ":"H","Ḣ":"H","Ḥ":"H","Ħ":"H","Í":"I","Ĭ":"I","Ǐ":"I","Î":"I","Ï":"I","Ḯ":"I","İ":"I","Ị":"I","Ȉ":"I","Ì":"I","Ỉ":"I","Ȋ":"I","Ī":"I","Į":"I","Ɨ":"I","Ĩ":"I","Ḭ":"I","Ꝺ":"D","Ꝼ":"F","Ᵹ":"G","Ꞃ":"R","Ꞅ":"S","Ꞇ":"T","Ꝭ":"IS","Ĵ":"J","Ɉ":"J","Ḱ":"K","Ǩ":"K","Ķ":"K","Ⱪ":"K","Ꝃ":"K","Ḳ":"K","Ƙ":"K","Ḵ":"K","Ꝁ":"K","Ꝅ":"K","Ĺ":"L","Ƚ":"L","Ľ":"L","Ļ":"L","Ḽ":"L","Ḷ":"L","Ḹ":"L","Ⱡ":"L","Ꝉ":"L","Ḻ":"L","Ŀ":"L","Ɫ":"L","Lj":"L","Ł":"L","LJ":"LJ","Ḿ":"M","Ṁ":"M","Ṃ":"M","Ɱ":"M","Ń":"N","Ň":"N","Ņ":"N","Ṋ":"N","Ṅ":"N","Ṇ":"N","Ǹ":"N","Ɲ":"N","Ṉ":"N","Ƞ":"N","Nj":"N","Ñ":"N","NJ":"NJ","Ó":"O","Ŏ":"O","Ǒ":"O","Ô":"O","Ố":"O","Ộ":"O","Ồ":"O","Ổ":"O","Ỗ":"O","Ö":"O","Ȫ":"O","Ȯ":"O","Ȱ":"O","Ọ":"O","Ő":"O","Ȍ":"O","Ò":"O","Ỏ":"O","Ơ":"O","Ớ":"O","Ợ":"O","Ờ":"O","Ở":"O","Ỡ":"O","Ȏ":"O","Ꝋ":"O","Ꝍ":"O","Ō":"O","Ṓ":"O","Ṑ":"O","Ɵ":"O","Ǫ":"O","Ǭ":"O","Ø":"O","Ǿ":"O","Õ":"O","Ṍ":"O","Ṏ":"O","Ȭ":"O","Ƣ":"OI","Ꝏ":"OO","Ɛ":"E","Ɔ":"O","Ȣ":"OU","Ṕ":"P","Ṗ":"P","Ꝓ":"P","Ƥ":"P","Ꝕ":"P","Ᵽ":"P","Ꝑ":"P","Ꝙ":"Q","Ꝗ":"Q","Ŕ":"R","Ř":"R","Ŗ":"R","Ṙ":"R","Ṛ":"R","Ṝ":"R","Ȑ":"R","Ȓ":"R","Ṟ":"R","Ɍ":"R","Ɽ":"R","Ꜿ":"C","Ǝ":"E","Ś":"S","Ṥ":"S","Š":"S","Ṧ":"S","Ş":"S","Ŝ":"S","Ș":"S","Ṡ":"S","Ṣ":"S","Ṩ":"S","Ť":"T","Ţ":"T","Ṱ":"T","Ț":"T","Ⱦ":"T","Ṫ":"T","Ṭ":"T","Ƭ":"T","Ṯ":"T","Ʈ":"T","Ŧ":"T","Ɐ":"A","Ꞁ":"L","Ɯ":"M","Ʌ":"V","Ꜩ":"TZ","Ú":"U","Ŭ":"U","Ǔ":"U","Û":"U","Ṷ":"U","Ü":"U","Ǘ":"U","Ǚ":"U","Ǜ":"U","Ǖ":"U","Ṳ":"U","Ụ":"U","Ű":"U","Ȕ":"U","Ù":"U","Ủ":"U","Ư":"U","Ứ":"U","Ự":"U","Ừ":"U","Ử":"U","Ữ":"U","Ȗ":"U","Ū":"U","Ṻ":"U","Ų":"U","Ů":"U","Ũ":"U","Ṹ":"U","Ṵ":"U","Ꝟ":"V","Ṿ":"V","Ʋ":"V","Ṽ":"V","Ꝡ":"VY","Ẃ":"W","Ŵ":"W","Ẅ":"W","Ẇ":"W","Ẉ":"W","Ẁ":"W","Ⱳ":"W","Ẍ":"X","Ẋ":"X","Ý":"Y","Ŷ":"Y","Ÿ":"Y","Ẏ":"Y","Ỵ":"Y","Ỳ":"Y","Ƴ":"Y","Ỷ":"Y","Ỿ":"Y","Ȳ":"Y","Ɏ":"Y","Ỹ":"Y","Ź":"Z","Ž":"Z","Ẑ":"Z","Ⱬ":"Z","Ż":"Z","Ẓ":"Z","Ȥ":"Z","Ẕ":"Z","Ƶ":"Z","IJ":"IJ","Œ":"OE","ᴀ":"A","ᴁ":"AE","ʙ":"B","ᴃ":"B","ᴄ":"C","ᴅ":"D","ᴇ":"E","ꜰ":"F","ɢ":"G","ʛ":"G","ʜ":"H","ɪ":"I","ʁ":"R","ᴊ":"J","ᴋ":"K","ʟ":"L","ᴌ":"L","ᴍ":"M","ɴ":"N","ᴏ":"O","ɶ":"OE","ᴐ":"O","ᴕ":"OU","ᴘ":"P","ʀ":"R","ᴎ":"N","ᴙ":"R","ꜱ":"S","ᴛ":"T","ⱻ":"E","ᴚ":"R","ᴜ":"U","ᴠ":"V","ᴡ":"W","ʏ":"Y","ᴢ":"Z","á":"a","ă":"a","ắ":"a","ặ":"a","ằ":"a","ẳ":"a","ẵ":"a","ǎ":"a","â":"a","ấ":"a","ậ":"a","ầ":"a","ẩ":"a","ẫ":"a","ä":"a","ǟ":"a","ȧ":"a","ǡ":"a","ạ":"a","ȁ":"a","à":"a","ả":"a","ȃ":"a","ā":"a","ą":"a","ᶏ":"a","ẚ":"a","å":"a","ǻ":"a","ḁ":"a","ⱥ":"a","ã":"a","ꜳ":"aa","æ":"ae","ǽ":"ae","ǣ":"ae","ꜵ":"ao","ꜷ":"au","ꜹ":"av","ꜻ":"av","ꜽ":"ay","ḃ":"b","ḅ":"b","ɓ":"b","ḇ":"b","ᵬ":"b","ᶀ":"b","ƀ":"b","ƃ":"b","ɵ":"o","ć":"c","č":"c","ç":"c","ḉ":"c","ĉ":"c","ɕ":"c","ċ":"c","ƈ":"c","ȼ":"c","ď":"d","ḑ":"d","ḓ":"d","ȡ":"d","ḋ":"d","ḍ":"d","ɗ":"d","ᶑ":"d","ḏ":"d","ᵭ":"d","ᶁ":"d","đ":"d","ɖ":"d","ƌ":"d","ı":"i","ȷ":"j","ɟ":"j","ʄ":"j","dz":"dz","dž":"dz","é":"e","ĕ":"e","ě":"e","ȩ":"e","ḝ":"e","ê":"e","ế":"e","ệ":"e","ề":"e","ể":"e","ễ":"e","ḙ":"e","ë":"e","ė":"e","ẹ":"e","ȅ":"e","è":"e","ẻ":"e","ȇ":"e","ē":"e","ḗ":"e","ḕ":"e","ⱸ":"e","ę":"e","ᶒ":"e","ɇ":"e","ẽ":"e","ḛ":"e","ꝫ":"et","ḟ":"f","ƒ":"f","ᵮ":"f","ᶂ":"f","ǵ":"g","ğ":"g","ǧ":"g","ģ":"g","ĝ":"g","ġ":"g","ɠ":"g","ḡ":"g","ᶃ":"g","ǥ":"g","ḫ":"h","ȟ":"h","ḩ":"h","ĥ":"h","ⱨ":"h","ḧ":"h","ḣ":"h","ḥ":"h","ɦ":"h","ẖ":"h","ħ":"h","ƕ":"hv","í":"i","ĭ":"i","ǐ":"i","î":"i","ï":"i","ḯ":"i","ị":"i","ȉ":"i","ì":"i","ỉ":"i","ȋ":"i","ī":"i","į":"i","ᶖ":"i","ɨ":"i","ĩ":"i","ḭ":"i","ꝺ":"d","ꝼ":"f","ᵹ":"g","ꞃ":"r","ꞅ":"s","ꞇ":"t","ꝭ":"is","ǰ":"j","ĵ":"j","ʝ":"j","ɉ":"j","ḱ":"k","ǩ":"k","ķ":"k","ⱪ":"k","ꝃ":"k","ḳ":"k","ƙ":"k","ḵ":"k","ᶄ":"k","ꝁ":"k","ꝅ":"k","ĺ":"l","ƚ":"l","ɬ":"l","ľ":"l","ļ":"l","ḽ":"l","ȴ":"l","ḷ":"l","ḹ":"l","ⱡ":"l","ꝉ":"l","ḻ":"l","ŀ":"l","ɫ":"l","ᶅ":"l","ɭ":"l","ł":"l","lj":"lj","ſ":"s","ẜ":"s","ẛ":"s","ẝ":"s","ḿ":"m","ṁ":"m","ṃ":"m","ɱ":"m","ᵯ":"m","ᶆ":"m","ń":"n","ň":"n","ņ":"n","ṋ":"n","ȵ":"n","ṅ":"n","ṇ":"n","ǹ":"n","ɲ":"n","ṉ":"n","ƞ":"n","ᵰ":"n","ᶇ":"n","ɳ":"n","ñ":"n","nj":"nj","ó":"o","ŏ":"o","ǒ":"o","ô":"o","ố":"o","ộ":"o","ồ":"o","ổ":"o","ỗ":"o","ö":"o","ȫ":"o","ȯ":"o","ȱ":"o","ọ":"o","ő":"o","ȍ":"o","ò":"o","ỏ":"o","ơ":"o","ớ":"o","ợ":"o","ờ":"o","ở":"o","ỡ":"o","ȏ":"o","ꝋ":"o","ꝍ":"o","ⱺ":"o","ō":"o","ṓ":"o","ṑ":"o","ǫ":"o","ǭ":"o","ø":"o","ǿ":"o","õ":"o","ṍ":"o","ṏ":"o","ȭ":"o","ƣ":"oi","ꝏ":"oo","ɛ":"e","ᶓ":"e","ɔ":"o","ᶗ":"o","ȣ":"ou","ṕ":"p","ṗ":"p","ꝓ":"p","ƥ":"p","ᵱ":"p","ᶈ":"p","ꝕ":"p","ᵽ":"p","ꝑ":"p","ꝙ":"q","ʠ":"q","ɋ":"q","ꝗ":"q","ŕ":"r","ř":"r","ŗ":"r","ṙ":"r","ṛ":"r","ṝ":"r","ȑ":"r","ɾ":"r","ᵳ":"r","ȓ":"r","ṟ":"r","ɼ":"r","ᵲ":"r","ᶉ":"r","ɍ":"r","ɽ":"r","ↄ":"c","ꜿ":"c","ɘ":"e","ɿ":"r","ś":"s","ṥ":"s","š":"s","ṧ":"s","ş":"s","ŝ":"s","ș":"s","ṡ":"s","ṣ":"s","ṩ":"s","ʂ":"s","ᵴ":"s","ᶊ":"s","ȿ":"s","ɡ":"g","ᴑ":"o","ᴓ":"o","ᴝ":"u","ť":"t","ţ":"t","ṱ":"t","ț":"t","ȶ":"t","ẗ":"t","ⱦ":"t","ṫ":"t","ṭ":"t","ƭ":"t","ṯ":"t","ᵵ":"t","ƫ":"t","ʈ":"t","ŧ":"t","ᵺ":"th","ɐ":"a","ᴂ":"ae","ǝ":"e","ᵷ":"g","ɥ":"h","ʮ":"h","ʯ":"h","ᴉ":"i","ʞ":"k","ꞁ":"l","ɯ":"m","ɰ":"m","ᴔ":"oe","ɹ":"r","ɻ":"r","ɺ":"r","ⱹ":"r","ʇ":"t","ʌ":"v","ʍ":"w","ʎ":"y","ꜩ":"tz","ú":"u","ŭ":"u","ǔ":"u","û":"u","ṷ":"u","ü":"u","ǘ":"u","ǚ":"u","ǜ":"u","ǖ":"u","ṳ":"u","ụ":"u","ű":"u","ȕ":"u","ù":"u","ủ":"u","ư":"u","ứ":"u","ự":"u","ừ":"u","ử":"u","ữ":"u","ȗ":"u","ū":"u","ṻ":"u","ų":"u","ᶙ":"u","ů":"u","ũ":"u","ṹ":"u","ṵ":"u","ᵫ":"ue","ꝸ":"um","ⱴ":"v","ꝟ":"v","ṿ":"v","ʋ":"v","ᶌ":"v","ⱱ":"v","ṽ":"v","ꝡ":"vy","ẃ":"w","ŵ":"w","ẅ":"w","ẇ":"w","ẉ":"w","ẁ":"w","ⱳ":"w","ẘ":"w","ẍ":"x","ẋ":"x","ᶍ":"x","ý":"y","ŷ":"y","ÿ":"y","ẏ":"y","ỵ":"y","ỳ":"y","ƴ":"y","ỷ":"y","ỿ":"y","ȳ":"y","ẙ":"y","ɏ":"y","ỹ":"y","ź":"z","ž":"z","ẑ":"z","ʑ":"z","ⱬ":"z","ż":"z","ẓ":"z","ȥ":"z","ẕ":"z","ᵶ":"z","ᶎ":"z","ʐ":"z","ƶ":"z","ɀ":"z","ff":"ff","ffi":"ffi","ffl":"ffl","fi":"fi","fl":"fl","ij":"ij","œ":"oe","st":"st","ₐ":"a","ₑ":"e","ᵢ":"i","ⱼ":"j","ₒ":"o","ᵣ":"r","ᵤ":"u","ᵥ":"v","ₓ":"x"}; -String.prototype.latinise=function(){return this.replace(/[^A-Za-z0-9\[\] ]/g,function(a){return Latinise.latin_map[a]||a})}; -String.prototype.latinize=String.prototype.latinise; -String.prototype.isLatin=function(){return this==this.latinise()} - -/** -* Array -*/ - -// ------ UNIQUE reduces duplicates ------ - -array_unique = function(ar){ - var r = new Array(); - o:for(var i = 0, n = ar.length; i < n; i++) - { - for(var x = 0, y = r.length; x < y; x++) - { - if(r[x]==ar[i]) - { - continue o; - } - } - r[r.length] = ar[i]; - } - return r; -}; - -// ------ SUBSTRACT substract two array ------ - -array_subtract = function(ara1,ara2) { - var aRes = new Array() ; - for (var i = ara1.length-1; i >= 0; i--) - if(array_contains(ara2,ara1[i])) - aRes.push(ara1[i]); - return aRes ; -} - -/* - SHUFFLE Add a shuffle function to Array object prototype - author: Stephane Roucheray - src: http://sroucheray.org/blog/2009/11/array-sort-should-not-be-used-to-shuffle-an-array/ - found 2011/09/08. -*/ -array_shuffle = function(ar){ - var i = ar.length, j, temp; - if ( i == 0 ) return; - while ( --i ) { - j = Math.floor( Math.random() * ( i + 1 ) ); - temp = ar[i]; - ar[i] = ar[j]; - ar[j] = temp; - } - return ar; -}; - -// ------ CONTAINS ------ - -array_contains = function(ar, obj) { - var i = ar.length; - while (i--) - if (ar[i] === obj) - return true; - return false; -}; - -// ------ REMOVE ------ - -// /!\ Found on the Internet, not sure of efficiency. -// Array.prototype.remove = function(v) { -// var x, _i, _len, _results; -// _results = []; -// for (_i = 0, _len = this.length; _i < _len; _i++) { -// x = this[_i]; -// if (x !== v) { -// _results.push(x); -// } -// } -// return _results; -// }; - -array_remove = function(ar){ - var what, a= arguments, L= a.length, ax; - while(L && ar.length){ - what= a[--L]; - while((ax= ar.indexOf(what))!= -1){ - ar.splice(ax, 1); - } - } - return ar; -}; - -// for IE -// if(!Array.prototype.indexOf){ -// Array.prototype.indexOf= function(what, i){ -// i= i || 0; -// var L= this.length; -// while(i< L){ -// if(this[i]=== what) return i; -// ++i; -// } -// return -1; -// }; -// } - -array_indexOf = function(ar, what, i){ - i= i || 0; - var L= ar.length; - while(i< L){ - if(ar[i]=== what) return i; - ++i; - } - return -1; -}; - -// ------ SUBSTRACT substract two array ------ - -function array_subtract(ara1,ara2) { - var aRes = new Array() ; - for (var i = ara1.length-1; i >= 0; i--) - if( !array_contains(ara1[i],ara2) ) - aRes.push(ara1[i]); - return aRes ; -}; - -/** -* Objects -* -*/ - -// ------ OBJECTSIZE get the length of objects ------ - -function objectSize(o) { - var len = o.length ? --o.length : 0; - for (var k in o) - len++; - return len; -} -// Object.prototype.size = function () { -// // var len = this.length ? --this.length : -1; // POURQUOI NE FONCTIONNE PAS? -// var len = this.length ? --this.length : -2; -// for (var k in this) -// len++; -// return len; -// } - -function objectIsEmpty(obj){ - for (var prop in obj) { - if (obj.hasOwnProperty(prop)) - return false; - } - return true; -}; - -// ------ OBJECTGETKEY get key of index ------ - -function objectGetKey(o,index){ - var i = 0; - for (var k in o){ - if (k === 'length' || !o.hasOwnProperty(k)) - continue; - if(i == index) - return k; - i ++; - } -} -// Object.prototype.getKey = function(index){ -// var i = 0; -// for (var key in this){ -// if (key === 'length' || !this.hasOwnProperty(key)) -// continue; -// if(i == index) -// return key; -// i ++; -// } -// } - -// ------ OBJECTSORT sort object ------ - -function objectSort(o,value) { - var connection = new Array(); - for (var i = objectSize(o) - 1; i >= 0; i--){ - var k = objectGetKey(o,i); - for (var j = objectSize(o[k].wit) - 1; j >= 0; j--){ - var k2 = objectGetKey(o[k].wit,j); - if (k2==value) { - var the_wit = parseFloat(o[k].wit[k2]); - connection.push( {wit:the_wit,nid:k} ); - }; - }; - }; - - connection.sort(function(a,b){ - // return (a.wit - b.wit);//ascending - return (b.wit - a.wit);//descending - }); - - var o_sort = {}; - for (var i = connection.length - 1; i >= 0; i--){ - // o_sort[connection[i].wit+'-'+connection[i].nid] = o[connection[i].nid]; - o_sort[connection[i].nid] = o[connection[i].nid]; - }; - - return o_sort; -} - -/** -* trigo -*/ - -// -------- getElementAngle ---------- -// L'angle 0 correspond au nord (vers le haut) -// Exemple : getElementAngle(posElementX, posElementY, posSourisX, posSourisY) -// Ceci retournera l'angle de l'élément par rapport à la position de la souris - -function getElementAngle(x1, y1, x2, y2) { - var adj = x2 - x1; - var opp = y2 - y1; - - var angle = Math.abs(Math.atan(opp/adj) * 180/Math.PI); - - if (adj > 0 && opp < 0 ) { - angle = 90 - angle; - } - else if (adj >= 0 && opp >= 0) { - angle += 90; - } - else if (adj < 0 && opp >= 0) { - angle = 180 + (90 - angle); - } - else { - angle += 270; - } - - return angle; -} - - - diff --git a/sites/all/themes/gui/materiobasetheme/components/gui/gui.less b/sites/all/themes/gui/materiobasetheme/components/gui/gui.less deleted file mode 100644 index 28017c64..00000000 --- a/sites/all/themes/gui/materiobasetheme/components/gui/gui.less +++ /dev/null @@ -1,592 +0,0 @@ -/* - * www.g-u-i.net - */ - -// = -// = -// = -// = -// = -// ===== TYPOGRAHIE ====================================================================================================== - -.8(){font-size:8px;} -.9(){font-size:9px;} -.10(){font-size:10px;} -.11(){font-size:10px;} -.12(){font-size:12px;} -.14(){font-size:14px;} -.16(){font-size:16px;} -.18(){font-size:18px;} -.20(){font-size:20px;} -.24(){font-size:24px;} -.28(){font-size:24px;} -.30(){font-size:30px;} -.36(){font-size:36px;} -.48(){font-size:48px;} -.60(){font-size:60px;} -.72(){font-size:72px;} - -.regular(){font-weight:normal;} -.bold(){font-weight:bold;} -.100(){font-weight:100;} -.200(){font-weight:200;} -.300(){font-weight:300;} -.400(){font-weight:400;} -.500(){font-weight:500;} -.600(){font-weight:600;} -.700(){font-weight:700;} -.800(){font-weight:800;} -.900(){font-weight:900;} - -.upper(){text-transform: uppercase;} -.italic(){font-style:italic;} -.normal(){font-style: normal;} - -.hyphens(@value: auto) -{ - -webkit-hyphens:@value; - -moz-hyphens:@value; - -ms-hyphens:@value; - -o-hyphens:@value; - hyphens:@value; -} -.font-size(@value: 1em,@lineheight:1.3em) -{ - font-size:@value; - line-height:@lineheight; -} - -@green:#17942A; -@red:#E60000; - -// = -// = -// = -// = -// = -// ===== SHORTCUTS ======================================================================================================= - -// padding -.p(@p){ padding:@arguments; } -.p(@v, @h){ padding:@arguments; } -.p(@t, @l, @b, @l){ padding:@arguments; } - -.pt(@p){ padding-top:@p; } -.pr(@p){ padding-right:@p; } -.pb(@p){ padding-bottom:@p; } -.pl(@p){ padding-left:@p; } - -// margin -.m(@p){ margin:@arguments; } -.m(@v, @h){ margin:@arguments; } -.m(@t, @l, @b, @l){ margin:@arguments; } - -.mt(@m){ margin-top:@m; } -.mr(@m){ margin-right:@m; } -.mb(@m){ margin-bottom:@m; } -.ml(@m){ margin-left:@m; } - -.0(){ margin:0; padding:0; } - -// border -.b(@b){ border: @b; } -.b(@size, @color){ border: @size solid @color; } - -.bt(@b){ border-top: @b;} -.bt(@size, @color){border-top: @size solid @color;} - -.br(@b){ border-right: @b;} -.br(@size, @color){border-right: @size solid @color;} - -.bb(@b){ border-bottom: @b;} -.bb(@size, @color){border-bottom: @size solid @color;} - -.bl(@b){ border-left: @b;} -.bl(@size, @color){border-left: @size solid @color;} - -.bordered(@top-color: #EEE, @right-color: #EEE, @bottom-color: #EEE, @left-color: #EEE) -{ - border-top : solid 1px @top-color; - border-right : solid 1px @right-color; - border-bottom: solid 1px @bottom-color; - border-left : solid 1px @left-color; -} - -// Background -.bg(@color, @url, @repeat, @scrollfixed, @pos){background: @arguments;} -.bgc(@color){background-color: @arguments;} -.bkgd(@params){background: @arguments;} -.bkgdc(@color){.bgc(@arguments);} - -.bgca(@r, @g, @b, @a){ - background-color: rgb(@r, @g, @b); // ie8 - background-color: rgba(@r, @g, @b, @a); - *background-color: rgb(@r, @g, @b); // ie7 -}; - -// Selection -.selection(@bgcolor,@color) -{ - &::selection { - background:@bgcolor; - color:@color; - } - &::-moz-selection { - background:@bgcolor; - color:@color; - } - &::-webkit-selection { - background:@bgcolor; - color:@color; - } -} - -// Colors -.color(@value) -{ - &, - & *{color:@value;} -} - -// Opacity -.opacity(@opacity: 0.5) -{ - -webkit-opacity: @opacity; - -khtml-opacity: @opacity; - -moz-opacity: @opacity; - opacity: @opacity; -} - -// size -.size(@height, @width) { - width: @width; - height: @height; -} -.square(@size) { - .size(@size, @size); -} - -// center -.center-block() { - display: block; - margin-left: auto; - margin-right: auto; -} - -// = -// = -// = -// = -// = -// ===== DISPLAY UTILS =================================================================================================== - -// Inline blocks -.inlineblock(@align:top) -{ - display:moz-inline-stack; - display:inline-block; - vertical-align:@align; - zoom:1; - *display:inline; - // .ie7 &, .ie8 &{display:block;float:left;} -} - -.db(){display:block;} -.dbn(){display:none;} -.dib(){.inlineblock;} -.dib(@align){.inlineblock(@align);} - -.float(@align:left){ - .db; float:@align; -} - -.abs(@value) { position:absolute; top:@value; left:@value; bottom:@value; right:@value; } -.abs(@top, @left) { position:absolute; top:@top; left:@left; } -.abs(@top, @right, @bottom, @left) { position:absolute; top:@top; left:@left; bottom:@bottom; right:@right; }; - -.fix(@value) { position:fixed; top:@value; left:@value; bottom:@value; right:@value; } -.fix(@top, @left) { position:fixed; top:@top; left:@left; } -.fix(@top, @right, @bottom, @left) { position:fixed; top:@top; left:@left; bottom:@bottom; right:@right; }; - -// Columns system -@g:0; -.g() { width:@g; } -.col(@col,@coltotal:@n,@gutter:@g) { - width: @col * ( 100% - ((@coltotal - 1) * @gutter) ) / @coltotal + ((@col - 1) * @gutter); -} -.inside-left(@col,@coltotal:@n,@gutter:@g) { - padding-left: @col * ( 100% - ((@coltotal - 1) * @gutter) ) / @coltotal + (@col * @gutter); -} -.inside-right(@col,@coltotal:@n,@gutter:@g) { - padding-right: @col * ( 100% - ((@coltotal - 1) * @gutter) ) / @coltotal + (@col * @gutter); -} - - -// Vertical alignement -// -// ___ .align-child() -// | -// | Permet l’alignement vertical d’un objet par rapport à son premier parent (dans son conteneur direct). -// | -// | 1 param : @vertical-align -// -.align-child(@align:middle){ - &:before { content: ""; .dib(middle); overflow: hidden; visibility: hidden; width: 0; height: 100%; } - & > * { .dib(@align); } -} - -.clear-after(){ - &:after{clear:both;content:'';display:block;height:0px;overflow:hidden;visibility:hidden;width:0px;} -} - -// For clearing floats like a boss h5bp.com/q -.clearix() { - *zoom: 1; - &:before, - &:after { - display: table; - content: ""; - // Fixes Opera/contenteditable bug: - // http://nicolasgallagher.com/micro-clearfix-hack/#comment-36952 - line-height: 0; - } - &:after { - clear: both; - } -} - -// = -// = -// = -// = -// = -// ===== CSS3 ============================================================================================================ - -// Gradients -.gradient(@color: #F5F5F5, @start: #EEE, @stop: #FFF) -{ - background: @color; - background: -webkit-gradient(linear, - left bottom, - left top, - color-stop(0, @start), - color-stop(1, @stop)); - background: -ms-linear-gradient(bottom, - @start, - @stop); - background: -moz-linear-gradient(center bottom, - @start 0%, - @stop 100%); -} -.bw-gradient(@color: #F5F5F5, @start: 0, @stop: 255) -{ - background: @color; - background: -webkit-gradient(linear, - left bottom, - left top, - color-stop(0, rgb(@start,@start,@start)), - color-stop(1, rgb(@stop,@stop,@stop))); - background: -ms-linear-gradient(bottom, - rgb(@start,@start,@start) 0%, - rgb(@start,@start,@start) 100%); - background: -moz-linear-gradient(center bottom, - rgb(@start,@start,@start) 0%, - rgb(@stop,@stop,@stop) 100%); -} - -// Shadows -// -// ___ .box-shadow() -// | -// | Ombré extérieur. -// | -// | 1 param : @blur -// | 2+ params : @horizontal / @vertical / @blur / @color: #000 / @spread: 0px -// -// ___ .inset-shadow() -// | -// | Ombré intérieur. -// | -// | 1 param : @blur -// | 2+ params : @horizontal / @vertical / @blur / @color: #000 / @spread: 0px -// -.box-shadow(@blur: 9px) -{ - filter: progid:DXImageTransform.Microsoft.dropshadow(OffX=0, OffY=0, Color='#000'); - -ms-filter: "progid:DXImageTransform.Microsoft.dropshadow(OffX=0, OffY=0, Color='#000')"; - -webkit-box-shadow: 0 0 @blur #000; - -moz-box-shadow: 0 0 @blur #000; - -ms-box-shadow: 0 0 @blur #000; - box-shadow: 0 0 @blur #000; -} -.box-shadow(@x, @y, @blur: 9px, @color: #000, @spread: 0px) -{ - filter: progid:DXImageTransform.Microsoft.dropshadow(OffX=@x, OffY=@y, Color=~'@{color}'); - -ms-filter: "progid:DXImageTransform.Microsoft.dropshadow(OffX=@{x}, OffY=@{y}, Color='@{color}')"; - -webkit-box-shadow: @x @y @blur @spread @color; - -moz-box-shadow: @x @y @blur @spread @color; - -ms-box-shadow: @x @y @blur @spread @color; - box-shadow: @x @y @blur @spread @color; -} -.inset-shadow(@blur: 9px) -{ - filter: progid:DXImageTransform.Microsoft.dropshadow(OffX=0, OffY=0, Color='#000'); - -ms-filter: "progid:DXImageTransform.Microsoft.dropshadow(OffX=0, OffY=0, Color='#000')"; - -webkit-box-shadow: 0 0 @blur #000 inset; - -moz-box-shadow: 0 0 @blur #000 inset; - -ms-box-shadow: 0 0 @blur #000 inset; - box-shadow: 0 0 @blur #000 inset; -} -.inset-shadow(@x, @y, @blur: 9px, @color: #000, @spread: 0px) -{ - filter: progid:DXImageTransform.Microsoft.dropshadow(OffX=@x, OffY=@y, Color=~'@{color}'); - -ms-filter: "progid:DXImageTransform.Microsoft.dropshadow(OffX=0, OffY=0, Color='@{color}')"; - -webkit-box-shadow: @x @y @blur @spread @color inset; - -moz-box-shadow: @x @y @blur @spread @color inset; - -ms-box-shadow: @x @y @blur @spread @color inset; - box-shadow: @x @y @blur @spread @color inset; -} - -.drop-shadow(@x-axis: 0, @y-axis: 1px, @blur: 2px, @alpha: 0.1) -{ - -webkit-box-shadow: @x-axis @y-axis @blur rgba(0, 0, 0, @alpha); - -moz-box-shadow: @x-axis @y-axis @blur rgba(0, 0, 0, @alpha); - box-shadow: @x-axis @y-axis @blur rgba(0, 0, 0, @alpha); -} - -// Border radius -.rounded(@radius: 2px) -{ - -webkit-border-radius: @radius; - -moz-border-radius: @radius; - border-radius: @radius; - -webkit-background-clip: padding-box; - -moz-background-clip: padding; - background-clip: padding-box; -} -.border-radius(@topleft: 0, @topright: 0, @bottomright: 0, @bottomleft: 0) -{ - -webkit-border-radius:@arguments; - -moz-border-radius:@arguments; - border-radius:@arguments; - -webkit-background-clip: padding-box; - -moz-background-clip: padding; - background-clip: padding-box; -} - -// transitions -.transition-simply-prefix(@string) { - -webkit-transition: @string; - -moz-transition: @string; - -o-transition: @string; - transition: @string; -} - -// -// ___ .transition() -// | -// | 1 param : @property -// | 2 params : @property / @duration -// | 3+ params : @property / @duration / @transitiondelay:0s , @timingfunction:ease-out -// -// ___ .transitions() -// | -// | Permet de fixer des paramètres spécifique par propriétés, exemple: -// | -// | .transitions( -// | 'height , padding , margin , box-shadow', -// | '.5s , .2s , .2s , .2s', -// | '0s , 0s , 0s , .3s', -// | 'linear , ease-out , linear , ease-out' -// | ); -// -.transition(@property: all) -{ - -webkit-transition: @property; - -moz-transition: @property; - -o-transition: @property; - transition: @property; -} -.transition(@property, @duration) -{ - -webkit-transition: @arguments; - -moz-transition: @arguments; - -o-transition: @arguments; - transition: @arguments; -} -.transition(@property, @duration, @transitiondelay, @timingfunction:ease-out) -{ - -webkit-transition: @arguments; - -moz-transition: @arguments; - -o-transition: @arguments; - transition: @arguments; -} -.transitions(@property: all, @duration:0s, @transitiondelay:0s, @timingfunction:ease-out) -{ - -webkit-transition-property :~'@{property}'; - -webkit-transition-duration :~'@{duration}'; - -webkit-transition-delay :~'@{transitiondelay}'; - -webkit-transition-timing-function:~'@{timingfunction}'; - -moz-transition-property :~'@{property}'; - -moz-transition-duration :~'@{duration}'; - -moz-transition-delay :~'@{transitiondelay}'; - -moz-transition-timing-function:~'@{timingfunction}'; - -o-transition-property :~'@{property}'; - -o-transition-duration :~'@{duration}'; - -o-transition-delay :~'@{transitiondelay}'; - -o-transition-timing-function:~'@{timingfunction}'; - transition-property :~'@{property}'; - transition-duration :~'@{duration}'; - transition-delay :~'@{transitiondelay}'; - transition-timing-function:~'@{timingfunction}'; -} - -.transitions-duration(@duration: 0s) -{ - -webkit-transition-duration: ~'@{duration}'; - -moz-transition-duration: ~'@{duration}'; - -o-transition-duration: ~'@{duration}'; - transition-duration: ~'@{duration}'; -} - -.transition-duration(@duration: 0.2s) -{ - -webkit-transition-duration: @duration; - -moz-transition-duration: @duration; - -o-transition-duration: @duration; - transition-duration: @duration; -} - -.transitions-delay(@delay: 0s) -{ - -webkit-transition-delay: ~'@{delay}'; - -moz-transition-delay: ~'@{delay}'; - -o-transition-delay: ~'@{delay}'; - transition-delay: ~'@{delay}'; -} - -// Rotate -// -// ___ .rotation() -// | -// | 1 param : @degree -// -// ___ .rotate() -// | -// | Tentative de compatibilté étendue (fonctionne uniquement pour 0, 90, 180 ou 270 degrés). -// | -// | 1 param : @degree -// | 3 params : @degree / @originX / @originY -// -.rotation(@deg:5deg) -{ - -webkit-transform: rotate(@deg); - -moz-transform: rotate(@deg); - transform: rotate(@deg); -} -.rotate(@value, @originX:0%, @originY:0%, @unit:'deg') -{ - filter: progid:DXImageTransform.Microsoft.BasicImage(rotation = (360 / @value) + 1); //0, 1, 2, or 3 rotate 0, 90, 180 or 270 - -webkit-transform: rotate(~"@{value}@{unit}"); // ~"@{value}@{unit}" rather than @value@unit remove the spaces between value and unit. - -moz-transform: rotate(~"@{value}@{unit}"); - -ms-transform: rotate(~"@{value}@{unit}"); - -o-transform: rotate(~"@{value}@{unit}"); - transform: rotate(~"@{value}@{unit}"); - -webkit-transform-origin:@originX @originY; - -moz-transform-origin:@originX @originY; - -ms-transform-origin:@originX @originY; - -o-transform-origin:@originX @originY; - transform-origin:@originX @originY; -} - -// Scale -.scale(@ratio:1.5) -{ - -webkit-transform:scale(@ratio); - -moz-transform:scale(@ratio); - transform:scale(@ratio); -} - -// Translate -.translate(@x:0, @y:0) -{ - -webkit-transform: translate(@x, @y); - -moz-transform: translate(@x, @y); - -ms-transform: translate(@x, @y); - -o-transform: translate(@x, @y); - transform: translate(@x, @y); -} - -// Columns -.columns(@colwidth: 250px, @colcount: 0, @colgap: 50px, @columnRuleColor: #EEE, @columnRuleStyle: solid, @columnRuleWidth: 1px) -{ - -webkit-column-width : @colwidth; - -webkit-column-count : @colcount; - -webkit-column-gap : @colgap; - -webkit-column-rule-color: @columnRuleColor; - -webkit-column-rule-style: @columnRuleStyle; - -webkit-column-rule-width: @columnRuleWidth; - -moz-column-width : @colwidth; - -moz-column-count : @colcount; - -moz-column-gap : @colgap; - -moz-column-rule-color: @columnRuleColor; - -moz-column-rule-style: @columnRuleStyle; - -moz-column-rule-width: @columnRuleWidth; - column-width : @colwidth; - column-count : @colcount; - column-gap : @colgap; - column-rule-color: @columnRuleColor; - column-rule-style: @columnRuleStyle; - column-rule-width: @columnRuleWidth; -} - -.edit-link(@bc:#CCFF2F,@c:#333) -{ - .dib; - background-color:@bc; - border:1px solid; - border-color:darken(desaturate(@bc, 35%),15%) darken(desaturate(@bc, 35%),15%) darken(desaturate(@bc, 35%),20%); - .rounded; - color: @c; - cursor: pointer; - .font-size(.8em,1em); - font-weight: normal; - padding: 0.25em 0.75em; - margin-top:.5em; - - &:hover{background-color:darken(@bc, 20%);} - &:active{ - text-shadow: 0 1px 0 lighten(@bc,5%); - background-color:darken(@bc, 20%); - //.inset-shadow(0,0,2px,darken(@bc,60)); - } -} - -.loader(@fc:#000,@bc:#ccc,@h:8px,@radius:0px) -{ - // Safari/chrome - &::-webkit-progress-bar{background-color:@bc;.rounded(@radius);} - &::-webkit-progress-value{background-color:@fc;.rounded(@radius);} - // Firefox - &{background-color:@bc;.rounded(@radius);height:@h;} - &::-moz-progress-bar{background-color:@fc;.rounded(@radius);} -} - -// = -// = -// = -// = -// = -// ===== RETINA ========================================================================================================== - -// retina.less -// A helper mixin for applying high-resolution background images (http://www.retinajs.com) -.at2x(@path, @w: auto, @h: auto) { - background-image: url(@path); - @at2x_path: ~`"@{path}".split('.').slice(0, "@{path}".split('.').length - 1).join(".") + "@2x" + "." + "@{path}".split('.')["@{path}".split('.').length - 1]`; - - @media all and (-webkit-min-device-pixel-ratio : 1.5) { - background-image: url(@at2x_path); - background-size: @w @h; - } -} diff --git a/sites/all/themes/gui/materiobasetheme/components/gui/gui.less.orig b/sites/all/themes/gui/materiobasetheme/components/gui/gui.less.orig deleted file mode 100644 index 5e84a944..00000000 --- a/sites/all/themes/gui/materiobasetheme/components/gui/gui.less.orig +++ /dev/null @@ -1,636 +0,0 @@ -<<<<<<< HEAD -/** -* www.g-u-i.net -*/ - -/** font */ - -.8{font-size:8px;} -.9{font-size:9px;} -.10{font-size:10px;} -.11{font-size:10px;} -.12{font-size:12px;} -.14{font-size:14px;} -.16{font-size:16px;} -.18{font-size:18px;} -.20{font-size:18px;} -.24{font-size:24px;} -.28{font-size:28px;} -.30{font-size:30px;} -.36{font-size:36px;} -.48{font-size:48px;} -.60{font-size:60px;} -.72{font-size:72px;} - -.regular{font-weight:normal;} -.bold{font-weight:bold;} -.100{font-weight:100;} -.300{font-weight:300;} -.500{font-weight:500;} -.700{font-weight:700;} -.900{font-weight:900;} - -.upper{text-transform: uppercase;} -.italic{font-style:italic;} -.normal{font-style: normal;} - - -/** shortcuts */ -======= -/* - * www.g-u-i.net - */ - -// = -// = -// = -// = -// = -// ===== TYPOGRAHIE ====================================================================================================== - -.8(){font-size:8px;} -.9(){font-size:9px;} -.10(){font-size:10px;} -.11(){font-size:10px;} -.12(){font-size:12px;} -.14(){font-size:14px;} -.16(){font-size:16px;} -.18(){font-size:18px;} -.24(){font-size:24px;} -.30(){font-size:30px;} -.36(){font-size:36px;} -.48(){font-size:48px;} -.60(){font-size:60px;} -.72(){font-size:72px;} - -.regular(){font-weight:normal;} -.bold(){font-weight:bold;} -.100(){font-weight:100;} -.300(){font-weight:300;} -.500(){font-weight:500;} -.700(){font-weight:700;} -.900(){font-weight:900;} - -.upper(){text-transform: uppercase;} -.italic(){font-style:italic;} -.normal(){font-style: normal;} - -.hyphens(@value: auto) -{ - -webkit-hyphens:@value; - -moz-hyphens:@value; - -ms-hyphens:@value; - -o-hyphens:@value; - hyphens:@value; -} -.font-size(@value: 1em,@lineheight:1.3em) -{ - font-size:@value; - line-height:@lineheight; -} - -@green:#17942A; -@red:#E60000; - -// = -// = -// = -// = -// = -// ===== SHORTCUTS ======================================================================================================= ->>>>>>> bitbucket/master - -// padding -.p(@p){ padding:@arguments; } -.p(@v, @h){ padding:@arguments; } -.p(@t, @l, @b, @l){ padding:@arguments; } - -.pt(@p){ padding-top:@p; } -.pr(@p){ padding-right:@p; } -.pb(@p){ padding-bottom:@p; } -.pl(@p){ padding-left:@p; } - -// margin -.m(@p){ margin:@arguments; } -.m(@v, @h){ margin:@arguments; } -.m(@t, @l, @b, @l){ margin:@arguments; } - -.mt(@m){ margin-top:@m; } -.mr(@m){ margin-right:@m; } -.mb(@m){ margin-bottom:@m; } -.ml(@m){ margin-left:@m; } - -.0(){ margin:0; padding:0; } - -// border -.b(@b){ border: @b; } -.b(@size, @color){ border: @size solid @color; } - -.bt(@b){ border-top: @b;} -.bt(@size, @color){border-top: @size solid @color;} - -.br(@b){ border-right: @b;} -.br(@size, @color){border-right: @size solid @color;} - -.bb(@b){ border-bottom: @b;} -.bb(@size, @color){border-bottom: @size solid @color;} - -.bl(@b){ border-left: @b;} -.bl(@size, @color){border-left: @size solid @color;} - -.bordered(@top-color: #EEE, @right-color: #EEE, @bottom-color: #EEE, @left-color: #EEE) -{ - border-top : solid 1px @top-color; - border-right : solid 1px @right-color; - border-bottom: solid 1px @bottom-color; - border-left : solid 1px @left-color; -} - -// Background -.bg(@color, @url, @repeat, @scrollfixed, @pos){background: @arguments;} -.bgc(@color){background-color: @arguments;} -.bkgd(@params){background: @arguments;} -.bkgdc(@color){.bgc(@arguments);} - -<<<<<<< HEAD -// opacity -.opacity(@opacity: 0.5) { - -moz-opacity: @opacity; - -khtml-opacity: @opacity; - -webkit-opacity: @opacity; - opacity: @opacity; -} - -/** Inline blocks */ -.inlineblock(){ - display:moz-inline-stack; - display:inline-block; - vertical-align:top; - zoom:1; - *display:inline; - /* margin-right:-.25em;*/ - .ie7 &{display:inline;} -} - - -// selection style -.selection(@bgcolor,@color){ -======= -// Selection -.selection(@bgcolor,@color) -{ ->>>>>>> bitbucket/master - &::selection { - background:@bgcolor; - color:@color; - } - &::-moz-selection { - background:@bgcolor; - color:@color; - } - &::-webkit-selection { - background:@bgcolor; - color:@color; - } -} - -// Colors -.color(@value) -{ - &, - & *{color:@value;} -} - -// Opacity -.opacity(@opacity: 0.5) -{ - -webkit-opacity: @opacity; - -khtml-opacity: @opacity; - -moz-opacity: @opacity; - opacity: @opacity; -} - -// size -.size(@height, @width) { - width: @width; - height: @height; -} -.square(@size) { - .size(@size, @size); -} - -// center -.center-block() { - display: block; - margin-left: auto; - margin-right: auto; -} - -// = -// = -// = -// = -// = -// ===== DISPLAY UTILS =================================================================================================== - -// Inline blocks -.inlineblock(@align:top) -{ - display:moz-inline-stack; - display:inline-block; - vertical-align:@align; - zoom:1; - *display:inline; - .ie7 &, .ie8 &{display:block;float:left;} -} - -.db(){display:block;} -.dib(){.inlineblock;} -.dib(@align){.inlineblock(@align);} - -// Vertical alignement -// -// ___ .align-child() -// | -// | Permet l’alignement vertical d’un objet par rapport à son premier parent (dans son conteneur direct). -// | -// | 1 param : @vertical-align -// -.align-child(@align:middle){ - &:before { content: ""; .dib(middle); overflow: hidden; visibility: hidden; width: 0; height: 100%; } - & > * { .dib(@align); } -} - -.clear-after(){ - &:after{clear:both;content:'';display:block;height:0px;overflow:hidden;visibility:hidden;width:0px;} -} - -// For clearing floats like a boss h5bp.com/q -.clearix() { - *zoom: 1; - &:before, - &:after { - display: table; - content: ""; - // Fixes Opera/contenteditable bug: - // http://nicolasgallagher.com/micro-clearfix-hack/#comment-36952 - line-height: 0; - } - &:after { - clear: both; - } -} - -// = -// = -// = -// = -// = -// ===== CSS3 ============================================================================================================ - -// Gradients -.gradient(@color: #F5F5F5, @start: #EEE, @stop: #FFF) -{ - background: @color; - background: -webkit-gradient(linear, - left bottom, - left top, - color-stop(0, @start), - color-stop(1, @stop)); - background: -ms-linear-gradient(bottom, - @start, - @stop); - background: -moz-linear-gradient(center bottom, - @start 0%, - @stop 100%); -} -.bw-gradient(@color: #F5F5F5, @start: 0, @stop: 255) -{ - background: @color; - background: -webkit-gradient(linear, - left bottom, - left top, - color-stop(0, rgb(@start,@start,@start)), - color-stop(1, rgb(@stop,@stop,@stop))); - background: -ms-linear-gradient(bottom, - rgb(@start,@start,@start) 0%, - rgb(@start,@start,@start) 100%); - background: -moz-linear-gradient(center bottom, - rgb(@start,@start,@start) 0%, - rgb(@stop,@stop,@stop) 100%); -} - -// Shadows -// -// ___ .box-shadow() -// | -// | Ombré extérieur. -// | -// | 1 param : @blur -// | 2+ params : @horizontal / @vertical / @blur / @color: #000 / @spread: 0px -// -// ___ .inset-shadow() -// | -// | Ombré intérieur. -// | -// | 1 param : @blur -// | 2+ params : @horizontal / @vertical / @blur / @color: #000 / @spread: 0px -// -.box-shadow(@blur: 9px) -{ - filter: progid:DXImageTransform.Microsoft.dropshadow(OffX=0, OffY=0, Color='#000'); - -ms-filter: "progid:DXImageTransform.Microsoft.dropshadow(OffX=0, OffY=0, Color='#000')"; - -webkit-box-shadow: 0 0 @blur #000; - -moz-box-shadow: 0 0 @blur #000; - -ms-box-shadow: 0 0 @blur #000; - box-shadow: 0 0 @blur #000; -} -.box-shadow(@x, @y, @blur: 9px, @color: #000, @spread: 0px) -{ - filter: progid:DXImageTransform.Microsoft.dropshadow(OffX=@x, OffY=@y, Color=~'@{color}'); - -ms-filter: "progid:DXImageTransform.Microsoft.dropshadow(OffX=@{x}, OffY=@{y}, Color='@{color}')"; - -webkit-box-shadow: @x @y @blur @spread @color; - -moz-box-shadow: @x @y @blur @spread @color; - -ms-box-shadow: @x @y @blur @spread @color; - box-shadow: @x @y @blur @spread @color; -} -.inset-shadow(@blur: 9px) -{ - filter: progid:DXImageTransform.Microsoft.dropshadow(OffX=0, OffY=0, Color='#000'); - -ms-filter: "progid:DXImageTransform.Microsoft.dropshadow(OffX=0, OffY=0, Color='#000')"; - -webkit-box-shadow: 0 0 @blur #000 inset; - -moz-box-shadow: 0 0 @blur #000 inset; - -ms-box-shadow: 0 0 @blur #000 inset; - box-shadow: 0 0 @blur #000 inset; -} -.inset-shadow(@x, @y, @blur: 9px, @color: #000, @spread: 0px) -{ - filter: progid:DXImageTransform.Microsoft.dropshadow(OffX=@x, OffY=@y, Color=~'@{color}'); - -ms-filter: "progid:DXImageTransform.Microsoft.dropshadow(OffX=0, OffY=0, Color='@{color}')"; - -webkit-box-shadow: @x @y @blur @spread @color inset; - -moz-box-shadow: @x @y @blur @spread @color inset; - -ms-box-shadow: @x @y @blur @spread @color inset; - box-shadow: @x @y @blur @spread @color inset; -} - -// Border radius -.rounded(@radius: 2px) -{ - -webkit-border-radius: @radius; - -moz-border-radius: @radius; - border-radius: @radius; - -webkit-background-clip: padding-box; - -moz-background-clip: padding; - background-clip: padding-box; -} -.border-radius(@topleft: 0, @topright: 0, @bottomright: 0, @bottomleft: 0) -{ - -webkit-border-radius:@arguments; - -moz-border-radius:@arguments; - border-radius:@arguments; - -webkit-background-clip: padding-box; - -moz-background-clip: padding; - background-clip: padding-box; -} - -<<<<<<< HEAD -// transitions -.transition-simply-prefix(@string) { - -webkit-transition: @string; - -moz-transition: @string; - -o-transition: @string; - transition: @string; -======= -// Transition -// -// ___ .transition() -// | -// | 1 param : @property -// | 2 params : @property / @duration -// | 3+ params : @property / @duration / @transitiondelay:0s , @timingfunction:ease-out -// -// ___ .transitions() -// | -// | Permet de fixer des paramètres spécifique par propriétés, exemple: -// | -// | .transitions( -// | 'height , padding , margin , box-shadow', -// | '.5s , .2s , .2s , .2s', -// | '0s , 0s , 0s , .3s', -// | 'linear , ease-out , linear , ease-out' -// | ); -// -.transition(@property: all) -{ - -webkit-transition: @property; - -moz-transition: @property; - -o-transition: @property; - transition: @property; ->>>>>>> bitbucket/master -} -.transition(@property, @duration) -{ - -webkit-transition: @arguments; - -moz-transition: @arguments; - -o-transition: @arguments; - transition: @arguments; -} -.transition(@property, @duration, @transitiondelay, @timingfunction:ease-out) -{ - -webkit-transition: @arguments; - -moz-transition: @arguments; - -o-transition: @arguments; - transition: @arguments; -} -.transitions(@property: all, @duration:0s, @transitiondelay:0s, @timingfunction:ease-out) -{ - -webkit-transition-property :~'@{property}'; - -webkit-transition-duration :~'@{duration}'; - -webkit-transition-delay :~'@{transitiondelay}'; - -webkit-transition-timing-function:~'@{timingfunction}'; - -moz-transition-property :~'@{property}'; - -moz-transition-duration :~'@{duration}'; - -moz-transition-delay :~'@{transitiondelay}'; - -moz-transition-timing-function:~'@{timingfunction}'; - -o-transition-property :~'@{property}'; - -o-transition-duration :~'@{duration}'; - -o-transition-delay :~'@{transitiondelay}'; - -o-transition-timing-function:~'@{timingfunction}'; - transition-property :~'@{property}'; - transition-duration :~'@{duration}'; - transition-delay :~'@{transitiondelay}'; - transition-timing-function:~'@{timingfunction}'; -} -<<<<<<< HEAD -.transition(@p, @d, @e, @de) { - -webkit-transition: @arguments; - -moz-transition: @arguments; - -o-transition: @arguments; - transition: @arguments; -} -.transition-delay(@delay: 0s) { - -webkit-transition-delay: @delay; - -moz-transition-delay: @delay; - -o-transition-delay: @delay; - transition-delay: @delay; -} -// rotation -.rotation(@deg:5deg){ -======= - -.transitions-duration(@duration: 0s) -{ - -webkit-transition-duration: ~'@{duration}'; - -moz-transition-duration: ~'@{duration}'; - -o-transition-duration: ~'@{duration}'; - transition-duration: ~'@{duration}'; -} - -.transition-duration(@duration: 0.2s) -{ - -webkit-transition-duration: @duration; - -moz-transition-duration: @duration; - -o-transition-duration: @duration; - transition-duration: @duration; -} - -// Rotate -// -// ___ .rotation() -// | -// | 1 param : @degree -// -// ___ .rotate() -// | -// | Tentative de compatibilté étendue (fonctionne uniquement pour 0, 90, 180 ou 270 degrés). -// | -// | 1 param : @degree -// | 3 params : @degree / @originX / @originY -// -.rotation(@deg:5deg) -{ ->>>>>>> bitbucket/master - -webkit-transform: rotate(@deg); - -moz-transform: rotate(@deg); - transform: rotate(@deg); -} -.rotate(@value, @originX:0%, @originY:0%, @unit:'deg') -{ - filter: progid:DXImageTransform.Microsoft.BasicImage(rotation = (360 / @value) + 1); //0, 1, 2, or 3 rotate 0, 90, 180 or 270 - -webkit-transform: rotate(~"@{value}@{unit}"); // ~"@{value}@{unit}" rather than @value@unit remove the spaces between value and unit. - -moz-transform: rotate(~"@{value}@{unit}"); - -ms-transform: rotate(~"@{value}@{unit}"); - -o-transform: rotate(~"@{value}@{unit}"); - transform: rotate(~"@{value}@{unit}"); - -webkit-transform-origin:@originX @originY; - -moz-transform-origin:@originX @originY; - -ms-transform-origin:@originX @originY; - -o-transform-origin:@originX @originY; - transform-origin:@originX @originY; -} - -// Scale -.scale(@ratio:1.5) -{ - -webkit-transform:scale(@ratio); -<<<<<<< HEAD - -moz-transform:scale(@ratio); - transform:scale(@ratio); -} - -// columns -.columns(@colwidth: 250px) { - -moz-column-width: @colwidth; - -webkit-column-width: @colwidth; - column-width: @colwidth; -} - -.columns(@colwidth: 250px, @colcount: 0, @colgap: 50px, @columnRuleColor: #EEE, @columnRuleStyle: solid, @columnRuleWidth: 1px) { - -moz-column-width: @colwidth; - -moz-column-count: @colcount; - -moz-column-gap: @colgap; - -moz-column-rule-color: @columnRuleColor; - -moz-column-rule-style: @columnRuleStyle; - -moz-column-rule-width: @columnRuleWidth; - -webkit-column-width: @colwidth; - -webkit-column-count: @colcount; - -webkit-column-gap: @colgap; -======= - -moz-transform:scale(@ratio); - transform:scale(@ratio); -} - -// Translate -.translate(@x:0, @y:0) -{ - -webkit-transform: translate(@x, @y); - -moz-transform: translate(@x, @y); - -ms-transform: translate(@x, @y); - -o-transform: translate(@x, @y); - transform: translate(@x, @y); -} - -// Columns -.columns(@colwidth: 250px, @colcount: 0, @colgap: 50px, @columnRuleColor: #EEE, @columnRuleStyle: solid, @columnRuleWidth: 1px) -{ - -webkit-column-width : @colwidth; - -webkit-column-count : @colcount; - -webkit-column-gap : @colgap; ->>>>>>> bitbucket/master - -webkit-column-rule-color: @columnRuleColor; - -webkit-column-rule-style: @columnRuleStyle; - -webkit-column-rule-width: @columnRuleWidth; - -moz-column-width : @colwidth; - -moz-column-count : @colcount; - -moz-column-gap : @colgap; - -moz-column-rule-color: @columnRuleColor; - -moz-column-rule-style: @columnRuleStyle; - -moz-column-rule-width: @columnRuleWidth; - column-width : @colwidth; - column-count : @colcount; - column-gap : @colgap; - column-rule-color: @columnRuleColor; - column-rule-style: @columnRuleStyle; - column-rule-width: @columnRuleWidth; -} - -.edit-link(@bc:#CCFF2F,@c:#333) -{ - .dib; - background-color:@bc; - border:1px solid; - border-color:darken(desaturate(@bc, 35%),15%) darken(desaturate(@bc, 35%),15%) darken(desaturate(@bc, 35%),20%); - .rounded; - color: @c; - cursor: pointer; - .font-size(.8em,1em); - font-weight: normal; - padding: 0.25em 0.75em; - margin-top:.5em; - - &:hover{background-color:darken(@bc, 20%);} - &:active{ - text-shadow: 0 1px 0 lighten(@bc,5%); - background-color:darken(@bc, 20%); - //.inset-shadow(0,0,2px,darken(@bc,60)); - } -} - -// = -// = -// = -// = -// = -// ===== RETINA ========================================================================================================== - -// retina.less -// A helper mixin for applying high-resolution background images (http://www.retinajs.com) -.at2x(@path, @w: auto, @h: auto) { - background-image: url(@path); - @at2x_path: ~`"@{path}".split('.').slice(0, "@{path}".split('.').length - 1).join(".") + "@2x" + "." + "@{path}".split('.')["@{path}".split('.').length - 1]`; - - @media all and (-webkit-min-device-pixel-ratio : 1.5) { - background-image: url(@at2x_path); - background-size: @w @h; - } -} diff --git a/sites/all/themes/gui/materiobasetheme/css/layout.css b/sites/all/themes/gui/materiobasetheme/css/layout.css index 48b726f3..ca15b571 100644 --- a/sites/all/themes/gui/materiobasetheme/css/layout.css +++ b/sites/all/themes/gui/materiobasetheme/css/layout.css @@ -1,23 +1,23 @@ /* Error: Undefined mixin 'transition'. - on line 108 of /home/sarahgarcin/Sites/materio/base_d7/sites/all/themes/gui/materiobasetheme/scss/layout.scss, in `transition' - from line 108 of /home/sarahgarcin/Sites/materio/base_d7/sites/all/themes/gui/materiobasetheme/scss/layout.scss + on line 131 of /home/sarahgarcin/Sites/materio/base_d7/sites/all/themes/gui/materiobasetheme/scss/layout.scss, in `transition' + from line 131 of /home/sarahgarcin/Sites/materio/base_d7/sites/all/themes/gui/materiobasetheme/scss/layout.scss -103: } -104: -105: /** NIVEAU 1 *\/ -106: #container{ -107: margin:0 auto; position:relative; -108: @include transition(padding-top 0.5s ease-out); // change this -109: } -110: -111: /** NIVEAU 2 *\/ -112: @mixin padded(){ $p:2%; width:100%-2*$p; padding-left:$p; padding-right:$p; } -113: +126: } +127: +128: /** NIVEAU 1 *\/ +129: #container{ +130: margin:0 auto; position:relative; +131: @include transition(padding-top 0.5s ease-out); // change this +132: } +133: +134: /** NIVEAU 2 *\/ +135: @mixin padded(){ $p:2%; width:100%-2*$p; padding-left:$p; padding-right:$p; } +136: Backtrace: -/home/sarahgarcin/Sites/materio/base_d7/sites/all/themes/gui/materiobasetheme/scss/layout.scss:108:in `transition' -/home/sarahgarcin/Sites/materio/base_d7/sites/all/themes/gui/materiobasetheme/scss/layout.scss:108 +/home/sarahgarcin/Sites/materio/base_d7/sites/all/themes/gui/materiobasetheme/scss/layout.scss:131:in `transition' +/home/sarahgarcin/Sites/materio/base_d7/sites/all/themes/gui/materiobasetheme/scss/layout.scss:131 /usr/lib/ruby/gems/2.2.0/gems/compass-1.0.3/vendor/bundle/ruby/2.2.0/gems/sass-3.4.13/lib/sass/tree/visitors/perform.rb:348:in `block in visit_mixin' /usr/lib/ruby/gems/2.2.0/gems/compass-1.0.3/vendor/bundle/ruby/2.2.0/gems/sass-3.4.13/lib/sass/stack.rb:98:in `block in with_mixin' /usr/lib/ruby/gems/2.2.0/gems/compass-1.0.3/vendor/bundle/ruby/2.2.0/gems/sass-3.4.13/lib/sass/stack.rb:115:in `with_frame' @@ -71,4 +71,4 @@ Backtrace: body:before { white-space: pre; font-family: monospace; - content: "Error: Undefined mixin 'transition'.\A on line 108 of /home/sarahgarcin/Sites/materio/base_d7/sites/all/themes/gui/materiobasetheme/scss/layout.scss, in `transition'\A from line 108 of /home/sarahgarcin/Sites/materio/base_d7/sites/all/themes/gui/materiobasetheme/scss/layout.scss\A \A 103: }\A 104: \A 105: /** NIVEAU 1 */\A 106: #container{ \A 107: margin:0 auto; position:relative; \A 108: @include transition(padding-top 0.5s ease-out); // change this\A 109: }\A 110: \A 111: /** NIVEAU 2 */\A 112: @mixin padded(){ $p:2%; width:100%-2*$p; padding-left:$p; padding-right:$p; }\A 113: "; } + content: "Error: Undefined mixin 'transition'.\A on line 131 of /home/sarahgarcin/Sites/materio/base_d7/sites/all/themes/gui/materiobasetheme/scss/layout.scss, in `transition'\A from line 131 of /home/sarahgarcin/Sites/materio/base_d7/sites/all/themes/gui/materiobasetheme/scss/layout.scss\A \A 126: }\A 127: \A 128: /** NIVEAU 1 */\A 129: #container{ \A 130: margin:0 auto; position:relative; \A 131: @include transition(padding-top 0.5s ease-out); // change this\A 132: }\A 133: \A 134: /** NIVEAU 2 */\A 135: @mixin padded(){ $p:2%; width:100%-2*$p; padding-left:$p; padding-right:$p; }\A 136: "; } diff --git a/sites/all/themes/gui/materiobasetheme/css/misc.css b/sites/all/themes/gui/materiobasetheme/css/misc.css index 075d9ee4..bcaf8b07 100644 --- a/sites/all/themes/gui/materiobasetheme/css/misc.css +++ b/sites/all/themes/gui/materiobasetheme/css/misc.css @@ -9,7 +9,7 @@ Error: Undefined mixin 'fs12'. 9: -moz-border-radius: 5px; 10: -webkit-border-radius: 5px; 11: border-radius: 5px; -12: @include fs12(); +12: @include fs12; 13: 14: &.warning { 15: color: #c09853;//#840; @@ -90,4 +90,4 @@ Backtrace: body:before { white-space: pre; font-family: monospace; - content: "Error: Undefined mixin 'fs12'.\A on line 12 of /home/sarahgarcin/Sites/materio/base_d7/sites/all/themes/gui/materiobasetheme/scss/misc.scss, in `fs12'\A from line 12 of /home/sarahgarcin/Sites/materio/base_d7/sites/all/themes/gui/materiobasetheme/scss/misc.scss, in `messages'\A from line 36 of /home/sarahgarcin/Sites/materio/base_d7/sites/all/themes/gui/materiobasetheme/scss/misc.scss\A \A 7: background: #d9edf7;//#cf8;\A 8: border: 1px solid #bce8f1;//#be7;\A 9: -moz-border-radius: 5px;\A 10: -webkit-border-radius: 5px;\A 11: border-radius: 5px;\A 12: @include fs12();\A 13: \A 14: &.warning {\A 15: color: #c09853;//#840;\A 16: background-color: #fcf8e3;//#fe6;\A 17: border-color: #fbeed5;//#ed5;"; } + content: "Error: Undefined mixin 'fs12'.\A on line 12 of /home/sarahgarcin/Sites/materio/base_d7/sites/all/themes/gui/materiobasetheme/scss/misc.scss, in `fs12'\A from line 12 of /home/sarahgarcin/Sites/materio/base_d7/sites/all/themes/gui/materiobasetheme/scss/misc.scss, in `messages'\A from line 36 of /home/sarahgarcin/Sites/materio/base_d7/sites/all/themes/gui/materiobasetheme/scss/misc.scss\A \A 7: background: #d9edf7;//#cf8;\A 8: border: 1px solid #bce8f1;//#be7;\A 9: -moz-border-radius: 5px;\A 10: -webkit-border-radius: 5px;\A 11: border-radius: 5px;\A 12: @include fs12;\A 13: \A 14: &.warning {\A 15: color: #c09853;//#840;\A 16: background-color: #fcf8e3;//#fe6;\A 17: border-color: #fbeed5;//#ed5;"; } diff --git a/sites/all/themes/gui/materiobasetheme/css/styles.css b/sites/all/themes/gui/materiobasetheme/css/styles.css index 3d35fe17..0d1d7aa9 100644 --- a/sites/all/themes/gui/materiobasetheme/css/styles.css +++ b/sites/all/themes/gui/materiobasetheme/css/styles.css @@ -9640,45 +9640,69 @@ input, button, select, textarea { * { box-sizing: content-box; } +/* line 68, ../scss/layout.scss */ +*:before, *:after { + box-sizing: content-box; +} -/* line 76, ../scss/layout.scss */ +/* line 79, ../scss/layout.scss */ body { overflow-y: scroll; top: 0; } -/* line 80, ../scss/layout.scss */ +/* line 83, ../scss/layout.scss */ h1, h2, h3, h4, h5, h6 { font-family: inherit; } -/* line 84, ../scss/layout.scss */ +/* line 87, ../scss/layout.scss */ h1 { font-weight: bold; } -/* line 88, ../scss/layout.scss */ +/* line 91, ../scss/layout.scss */ figure { margin: 0; } -/* line 92, ../scss/layout.scss */ +/* line 95, ../scss/layout.scss */ input[type="checkbox"] + label { margin: 0; } -/** NIVEAU 0 */ /* line 99, ../scss/layout.scss */ +p { + font-family: inherit; + font-weight: inherit; + font-size: inherit; + line-height: inherit; + margin-bottom: inherit; +} + +/* line 107, ../scss/layout.scss */ +a { + font-size: inherit; +} + +/* line 111, ../scss/layout.scss */ +.column, .columns { + padding: inherit; + float: inherit; +} + +/** NIVEAU 0 */ +/* line 119, ../scss/layout.scss */ #root { min-width: 320px; } -/* line 102, ../scss/layout.scss */ +/* line 122, ../scss/layout.scss */ .ie8 #root { min-width: 1024px; } /** NIVEAU 1 */ -/* line 106, ../scss/layout.scss */ +/* line 126, ../scss/layout.scss */ #container { margin: 0 auto; position: relative; @@ -9687,7 +9711,7 @@ input[type="checkbox"] + label { } /** NIVEAU 2 */ -/* line 115, ../scss/layout.scss */ +/* line 135, ../scss/layout.scss */ #header { z-index: 1000; width: 96%; @@ -9695,7 +9719,7 @@ input[type="checkbox"] + label { padding-right: 2%; } @media only screen and (min-width: 40.063em) { - /* line 115, ../scss/layout.scss */ + /* line 135, ../scss/layout.scss */ #header { position: fixed; top: 0; @@ -9704,16 +9728,16 @@ input[type="checkbox"] + label { min-width: 310.4px; } } -/* line 121, ../scss/layout.scss */ +/* line 141, ../scss/layout.scss */ .editmenu-enabled #header { margin-top: 30px; } -/* line 122, ../scss/layout.scss */ +/* line 142, ../scss/layout.scss */ .admin-menu #header { margin-top: 35px; } -/* line 125, ../scss/layout.scss */ +/* line 145, ../scss/layout.scss */ #utilities { z-index: 999; background-color: #fff; @@ -9722,7 +9746,7 @@ input[type="checkbox"] + label { padding-right: 2%; } @media only screen and (min-width: 40.063em) { - /* line 127, ../scss/layout.scss */ + /* line 147, ../scss/layout.scss */ html.no-touch #utilities { position: fixed; top: 0; @@ -9730,24 +9754,24 @@ input[type="checkbox"] + label { min-width: 310.4px; margin-top: 60px; } - /* line 131, ../scss/layout.scss */ + /* line 151, ../scss/layout.scss */ html.no-touch .editmenu-enabled #utilities { margin-top: 80px; } - /* line 132, ../scss/layout.scss */ + /* line 152, ../scss/layout.scss */ html.no-touch .admin-menu #utilities { margin-top: 85px; } } -@media only screen and (min-width: 40.063em) and (max-width: 64em) { - /* line 135, ../scss/layout.scss */ +@media only screen and (max-width: 40em) { + /* line 155, ../scss/layout.scss */ #utilities > .region { padding-top: 5px; padding-bottom: 5px; } } -/* line 143, ../scss/layout.scss */ +/* line 163, ../scss/layout.scss */ #main { width: 96%; padding-left: 2%; @@ -9755,7 +9779,7 @@ input[type="checkbox"] + label { overflow-x: hidden; } -/* line 145, ../scss/layout.scss */ +/* line 165, ../scss/layout.scss */ #footer { width: 96%; padding-left: 2%; @@ -9764,23 +9788,23 @@ input[type="checkbox"] + label { /** NIVEAU 3 */ /** NIVEAU 4 */ -/* line 159, ../scss/layout.scss */ +/* line 179, ../scss/layout.scss */ #center { padding: 5px; } /** Z-INDEX */ -/* line 162, ../scss/layout.scss */ +/* line 182, ../scss/layout.scss */ #block-feedback-form { z-index: 1001; } -/* line 163, ../scss/layout.scss */ +/* line 183, ../scss/layout.scss */ #admin-menu { z-index: 1002; } -/* line 164, ../scss/layout.scss */ +/* line 184, ../scss/layout.scss */ #admin-toolbar { z-index: 1003; } @@ -10144,7 +10168,7 @@ html.no-touch #header #header-blocks #block-user-login:hover form#user-login-for /* line 347, ../scss/styles.scss */ #header #header-blocks #block-logintoboggan-logintoboggan-logged-in i { vertical-align: text-bottom; - margin: 0 2px 1px 0; + margin: 0 5px 1px 0; } /* line 351, ../scss/styles.scss */ #header #header-blocks #block-logintoboggan-logintoboggan-logged-in a span.account { @@ -11078,7 +11102,7 @@ html.js #highlighted .block-materio-didactique .tabs > *:hover, html.js #highlig display: none; font-size: 10px; } -@media only screen and (min-width: 40.063em) and (max-width: 64em) { +@media only screen and (max-width: 40em) { /* line 856, ../scss/styles.scss */ #tool-bar #block-materio-search-api-materio-search-api-viewmode .viewmode-link { display: block; @@ -11094,7 +11118,7 @@ html.js #highlighted .block-materio-didactique .tabs > *:hover, html.js #highlig display: block; } } -@media only screen and (min-width: 40.063em) and (max-width: 64em) { +@media only screen and (max-width: 40em) { /* line 863, ../scss/styles.scss */ html.no-touch #tool-bar #block-materio-search-api-materio-search-api-viewmode:hover .viewmode-link.viewmode-cardsmall, html.no-touch #tool-bar #block-materio-search-api-materio-search-api-viewmode:hover .viewmode-link.viewmode-cardmedium, html.no-touch #tool-bar #block-materio-search-api-materio-search-api-viewmode:hover .viewmode-link.viewmode-cardbig, #tool-bar #block-materio-search-api-materio-search-api-viewmode.hovered .viewmode-link.viewmode-cardsmall, #tool-bar #block-materio-search-api-materio-search-api-viewmode.hovered .viewmode-link.viewmode-cardmedium, #tool-bar #block-materio-search-api-materio-search-api-viewmode.hovered .viewmode-link.viewmode-cardbig { display: block; @@ -11175,60 +11199,61 @@ html.js #highlighted .block-materio-didactique .tabs > *:hover, html.js #highlig font-size: 12px; line-height: 1; background-position: 100% 5px; + width: 105%; } -/* line 897, ../scss/styles.scss */ +/* line 898, ../scss/styles.scss */ #tool-bar #materio-search-api-search-form input#edit-searchfield.throbbing { background-position: 100% -15px; } -/* line 901, ../scss/styles.scss */ +/* line 902, ../scss/styles.scss */ .oldie #tool-bar #materio-search-api-search-form #edit-searchfield-autocomplete-aria-live { background-color: #1a1a1a; } -/* line 906, ../scss/styles.scss */ +/* line 907, ../scss/styles.scss */ #tool-bar #materio-search-api-search-form input#edit-create { padding: 3px; } -/* line 908, ../scss/styles.scss */ +/* line 909, ../scss/styles.scss */ #tool-bar #materio-search-api-search-form.loading { background: transparent url("../img/ajax-loader.gif") no-repeat 98% center; } -/* line 910, ../scss/styles.scss */ +/* line 911, ../scss/styles.scss */ #tool-bar #materio-search-api-search-form.loading input#edit-create { visibility: hidden; } @media only screen and (max-width: 40em) { - /* line 914, ../scss/styles.scss */ + /* line 915, ../scss/styles.scss */ #tool-bar #materio-search-api-search-form input#edit-searchfield { width: 16em; } - /* line 915, ../scss/styles.scss */ + /* line 916, ../scss/styles.scss */ #tool-bar #materio-search-api-search-form #edit-bundles-filter { display: none; } } -/* line 921, ../scss/styles.scss */ +/* line 922, ../scss/styles.scss */ #center { background-color: #e6e6e6; border-radius: 10px; background-clip: padding-box; } -/* line 923, ../scss/styles.scss */ +/* line 924, ../scss/styles.scss */ .node-type-page #center { background-color: #fff; } -/* line 924, ../scss/styles.scss */ +/* line 925, ../scss/styles.scss */ .ie8 #center { height: 100%; margin-top: 20px; } -/* line 928, ../scss/styles.scss */ +/* line 929, ../scss/styles.scss */ #content { -webkit-transition: height 0.3s ease-out; transition: height 0.3s ease-out; } -/* line 932, ../scss/styles.scss */ +/* line 933, ../scss/styles.scss */ #content.faded { -webkit-opacity: 0.5; -khtml-opacity: 0.5; @@ -11237,49 +11262,49 @@ html.js #highlighted .block-materio-didactique .tabs > *:hover, html.js #highlig -webkit-transition: opacity 0.3s ease-out; transition: opacity 0.3s ease-out; } -/* line 937, ../scss/styles.scss */ +/* line 938, ../scss/styles.scss */ #content .materiobase-results, #content .materiobase-actuality, #content .materio-flags-list { padding: 0 0 30px 0; margin: 0 0 20px 0; } -/* line 940, ../scss/styles.scss */ +/* line 941, ../scss/styles.scss */ #content .materiobase-results.loading, #content .materiobase-actuality.loading, #content .materio-flags-list.loading { background-image: url("../img/ajax-loader.gif"); background-position: center bottom; background-repeat: no-repeat; } -/* line 946, ../scss/styles.scss */ +/* line 947, ../scss/styles.scss */ #content .materiobase-results p.search-performance, #content .materiobase-results p.flaglist-infos, #content .materiobase-results p.actualities-infos, #content .materiobase-actuality p.search-performance, #content .materiobase-actuality p.flaglist-infos, #content .materiobase-actuality p.actualities-infos, #content .materio-flags-list p.search-performance, #content .materio-flags-list p.flaglist-infos, #content .materio-flags-list p.actualities-infos { font-size: 12px; font-weight: 500; margin: 0; padding: 10px 0 5px 15px; } -/* line 952, ../scss/styles.scss */ +/* line 953, ../scss/styles.scss */ #content .materiobase-results .search-results, #content .materiobase-results .actuality-items, #content .materiobase-results .flaglist-items, #content .materiobase-actuality .search-results, #content .materiobase-actuality .actuality-items, #content .materiobase-actuality .flaglist-items, #content .materio-flags-list .search-results, #content .materio-flags-list .actuality-items, #content .materio-flags-list .flaglist-items { font-size: 0; text-align: center; } -/* line 954, ../scss/styles.scss */ +/* line 955, ../scss/styles.scss */ #content .materiobase-results .search-results > *, #content .materiobase-results .actuality-items > *, #content .materiobase-results .flaglist-items > *, #content .materiobase-actuality .search-results > *, #content .materiobase-actuality .actuality-items > *, #content .materiobase-actuality .flaglist-items > *, #content .materio-flags-list .search-results > *, #content .materio-flags-list .actuality-items > *, #content .materio-flags-list .flaglist-items > * { font-size: 16px; } -/* line 956, ../scss/styles.scss */ +/* line 957, ../scss/styles.scss */ #content .materiobase-results .search-results > *, #content .materiobase-results .actuality-items > *, #content .materiobase-results .flaglist-items > *, #content .materiobase-actuality .search-results > *, #content .materiobase-actuality .actuality-items > *, #content .materiobase-actuality .flaglist-items > *, #content .materio-flags-list .search-results > *, #content .materio-flags-list .actuality-items > *, #content .materio-flags-list .flaglist-items > * { text-align: left; } -/* line 962, ../scss/styles.scss */ +/* line 963, ../scss/styles.scss */ #content ul.pager { padding: 1em 0; text-align: left; } -/* line 964, ../scss/styles.scss */ +/* line 965, ../scss/styles.scss */ .ie8 #content ul.pager { position: absolute; left: 37px; bottom: 35px; } -/* line 966, ../scss/styles.scss */ +/* line 967, ../scss/styles.scss */ #content ul.pager li { margin: 0; display: moz-inline-stack; @@ -11289,46 +11314,46 @@ html.js #highlighted .block-materio-didactique .tabs > *:hover, html.js #highlig *display: inline; vertical-align: middle; } -/* line 968, ../scss/styles.scss */ +/* line 969, ../scss/styles.scss */ #content ul.pager .pager-current, #content ul.pager a { color: #000; font-size: 12px; } -/* line 969, ../scss/styles.scss */ +/* line 970, ../scss/styles.scss */ #content ul.pager .pager-current { font-weight: 900; font-size: 14px; } -/* line 969, ../scss/styles.scss */ +/* line 970, ../scss/styles.scss */ .ie8 #content ul.pager .pager-current { background: #fff; padding: 0.3em 1em 0.3em 1em; margin-top: 0.05em; border: 1px solid #333333; } -/* line 970, ../scss/styles.scss */ +/* line 971, ../scss/styles.scss */ #content ul.pager .pager-first a, #content ul.pager .pager-previous a, #content ul.pager .pager-next a, #content ul.pager .pager-last a { font-size: 24px; font-weight: 300; } /** #content-bottom */ -/* line 981, ../scss/styles.scss */ +/* line 982, ../scss/styles.scss */ #content-bottom { padding-top: 10px; } /** CARDS */ /** card search performance */ -/* line 1160, ../scss/styles.scss */ +/* line 1161, ../scss/styles.scss */ article.search-performance .inner { padding: 1em; } -/* line 1164, ../scss/styles.scss */ +/* line 1165, ../scss/styles.scss */ article.search-performance p { font-size: 14px; } -/* line 1166, ../scss/styles.scss */ +/* line 1167, ../scss/styles.scss */ article.search-performance a.button { display: block; margin: 10px auto; @@ -11358,7 +11383,7 @@ article.search-performance a.button:active { transition: text-shadow 0s ease-out; text-shadow: 0 0 2px rgba(0, 0, 0, 0.2); } -/* line 1174, ../scss/styles.scss */ +/* line 1175, ../scss/styles.scss */ article.search-performance.view-mode-cardsmall { width: 327px; height: 140px; @@ -11376,7 +11401,7 @@ article.search-performance.view-mode-cardsmall { -webkit-transition: box-shadow 0.3s ease-out; transition: box-shadow 0.3s ease-out; } -/* line 1177, ../scss/styles.scss */ +/* line 1178, ../scss/styles.scss */ article.search-performance.view-mode-cardmedium { width: 210px; height: 295px; @@ -11394,11 +11419,11 @@ article.search-performance.view-mode-cardmedium { -webkit-transition: box-shadow 0.3s ease-out; transition: box-shadow 0.3s ease-out; } -/* line 1179, ../scss/styles.scss */ +/* line 1180, ../scss/styles.scss */ article.search-performance.view-mode-cardmedium .inner { padding: 4em 1em 0; } -/* line 1183, ../scss/styles.scss */ +/* line 1184, ../scss/styles.scss */ article.search-performance.view-mode-cardbig { width: 425px; height: 115px; @@ -11418,7 +11443,7 @@ article.search-performance.view-mode-cardbig { display: block; margin: 0 auto; } -/* line 1187, ../scss/styles.scss */ +/* line 1188, ../scss/styles.scss */ article.search-performance.view-mode-cardfull { width: 850px; height: 115px; @@ -11438,13 +11463,13 @@ article.search-performance.view-mode-cardfull { display: block; margin: 0 auto; } -/* line 1189, ../scss/styles.scss */ +/* line 1190, ../scss/styles.scss */ article.search-performance.view-mode-cardfull .inner { padding: 1em 212px; } /** CARD BOOKMARKS */ -/* line 1197, ../scss/styles.scss */ +/* line 1198, ../scss/styles.scss */ article.node-materiau.vm-bookmark, article.node-breve.vm-bookmark { width: 50px; height: 70px; @@ -11463,41 +11488,41 @@ article.node-materiau.vm-bookmark, article.node-breve.vm-bookmark { transition: box-shadow 0.3s ease-out; margin: 3px; } -/* line 1015, ../scss/styles.scss */ +/* line 1016, ../scss/styles.scss */ article.node-materiau.vm-bookmark > div.side, article.node-breve.vm-bookmark > div.side { border-radius: 5px; background-clip: padding-box; overflow: hidden; } -/* line 1020, ../scss/styles.scss */ +/* line 1021, ../scss/styles.scss */ article.node-materiau.vm-bookmark.focused, article.node-breve.vm-bookmark.focused { box-shadow: 0 0 7px rgba(0, 0, 0, 0.9); } -/* line 1022, ../scss/styles.scss */ +/* line 1023, ../scss/styles.scss */ article.node-materiau.vm-bookmark.just-added, article.node-breve.vm-bookmark.just-added { -webkit-opacity: 0; -khtml-opacity: 0; -moz-opacity: 0; opacity: 0; } -/* line 1024, ../scss/styles.scss */ +/* line 1025, ../scss/styles.scss */ article.node-materiau.vm-bookmark.associated, article.node-breve.vm-bookmark.associated { -webkit-transition: margin 0.3s ease-out; transition: margin 0.3s ease-out; } -/* line 1026, ../scss/styles.scss */ +/* line 1027, ../scss/styles.scss */ article.node-materiau.vm-bookmark.associated.just-added, article.node-breve.vm-bookmark.associated.just-added { margin-left: -50px; margin-right: 50px; } -/* line 1028, ../scss/styles.scss */ +/* line 1029, ../scss/styles.scss */ .modal-content article.node-materiau.vm-bookmark.associated, .modal-content article.node-breve.vm-bookmark.associated { position: absolute; top: 0; left: 0; z-index: 999; } -/* line 1036, ../scss/styles.scss */ +/* line 1037, ../scss/styles.scss */ article.node-materiau.vm-bookmark.removed, article.node-breve.vm-bookmark.removed { -webkit-transition: width 0.3s ease-out; transition: width 0.3s ease-out; @@ -11508,7 +11533,7 @@ article.node-materiau.vm-bookmark.removed, article.node-breve.vm-bookmark.remove margin-left: 0; overflow: hidden; } -/* line 1046, ../scss/styles.scss */ +/* line 1047, ../scss/styles.scss */ article.node-materiau.vm-bookmark nav.nav, article.node-breve.vm-bookmark nav.nav { position: absolute; top: 0; @@ -11523,39 +11548,39 @@ article.node-materiau.vm-bookmark nav.nav, article.node-breve.vm-bookmark nav.na *background-color: white; color: #000; } -/* line 1058, ../scss/styles.scss */ +/* line 1059, ../scss/styles.scss */ article.node-materiau.vm-bookmark nav.nav a, article.node-breve.vm-bookmark nav.nav a { color: #000; } -/* line 1059, ../scss/styles.scss */ +/* line 1060, ../scss/styles.scss */ article.node-materiau.vm-bookmark nav.nav ul, article.node-breve.vm-bookmark nav.nav ul { background-color: white; background-color: rgba(255, 255, 255, 0.9); *background-color: white; } -/* line 1060, ../scss/styles.scss */ +/* line 1061, ../scss/styles.scss */ article.node-materiau.vm-bookmark nav.nav span.op, article.node-breve.vm-bookmark nav.nav span.op { font-weight: 900; font-size: 14px; } -/* line 1062, ../scss/styles.scss */ +/* line 1063, ../scss/styles.scss */ article.node-materiau.vm-bookmark nav.nav ul, article.node-breve.vm-bookmark nav.nav ul { padding: 0; margin: 0; } -/* line 1064, ../scss/styles.scss */ +/* line 1065, ../scss/styles.scss */ article.node-materiau.vm-bookmark nav.nav section, article.node-breve.vm-bookmark nav.nav section { position: relative; } -/* line 1067, ../scss/styles.scss */ +/* line 1068, ../scss/styles.scss */ article.node-materiau.vm-bookmark nav.nav section > i, article.node-breve.vm-bookmark nav.nav section > i { margin: 0 5px; } -/* line 1067, ../scss/styles.scss */ +/* line 1068, ../scss/styles.scss */ article.node-materiau.vm-bookmark nav.nav section > i:hover, article.node-breve.vm-bookmark nav.nav section > i:hover { cursor: pointer; } -/* line 1070, ../scss/styles.scss */ +/* line 1071, ../scss/styles.scss */ article.node-materiau.vm-bookmark nav.nav ul, article.node-breve.vm-bookmark nav.nav ul { position: absolute; right: 0; @@ -11568,7 +11593,7 @@ article.node-materiau.vm-bookmark nav.nav ul, article.node-breve.vm-bookmark nav background-clip: padding-box; box-shadow: -2px 2px 5px rgba(0, 0, 0, 0.2); } -/* line 1074, ../scss/styles.scss */ +/* line 1075, ../scss/styles.scss */ article.node-materiau.vm-bookmark nav.nav ul li, article.node-breve.vm-bookmark nav.nav ul li { padding: 0; margin: 0; @@ -11579,20 +11604,20 @@ article.node-materiau.vm-bookmark nav.nav ul li, article.node-breve.vm-bookmark -webkit-transition: height 0.2s ease-out; transition: height 0.2s ease-out; } -/* line 1078, ../scss/styles.scss */ +/* line 1079, ../scss/styles.scss */ article.node-materiau.vm-bookmark nav.nav ul li a, article.node-breve.vm-bookmark nav.nav ul li a { display: block; } -/* line 1081, ../scss/styles.scss */ +/* line 1082, ../scss/styles.scss */ article.node-materiau.vm-bookmark nav.nav ul.flag-lists-entity-links, article.node-breve.vm-bookmark nav.nav ul.flag-lists-entity-links { width: 160px; font-size: 0; } -/* line 1084, ../scss/styles.scss */ +/* line 1085, ../scss/styles.scss */ article.node-materiau.vm-bookmark nav.nav ul.flag-lists-entity-links > *, article.node-breve.vm-bookmark nav.nav ul.flag-lists-entity-links > * { font-size: 11px; } -/* line 1089, ../scss/styles.scss */ +/* line 1090, ../scss/styles.scss */ article.node-materiau.vm-bookmark nav.nav ul.flag-lists-entity-links li, article.node-breve.vm-bookmark nav.nav ul.flag-lists-entity-links li { display: moz-inline-stack; display: inline-block; @@ -11603,53 +11628,53 @@ article.node-materiau.vm-bookmark nav.nav ul.flag-lists-entity-links li, article max-width: 98%; padding-left: 2px; } -/* line 1091, ../scss/styles.scss */ +/* line 1092, ../scss/styles.scss */ article.node-materiau.vm-bookmark nav.nav ul.flag-lists-entity-links li a, article.node-breve.vm-bookmark nav.nav ul.flag-lists-entity-links li a { color: #a6a6a6; -webkit-transition: color 0.2s ease-out; transition: color 0.2s ease-out; } -/* line 1093, ../scss/styles.scss */ +/* line 1094, ../scss/styles.scss */ article.node-materiau.vm-bookmark nav.nav ul.flag-lists-entity-links li a:hover, article.node-materiau.vm-bookmark nav.nav ul.flag-lists-entity-links li a.unflag-action, article.node-breve.vm-bookmark nav.nav ul.flag-lists-entity-links li a:hover, article.node-breve.vm-bookmark nav.nav ul.flag-lists-entity-links li a.unflag-action { color: #000; text-decoration: none; } -/* line 1097, ../scss/styles.scss */ +/* line 1098, ../scss/styles.scss */ article.node-materiau.vm-bookmark nav.nav ul.flag-lists-entity-links li.flag-lists-create, article.node-breve.vm-bookmark nav.nav ul.flag-lists-entity-links li.flag-lists-create { display: block; width: 100%; } -/* line 1099, ../scss/styles.scss */ +/* line 1100, ../scss/styles.scss */ article.node-materiau.vm-bookmark nav.nav ul.flag-lists-entity-links li.flag-lists-create > *, article.node-breve.vm-bookmark nav.nav ul.flag-lists-entity-links li.flag-lists-create > * { margin-top: 1px; padding-top: 1px; border-top: 1px solid #e6e6e6; } -/* line 1100, ../scss/styles.scss */ +/* line 1101, ../scss/styles.scss */ article.node-materiau.vm-bookmark nav.nav ul.flag-lists-entity-links li.flag-lists-create a, article.node-breve.vm-bookmark nav.nav ul.flag-lists-entity-links li.flag-lists-create a { color: #000; } -/* line 1102, ../scss/styles.scss */ +/* line 1103, ../scss/styles.scss */ article.node-materiau.vm-bookmark nav.nav ul.flag-lists-entity-links li.loading, article.node-breve.vm-bookmark nav.nav ul.flag-lists-entity-links li.loading { background: transparent url("../img/ajax-loader.gif") no-repeat 98% center; } -/* line 1103, ../scss/styles.scss */ +/* line 1104, ../scss/styles.scss */ article.node-materiau.vm-bookmark nav.nav ul.flag-lists-entity-links li.loading a, article.node-breve.vm-bookmark nav.nav ul.flag-lists-entity-links li.loading a { visibility: hidden; } -/* line 1108, ../scss/styles.scss */ +/* line 1109, ../scss/styles.scss */ .ie8 article.node-materiau.vm-bookmark nav.nav ul, .ie8 article.node-breve.vm-bookmark nav.nav ul { background: #FFF; } -/* line 1113, ../scss/styles.scss */ +/* line 1114, ../scss/styles.scss */ article.node-materiau.vm-bookmark nav.nav section:hover ul, article.node-breve.vm-bookmark nav.nav section:hover ul { padding: 5px 5px; } -/* line 1115, ../scss/styles.scss */ +/* line 1116, ../scss/styles.scss */ article.node-materiau.vm-bookmark nav.nav section:hover ul li, article.node-breve.vm-bookmark nav.nav section:hover ul li { height: 17px; } -/* line 1128, ../scss/styles.scss */ +/* line 1129, ../scss/styles.scss */ article.node-materiau.vm-bookmark div.workflow, article.node-breve.vm-bookmark div.workflow { position: absolute; top: 0; @@ -11665,7 +11690,7 @@ article.node-materiau.vm-bookmark div.workflow, article.node-breve.vm-bookmark d *background-color: white; color: #000; } -/* line 1134, ../scss/styles.scss */ +/* line 1135, ../scss/styles.scss */ article.node-materiau.vm-bookmark div.workflow span, article.node-breve.vm-bookmark div.workflow span { padding: 3px 0 0 4px; display: moz-inline-stack; @@ -11674,7 +11699,7 @@ article.node-materiau.vm-bookmark div.workflow span, article.node-breve.vm-bookm zoom: 1; *display: inline; } -/* line 1137, ../scss/styles.scss */ +/* line 1138, ../scss/styles.scss */ article.node-materiau.vm-bookmark .field-name-field-description .upgrade, article.node-breve.vm-bookmark .field-name-field-description .upgrade { font-size: 12px; padding-top: 4em; @@ -11683,12 +11708,12 @@ article.node-materiau.vm-bookmark .field-name-field-description .upgrade, articl background: linear-gradient(to bottom, rgba(255, 255, 255, 0) 0%, #fff 4em); position: relative; } -/* line 1145, ../scss/styles.scss */ +/* line 1146, ../scss/styles.scss */ article.node-materiau.vm-bookmark .side.oops p, article.node-materiau.vm-bookmark .side .upgrade p, article.node-breve.vm-bookmark .side.oops p, article.node-breve.vm-bookmark .side .upgrade p { padding: 10px; font-size: 12px; } -/* line 1147, ../scss/styles.scss */ +/* line 1148, ../scss/styles.scss */ article.node-materiau.vm-bookmark .side.oops p a, article.node-materiau.vm-bookmark .side .upgrade p a, article.node-breve.vm-bookmark .side.oops p a, article.node-breve.vm-bookmark .side .upgrade p a { display: block; margin: 10px 0; @@ -11717,11 +11742,11 @@ article.node-materiau.vm-bookmark .side.oops p a:active, article.node-materiau.v transition: text-shadow 0s ease-out; text-shadow: 0 0 2px rgba(0, 0, 0, 0.2); } -/* line 1200, ../scss/styles.scss */ +/* line 1201, ../scss/styles.scss */ article.node-materiau.vm-bookmark .group-header, article.node-breve.vm-bookmark .group-header { display: none; } -/* line 1204, ../scss/styles.scss */ +/* line 1205, ../scss/styles.scss */ article.node-materiau.vm-bookmark .group-images, article.node-breve.vm-bookmark .group-images { position: relative; z-index: 1; @@ -11738,13 +11763,13 @@ article.node-materiau.vm-bookmark .group-images figure:first-child, article.node position: relative; z-index: 1; } -/* line 1206, ../scss/styles.scss */ +/* line 1207, ../scss/styles.scss */ article.node-materiau.vm-bookmark div.workflow, article.node-breve.vm-bookmark div.workflow { display: none; } /** CARD SMALL */ -/* line 1210, ../scss/styles.scss */ +/* line 1211, ../scss/styles.scss */ article.node-materiau.vm-cardsmall, article.node-breve.vm-cardsmall { width: 100px; height: 140px; @@ -11762,41 +11787,41 @@ article.node-materiau.vm-cardsmall, article.node-breve.vm-cardsmall { -webkit-transition: box-shadow 0.3s ease-out; transition: box-shadow 0.3s ease-out; } -/* line 1015, ../scss/styles.scss */ +/* line 1016, ../scss/styles.scss */ article.node-materiau.vm-cardsmall > div.side, article.node-breve.vm-cardsmall > div.side { border-radius: 5px; background-clip: padding-box; overflow: hidden; } -/* line 1020, ../scss/styles.scss */ +/* line 1021, ../scss/styles.scss */ article.node-materiau.vm-cardsmall.focused, article.node-breve.vm-cardsmall.focused { box-shadow: 0 0 7px rgba(0, 0, 0, 0.9); } -/* line 1022, ../scss/styles.scss */ +/* line 1023, ../scss/styles.scss */ article.node-materiau.vm-cardsmall.just-added, article.node-breve.vm-cardsmall.just-added { -webkit-opacity: 0; -khtml-opacity: 0; -moz-opacity: 0; opacity: 0; } -/* line 1024, ../scss/styles.scss */ +/* line 1025, ../scss/styles.scss */ article.node-materiau.vm-cardsmall.associated, article.node-breve.vm-cardsmall.associated { -webkit-transition: margin 0.3s ease-out; transition: margin 0.3s ease-out; } -/* line 1026, ../scss/styles.scss */ +/* line 1027, ../scss/styles.scss */ article.node-materiau.vm-cardsmall.associated.just-added, article.node-breve.vm-cardsmall.associated.just-added { margin-left: -100px; margin-right: 100px; } -/* line 1028, ../scss/styles.scss */ +/* line 1029, ../scss/styles.scss */ .modal-content article.node-materiau.vm-cardsmall.associated, .modal-content article.node-breve.vm-cardsmall.associated { position: absolute; top: 0; left: 0; z-index: 999; } -/* line 1036, ../scss/styles.scss */ +/* line 1037, ../scss/styles.scss */ article.node-materiau.vm-cardsmall.removed, article.node-breve.vm-cardsmall.removed { -webkit-transition: width 0.3s ease-out; transition: width 0.3s ease-out; @@ -11807,7 +11832,7 @@ article.node-materiau.vm-cardsmall.removed, article.node-breve.vm-cardsmall.remo margin-left: 0; overflow: hidden; } -/* line 1046, ../scss/styles.scss */ +/* line 1047, ../scss/styles.scss */ article.node-materiau.vm-cardsmall nav.nav, article.node-breve.vm-cardsmall nav.nav { position: absolute; top: 0; @@ -11822,39 +11847,39 @@ article.node-materiau.vm-cardsmall nav.nav, article.node-breve.vm-cardsmall nav. *background-color: white; color: #000; } -/* line 1058, ../scss/styles.scss */ +/* line 1059, ../scss/styles.scss */ article.node-materiau.vm-cardsmall nav.nav a, article.node-breve.vm-cardsmall nav.nav a { color: #000; } -/* line 1059, ../scss/styles.scss */ +/* line 1060, ../scss/styles.scss */ article.node-materiau.vm-cardsmall nav.nav ul, article.node-breve.vm-cardsmall nav.nav ul { background-color: white; background-color: rgba(255, 255, 255, 0.9); *background-color: white; } -/* line 1060, ../scss/styles.scss */ +/* line 1061, ../scss/styles.scss */ article.node-materiau.vm-cardsmall nav.nav span.op, article.node-breve.vm-cardsmall nav.nav span.op { font-weight: 900; font-size: 14px; } -/* line 1062, ../scss/styles.scss */ +/* line 1063, ../scss/styles.scss */ article.node-materiau.vm-cardsmall nav.nav ul, article.node-breve.vm-cardsmall nav.nav ul { padding: 0; margin: 0; } -/* line 1064, ../scss/styles.scss */ +/* line 1065, ../scss/styles.scss */ article.node-materiau.vm-cardsmall nav.nav section, article.node-breve.vm-cardsmall nav.nav section { position: relative; } -/* line 1067, ../scss/styles.scss */ +/* line 1068, ../scss/styles.scss */ article.node-materiau.vm-cardsmall nav.nav section > i, article.node-breve.vm-cardsmall nav.nav section > i { margin: 0 5px; } -/* line 1067, ../scss/styles.scss */ +/* line 1068, ../scss/styles.scss */ article.node-materiau.vm-cardsmall nav.nav section > i:hover, article.node-breve.vm-cardsmall nav.nav section > i:hover { cursor: pointer; } -/* line 1070, ../scss/styles.scss */ +/* line 1071, ../scss/styles.scss */ article.node-materiau.vm-cardsmall nav.nav ul, article.node-breve.vm-cardsmall nav.nav ul { position: absolute; right: 0; @@ -11867,7 +11892,7 @@ article.node-materiau.vm-cardsmall nav.nav ul, article.node-breve.vm-cardsmall n background-clip: padding-box; box-shadow: -2px 2px 5px rgba(0, 0, 0, 0.2); } -/* line 1074, ../scss/styles.scss */ +/* line 1075, ../scss/styles.scss */ article.node-materiau.vm-cardsmall nav.nav ul li, article.node-breve.vm-cardsmall nav.nav ul li { padding: 0; margin: 0; @@ -11878,20 +11903,20 @@ article.node-materiau.vm-cardsmall nav.nav ul li, article.node-breve.vm-cardsmal -webkit-transition: height 0.2s ease-out; transition: height 0.2s ease-out; } -/* line 1078, ../scss/styles.scss */ +/* line 1079, ../scss/styles.scss */ article.node-materiau.vm-cardsmall nav.nav ul li a, article.node-breve.vm-cardsmall nav.nav ul li a { display: block; } -/* line 1081, ../scss/styles.scss */ +/* line 1082, ../scss/styles.scss */ article.node-materiau.vm-cardsmall nav.nav ul.flag-lists-entity-links, article.node-breve.vm-cardsmall nav.nav ul.flag-lists-entity-links { width: 160px; font-size: 0; } -/* line 1084, ../scss/styles.scss */ +/* line 1085, ../scss/styles.scss */ article.node-materiau.vm-cardsmall nav.nav ul.flag-lists-entity-links > *, article.node-breve.vm-cardsmall nav.nav ul.flag-lists-entity-links > * { font-size: 11px; } -/* line 1089, ../scss/styles.scss */ +/* line 1090, ../scss/styles.scss */ article.node-materiau.vm-cardsmall nav.nav ul.flag-lists-entity-links li, article.node-breve.vm-cardsmall nav.nav ul.flag-lists-entity-links li { display: moz-inline-stack; display: inline-block; @@ -11902,53 +11927,53 @@ article.node-materiau.vm-cardsmall nav.nav ul.flag-lists-entity-links li, articl max-width: 98%; padding-left: 2px; } -/* line 1091, ../scss/styles.scss */ +/* line 1092, ../scss/styles.scss */ article.node-materiau.vm-cardsmall nav.nav ul.flag-lists-entity-links li a, article.node-breve.vm-cardsmall nav.nav ul.flag-lists-entity-links li a { color: #a6a6a6; -webkit-transition: color 0.2s ease-out; transition: color 0.2s ease-out; } -/* line 1093, ../scss/styles.scss */ +/* line 1094, ../scss/styles.scss */ article.node-materiau.vm-cardsmall nav.nav ul.flag-lists-entity-links li a:hover, article.node-materiau.vm-cardsmall nav.nav ul.flag-lists-entity-links li a.unflag-action, article.node-breve.vm-cardsmall nav.nav ul.flag-lists-entity-links li a:hover, article.node-breve.vm-cardsmall nav.nav ul.flag-lists-entity-links li a.unflag-action { color: #000; text-decoration: none; } -/* line 1097, ../scss/styles.scss */ +/* line 1098, ../scss/styles.scss */ article.node-materiau.vm-cardsmall nav.nav ul.flag-lists-entity-links li.flag-lists-create, article.node-breve.vm-cardsmall nav.nav ul.flag-lists-entity-links li.flag-lists-create { display: block; width: 100%; } -/* line 1099, ../scss/styles.scss */ +/* line 1100, ../scss/styles.scss */ article.node-materiau.vm-cardsmall nav.nav ul.flag-lists-entity-links li.flag-lists-create > *, article.node-breve.vm-cardsmall nav.nav ul.flag-lists-entity-links li.flag-lists-create > * { margin-top: 1px; padding-top: 1px; border-top: 1px solid #e6e6e6; } -/* line 1100, ../scss/styles.scss */ +/* line 1101, ../scss/styles.scss */ article.node-materiau.vm-cardsmall nav.nav ul.flag-lists-entity-links li.flag-lists-create a, article.node-breve.vm-cardsmall nav.nav ul.flag-lists-entity-links li.flag-lists-create a { color: #000; } -/* line 1102, ../scss/styles.scss */ +/* line 1103, ../scss/styles.scss */ article.node-materiau.vm-cardsmall nav.nav ul.flag-lists-entity-links li.loading, article.node-breve.vm-cardsmall nav.nav ul.flag-lists-entity-links li.loading { background: transparent url("../img/ajax-loader.gif") no-repeat 98% center; } -/* line 1103, ../scss/styles.scss */ +/* line 1104, ../scss/styles.scss */ article.node-materiau.vm-cardsmall nav.nav ul.flag-lists-entity-links li.loading a, article.node-breve.vm-cardsmall nav.nav ul.flag-lists-entity-links li.loading a { visibility: hidden; } -/* line 1108, ../scss/styles.scss */ +/* line 1109, ../scss/styles.scss */ .ie8 article.node-materiau.vm-cardsmall nav.nav ul, .ie8 article.node-breve.vm-cardsmall nav.nav ul { background: #FFF; } -/* line 1113, ../scss/styles.scss */ +/* line 1114, ../scss/styles.scss */ article.node-materiau.vm-cardsmall nav.nav section:hover ul, article.node-breve.vm-cardsmall nav.nav section:hover ul { padding: 5px 5px; } -/* line 1115, ../scss/styles.scss */ +/* line 1116, ../scss/styles.scss */ article.node-materiau.vm-cardsmall nav.nav section:hover ul li, article.node-breve.vm-cardsmall nav.nav section:hover ul li { height: 17px; } -/* line 1128, ../scss/styles.scss */ +/* line 1129, ../scss/styles.scss */ article.node-materiau.vm-cardsmall div.workflow, article.node-breve.vm-cardsmall div.workflow { position: absolute; top: 0; @@ -11964,7 +11989,7 @@ article.node-materiau.vm-cardsmall div.workflow, article.node-breve.vm-cardsmall *background-color: white; color: #000; } -/* line 1134, ../scss/styles.scss */ +/* line 1135, ../scss/styles.scss */ article.node-materiau.vm-cardsmall div.workflow span, article.node-breve.vm-cardsmall div.workflow span { padding: 3px 0 0 4px; display: moz-inline-stack; @@ -11973,7 +11998,7 @@ article.node-materiau.vm-cardsmall div.workflow span, article.node-breve.vm-card zoom: 1; *display: inline; } -/* line 1137, ../scss/styles.scss */ +/* line 1138, ../scss/styles.scss */ article.node-materiau.vm-cardsmall .field-name-field-description .upgrade, article.node-breve.vm-cardsmall .field-name-field-description .upgrade { font-size: 12px; padding-top: 4em; @@ -11982,12 +12007,12 @@ article.node-materiau.vm-cardsmall .field-name-field-description .upgrade, artic background: linear-gradient(to bottom, rgba(255, 255, 255, 0) 0%, #fff 4em); position: relative; } -/* line 1145, ../scss/styles.scss */ +/* line 1146, ../scss/styles.scss */ article.node-materiau.vm-cardsmall .side.oops p, article.node-materiau.vm-cardsmall .side .upgrade p, article.node-breve.vm-cardsmall .side.oops p, article.node-breve.vm-cardsmall .side .upgrade p { padding: 10px; font-size: 12px; } -/* line 1147, ../scss/styles.scss */ +/* line 1148, ../scss/styles.scss */ article.node-materiau.vm-cardsmall .side.oops p a, article.node-materiau.vm-cardsmall .side .upgrade p a, article.node-breve.vm-cardsmall .side.oops p a, article.node-breve.vm-cardsmall .side .upgrade p a { display: block; margin: 10px 0; @@ -12016,18 +12041,18 @@ article.node-materiau.vm-cardsmall .side.oops p a:active, article.node-materiau. transition: text-shadow 0s ease-out; text-shadow: 0 0 2px rgba(0, 0, 0, 0.2); } -/* line 1212, ../scss/styles.scss */ +/* line 1213, ../scss/styles.scss */ article.node-materiau.vm-cardsmall .group-header, article.node-breve.vm-cardsmall .group-header { display: none; position: absolute; font-size: 14px; font-weight: 500; } -/* line 1215, ../scss/styles.scss */ +/* line 1216, ../scss/styles.scss */ article.node-materiau.vm-cardsmall .group-header .field-name-title-field, article.node-breve.vm-cardsmall .group-header .field-name-title-field { font-weight: 700; } -/* line 1216, ../scss/styles.scss */ +/* line 1217, ../scss/styles.scss */ article.node-materiau.vm-cardsmall .group-header .field-name-field-reference-materio, article.node-materiau.vm-cardsmall .group-header .field-name-field-localisation, article.node-breve.vm-cardsmall .group-header .field-name-field-reference-materio, article.node-breve.vm-cardsmall .group-header .field-name-field-localisation { display: moz-inline-stack; display: inline-block; @@ -12036,11 +12061,11 @@ article.node-materiau.vm-cardsmall .group-header .field-name-field-reference-mat *display: inline; font-size: 12px; } -/* line 1217, ../scss/styles.scss */ +/* line 1218, ../scss/styles.scss */ article.node-materiau.vm-cardsmall .group-header .field-name-field-localisation, article.node-breve.vm-cardsmall .group-header .field-name-field-localisation { float: right; } -/* line 1219, ../scss/styles.scss */ +/* line 1220, ../scss/styles.scss */ article.node-materiau.vm-cardsmall .group-images, article.node-breve.vm-cardsmall .group-images { position: relative; z-index: 1; @@ -12060,20 +12085,20 @@ article.node-materiau.vm-cardsmall .group-images figure:first-child, article.nod position: relative; z-index: 1; } -/* line 1222, ../scss/styles.scss */ +/* line 1223, ../scss/styles.scss */ article.node-materiau.vm-cardsmall nav.nav ul.flag-lists-entity-links, article.node-breve.vm-cardsmall nav.nav ul.flag-lists-entity-links { width: 75px; min-width: 75px; } -/* line 1224, ../scss/styles.scss */ +/* line 1225, ../scss/styles.scss */ article.node-materiau.vm-cardsmall nav.nav ul.flag-lists-entity-links li, article.node-breve.vm-cardsmall nav.nav ul.flag-lists-entity-links li { width: 98%; } -/* line 1226, ../scss/styles.scss */ +/* line 1227, ../scss/styles.scss */ .ie8 article.node-materiau.vm-cardsmall nav.nav, .ie8 article.node-breve.vm-cardsmall nav.nav { background: #FFF; } -/* line 1228, ../scss/styles.scss */ +/* line 1229, ../scss/styles.scss */ .no-touch article.node-materiau.vm-cardsmall:not(.focused) nav.nav, .no-touch article.node-breve.vm-cardsmall:not(.focused) nav.nav { visibility: hidden; } @@ -12095,7 +12120,7 @@ article.node-materiau.vm-cardsmall nav.nav ul.flag-lists-entity-links li, articl -webkit-transition: margin-top 0s 0.3s; transition: margin-top 0s 0.3s; } -/* line 1230, ../scss/styles.scss */ +/* line 1231, ../scss/styles.scss */ .no-touch article.node-materiau.vm-cardsmall:not(.focused) div.workflow, .no-touch article.node-breve.vm-cardsmall:not(.focused) div.workflow { visibility: hidden; } @@ -12119,16 +12144,16 @@ article.node-materiau.vm-cardsmall nav.nav ul.flag-lists-entity-links li, articl } /** TOOLTIP SMALL CARD */ -/* line 1235, ../scss/styles.scss */ +/* line 1236, ../scss/styles.scss */ #tooltip .group-header.smallcard { font-size: 14px; font-weight: 500; } -/* line 1237, ../scss/styles.scss */ +/* line 1238, ../scss/styles.scss */ #tooltip .group-header.smallcard .field-name-title-field { font-weight: 700; } -/* line 1238, ../scss/styles.scss */ +/* line 1239, ../scss/styles.scss */ #tooltip .group-header.smallcard .field-name-field-reference-materio, #tooltip .group-header.smallcard .field-name-field-localisation { display: moz-inline-stack; display: inline-block; @@ -12137,13 +12162,13 @@ article.node-materiau.vm-cardsmall nav.nav ul.flag-lists-entity-links li, articl *display: inline; font-size: 12px; } -/* line 1239, ../scss/styles.scss */ +/* line 1240, ../scss/styles.scss */ #tooltip .group-header.smallcard .field-name-field-localisation { float: right; } /** CARD MEDIUM */ -/* line 1244, ../scss/styles.scss */ +/* line 1245, ../scss/styles.scss */ article.node-materiau.vm-cardmedium, article.node-breve.vm-cardmedium { width: 210px; height: 295px; @@ -12161,41 +12186,41 @@ article.node-materiau.vm-cardmedium, article.node-breve.vm-cardmedium { -webkit-transition: box-shadow 0.3s ease-out; transition: box-shadow 0.3s ease-out; } -/* line 1015, ../scss/styles.scss */ +/* line 1016, ../scss/styles.scss */ article.node-materiau.vm-cardmedium > div.side, article.node-breve.vm-cardmedium > div.side { border-radius: 5px; background-clip: padding-box; overflow: hidden; } -/* line 1020, ../scss/styles.scss */ +/* line 1021, ../scss/styles.scss */ article.node-materiau.vm-cardmedium.focused, article.node-breve.vm-cardmedium.focused { box-shadow: 0 0 7px rgba(0, 0, 0, 0.9); } -/* line 1022, ../scss/styles.scss */ +/* line 1023, ../scss/styles.scss */ article.node-materiau.vm-cardmedium.just-added, article.node-breve.vm-cardmedium.just-added { -webkit-opacity: 0; -khtml-opacity: 0; -moz-opacity: 0; opacity: 0; } -/* line 1024, ../scss/styles.scss */ +/* line 1025, ../scss/styles.scss */ article.node-materiau.vm-cardmedium.associated, article.node-breve.vm-cardmedium.associated { -webkit-transition: margin 0.3s ease-out; transition: margin 0.3s ease-out; } -/* line 1026, ../scss/styles.scss */ +/* line 1027, ../scss/styles.scss */ article.node-materiau.vm-cardmedium.associated.just-added, article.node-breve.vm-cardmedium.associated.just-added { margin-left: -210px; margin-right: 210px; } -/* line 1028, ../scss/styles.scss */ +/* line 1029, ../scss/styles.scss */ .modal-content article.node-materiau.vm-cardmedium.associated, .modal-content article.node-breve.vm-cardmedium.associated { position: absolute; top: 0; left: 0; z-index: 999; } -/* line 1036, ../scss/styles.scss */ +/* line 1037, ../scss/styles.scss */ article.node-materiau.vm-cardmedium.removed, article.node-breve.vm-cardmedium.removed { -webkit-transition: width 0.3s ease-out; transition: width 0.3s ease-out; @@ -12206,7 +12231,7 @@ article.node-materiau.vm-cardmedium.removed, article.node-breve.vm-cardmedium.re margin-left: 0; overflow: hidden; } -/* line 1046, ../scss/styles.scss */ +/* line 1047, ../scss/styles.scss */ article.node-materiau.vm-cardmedium nav.nav, article.node-breve.vm-cardmedium nav.nav { position: absolute; top: 0; @@ -12221,39 +12246,39 @@ article.node-materiau.vm-cardmedium nav.nav, article.node-breve.vm-cardmedium na *background-color: white; color: #000; } -/* line 1058, ../scss/styles.scss */ +/* line 1059, ../scss/styles.scss */ article.node-materiau.vm-cardmedium nav.nav a, article.node-breve.vm-cardmedium nav.nav a { color: #000; } -/* line 1059, ../scss/styles.scss */ +/* line 1060, ../scss/styles.scss */ article.node-materiau.vm-cardmedium nav.nav ul, article.node-breve.vm-cardmedium nav.nav ul { background-color: white; background-color: rgba(255, 255, 255, 0.9); *background-color: white; } -/* line 1060, ../scss/styles.scss */ +/* line 1061, ../scss/styles.scss */ article.node-materiau.vm-cardmedium nav.nav span.op, article.node-breve.vm-cardmedium nav.nav span.op { font-weight: 900; font-size: 14px; } -/* line 1062, ../scss/styles.scss */ +/* line 1063, ../scss/styles.scss */ article.node-materiau.vm-cardmedium nav.nav ul, article.node-breve.vm-cardmedium nav.nav ul { padding: 0; margin: 0; } -/* line 1064, ../scss/styles.scss */ +/* line 1065, ../scss/styles.scss */ article.node-materiau.vm-cardmedium nav.nav section, article.node-breve.vm-cardmedium nav.nav section { position: relative; } -/* line 1067, ../scss/styles.scss */ +/* line 1068, ../scss/styles.scss */ article.node-materiau.vm-cardmedium nav.nav section > i, article.node-breve.vm-cardmedium nav.nav section > i { margin: 0 5px; } -/* line 1067, ../scss/styles.scss */ +/* line 1068, ../scss/styles.scss */ article.node-materiau.vm-cardmedium nav.nav section > i:hover, article.node-breve.vm-cardmedium nav.nav section > i:hover { cursor: pointer; } -/* line 1070, ../scss/styles.scss */ +/* line 1071, ../scss/styles.scss */ article.node-materiau.vm-cardmedium nav.nav ul, article.node-breve.vm-cardmedium nav.nav ul { position: absolute; right: 0; @@ -12266,7 +12291,7 @@ article.node-materiau.vm-cardmedium nav.nav ul, article.node-breve.vm-cardmedium background-clip: padding-box; box-shadow: -2px 2px 5px rgba(0, 0, 0, 0.2); } -/* line 1074, ../scss/styles.scss */ +/* line 1075, ../scss/styles.scss */ article.node-materiau.vm-cardmedium nav.nav ul li, article.node-breve.vm-cardmedium nav.nav ul li { padding: 0; margin: 0; @@ -12277,20 +12302,20 @@ article.node-materiau.vm-cardmedium nav.nav ul li, article.node-breve.vm-cardmed -webkit-transition: height 0.2s ease-out; transition: height 0.2s ease-out; } -/* line 1078, ../scss/styles.scss */ +/* line 1079, ../scss/styles.scss */ article.node-materiau.vm-cardmedium nav.nav ul li a, article.node-breve.vm-cardmedium nav.nav ul li a { display: block; } -/* line 1081, ../scss/styles.scss */ +/* line 1082, ../scss/styles.scss */ article.node-materiau.vm-cardmedium nav.nav ul.flag-lists-entity-links, article.node-breve.vm-cardmedium nav.nav ul.flag-lists-entity-links { width: 160px; font-size: 0; } -/* line 1084, ../scss/styles.scss */ +/* line 1085, ../scss/styles.scss */ article.node-materiau.vm-cardmedium nav.nav ul.flag-lists-entity-links > *, article.node-breve.vm-cardmedium nav.nav ul.flag-lists-entity-links > * { font-size: 11px; } -/* line 1089, ../scss/styles.scss */ +/* line 1090, ../scss/styles.scss */ article.node-materiau.vm-cardmedium nav.nav ul.flag-lists-entity-links li, article.node-breve.vm-cardmedium nav.nav ul.flag-lists-entity-links li { display: moz-inline-stack; display: inline-block; @@ -12301,53 +12326,53 @@ article.node-materiau.vm-cardmedium nav.nav ul.flag-lists-entity-links li, artic max-width: 98%; padding-left: 2px; } -/* line 1091, ../scss/styles.scss */ +/* line 1092, ../scss/styles.scss */ article.node-materiau.vm-cardmedium nav.nav ul.flag-lists-entity-links li a, article.node-breve.vm-cardmedium nav.nav ul.flag-lists-entity-links li a { color: #a6a6a6; -webkit-transition: color 0.2s ease-out; transition: color 0.2s ease-out; } -/* line 1093, ../scss/styles.scss */ +/* line 1094, ../scss/styles.scss */ article.node-materiau.vm-cardmedium nav.nav ul.flag-lists-entity-links li a:hover, article.node-materiau.vm-cardmedium nav.nav ul.flag-lists-entity-links li a.unflag-action, article.node-breve.vm-cardmedium nav.nav ul.flag-lists-entity-links li a:hover, article.node-breve.vm-cardmedium nav.nav ul.flag-lists-entity-links li a.unflag-action { color: #000; text-decoration: none; } -/* line 1097, ../scss/styles.scss */ +/* line 1098, ../scss/styles.scss */ article.node-materiau.vm-cardmedium nav.nav ul.flag-lists-entity-links li.flag-lists-create, article.node-breve.vm-cardmedium nav.nav ul.flag-lists-entity-links li.flag-lists-create { display: block; width: 100%; } -/* line 1099, ../scss/styles.scss */ +/* line 1100, ../scss/styles.scss */ article.node-materiau.vm-cardmedium nav.nav ul.flag-lists-entity-links li.flag-lists-create > *, article.node-breve.vm-cardmedium nav.nav ul.flag-lists-entity-links li.flag-lists-create > * { margin-top: 1px; padding-top: 1px; border-top: 1px solid #e6e6e6; } -/* line 1100, ../scss/styles.scss */ +/* line 1101, ../scss/styles.scss */ article.node-materiau.vm-cardmedium nav.nav ul.flag-lists-entity-links li.flag-lists-create a, article.node-breve.vm-cardmedium nav.nav ul.flag-lists-entity-links li.flag-lists-create a { color: #000; } -/* line 1102, ../scss/styles.scss */ +/* line 1103, ../scss/styles.scss */ article.node-materiau.vm-cardmedium nav.nav ul.flag-lists-entity-links li.loading, article.node-breve.vm-cardmedium nav.nav ul.flag-lists-entity-links li.loading { background: transparent url("../img/ajax-loader.gif") no-repeat 98% center; } -/* line 1103, ../scss/styles.scss */ +/* line 1104, ../scss/styles.scss */ article.node-materiau.vm-cardmedium nav.nav ul.flag-lists-entity-links li.loading a, article.node-breve.vm-cardmedium nav.nav ul.flag-lists-entity-links li.loading a { visibility: hidden; } -/* line 1108, ../scss/styles.scss */ +/* line 1109, ../scss/styles.scss */ .ie8 article.node-materiau.vm-cardmedium nav.nav ul, .ie8 article.node-breve.vm-cardmedium nav.nav ul { background: #FFF; } -/* line 1113, ../scss/styles.scss */ +/* line 1114, ../scss/styles.scss */ article.node-materiau.vm-cardmedium nav.nav section:hover ul, article.node-breve.vm-cardmedium nav.nav section:hover ul { padding: 5px 5px; } -/* line 1115, ../scss/styles.scss */ +/* line 1116, ../scss/styles.scss */ article.node-materiau.vm-cardmedium nav.nav section:hover ul li, article.node-breve.vm-cardmedium nav.nav section:hover ul li { height: 17px; } -/* line 1128, ../scss/styles.scss */ +/* line 1129, ../scss/styles.scss */ article.node-materiau.vm-cardmedium div.workflow, article.node-breve.vm-cardmedium div.workflow { position: absolute; top: 0; @@ -12363,7 +12388,7 @@ article.node-materiau.vm-cardmedium div.workflow, article.node-breve.vm-cardmedi *background-color: white; color: #000; } -/* line 1134, ../scss/styles.scss */ +/* line 1135, ../scss/styles.scss */ article.node-materiau.vm-cardmedium div.workflow span, article.node-breve.vm-cardmedium div.workflow span { padding: 3px 0 0 4px; display: moz-inline-stack; @@ -12372,7 +12397,7 @@ article.node-materiau.vm-cardmedium div.workflow span, article.node-breve.vm-car zoom: 1; *display: inline; } -/* line 1137, ../scss/styles.scss */ +/* line 1138, ../scss/styles.scss */ article.node-materiau.vm-cardmedium .field-name-field-description .upgrade, article.node-breve.vm-cardmedium .field-name-field-description .upgrade { font-size: 12px; padding-top: 4em; @@ -12381,12 +12406,12 @@ article.node-materiau.vm-cardmedium .field-name-field-description .upgrade, arti background: linear-gradient(to bottom, rgba(255, 255, 255, 0) 0%, #fff 4em); position: relative; } -/* line 1145, ../scss/styles.scss */ +/* line 1146, ../scss/styles.scss */ article.node-materiau.vm-cardmedium .side.oops p, article.node-materiau.vm-cardmedium .side .upgrade p, article.node-breve.vm-cardmedium .side.oops p, article.node-breve.vm-cardmedium .side .upgrade p { padding: 10px; font-size: 12px; } -/* line 1147, ../scss/styles.scss */ +/* line 1148, ../scss/styles.scss */ article.node-materiau.vm-cardmedium .side.oops p a, article.node-materiau.vm-cardmedium .side .upgrade p a, article.node-breve.vm-cardmedium .side.oops p a, article.node-breve.vm-cardmedium .side .upgrade p a { display: block; margin: 10px 0; @@ -12415,7 +12440,7 @@ article.node-materiau.vm-cardmedium .side.oops p a:active, article.node-materiau transition: text-shadow 0s ease-out; text-shadow: 0 0 2px rgba(0, 0, 0, 0.2); } -/* line 1247, ../scss/styles.scss */ +/* line 1248, ../scss/styles.scss */ article.node-materiau.vm-cardmedium .side, article.node-breve.vm-cardmedium .side { position: absolute; width: 100%; @@ -12425,11 +12450,11 @@ article.node-materiau.vm-cardmedium .side, article.node-breve.vm-cardmedium .sid background-color: #fff; cursor: pointer; } -/* line 1249, ../scss/styles.scss */ +/* line 1250, ../scss/styles.scss */ article.node-materiau.vm-cardmedium .side:nth-child(2), article.node-breve.vm-cardmedium .side:nth-child(2) { z-index: 1; } -/* line 1252, ../scss/styles.scss */ +/* line 1253, ../scss/styles.scss */ article.node-materiau.vm-cardmedium .group-header, article.node-breve.vm-cardmedium .group-header { position: absolute; bottom: 0; @@ -12450,15 +12475,15 @@ article.node-materiau.vm-cardmedium .group-header, article.node-breve.vm-cardmed background-clip: padding-box; overflow: hidden; } -/* line 1256, ../scss/styles.scss */ +/* line 1257, ../scss/styles.scss */ article.node-materiau.vm-cardmedium .group-header .field-name-title-field, article.node-breve.vm-cardmedium .group-header .field-name-title-field { font-weight: 700; } -/* line 1257, ../scss/styles.scss */ +/* line 1258, ../scss/styles.scss */ article.node-materiau.vm-cardmedium .group-header .field-name-field-nature-titre, article.node-breve.vm-cardmedium .group-header .field-name-field-nature-titre { font-size: 14px; } -/* line 1262, ../scss/styles.scss */ +/* line 1263, ../scss/styles.scss */ article.node-materiau.vm-cardmedium .group-header .field-name-field-reference-materio, article.node-materiau.vm-cardmedium .group-header .field-name-field-localisation, article.node-materiau.vm-cardmedium .group-header .field-name-field-authored-on, article.node-breve.vm-cardmedium .group-header .field-name-field-reference-materio, article.node-breve.vm-cardmedium .group-header .field-name-field-localisation, article.node-breve.vm-cardmedium .group-header .field-name-field-authored-on { display: moz-inline-stack; display: inline-block; @@ -12469,18 +12494,18 @@ article.node-materiau.vm-cardmedium .group-header .field-name-field-reference-ma vertical-align: bottom; width: 48%; } -/* line 1263, ../scss/styles.scss */ +/* line 1264, ../scss/styles.scss */ article.node-materiau.vm-cardmedium .group-header .field-name-field-localisation, article.node-breve.vm-cardmedium .group-header .field-name-field-localisation { text-align: right; } -/* line 1264, ../scss/styles.scss */ +/* line 1265, ../scss/styles.scss */ .ie8 article.node-materiau.vm-cardmedium .group-header, .ie8 article.node-breve.vm-cardmedium .group-header { background: #fff; font-color: #000; line-height: 1em; padding: 10px; } -/* line 1268, ../scss/styles.scss */ +/* line 1269, ../scss/styles.scss */ article.node-materiau.vm-cardmedium.node-breve .group-header, article.node-breve.vm-cardmedium.node-breve .group-header { color: #fff; background-color: black; @@ -12490,18 +12515,18 @@ article.node-materiau.vm-cardmedium.node-breve .group-header, article.node-breve -webkit-transition: background-color 0.2s ease-out; transition: background-color 0.2s ease-out; } -/* line 1271, ../scss/styles.scss */ +/* line 1272, ../scss/styles.scss */ article.node-materiau.vm-cardmedium.node-breve .group-header .field-name-field-authored-on, article.node-breve.vm-cardmedium.node-breve .group-header .field-name-field-authored-on { font-size: 12px; font-weight: 500; } -/* line 1272, ../scss/styles.scss */ +/* line 1273, ../scss/styles.scss */ .ie8 article.node-materiau.vm-cardmedium.node-breve .group-header, .ie8 article.node-breve.vm-cardmedium.node-breve .group-header { background: #000; font-size: 15px; line-height: 1.2em; } -/* line 1279, ../scss/styles.scss */ +/* line 1280, ../scss/styles.scss */ article.node-materiau.vm-cardmedium .group-images, article.node-breve.vm-cardmedium .group-images { position: relative; z-index: 1; @@ -12518,7 +12543,7 @@ article.node-materiau.vm-cardmedium .group-images figure:first-child, article.no position: relative; z-index: 1; } -/* line 1282, ../scss/styles.scss */ +/* line 1283, ../scss/styles.scss */ article.node-materiau.vm-cardmedium .field-name-field-description, article.node-materiau.vm-cardmedium .field-name-body, article.node-breve.vm-cardmedium .field-name-field-description, article.node-breve.vm-cardmedium .field-name-body { font-size: 12px; font-weight: 300; @@ -12558,11 +12583,11 @@ article.node-materiau.vm-cardmedium .field-name-field-description.columnized .co article.node-materiau.vm-cardmedium .field-name-field-description.columnized .column-switcher.next-column, article.node-materiau.vm-cardmedium .field-name-body.columnized .column-switcher.next-column, article.node-breve.vm-cardmedium .field-name-field-description.columnized .column-switcher.next-column, article.node-breve.vm-cardmedium .field-name-body.columnized .column-switcher.next-column { cursor: e-resize; } -/* line 1284, ../scss/styles.scss */ +/* line 1285, ../scss/styles.scss */ article.node-materiau.vm-cardmedium .field-name-field-description .column > *, article.node-materiau.vm-cardmedium .field-name-body .column > *, article.node-breve.vm-cardmedium .field-name-field-description .column > *, article.node-breve.vm-cardmedium .field-name-body .column > * { padding-right: 25px; } -/* line 1288, ../scss/styles.scss */ +/* line 1289, ../scss/styles.scss */ article.node-materiau.vm-cardmedium .column-wrapper, article.node-breve.vm-cardmedium .column-wrapper { padding: 5px; } @@ -12598,38 +12623,38 @@ article.node-materiau.vm-cardmedium .column-wrapper.columnized .column-switcher. article.node-materiau.vm-cardmedium .column-wrapper.columnized .column-switcher.next-column, article.node-breve.vm-cardmedium .column-wrapper.columnized .column-switcher.next-column { cursor: e-resize; } -/* line 1291, ../scss/styles.scss */ +/* line 1292, ../scss/styles.scss */ article.node-materiau.vm-cardmedium .field-name-field-company-fab, article.node-materiau.vm-cardmedium .field-name-field-company-distrib, article.node-breve.vm-cardmedium .field-name-field-company-fab, article.node-breve.vm-cardmedium .field-name-field-company-distrib { font-size: 12px; padding: 5px; font-weight: 300; } -/* line 1293, ../scss/styles.scss */ +/* line 1294, ../scss/styles.scss */ article.node-materiau.vm-cardmedium .field-name-field-company-fab .field-label, article.node-materiau.vm-cardmedium .field-name-field-company-distrib .field-label, article.node-breve.vm-cardmedium .field-name-field-company-fab .field-label, article.node-breve.vm-cardmedium .field-name-field-company-distrib .field-label { font-size: 10px; text-transform: lowercase; margin: 0; } -/* line 1294, ../scss/styles.scss */ +/* line 1295, ../scss/styles.scss */ article.node-materiau.vm-cardmedium .field-name-field-company-fab .field-name-field-tode-company, article.node-materiau.vm-cardmedium .field-name-field-company-distrib .field-name-field-tode-company, article.node-breve.vm-cardmedium .field-name-field-company-fab .field-name-field-tode-company, article.node-breve.vm-cardmedium .field-name-field-company-distrib .field-name-field-tode-company { font-size: 14px; } -/* line 1298, ../scss/styles.scss */ +/* line 1299, ../scss/styles.scss */ article.node-materiau.vm-cardmedium .field-name-field-materiau-ref, article.node-materiau.vm-cardmedium .field-name-field-source, article.node-materiau.vm-cardmedium .field-name-field-attachments, article.node-breve.vm-cardmedium .field-name-field-materiau-ref, article.node-breve.vm-cardmedium .field-name-field-source, article.node-breve.vm-cardmedium .field-name-field-attachments { font-size: 12px; padding: 5px; font-weight: 300; } -/* line 1300, ../scss/styles.scss */ +/* line 1301, ../scss/styles.scss */ article.node-materiau.vm-cardmedium .field-name-field-materiau-ref a, article.node-materiau.vm-cardmedium .field-name-field-source a, article.node-materiau.vm-cardmedium .field-name-field-attachments a, article.node-breve.vm-cardmedium .field-name-field-materiau-ref a, article.node-breve.vm-cardmedium .field-name-field-source a, article.node-breve.vm-cardmedium .field-name-field-attachments a { color: #000; } -/* line 1302, ../scss/styles.scss */ +/* line 1303, ../scss/styles.scss */ article.node-materiau.vm-cardmedium .field-label, article.node-breve.vm-cardmedium .field-label { font-weight: 900; margin: 1em 0 0.5em; } -/* line 1304, ../scss/styles.scss */ +/* line 1305, ../scss/styles.scss */ .no-touch article.node-materiau.vm-cardmedium:not(.focused) nav.nav, .no-touch article.node-breve.vm-cardmedium:not(.focused) nav.nav { visibility: hidden; } @@ -12651,7 +12676,7 @@ article.node-materiau.vm-cardmedium .field-label, article.node-breve.vm-cardmedi -webkit-transition: margin-top 0s 0.3s; transition: margin-top 0s 0.3s; } -/* line 1306, ../scss/styles.scss */ +/* line 1307, ../scss/styles.scss */ .no-touch article.node-materiau.vm-cardmedium:not(.focused) div.workflow, .no-touch article.node-breve.vm-cardmedium:not(.focused) div.workflow { visibility: hidden; } @@ -12673,13 +12698,13 @@ article.node-materiau.vm-cardmedium .field-label, article.node-breve.vm-cardmedi -webkit-transition: margin-top 0s 0.3s; transition: margin-top 0s 0.3s; } -/* line 1308, ../scss/styles.scss */ +/* line 1309, ../scss/styles.scss */ .ie8 article.node-materiau.vm-cardmedium nav.nav, .ie8 article.node-breve.vm-cardmedium nav.nav { background: #FFF; } /** CARD BIG */ -/* line 1312, ../scss/styles.scss */ +/* line 1313, ../scss/styles.scss */ article.node-materiau.vm-cardbig, article.node-breve.vm-cardbig { width: 425px; height: 610px; @@ -12697,41 +12722,41 @@ article.node-materiau.vm-cardbig, article.node-breve.vm-cardbig { -webkit-transition: box-shadow 0.3s ease-out; transition: box-shadow 0.3s ease-out; } -/* line 1015, ../scss/styles.scss */ +/* line 1016, ../scss/styles.scss */ article.node-materiau.vm-cardbig > div.side, article.node-breve.vm-cardbig > div.side { border-radius: 5px; background-clip: padding-box; overflow: hidden; } -/* line 1020, ../scss/styles.scss */ +/* line 1021, ../scss/styles.scss */ article.node-materiau.vm-cardbig.focused, article.node-breve.vm-cardbig.focused { box-shadow: 0 0 7px rgba(0, 0, 0, 0.9); } -/* line 1022, ../scss/styles.scss */ +/* line 1023, ../scss/styles.scss */ article.node-materiau.vm-cardbig.just-added, article.node-breve.vm-cardbig.just-added { -webkit-opacity: 0; -khtml-opacity: 0; -moz-opacity: 0; opacity: 0; } -/* line 1024, ../scss/styles.scss */ +/* line 1025, ../scss/styles.scss */ article.node-materiau.vm-cardbig.associated, article.node-breve.vm-cardbig.associated { -webkit-transition: margin 0.3s ease-out; transition: margin 0.3s ease-out; } -/* line 1026, ../scss/styles.scss */ +/* line 1027, ../scss/styles.scss */ article.node-materiau.vm-cardbig.associated.just-added, article.node-breve.vm-cardbig.associated.just-added { margin-left: -425px; margin-right: 425px; } -/* line 1028, ../scss/styles.scss */ +/* line 1029, ../scss/styles.scss */ .modal-content article.node-materiau.vm-cardbig.associated, .modal-content article.node-breve.vm-cardbig.associated { position: absolute; top: 0; left: 0; z-index: 999; } -/* line 1036, ../scss/styles.scss */ +/* line 1037, ../scss/styles.scss */ article.node-materiau.vm-cardbig.removed, article.node-breve.vm-cardbig.removed { -webkit-transition: width 0.3s ease-out; transition: width 0.3s ease-out; @@ -12742,7 +12767,7 @@ article.node-materiau.vm-cardbig.removed, article.node-breve.vm-cardbig.removed margin-left: 0; overflow: hidden; } -/* line 1046, ../scss/styles.scss */ +/* line 1047, ../scss/styles.scss */ article.node-materiau.vm-cardbig nav.nav, article.node-breve.vm-cardbig nav.nav { position: absolute; top: 0; @@ -12757,39 +12782,39 @@ article.node-materiau.vm-cardbig nav.nav, article.node-breve.vm-cardbig nav.nav *background-color: white; color: #000; } -/* line 1058, ../scss/styles.scss */ +/* line 1059, ../scss/styles.scss */ article.node-materiau.vm-cardbig nav.nav a, article.node-breve.vm-cardbig nav.nav a { color: #000; } -/* line 1059, ../scss/styles.scss */ +/* line 1060, ../scss/styles.scss */ article.node-materiau.vm-cardbig nav.nav ul, article.node-breve.vm-cardbig nav.nav ul { background-color: white; background-color: rgba(255, 255, 255, 0.9); *background-color: white; } -/* line 1060, ../scss/styles.scss */ +/* line 1061, ../scss/styles.scss */ article.node-materiau.vm-cardbig nav.nav span.op, article.node-breve.vm-cardbig nav.nav span.op { font-weight: 900; font-size: 14px; } -/* line 1062, ../scss/styles.scss */ +/* line 1063, ../scss/styles.scss */ article.node-materiau.vm-cardbig nav.nav ul, article.node-breve.vm-cardbig nav.nav ul { padding: 0; margin: 0; } -/* line 1064, ../scss/styles.scss */ +/* line 1065, ../scss/styles.scss */ article.node-materiau.vm-cardbig nav.nav section, article.node-breve.vm-cardbig nav.nav section { position: relative; } -/* line 1067, ../scss/styles.scss */ +/* line 1068, ../scss/styles.scss */ article.node-materiau.vm-cardbig nav.nav section > i, article.node-breve.vm-cardbig nav.nav section > i { margin: 0 5px; } -/* line 1067, ../scss/styles.scss */ +/* line 1068, ../scss/styles.scss */ article.node-materiau.vm-cardbig nav.nav section > i:hover, article.node-breve.vm-cardbig nav.nav section > i:hover { cursor: pointer; } -/* line 1070, ../scss/styles.scss */ +/* line 1071, ../scss/styles.scss */ article.node-materiau.vm-cardbig nav.nav ul, article.node-breve.vm-cardbig nav.nav ul { position: absolute; right: 0; @@ -12802,7 +12827,7 @@ article.node-materiau.vm-cardbig nav.nav ul, article.node-breve.vm-cardbig nav.n background-clip: padding-box; box-shadow: -2px 2px 5px rgba(0, 0, 0, 0.2); } -/* line 1074, ../scss/styles.scss */ +/* line 1075, ../scss/styles.scss */ article.node-materiau.vm-cardbig nav.nav ul li, article.node-breve.vm-cardbig nav.nav ul li { padding: 0; margin: 0; @@ -12813,20 +12838,20 @@ article.node-materiau.vm-cardbig nav.nav ul li, article.node-breve.vm-cardbig na -webkit-transition: height 0.2s ease-out; transition: height 0.2s ease-out; } -/* line 1078, ../scss/styles.scss */ +/* line 1079, ../scss/styles.scss */ article.node-materiau.vm-cardbig nav.nav ul li a, article.node-breve.vm-cardbig nav.nav ul li a { display: block; } -/* line 1081, ../scss/styles.scss */ +/* line 1082, ../scss/styles.scss */ article.node-materiau.vm-cardbig nav.nav ul.flag-lists-entity-links, article.node-breve.vm-cardbig nav.nav ul.flag-lists-entity-links { width: 160px; font-size: 0; } -/* line 1084, ../scss/styles.scss */ +/* line 1085, ../scss/styles.scss */ article.node-materiau.vm-cardbig nav.nav ul.flag-lists-entity-links > *, article.node-breve.vm-cardbig nav.nav ul.flag-lists-entity-links > * { font-size: 11px; } -/* line 1089, ../scss/styles.scss */ +/* line 1090, ../scss/styles.scss */ article.node-materiau.vm-cardbig nav.nav ul.flag-lists-entity-links li, article.node-breve.vm-cardbig nav.nav ul.flag-lists-entity-links li { display: moz-inline-stack; display: inline-block; @@ -12837,53 +12862,53 @@ article.node-materiau.vm-cardbig nav.nav ul.flag-lists-entity-links li, article. max-width: 98%; padding-left: 2px; } -/* line 1091, ../scss/styles.scss */ +/* line 1092, ../scss/styles.scss */ article.node-materiau.vm-cardbig nav.nav ul.flag-lists-entity-links li a, article.node-breve.vm-cardbig nav.nav ul.flag-lists-entity-links li a { color: #a6a6a6; -webkit-transition: color 0.2s ease-out; transition: color 0.2s ease-out; } -/* line 1093, ../scss/styles.scss */ +/* line 1094, ../scss/styles.scss */ article.node-materiau.vm-cardbig nav.nav ul.flag-lists-entity-links li a:hover, article.node-materiau.vm-cardbig nav.nav ul.flag-lists-entity-links li a.unflag-action, article.node-breve.vm-cardbig nav.nav ul.flag-lists-entity-links li a:hover, article.node-breve.vm-cardbig nav.nav ul.flag-lists-entity-links li a.unflag-action { color: #000; text-decoration: none; } -/* line 1097, ../scss/styles.scss */ +/* line 1098, ../scss/styles.scss */ article.node-materiau.vm-cardbig nav.nav ul.flag-lists-entity-links li.flag-lists-create, article.node-breve.vm-cardbig nav.nav ul.flag-lists-entity-links li.flag-lists-create { display: block; width: 100%; } -/* line 1099, ../scss/styles.scss */ +/* line 1100, ../scss/styles.scss */ article.node-materiau.vm-cardbig nav.nav ul.flag-lists-entity-links li.flag-lists-create > *, article.node-breve.vm-cardbig nav.nav ul.flag-lists-entity-links li.flag-lists-create > * { margin-top: 1px; padding-top: 1px; border-top: 1px solid #e6e6e6; } -/* line 1100, ../scss/styles.scss */ +/* line 1101, ../scss/styles.scss */ article.node-materiau.vm-cardbig nav.nav ul.flag-lists-entity-links li.flag-lists-create a, article.node-breve.vm-cardbig nav.nav ul.flag-lists-entity-links li.flag-lists-create a { color: #000; } -/* line 1102, ../scss/styles.scss */ +/* line 1103, ../scss/styles.scss */ article.node-materiau.vm-cardbig nav.nav ul.flag-lists-entity-links li.loading, article.node-breve.vm-cardbig nav.nav ul.flag-lists-entity-links li.loading { background: transparent url("../img/ajax-loader.gif") no-repeat 98% center; } -/* line 1103, ../scss/styles.scss */ +/* line 1104, ../scss/styles.scss */ article.node-materiau.vm-cardbig nav.nav ul.flag-lists-entity-links li.loading a, article.node-breve.vm-cardbig nav.nav ul.flag-lists-entity-links li.loading a { visibility: hidden; } -/* line 1108, ../scss/styles.scss */ +/* line 1109, ../scss/styles.scss */ .ie8 article.node-materiau.vm-cardbig nav.nav ul, .ie8 article.node-breve.vm-cardbig nav.nav ul { background: #FFF; } -/* line 1113, ../scss/styles.scss */ +/* line 1114, ../scss/styles.scss */ article.node-materiau.vm-cardbig nav.nav section:hover ul, article.node-breve.vm-cardbig nav.nav section:hover ul { padding: 5px 5px; } -/* line 1115, ../scss/styles.scss */ +/* line 1116, ../scss/styles.scss */ article.node-materiau.vm-cardbig nav.nav section:hover ul li, article.node-breve.vm-cardbig nav.nav section:hover ul li { height: 17px; } -/* line 1128, ../scss/styles.scss */ +/* line 1129, ../scss/styles.scss */ article.node-materiau.vm-cardbig div.workflow, article.node-breve.vm-cardbig div.workflow { position: absolute; top: 0; @@ -12899,7 +12924,7 @@ article.node-materiau.vm-cardbig div.workflow, article.node-breve.vm-cardbig div *background-color: white; color: #000; } -/* line 1134, ../scss/styles.scss */ +/* line 1135, ../scss/styles.scss */ article.node-materiau.vm-cardbig div.workflow span, article.node-breve.vm-cardbig div.workflow span { padding: 3px 0 0 4px; display: moz-inline-stack; @@ -12908,7 +12933,7 @@ article.node-materiau.vm-cardbig div.workflow span, article.node-breve.vm-cardbi zoom: 1; *display: inline; } -/* line 1137, ../scss/styles.scss */ +/* line 1138, ../scss/styles.scss */ article.node-materiau.vm-cardbig .field-name-field-description .upgrade, article.node-breve.vm-cardbig .field-name-field-description .upgrade { font-size: 12px; padding-top: 4em; @@ -12917,12 +12942,12 @@ article.node-materiau.vm-cardbig .field-name-field-description .upgrade, article background: linear-gradient(to bottom, rgba(255, 255, 255, 0) 0%, #fff 4em); position: relative; } -/* line 1145, ../scss/styles.scss */ +/* line 1146, ../scss/styles.scss */ article.node-materiau.vm-cardbig .side.oops p, article.node-materiau.vm-cardbig .side .upgrade p, article.node-breve.vm-cardbig .side.oops p, article.node-breve.vm-cardbig .side .upgrade p { padding: 10px; font-size: 12px; } -/* line 1147, ../scss/styles.scss */ +/* line 1148, ../scss/styles.scss */ article.node-materiau.vm-cardbig .side.oops p a, article.node-materiau.vm-cardbig .side .upgrade p a, article.node-breve.vm-cardbig .side.oops p a, article.node-breve.vm-cardbig .side .upgrade p a { display: block; margin: 10px 0; @@ -12951,7 +12976,7 @@ article.node-materiau.vm-cardbig .side.oops p a:active, article.node-materiau.vm transition: text-shadow 0s ease-out; text-shadow: 0 0 2px rgba(0, 0, 0, 0.2); } -/* line 1315, ../scss/styles.scss */ +/* line 1316, ../scss/styles.scss */ article.node-materiau.vm-cardbig .side, article.node-breve.vm-cardbig .side { position: absolute; width: 100%; @@ -12963,18 +12988,18 @@ article.node-materiau.vm-cardbig .side, article.node-breve.vm-cardbig .side { top: 340px; cursor: pointer; } -/* line 1317, ../scss/styles.scss */ +/* line 1318, ../scss/styles.scss */ article.node-materiau.vm-cardbig .side:nth-child(2), article.node-breve.vm-cardbig .side:nth-child(2) { z-index: 1; } -/* line 1320, ../scss/styles.scss */ +/* line 1321, ../scss/styles.scss */ article.node-materiau.vm-cardbig .group-side1, article.node-breve.vm-cardbig .group-side1 { position: relative; border-radius: 5px 5px 0 0; background-clip: padding-box; overflow: hidden; } -/* line 1322, ../scss/styles.scss */ +/* line 1323, ../scss/styles.scss */ article.node-materiau.vm-cardbig .group-header, article.node-breve.vm-cardbig .group-header { position: absolute; bottom: 0; @@ -12991,15 +13016,15 @@ article.node-materiau.vm-cardbig .group-header, article.node-breve.vm-cardbig .g -webkit-transition: background-color 0.2s ease-out; transition: background-color 0.2s ease-out; } -/* line 1326, ../scss/styles.scss */ +/* line 1327, ../scss/styles.scss */ article.node-materiau.vm-cardbig .group-header .field-name-title-field, article.node-breve.vm-cardbig .group-header .field-name-title-field { font-weight: 700; } -/* line 1327, ../scss/styles.scss */ +/* line 1328, ../scss/styles.scss */ article.node-materiau.vm-cardbig .group-header .field-name-field-nature-titre, article.node-breve.vm-cardbig .group-header .field-name-field-nature-titre { font-size: 14px; } -/* line 1329, ../scss/styles.scss */ +/* line 1330, ../scss/styles.scss */ article.node-materiau.vm-cardbig .group-header .field-name-field-reference-materio, article.node-materiau.vm-cardbig .group-header .field-name-field-localisation, article.node-materiau.vm-cardbig .group-header .field-name-field-authored-on, article.node-breve.vm-cardbig .group-header .field-name-field-reference-materio, article.node-breve.vm-cardbig .group-header .field-name-field-localisation, article.node-breve.vm-cardbig .group-header .field-name-field-authored-on { display: moz-inline-stack; display: inline-block; @@ -13010,11 +13035,11 @@ article.node-materiau.vm-cardbig .group-header .field-name-field-reference-mater vertical-align: bottom; width: 48%; } -/* line 1330, ../scss/styles.scss */ +/* line 1331, ../scss/styles.scss */ article.node-materiau.vm-cardbig .group-header .field-name-field-localisation, article.node-breve.vm-cardbig .group-header .field-name-field-localisation { text-align: right; } -/* line 1331, ../scss/styles.scss */ +/* line 1332, ../scss/styles.scss */ .ie8 article.node-materiau.vm-cardbig .group-header, .ie8 article.node-breve.vm-cardbig .group-header { background: #fff; font-color: #000; @@ -13022,7 +13047,7 @@ article.node-materiau.vm-cardbig .group-header .field-name-field-localisation, a padding: 20px; border-bottom: 1px solid #C6C6C6; } -/* line 1335, ../scss/styles.scss */ +/* line 1336, ../scss/styles.scss */ article.node-materiau.vm-cardbig.node-breve .group-header, article.node-breve.vm-cardbig.node-breve .group-header { color: #fff; background-color: black; @@ -13032,19 +13057,19 @@ article.node-materiau.vm-cardbig.node-breve .group-header, article.node-breve.vm -webkit-transition: background-color 0.2s ease-out; transition: background-color 0.2s ease-out; } -/* line 1337, ../scss/styles.scss */ +/* line 1338, ../scss/styles.scss */ article.node-materiau.vm-cardbig.node-breve .group-header .field-name-field-authored-on, article.node-breve.vm-cardbig.node-breve .group-header .field-name-field-authored-on { font-size: 12px; font-weight: 500; } -/* line 1338, ../scss/styles.scss */ +/* line 1339, ../scss/styles.scss */ .ie8 article.node-materiau.vm-cardbig.node-breve .group-header, .ie8 article.node-breve.vm-cardbig.node-breve .group-header { background: #000; font-color: #fff; line-height: 1em; padding: 20px; } -/* line 1341, ../scss/styles.scss */ +/* line 1342, ../scss/styles.scss */ article.node-materiau.vm-cardbig .group-images, article.node-breve.vm-cardbig .group-images { position: relative; z-index: 1; @@ -13062,7 +13087,7 @@ article.node-materiau.vm-cardbig .group-images figure:first-child, article.node- position: relative; z-index: 1; } -/* line 1344, ../scss/styles.scss */ +/* line 1345, ../scss/styles.scss */ article.node-materiau.vm-cardbig .field-name-field-description, article.node-materiau.vm-cardbig .field-name-body, article.node-breve.vm-cardbig .field-name-field-description, article.node-breve.vm-cardbig .field-name-body { font-size: 12px; font-weight: 300; @@ -13100,7 +13125,7 @@ article.node-materiau.vm-cardbig .field-name-field-description.columnized .colum article.node-materiau.vm-cardbig .field-name-field-description.columnized .column-switcher.next-column, article.node-materiau.vm-cardbig .field-name-body.columnized .column-switcher.next-column, article.node-breve.vm-cardbig .field-name-field-description.columnized .column-switcher.next-column, article.node-breve.vm-cardbig .field-name-body.columnized .column-switcher.next-column { cursor: e-resize; } -/* line 1348, ../scss/styles.scss */ +/* line 1349, ../scss/styles.scss */ article.node-materiau.vm-cardbig .column-wrapper, article.node-breve.vm-cardbig .column-wrapper { padding: 10px; } @@ -13136,46 +13161,46 @@ article.node-materiau.vm-cardbig .column-wrapper.columnized .column-switcher.pre article.node-materiau.vm-cardbig .column-wrapper.columnized .column-switcher.next-column, article.node-breve.vm-cardbig .column-wrapper.columnized .column-switcher.next-column { cursor: e-resize; } -/* line 1352, ../scss/styles.scss */ +/* line 1353, ../scss/styles.scss */ article.node-materiau.vm-cardbig .field-name-field-company-fab, article.node-materiau.vm-cardbig .field-name-field-company-distrib, article.node-breve.vm-cardbig .field-name-field-company-fab, article.node-breve.vm-cardbig .field-name-field-company-distrib { font-size: 12px; padding: 10px; font-weight: 300; } -/* line 1354, ../scss/styles.scss */ +/* line 1355, ../scss/styles.scss */ article.node-materiau.vm-cardbig .field-name-field-company-fab .field-label, article.node-materiau.vm-cardbig .field-name-field-company-distrib .field-label, article.node-breve.vm-cardbig .field-name-field-company-fab .field-label, article.node-breve.vm-cardbig .field-name-field-company-distrib .field-label { font-size: 10px; text-transform: lowercase; float: none; } -/* line 1355, ../scss/styles.scss */ +/* line 1356, ../scss/styles.scss */ article.node-materiau.vm-cardbig .field-name-field-company-fab .field-name-field-tode-company, article.node-materiau.vm-cardbig .field-name-field-company-distrib .field-name-field-tode-company, article.node-breve.vm-cardbig .field-name-field-company-fab .field-name-field-tode-company, article.node-breve.vm-cardbig .field-name-field-company-distrib .field-name-field-tode-company { font-size: 14px; } -/* line 1359, ../scss/styles.scss */ +/* line 1360, ../scss/styles.scss */ article.node-materiau.vm-cardbig .field-name-field-materiau-ref, article.node-materiau.vm-cardbig .field-name-field-source, article.node-materiau.vm-cardbig .field-name-field-attachments, article.node-breve.vm-cardbig .field-name-field-materiau-ref, article.node-breve.vm-cardbig .field-name-field-source, article.node-breve.vm-cardbig .field-name-field-attachments { font-size: 12px; padding: 10px; font-weight: 300; } -/* line 1360, ../scss/styles.scss */ +/* line 1361, ../scss/styles.scss */ article.node-materiau.vm-cardbig .field-name-field-materiau-ref a, article.node-materiau.vm-cardbig .field-name-field-source a, article.node-materiau.vm-cardbig .field-name-field-attachments a, article.node-breve.vm-cardbig .field-name-field-materiau-ref a, article.node-breve.vm-cardbig .field-name-field-source a, article.node-breve.vm-cardbig .field-name-field-attachments a { color: #000; } -/* line 1362, ../scss/styles.scss */ +/* line 1363, ../scss/styles.scss */ article.node-materiau.vm-cardbig .field-label, article.node-breve.vm-cardbig .field-label { font-weight: 900; margin: 0 0 0.5em; } -/* line 1366, ../scss/styles.scss */ +/* line 1367, ../scss/styles.scss */ .ie8 article.node-materiau.vm-cardbig nav.nav, .ie8 article.node-breve.vm-cardbig nav.nav { background: #FFF; } -/* line 1369, ../scss/styles.scss */ +/* line 1370, ../scss/styles.scss */ article.node-materiau.vm-cardbig .side.oops p, article.node-materiau.vm-cardbig .side .upgrade p, article.node-breve.vm-cardbig .side.oops p, article.node-breve.vm-cardbig .side .upgrade p { padding: 3em; } -/* line 1371, ../scss/styles.scss */ +/* line 1372, ../scss/styles.scss */ article.node-materiau.vm-cardbig .side.oops p a, article.node-materiau.vm-cardbig .side .upgrade p a, article.node-breve.vm-cardbig .side.oops p a, article.node-breve.vm-cardbig .side .upgrade p a { border: 2px solid #eee; background-color: #eee; @@ -13185,14 +13210,14 @@ article.node-materiau.vm-cardbig .side.oops p a, article.node-materiau.vm-cardbi -webkit-transition: background-color 0.3s ease-out; transition: background-color 0.3s ease-out; } -/* line 1378, ../scss/styles.scss */ +/* line 1379, ../scss/styles.scss */ article.node-materiau.vm-cardbig:hover .side.oops p a, article.node-materiau.vm-cardbig:hover .side .upgrade p a, article.node-breve.vm-cardbig:hover .side.oops p a, article.node-breve.vm-cardbig:hover .side .upgrade p a { border: 2px solid #69CDCF; background-color: #69CDCF; } /** CARD FULL */ -/* line 1385, ../scss/styles.scss */ +/* line 1386, ../scss/styles.scss */ article.node-materiau.vm-cardfull, article.node-breve.vm-cardfull { width: 850px; height: 610px; @@ -13211,41 +13236,41 @@ article.node-materiau.vm-cardfull, article.node-breve.vm-cardfull { transition: box-shadow 0.3s ease-out; font-size: 0px; } -/* line 1015, ../scss/styles.scss */ +/* line 1016, ../scss/styles.scss */ article.node-materiau.vm-cardfull > div.side, article.node-breve.vm-cardfull > div.side { border-radius: 5px; background-clip: padding-box; overflow: hidden; } -/* line 1020, ../scss/styles.scss */ +/* line 1021, ../scss/styles.scss */ article.node-materiau.vm-cardfull.focused, article.node-breve.vm-cardfull.focused { box-shadow: 0 0 7px rgba(0, 0, 0, 0.9); } -/* line 1022, ../scss/styles.scss */ +/* line 1023, ../scss/styles.scss */ article.node-materiau.vm-cardfull.just-added, article.node-breve.vm-cardfull.just-added { -webkit-opacity: 0; -khtml-opacity: 0; -moz-opacity: 0; opacity: 0; } -/* line 1024, ../scss/styles.scss */ +/* line 1025, ../scss/styles.scss */ article.node-materiau.vm-cardfull.associated, article.node-breve.vm-cardfull.associated { -webkit-transition: margin 0.3s ease-out; transition: margin 0.3s ease-out; } -/* line 1026, ../scss/styles.scss */ +/* line 1027, ../scss/styles.scss */ article.node-materiau.vm-cardfull.associated.just-added, article.node-breve.vm-cardfull.associated.just-added { margin-left: -850px; margin-right: 850px; } -/* line 1028, ../scss/styles.scss */ +/* line 1029, ../scss/styles.scss */ .modal-content article.node-materiau.vm-cardfull.associated, .modal-content article.node-breve.vm-cardfull.associated { position: absolute; top: 0; left: 0; z-index: 999; } -/* line 1036, ../scss/styles.scss */ +/* line 1037, ../scss/styles.scss */ article.node-materiau.vm-cardfull.removed, article.node-breve.vm-cardfull.removed { -webkit-transition: width 0.3s ease-out; transition: width 0.3s ease-out; @@ -13256,7 +13281,7 @@ article.node-materiau.vm-cardfull.removed, article.node-breve.vm-cardfull.remove margin-left: 0; overflow: hidden; } -/* line 1046, ../scss/styles.scss */ +/* line 1047, ../scss/styles.scss */ article.node-materiau.vm-cardfull nav.nav, article.node-breve.vm-cardfull nav.nav { position: absolute; top: 0; @@ -13271,39 +13296,39 @@ article.node-materiau.vm-cardfull nav.nav, article.node-breve.vm-cardfull nav.na *background-color: white; color: #000; } -/* line 1058, ../scss/styles.scss */ +/* line 1059, ../scss/styles.scss */ article.node-materiau.vm-cardfull nav.nav a, article.node-breve.vm-cardfull nav.nav a { color: #000; } -/* line 1059, ../scss/styles.scss */ +/* line 1060, ../scss/styles.scss */ article.node-materiau.vm-cardfull nav.nav ul, article.node-breve.vm-cardfull nav.nav ul { background-color: white; background-color: rgba(255, 255, 255, 0.9); *background-color: white; } -/* line 1060, ../scss/styles.scss */ +/* line 1061, ../scss/styles.scss */ article.node-materiau.vm-cardfull nav.nav span.op, article.node-breve.vm-cardfull nav.nav span.op { font-weight: 900; font-size: 14px; } -/* line 1062, ../scss/styles.scss */ +/* line 1063, ../scss/styles.scss */ article.node-materiau.vm-cardfull nav.nav ul, article.node-breve.vm-cardfull nav.nav ul { padding: 0; margin: 0; } -/* line 1064, ../scss/styles.scss */ +/* line 1065, ../scss/styles.scss */ article.node-materiau.vm-cardfull nav.nav section, article.node-breve.vm-cardfull nav.nav section { position: relative; } -/* line 1067, ../scss/styles.scss */ +/* line 1068, ../scss/styles.scss */ article.node-materiau.vm-cardfull nav.nav section > i, article.node-breve.vm-cardfull nav.nav section > i { margin: 0 5px; } -/* line 1067, ../scss/styles.scss */ +/* line 1068, ../scss/styles.scss */ article.node-materiau.vm-cardfull nav.nav section > i:hover, article.node-breve.vm-cardfull nav.nav section > i:hover { cursor: pointer; } -/* line 1070, ../scss/styles.scss */ +/* line 1071, ../scss/styles.scss */ article.node-materiau.vm-cardfull nav.nav ul, article.node-breve.vm-cardfull nav.nav ul { position: absolute; right: 0; @@ -13316,7 +13341,7 @@ article.node-materiau.vm-cardfull nav.nav ul, article.node-breve.vm-cardfull nav background-clip: padding-box; box-shadow: -2px 2px 5px rgba(0, 0, 0, 0.2); } -/* line 1074, ../scss/styles.scss */ +/* line 1075, ../scss/styles.scss */ article.node-materiau.vm-cardfull nav.nav ul li, article.node-breve.vm-cardfull nav.nav ul li { padding: 0; margin: 0; @@ -13327,20 +13352,20 @@ article.node-materiau.vm-cardfull nav.nav ul li, article.node-breve.vm-cardfull -webkit-transition: height 0.2s ease-out; transition: height 0.2s ease-out; } -/* line 1078, ../scss/styles.scss */ +/* line 1079, ../scss/styles.scss */ article.node-materiau.vm-cardfull nav.nav ul li a, article.node-breve.vm-cardfull nav.nav ul li a { display: block; } -/* line 1081, ../scss/styles.scss */ +/* line 1082, ../scss/styles.scss */ article.node-materiau.vm-cardfull nav.nav ul.flag-lists-entity-links, article.node-breve.vm-cardfull nav.nav ul.flag-lists-entity-links { width: 160px; font-size: 0; } -/* line 1084, ../scss/styles.scss */ +/* line 1085, ../scss/styles.scss */ article.node-materiau.vm-cardfull nav.nav ul.flag-lists-entity-links > *, article.node-breve.vm-cardfull nav.nav ul.flag-lists-entity-links > * { font-size: 11px; } -/* line 1089, ../scss/styles.scss */ +/* line 1090, ../scss/styles.scss */ article.node-materiau.vm-cardfull nav.nav ul.flag-lists-entity-links li, article.node-breve.vm-cardfull nav.nav ul.flag-lists-entity-links li { display: moz-inline-stack; display: inline-block; @@ -13351,53 +13376,53 @@ article.node-materiau.vm-cardfull nav.nav ul.flag-lists-entity-links li, article max-width: 98%; padding-left: 2px; } -/* line 1091, ../scss/styles.scss */ +/* line 1092, ../scss/styles.scss */ article.node-materiau.vm-cardfull nav.nav ul.flag-lists-entity-links li a, article.node-breve.vm-cardfull nav.nav ul.flag-lists-entity-links li a { color: #a6a6a6; -webkit-transition: color 0.2s ease-out; transition: color 0.2s ease-out; } -/* line 1093, ../scss/styles.scss */ +/* line 1094, ../scss/styles.scss */ article.node-materiau.vm-cardfull nav.nav ul.flag-lists-entity-links li a:hover, article.node-materiau.vm-cardfull nav.nav ul.flag-lists-entity-links li a.unflag-action, article.node-breve.vm-cardfull nav.nav ul.flag-lists-entity-links li a:hover, article.node-breve.vm-cardfull nav.nav ul.flag-lists-entity-links li a.unflag-action { color: #000; text-decoration: none; } -/* line 1097, ../scss/styles.scss */ +/* line 1098, ../scss/styles.scss */ article.node-materiau.vm-cardfull nav.nav ul.flag-lists-entity-links li.flag-lists-create, article.node-breve.vm-cardfull nav.nav ul.flag-lists-entity-links li.flag-lists-create { display: block; width: 100%; } -/* line 1099, ../scss/styles.scss */ +/* line 1100, ../scss/styles.scss */ article.node-materiau.vm-cardfull nav.nav ul.flag-lists-entity-links li.flag-lists-create > *, article.node-breve.vm-cardfull nav.nav ul.flag-lists-entity-links li.flag-lists-create > * { margin-top: 1px; padding-top: 1px; border-top: 1px solid #e6e6e6; } -/* line 1100, ../scss/styles.scss */ +/* line 1101, ../scss/styles.scss */ article.node-materiau.vm-cardfull nav.nav ul.flag-lists-entity-links li.flag-lists-create a, article.node-breve.vm-cardfull nav.nav ul.flag-lists-entity-links li.flag-lists-create a { color: #000; } -/* line 1102, ../scss/styles.scss */ +/* line 1103, ../scss/styles.scss */ article.node-materiau.vm-cardfull nav.nav ul.flag-lists-entity-links li.loading, article.node-breve.vm-cardfull nav.nav ul.flag-lists-entity-links li.loading { background: transparent url("../img/ajax-loader.gif") no-repeat 98% center; } -/* line 1103, ../scss/styles.scss */ +/* line 1104, ../scss/styles.scss */ article.node-materiau.vm-cardfull nav.nav ul.flag-lists-entity-links li.loading a, article.node-breve.vm-cardfull nav.nav ul.flag-lists-entity-links li.loading a { visibility: hidden; } -/* line 1108, ../scss/styles.scss */ +/* line 1109, ../scss/styles.scss */ .ie8 article.node-materiau.vm-cardfull nav.nav ul, .ie8 article.node-breve.vm-cardfull nav.nav ul { background: #FFF; } -/* line 1113, ../scss/styles.scss */ +/* line 1114, ../scss/styles.scss */ article.node-materiau.vm-cardfull nav.nav section:hover ul, article.node-breve.vm-cardfull nav.nav section:hover ul { padding: 5px 5px; } -/* line 1115, ../scss/styles.scss */ +/* line 1116, ../scss/styles.scss */ article.node-materiau.vm-cardfull nav.nav section:hover ul li, article.node-breve.vm-cardfull nav.nav section:hover ul li { height: 17px; } -/* line 1128, ../scss/styles.scss */ +/* line 1129, ../scss/styles.scss */ article.node-materiau.vm-cardfull div.workflow, article.node-breve.vm-cardfull div.workflow { position: absolute; top: 0; @@ -13413,7 +13438,7 @@ article.node-materiau.vm-cardfull div.workflow, article.node-breve.vm-cardfull d *background-color: white; color: #000; } -/* line 1134, ../scss/styles.scss */ +/* line 1135, ../scss/styles.scss */ article.node-materiau.vm-cardfull div.workflow span, article.node-breve.vm-cardfull div.workflow span { padding: 3px 0 0 4px; display: moz-inline-stack; @@ -13422,7 +13447,7 @@ article.node-materiau.vm-cardfull div.workflow span, article.node-breve.vm-cardf zoom: 1; *display: inline; } -/* line 1137, ../scss/styles.scss */ +/* line 1138, ../scss/styles.scss */ article.node-materiau.vm-cardfull .field-name-field-description .upgrade, article.node-breve.vm-cardfull .field-name-field-description .upgrade { font-size: 12px; padding-top: 4em; @@ -13431,12 +13456,12 @@ article.node-materiau.vm-cardfull .field-name-field-description .upgrade, articl background: linear-gradient(to bottom, rgba(255, 255, 255, 0) 0%, #fff 4em); position: relative; } -/* line 1145, ../scss/styles.scss */ +/* line 1146, ../scss/styles.scss */ article.node-materiau.vm-cardfull .side.oops p, article.node-materiau.vm-cardfull .side .upgrade p, article.node-breve.vm-cardfull .side.oops p, article.node-breve.vm-cardfull .side .upgrade p { padding: 10px; font-size: 12px; } -/* line 1147, ../scss/styles.scss */ +/* line 1148, ../scss/styles.scss */ article.node-materiau.vm-cardfull .side.oops p a, article.node-materiau.vm-cardfull .side .upgrade p a, article.node-breve.vm-cardfull .side.oops p a, article.node-breve.vm-cardfull .side .upgrade p a { display: block; margin: 10px 0; @@ -13465,15 +13490,15 @@ article.node-materiau.vm-cardfull .side.oops p a:active, article.node-materiau.v transition: text-shadow 0s ease-out; text-shadow: 0 0 2px rgba(0, 0, 0, 0.2); } -/* line 1387, ../scss/styles.scss */ +/* line 1388, ../scss/styles.scss */ article.node-materiau.vm-cardfull nav.nav, article.node-breve.vm-cardfull nav.nav { top: 0; } -/* line 1391, ../scss/styles.scss */ +/* line 1392, ../scss/styles.scss */ article.node-materiau.vm-cardfull > *, article.node-breve.vm-cardfull > * { font-size: 16px; } -/* line 1393, ../scss/styles.scss */ +/* line 1394, ../scss/styles.scss */ article.node-materiau.vm-cardfull > .side, article.node-breve.vm-cardfull > .side { display: moz-inline-stack; display: inline-block; @@ -13482,17 +13507,17 @@ article.node-materiau.vm-cardfull > .side, article.node-breve.vm-cardfull > .sid *display: inline; width: 50%; } -/* line 1394, ../scss/styles.scss */ +/* line 1395, ../scss/styles.scss */ article.node-materiau.vm-cardfull > .side.group-side-left, article.node-breve.vm-cardfull > .side.group-side-left { border-radius: 5px 0 0 5px; background-clip: padding-box; } -/* line 1397, ../scss/styles.scss */ +/* line 1398, ../scss/styles.scss */ article.node-materiau.vm-cardfull > .side.group-side-right, article.node-breve.vm-cardfull > .side.group-side-right { border-radius: 0 5px 5px 0; background-clip: padding-box; } -/* line 1403, ../scss/styles.scss */ +/* line 1404, ../scss/styles.scss */ article.node-materiau.vm-cardfull .group-images, article.node-breve.vm-cardfull .group-images { position: relative; z-index: 1; @@ -13509,17 +13534,17 @@ article.node-materiau.vm-cardfull .group-images figure:first-child, article.node position: relative; z-index: 1; } -/* line 1405, ../scss/styles.scss */ +/* line 1406, ../scss/styles.scss */ article.node-materiau.vm-cardfull .group-header, article.node-breve.vm-cardfull .group-header { font-size: 20px; font-weight: 300; padding: 10px; } -/* line 1407, ../scss/styles.scss */ +/* line 1408, ../scss/styles.scss */ article.node-materiau.vm-cardfull .group-header .field-name-title-field, article.node-breve.vm-cardfull .group-header .field-name-title-field { font-weight: 700; } -/* line 1408, ../scss/styles.scss */ +/* line 1409, ../scss/styles.scss */ article.node-materiau.vm-cardfull .group-header .field-name-field-reference-materio, article.node-materiau.vm-cardfull .group-header .field-name-field-localisation, article.node-materiau.vm-cardfull .group-header .field-name-field-authored-on, article.node-breve.vm-cardfull .group-header .field-name-field-reference-materio, article.node-breve.vm-cardfull .group-header .field-name-field-localisation, article.node-breve.vm-cardfull .group-header .field-name-field-authored-on { display: moz-inline-stack; display: inline-block; @@ -13529,7 +13554,7 @@ article.node-materiau.vm-cardfull .group-header .field-name-field-reference-mate font-size: 12px; padding-right: 15px; } -/* line 1412, ../scss/styles.scss */ +/* line 1413, ../scss/styles.scss */ article.node-materiau.vm-cardfull.node-breve .group-header, article.node-breve.vm-cardfull.node-breve .group-header { color: #fff; background-color: black; @@ -13539,22 +13564,22 @@ article.node-materiau.vm-cardfull.node-breve .group-header, article.node-breve.v -webkit-transition: background-color 0.2s ease-out; transition: background-color 0.2s ease-out; } -/* line 1414, ../scss/styles.scss */ +/* line 1415, ../scss/styles.scss */ article.node-materiau.vm-cardfull.node-breve .group-header .field-name-field-authored-on, article.node-breve.vm-cardfull.node-breve .group-header .field-name-field-authored-on { font-weight: 500; } -/* line 1418, ../scss/styles.scss */ +/* line 1419, ../scss/styles.scss */ article.node-materiau.vm-cardfull .field-name-field-description, article.node-materiau.vm-cardfull .field-name-body, article.node-breve.vm-cardfull .field-name-field-description, article.node-breve.vm-cardfull .field-name-body { font-size: 12px; font-weight: 300; padding: 10px; } -/* line 1422, ../scss/styles.scss */ +/* line 1423, ../scss/styles.scss */ article.node-materiau.vm-cardfull .field-name-field-attachments, article.node-breve.vm-cardfull .field-name-field-attachments { padding: 10px; font-size: 12px; } -/* line 1428, ../scss/styles.scss */ +/* line 1429, ../scss/styles.scss */ article.node-materiau.vm-cardfull .field-name-field-company-fab, article.node-materiau.vm-cardfull .field-name-field-company-distrib, article.node-breve.vm-cardfull .field-name-field-company-fab, article.node-breve.vm-cardfull .field-name-field-company-distrib { font-size: 12px; padding: 10px; @@ -13566,48 +13591,48 @@ article.node-materiau.vm-cardfull .field-name-field-company-fab, article.node-ma *display: inline; width: 40%; } -/* line 1431, ../scss/styles.scss */ +/* line 1432, ../scss/styles.scss */ article.node-materiau.vm-cardfull .field-name-field-company-fab .field-item, article.node-materiau.vm-cardfull .field-name-field-company-distrib .field-item, article.node-breve.vm-cardfull .field-name-field-company-fab .field-item, article.node-breve.vm-cardfull .field-name-field-company-distrib .field-item { margin-top: 1em; } -/* line 1432, ../scss/styles.scss */ +/* line 1433, ../scss/styles.scss */ article.node-materiau.vm-cardfull .field-name-field-company-fab .field-label, article.node-materiau.vm-cardfull .field-name-field-company-distrib .field-label, article.node-breve.vm-cardfull .field-name-field-company-fab .field-label, article.node-breve.vm-cardfull .field-name-field-company-distrib .field-label { font-size: 10px; text-transform: lowercase; float: none; } -/* line 1433, ../scss/styles.scss */ +/* line 1434, ../scss/styles.scss */ article.node-materiau.vm-cardfull .field-name-field-company-fab .field-name-field-tode-company, article.node-materiau.vm-cardfull .field-name-field-company-distrib .field-name-field-tode-company, article.node-breve.vm-cardfull .field-name-field-company-fab .field-name-field-tode-company, article.node-breve.vm-cardfull .field-name-field-company-distrib .field-name-field-tode-company { font-size: 14px; } -/* line 1436, ../scss/styles.scss */ +/* line 1437, ../scss/styles.scss */ article.node-materiau.vm-cardfull .field-name-field-materiau-ref, article.node-materiau.vm-cardfull .field-name-field-source, article.node-materiau.vm-cardfull .field-name-field-attachments, article.node-breve.vm-cardfull .field-name-field-materiau-ref, article.node-breve.vm-cardfull .field-name-field-source, article.node-breve.vm-cardfull .field-name-field-attachments { font-size: 12px; padding: 10px; font-weight: 300; } -/* line 1437, ../scss/styles.scss */ +/* line 1438, ../scss/styles.scss */ article.node-materiau.vm-cardfull .field-name-field-materiau-ref a, article.node-materiau.vm-cardfull .field-name-field-source a, article.node-materiau.vm-cardfull .field-name-field-attachments a, article.node-breve.vm-cardfull .field-name-field-materiau-ref a, article.node-breve.vm-cardfull .field-name-field-source a, article.node-breve.vm-cardfull .field-name-field-attachments a { color: #000; } -/* line 1439, ../scss/styles.scss */ +/* line 1440, ../scss/styles.scss */ article.node-materiau.vm-cardfull .field-label, article.node-breve.vm-cardfull .field-label { font-weight: 900; margin: 0 0 0.5em; } -/* line 1442, ../scss/styles.scss */ +/* line 1443, ../scss/styles.scss */ article.node-materiau.vm-cardfull nav.nav, article.node-breve.vm-cardfull nav.nav { margin: 5px; } -/* line 1444, ../scss/styles.scss */ +/* line 1445, ../scss/styles.scss */ article.node-materiau.vm-cardfull div.workflow, article.node-breve.vm-cardfull div.workflow { margin: 5px; } -/* line 1447, ../scss/styles.scss */ +/* line 1448, ../scss/styles.scss */ article.node-materiau.vm-cardfull .side.oops p, article.node-materiau.vm-cardfull .side .upgrade p, article.node-breve.vm-cardfull .side.oops p, article.node-breve.vm-cardfull .side .upgrade p { padding: 3em; } -/* line 1449, ../scss/styles.scss */ +/* line 1450, ../scss/styles.scss */ article.node-materiau.vm-cardfull .side.oops p a, article.node-materiau.vm-cardfull .side .upgrade p a, article.node-breve.vm-cardfull .side.oops p a, article.node-breve.vm-cardfull .side .upgrade p a { border: 2px solid #eee; background-color: #eee; @@ -13617,7 +13642,7 @@ article.node-materiau.vm-cardfull .side.oops p a, article.node-materiau.vm-cardf -webkit-transition: background-color 0.3s ease-out; transition: background-color 0.3s ease-out; } -/* line 1456, ../scss/styles.scss */ +/* line 1457, ../scss/styles.scss */ article.node-materiau.vm-cardfull:hover .side.oops p a, article.node-materiau.vm-cardfull:hover .side .upgrade p a, article.node-breve.vm-cardfull:hover .side.oops p a, article.node-breve.vm-cardfull:hover .side .upgrade p a { border: 2px solid #69CDCF; background-color: #69CDCF; @@ -13716,138 +13741,6 @@ div.messages.status { /** * icons */ -/* line 141, ../scss/misc.scss */ -i.icon-materio-viewmode-cardsmall { - background-image: url("../img/sprite.png"); - width: 20px; - height: 20px; - line-height: 20px; - background-position: -42px 0; - background-color: #fff; -} -/* line 143, ../scss/misc.scss */ -i.icon-materio-viewmode-cardsmall.active { - background-image: url("../img/sprite.png"); - width: 21px; - height: 21px; - line-height: 21px; - background-position: 0 0; - background-color: #fff; -} -/* line 144, ../scss/misc.scss */ -i.icon-materio-viewmode-cardsmall:hover:not(.active) { - background-image: url("../img/sprite.png"); - width: 21px; - height: 21px; - line-height: 21px; - background-position: -21px 0; - background-color: #fff; -} - -/* line 146, ../scss/misc.scss */ -i.icon-materio-viewmode-cardmedium { - background-image: url("../img/sprite.png"); - width: 21px; - height: 21px; - line-height: 21px; - background-position: -42px -21px; - background-color: #fff; -} -/* line 148, ../scss/misc.scss */ -i.icon-materio-viewmode-cardmedium.active { - background-image: url("../img/sprite.png"); - width: 21px; - height: 21px; - line-height: 21px; - background-position: 0 -21px; - background-color: #fff; -} -/* line 149, ../scss/misc.scss */ -i.icon-materio-viewmode-cardmedium:hover:not(.active) { - background-image: url("../img/sprite.png"); - width: 21px; - height: 21px; - line-height: 21px; - background-position: -21px -21px; - background-color: #fff; -} - -/* line 151, ../scss/misc.scss */ -i.icon-materio-viewmode-cardbig { - background-image: url("../img/sprite.png"); - width: 21px; - height: 21px; - line-height: 21px; - background-position: -42px -42px; - background-color: #fff; -} -/* line 153, ../scss/misc.scss */ -i.icon-materio-viewmode-cardbig.active { - background-image: url("../img/sprite.png"); - width: 21px; - height: 21px; - line-height: 21px; - background-position: 0 -42px; - background-color: #fff; -} -/* line 154, ../scss/misc.scss */ -i.icon-materio-viewmode-cardbig:hover:not(.active) { - background-image: url("../img/sprite.png"); - width: 21px; - height: 21px; - line-height: 21px; - background-position: -21px -42px; - background-color: #fff; -} - -/* line 156, ../scss/misc.scss */ -i.icon-materio-viewmode-cardfull { - background-image: url("../img/sprite.png"); - width: 21px; - height: 21px; - line-height: 21px; - background-position: -42px -63px; - background-color: #fff; -} -/* line 158, ../scss/misc.scss */ -i.icon-materio-viewmode-cardfull.active { - background-image: url("../img/sprite.png"); - width: 21px; - height: 21px; - line-height: 21px; - background-position: 0 -63px; - background-color: #fff; -} -/* line 159, ../scss/misc.scss */ -i.icon-materio-viewmode-cardfull:hover:not(.active) { - background-image: url("../img/sprite.png"); - width: 21px; - height: 21px; - line-height: 21px; - background-position: -21px -63px; - background-color: #fff; -} - -/* line 162, ../scss/misc.scss */ -i.icon-materio-search { - background-image: url("../img/sprite.png"); - width: 21px; - height: 21px; - line-height: 21px; - background-position: -63px -63px; - background-color: #fff; -} - -/* line 166, ../scss/misc.scss */ -i.icon-materio-folder { - background-image: url("../img/sprite.png"); - width: 21px; - height: 21px; - line-height: 21px; - background-position: -84px -63px; - background-color: #fff; -} - /** * figures */ @@ -13910,7 +13803,7 @@ a:hover { } /** AUTOCOMPLETE */ -/* line 1466, ../scss/styles.scss */ +/* line 1467, ../scss/styles.scss */ #autocomplete { border: 0; border-radius: 3px; @@ -13921,23 +13814,23 @@ a:hover { text-align: left; margin-left: 2px; } -/* line 1471, ../scss/styles.scss */ +/* line 1472, ../scss/styles.scss */ .oldie #autocomplete { background-color: #545454; } -/* line 1472, ../scss/styles.scss */ +/* line 1473, ../scss/styles.scss */ #autocomplete li { color: #FFF; background-color: transparent; font-size: 12px; } -/* line 1474, ../scss/styles.scss */ +/* line 1475, ../scss/styles.scss */ #autocomplete li.selected { background-color: black; background-color: rgba(0, 0, 0, 0.8); *background-color: black; } -/* line 1475, ../scss/styles.scss */ +/* line 1476, ../scss/styles.scss */ #autocomplete li div { padding: 0.1em 5px; } @@ -13945,7 +13838,7 @@ a:hover { /** * the old modal api (balck bg) for contextual forms (create new flag list) */ -/* line 1507, ../scss/styles.scss */ +/* line 1508, ../scss/styles.scss */ #modal { background-color: rgba(0, 0, 0, 0.7); border-radius: 5px; @@ -13953,35 +13846,35 @@ a:hover { border: 0; font-size: 12px; } -/* line 1486, ../scss/styles.scss */ +/* line 1487, ../scss/styles.scss */ #modal * { color: #fff; background-color: transparent; } -/* line 1488, ../scss/styles.scss */ +/* line 1489, ../scss/styles.scss */ #modal form { background-color: transparent; color: #fff; border: 0px; } -/* line 1491, ../scss/styles.scss */ +/* line 1492, ../scss/styles.scss */ #modal form .form-actions { background-color: transparent; margin: 0; padding: 0; border: 0; } -/* line 1494, ../scss/styles.scss */ +/* line 1495, ../scss/styles.scss */ #modal form input.form-text, #modal form textarea, #modal form div.grippie { background-color: #fff; color: #000; border: 0; } -/* line 1496, ../scss/styles.scss */ +/* line 1497, ../scss/styles.scss */ #modal form .form-actions { text-align: right; } -/* line 1497, ../scss/styles.scss */ +/* line 1498, ../scss/styles.scss */ #modal form input.form-submit { border-style: solid; border-width: 0; @@ -14016,15 +13909,15 @@ a:hover { #modal form input.form-submit:hover, #modal form input.form-submit:focus { color: #FFFFFF; } -/* line 1509, ../scss/styles.scss */ +/* line 1510, ../scss/styles.scss */ #modal > * { padding: 10px; } -/* line 1513, ../scss/styles.scss */ +/* line 1514, ../scss/styles.scss */ #modal .form-item-flag-lists-name input { width: 95%; } -/* line 1516, ../scss/styles.scss */ +/* line 1517, ../scss/styles.scss */ #modal .actions { text-align: right; } @@ -14032,7 +13925,7 @@ a:hover { /** * the new modal api used for preview and register modal */ -/* line 1524, ../scss/styles.scss */ +/* line 1525, ../scss/styles.scss */ .modal-wrapper { bottom: 0; left: 0; @@ -14043,7 +13936,7 @@ a:hover { white-space: nowrap; z-index: 99998; } -/* line 1525, ../scss/styles.scss */ +/* line 1526, ../scss/styles.scss */ .modal-wrapper:before { content: ""; display: inline-block; @@ -14051,11 +13944,11 @@ a:hover { margin-right: -0.25em; vertical-align: middle; } -/* line 1532, ../scss/styles.scss */ +/* line 1533, ../scss/styles.scss */ .modal-wrapper:after, .modal-wrapper:before { -moz-box-sizing: border-box; } -/* line 1547, ../scss/styles.scss */ +/* line 1548, ../scss/styles.scss */ .modal-wrapper .modal-bg { background-color: #000; position: absolute; @@ -14068,7 +13961,7 @@ a:hover { -moz-opacity: 0.5; opacity: 0.5; } -/* line 1555, ../scss/styles.scss */ +/* line 1556, ../scss/styles.scss */ .modal-wrapper .modal-content { position: relative; display: inline-block; @@ -14081,16 +13974,16 @@ a:hover { /** MODALCONTENT */ /** JSCROLLPAN */ -/* line 1614, ../scss/styles.scss */ +/* line 1615, ../scss/styles.scss */ .jspContainer .jspVerticalBar { background-color: transparent; width: 5px; } -/* line 1618, ../scss/styles.scss */ +/* line 1619, ../scss/styles.scss */ .jspContainer .jspVerticalBar .jspTrack { background-color: transparent; } -/* line 1620, ../scss/styles.scss */ +/* line 1621, ../scss/styles.scss */ .jspContainer .jspVerticalBar .jspTrack .jspDrag { background-color: #ccc; border-radius: 3px; @@ -14098,7 +13991,7 @@ a:hover { } /** TOOLTIP */ -/* line 1629, ../scss/styles.scss */ +/* line 1630, ../scss/styles.scss */ #tooltip { position: absolute; z-index: 999; @@ -14111,7 +14004,7 @@ a:hover { font-weight: 500; box-shadow: 0 0 5px rgba(0, 0, 0, 0.4); } -/* line 1633, ../scss/styles.scss */ +/* line 1634, ../scss/styles.scss */ #tooltip.op-visible { -webkit-transition: opacity 0.1s ease-out; transition: opacity 0.1s ease-out; @@ -14119,24 +14012,24 @@ a:hover { /** FEEDBACK */ @media only screen and (min-width: 40.063em) and (max-width: 64em) { - /* line 1640, ../scss/styles.scss */ + /* line 1641, ../scss/styles.scss */ #block-feedback-form { bottom: 5px; left: 5px; right: auto; } } -/* line 1644, ../scss/styles.scss */ +/* line 1645, ../scss/styles.scss */ #block-feedback-form h2 { line-height: 1.2; font-size: 14px; margin: 0; } -/* line 1646, ../scss/styles.scss */ +/* line 1647, ../scss/styles.scss */ #block-feedback-form h2 .title { display: none; } -/* line 1649, ../scss/styles.scss */ +/* line 1650, ../scss/styles.scss */ #block-feedback-form #feedback-form-toggle { padding: 2px 3px; border-radius: 3px; @@ -14146,7 +14039,7 @@ a:hover { line-height: 2; font-weight: 900; } -/* line 1653, ../scss/styles.scss */ +/* line 1654, ../scss/styles.scss */ #block-feedback-form .content { background-color: rgba(0, 0, 0, 0.7); border-radius: 5px; @@ -14154,35 +14047,35 @@ a:hover { border: 0; font-size: 12px; } -/* line 1486, ../scss/styles.scss */ +/* line 1487, ../scss/styles.scss */ #block-feedback-form .content * { color: #fff; background-color: transparent; } -/* line 1488, ../scss/styles.scss */ +/* line 1489, ../scss/styles.scss */ #block-feedback-form .content form { background-color: transparent; color: #fff; border: 0px; } -/* line 1491, ../scss/styles.scss */ +/* line 1492, ../scss/styles.scss */ #block-feedback-form .content form .form-actions { background-color: transparent; margin: 0; padding: 0; border: 0; } -/* line 1494, ../scss/styles.scss */ +/* line 1495, ../scss/styles.scss */ #block-feedback-form .content form input.form-text, #block-feedback-form .content form textarea, #block-feedback-form .content form div.grippie { background-color: #fff; color: #000; border: 0; } -/* line 1496, ../scss/styles.scss */ +/* line 1497, ../scss/styles.scss */ #block-feedback-form .content form .form-actions { text-align: right; } -/* line 1497, ../scss/styles.scss */ +/* line 1498, ../scss/styles.scss */ #block-feedback-form .content form input.form-submit { border-style: solid; border-width: 0; @@ -14217,18 +14110,18 @@ a:hover { #block-feedback-form .content form input.form-submit:hover, #block-feedback-form .content form input.form-submit:focus { color: #FFFFFF; } -/* line 1655, ../scss/styles.scss */ +/* line 1656, ../scss/styles.scss */ .ie8 #block-feedback-form .content { background: #000; } -/* line 1658, ../scss/styles.scss */ +/* line 1659, ../scss/styles.scss */ #block-feedback-form #feedback-status-message { background-color: #fff; padding: 5px; } /** TASK / TABS **/ -/* line 1676, ../scss/styles.scss */ +/* line 1677, ../scss/styles.scss */ #tasks ul.tabs { display: moz-inline-stack; display: inline-block; @@ -14239,23 +14132,23 @@ a:hover { padding: 0; margin: 0; } -/* line 1680, ../scss/styles.scss */ +/* line 1681, ../scss/styles.scss */ #tasks ul.tabs li { padding: 0; margin: 2px 5px; border: 0 solid #fff; } -/* line 1681, ../scss/styles.scss */ +/* line 1682, ../scss/styles.scss */ #tasks ul.tabs a { border: 0; color: #7f7f7f; } -/* line 1683, ../scss/styles.scss */ +/* line 1684, ../scss/styles.scss */ #tasks ul.tabs a.active, #tasks ul.tabs a:hover { font-weight: 900; color: #000; } -/* line 1663, ../scss/styles.scss */ +/* line 1664, ../scss/styles.scss */ #tasks ul.tabs.primary a { font-size: 12px; padding: 5px 10px; @@ -14263,11 +14156,11 @@ a:hover { border-radius: 3px; background-clip: padding-box; } -/* line 1667, ../scss/styles.scss */ +/* line 1668, ../scss/styles.scss */ #tasks ul.tabs.primary a.active, #tasks ul.tabs.primary a:hover { background-color: #e6e6e6; } -/* line 1690, ../scss/styles.scss */ +/* line 1691, ../scss/styles.scss */ #tasks ul.tabs.secondary { font-size: 10px; padding: 0.5em 1em; @@ -14275,20 +14168,20 @@ a:hover { /** STATICS */ /** user */ -/* line 1701, ../scss/styles.scss */ +/* line 1702, ../scss/styles.scss */ .page-user #main, .page-user-edit #main, .page-user-password #main, .page-user-reset #main, .page-toboggan #main { background: #fff url("../img/user-page-bg.gif") no-repeat bottom right; } -/* line 1703, ../scss/styles.scss */ +/* line 1704, ../scss/styles.scss */ .page-user .messages, .page-user-edit .messages, .page-user-password .messages, .page-user-reset .messages, .page-toboggan .messages { width: 800px; margin: 0 auto; } -/* line 1705, ../scss/styles.scss */ +/* line 1706, ../scss/styles.scss */ .page-user.role-6 #tasks .tabs.primary, .page-user-edit.role-6 #tasks .tabs.primary, .page-user-password.role-6 #tasks .tabs.primary, .page-user-reset.role-6 #tasks .tabs.primary, .page-toboggan.role-6 #tasks .tabs.primary { display: none; } -/* line 1663, ../scss/styles.scss */ +/* line 1664, ../scss/styles.scss */ .page-user.role-6 #tasks .tabs.secondary a, .page-user-edit.role-6 #tasks .tabs.secondary a, .page-user-password.role-6 #tasks .tabs.secondary a, .page-user-reset.role-6 #tasks .tabs.secondary a, .page-toboggan.role-6 #tasks .tabs.secondary a { font-size: 12px; padding: 5px 10px; @@ -14296,11 +14189,11 @@ a:hover { border-radius: 3px; background-clip: padding-box; } -/* line 1667, ../scss/styles.scss */ +/* line 1668, ../scss/styles.scss */ .page-user.role-6 #tasks .tabs.secondary a.active, .page-user.role-6 #tasks .tabs.secondary a:hover, .page-user-edit.role-6 #tasks .tabs.secondary a.active, .page-user-edit.role-6 #tasks .tabs.secondary a:hover, .page-user-password.role-6 #tasks .tabs.secondary a.active, .page-user-password.role-6 #tasks .tabs.secondary a:hover, .page-user-reset.role-6 #tasks .tabs.secondary a.active, .page-user-reset.role-6 #tasks .tabs.secondary a:hover, .page-toboggan.role-6 #tasks .tabs.secondary a.active, .page-toboggan.role-6 #tasks .tabs.secondary a:hover { background-color: #e6e6e6; } -/* line 1708, ../scss/styles.scss */ +/* line 1709, ../scss/styles.scss */ .page-user #content .inner-content > *, .page-user-edit #content .inner-content > *, .page-user-password #content .inner-content > *, .page-user-reset #content .inner-content > *, .page-toboggan #content .inner-content > * { width: 800px; margin: 0 auto; @@ -14308,11 +14201,11 @@ a:hover { font-size: 14px; /* #user-profile-form */ } -/* line 1711, ../scss/styles.scss */ +/* line 1712, ../scss/styles.scss */ .page-user #content .inner-content > * fieldset, .page-user-edit #content .inner-content > * fieldset, .page-user-password #content .inner-content > * fieldset, .page-user-reset #content .inner-content > * fieldset, .page-toboggan #content .inner-content > * fieldset { margin-bottom: 1em; } -/* line 1715, ../scss/styles.scss */ +/* line 1716, ../scss/styles.scss */ .page-user #content .inner-content > * legend, .page-user-edit #content .inner-content > * legend, .page-user-password #content .inner-content > * legend, .page-user-reset #content .inner-content > * legend, .page-toboggan #content .inner-content > * legend { font-size: 16px; margin: 0; @@ -14320,16 +14213,16 @@ a:hover { line-height: 1; border: 0 solid #fff; } -/* line 1717, ../scss/styles.scss */ +/* line 1718, ../scss/styles.scss */ .page-user #content .inner-content > * legend a, .page-user-edit #content .inner-content > * legend a, .page-user-password #content .inner-content > * legend a, .page-user-reset #content .inner-content > * legend a, .page-toboggan #content .inner-content > * legend a { color: #000; } -/* line 1720, ../scss/styles.scss */ +/* line 1721, ../scss/styles.scss */ .page-user #content .inner-content > * .form-item, .page-user-edit #content .inner-content > * .form-item, .page-user-password #content .inner-content > * .form-item, .page-user-reset #content .inner-content > * .form-item, .page-toboggan #content .inner-content > * .form-item { margin: 0 0 0.5em 0; width: 100%; } -/* line 1722, ../scss/styles.scss */ +/* line 1723, ../scss/styles.scss */ .page-user #content .inner-content > * .form-item label, .page-user #content .inner-content > * .form-item input.form-text, .page-user-edit #content .inner-content > * .form-item label, .page-user-edit #content .inner-content > * .form-item input.form-text, .page-user-password #content .inner-content > * .form-item label, .page-user-password #content .inner-content > * .form-item input.form-text, .page-user-reset #content .inner-content > * .form-item label, .page-user-reset #content .inner-content > * .form-item input.form-text, .page-toboggan #content .inner-content > * .form-item label, .page-toboggan #content .inner-content > * .form-item input.form-text { display: moz-inline-stack; display: inline-block; @@ -14338,42 +14231,42 @@ a:hover { *display: inline; vertical-align: middle; } -/* line 1725, ../scss/styles.scss */ +/* line 1726, ../scss/styles.scss */ .page-user #content .inner-content > * .form-item label, .page-user-edit #content .inner-content > * .form-item label, .page-user-password #content .inner-content > * .form-item label, .page-user-reset #content .inner-content > * .form-item label, .page-toboggan #content .inner-content > * .form-item label { margin-right: 1em; min-width: 6em; } -/* line 1726, ../scss/styles.scss */ +/* line 1727, ../scss/styles.scss */ .page-user #content .inner-content > * .form-item input.form-text, .page-user-edit #content .inner-content > * .form-item input.form-text, .page-user-password #content .inner-content > * .form-item input.form-text, .page-user-reset #content .inner-content > * .form-item input.form-text, .page-toboggan #content .inner-content > * .form-item input.form-text { padding: 2px 4px; } -/* line 1731, ../scss/styles.scss */ +/* line 1732, ../scss/styles.scss */ .page-user #content .inner-content > * .form-wrapper > .form-item, .page-user-edit #content .inner-content > * .form-wrapper > .form-item, .page-user-password #content .inner-content > * .form-wrapper > .form-item, .page-user-reset #content .inner-content > * .form-wrapper > .form-item, .page-toboggan #content .inner-content > * .form-wrapper > .form-item { margin: 0 0 2em 0; } -/* line 1735, ../scss/styles.scss */ +/* line 1736, ../scss/styles.scss */ .page-user #content .inner-content > * .form-type-password-confirm label, .page-user #content .inner-content > * .form-type-new-password-confirm label, .page-user-edit #content .inner-content > * .form-type-password-confirm label, .page-user-edit #content .inner-content > * .form-type-new-password-confirm label, .page-user-password #content .inner-content > * .form-type-password-confirm label, .page-user-password #content .inner-content > * .form-type-new-password-confirm label, .page-user-reset #content .inner-content > * .form-type-password-confirm label, .page-user-reset #content .inner-content > * .form-type-new-password-confirm label, .page-toboggan #content .inner-content > * .form-type-password-confirm label, .page-toboggan #content .inner-content > * .form-type-new-password-confirm label { width: 9em; } -/* line 1736, ../scss/styles.scss */ +/* line 1737, ../scss/styles.scss */ .page-user #content .inner-content > * .form-type-password-confirm .password-parent, .page-user #content .inner-content > * .form-type-new-password-confirm .password-parent, .page-user-edit #content .inner-content > * .form-type-password-confirm .password-parent, .page-user-edit #content .inner-content > * .form-type-new-password-confirm .password-parent, .page-user-password #content .inner-content > * .form-type-password-confirm .password-parent, .page-user-password #content .inner-content > * .form-type-new-password-confirm .password-parent, .page-user-reset #content .inner-content > * .form-type-password-confirm .password-parent, .page-user-reset #content .inner-content > * .form-type-new-password-confirm .password-parent, .page-toboggan #content .inner-content > * .form-type-password-confirm .password-parent, .page-toboggan #content .inner-content > * .form-type-new-password-confirm .password-parent { width: auto; } -/* line 1737, ../scss/styles.scss */ +/* line 1738, ../scss/styles.scss */ .page-user #content .inner-content > * .form-type-password-confirm .password-strength, .page-user #content .inner-content > * .form-type-password-confirm .password-confirm, .page-user #content .inner-content > * .form-type-new-password-confirm .password-strength, .page-user #content .inner-content > * .form-type-new-password-confirm .password-confirm, .page-user-edit #content .inner-content > * .form-type-password-confirm .password-strength, .page-user-edit #content .inner-content > * .form-type-password-confirm .password-confirm, .page-user-edit #content .inner-content > * .form-type-new-password-confirm .password-strength, .page-user-edit #content .inner-content > * .form-type-new-password-confirm .password-confirm, .page-user-password #content .inner-content > * .form-type-password-confirm .password-strength, .page-user-password #content .inner-content > * .form-type-password-confirm .password-confirm, .page-user-password #content .inner-content > * .form-type-new-password-confirm .password-strength, .page-user-password #content .inner-content > * .form-type-new-password-confirm .password-confirm, .page-user-reset #content .inner-content > * .form-type-password-confirm .password-strength, .page-user-reset #content .inner-content > * .form-type-password-confirm .password-confirm, .page-user-reset #content .inner-content > * .form-type-new-password-confirm .password-strength, .page-user-reset #content .inner-content > * .form-type-new-password-confirm .password-confirm, .page-toboggan #content .inner-content > * .form-type-password-confirm .password-strength, .page-toboggan #content .inner-content > * .form-type-password-confirm .password-confirm, .page-toboggan #content .inner-content > * .form-type-new-password-confirm .password-strength, .page-toboggan #content .inner-content > * .form-type-new-password-confirm .password-confirm { width: 15em; margin-top: 0; } -/* line 1743, ../scss/styles.scss */ +/* line 1744, ../scss/styles.scss */ .page-user #content .inner-content > * .form-type-checkbox input, .page-user-edit #content .inner-content > * .form-type-checkbox input, .page-user-password #content .inner-content > * .form-type-checkbox input, .page-user-reset #content .inner-content > * .form-type-checkbox input, .page-toboggan #content .inner-content > * .form-type-checkbox input { margin: 0; } -/* line 1744, ../scss/styles.scss */ +/* line 1745, ../scss/styles.scss */ .page-user #content .inner-content > * .form-type-checkbox label, .page-user-edit #content .inner-content > * .form-type-checkbox label, .page-user-password #content .inner-content > * .form-type-checkbox label, .page-user-reset #content .inner-content > * .form-type-checkbox label, .page-toboggan #content .inner-content > * .form-type-checkbox label { font-size: 14px; margin: 0; } -/* line 1748, ../scss/styles.scss */ +/* line 1749, ../scss/styles.scss */ .page-user #content .inner-content > * #edit-language .form-item, .page-user-edit #content .inner-content > * #edit-language .form-item, .page-user-password #content .inner-content > * #edit-language .form-item, .page-user-reset #content .inner-content > * #edit-language .form-item, .page-toboggan #content .inner-content > * #edit-language .form-item { display: moz-inline-stack; display: inline-block; @@ -14383,27 +14276,27 @@ a:hover { width: auto; margin-right: 1em; } -/* line 1750, ../scss/styles.scss */ +/* line 1751, ../scss/styles.scss */ .page-user #content .inner-content > * #edit-language .form-item input, .page-user #content .inner-content > * #edit-language .form-item label, .page-user-edit #content .inner-content > * #edit-language .form-item input, .page-user-edit #content .inner-content > * #edit-language .form-item label, .page-user-password #content .inner-content > * #edit-language .form-item input, .page-user-password #content .inner-content > * #edit-language .form-item label, .page-user-reset #content .inner-content > * #edit-language .form-item input, .page-user-reset #content .inner-content > * #edit-language .form-item label, .page-toboggan #content .inner-content > * #edit-language .form-item input, .page-toboggan #content .inner-content > * #edit-language .form-item label { margin: 0; } -/* line 1754, ../scss/styles.scss */ +/* line 1755, ../scss/styles.scss */ .page-user #content .inner-content > * select.form-select, .page-user-edit #content .inner-content > * select.form-select, .page-user-password #content .inner-content > * select.form-select, .page-user-reset #content .inner-content > * select.form-select, .page-toboggan #content .inner-content > * select.form-select { width: auto; padding: 2px 4px; height: auto; } -/* line 1758, ../scss/styles.scss */ +/* line 1759, ../scss/styles.scss */ .page-user #content .inner-content > * div.description, .page-user-edit #content .inner-content > * div.description, .page-user-password #content .inner-content > * div.description, .page-user-reset #content .inner-content > * div.description, .page-toboggan #content .inner-content > * div.description { font-size: 10px; } -/* line 1761, ../scss/styles.scss */ +/* line 1762, ../scss/styles.scss */ .page-user #content .inner-content > * div.form-actions, .page-user-edit #content .inner-content > * div.form-actions, .page-user-password #content .inner-content > * div.form-actions, .page-user-reset #content .inner-content > * div.form-actions, .page-toboggan #content .inner-content > * div.form-actions { margin: 0; text-align: right; padding: 1em 0.5em; } -/* line 1768, ../scss/styles.scss */ +/* line 1769, ../scss/styles.scss */ .page-user #content .inner-content > * #edit-profile-adherent-field-first-name, .page-user #content .inner-content > * #edit-profile-adherent-field-name, .page-user #content .inner-content > * #edit-profile-adherent-field-private-quality, .page-user #content .inner-content > * #edit-profile-adherent-field-service, .page-user #content .inner-content > * #edit-profile-adherent-field-employee, .page-user #content .inner-content > * #edit-profile-adherent-field-naf, .page-user #content .inner-content > * #edit-profile-adherent-field-siret, .page-user-edit #content .inner-content > * #edit-profile-adherent-field-first-name, .page-user-edit #content .inner-content > * #edit-profile-adherent-field-name, @@ -14424,7 +14317,7 @@ a:hover { width: auto; margin: 0 1em 0.5em 0; } -/* line 1772, ../scss/styles.scss */ +/* line 1773, ../scss/styles.scss */ .page-user #content .inner-content > * #edit-profile-adherent-field-first-name div, .page-user #content .inner-content > * #edit-profile-adherent-field-name div, .page-user #content .inner-content > * #edit-profile-adherent-field-private-quality div, .page-user #content .inner-content > * #edit-profile-adherent-field-service div, .page-user #content .inner-content > * #edit-profile-adherent-field-employee div, .page-user #content .inner-content > * #edit-profile-adherent-field-naf div, .page-user #content .inner-content > * #edit-profile-adherent-field-siret div, .page-user-edit #content .inner-content > * #edit-profile-adherent-field-first-name div, .page-user-edit #content .inner-content > * #edit-profile-adherent-field-name div, @@ -14440,7 +14333,7 @@ a:hover { margin: 0; padding: 0; } -/* line 1778, ../scss/styles.scss */ +/* line 1779, ../scss/styles.scss */ .page-user #content .inner-content > * #edit-profile-adherent-field-name label, .page-user #content .inner-content > * #edit-profile-adherent-field-service label, .page-user #content .inner-content > * #edit-profile-adherent-field-naf label, .page-user #content .inner-content > * #edit-profile-adherent-field-siret label, .page-user #content .inner-content > * .form-item-profile-adherent-field-adresse-und-0-locality label, .page-user-edit #content .inner-content > * #edit-profile-adherent-field-name label, .page-user-edit #content .inner-content > * #edit-profile-adherent-field-service label, .page-user-edit #content .inner-content > * #edit-profile-adherent-field-naf label, .page-user-edit #content .inner-content > * #edit-profile-adherent-field-siret label, .page-user-edit #content .inner-content > * .form-item-profile-adherent-field-adresse-und-0-locality label, .page-user-password #content .inner-content > * #edit-profile-adherent-field-name label, .page-user-password #content .inner-content > * #edit-profile-adherent-field-service label, @@ -14449,27 +14342,27 @@ a:hover { .page-toboggan #content .inner-content > * #edit-profile-adherent-field-naf label, .page-toboggan #content .inner-content > * #edit-profile-adherent-field-siret label, .page-toboggan #content .inner-content > * .form-item-profile-adherent-field-adresse-und-0-locality label { min-width: auto; } -/* line 1781, ../scss/styles.scss */ +/* line 1782, ../scss/styles.scss */ .page-user #content .inner-content > * #edit-profile-adherent-field-siret input, .page-user-edit #content .inner-content > * #edit-profile-adherent-field-siret input, .page-user-password #content .inner-content > * #edit-profile-adherent-field-siret input, .page-user-reset #content .inner-content > * #edit-profile-adherent-field-siret input, .page-toboggan #content .inner-content > * #edit-profile-adherent-field-siret input { width: 8em; } -/* line 1782, ../scss/styles.scss */ +/* line 1783, ../scss/styles.scss */ .page-user #content .inner-content > * #edit-profile-adherent-field-naf input, .page-user-edit #content .inner-content > * #edit-profile-adherent-field-naf input, .page-user-password #content .inner-content > * #edit-profile-adherent-field-naf input, .page-user-reset #content .inner-content > * #edit-profile-adherent-field-naf input, .page-toboggan #content .inner-content > * #edit-profile-adherent-field-naf input { width: 13em; } -/* line 1784, ../scss/styles.scss */ +/* line 1785, ../scss/styles.scss */ .page-user #content .inner-content > * #edit-profile-adherent-field-organization, .page-user-edit #content .inner-content > * #edit-profile-adherent-field-organization, .page-user-password #content .inner-content > * #edit-profile-adherent-field-organization, .page-user-reset #content .inner-content > * #edit-profile-adherent-field-organization, .page-toboggan #content .inner-content > * #edit-profile-adherent-field-organization { margin: 2em 0 0 0; } -/* line 1784, ../scss/styles.scss */ +/* line 1785, ../scss/styles.scss */ .page-user #content .inner-content > * #edit-profile-adherent-field-organization input, .page-user-edit #content .inner-content > * #edit-profile-adherent-field-organization input, .page-user-password #content .inner-content > * #edit-profile-adherent-field-organization input, .page-user-reset #content .inner-content > * #edit-profile-adherent-field-organization input, .page-toboggan #content .inner-content > * #edit-profile-adherent-field-organization input { width: 35em; } -/* line 1786, ../scss/styles.scss */ +/* line 1787, ../scss/styles.scss */ .page-user #content .inner-content > * #edit-profile-adherent-field-employee input, .page-user-edit #content .inner-content > * #edit-profile-adherent-field-employee input, .page-user-password #content .inner-content > * #edit-profile-adherent-field-employee input, .page-user-reset #content .inner-content > * #edit-profile-adherent-field-employee input, .page-toboggan #content .inner-content > * #edit-profile-adherent-field-employee input { width: 4em; } -/* line 1790, ../scss/styles.scss */ +/* line 1791, ../scss/styles.scss */ .page-user #content .inner-content > * #edit-profile-adherent-field-private-phone .form-phone-number, .page-user-edit #content .inner-content > * #edit-profile-adherent-field-private-phone .form-phone-number, .page-user-password #content .inner-content > * #edit-profile-adherent-field-private-phone .form-phone-number, .page-user-reset #content .inner-content > * #edit-profile-adherent-field-private-phone .form-phone-number, .page-toboggan #content .inner-content > * #edit-profile-adherent-field-private-phone .form-phone-number { display: moz-inline-stack; display: inline-block; @@ -14478,20 +14371,20 @@ a:hover { *display: inline; vertical-align: middle; } -/* line 1797, ../scss/styles.scss */ +/* line 1798, ../scss/styles.scss */ .page-user #content .inner-content > * #edit-profile-adherent-field-adresse .street-block input, .page-user-edit #content .inner-content > * #edit-profile-adherent-field-adresse .street-block input, .page-user-password #content .inner-content > * #edit-profile-adherent-field-adresse .street-block input, .page-user-reset #content .inner-content > * #edit-profile-adherent-field-adresse .street-block input, .page-toboggan #content .inner-content > * #edit-profile-adherent-field-adresse .street-block input { width: 35em; } -/* line 1800, ../scss/styles.scss */ +/* line 1801, ../scss/styles.scss */ .page-user #content .inner-content > * #edit-profile-adherent-field-adresse .locality-block .form-item, .page-user-edit #content .inner-content > * #edit-profile-adherent-field-adresse .locality-block .form-item, .page-user-password #content .inner-content > * #edit-profile-adherent-field-adresse .locality-block .form-item, .page-user-reset #content .inner-content > * #edit-profile-adherent-field-adresse .locality-block .form-item, .page-toboggan #content .inner-content > * #edit-profile-adherent-field-adresse .locality-block .form-item { width: auto; margin-right: 1em; } -/* line 1804, ../scss/styles.scss */ +/* line 1805, ../scss/styles.scss */ .page-user #content .inner-content > * #edit-profile-adherent-field-user-website, .page-user-edit #content .inner-content > * #edit-profile-adherent-field-user-website, .page-user-password #content .inner-content > * #edit-profile-adherent-field-user-website, .page-user-reset #content .inner-content > * #edit-profile-adherent-field-user-website, .page-toboggan #content .inner-content > * #edit-profile-adherent-field-user-website { margin: 2em 0 0 0; } -/* line 1806, ../scss/styles.scss */ +/* line 1807, ../scss/styles.scss */ .page-user #content .inner-content > * #edit-profile-adherent-field-user-website .form-item > *, .page-user-edit #content .inner-content > * #edit-profile-adherent-field-user-website .form-item > *, .page-user-password #content .inner-content > * #edit-profile-adherent-field-user-website .form-item > *, .page-user-reset #content .inner-content > * #edit-profile-adherent-field-user-website .form-item > *, .page-toboggan #content .inner-content > * #edit-profile-adherent-field-user-website .form-item > * { display: moz-inline-stack; display: inline-block; @@ -14500,25 +14393,25 @@ a:hover { *display: inline; vertical-align: middle; } -/* line 1807, ../scss/styles.scss */ +/* line 1808, ../scss/styles.scss */ .page-user #content .inner-content > * #edit-profile-adherent-field-user-website input, .page-user-edit #content .inner-content > * #edit-profile-adherent-field-user-website input, .page-user-password #content .inner-content > * #edit-profile-adherent-field-user-website input, .page-user-reset #content .inner-content > * #edit-profile-adherent-field-user-website input, .page-toboggan #content .inner-content > * #edit-profile-adherent-field-user-website input { width: 35em; } -/* line 1811, ../scss/styles.scss */ +/* line 1812, ../scss/styles.scss */ .page-user #content .inner-content > *.profile h3, .page-user-edit #content .inner-content > *.profile h3, .page-user-password #content .inner-content > *.profile h3, .page-user-reset #content .inner-content > *.profile h3, .page-toboggan #content .inner-content > *.profile h3 { border: 0 solid transparent; } -/* line 1812, ../scss/styles.scss */ +/* line 1813, ../scss/styles.scss */ .page-user #content .inner-content > *.profile .field-label, .page-user-edit #content .inner-content > *.profile .field-label, .page-user-password #content .inner-content > *.profile .field-label, .page-user-reset #content .inner-content > *.profile .field-label, .page-toboggan #content .inner-content > *.profile .field-label { display: inline; } /** SIMPLENEWS */ -/* line 1820, ../scss/styles.scss */ +/* line 1821, ../scss/styles.scss */ body.node-type-simplenews #content .inner-content { text-align: center; } -/* line 1823, ../scss/styles.scss */ +/* line 1824, ../scss/styles.scss */ body.node-type-simplenews #content article.node.node-simplenews { display: moz-inline-stack; display: inline-block; @@ -14528,17 +14421,17 @@ body.node-type-simplenews #content article.node.node-simplenews { max-width: 600px; padding: 1em 0; } -/* line 1827, ../scss/styles.scss */ +/* line 1828, ../scss/styles.scss */ body.node-type-simplenews #content article.node.node-simplenews tbody { border-top: 0px; } /** PAGE CONTACT */ -/* line 1836, ../scss/styles.scss */ +/* line 1837, ../scss/styles.scss */ .page-node-11175 #main { background: #fff url("../img/bg-contact.gif") no-repeat bottom right; } -/* line 1840, ../scss/styles.scss */ +/* line 1841, ../scss/styles.scss */ .page-node-11175 #main .field-name-body p { display: moz-inline-stack; display: inline-block; @@ -14547,14 +14440,14 @@ body.node-type-simplenews #content article.node.node-simplenews tbody { *display: inline; margin: 15px; } -/* line 1842, ../scss/styles.scss */ +/* line 1843, ../scss/styles.scss */ .page-node-11175 #main .field-name-body p strong { font-size: 18px; } /** PRICING */ @media only screen and (min-width: 40.063em) { - /* line 1854, ../scss/styles.scss */ + /* line 1855, ../scss/styles.scss */ body.page-node-11187 .node-11187 .field-name-body div.column, body.page-node-11187 .node-11187 .field-name-body div.column-demi, body.page-node-11187 .node-11187 .field-name-body div.column-full, body.page-node-11187 .node-11187 .field-name-body div.column-auto { display: moz-inline-stack; display: inline-block; @@ -14563,52 +14456,52 @@ body.node-type-simplenews #content article.node.node-simplenews tbody { *display: inline; margin: 10px; } - /* line 1857, ../scss/styles.scss */ + /* line 1858, ../scss/styles.scss */ body.page-node-11187 .node-11187 .field-name-body div.column { width: 22.4%; } - /* line 1859, ../scss/styles.scss */ + /* line 1860, ../scss/styles.scss */ body.page-node-11187 .node-11187 .field-name-body div.column ul.list-text { min-height: 170px; } - /* line 1861, ../scss/styles.scss */ + /* line 1862, ../scss/styles.scss */ body.page-node-11187 .node-11187 .field-name-body div.column-demi { width: 46%; } - /* line 1863, ../scss/styles.scss */ + /* line 1864, ../scss/styles.scss */ body.page-node-11187 .node-11187 .field-name-body div.column-demi ul.list-text { min-height: 110px; } - /* line 1865, ../scss/styles.scss */ + /* line 1866, ../scss/styles.scss */ body.page-node-11187 .node-11187 .field-name-body div.column-full { width: 92%; } - /* line 1869, ../scss/styles.scss */ + /* line 1870, ../scss/styles.scss */ body.page-node-11187 .node-11187 .field-name-body div.column-auto { width: auto; max-width: 98%; } - /* line 1876, ../scss/styles.scss */ + /* line 1877, ../scss/styles.scss */ body.page-node-11187 #block-materio-user-user-register { width: 600px; margin: 0 auto; } } @media only screen and (max-width: 40em) { - /* line 1883, ../scss/styles.scss */ + /* line 1884, ../scss/styles.scss */ body.page-node-11187 #block-system-help { text-align: center; } } -/* line 1887, ../scss/styles.scss */ +/* line 1888, ../scss/styles.scss */ body.page-node-11187 .node-11187 .field-name-body { text-align: center; } -/* line 1889, ../scss/styles.scss */ +/* line 1890, ../scss/styles.scss */ body.page-node-11187 .node-11187 .field-name-body > * { text-align: left; } -/* line 1890, ../scss/styles.scss */ +/* line 1891, ../scss/styles.scss */ body.page-node-11187 .node-11187 .field-name-body div.column, body.page-node-11187 .node-11187 .field-name-body div.column-demi, body.page-node-11187 .node-11187 .field-name-body div.column-full, body.page-node-11187 .node-11187 .field-name-body div.column-auto { position: relative; border-radius: 5px; @@ -14616,28 +14509,28 @@ body.page-node-11187 .node-11187 .field-name-body div.column, body.page-node-111 box-shadow: 0 0 6px rgba(0, 0, 0, 0.5); overflow: hidden; } -/* line 1893, ../scss/styles.scss */ +/* line 1894, ../scss/styles.scss */ .ie8 body.page-node-11187 .node-11187 .field-name-body div.column, .ie8 body.page-node-11187 .node-11187 .field-name-body div.column-demi, .ie8 body.page-node-11187 .node-11187 .field-name-body div.column-full, .ie8 body.page-node-11187 .node-11187 .field-name-body div.column-auto { max-width: 500px; margin: auto; margin-bottom: 15px; border: 1px solid #C6C6C6; } -/* line 1896, ../scss/styles.scss */ +/* line 1897, ../scss/styles.scss */ body.page-node-11187 .node-11187 .field-name-body div.column > *, body.page-node-11187 .node-11187 .field-name-body div.column-demi > *, body.page-node-11187 .node-11187 .field-name-body div.column-full > *, body.page-node-11187 .node-11187 .field-name-body div.column-auto > * { padding: 0 10px; } -/* line 1897, ../scss/styles.scss */ +/* line 1898, ../scss/styles.scss */ body.page-node-11187 .node-11187 .field-name-body div.column img, body.page-node-11187 .node-11187 .field-name-body div.column-demi img, body.page-node-11187 .node-11187 .field-name-body div.column-full img, body.page-node-11187 .node-11187 .field-name-body div.column-auto img { float: left; padding: 0; } -/* line 1898, ../scss/styles.scss */ +/* line 1899, ../scss/styles.scss */ body.page-node-11187 .node-11187 .field-name-body div.column h2, body.page-node-11187 .node-11187 .field-name-body div.column-demi h2, body.page-node-11187 .node-11187 .field-name-body div.column-full h2, body.page-node-11187 .node-11187 .field-name-body div.column-auto h2 { text-align: left; margin: 5px 0 0; } -/* line 1899, ../scss/styles.scss */ +/* line 1900, ../scss/styles.scss */ body.page-node-11187 .node-11187 .field-name-body div.column .subtitle, body.page-node-11187 .node-11187 .field-name-body div.column-demi .subtitle, body.page-node-11187 .node-11187 .field-name-body div.column-full .subtitle, body.page-node-11187 .node-11187 .field-name-body div.column-auto .subtitle { padding: 0 0 0 1em; font-size: 18px; @@ -14645,22 +14538,22 @@ body.page-node-11187 .node-11187 .field-name-body div.column .subtitle, body.pag font-weight: bold; line-height: 1; } -/* line 1903, ../scss/styles.scss */ +/* line 1904, ../scss/styles.scss */ body.page-node-11187 .node-11187 .field-name-body div.column ul, body.page-node-11187 .node-11187 .field-name-body div.column-demi ul, body.page-node-11187 .node-11187 .field-name-body div.column-full ul, body.page-node-11187 .node-11187 .field-name-body div.column-auto ul { margin: 0; padding: 0 15px; } -/* line 1904, ../scss/styles.scss */ +/* line 1905, ../scss/styles.scss */ body.page-node-11187 .node-11187 .field-name-body div.column li, body.page-node-11187 .node-11187 .field-name-body div.column-demi li, body.page-node-11187 .node-11187 .field-name-body div.column-full li, body.page-node-11187 .node-11187 .field-name-body div.column-auto li { list-style: none; font-size: 12px; } -/* line 1906, ../scss/styles.scss */ +/* line 1907, ../scss/styles.scss */ body.page-node-11187 .node-11187 .field-name-body div.column li:before, body.page-node-11187 .node-11187 .field-name-body div.column-demi li:before, body.page-node-11187 .node-11187 .field-name-body div.column-full li:before, body.page-node-11187 .node-11187 .field-name-body div.column-auto li:before { content: "+ "; font-weight: 900; } -/* line 1911, ../scss/styles.scss */ +/* line 1912, ../scss/styles.scss */ body.page-node-11187 .node-11187 .field-name-body div.column .get-link, body.page-node-11187 .node-11187 .field-name-body div.column-demi .get-link, body.page-node-11187 .node-11187 .field-name-body div.column-full .get-link, body.page-node-11187 .node-11187 .field-name-body div.column-auto .get-link { margin: 0; border-radius: 0 0 5px 5px 0 0 0; @@ -14668,7 +14561,7 @@ body.page-node-11187 .node-11187 .field-name-body div.column .get-link, body.pag border: 1px solid #fff; min-height: 92px; } -/* line 1913, ../scss/styles.scss */ +/* line 1914, ../scss/styles.scss */ body.page-node-11187 .node-11187 .field-name-body div.column .get-link a, body.page-node-11187 .node-11187 .field-name-body div.column-demi .get-link a, body.page-node-11187 .node-11187 .field-name-body div.column-full .get-link a, body.page-node-11187 .node-11187 .field-name-body div.column-auto .get-link a { display: block; width: 100%; @@ -14676,32 +14569,36 @@ body.page-node-11187 .node-11187 .field-name-body div.column .get-link a, body.p color: #1A1A1A; text-decoration: none; } -/* line 1915, ../scss/styles.scss */ +/* line 1916, ../scss/styles.scss */ body.page-node-11187 .node-11187 .field-name-body div.column.gratos .get-link, body.page-node-11187 .node-11187 .field-name-body div.column-demi.gratos .get-link, body.page-node-11187 .node-11187 .field-name-body div.column-full.gratos .get-link, body.page-node-11187 .node-11187 .field-name-body div.column-auto.gratos .get-link { background-color: #4BA13D; } -/* line 1916, ../scss/styles.scss */ +/* line 1917, ../scss/styles.scss */ body.page-node-11187 .node-11187 .field-name-body div.column.flocon .get-link, body.page-node-11187 .node-11187 .field-name-body div.column-demi.flocon .get-link, body.page-node-11187 .node-11187 .field-name-body div.column-full.flocon .get-link, body.page-node-11187 .node-11187 .field-name-body div.column-auto.flocon .get-link { background-color: #69CDCF; } -/* line 1917, ../scss/styles.scss */ +/* line 1918, ../scss/styles.scss */ body.page-node-11187 .node-11187 .field-name-body div.column.etoile .get-link, body.page-node-11187 .node-11187 .field-name-body div.column-demi.etoile .get-link, body.page-node-11187 .node-11187 .field-name-body div.column-full.etoile .get-link, body.page-node-11187 .node-11187 .field-name-body div.column-auto.etoile .get-link { background-color: #D476AE; } -/* line 1918, ../scss/styles.scss */ +/* line 1919, ../scss/styles.scss */ body.page-node-11187 .node-11187 .field-name-body div.column.cinqetoiles .get-link, body.page-node-11187 .node-11187 .field-name-body div.column-demi.cinqetoiles .get-link, body.page-node-11187 .node-11187 .field-name-body div.column-full.cinqetoiles .get-link, body.page-node-11187 .node-11187 .field-name-body div.column-auto.cinqetoiles .get-link { background-color: #E6DE1C; } -/* line 1924, ../scss/styles.scss */ +/* line 1920, ../scss/styles.scss */ +body.page-node-11187 .node-11187 .field-name-body div.column.ecole-de-neige, body.page-node-11187 .node-11187 .field-name-body div.column-demi.ecole-de-neige, body.page-node-11187 .node-11187 .field-name-body div.column-full.ecole-de-neige, body.page-node-11187 .node-11187 .field-name-body div.column-auto.ecole-de-neige { + float: none; +} +/* line 1926, ../scss/styles.scss */ body.page-node-11187 .node-11187 .field-name-body div.column h2 { padding: 10px 0 0; font-size: 24px; } -/* line 1925, ../scss/styles.scss */ +/* line 1927, ../scss/styles.scss */ body.page-node-11187 .node-11187 .field-name-body div.column .subtitle { min-height: 3em; } -/* line 1926, ../scss/styles.scss */ +/* line 1928, ../scss/styles.scss */ body.page-node-11187 .node-11187 .field-name-body div.column .get-link { padding: 0; font-size: 24px; @@ -14713,7 +14610,7 @@ body.page-node-11187 .node-11187 .field-name-body div.column .get-link { -webkit-transition: text-shadow 0.3s ease-out; transition: text-shadow 0.3s ease-out; } -/* line 1930, ../scss/styles.scss */ +/* line 1932, ../scss/styles.scss */ body.page-node-11187 .node-11187 .field-name-body div.column .get-link span { font-size: 20px; } @@ -14727,71 +14624,71 @@ body.page-node-11187 .node-11187 .field-name-body div.column .get-link:active { transition: text-shadow 0s ease-out; text-shadow: 0 0 2px rgba(255, 255, 255, 0.2); } -/* line 1935, ../scss/styles.scss */ +/* line 1937, ../scss/styles.scss */ body.page-node-11187 .node-11187 .field-name-body div.column-demi h2 { padding: 10px 0 0; font-size: 24px; top: 0; } -/* line 1936, ../scss/styles.scss */ +/* line 1938, ../scss/styles.scss */ body.page-node-11187 .node-11187 .field-name-body div.column-demi .subtitle { min-height: 2em; } -/* line 1937, ../scss/styles.scss */ +/* line 1939, ../scss/styles.scss */ body.page-node-11187 .node-11187 .field-name-body div.column-demi ul { font-size: 14px; min-height: 120px; } -/* line 1938, ../scss/styles.scss */ +/* line 1940, ../scss/styles.scss */ body.page-node-11187 .node-11187 .field-name-body div.column-demi .get-link { font-size: 14px; text-align: left; padding: 0 1em; background-color: #ddd; } -/* line 1947, ../scss/styles.scss */ +/* line 1949, ../scss/styles.scss */ body.page-node-11187.logged-in .column.gratos .get-link { cursor: auto !important; } -/* line 1949, ../scss/styles.scss */ +/* line 1951, ../scss/styles.scss */ body.page-node-11187.logged-in .column.gratos .get-link a { display: none !important; } -/* line 1952, ../scss/styles.scss */ +/* line 1954, ../scss/styles.scss */ body.page-node-11187.logged-in.role-6 .column.flocon .get-link { cursor: auto !important; } -/* line 1954, ../scss/styles.scss */ +/* line 1956, ../scss/styles.scss */ body.page-node-11187.logged-in.role-6 .column.flocon .get-link a { display: none !important; } /** ADHESION FORM */ -/* line 1962, ../scss/styles.scss */ +/* line 1964, ../scss/styles.scss */ .node-11186 nav ul.links a.language-link { display: none; } -/* line 1965, ../scss/styles.scss */ +/* line 1967, ../scss/styles.scss */ #webform-client-form-11186 { background-color: #e6e6e6; border-radius: 10px; background-clip: padding-box; } @media only screen and (min-width: 40.063em) { - /* line 1965, ../scss/styles.scss */ + /* line 1967, ../scss/styles.scss */ #webform-client-form-11186 { padding: 10px 30px; } - /* line 1968, ../scss/styles.scss */ + /* line 1970, ../scss/styles.scss */ #webform-client-form-11186 #webform-component-column-left--membership-options { margin: 10px 0; } - /* line 1970, ../scss/styles.scss */ + /* line 1972, ../scss/styles.scss */ #webform-client-form-11186 #webform-component-column-left--membership-options label { width: auto; } - /* line 1972, ../scss/styles.scss */ + /* line 1974, ../scss/styles.scss */ #webform-client-form-11186 fieldset { border-radius: 5px; background-clip: padding-box; @@ -14799,22 +14696,22 @@ body.page-node-11187.logged-in.role-6 .column.flocon .get-link a { border-bottom: 1px solid #cccccc; padding: 10px; } - /* line 1974, ../scss/styles.scss */ + /* line 1976, ../scss/styles.scss */ #webform-client-form-11186 fieldset fieldset { border: 0 solid #ddd; padding: 0; } - /* line 1976, ../scss/styles.scss */ + /* line 1978, ../scss/styles.scss */ #webform-client-form-11186 legend { margin: 0; font-size: 18px; font-weight: 700; } - /* line 1977, ../scss/styles.scss */ + /* line 1979, ../scss/styles.scss */ #webform-client-form-11186 .form-item { margin: 0 20px 0 0; } - /* line 1978, ../scss/styles.scss */ + /* line 1980, ../scss/styles.scss */ #webform-client-form-11186 label { font-size: 12px; width: 10em; @@ -14827,7 +14724,7 @@ body.page-node-11187.logged-in.role-6 .column.flocon .get-link a { margin-right: 1em; border-bottom: 1px solid #cccccc; } - /* line 1979, ../scss/styles.scss */ + /* line 1981, ../scss/styles.scss */ #webform-client-form-11186 .description { font-size: 10px; width: 25em; @@ -14840,40 +14737,40 @@ body.page-node-11187.logged-in.role-6 .column.flocon .get-link a { margin-left: 1em; color: #7f7f7f; } - /* line 1980, ../scss/styles.scss */ + /* line 1982, ../scss/styles.scss */ #webform-client-form-11186 input.form-text { width: 13em; } } @media only screen and (min-width: 40.063em) and (max-width: 64em) { - /* line 1965, ../scss/styles.scss */ + /* line 1967, ../scss/styles.scss */ #webform-client-form-11186 { padding: 10px; } - /* line 1985, ../scss/styles.scss */ + /* line 1987, ../scss/styles.scss */ #webform-client-form-11186 #webform-component-column-left--membership-options { margin: 0 0 10px 0; } - /* line 1987, ../scss/styles.scss */ + /* line 1989, ../scss/styles.scss */ #webform-client-form-11186 #webform-component-column-left--membership-options .form-item { width: 100%; } - /* line 1988, ../scss/styles.scss */ + /* line 1990, ../scss/styles.scss */ #webform-client-form-11186 #webform-component-column-left--membership-options label { width: 75%; } - /* line 1990, ../scss/styles.scss */ + /* line 1992, ../scss/styles.scss */ #webform-client-form-11186 legend { margin: 0; font-size: 16px; font-weight: 700; } - /* line 1991, ../scss/styles.scss */ + /* line 1993, ../scss/styles.scss */ #webform-client-form-11186 .form-item { margin: 0; float: none; } - /* line 1992, ../scss/styles.scss */ + /* line 1994, ../scss/styles.scss */ #webform-client-form-11186 label { font-size: 12px; width: 30%; @@ -14885,16 +14782,16 @@ body.page-node-11187.logged-in.role-6 .column.flocon .get-link a { vertical-align: middle; margin-right: 0.5em; } - /* line 1993, ../scss/styles.scss */ + /* line 1995, ../scss/styles.scss */ #webform-client-form-11186 input.form-text, #webform-client-form-11186 select.form-select { width: 60%; } - /* line 1994, ../scss/styles.scss */ + /* line 1996, ../scss/styles.scss */ #webform-client-form-11186 #webform-component-infos { font-size: 14px; } } -/* line 1999, ../scss/styles.scss */ +/* line 2001, ../scss/styles.scss */ #webform-client-form-11186 .fieldset-wrapper > .form-item { display: moz-inline-stack; display: inline-block; @@ -14902,7 +14799,7 @@ body.page-node-11187.logged-in.role-6 .column.flocon .get-link a { zoom: 1; *display: inline; } -/* line 2001, ../scss/styles.scss */ +/* line 2003, ../scss/styles.scss */ #webform-client-form-11186 #webform-component-column-left { display: moz-inline-stack; display: inline-block; @@ -14912,7 +14809,7 @@ body.page-node-11187.logged-in.role-6 .column.flocon .get-link a { width: 25%; border: none; } -/* line 2002, ../scss/styles.scss */ +/* line 2004, ../scss/styles.scss */ #webform-client-form-11186 #webform-component-column-right { display: moz-inline-stack; display: inline-block; @@ -14921,7 +14818,7 @@ body.page-node-11187.logged-in.role-6 .column.flocon .get-link a { *display: inline; min-width: 70%; } -/* line 2006, ../scss/styles.scss */ +/* line 2008, ../scss/styles.scss */ #webform-client-form-11186 #webform-component-column-left--membership-options .form-type-radio { border: 1px solid #ddd; border-radius: 5px; @@ -14930,7 +14827,7 @@ body.page-node-11187.logged-in.role-6 .column.flocon .get-link a { margin: 5px 0; background-color: #fff; } -/* line 2008, ../scss/styles.scss */ +/* line 2010, ../scss/styles.scss */ #webform-client-form-11186 #webform-component-column-left--membership-options .form-type-radio input { display: moz-inline-stack; display: inline-block; @@ -14940,7 +14837,7 @@ body.page-node-11187.logged-in.role-6 .column.flocon .get-link a { vertical-align: middle; margin: 0px 5px; } -/* line 2009, ../scss/styles.scss */ +/* line 2011, ../scss/styles.scss */ #webform-client-form-11186 #webform-component-column-left--membership-options .form-type-radio label { font-size: 20px; font-weight: 700; @@ -14952,41 +14849,41 @@ body.page-node-11187.logged-in.role-6 .column.flocon .get-link a { vertical-align: middle; margin: 0; } -/* line 2011, ../scss/styles.scss */ +/* line 2013, ../scss/styles.scss */ #webform-client-form-11186 #webform-component-column-left--membership-options .form-type-radio:hover { box-shadow: 0 0 5px rgba(0, 0, 0, 0.2); } -/* line 2012, ../scss/styles.scss */ +/* line 2014, ../scss/styles.scss */ #webform-client-form-11186 #webform-component-column-left--membership-options .form-type-radio.form-item-submitted-column-left-membership-options:nth-child(1) { background-color: #69CDCF; } -/* line 2013, ../scss/styles.scss */ +/* line 2015, ../scss/styles.scss */ #webform-client-form-11186 #webform-component-column-left--membership-options .form-type-radio.form-item-submitted-column-left-membership-options:nth-child(2) { background-color: #D476AE; } -/* line 2014, ../scss/styles.scss */ +/* line 2016, ../scss/styles.scss */ #webform-client-form-11186 #webform-component-column-left--membership-options .form-type-radio.form-item-submitted-column-left-membership-options:nth-child(3) { background-color: #E6DE1C; } -/* line 2016, ../scss/styles.scss */ +/* line 2018, ../scss/styles.scss */ #webform-client-form-11186 #webform-component-column-left--membership-options .form-type-radio.form-item-submitted-column-left-membership-options:not(.selected) { opacity: 0.4; } -/* line 2019, ../scss/styles.scss */ +/* line 2021, ../scss/styles.scss */ #webform-client-form-11186 #webform-component-column-left--membership-options > label { width: 200px; font-size: 18px; font-weight: 700; } -/* line 2020, ../scss/styles.scss */ +/* line 2022, ../scss/styles.scss */ #webform-client-form-11186 #webform-component-column-left--membership-options label { border: 0; } -/* line 2023, ../scss/styles.scss */ +/* line 2025, ../scss/styles.scss */ #webform-client-form-11186 #webform-component-column-right--me--my-account-email { display: block; } -/* line 2028, ../scss/styles.scss */ +/* line 2030, ../scss/styles.scss */ #webform-client-form-11186 #webform-component-column-right--company--administrative-e-mail .description { display: moz-inline-stack; display: inline-block; @@ -14994,11 +14891,11 @@ body.page-node-11187.logged-in.role-6 .column.flocon .get-link a { zoom: 1; *display: inline; } -/* line 2031, ../scss/styles.scss */ +/* line 2033, ../scss/styles.scss */ #webform-client-form-11186 #addressfield-wrapper { margin-top: 1em; } -/* line 2032, ../scss/styles.scss */ +/* line 2034, ../scss/styles.scss */ #webform-client-form-11186 .street-block .form-item { display: moz-inline-stack; display: inline-block; @@ -15006,12 +14903,12 @@ body.page-node-11187.logged-in.role-6 .column.flocon .get-link a { zoom: 1; *display: inline; } -/* line 2034, ../scss/styles.scss */ +/* line 2036, ../scss/styles.scss */ #webform-client-form-11186 #webform-component-column-right--collaborators { margin: 20px 0; overflow: hidden; } -/* line 2036, ../scss/styles.scss */ +/* line 2038, ../scss/styles.scss */ #webform-client-form-11186 #webform-component-column-right--collaborators fieldset { display: moz-inline-stack; display: inline-block; @@ -15020,23 +14917,23 @@ body.page-node-11187.logged-in.role-6 .column.flocon .get-link a { *display: inline; width: 33%; } -/* line 2037, ../scss/styles.scss */ +/* line 2039, ../scss/styles.scss */ #webform-client-form-11186 #webform-component-column-right--collaborators .form-item { display: block; } -/* line 2038, ../scss/styles.scss */ +/* line 2040, ../scss/styles.scss */ #webform-client-form-11186 #webform-component-column-right--collaborators label { width: 6em; } -/* line 2039, ../scss/styles.scss */ +/* line 2041, ../scss/styles.scss */ #webform-client-form-11186 #webform-component-column-right--collaborators input { width: 11em; } -/* line 2042, ../scss/styles.scss */ +/* line 2044, ../scss/styles.scss */ #webform-client-form-11186 #webform-component-infos { margin: 20px 0; } -/* line 2044, ../scss/styles.scss */ +/* line 2046, ../scss/styles.scss */ #webform-client-form-11186 .form-actions { padding: 0; margin: 0; @@ -15044,7 +14941,7 @@ body.page-node-11187.logged-in.role-6 .column.flocon .get-link a { background-color: transparent; text-align: left; } -/* line 2049, ../scss/styles.scss */ +/* line 2051, ../scss/styles.scss */ #webform-client-form-11186 .form-actions .form-submit { border: 2px solid #69CDCF; background-color: #69CDCF; @@ -15070,7 +14967,7 @@ body.page-node-11187.logged-in.role-6 .column.flocon .get-link a { transition: text-shadow 0s ease-out; text-shadow: 0 0 2px rgba(0, 0, 0, 0.2); } -/* line 2059, ../scss/styles.scss */ +/* line 2061, ../scss/styles.scss */ #webform-client-form-11186 #webform-component-column-right--news-letters > label { margin: 0; font-size: 18px; @@ -15078,7 +14975,7 @@ body.page-node-11187.logged-in.role-6 .column.flocon .get-link a { border: none; line-height: 40px; } -/* line 2060, ../scss/styles.scss */ +/* line 2062, ../scss/styles.scss */ #webform-client-form-11186 #webform-component-column-right--news-letters .form-item { display: moz-inline-stack; display: inline-block; @@ -15086,63 +14983,63 @@ body.page-node-11187.logged-in.role-6 .column.flocon .get-link a { zoom: 1; *display: inline; } -/* line 2062, ../scss/styles.scss */ +/* line 2064, ../scss/styles.scss */ #webform-client-form-11186 #webform-component-column-right--news-letters .form-item label { width: auto; } -/* line 2063, ../scss/styles.scss */ +/* line 2065, ../scss/styles.scss */ #webform-client-form-11186 #webform-component-column-right--news-letters .form-item input, #webform-client-form-11186 #webform-component-column-right--news-letters .form-item label { margin: 0; } -/* line 2067, ../scss/styles.scss */ +/* line 2069, ../scss/styles.scss */ #webform-client-form-11186 #edit-submitted-terms-of-services { margin-bottom: 0.5em; } -/* line 2069, ../scss/styles.scss */ +/* line 2071, ../scss/styles.scss */ #webform-client-form-11186 #edit-submitted-terms-of-services input, #webform-client-form-11186 #edit-submitted-terms-of-services label { margin: 0 0.3em 0 0; } -/* line 2070, ../scss/styles.scss */ +/* line 2072, ../scss/styles.scss */ #webform-client-form-11186 #edit-submitted-terms-of-services label { width: auto; } /** UC CART VIEW FORM */ -/* line 2075, ../scss/styles.scss */ +/* line 2077, ../scss/styles.scss */ #uc-cart-view-form { background-color: #e6e6e6; padding: 10px, 30px; display: inline-block; } -/* line 2081, ../scss/styles.scss */ +/* line 2083, ../scss/styles.scss */ #uc-cart-view-form table { width: auto; display: table; background-color: #fff; } -/* line 2085, ../scss/styles.scss */ +/* line 2087, ../scss/styles.scss */ #uc-cart-view-form table thead th { border-bottom: none; padding: 1em; } -/* line 2086, ../scss/styles.scss */ +/* line 2088, ../scss/styles.scss */ #uc-cart-view-form table tbody { border-top: none; } -/* line 2088, ../scss/styles.scss */ +/* line 2090, ../scss/styles.scss */ #uc-cart-view-form table tbody tr.even, #uc-cart-view-form table tbody tr.odd { background-color: #fff; border-bottom: none; } -/* line 2092, ../scss/styles.scss */ +/* line 2094, ../scss/styles.scss */ #uc-cart-view-form table tbody td { padding: 1em; } -/* line 2099, ../scss/styles.scss */ +/* line 2101, ../scss/styles.scss */ #uc-cart-view-form .form-type-uc-quantity input { width: 2em; } -/* line 2103, ../scss/styles.scss */ +/* line 2105, ../scss/styles.scss */ #uc-cart-view-form .form-actions { padding: 0; margin: 0; @@ -15152,11 +15049,11 @@ body.page-node-11187.logged-in.role-6 .column.flocon .get-link a { display: block; width: 100%; } -/* line 2110, ../scss/styles.scss */ +/* line 2112, ../scss/styles.scss */ #uc-cart-view-form .form-actions:before, #uc-cart-view-form .form-actions:after { display: block; } -/* line 2113, ../scss/styles.scss */ +/* line 2115, ../scss/styles.scss */ #uc-cart-view-form .form-actions .form-submit { font-size: 16px; font-weight: bold; @@ -15184,7 +15081,7 @@ body.page-node-11187.logged-in.role-6 .column.flocon .get-link a { transition: text-shadow 0s ease-out; text-shadow: 0 0 2px rgba(255, 255, 255, 0.2); } -/* line 2116, ../scss/styles.scss */ +/* line 2118, ../scss/styles.scss */ #uc-cart-view-form .form-actions .form-submit#edit-checkout--2 { font-size: 16px; font-weight: bold; @@ -15230,18 +15127,18 @@ body.page-node-11187.logged-in.role-6 .column.flocon .get-link a { } /** UC CHECKOUT FORM */ -/* line 2124, ../scss/styles.scss */ +/* line 2126, ../scss/styles.scss */ #uc-cart-checkout-form { display: inline-block; background-color: #e6e6e6; padding: 10px, 30px; } -/* line 2137, ../scss/styles.scss */ +/* line 2139, ../scss/styles.scss */ #uc-cart-checkout-form fieldset.form-row { padding-bottom: 20px; margin-bottom: 20px; } -/* line 2143, ../scss/styles.scss */ +/* line 2145, ../scss/styles.scss */ #uc-cart-checkout-form fieldset.form-column { display: moz-inline-stack; display: inline-block; @@ -15251,17 +15148,17 @@ body.page-node-11187.logged-in.role-6 .column.flocon .get-link a { max-width: 39%; margin: 15px 1em; } -/* line 2146, ../scss/styles.scss */ +/* line 2148, ../scss/styles.scss */ #uc-cart-checkout-form fieldset.form-column > .fieldset-wrapper > .form-wrapper { margin: 10px 0; } -/* line 2153, ../scss/styles.scss */ +/* line 2155, ../scss/styles.scss */ #uc-cart-checkout-form fieldset.form-column-right { border-left: 1px solid #ccc; margin-left: 2em; padding-left: 2em; } -/* line 2159, ../scss/styles.scss */ +/* line 2161, ../scss/styles.scss */ #uc-cart-checkout-form legend { margin: 0; font-size: 18px; @@ -15269,19 +15166,19 @@ body.page-node-11187.logged-in.role-6 .column.flocon .get-link a { border: none; line-height: 2; } -/* line 2160, ../scss/styles.scss */ +/* line 2162, ../scss/styles.scss */ #uc-cart-checkout-form .fieldset-description { font-size: 12px; } -/* line 2161, ../scss/styles.scss */ +/* line 2163, ../scss/styles.scss */ #uc-cart-checkout-form .fieldset-wrapper { font-size: 12px; } -/* line 2162, ../scss/styles.scss */ +/* line 2164, ../scss/styles.scss */ #uc-cart-checkout-form .form-item { margin: 0 20px 0 0; } -/* line 2164, ../scss/styles.scss */ +/* line 2166, ../scss/styles.scss */ #uc-cart-checkout-form .description { font-size: 10px; width: 25em; @@ -15294,7 +15191,7 @@ body.page-node-11187.logged-in.role-6 .column.flocon .get-link a { margin-left: 1em; color: #7f7f7f; } -/* line 2167, ../scss/styles.scss */ +/* line 2169, ../scss/styles.scss */ #uc-cart-checkout-form #cart-pane > .fieldset-wrapper { display: moz-inline-stack; display: inline-block; @@ -15306,57 +15203,57 @@ body.page-node-11187.logged-in.role-6 .column.flocon .get-link a { padding: 10px; background-color: #fff; } -/* line 2174, ../scss/styles.scss */ +/* line 2176, ../scss/styles.scss */ #uc-cart-checkout-form #cart-pane table { font-size: 14px; min-width: 20em; } -/* line 2130, ../scss/styles.scss */ +/* line 2132, ../scss/styles.scss */ #uc-cart-checkout-form #cart-pane table td.price { width: 4em; } -/* line 2178, ../scss/styles.scss */ +/* line 2180, ../scss/styles.scss */ #uc-cart-checkout-form #cart-pane tbody { border: none; } -/* line 2179, ../scss/styles.scss */ +/* line 2181, ../scss/styles.scss */ #uc-cart-checkout-form #cart-pane tr { background-color: transparent; border: none; } -/* line 2180, ../scss/styles.scss */ +/* line 2182, ../scss/styles.scss */ #uc-cart-checkout-form #cart-pane td { padding: 0 5px; vertical-align: bottom; } -/* line 2183, ../scss/styles.scss */ +/* line 2185, ../scss/styles.scss */ #uc-cart-checkout-form #cart-pane td.products { width: auto; } -/* line 2184, ../scss/styles.scss */ +/* line 2186, ../scss/styles.scss */ #uc-cart-checkout-form #cart-pane td.products a { color: inherit; font-weight: 700; } -/* line 2186, ../scss/styles.scss */ +/* line 2188, ../scss/styles.scss */ #uc-cart-checkout-form #cart-pane td.products ul.product-description { margin: 0; font-size: 12px; } -/* line 2187, ../scss/styles.scss */ +/* line 2189, ../scss/styles.scss */ #uc-cart-checkout-form #cart-pane td.products li { list-style: none; } -/* line 2191, ../scss/styles.scss */ +/* line 2193, ../scss/styles.scss */ #uc-cart-checkout-form #cart-pane tr.subtotal td { font-size: 16px; font-weight: 700; } -/* line 2195, ../scss/styles.scss */ +/* line 2197, ../scss/styles.scss */ #uc-cart-checkout-form #customer-pane { width: 35em; } -/* line 2198, ../scss/styles.scss */ +/* line 2200, ../scss/styles.scss */ #uc-cart-checkout-form #billing-pane label { font-size: 12px; width: 8em; @@ -15369,22 +15266,22 @@ body.page-node-11187.logged-in.role-6 .column.flocon .get-link a { margin-right: 1em; border-bottom: 1px solid #cccccc; } -/* line 2199, ../scss/styles.scss */ +/* line 2201, ../scss/styles.scss */ #uc-cart-checkout-form #billing-pane input.form-text { width: 13em; } -/* line 2206, ../scss/styles.scss */ +/* line 2208, ../scss/styles.scss */ #uc-cart-checkout-form #payment-pane { float: right; } -/* line 2209, ../scss/styles.scss */ +/* line 2211, ../scss/styles.scss */ #uc-cart-checkout-form #payment-pane .fieldset-wrapper { background-color: #fff; border-radius: 5px; background-clip: padding-box; padding: 10px; } -/* line 2215, ../scss/styles.scss */ +/* line 2217, ../scss/styles.scss */ #uc-cart-checkout-form #payment-pane #line-items-div { float: none; border: none; @@ -15395,57 +15292,57 @@ body.page-node-11187.logged-in.role-6 .column.flocon .get-link a { *display: inline; margin: 10px 0 20px; } -/* line 2218, ../scss/styles.scss */ +/* line 2220, ../scss/styles.scss */ #uc-cart-checkout-form #payment-pane #line-items-div table { font-size: 14px; min-width: 20em; } -/* line 2130, ../scss/styles.scss */ +/* line 2132, ../scss/styles.scss */ #uc-cart-checkout-form #payment-pane #line-items-div table td.price { width: 4em; } -/* line 2219, ../scss/styles.scss */ +/* line 2221, ../scss/styles.scss */ #uc-cart-checkout-form #payment-pane #line-items-div tbody { border: none; } -/* line 2220, ../scss/styles.scss */ +/* line 2222, ../scss/styles.scss */ #uc-cart-checkout-form #payment-pane #line-items-div td { padding: 0 5px; } -/* line 2224, ../scss/styles.scss */ +/* line 2226, ../scss/styles.scss */ #uc-cart-checkout-form #payment-pane #line-items-div tr td { font-weight: 500; } -/* line 2226, ../scss/styles.scss */ +/* line 2228, ../scss/styles.scss */ #uc-cart-checkout-form #payment-pane #line-items-div tr.line-item-total td { font-size: 16px; font-weight: 700; text-align: right; } -/* line 2233, ../scss/styles.scss */ +/* line 2235, ../scss/styles.scss */ #uc-cart-checkout-form #payment-pane #edit-panes-payment-payment-method label { width: auto; border-bottom: none; } -/* line 2234, ../scss/styles.scss */ +/* line 2236, ../scss/styles.scss */ #uc-cart-checkout-form #payment-pane #edit-panes-payment-payment-method .form-item-panes-payment-payment-method { border: 1px solid #ddd; border-radius: 5px; margin: 0.5em; padding: 0.5em; } -/* line 2238, ../scss/styles.scss */ +/* line 2240, ../scss/styles.scss */ #uc-cart-checkout-form #payment-pane #edit-panes-payment-payment-method .form-item-panes-payment-payment-method label { font-weight: bold; } -/* line 2242, ../scss/styles.scss */ +/* line 2244, ../scss/styles.scss */ #uc-cart-checkout-form #payment-pane #payment-details { width: 25em; border-top: none; padding: 0; margin: 0; } -/* line 2248, ../scss/styles.scss */ +/* line 2250, ../scss/styles.scss */ #uc-cart-checkout-form .form-actions { padding: 0; margin: 0; @@ -15453,7 +15350,7 @@ body.page-node-11187.logged-in.role-6 .column.flocon .get-link a { background-color: transparent; text-align: right; } -/* line 2253, ../scss/styles.scss */ +/* line 2255, ../scss/styles.scss */ #uc-cart-checkout-form .form-actions .form-submit { font-size: 16px; font-weight: bold; @@ -15481,7 +15378,7 @@ body.page-node-11187.logged-in.role-6 .column.flocon .get-link a { transition: text-shadow 0s ease-out; text-shadow: 0 0 2px rgba(255, 255, 255, 0.2); } -/* line 2256, ../scss/styles.scss */ +/* line 2258, ../scss/styles.scss */ #uc-cart-checkout-form .form-actions .form-submit#edit-continue { font-size: 16px; font-weight: bold; @@ -15527,65 +15424,65 @@ body.page-node-11187.logged-in.role-6 .column.flocon .get-link a { } /* UC CART && UC CHECKOUT VALIDATION */ -/* line 2269, ../scss/styles.scss */ +/* line 2271, ../scss/styles.scss */ .page-cart-checkout-review #content > .inner-content { display: inline-block; padding: 1em; } -/* line 2277, ../scss/styles.scss */ +/* line 2279, ../scss/styles.scss */ .page-cart-checkout-review #edit-actions { margin: 0; padding: 0; } -/* line 2279, ../scss/styles.scss */ +/* line 2281, ../scss/styles.scss */ .page-cart-checkout-review #edit-actions:before, .page-cart-checkout-review #edit-actions:after { display: block; } -/* line 2283, ../scss/styles.scss */ +/* line 2285, ../scss/styles.scss */ .page-cart-checkout-review #review-instructions { width: 30em; padding: 1em 0; } -/* line 2289, ../scss/styles.scss */ +/* line 2291, ../scss/styles.scss */ .page-cart-checkout-review table.order-review-table { border: none; } -/* line 2291, ../scss/styles.scss */ +/* line 2293, ../scss/styles.scss */ .page-cart-checkout-review table.order-review-table .pane-title-row { border: none; background-color: transparent; text-align: left; font-size: 18px; } -/* line 2296, ../scss/styles.scss */ +/* line 2298, ../scss/styles.scss */ .page-cart-checkout-review table.order-review-table .pane-title-row td { padding: 1em 0 0 0; } -/* line 2299, ../scss/styles.scss */ +/* line 2301, ../scss/styles.scss */ .page-cart-checkout-review table.order-review-table table.cart-review tr.odd { background-color: transparent; border: none; } -/* line 2304, ../scss/styles.scss */ +/* line 2306, ../scss/styles.scss */ .page-cart-checkout-review table.order-review-table td.title-col { padding: 0; text-align: left; } -/* line 2308, ../scss/styles.scss */ +/* line 2310, ../scss/styles.scss */ .page-cart-checkout-review table.order-review-table td.data-col { padding: 0; width: 75%; } -/* line 2312, ../scss/styles.scss */ +/* line 2314, ../scss/styles.scss */ .page-cart-checkout-review table.order-review-table .review-button-row { border: none; background-color: transparent; } -/* line 2316, ../scss/styles.scss */ +/* line 2318, ../scss/styles.scss */ .page-cart-checkout-review table.order-review-table .review-button-row > td { padding: 3em 0 0 0; } -/* line 2320, ../scss/styles.scss */ +/* line 2322, ../scss/styles.scss */ .page-cart-checkout-review table.order-review-table .review-button-row form { margin: 0 0.5em 0 0; display: moz-inline-stack; @@ -15594,13 +15491,13 @@ body.page-node-11187.logged-in.role-6 .column.flocon .get-link a { zoom: 1; *display: inline; } -/* line 2327, ../scss/styles.scss */ +/* line 2329, ../scss/styles.scss */ .page-cart-checkout-review #edit-actions { border: 0px; background-color: transparent; text-align: right; } -/* line 2332, ../scss/styles.scss */ +/* line 2334, ../scss/styles.scss */ .page-cart-checkout-review input.form-submit { font-size: 16px; font-weight: bold; @@ -15628,7 +15525,7 @@ body.page-node-11187.logged-in.role-6 .column.flocon .get-link a { transition: text-shadow 0s ease-out; text-shadow: 0 0 2px rgba(255, 255, 255, 0.2); } -/* line 2335, ../scss/styles.scss */ +/* line 2337, ../scss/styles.scss */ .page-cart-checkout-review input.form-submit#edit-submit { font-size: 16px; font-weight: bold; @@ -15674,7 +15571,7 @@ body.page-node-11187.logged-in.role-6 .column.flocon .get-link a { } /** WHO WE ARE */ -/* line 2345, ../scss/styles.scss */ +/* line 2347, ../scss/styles.scss */ #didactique-page .node-didactique { border-radius: 5px; background-clip: padding-box; @@ -15686,23 +15583,23 @@ body.page-node-11187.logged-in.role-6 .column.flocon .get-link a { margin: 1em auto; padding: 1em; } -/* line 2352, ../scss/styles.scss */ +/* line 2354, ../scss/styles.scss */ #didactique-page .node-didactique .field-name-field-emvideo { margin: 1em 0; } -/* line 2356, ../scss/styles.scss */ +/* line 2358, ../scss/styles.scss */ #didactique-page .node-didactique .field-name-title-field { font-size: 24px; font-weight: 900; font-style: italic; padding: 5px 0; } -/* line 2360, ../scss/styles.scss */ +/* line 2362, ../scss/styles.scss */ #didactique-page .node-didactique .field-name-field-visuel figure, #didactique-page .node-didactique .field-name-field-visuel img { max-width: 100%; } @media only screen and (min-width: 40.063em) { - /* line 2365, ../scss/styles.scss */ + /* line 2367, ../scss/styles.scss */ #didactique-page .side { display: moz-inline-stack; display: inline-block; @@ -15711,11 +15608,11 @@ body.page-node-11187.logged-in.role-6 .column.flocon .get-link a { *display: inline; vertical-align: top; } - /* line 2366, ../scss/styles.scss */ + /* line 2368, ../scss/styles.scss */ #didactique-page .group-sideleft { width: 60%; } - /* line 2367, ../scss/styles.scss */ + /* line 2369, ../scss/styles.scss */ #didactique-page .group-sideright { width: 39%; } @@ -15723,30 +15620,30 @@ body.page-node-11187.logged-in.role-6 .column.flocon .get-link a { /** DIDACTIQUE */ @media only screen and (max-width: 40em) { - /* line 2379, ../scss/styles.scss */ + /* line 2381, ../scss/styles.scss */ .page-whoweare #tool-bar #block-materio-page-title-materio-page-title { display: none; } } /** maintenance */ -/* line 2386, ../scss/styles.scss */ +/* line 2388, ../scss/styles.scss */ .maintenance-page #container, .maintenance-page #header { text-align: center; padding: 0; position: relative; } -/* line 2387, ../scss/styles.scss */ +/* line 2389, ../scss/styles.scss */ .maintenance-page #main { background-color: transparent; } -/* line 2388, ../scss/styles.scss */ +/* line 2390, ../scss/styles.scss */ .maintenance-page #header h1.site-name { font-size: 36px; margin: 0; padding-left: 0; } -/* line 2389, ../scss/styles.scss */ +/* line 2391, ../scss/styles.scss */ .maintenance-page h2.site-slogan { font-size: 16px; font-weight: 300; @@ -15755,69 +15652,69 @@ body.page-node-11187.logged-in.role-6 .column.flocon .get-link a { } /** FAQ */ -/* line 2393, ../scss/styles.scss */ +/* line 2395, ../scss/styles.scss */ .page-faq-page #main { background: #fff url("../img/bg-faq.png") no-repeat bottom right; } -/* line 2399, ../scss/styles.scss */ +/* line 2401, ../scss/styles.scss */ #content .faq-content .faq-description { font-size: 12px; padding-bottom: 2em; } -/* line 2403, ../scss/styles.scss */ +/* line 2405, ../scss/styles.scss */ #content .faq-content ul.faq-ul-questions-top { margin: 0; } -/* line 2405, ../scss/styles.scss */ +/* line 2407, ../scss/styles.scss */ #content .faq-content ul.faq-ul-questions-top li { list-style: none; } -/* line 2407, ../scss/styles.scss */ +/* line 2409, ../scss/styles.scss */ #content .faq-content ul.faq-ul-questions-top li a { font-size: 18px; font-weight: 500; } -/* line 2413, ../scss/styles.scss */ +/* line 2415, ../scss/styles.scss */ #content .faq-content h3.faq-header { font-size: 20px; font-weight: 700; line-height: 1.2; margin: 0; } -/* line 2416, ../scss/styles.scss */ +/* line 2418, ../scss/styles.scss */ #content .faq-content h3.faq-header a { color: #000; } -/* line 2419, ../scss/styles.scss */ +/* line 2421, ../scss/styles.scss */ #content .faq-content .faq-dl-hide-answer { padding: 0; } -/* line 2422, ../scss/styles.scss */ +/* line 2424, ../scss/styles.scss */ #content .faq-content .faq-category-group { padding-bottom: 1em; } -/* line 2425, ../scss/styles.scss */ +/* line 2427, ../scss/styles.scss */ #content .faq-content .faq-question-answer { padding: 0.3em 0 0 0.8em; } -/* line 2427, ../scss/styles.scss */ +/* line 2429, ../scss/styles.scss */ #content .faq-content .faq-question-answer .faq-question { font-size: 16px; padding: 0; font-weight: 500; } -/* line 2429, ../scss/styles.scss */ +/* line 2431, ../scss/styles.scss */ #content .faq-content .faq-question-answer .faq-question a { color: #000; } -/* line 2431, ../scss/styles.scss */ +/* line 2433, ../scss/styles.scss */ #content .faq-content .faq-question-answer .faq-answer { padding: 0; margin-bottom: 2em; font-size: 12px; } -/* line 2437, ../scss/styles.scss */ +/* line 2439, ../scss/styles.scss */ #content .faq-content .field-name-body img { max-width: 50%; height: auto; diff --git a/sites/all/themes/gui/materiobasetheme/fonts/icon/foundation-icons-custom.eot b/sites/all/themes/gui/materiobasetheme/fonts/icon/foundation-icons-custom.eot new file mode 100644 index 00000000..8efc9140 Binary files /dev/null and b/sites/all/themes/gui/materiobasetheme/fonts/icon/foundation-icons-custom.eot differ diff --git a/sites/all/themes/gui/materiobasetheme/fonts/icon/foundation-icons-custom.svg b/sites/all/themes/gui/materiobasetheme/fonts/icon/foundation-icons-custom.svg new file mode 100644 index 00000000..226d5227 --- /dev/null +++ b/sites/all/themes/gui/materiobasetheme/fonts/icon/foundation-icons-custom.svg @@ -0,0 +1,305 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/sites/all/themes/gui/materiobasetheme/fonts/icon/foundation-icons-custom.ttf b/sites/all/themes/gui/materiobasetheme/fonts/icon/foundation-icons-custom.ttf new file mode 100644 index 00000000..5287edea Binary files /dev/null and b/sites/all/themes/gui/materiobasetheme/fonts/icon/foundation-icons-custom.ttf differ diff --git a/sites/all/themes/gui/materiobasetheme/fonts/icon/foundation-icons-custom.woff b/sites/all/themes/gui/materiobasetheme/fonts/icon/foundation-icons-custom.woff new file mode 100644 index 00000000..d13c533a Binary files /dev/null and b/sites/all/themes/gui/materiobasetheme/fonts/icon/foundation-icons-custom.woff differ diff --git a/sites/all/themes/gui/materiobasetheme/fonts/icon/foundation-icons.css b/sites/all/themes/gui/materiobasetheme/fonts/icon/foundation-icons.css index f3ccdd03..da821488 100644 --- a/sites/all/themes/gui/materiobasetheme/fonts/icon/foundation-icons.css +++ b/sites/all/themes/gui/materiobasetheme/fonts/icon/foundation-icons.css @@ -15,6 +15,18 @@ font-style: normal; } +@font-face { + font-family: 'foundation-icons-ciconscustom'; + src: url('foundation-icons-custom.eot'); + src: url('foundation-icons-custom.eot?#iefix') format('embedded-opentype'), + url('foundation-icons-custom.woff') format('woff'), + url('foundation-icons-custom.ttf') format('truetype'), + url('foundation-icons-custom.svg#foundation-icons-ciconscustom') format('svg'); + font-weight: normal; + font-style: normal; + +} + .fi-address-book:before, .fi-alert:before, .fi-align-center:before, @@ -307,9 +319,36 @@ -webkit-font-smoothing: antialiased; display: inline-block; text-decoration: inherit; - font-size: 14px; + font-size: 16px; } +/* CUSTOM ICONS */ +.icon-materio-viewmode-cardsmall, +.icon-materio-viewmode-cardmedium, +.icon-materio-viewmode-cardbig, +.icon-materio-viewmode-cardfull, +.icon-materio-folder { + font-family: "foundation-icons-ciconscustom"; + font-style: normal; + font-weight: normal; + font-variant: normal; + text-transform: none; + line-height: 1; + -webkit-font-smoothing: antialiased; + display: inline-block; + text-decoration: inherit; + font-size: 25px; + color: #313131; +} + +.icon-materio-folder{ + color: #007BC2; + font-size: 20px; + +} + +/*FOUNDATION ICONS*/ + .fi-address-book:before { content: "\f100"; } .fi-alert:before { content: "\f101"; } .fi-align-center:before { content: "\f102"; } @@ -593,3 +632,14 @@ .fi-yen:before { content: "\f218"; } .fi-zoom-in:before { content: "\f219"; } .fi-zoom-out:before { content: "\f21a"; } + +/*CUSTOM ICONS*/ +.icon-materio-viewmode-cardsmall.active:before{ content: "\f21b"; } +.icon-materio-viewmode-cardmedium.active:before{ content: "\f21c"; } +.icon-materio-viewmode-cardbig.active:before{ content: "\f21d"; } +.icon-materio-viewmode-cardfull.active:before{ content: "\f21e"; } +.icon-materio-viewmode-cardsmall:before{ content: "\f21f"; } +.icon-materio-viewmode-cardmedium:before{ content: "\f220"; } +.icon-materio-viewmode-cardbig:before{ content: "\f221"; } +.icon-materio-viewmode-cardfull:before{ content: "\f222"; } +.icon-materio-folder:before{ content: "\f223"; } diff --git a/sites/all/themes/gui/materiobasetheme/js/libs/idangerous.swiper-1.9.1.min.js b/sites/all/themes/gui/materiobasetheme/js/libs/idangerous.swiper-1.9.1.min.js deleted file mode 100644 index 0168c61b..00000000 --- a/sites/all/themes/gui/materiobasetheme/js/libs/idangerous.swiper-1.9.1.min.js +++ /dev/null @@ -1,13 +0,0 @@ -/* - * Swiper 1.9.1 - Mobile Touch Slider - * http://www.idangero.us/sliders/swiper/ - * - * Copyright 2012-2013, Vladimir Kharlampidi - * The iDangero.us - * http://www.idangero.us/ - * - * Licensed under GPL & MIT - * - * Updated on: April 7, 2013 -*/ -var Swiper=function(f,b){function g(){var c=y-l;b.loop&&(c-=l);b.scrollContainer&&(c=p-l,0>c&&(c=0));b.slidesPerSlide>a.slides.length&&(c=0);return c}function j(c){a.allowLinks||c.preventDefault()}function s(c){if(a.isTouched||b.onlyExternal)return!1;a.isTouched=!0;u="touchstart"==c.type;if(!u||1==c.targetTouches.length){a.callPlugins("onTouchStartBegin");b.loop&&a.fixLoop();u||(c.preventDefault?c.preventDefault():c.returnValue=!1);var d=u?c.targetTouches[0].pageX:c.pageX||c.clientX;c=u?c.targetTouches[0].pageY:c.pageY||c.clientY;a.touches.startX=a.touches.currentX=d;a.touches.startY=a.touches.currentY=c;a.touches.start=a.touches.current=h?a.touches.startX:a.touches.startY;a.setTransition(0);a.positions.start=a.positions.current=h?a.getTranslate("x"):a.getTranslate("y");h?a.setTransform(a.positions.start,0,0):a.setTransform(0,a.positions.start,0);a.times.start=(new Date).getTime();w=void 0;if(b.onSlideClick||b.onSlideTouch){var e=a.container,f=e.getBoundingClientRect(),g=document.body,d=d-f.left+(e.clientLeft||g.clientLeft||0)-(window.pageXOffset||e.scrollLeft);c=c-f.top-(e.clientTop||g.clientTop||0)-(window.pageYOffset||e.scrollTop);d=h?d:c;c=-Math.round(a.positions.current/p);c=d=Math.floor(d/p)+c;b.loop&&(c=d-b.slidesPerSlide,0>c&&(c=a.slides.length+c-2*b.slidesPerSlide));a.clickedSlideIndex=c;a.clickedSlide=a.getSlide(d);b.onSlideTouch&&(b.onSlideTouch(a),a.callPlugins("onSlideTouch"))}0Math.abs(d-a.touches.startX)));"undefined"===typeof w&&!h&&(w=!!(w||Math.abs(e-a.touches.startY)c?l/2:a.positions.current*c;if(a.positions.current<-g()&&(!b.freeMode||b.freeModeFluid))b.loop?(c=1,d=a.positions.current,e=-g()-l):(d=(a.touches.current-a.touches.start)*b.ratio+(g()+a.positions.start),c=(l+d)/l,d=a.positions.current-d*(1-c)/2,e=-g()-l/2),a.positions.current=d=c?e:d}if(b.followFinger){b.moveStartThreshold?Math.abs(a.touches.current-a.touches.start)>b.moveStartThreshold||D?(D=!0,h?a.setTransform(a.positions.current,0,0):a.setTransform(0,a.positions.current,0)):a.positions.current=a.positions.start:h?a.setTransform(a.positions.current,0,0):a.setTransform(0,a.positions.current,0);b.freeMode&&a.updateActiveSlide(a.positions.current);b.onSlideClick&&a.clickedSlide&&(a.clickedSlide=!1);b.grabCursor&&(a.container.style.cursor="move",a.container.style.cursor="grabbing",a.container.style.cursor="-moz-grabbin",a.container.style.cursor="-webkit-grabbing");a.callPlugins("onTouchMoveEnd");if(b.onTouchMove)b.onTouchMove(a);return!1}}}}function r(){if(!b.onlyExternal&&a.isTouched){a.isTouched=!1;b.preventLinks&&setTimeout(function(){a.allowLinks=!0},10);b.grabCursor&&(a.container.style.cursor="move",a.container.style.cursor="grab",a.container.style.cursor="-moz-grab",a.container.style.cursor="-webkit-grab");b.onSlideClick&&a.clickedSlide&&(b.onSlideClick(a),a.callPlugins("onSlideClick"));!a.positions.current&&0!==a.positions.current&&(a.positions.current=a.positions.start);b.followFinger&&(h?a.setTransform(a.positions.current,0,0):a.setTransform(0,a.positions.current,0));a.times.end=(new Date).getTime();a.touches.diff=a.touches.current-a.touches.start;a.touches.abs=Math.abs(a.touches.diff);a.positions.diff=a.positions.current-a.positions.start;a.positions.abs=Math.abs(a.positions.diff);var c=a.positions.diff,d=a.positions.abs;5>d&&a.swipeReset();var e=y-l;b.scrollContainer&&(e=p-l);0a.times.end-a.times.start&&b.freeModeFluid&&(d=a.positions.current+2*a.touches.diff,d<-1*e&&(d=-e),0c?"toNext":"toPrev","toNext"==x&&300>=a.times.end-a.times.start&&(30>d||!b.shortSwipes?a.swipeReset():a.swipeNext(!0)),"toPrev"==x&&300>=a.times.end-a.times.start&&(30>d||!b.shortSwipes?a.swipeReset():a.swipePrev(!0)),e=p*b.slidesPerGroup,"toNext"==x&&300=0.5*e?a.swipeNext(!0):a.swipeReset()),"toPrev"==x&&300=0.5*e?a.swipePrev(!0):a.swipeReset()));if(b.onTouchEnd)b.onTouchEnd(a);a.callPlugins("onTouchEnd")}}function E(){a.callPlugins("onSlideChangeStart");if(b.onSlideChangeStart)b.onSlideChangeStart(a);b.onSlideChangeEnd&&a.transitionEnd(b.onSlideChangeEnd)}window.addEventListener||(window.Element||(Element=function(){}),Element.prototype.addEventListener=HTMLDocument.prototype.addEventListener=addEventListener=function(a,b){this.attachEvent("on"+a,b)},Element.prototype.removeEventListener=HTMLDocument.prototype.removeEventListener=removeEventListener=function(a,b){this.detachEvent("on"+a,b)});if(document.body.__defineGetter__&&HTMLElement){var q=HTMLElement.prototype;q.__defineGetter__&&q.__defineGetter__("outerHTML",function(){return(new XMLSerializer).serializeToString(this)})}window.getComputedStyle||(window.getComputedStyle=function(a){this.el=a;this.getPropertyValue=function(b){var e=/(\-([a-z]){1})/g;"float"==b&&(b="styleFloat");e.test(b)&&(b=b.replace(e,function(a,c,b){return b.toUpperCase()}));return a.currentStyle[b]?a.currentStyle[b]:null};return this});if(f.nodeType||document.querySelectorAll&&0!=document.querySelectorAll(f).length){var a=this;a.touches={};a.positions={current:0};a.id=(new Date).getTime();a.container=f.nodeType?f:document.querySelectorAll(f)[0];a.times={};a.isTouched=!1;a.realIndex=0;a.activeSlide=0;a.previousSlide=null;a.langDirection=window.getComputedStyle(a.container,null).getPropertyValue("direction");a.support={touch:a.isSupportTouch(),threeD:a.isSupport3D()};a.use3D=a.support.threeD;q={mode:"horizontal",ratio:1,speed:300,freeMode:!1,freeModeFluid:!1,slidesPerSlide:1,slidesPerGroup:1,simulateTouch:!0,followFinger:!0,shortSwipes:!0,moveStartThreshold:!1,autoPlay:!1,onlyExternal:!1,createPagination:!0,pagination:!1,resistance:!0,scrollContainer:!1,preventLinks:!0,initialSlide:0,keyboardControl:!1,mousewheelControl:!1,resizeEvent:"auto",useCSS3Transforms:!0,slideElement:"div",slideClass:"swiper-slide",wrapperClass:"swiper-wrapper",paginationClass:"swiper-pagination-switch",paginationActiveClass:"swiper-active-switch"};b=b||{};for(var m in q)m in b||(b[m]=q[m]);a.params=b;b.scrollContainer&&(b.freeMode=!0,b.freeModeFluid=!0);var z=!1;"auto"==b.slidesPerSlide&&(z=!0,b.slidesPerSlide=1);var n,h,p,k,y,x,w,l;for(m=a.container.childNodes.length-1;0<=m;m--)if(a.container.childNodes[m].className)for(var q=a.container.childNodes[m].className.split(" "),F=0;Fa.slides.length)){var c=document.querySelectorAll(b.pagination+" ."+b.paginationActiveClass);if(c){for(var d=0;d=c&&(g-=c);0>g&&(g=c+g);g
                                ';document.querySelectorAll(b.pagination)[0].innerHTML=c;a.updatePagination();a.callPlugins("onCreatePagination")}};a.createPagination();a.resizeEvent="auto"===b.resizeEvent?"onorientationchange"in window?"orientationchange":"resize":b.resizeEvent;a.resizeFix=function(){a.callPlugins("beforeResizeFix");a.init();if(b.scrollContainer){if((h?a.getTranslate("x"):a.getTranslate("y"))<-g()){var c=h?-g():0,d=h?0:-g();a.setTransition(0);a.setTransform(c,d,0)}}else a.swipeTo(a.activeSlide,0,!1);a.callPlugins("afterResizeFix")};b.disableAutoResize||window.addEventListener(a.resizeEvent,a.resizeFix,!1);var C;a.startAutoPlay=function(){b.autoPlay&&!b.loop?C=setInterval(function(){var b=a.realIndex+1;b==k&&(b=0);a.swipeTo(b)},b.autoPlay):b.autoPlay&&b.loop&&(C=setInterval(function(){a.fixLoop();a.swipeNext(!0)},b.autoPlay));a.callPlugins("onAutoPlayStart")};a.stopAutoPlay=function(){C&&clearInterval(C);a.callPlugins("onAutoPlayStop")};b.autoPlay&&a.startAutoPlay();a.ie10?(n.addEventListener(a.touchEvents.touchStart,s,!1),document.addEventListener(a.touchEvents.touchMove,v,!1),document.addEventListener(a.touchEvents.touchEnd,r,!1)):(a.support.touch&&(n.addEventListener("touchstart",s,!1),n.addEventListener("touchmove",v,!1),n.addEventListener("touchend",r,!1)),b.simulateTouch&&(n.addEventListener("mousedown",s,!1),document.addEventListener("mousemove",v,!1),document.addEventListener("mouseup",r,!1)));a.destroy=function(c){(!1===c?c:1)&&window.removeEventListener(a.resizeEvent,a.resizeFix,!1);a.ie10?(n.removeEventListener(a.touchEvents.touchStart,s,!1),document.removeEventListener(a.touchEvents.touchMove,v,!1),document.removeEventListener(a.touchEvents.touchEnd,r,!1)):(a.support.touch&&(n.removeEventListener("touchstart",s,!1),n.removeEventListener("touchmove",v,!1),n.removeEventListener("touchend",r,!1)),n.removeEventListener("mousedown",s,!1),document.removeEventListener("mousemove",v,!1),document.removeEventListener("mouseup",r,!1));b.keyboardControl&&document.removeEventListener("keydown",G,!1);b.mousewheelControl&&a._wheelEvent&&a.container.removeEventListener(a._wheelEvent,H,!1);b.autoPlay&&a.stopAutoPlay();a.callPlugins("onDestroy")};a.allowLinks=!0;if(b.preventLinks){t=a.container.querySelectorAll("a");for(m=0;mMath.abs(c.deltaY)?-c.deltaX:-c.deltaY);b.freeMode?(h?a.getTranslate("x"):a.getTranslate("y"),h?(d=a.getTranslate("x")+e,e=a.getTranslate("y"),0e?a.swipeNext():a.swipePrev();c.preventDefault();return!1};a._wheelEvent&&a.container.addEventListener(a._wheelEvent,H,!1)}b.grabCursor&&(a.container.style.cursor="move",a.container.style.cursor="grab",a.container.style.cursor="-moz-grab",a.container.style.cursor="-webkit-grab");var u=!1,D;a.swipeNext=function(c){!c&&b.loop&&a.fixLoop();!c&&b.autoPlay&&a.stopAutoPlay();a.callPlugins("onSwipeNext");c=h?a.getTranslate("x"):a.getTranslate("y");var d=p*b.slidesPerGroup,d=Math.floor(Math.abs(c)/Math.floor(d))*d+d;c=Math.abs(c);if(d!=y&&(!(c>=g())||b.loop))return d>g()&&!b.loop&&(d=g()),b.loop&&d>=g()+l&&(d=g()+l),h?a.setTransform(-d,0,0):a.setTransform(0,-d,0),a.setTransition(b.speed),a.updateActiveSlide(-d),E(),!0};a.swipePrev=function(c){!c&&b.loop&&a.fixLoop();!c&&b.autoPlay&&a.stopAutoPlay();a.callPlugins("onSwipePrev");c=h?a.getTranslate("x"):a.getTranslate("y");var d=p*b.slidesPerGroup;c=(Math.ceil(-c/d)-1)*d;0>c&&(c=0);h?a.setTransform(-c,0,0):a.setTransform(0,-c,0);a.setTransition(b.speed);a.updateActiveSlide(-c);E();return!0};a.swipeReset=function(){a.callPlugins("onSwipeReset");var c=h?a.getTranslate("x"):a.getTranslate("y"),d=p*b.slidesPerGroup,d=0>c?Math.round(c/d)*d:0,e=-g();b.scrollContainer&&(d=0>c?c:0,e=l-p);d<=e&&(d=e);b.scrollContainer&&l>p&&(d=0);"horizontal"==b.mode?a.setTransform(d,0,0):a.setTransform(0,d,0);a.setTransition(b.speed);a.updateActiveSlide(d);if(b.onSlideReset)b.onSlideReset(a);return!0};var I=!0;a.swipeTo=function(c,d,e){c=parseInt(c,10);a.callPlugins("onSwipeTo",{index:c,speed:d});if(!(c>k-1)&&(!(0>c)||b.loop))return e=!1===e?!1:e||!0,d=0===d?d:d||b.speed,b.loop&&(c+=b.slidesPerSlide),c>k-b.slidesPerSlide&&(c=k-b.slidesPerSlide),c=-c*p,I&&(b.loop&&0=k-2*b.slidesPerSlide&&(a.activeSlide=k-2*b.slidesPerSlide-a.activeSlide),0>a.activeSlide&&(a.activeSlide=k-2*b.slidesPerSlide+a.activeSlide)):a.activeSlide=a.realIndex;a.realIndex==k&&(a.realIndex=k-1);0>a.realIndex&&(a.realIndex=0);b.pagination&&a.updatePagination()};a.fixLoop=function(){if(a.realIndexk-2*b.slidesPerSlide&&(c=-k+a.realIndex+b.slidesPerSlide,a.swipeTo(c,0,!1))};b.loop&&a.swipeTo(0,0,!1)}};Swiper.prototype={plugins:{},transitionEnd:function(f,b){var g=this,j=g.wrapper,s=["webkitTransitionEnd","transitionend","oTransitionEnd","MSTransitionEnd","msTransitionEnd"];if(f)for(var v=function(){f(g);if(!b)for(var r=0;rf}(),ie10:window.navigator.msPointerEnabled};if(window.jQuery||window.Zepto)(function(f){f.fn.swiper=function(b){b=new Swiper(f(this)[0],b);f(this).data("swiper",b);return b}})(window.jQuery||window.Zepto); \ No newline at end of file diff --git a/sites/all/themes/gui/materiobasetheme/js/libs/idangerous.swiper.css b/sites/all/themes/gui/materiobasetheme/js/libs/idangerous.swiper.css deleted file mode 100644 index 1813e064..00000000 --- a/sites/all/themes/gui/materiobasetheme/js/libs/idangerous.swiper.css +++ /dev/null @@ -1,77 +0,0 @@ -/* - * Swiper - Mobile Touch Slider CSS - * http://www.idangero.us/sliders/swiper - * - * Vladimir Kharlampidi, The iDangero.us - * http://www.idangero.us/ - * - * Copyright 2012, Vladimir Kharlampidi - * The iDangero.us - * http://www.idangero.us - * - * Licensed under GPL & MIT - * -*/ - -/* Swiper Styles */ -.swiper-container { - margin:0 auto; - position:relative; - overflow:hidden; - -webkit-backface-visibility:hidden; - -moz-backface-visibility:hidden; - -ms-backface-visibility:hidden; - -o-backface-visibility:hidden; - backface-visibility:hidden; - /* Fix of Webkit flickering */ - z-index:1; -} -.swiper-wrapper { - position:relative; - width:100%; - -webkit-transition-property:-webkit-transform, left, top; - -webkit-transition-duration:0s; - -webkit-transform:translate3d(0px,0,0); - -webkit-transition-timing-function:ease; - - -moz-transition-property:-moz-transform, left, top; - -moz-transition-duration:0s; - -moz-transform:translate3d(0px,0,0); - -moz-transition-timing-function:ease; - - -o-transition-property:-o-transform, left, top; - -o-transition-duration:0s; - -o-transform:translate3d(0px,0,0); - -o-transition-timing-function:ease; - -o-transform:translate(0px,0px); - - -ms-transition-property:-ms-transform, left, top; - -ms-transition-duration:0s; - -ms-transform:translate3d(0px,0,0); - -ms-transition-timing-function:ease; - - transition-property:transform, left, top; - transition-duration:0s; - transform:translate3d(0px,0,0); - transition-timing-function:ease; - -} -.swiper-slide { - float: left; -} - -/* IE10 Windows Phone 8 Fixes */ -.swiper-wp8-horizontal { - -ms-touch-action: pan-y; -} -.swiper-wp8-vertical { - -ms-touch-action: pan-x; -} - -/* Specify Swiper's Size: */ -.swiper-container, .swiper-slide { - width: 500px; - height: 200px; -} - - diff --git a/sites/all/themes/gui/materiobasetheme/js/libs/jquery.history.js b/sites/all/themes/gui/materiobasetheme/js/libs/jquery.history.js deleted file mode 100644 index 8d4edcd2..00000000 --- a/sites/all/themes/gui/materiobasetheme/js/libs/jquery.history.js +++ /dev/null @@ -1 +0,0 @@ -window.JSON||(window.JSON={}),function(){function f(a){return a<10?"0"+a:a}function quote(a){return escapable.lastIndex=0,escapable.test(a)?'"'+a.replace(escapable,function(a){var b=meta[a];return typeof b=="string"?b:"\\u"+("0000"+a.charCodeAt(0).toString(16)).slice(-4)})+'"':'"'+a+'"'}function str(a,b){var c,d,e,f,g=gap,h,i=b[a];i&&typeof i=="object"&&typeof i.toJSON=="function"&&(i=i.toJSON(a)),typeof rep=="function"&&(i=rep.call(b,a,i));switch(typeof i){case"string":return quote(i);case"number":return isFinite(i)?String(i):"null";case"boolean":case"null":return String(i);case"object":if(!i)return"null";gap+=indent,h=[];if(Object.prototype.toString.apply(i)==="[object Array]"){f=i.length;for(c=0;c")&&c[0]);return a>4?a:!1}();return a},m.isInternetExplorer=function(){var a=m.isInternetExplorer.cached=typeof m.isInternetExplorer.cached!="undefined"?m.isInternetExplorer.cached:Boolean(m.getInternetExplorerMajorVersion());return a},m.emulated={pushState:!Boolean(a.history&&a.history.pushState&&a.history.replaceState&&!/ Mobile\/([1-7][a-z]|(8([abcde]|f(1[0-8]))))/i.test(e.userAgent)&&!/AppleWebKit\/5([0-2]|3[0-2])/i.test(e.userAgent)),hashChange:Boolean(!("onhashchange"in a||"onhashchange"in d)||m.isInternetExplorer()&&m.getInternetExplorerMajorVersion()<8)},m.enabled=!m.emulated.pushState,m.bugs={setHash:Boolean(!m.emulated.pushState&&e.vendor==="Apple Computer, Inc."&&/AppleWebKit\/5([0-2]|3[0-3])/.test(e.userAgent)),safariPoll:Boolean(!m.emulated.pushState&&e.vendor==="Apple Computer, Inc."&&/AppleWebKit\/5([0-2]|3[0-3])/.test(e.userAgent)),ieDoubleCheck:Boolean(m.isInternetExplorer()&&m.getInternetExplorerMajorVersion()<8),hashEscape:Boolean(m.isInternetExplorer()&&m.getInternetExplorerMajorVersion()<7)},m.isEmptyObject=function(a){for(var b in a)return!1;return!0},m.cloneObject=function(a){var b,c;return a?(b=k.stringify(a),c=k.parse(b)):c={},c},m.getRootUrl=function(){var a=d.location.protocol+"//"+(d.location.hostname||d.location.host);if(d.location.port||!1)a+=":"+d.location.port;return a+="/",a},m.getBaseHref=function(){var a=d.getElementsByTagName("base"),b=null,c="";return a.length===1&&(b=a[0],c=b.href.replace(/[^\/]+$/,"")),c=c.replace(/\/+$/,""),c&&(c+="/"),c},m.getBaseUrl=function(){var a=m.getBaseHref()||m.getBasePageUrl()||m.getRootUrl();return a},m.getPageUrl=function(){var a=m.getState(!1,!1),b=(a||{}).url||d.location.href,c;return c=b.replace(/\/+$/,"").replace(/[^\/]+$/,function(a,b,c){return/\./.test(a)?a:a+"/"}),c},m.getBasePageUrl=function(){var a=d.location.href.replace(/[#\?].*/,"").replace(/[^\/]+$/,function(a,b,c){return/[^\/]$/.test(a)?"":a}).replace(/\/+$/,"")+"/";return a},m.getFullUrl=function(a,b){var c=a,d=a.substring(0,1);return b=typeof b=="undefined"?!0:b,/[a-z]+\:\/\//.test(a)||(d==="/"?c=m.getRootUrl()+a.replace(/^\/+/,""):d==="#"?c=m.getPageUrl().replace(/#.*/,"")+a:d==="?"?c=m.getPageUrl().replace(/[\?#].*/,"")+a:b?c=m.getBaseUrl()+a.replace(/^(\.\/)+/,""):c=m.getBasePageUrl()+a.replace(/^(\.\/)+/,"")),c.replace(/\#$/,"")},m.getShortUrl=function(a){var b=a,c=m.getBaseUrl(),d=m.getRootUrl();return m.emulated.pushState&&(b=b.replace(c,"")),b=b.replace(d,"/"),m.isTraditionalAnchor(b)&&(b="./"+b),b=b.replace(/^(\.\/)+/g,"./").replace(/\#$/,""),b},m.store={},m.idToState=m.idToState||{},m.stateToId=m.stateToId||{},m.urlToId=m.urlToId||{},m.storedStates=m.storedStates||[],m.savedStates=m.savedStates||[],m.normalizeStore=function(){m.store.idToState=m.store.idToState||{},m.store.urlToId=m.store.urlToId||{},m.store.stateToId=m.store.stateToId||{}},m.getState=function(a,b){typeof a=="undefined"&&(a=!0),typeof b=="undefined"&&(b=!0);var c=m.getLastSavedState();return!c&&b&&(c=m.createStateObject()),a&&(c=m.cloneObject(c),c.url=c.cleanUrl||c.url),c},m.getIdByState=function(a){var b=m.extractId(a.url),c;if(!b){c=m.getStateString(a);if(typeof m.stateToId[c]!="undefined")b=m.stateToId[c];else if(typeof m.store.stateToId[c]!="undefined")b=m.store.stateToId[c];else{for(;;){b=(new Date).getTime()+String(Math.random()).replace(/\D/g,"");if(typeof m.idToState[b]=="undefined"&&typeof m.store.idToState[b]=="undefined")break}m.stateToId[c]=b,m.idToState[b]=a}}return b},m.normalizeState=function(a){var b,c;if(!a||typeof a!="object")a={};if(typeof a.normalized!="undefined")return a;if(!a.data||typeof a.data!="object")a.data={};b={},b.normalized=!0,b.title=a.title||"",b.url=m.getFullUrl(m.unescapeString(a.url||d.location.href)),b.hash=m.getShortUrl(b.url),b.data=m.cloneObject(a.data),b.id=m.getIdByState(b),b.cleanUrl=b.url.replace(/\??\&_suid.*/,""),b.url=b.cleanUrl,c=!m.isEmptyObject(b.data);if(b.title||c)b.hash=m.getShortUrl(b.url).replace(/\??\&_suid.*/,""),/\?/.test(b.hash)||(b.hash+="?"),b.hash+="&_suid="+b.id;return b.hashedUrl=m.getFullUrl(b.hash),(m.emulated.pushState||m.bugs.safariPoll)&&m.hasUrlDuplicate(b)&&(b.url=b.hashedUrl),b},m.createStateObject=function(a,b,c){var d={data:a,title:b,url:c};return d=m.normalizeState(d),d},m.getStateById=function(a){a=String(a);var c=m.idToState[a]||m.store.idToState[a]||b;return c},m.getStateString=function(a){var b,c,d;return b=m.normalizeState(a),c={data:b.data,title:a.title,url:a.url},d=k.stringify(c),d},m.getStateId=function(a){var b,c;return b=m.normalizeState(a),c=b.id,c},m.getHashByState=function(a){var b,c;return b=m.normalizeState(a),c=b.hash,c},m.extractId=function(a){var b,c,d;return c=/(.*)\&_suid=([0-9]+)$/.exec(a),d=c?c[1]||a:a,b=c?String(c[2]||""):"",b||!1},m.isTraditionalAnchor=function(a){var b=!/[\/\?\.]/.test(a);return b},m.extractState=function(a,b){var c=null,d,e;return b=b||!1,d=m.extractId(a),d&&(c=m.getStateById(d)),c||(e=m.getFullUrl(a),d=m.getIdByUrl(e)||!1,d&&(c=m.getStateById(d)),!c&&b&&!m.isTraditionalAnchor(a)&&(c=m.createStateObject(null,null,e))),c},m.getIdByUrl=function(a){var c=m.urlToId[a]||m.store.urlToId[a]||b;return c},m.getLastSavedState=function(){return m.savedStates[m.savedStates.length-1]||b},m.getLastStoredState=function(){return m.storedStates[m.storedStates.length-1]||b},m.hasUrlDuplicate=function(a){var b=!1,c;return c=m.extractState(a.url),b=c&&c.id!==a.id,b},m.storeState=function(a){return m.urlToId[a.url]=a.id,m.storedStates.push(m.cloneObject(a)),a},m.isLastSavedState=function(a){var b=!1,c,d,e;return m.savedStates.length&&(c=a.id,d=m.getLastSavedState(),e=d.id,b=c===e),b},m.saveState=function(a){return m.isLastSavedState(a)?!1:(m.savedStates.push(m.cloneObject(a)),!0)},m.getStateByIndex=function(a){var b=null;return typeof a=="undefined"?b=m.savedStates[m.savedStates.length-1]:a<0?b=m.savedStates[m.savedStates.length+a]:b=m.savedStates[a],b},m.getHash=function(){var a=m.unescapeHash(d.location.hash);return a},m.unescapeString=function(b){var c=b,d;for(;;){d=a.unescape(c);if(d===c)break;c=d}return c},m.unescapeHash=function(a){var b=m.normalizeHash(a);return b=m.unescapeString(b),b},m.normalizeHash=function(a){var b=a.replace(/[^#]*#/,"").replace(/#.*/,"");return b},m.setHash=function(a,b){var c,e,f;return b!==!1&&m.busy()?(m.pushQueue({scope:m,callback:m.setHash,args:arguments,queue:b}),!1):(c=m.escapeHash(a),m.busy(!0),e=m.extractState(a,!0),e&&!m.emulated.pushState?m.pushState(e.data,e.title,e.url,!1):d.location.hash!==c&&(m.bugs.setHash?(f=m.getPageUrl(),m.pushState(null,null,f+"#"+c,!1)):d.location.hash=c),m)},m.escapeHash=function(b){var c=m.normalizeHash(b);return c=a.escape(c),m.bugs.hashEscape||(c=c.replace(/\%21/g,"!").replace(/\%26/g,"&").replace(/\%3D/g,"=").replace(/\%3F/g,"?")),c},m.getHashByUrl=function(a){var b=String(a).replace(/([^#]*)#?([^#]*)#?(.*)/,"$2");return b=m.unescapeHash(b),b},m.setTitle=function(a){var b=a.title,c;b||(c=m.getStateByIndex(0),c&&c.url===a.url&&(b=c.title||m.options.initialTitle));try{d.getElementsByTagName("title")[0].innerHTML=b.replace("<","<").replace(">",">").replace(" & "," & ")}catch(e){}return d.title=b,m},m.queues=[],m.busy=function(a){typeof a!="undefined"?m.busy.flag=a:typeof m.busy.flag=="undefined"&&(m.busy.flag=!1);if(!m.busy.flag){h(m.busy.timeout);var b=function(){var a,c,d;if(m.busy.flag)return;for(a=m.queues.length-1;a>=0;--a){c=m.queues[a];if(c.length===0)continue;d=c.shift(),m.fireQueueItem(d),m.busy.timeout=g(b,m.options.busyDelay)}};m.busy.timeout=g(b,m.options.busyDelay)}return m.busy.flag},m.busy.flag=!1,m.fireQueueItem=function(a){return a.callback.apply(a.scope||m,a.args||[])},m.pushQueue=function(a){return m.queues[a.queue||0]=m.queues[a.queue||0]||[],m.queues[a.queue||0].push(a),m},m.queue=function(a,b){return typeof a=="function"&&(a={callback:a}),typeof b!="undefined"&&(a.queue=b),m.busy()?m.pushQueue(a):m.fireQueueItem(a),m},m.clearQueue=function(){return m.busy.flag=!1,m.queues=[],m},m.stateChanged=!1,m.doubleChecker=!1,m.doubleCheckComplete=function(){return m.stateChanged=!0,m.doubleCheckClear(),m},m.doubleCheckClear=function(){return m.doubleChecker&&(h(m.doubleChecker),m.doubleChecker=!1),m},m.doubleCheck=function(a){return m.stateChanged=!1,m.doubleCheckClear(),m.bugs.ieDoubleCheck&&(m.doubleChecker=g(function(){return m.doubleCheckClear(),m.stateChanged||a(),!0},m.options.doubleCheckInterval)),m},m.safariStatePoll=function(){var b=m.extractState(d.location.href),c;if(!m.isLastSavedState(b))c=b;else return;return c||(c=m.createStateObject()),m.Adapter.trigger(a,"popstate"),m},m.back=function(a){return a!==!1&&m.busy()?(m.pushQueue({scope:m,callback:m.back,args:arguments,queue:a}),!1):(m.busy(!0),m.doubleCheck(function(){m.back(!1)}),n.go(-1),!0)},m.forward=function(a){return a!==!1&&m.busy()?(m.pushQueue({scope:m,callback:m.forward,args:arguments,queue:a}),!1):(m.busy(!0),m.doubleCheck(function(){m.forward(!1)}),n.go(1),!0)},m.go=function(a,b){var c;if(a>0)for(c=1;c<=a;++c)m.forward(b);else{if(!(a<0))throw new Error("History.go: History.go requires a positive or negative integer passed.");for(c=-1;c>=a;--c)m.back(b)}return m};if(m.emulated.pushState){var o=function(){};m.pushState=m.pushState||o,m.replaceState=m.replaceState||o}else m.onPopState=function(b,c){var e=!1,f=!1,g,h;return m.doubleCheckComplete(),g=m.getHash(),g?(h=m.extractState(g||d.location.href,!0),h?m.replaceState(h.data,h.title,h.url,!1):(m.Adapter.trigger(a,"anchorchange"),m.busy(!1)),m.expectedStateId=!1,!1):(e=m.Adapter.extractEventData("state",b,c)||!1,e?f=m.getStateById(e):m.expectedStateId?f=m.getStateById(m.expectedStateId):f=m.extractState(d.location.href),f||(f=m.createStateObject(null,null,d.location.href)),m.expectedStateId=!1,m.isLastSavedState(f)?(m.busy(!1),!1):(m.storeState(f),m.saveState(f),m.setTitle(f),m.Adapter.trigger(a,"statechange"),m.busy(!1),!0))},m.Adapter.bind(a,"popstate",m.onPopState),m.pushState=function(b,c,d,e){if(m.getHashByUrl(d)&&m.emulated.pushState)throw new Error("History.js does not support states with fragement-identifiers (hashes/anchors).");if(e!==!1&&m.busy())return m.pushQueue({scope:m,callback:m.pushState,args:arguments,queue:e}),!1;m.busy(!0);var f=m.createStateObject(b,c,d);return m.isLastSavedState(f)?m.busy(!1):(m.storeState(f),m.expectedStateId=f.id,n.pushState(f.id,f.title,f.url),m.Adapter.trigger(a,"popstate")),!0},m.replaceState=function(b,c,d,e){if(m.getHashByUrl(d)&&m.emulated.pushState)throw new Error("History.js does not support states with fragement-identifiers (hashes/anchors).");if(e!==!1&&m.busy())return m.pushQueue({scope:m,callback:m.replaceState,args:arguments,queue:e}),!1;m.busy(!0);var f=m.createStateObject(b,c,d);return m.isLastSavedState(f)?m.busy(!1):(m.storeState(f),m.expectedStateId=f.id,n.replaceState(f.id,f.title,f.url),m.Adapter.trigger(a,"popstate")),!0};if(f){try{m.store=k.parse(f.getItem("History.store"))||{}}catch(p){m.store={}}m.normalizeStore()}else m.store={},m.normalizeStore();m.Adapter.bind(a,"beforeunload",m.clearAllIntervals),m.Adapter.bind(a,"unload",m.clearAllIntervals),m.saveState(m.storeState(m.extractState(d.location.href,!0))),f&&(m.onUnload=function(){var a,b;try{a=k.parse(f.getItem("History.store"))||{}}catch(c){a={}}a.idToState=a.idToState||{},a.urlToId=a.urlToId||{},a.stateToId=a.stateToId||{};for(b in m.idToState){if(!m.idToState.hasOwnProperty(b))continue;a.idToState[b]=m.idToState[b]}for(b in m.urlToId){if(!m.urlToId.hasOwnProperty(b))continue;a.urlToId[b]=m.urlToId[b]}for(b in m.stateToId){if(!m.stateToId.hasOwnProperty(b))continue;a.stateToId[b]=m.stateToId[b]}m.store=a,m.normalizeStore(),f.setItem("History.store",k.stringify(a))},m.intervalList.push(i(m.onUnload,m.options.storeInterval)),m.Adapter.bind(a,"beforeunload",m.onUnload),m.Adapter.bind(a,"unload",m.onUnload));if(!m.emulated.pushState){m.bugs.safariPoll&&m.intervalList.push(i(m.safariStatePoll,m.options.safariPollInterval));if(e.vendor==="Apple Computer, Inc."||(e.appCodeName||"")==="Mozilla")m.Adapter.bind(a,"hashchange",function(){m.Adapter.trigger(a,"popstate")}),m.getHash()&&m.Adapter.onDomLoad(function(){m.Adapter.trigger(a,"hashchange")})}},m.init()}(window) \ No newline at end of file diff --git a/sites/all/themes/gui/materiobasetheme/js/libs/jquery.hotkeys.js b/sites/all/themes/gui/materiobasetheme/js/libs/jquery.hotkeys.js deleted file mode 100644 index fbd71c71..00000000 --- a/sites/all/themes/gui/materiobasetheme/js/libs/jquery.hotkeys.js +++ /dev/null @@ -1,99 +0,0 @@ -/* - * jQuery Hotkeys Plugin - * Copyright 2010, John Resig - * Dual licensed under the MIT or GPL Version 2 licenses. - * - * Based upon the plugin by Tzury Bar Yochay: - * http://github.com/tzuryby/hotkeys - * - * Original idea by: - * Binny V A, http://www.openjs.com/scripts/events/keyboard_shortcuts/ -*/ - -(function(jQuery){ - - jQuery.hotkeys = { - version: "0.8", - - specialKeys: { - 8: "backspace", 9: "tab", 13: "return", 16: "shift", 17: "ctrl", 18: "alt", 19: "pause", - 20: "capslock", 27: "esc", 32: "space", 33: "pageup", 34: "pagedown", 35: "end", 36: "home", - 37: "left", 38: "up", 39: "right", 40: "down", 45: "insert", 46: "del", - 96: "0", 97: "1", 98: "2", 99: "3", 100: "4", 101: "5", 102: "6", 103: "7", - 104: "8", 105: "9", 106: "*", 107: "+", 109: "-", 110: ".", 111 : "/", - 112: "f1", 113: "f2", 114: "f3", 115: "f4", 116: "f5", 117: "f6", 118: "f7", 119: "f8", - 120: "f9", 121: "f10", 122: "f11", 123: "f12", 144: "numlock", 145: "scroll", 191: "/", 224: "meta" - }, - - shiftNums: { - "`": "~", "1": "!", "2": "@", "3": "#", "4": "$", "5": "%", "6": "^", "7": "&", - "8": "*", "9": "(", "0": ")", "-": "_", "=": "+", ";": ": ", "'": "\"", ",": "<", - ".": ">", "/": "?", "\\": "|" - } - }; - - function keyHandler( handleObj ) { - // Only care when a possible input has been specified - if ( typeof handleObj.data !== "string" ) { - return; - } - - var origHandler = handleObj.handler, - keys = handleObj.data.toLowerCase().split(" "); - - handleObj.handler = function( event ) { - // Don't fire in text-accepting inputs that we didn't directly bind to - if ( this !== event.target && (/textarea|select/i.test( event.target.nodeName ) || - event.target.type === "text") ) { - return; - } - - // Keypress represents characters, not special keys - var special = event.type !== "keypress" && jQuery.hotkeys.specialKeys[ event.which ], - character = String.fromCharCode( event.which ).toLowerCase(), - key, modif = "", possible = {}; - - // check combinations (alt|ctrl|shift+anything) - if ( event.altKey && special !== "alt" ) { - modif += "alt+"; - } - - if ( event.ctrlKey && special !== "ctrl" ) { - modif += "ctrl+"; - } - - // TODO: Need to make sure this works consistently across platforms - if ( event.metaKey && !event.ctrlKey && special !== "meta" ) { - modif += "meta+"; - } - - if ( event.shiftKey && special !== "shift" ) { - modif += "shift+"; - } - - if ( special ) { - possible[ modif + special ] = true; - - } else { - possible[ modif + character ] = true; - possible[ modif + jQuery.hotkeys.shiftNums[ character ] ] = true; - - // "$" can be triggered as "Shift+4" or "Shift+$" or just "$" - if ( modif === "shift+" ) { - possible[ jQuery.hotkeys.shiftNums[ character ] ] = true; - } - } - - for ( var i = 0, l = keys.length; i < l; i++ ) { - if ( possible[ keys[i] ] ) { - return origHandler.apply( this, arguments ); - } - } - }; - } - - jQuery.each([ "keydown", "keyup", "keypress" ], function() { - jQuery.event.special[ this ] = { add: keyHandler }; - }); - -})( jQuery ); \ No newline at end of file diff --git a/sites/all/themes/gui/materiobasetheme/js/libs/jquery.lazyload.min.js b/sites/all/themes/gui/materiobasetheme/js/libs/jquery.lazyload.min.js deleted file mode 100644 index 849dc618..00000000 --- a/sites/all/themes/gui/materiobasetheme/js/libs/jquery.lazyload.min.js +++ /dev/null @@ -1,15 +0,0 @@ -/* - * Lazy Load - jQuery plugin for lazy loading images - * - * Copyright (c) 2007-2012 Mika Tuupola - * - * Licensed under the MIT license: - * http://www.opensource.org/licenses/mit-license.php - * - * Project home: - * http://www.appelsiini.net/projects/lazyload - * - * Version: 1.8.2 - * - */ -(function(a,b,c,d){var e=a(b);a.fn.lazyload=function(f){function j(){var b=0;g.each(function(){var c=a(this);if(i.skip_invisible&&!c.is(":visible"))return;if(!a.abovethetop(this,i)&&!a.leftofbegin(this,i))if(!a.belowthefold(this,i)&&!a.rightoffold(this,i))c.trigger("appear"),b=0;else if(++b>i.failure_limit)return!1})}var g=this,h,i={threshold:0,failure_limit:0,event:"scroll",effect:"show",container:b,data_attribute:"original",skip_invisible:!0,appear:null,load:null};return f&&(d!==f.failurelimit&&(f.failure_limit=f.failurelimit,delete f.failurelimit),d!==f.effectspeed&&(f.effect_speed=f.effectspeed,delete f.effectspeed),a.extend(i,f)),h=i.container===d||i.container===b?e:a(i.container),0===i.event.indexOf("scroll")&&h.bind(i.event,function(a){return j()}),this.each(function(){var b=this,c=a(b);b.loaded=!1,c.one("appear",function(){if(!this.loaded){if(i.appear){var d=g.length;i.appear.call(b,d,i)}a("").bind("load",function(){c.hide().attr("src",c.data(i.data_attribute))[i.effect](i.effect_speed),b.loaded=!0;var d=a.grep(g,function(a){return!a.loaded});g=a(d);if(i.load){var e=g.length;i.load.call(b,e,i)}}).attr("src",c.data(i.data_attribute))}}),0!==i.event.indexOf("scroll")&&c.bind(i.event,function(a){b.loaded||c.trigger("appear")})}),e.bind("resize",function(a){j()}),/iphone|ipod|ipad.*os 5/gi.test(navigator.appVersion)&&e.bind("pageshow",function(b){b.originalEvent.persisted&&g.each(function(){a(this).trigger("appear")})}),a(c).ready(function(){j()}),this},a.belowthefold=function(c,f){var g;return f.container===d||f.container===b?g=e.height()+e.scrollTop():g=a(f.container).offset().top+a(f.container).height(),g<=a(c).offset().top-f.threshold},a.rightoffold=function(c,f){var g;return f.container===d||f.container===b?g=e.width()+e.scrollLeft():g=a(f.container).offset().left+a(f.container).width(),g<=a(c).offset().left-f.threshold},a.abovethetop=function(c,f){var g;return f.container===d||f.container===b?g=e.scrollTop():g=a(f.container).offset().top,g>=a(c).offset().top+f.threshold+a(c).height()},a.leftofbegin=function(c,f){var g;return f.container===d||f.container===b?g=e.scrollLeft():g=a(f.container).offset().left,g>=a(c).offset().left+f.threshold+a(c).width()},a.inviewport=function(b,c){return!a.rightoffold(b,c)&&!a.leftofbegin(b,c)&&!a.belowthefold(b,c)&&!a.abovethetop(b,c)},a.extend(a.expr[":"],{"below-the-fold":function(b){return a.belowthefold(b,{threshold:0})},"above-the-top":function(b){return!a.belowthefold(b,{threshold:0})},"right-of-screen":function(b){return a.rightoffold(b,{threshold:0})},"left-of-screen":function(b){return!a.rightoffold(b,{threshold:0})},"in-viewport":function(b){return a.inviewport(b,{threshold:0})},"above-the-fold":function(b){return!a.belowthefold(b,{threshold:0})},"right-of-fold":function(b){return a.rightoffold(b,{threshold:0})},"left-of-fold":function(b){return!a.rightoffold(b,{threshold:0})}})})(jQuery,window,document) diff --git a/sites/all/themes/gui/materiobasetheme/js/libs/jquery.transit.js b/sites/all/themes/gui/materiobasetheme/js/libs/jquery.transit.js deleted file mode 100644 index 3ebae618..00000000 --- a/sites/all/themes/gui/materiobasetheme/js/libs/jquery.transit.js +++ /dev/null @@ -1,658 +0,0 @@ -/*! - * jQuery Transit - CSS3 transitions and transformations - * Copyright(c) 2011 Rico Sta. Cruz - * MIT Licensed. - * - * http://ricostacruz.com/jquery.transit - * http://github.com/rstacruz/jquery.transit - */ - -(function($) { - "use strict"; - - $.transit = { - version: "0.1.3", - - // Map of $.css() keys to values for 'transitionProperty'. - // See https://developer.mozilla.org/en/CSS/CSS_transitions#Properties_that_can_be_animated - propertyMap: { - marginLeft : 'margin', - marginRight : 'margin', - marginBottom : 'margin', - marginTop : 'margin', - paddingLeft : 'padding', - paddingRight : 'padding', - paddingBottom : 'padding', - paddingTop : 'padding' - }, - - // Will simply transition "instantly" if false - enabled: true, - - // Set this to false if you don't want to use the transition end property. - useTransitionEnd: false - }; - - var div = document.createElement('div'); - var support = {}; - - // Helper function to get the proper vendor property name. - // (`transition` => `WebkitTransition`) - function getVendorPropertyName(prop) { - var prefixes = ['Moz', 'Webkit', 'O', 'ms']; - var prop_ = prop.charAt(0).toUpperCase() + prop.substr(1); - - if (prop in div.style) { return prop; } - - for (var i=0; i -1; - - // Check for the browser's transitions support. - // You can access this in jQuery's `$.support.transition`. - // As per [jQuery's cssHooks documentation](http://api.jquery.com/jQuery.cssHooks/), - // we set $.support.transition to a string of the actual property name used. - support.transition = getVendorPropertyName('transition'); - support.transitionDelay = getVendorPropertyName('transitionDelay'); - support.transform = getVendorPropertyName('transform'); - support.transformOrigin = getVendorPropertyName('transformOrigin'); - support.transform3d = checkTransform3dSupport(); - - $.extend($.support, support); - - var eventNames = { - 'MozTransition': 'transitionend', - 'OTransition': 'oTransitionEnd', - 'WebkitTransition': 'webkitTransitionEnd', - 'msTransition': 'MSTransitionEnd' - }; - - // Detect the 'transitionend' event needed. - var transitionEnd = support.transitionEnd = eventNames[support.transition] || null; - - // Avoid memory leak in IE. - div = null; - - // ## $.cssEase - // List of easing aliases that you can use with `$.fn.transition`. - $.cssEase = { - '_default': 'ease', - 'in': 'ease-in', - 'out': 'ease-out', - 'in-out': 'ease-in-out', - 'snap': 'cubic-bezier(0,1,.5,1)' - }; - - // ## 'transform' CSS hook - // Allows you to use the `transform` property in CSS. - // - // $("#hello").css({ transform: "rotate(90deg)" }); - // - // $("#hello").css('transform'); - // //=> { rotate: '90deg' } - // - $.cssHooks.transform = { - // The getter returns a `Transform` object. - get: function(elem) { - return $(elem).data('transform'); - }, - - // The setter accepts a `Transform` object or a string. - set: function(elem, v) { - var value = v; - - if (!(value instanceof Transform)) { - value = new Transform(value); - } - - // We've seen the 3D version of Scale() not work in Chrome when the - // element being scaled extends outside of the viewport. Thus, we're - // forcing Chrome to not use the 3d transforms as well. Not sure if - // translate is affectede, but not risking it. Detection code from - // http://davidwalsh.name/detecting-google-chrome-javascript - if (support.transform === 'WebkitTransform' && !isChrome) { - elem.style[support.transform] = value.toString(true); - } else { - elem.style[support.transform] = value.toString(); - } - - $(elem).data('transform', value); - } - }; - - // ## 'transformOrigin' CSS hook - // Allows the use for `transformOrigin` to define where scaling and rotation - // is pivoted. - // - // $("#hello").css({ transformOrigin: '0 0' }); - // - $.cssHooks.transformOrigin = { - get: function(elem) { - return elem.style[support.transformOrigin]; - }, - set: function(elem, value) { - elem.style[support.transformOrigin] = value; - } - }; - - // ## 'transition' CSS hook - // Allows you to use the `transition` property in CSS. - // - // $("#hello").css({ transition: 'all 0 ease 0' }); - // - $.cssHooks.transition = { - get: function(elem) { - return elem.style[support.transition]; - }, - set: function(elem, value) { - elem.style[support.transition] = value; - } - }; - - // ## Other CSS hooks - // Allows you to rotate, scale and translate. - registerCssHook('scale'); - registerCssHook('translate'); - registerCssHook('rotate'); - registerCssHook('rotateX'); - registerCssHook('rotateY'); - registerCssHook('rotate3d'); - registerCssHook('perspective'); - registerCssHook('skewX'); - registerCssHook('skewY'); - registerCssHook('x', true); - registerCssHook('y', true); - - // ## Transform class - // This is the main class of a transformation property that powers - // `$.fn.css({ transform: '...' })`. - // - // This is, in essence, a dictionary object with key/values as `-transform` - // properties. - // - // var t = new Transform("rotate(90) scale(4)"); - // - // t.rotate //=> "90deg" - // t.scale //=> "4,4" - // - // Setters are accounted for. - // - // t.set('rotate', 4) - // t.rotate //=> "4deg" - // - // Convert it to a CSS string using the `toString()` and `toString(true)` (for WebKit) - // functions. - // - // t.toString() //=> "rotate(90deg) scale(4,4)" - // t.toString(true) //=> "rotate(90deg) scale3d(4,4,0)" (WebKit version) - // - function Transform(str) { - if (typeof str === 'string') { this.parse(str); } - return this; - } - - Transform.prototype = { - // ### setFromString() - // Sets a property from a string. - // - // t.setFromString('scale', '2,4'); - // // Same as set('scale', '2', '4'); - // - setFromString: function(prop, val) { - var args = - (typeof val === 'string') ? val.split(',') : - (val.constructor === Array) ? val : - [ val ]; - - args.unshift(prop); - - Transform.prototype.set.apply(this, args); - }, - - // ### set() - // Sets a property. - // - // t.set('scale', 2, 4); - // - set: function(prop) { - var args = Array.prototype.slice.apply(arguments, [1]); - if (this.setter[prop]) { - this.setter[prop].apply(this, args); - } else { - this[prop] = args.join(','); - } - }, - - get: function(prop) { - if (this.getter[prop]) { - return this.getter[prop].apply(this); - } else { - return this[prop] || 0; - } - }, - - setter: { - // ### rotate - // - // .css({ rotate: 30 }) - // .css({ rotate: "30" }) - // .css({ rotate: "30deg" }) - // .css({ rotate: "30deg" }) - // - rotate: function(theta) { - this.rotate = unit(theta, 'deg'); - }, - - rotateX: function(theta) { - this.rotateX = unit(theta, 'deg'); - }, - - rotateY: function(theta) { - this.rotateY = unit(theta, 'deg'); - }, - - // ### scale - // - // .css({ scale: 9 }) //=> "scale(9,9)" - // .css({ scale: '3,2' }) //=> "scale(3,2)" - // - scale: function(x, y) { - if (y === undefined) { y = x; } - this.scale = x + "," + y; - }, - - // ### skewX + skewY - skewX: function(x) { - this.skewX = unit(x, 'deg'); - }, - - skewY: function(y) { - this.skewY = unit(y, 'deg'); - }, - - // ### perspectvie - perspective: function(dist) { - this.perspective = unit(dist, 'px'); - }, - - // ### x / y - // Translations. Notice how this keeps the other value. - // - // .css({ x: 4 }) //=> "translate(4px, 0)" - // .css({ y: 10 }) //=> "translate(4px, 10px)" - // - x: function(x) { - this.set('translate', x, null); - }, - - y: function(y) { - this.set('translate', null, y); - }, - - // ### translate - // Notice how this keeps the other value. - // - // .css({ translate: '2, 5' }) //=> "translate(2px, 5px)" - // - translate: function(x, y) { - if (this._translateX === undefined) { this._translateX = 0; } - if (this._translateY === undefined) { this._translateY = 0; } - - if (x !== null) { this._translateX = unit(x, 'px'); } - if (y !== null) { this._translateY = unit(y, 'px'); } - - this.translate = this._translateX + "," + this._translateY; - } - }, - - getter: { - x: function() { - return this._translateX || 0; - }, - - y: function() { - return this._translateY || 0; - }, - - scale: function() { - var s = (this.scale || "1,1").split(','); - if (s[0]) { s[0] = parseFloat(s[0]); } - if (s[1]) { s[1] = parseFloat(s[1]); } - - // "2.5,2.5" => 2.5 - // "2.5,1" => [2.5,1] - return (s[0] === s[1]) ? s[0] : s; - }, - - rotate3d: function() { - var s = (this.rotate3d || "0,0,0,0deg").split(','); - for (var i=0; i<=3; ++i) { - if (s[i]) { s[i] = parseFloat(s[i]); } - } - if (s[3]) { s[3] = unit(s[3], 'deg'); } - - return s; - } - }, - - // ### parse() - // Parses from a string. Called on constructor. - parse: function(str) { - var self = this; - str.replace(/([a-zA-Z0-9]+)\((.*?)\)/g, function(x, prop, val) { - self.setFromString(prop, val); - }); - }, - - // ### toString() - // Converts to a `transition` CSS property string. If `use3d` is given, - // it converts to a `-webkit-transition` CSS property string instead. - toString: function(use3d) { - var re = []; - - for (var i in this) { - if (this.hasOwnProperty(i)) { - // Don't use 3D transformations if the browser can't support it. - if ((!support.transform3d) && ( - (i === 'rotateX') || - (i === 'rotateY') || - (i === 'perspective') || - (i === 'transformOrigin'))) { continue; } - - if (i[0] !== '_') { - if (use3d && (i === 'scale')) { - re.push(i + "3d(" + this[i] + ",1)"); - } else if (use3d && (i === 'translate')) { - re.push(i + "3d(" + this[i] + ",0)"); - } else { - re.push(i + "(" + this[i] + ")"); - } - } - } - } - - return re.join(" "); - } - }; - - function callOrQueue(self, queue, fn) { - if (queue === true) { - self.queue(fn); - } else if (queue) { - self.queue(queue, fn); - } else { - fn(); - } - } - - // ### getProperties(dict) - // Returns properties (for `transition-property`) for dictionary `props`. The - // value of `props` is what you would expect in `$.css(...)`. - function getProperties(props) { - var re = []; - - $.each(props, function(key) { - key = $.camelCase(key); // Convert "text-align" => "textAlign" - key = $.transit.propertyMap[key] || key; - key = uncamel(key); // Convert back to dasherized - - if ($.inArray(key, re) === -1) { re.push(key); } - }); - - return re; - } - - // ### getTransition() - // Returns the transition string to be used for the `transition` CSS property. - // - // Example: - // - // getTransition({ opacity: 1, rotate: 30 }, 500, 'ease'); - // //=> 'opacity 500ms ease, -webkit-transform 500ms ease' - // - function getTransition(properties, duration, easing, delay) { - // Get the CSS properties needed. - var props = getProperties(properties); - - // Account for aliases (`in` => `ease-in`). - if ($.cssEase[easing]) { easing = $.cssEase[easing]; } - - // Build the duration/easing/delay attributes for it. - var attribs = '' + toMS(duration) + ' ' + easing; - if (parseInt(delay, 10) > 0) { attribs += ' ' + toMS(delay); } - - // For more properties, add them this way: - // "margin 200ms ease, padding 200ms ease, ..." - var transitions = []; - $.each(props, function(i, name) { - transitions.push(name + ' ' + attribs); - }); - - return transitions.join(', '); - } - - // ## $.fn.transition - // Works like $.fn.animate(), but uses CSS transitions. - // - // $("...").transition({ opacity: 0.1, scale: 0.3 }); - // - // // Specific duration - // $("...").transition({ opacity: 0.1, scale: 0.3 }, 500); - // - // // With duration and easing - // $("...").transition({ opacity: 0.1, scale: 0.3 }, 500, 'in'); - // - // // With callback - // $("...").transition({ opacity: 0.1, scale: 0.3 }, function() { ... }); - // - // // With everything - // $("...").transition({ opacity: 0.1, scale: 0.3 }, 500, 'in', function() { ... }); - // - // // Alternate syntax - // $("...").transition({ - // opacity: 0.1, - // duration: 200, - // delay: 40, - // easing: 'in', - // complete: function() { /* ... */ } - // }); - // - $.fn.transition = $.fn.transit = function(properties, duration, easing, callback) { - var self = this; - var delay = 0; - var queue = true; - - // Account for `.transition(properties, callback)`. - if (typeof duration === 'function') { - callback = duration; - duration = undefined; - } - - // Account for `.transition(properties, duration, callback)`. - if (typeof easing === 'function') { - callback = easing; - easing = undefined; - } - - // Alternate syntax. - if (typeof properties.easing !== 'undefined') { - easing = properties.easing; - delete properties.easing; - } - - if (typeof properties.duration !== 'undefined') { - duration = properties.duration; - delete properties.duration; - } - - if (typeof properties.complete !== 'undefined') { - callback = properties.complete; - delete properties.complete; - } - - if (typeof properties.queue !== 'undefined') { - queue = properties.queue; - delete properties.queue; - } - - if (typeof properties.delay !== 'undefined') { - delay = properties.delay; - delete properties.delay; - } - - // Set defaults. (`400` duration, `ease` easing) - if (typeof duration === 'undefined') { duration = $.fx.speeds._default; } - if (typeof easing === 'undefined') { easing = $.cssEase._default; } - - duration = toMS(duration); - - // Build the `transition` property. - var transitionValue = getTransition(properties, duration, easing, delay); - - // Compute delay until callback. - // If this becomes 0, don't bother setting the transition property. - var work = $.transit.enabled && support.transition; - var i = work ? (parseInt(duration, 10) + parseInt(delay, 10)) : 0; - - // If there's nothing to do... - if (i === 0) { - var fn = function(next) { - self.css(properties); - if (callback) { callback.apply(self); } - if (next) { next(); } - }; - - callOrQueue(self, queue, fn); - return self; - } - - // Save the old transitions of each element so we can restore it later. - var oldTransitions = {}; - - var run = function(nextCall) { - var bound = false; - - // Prepare the callback. - var cb = function() { - if (bound) { self.unbind(transitionEnd, cb); } - - if (i > 0) { - self.each(function() { - this.style[support.transition] = (oldTransitions[this] || null); - }); - } - - if (typeof callback === 'function') { callback.apply(self); } - if (typeof nextCall === 'function') { nextCall(); } - }; - - if ((i > 0) && (transitionEnd) && ($.transit.useTransitionEnd)) { - // Use the 'transitionend' event if it's available. - bound = true; - self.bind(transitionEnd, cb); - } else { - // Fallback to timers if the 'transitionend' event isn't supported. - window.setTimeout(cb, i); - } - - // Apply transitions. - self.each(function() { - if (i > 0) { - this.style[support.transition] = transitionValue; - } - $(this).css(properties); - }); - }; - - // Defer running. This allows the browser to paint any pending CSS it hasn't - // painted yet before doing the transitions. - var deferredRun = function(next) { - var i = 0; - - // Durations that are too slow will get transitions mixed up. - // (Tested on Mac/FF 7.0.1) - if ((support.transition === 'MozTransition') && (i < 25)) { i = 25; } - - window.setTimeout(function() { run(next); }, i); - }; - - // Use jQuery's fx queue. - callOrQueue(self, queue, deferredRun); - - // Chainability. - return this; - }; - - function registerCssHook(prop, isPixels) { - // For certain properties, the 'px' should not be implied. - if (!isPixels) { $.cssNumber[prop] = true; } - - $.transit.propertyMap[prop] = support.transform; - - $.cssHooks[prop] = { - get: function(elem) { - var t = $(elem).css('transform') || new Transform(); - return t.get(prop); - }, - - set: function(elem, value) { - var t = $(elem).css('transform') || new Transform(); - t.setFromString(prop, value); - - $(elem).css({ transform: t }); - } - }; - } - - // ### uncamel(str) - // Converts a camelcase string to a dasherized string. - // (`marginLeft` => `margin-left`) - function uncamel(str) { - return str.replace(/([A-Z])/g, function(letter) { return '-' + letter.toLowerCase(); }); - } - - // ### unit(number, unit) - // Ensures that number `number` has a unit. If no unit is found, assume the - // default is `unit`. - // - // unit(2, 'px') //=> "2px" - // unit("30deg", 'rad') //=> "30deg" - // - function unit(i, units) { - if ((typeof i === "string") && (!i.match(/^[\-0-9\.]+$/))) { - return i; - } else { - return "" + i + units; - } - } - - // ### toMS(duration) - // Converts given `duration` to a millisecond string. - // - // toMS('fast') //=> '400ms' - // toMS(10) //=> '10ms' - // - function toMS(duration) { - var i = duration; - - // Allow for string durations like 'fast'. - if ($.fx.speeds[i]) { i = $.fx.speeds[i]; } - - return unit(i, 'ms'); - } - - // Export some functions for testable-ness. - $.transit.getTransitionValue = getTransition; -})(jQuery); diff --git a/sites/all/themes/gui/materiobasetheme/js/libs/jquery.transit.min.js b/sites/all/themes/gui/materiobasetheme/js/libs/jquery.transit.min.js deleted file mode 100644 index d05da6d7..00000000 --- a/sites/all/themes/gui/materiobasetheme/js/libs/jquery.transit.min.js +++ /dev/null @@ -1,20 +0,0 @@ -/*! - * jQuery Transit - CSS3 transitions and transformations - * Copyright(c) 2011 Rico Sta. Cruz - * MIT Licensed. - * - * http://ricostacruz.com/jquery.transit - * http://github.com/rstacruz/jquery.transit - */ -(function(d){function k(a){var b=["Moz","Webkit","O","ms"],c=a.charAt(0).toUpperCase()+a.substr(1);if(a in i.style)return a;for(a=0;a=b;++b)a[b]&&(a[b]=parseFloat(a[b]));a[3]&&(a[3]=g(a[3],"deg"));return a}},parse:function(a){var b=this;a.replace(/([a-zA-Z0-9]+)\((.*?)\)/g,function(a,d, -e){b.setFromString(d,e)})},toString:function(a){var b=[],c;for(c in this)if(this.hasOwnProperty(c)&&(e.transform3d||!("rotateX"===c||"rotateY"===c||"perspective"===c||"transformOrigin"===c)))"_"!==c[0]&&(a&&"scale"===c?b.push(c+"3d("+this[c]+",1)"):a&&"translate"===c?b.push(c+"3d("+this[c]+",0)"):b.push(c+"("+this[c]+")"));return b.join(" ")}};d.fn.transition=d.fn.transit=function(a,b,c,f){var h=this,g=0,i=!0;"function"===typeof b&&(f=b,b=void 0);"function"===typeof c&&(f=c,c=void 0);"undefined"!== -typeof a.easing&&(c=a.easing,delete a.easing);"undefined"!==typeof a.duration&&(b=a.duration,delete a.duration);"undefined"!==typeof a.complete&&(f=a.complete,delete a.complete);"undefined"!==typeof a.queue&&(i=a.queue,delete a.queue);"undefined"!==typeof a.delay&&(g=a.delay,delete a.delay);"undefined"===typeof b&&(b=d.fx.speeds._default);"undefined"===typeof c&&(c=d.cssEase._default);var b=n(b),j=q(a,b,c,g),l=d.transit.enabled&&e.transition?parseInt(b,10)+parseInt(g,10):0;if(0===l)return p(h,i,function(b){h.css(a); -f&&f.apply(h);b&&b()}),h;var k={},m=function(b){var c=false,g=function(){c&&h.unbind(o,g);l>0&&h.each(function(){this.style[e.transition]=k[this]||null});typeof f==="function"&&f.apply(h);typeof b==="function"&&b()};if(l>0&&o&&d.transit.useTransitionEnd){c=true;h.bind(o,g)}else window.setTimeout(g,l);h.each(function(){l>0&&(this.style[e.transition]=j);d(this).css(a)})};p(h,i,function(a){var b=0;e.transition==="MozTransition"&&b<25&&(b=25);window.setTimeout(function(){m(a)},b)});return this};d.transit.getTransitionValue= -q})(jQuery); diff --git a/sites/all/themes/gui/materiobasetheme/js/libs/modernizr-2.6.1.min.js b/sites/all/themes/gui/materiobasetheme/js/libs/modernizr-2.6.1.min.js deleted file mode 100644 index 52b523fa..00000000 --- a/sites/all/themes/gui/materiobasetheme/js/libs/modernizr-2.6.1.min.js +++ /dev/null @@ -1,4 +0,0 @@ -/* Modernizr 2.6.1 (Custom Build) | MIT & BSD - * Build: http://modernizr.com/download/#-fontface-backgroundsize-borderimage-borderradius-boxshadow-flexbox-hsla-multiplebgs-opacity-rgba-textshadow-cssanimations-csscolumns-generatedcontent-cssgradients-cssreflections-csstransforms-csstransforms3d-csstransitions-applicationcache-canvas-canvastext-draganddrop-hashchange-history-audio-video-indexeddb-input-inputtypes-localstorage-postmessage-sessionstorage-websockets-websqldatabase-webworkers-geolocation-inlinesvg-smil-svg-svgclippaths-touch-webgl-shiv-mq-cssclasses-addtest-prefixed-teststyles-testprop-testallprops-hasevent-prefixes-domprefixes-load - */ -;window.Modernizr=function(a,b,c){function D(a){j.cssText=a}function E(a,b){return D(n.join(a+";")+(b||""))}function F(a,b){return typeof a===b}function G(a,b){return!!~(""+a).indexOf(b)}function H(a,b){for(var d in a){var e=a[d];if(!G(e,"-")&&j[e]!==c)return b=="pfx"?e:!0}return!1}function I(a,b,d){for(var e in a){var f=b[a[e]];if(f!==c)return d===!1?a[e]:F(f,"function")?f.bind(d||b):f}return!1}function J(a,b,c){var d=a.charAt(0).toUpperCase()+a.slice(1),e=(a+" "+p.join(d+" ")+d).split(" ");return F(b,"string")||F(b,"undefined")?H(e,b):(e=(a+" "+q.join(d+" ")+d).split(" "),I(e,b,c))}function K(){e.input=function(c){for(var d=0,e=c.length;d',a,""].join(""),k.id=h,(l?k:m).innerHTML+=f,m.appendChild(k),l||(m.style.background="",g.appendChild(m)),i=c(k,a),l?k.parentNode.removeChild(k):m.parentNode.removeChild(m),!!i},z=function(b){var c=a.matchMedia||a.msMatchMedia;if(c)return c(b).matches;var d;return y("@media "+b+" { #"+h+" { position: absolute; } }",function(b){d=(a.getComputedStyle?getComputedStyle(b,null):b.currentStyle)["position"]=="absolute"}),d},A=function(){function d(d,e){e=e||b.createElement(a[d]||"div"),d="on"+d;var f=d in e;return f||(e.setAttribute||(e=b.createElement("div")),e.setAttribute&&e.removeAttribute&&(e.setAttribute(d,""),f=F(e[d],"function"),F(e[d],"undefined")||(e[d]=c),e.removeAttribute(d))),e=null,f}var a={select:"input",change:"input",submit:"form",reset:"form",error:"img",load:"img",abort:"img"};return d}(),B={}.hasOwnProperty,C;!F(B,"undefined")&&!F(B.call,"undefined")?C=function(a,b){return B.call(a,b)}:C=function(a,b){return b in a&&F(a.constructor.prototype[b],"undefined")},Function.prototype.bind||(Function.prototype.bind=function(b){var c=this;if(typeof c!="function")throw new TypeError;var d=w.call(arguments,1),e=function(){if(this instanceof e){var a=function(){};a.prototype=c.prototype;var f=new a,g=c.apply(f,d.concat(w.call(arguments)));return Object(g)===g?g:f}return c.apply(b,d.concat(w.call(arguments)))};return e}),s.flexbox=function(){return J("flexWrap")},s.canvas=function(){var a=b.createElement("canvas");return!!a.getContext&&!!a.getContext("2d")},s.canvastext=function(){return!!e.canvas&&!!F(b.createElement("canvas").getContext("2d").fillText,"function")},s.webgl=function(){return!!a.WebGLRenderingContext},s.touch=function(){var c;return"ontouchstart"in a||a.DocumentTouch&&b instanceof DocumentTouch?c=!0:y(["@media (",n.join("touch-enabled),("),h,")","{#modernizr{top:9px;position:absolute}}"].join(""),function(a){c=a.offsetTop===9}),c},s.geolocation=function(){return"geolocation"in navigator},s.postmessage=function(){return!!a.postMessage},s.websqldatabase=function(){return!!a.openDatabase},s.indexedDB=function(){return!!J("indexedDB",a)},s.hashchange=function(){return A("hashchange",a)&&(b.documentMode===c||b.documentMode>7)},s.history=function(){return!!a.history&&!!history.pushState},s.draganddrop=function(){var a=b.createElement("div");return"draggable"in a||"ondragstart"in a&&"ondrop"in a},s.websockets=function(){return"WebSocket"in a||"MozWebSocket"in a},s.rgba=function(){return D("background-color:rgba(150,255,150,.5)"),G(j.backgroundColor,"rgba")},s.hsla=function(){return D("background-color:hsla(120,40%,100%,.5)"),G(j.backgroundColor,"rgba")||G(j.backgroundColor,"hsla")},s.multiplebgs=function(){return D("background:url(https://),url(https://),red url(https://)"),/(url\s*\(.*?){3}/.test(j.background)},s.backgroundsize=function(){return J("backgroundSize")},s.borderimage=function(){return J("borderImage")},s.borderradius=function(){return J("borderRadius")},s.boxshadow=function(){return J("boxShadow")},s.textshadow=function(){return b.createElement("div").style.textShadow===""},s.opacity=function(){return E("opacity:.55"),/^0.55$/.test(j.opacity)},s.cssanimations=function(){return J("animationName")},s.csscolumns=function(){return J("columnCount")},s.cssgradients=function(){var a="background-image:",b="gradient(linear,left top,right bottom,from(#9f9),to(white));",c="linear-gradient(left top,#9f9, white);";return D((a+"-webkit- ".split(" ").join(b+a)+n.join(c+a)).slice(0,-a.length)),G(j.backgroundImage,"gradient")},s.cssreflections=function(){return J("boxReflect")},s.csstransforms=function(){return!!J("transform")},s.csstransforms3d=function(){var a=!!J("perspective");return a&&"webkitPerspective"in g.style&&y("@media (transform-3d),(-webkit-transform-3d){#modernizr{left:9px;position:absolute;height:3px;}}",function(b,c){a=b.offsetLeft===9&&b.offsetHeight===3}),a},s.csstransitions=function(){return J("transition")},s.fontface=function(){var a;return y('@font-face {font-family:"font";src:url("https://")}',function(c,d){var e=b.getElementById("smodernizr"),f=e.sheet||e.styleSheet,g=f?f.cssRules&&f.cssRules[0]?f.cssRules[0].cssText:f.cssText||"":"";a=/src/i.test(g)&&g.indexOf(d.split(" ")[0])===0}),a},s.generatedcontent=function(){var a;return y(['#modernizr:after{content:"',l,'";visibility:hidden}'].join(""),function(b){a=b.offsetHeight>=1}),a},s.video=function(){var a=b.createElement("video"),c=!1;try{if(c=!!a.canPlayType)c=new Boolean(c),c.ogg=a.canPlayType('video/ogg; codecs="theora"').replace(/^no$/,""),c.h264=a.canPlayType('video/mp4; codecs="avc1.42E01E"').replace(/^no$/,""),c.webm=a.canPlayType('video/webm; codecs="vp8, vorbis"').replace(/^no$/,"")}catch(d){}return c},s.audio=function(){var a=b.createElement("audio"),c=!1;try{if(c=!!a.canPlayType)c=new Boolean(c),c.ogg=a.canPlayType('audio/ogg; codecs="vorbis"').replace(/^no$/,""),c.mp3=a.canPlayType("audio/mpeg;").replace(/^no$/,""),c.wav=a.canPlayType('audio/wav; codecs="1"').replace(/^no$/,""),c.m4a=(a.canPlayType("audio/x-m4a;")||a.canPlayType("audio/aac;")).replace(/^no$/,"")}catch(d){}return c},s.localstorage=function(){try{return localStorage.setItem(h,h),localStorage.removeItem(h),!0}catch(a){return!1}},s.sessionstorage=function(){try{return sessionStorage.setItem(h,h),sessionStorage.removeItem(h),!0}catch(a){return!1}},s.webworkers=function(){return!!a.Worker},s.applicationcache=function(){return!!a.applicationCache},s.svg=function(){return!!b.createElementNS&&!!b.createElementNS(r.svg,"svg").createSVGRect},s.inlinesvg=function(){var a=b.createElement("div");return a.innerHTML="",(a.firstChild&&a.firstChild.namespaceURI)==r.svg},s.smil=function(){return!!b.createElementNS&&/SVGAnimate/.test(m.call(b.createElementNS(r.svg,"animate")))},s.svgclippaths=function(){return!!b.createElementNS&&/SVGClipPath/.test(m.call(b.createElementNS(r.svg,"clipPath")))};for(var L in s)C(s,L)&&(x=L.toLowerCase(),e[x]=s[L](),v.push((e[x]?"":"no-")+x));return e.input||K(),e.addTest=function(a,b){if(typeof a=="object")for(var d in a)C(a,d)&&e.addTest(d,a[d]);else{a=a.toLowerCase();if(e[a]!==c)return e;b=typeof b=="function"?b():b,f&&(g.className+=" "+(b?"":"no-")+a),e[a]=b}return e},D(""),i=k=null,function(a,b){function k(a,b){var c=a.createElement("p"),d=a.getElementsByTagName("head")[0]||a.documentElement;return c.innerHTML="x",d.insertBefore(c.lastChild,d.firstChild)}function l(){var a=r.elements;return typeof a=="string"?a.split(" "):a}function m(a){var b=i[a[g]];return b||(b={},h++,a[g]=h,i[h]=b),b}function n(a,c,f){c||(c=b);if(j)return c.createElement(a);f||(f=m(c));var g;return f.cache[a]?g=f.cache[a].cloneNode():e.test(a)?g=(f.cache[a]=f.createElem(a)).cloneNode():g=f.createElem(a),g.canHaveChildren&&!d.test(a)?f.frag.appendChild(g):g}function o(a,c){a||(a=b);if(j)return a.createDocumentFragment();c=c||m(a);var d=c.frag.cloneNode(),e=0,f=l(),g=f.length;for(;e",f="hidden"in a,j=a.childNodes.length==1||function(){b.createElement("a");var a=b.createDocumentFragment();return typeof a.cloneNode=="undefined"||typeof a.createDocumentFragment=="undefined"||typeof a.createElement=="undefined"}()}catch(c){f=!0,j=!0}})();var r={elements:c.elements||"abbr article aside audio bdi canvas data datalist details figcaption figure footer header hgroup mark meter nav output progress section summary time video",shivCSS:c.shivCSS!==!1,supportsUnknownElements:j,shivMethods:c.shivMethods!==!1,type:"default",shivDocument:q,createElement:n,createDocumentFragment:o};a.html5=r,q(b)}(this,b),e._version=d,e._prefixes=n,e._domPrefixes=q,e._cssomPrefixes=p,e.mq=z,e.hasEvent=A,e.testProp=function(a){return H([a])},e.testAllProps=J,e.testStyles=y,e.prefixed=function(a,b,c){return b?J(a,b,c):J(a,"pfx")},g.className=g.className.replace(/(^|\s)no-js(\s|$)/,"$1$2")+(f?" js "+v.join(" "):""),e}(this,this.document),function(a,b,c){function d(a){return o.call(a)=="[object Function]"}function e(a){return typeof a=="string"}function f(){}function g(a){return!a||a=="loaded"||a=="complete"||a=="uninitialized"}function h(){var a=p.shift();q=1,a?a.t?m(function(){(a.t=="c"?B.injectCss:B.injectJs)(a.s,0,a.a,a.x,a.e,1)},0):(a(),h()):q=0}function i(a,c,d,e,f,i,j){function k(b){if(!o&&g(l.readyState)&&(u.r=o=1,!q&&h(),l.onload=l.onreadystatechange=null,b)){a!="img"&&m(function(){t.removeChild(l)},50);for(var d in y[c])y[c].hasOwnProperty(d)&&y[c][d].onload()}}var j=j||B.errorTimeout,l={},o=0,r=0,u={t:d,s:c,e:f,a:i,x:j};y[c]===1&&(r=1,y[c]=[],l=b.createElement(a)),a=="object"?l.data=c:(l.src=c,l.type=a),l.width=l.height="0",l.onerror=l.onload=l.onreadystatechange=function(){k.call(this,r)},p.splice(e,0,u),a!="img"&&(r||y[c]===2?(t.insertBefore(l,s?null:n),m(k,j)):y[c].push(l))}function j(a,b,c,d,f){return q=0,b=b||"j",e(a)?i(b=="c"?v:u,a,b,this.i++,c,d,f):(p.splice(this.i++,0,a),p.length==1&&h()),this}function k(){var a=B;return a.loader={load:j,i:0},a}var l=b.documentElement,m=a.setTimeout,n=b.getElementsByTagName("script")[0],o={}.toString,p=[],q=0,r="MozAppearance"in l.style,s=r&&!!b.createRange().compareNode,t=s?l:n.parentNode,l=a.opera&&o.call(a.opera)=="[object Opera]",l=!!b.attachEvent&&!l,u=r?"object":l?"script":"img",v=l?"script":u,w=Array.isArray||function(a){return o.call(a)=="[object Array]"},x=[],y={},z={timeout:function(a,b){return b.length&&(a.timeout=b[0]),a}},A,B;B=function(a){function b(a){var a=a.split("!"),b=x.length,c=a.pop(),d=a.length,c={url:c,origUrl:c,prefixes:a},e,f,g;for(f=0;f\"\'\`]/.test(text)) { - return text; - } - map = { - "<": "<", - ">": ">", - '"': """, - "'": "'", - "`": "`" - }; - unsafe_chars = /&(?!\w+;)|[\<\>\"\'\`]/g; - return text.replace(unsafe_chars, function(chr) { - return map[chr] || "&"; - }); - }; - - return SelectParser; - - })(); - - SelectParser.select_to_array = function(select) { - var child, parser, _i, _len, _ref; - parser = new SelectParser(); - _ref = select.childNodes; - for (_i = 0, _len = _ref.length; _i < _len; _i++) { - child = _ref[_i]; - parser.add_node(child); - } - return parser.parsed; - }; - - AbstractChosen = (function() { - function AbstractChosen(form_field, options) { - this.form_field = form_field; - this.options = options != null ? options : {}; - if (!AbstractChosen.browser_is_supported()) { - return; - } - this.is_multiple = this.form_field.multiple; - this.set_default_text(); - this.set_default_values(); - this.setup(); - this.set_up_html(); - this.register_observers(); - } - - AbstractChosen.prototype.set_default_values = function() { - var _this = this; - this.click_test_action = function(evt) { - return _this.test_active_click(evt); - }; - this.activate_action = function(evt) { - return _this.activate_field(evt); - }; - this.active_field = false; - this.mouse_on_container = false; - this.results_showing = false; - this.result_highlighted = null; - this.allow_single_deselect = (this.options.allow_single_deselect != null) && (this.form_field.options[0] != null) && this.form_field.options[0].text === "" ? this.options.allow_single_deselect : false; - this.disable_search_threshold = this.options.disable_search_threshold || 0; - this.disable_search = this.options.disable_search || false; - this.enable_split_word_search = this.options.enable_split_word_search != null ? this.options.enable_split_word_search : true; - this.group_search = this.options.group_search != null ? this.options.group_search : true; - this.search_contains = this.options.search_contains || false; - this.single_backstroke_delete = this.options.single_backstroke_delete != null ? this.options.single_backstroke_delete : true; - this.max_selected_options = this.options.max_selected_options || Infinity; - this.inherit_select_classes = this.options.inherit_select_classes || false; - this.display_selected_options = this.options.display_selected_options != null ? this.options.display_selected_options : true; - return this.display_disabled_options = this.options.display_disabled_options != null ? this.options.display_disabled_options : true; - }; - - AbstractChosen.prototype.set_default_text = function() { - if (this.form_field.getAttribute("data-placeholder")) { - this.default_text = this.form_field.getAttribute("data-placeholder"); - } else if (this.is_multiple) { - this.default_text = this.options.placeholder_text_multiple || this.options.placeholder_text || AbstractChosen.default_multiple_text; - } else { - this.default_text = this.options.placeholder_text_single || this.options.placeholder_text || AbstractChosen.default_single_text; - } - return this.results_none_found = this.form_field.getAttribute("data-no_results_text") || this.options.no_results_text || AbstractChosen.default_no_result_text; - }; - - AbstractChosen.prototype.mouse_enter = function() { - return this.mouse_on_container = true; - }; - - AbstractChosen.prototype.mouse_leave = function() { - return this.mouse_on_container = false; - }; - - AbstractChosen.prototype.input_focus = function(evt) { - var _this = this; - if (this.is_multiple) { - if (!this.active_field) { - return setTimeout((function() { - return _this.container_mousedown(); - }), 50); - } - } else { - if (!this.active_field) { - return this.activate_field(); - } - } - }; - - AbstractChosen.prototype.input_blur = function(evt) { - var _this = this; - if (!this.mouse_on_container) { - this.active_field = false; - return setTimeout((function() { - return _this.blur_test(); - }), 100); - } - }; - - AbstractChosen.prototype.results_option_build = function(options) { - var content, data, _i, _len, _ref; - content = ''; - _ref = this.results_data; - for (_i = 0, _len = _ref.length; _i < _len; _i++) { - data = _ref[_i]; - if (data.group) { - content += this.result_add_group(data); - } else { - content += this.result_add_option(data); - } - if (options != null ? options.first : void 0) { - if (data.selected && this.is_multiple) { - this.choice_build(data); - } else if (data.selected && !this.is_multiple) { - this.single_set_selected_text(data.text); - } - } - } - return content; - }; - - AbstractChosen.prototype.result_add_option = function(option) { - var classes, option_el; - if (!option.search_match) { - return ''; - } - if (!this.include_option_in_results(option)) { - return ''; - } - classes = []; - if (!option.disabled && !(option.selected && this.is_multiple)) { - classes.push("active-result"); - } - if (option.disabled && !(option.selected && this.is_multiple)) { - classes.push("disabled-result"); - } - if (option.selected) { - classes.push("result-selected"); - } - if (option.group_array_index != null) { - classes.push("group-option"); - } - if (option.classes !== "") { - classes.push(option.classes); - } - option_el = document.createElement("li"); - option_el.className = classes.join(" "); - option_el.style.cssText = option.style; - option_el.setAttribute("data-option-array-index", option.array_index); - option_el.innerHTML = option.search_text; - return this.outerHTML(option_el); - }; - - AbstractChosen.prototype.result_add_group = function(group) { - var group_el; - if (!(group.search_match || group.group_match)) { - return ''; - } - if (!(group.active_options > 0)) { - return ''; - } - group_el = document.createElement("li"); - group_el.className = "group-result"; - group_el.innerHTML = group.search_text; - return this.outerHTML(group_el); - }; - - AbstractChosen.prototype.results_update_field = function() { - this.set_default_text(); - if (!this.is_multiple) { - this.results_reset_cleanup(); - } - this.result_clear_highlight(); - this.results_build(); - if (this.results_showing) { - return this.winnow_results(); - } - }; - - AbstractChosen.prototype.reset_single_select_options = function() { - var result, _i, _len, _ref, _results; - _ref = this.results_data; - _results = []; - for (_i = 0, _len = _ref.length; _i < _len; _i++) { - result = _ref[_i]; - if (result.selected) { - _results.push(result.selected = false); - } else { - _results.push(void 0); - } - } - return _results; - }; - - AbstractChosen.prototype.results_toggle = function() { - if (this.results_showing) { - return this.results_hide(); - } else { - return this.results_show(); - } - }; - - AbstractChosen.prototype.results_search = function(evt) { - if (this.results_showing) { - return this.winnow_results(); - } else { - return this.results_show(); - } - }; - - AbstractChosen.prototype.winnow_results = function() { - var escapedSearchText, option, regex, regexAnchor, results, results_group, searchText, startpos, text, zregex, _i, _len, _ref; - this.no_results_clear(); - results = 0; - searchText = this.get_search_text(); - escapedSearchText = searchText.replace(/[-[\]{}()*+?.,\\^$|#\s]/g, "\\$&"); - regexAnchor = this.search_contains ? "" : "^"; - regex = new RegExp(regexAnchor + escapedSearchText, 'i'); - zregex = new RegExp(escapedSearchText, 'i'); - _ref = this.results_data; - for (_i = 0, _len = _ref.length; _i < _len; _i++) { - option = _ref[_i]; - option.search_match = false; - results_group = null; - if (this.include_option_in_results(option)) { - if (option.group) { - option.group_match = false; - option.active_options = 0; - } - if ((option.group_array_index != null) && this.results_data[option.group_array_index]) { - results_group = this.results_data[option.group_array_index]; - if (results_group.active_options === 0 && results_group.search_match) { - results += 1; - } - results_group.active_options += 1; - } - if (!(option.group && !this.group_search)) { - option.search_text = option.group ? option.label : option.html; - option.search_match = this.search_string_match(option.search_text, regex); - if (option.search_match && !option.group) { - results += 1; - } - if (option.search_match) { - if (searchText.length) { - startpos = option.search_text.search(zregex); - text = option.search_text.substr(0, startpos + searchText.length) + '' + option.search_text.substr(startpos + searchText.length); - option.search_text = text.substr(0, startpos) + '' + text.substr(startpos); - } - if (results_group != null) { - results_group.group_match = true; - } - } else if ((option.group_array_index != null) && this.results_data[option.group_array_index].search_match) { - option.search_match = true; - } - } - } - } - this.result_clear_highlight(); - if (results < 1 && searchText.length) { - this.update_results_content(""); - return this.no_results(searchText); - } else { - this.update_results_content(this.results_option_build()); - return this.winnow_results_set_highlight(); - } - }; - - AbstractChosen.prototype.search_string_match = function(search_string, regex) { - var part, parts, _i, _len; - if (regex.test(search_string)) { - return true; - } else if (this.enable_split_word_search && (search_string.indexOf(" ") >= 0 || search_string.indexOf("[") === 0)) { - parts = search_string.replace(/\[|\]/g, "").split(" "); - if (parts.length) { - for (_i = 0, _len = parts.length; _i < _len; _i++) { - part = parts[_i]; - if (regex.test(part)) { - return true; - } - } - } - } - }; - - AbstractChosen.prototype.choices_count = function() { - var option, _i, _len, _ref; - if (this.selected_option_count != null) { - return this.selected_option_count; - } - this.selected_option_count = 0; - _ref = this.form_field.options; - for (_i = 0, _len = _ref.length; _i < _len; _i++) { - option = _ref[_i]; - if (option.selected) { - this.selected_option_count += 1; - } - } - return this.selected_option_count; - }; - - AbstractChosen.prototype.choices_click = function(evt) { - evt.preventDefault(); - if (!(this.results_showing || this.is_disabled)) { - return this.results_show(); - } - }; - - AbstractChosen.prototype.keyup_checker = function(evt) { - var stroke, _ref; - stroke = (_ref = evt.which) != null ? _ref : evt.keyCode; - this.search_field_scale(); - switch (stroke) { - case 8: - if (this.is_multiple && this.backstroke_length < 1 && this.choices_count() > 0) { - return this.keydown_backstroke(); - } else if (!this.pending_backstroke) { - this.result_clear_highlight(); - return this.results_search(); - } - break; - case 13: - evt.preventDefault(); - if (this.results_showing) { - return this.result_select(evt); - } - break; - case 27: - if (this.results_showing) { - this.results_hide(); - } - return true; - case 9: - case 38: - case 40: - case 16: - case 91: - case 17: - break; - default: - return this.results_search(); - } - }; - - AbstractChosen.prototype.clipboard_event_checker = function(evt) { - var _this = this; - return setTimeout((function() { - return _this.results_search(); - }), 50); - }; - - AbstractChosen.prototype.container_width = function() { - if (this.options.width != null) { - return this.options.width; - } else { - return "" + this.form_field.offsetWidth + "px"; - } - }; - - AbstractChosen.prototype.include_option_in_results = function(option) { - if (this.is_multiple && (!this.display_selected_options && option.selected)) { - return false; - } - if (!this.display_disabled_options && option.disabled) { - return false; - } - if (option.empty) { - return false; - } - return true; - }; - - AbstractChosen.prototype.search_results_touchstart = function(evt) { - this.touch_started = true; - return this.search_results_mouseover(evt); - }; - - AbstractChosen.prototype.search_results_touchmove = function(evt) { - this.touch_started = false; - return this.search_results_mouseout(evt); - }; - - AbstractChosen.prototype.search_results_touchend = function(evt) { - if (this.touch_started) { - return this.search_results_mouseup(evt); - } - }; - - AbstractChosen.prototype.outerHTML = function(element) { - var tmp; - if (element.outerHTML) { - return element.outerHTML; - } - tmp = document.createElement("div"); - tmp.appendChild(element); - return tmp.innerHTML; - }; - - AbstractChosen.browser_is_supported = function() { - if (window.navigator.appName === "Microsoft Internet Explorer") { - return document.documentMode >= 8; - } - if (/iP(od|hone)/i.test(window.navigator.userAgent)) { - return false; - } - if (/Android/i.test(window.navigator.userAgent)) { - if (/Mobile/i.test(window.navigator.userAgent)) { - return false; - } - } - return true; - }; - - AbstractChosen.default_multiple_text = "Select Some Options"; - - AbstractChosen.default_single_text = "Select an Option"; - - AbstractChosen.default_no_result_text = "No results match"; - - return AbstractChosen; - - })(); - - $ = jQuery; - - $.fn.extend({ - chosen: function(options) { - if (!AbstractChosen.browser_is_supported()) { - return this; - } - return this.each(function(input_field) { - var $this, chosen; - $this = $(this); - chosen = $this.data('chosen'); - if (options === 'destroy' && chosen) { - chosen.destroy(); - } else if (!chosen) { - $this.data('chosen', new Chosen(this, options)); - } - }); - } - }); - - Chosen = (function(_super) { - __extends(Chosen, _super); - - function Chosen() { - _ref = Chosen.__super__.constructor.apply(this, arguments); - return _ref; - } - - Chosen.prototype.setup = function() { - this.form_field_jq = $(this.form_field); - this.current_selectedIndex = this.form_field.selectedIndex; - return this.is_rtl = this.form_field_jq.hasClass("chosen-rtl"); - }; - - Chosen.prototype.set_up_html = function() { - var container_classes, container_props; - container_classes = ["chosen-container"]; - container_classes.push("chosen-container-" + (this.is_multiple ? "multi" : "single")); - if (this.inherit_select_classes && this.form_field.className) { - container_classes.push(this.form_field.className); - } - if (this.is_rtl) { - container_classes.push("chosen-rtl"); - } - container_props = { - 'class': container_classes.join(' '), - 'style': "width: " + (this.container_width()) + ";", - 'title': this.form_field.title - }; - if (this.form_field.id.length) { - container_props.id = this.form_field.id.replace(/[^\w]/g, '_') + "_chosen"; - } - this.container = $("
                                ", container_props); - if (this.is_multiple) { - this.container.html('
                                  '); - } else { - this.container.html('' + this.default_text + '
                                    '); - } - this.form_field_jq.hide().after(this.container); - this.dropdown = this.container.find('div.chosen-drop').first(); - this.search_field = this.container.find('input').first(); - this.search_results = this.container.find('ul.chosen-results').first(); - this.search_field_scale(); - this.search_no_results = this.container.find('li.no-results').first(); - if (this.is_multiple) { - this.search_choices = this.container.find('ul.chosen-choices').first(); - this.search_container = this.container.find('li.search-field').first(); - } else { - this.search_container = this.container.find('div.chosen-search').first(); - this.selected_item = this.container.find('.chosen-single').first(); - } - this.results_build(); - this.set_tab_index(); - this.set_label_behavior(); - return this.form_field_jq.trigger("chosen:ready", { - chosen: this - }); - }; - - Chosen.prototype.register_observers = function() { - var _this = this; - this.container.bind('mousedown.chosen', function(evt) { - _this.container_mousedown(evt); - }); - this.container.bind('mouseup.chosen', function(evt) { - _this.container_mouseup(evt); - }); - this.container.bind('mouseenter.chosen', function(evt) { - _this.mouse_enter(evt); - }); - this.container.bind('mouseleave.chosen', function(evt) { - _this.mouse_leave(evt); - }); - this.search_results.bind('mouseup.chosen', function(evt) { - _this.search_results_mouseup(evt); - }); - this.search_results.bind('mouseover.chosen', function(evt) { - _this.search_results_mouseover(evt); - }); - this.search_results.bind('mouseout.chosen', function(evt) { - _this.search_results_mouseout(evt); - }); - this.search_results.bind('mousewheel.chosen DOMMouseScroll.chosen', function(evt) { - _this.search_results_mousewheel(evt); - }); - this.search_results.bind('touchstart.chosen', function(evt) { - _this.search_results_touchstart(evt); - }); - this.search_results.bind('touchmove.chosen', function(evt) { - _this.search_results_touchmove(evt); - }); - this.search_results.bind('touchend.chosen', function(evt) { - _this.search_results_touchend(evt); - }); - this.form_field_jq.bind("chosen:updated.chosen", function(evt) { - _this.results_update_field(evt); - }); - this.form_field_jq.bind("chosen:activate.chosen", function(evt) { - _this.activate_field(evt); - }); - this.form_field_jq.bind("chosen:open.chosen", function(evt) { - _this.container_mousedown(evt); - }); - this.form_field_jq.bind("chosen:close.chosen", function(evt) { - _this.input_blur(evt); - }); - this.search_field.bind('blur.chosen', function(evt) { - _this.input_blur(evt); - }); - this.search_field.bind('keyup.chosen', function(evt) { - _this.keyup_checker(evt); - }); - this.search_field.bind('keydown.chosen', function(evt) { - _this.keydown_checker(evt); - }); - this.search_field.bind('focus.chosen', function(evt) { - _this.input_focus(evt); - }); - this.search_field.bind('cut.chosen', function(evt) { - _this.clipboard_event_checker(evt); - }); - this.search_field.bind('paste.chosen', function(evt) { - _this.clipboard_event_checker(evt); - }); - if (this.is_multiple) { - return this.search_choices.bind('click.chosen', function(evt) { - _this.choices_click(evt); - }); - } else { - return this.container.bind('click.chosen', function(evt) { - evt.preventDefault(); - }); - } - }; - - Chosen.prototype.destroy = function() { - $(this.container[0].ownerDocument).unbind("click.chosen", this.click_test_action); - if (this.search_field[0].tabIndex) { - this.form_field_jq[0].tabIndex = this.search_field[0].tabIndex; - } - this.container.remove(); - this.form_field_jq.removeData('chosen'); - return this.form_field_jq.show(); - }; - - Chosen.prototype.search_field_disabled = function() { - this.is_disabled = this.form_field_jq[0].disabled; - if (this.is_disabled) { - this.container.addClass('chosen-disabled'); - this.search_field[0].disabled = true; - if (!this.is_multiple) { - this.selected_item.unbind("focus.chosen", this.activate_action); - } - return this.close_field(); - } else { - this.container.removeClass('chosen-disabled'); - this.search_field[0].disabled = false; - if (!this.is_multiple) { - return this.selected_item.bind("focus.chosen", this.activate_action); - } - } - }; - - Chosen.prototype.container_mousedown = function(evt) { - if (!this.is_disabled) { - if (evt && evt.type === "mousedown" && !this.results_showing) { - evt.preventDefault(); - } - if (!((evt != null) && ($(evt.target)).hasClass("search-choice-close"))) { - if (!this.active_field) { - if (this.is_multiple) { - this.search_field.val(""); - } - $(this.container[0].ownerDocument).bind('click.chosen', this.click_test_action); - this.results_show(); - } else if (!this.is_multiple && evt && (($(evt.target)[0] === this.selected_item[0]) || $(evt.target).parents("a.chosen-single").length)) { - evt.preventDefault(); - this.results_toggle(); - } - return this.activate_field(); - } - } - }; - - Chosen.prototype.container_mouseup = function(evt) { - if (evt.target.nodeName === "ABBR" && !this.is_disabled) { - return this.results_reset(evt); - } - }; - - Chosen.prototype.search_results_mousewheel = function(evt) { - var delta; - if (evt.originalEvent) { - delta = -evt.originalEvent.wheelDelta || evt.originalEvent.detail; - } - if (delta != null) { - evt.preventDefault(); - if (evt.type === 'DOMMouseScroll') { - delta = delta * 40; - } - return this.search_results.scrollTop(delta + this.search_results.scrollTop()); - } - }; - - Chosen.prototype.blur_test = function(evt) { - if (!this.active_field && this.container.hasClass("chosen-container-active")) { - return this.close_field(); - } - }; - - Chosen.prototype.close_field = function() { - $(this.container[0].ownerDocument).unbind("click.chosen", this.click_test_action); - this.active_field = false; - this.results_hide(); - this.container.removeClass("chosen-container-active"); - this.clear_backstroke(); - this.show_search_field_default(); - return this.search_field_scale(); - }; - - Chosen.prototype.activate_field = function() { - this.container.addClass("chosen-container-active"); - this.active_field = true; - this.search_field.val(this.search_field.val()); - return this.search_field.focus(); - }; - - Chosen.prototype.test_active_click = function(evt) { - var active_container; - active_container = $(evt.target).closest('.chosen-container'); - if (active_container.length && this.container[0] === active_container[0]) { - return this.active_field = true; - } else { - return this.close_field(); - } - }; - - Chosen.prototype.results_build = function() { - this.parsing = true; - this.selected_option_count = null; - this.results_data = SelectParser.select_to_array(this.form_field); - if (this.is_multiple) { - this.search_choices.find("li.search-choice").remove(); - } else if (!this.is_multiple) { - this.single_set_selected_text(); - if (this.disable_search || this.form_field.options.length <= this.disable_search_threshold) { - this.search_field[0].readOnly = true; - this.container.addClass("chosen-container-single-nosearch"); - } else { - this.search_field[0].readOnly = false; - this.container.removeClass("chosen-container-single-nosearch"); - } - } - this.update_results_content(this.results_option_build({ - first: true - })); - this.search_field_disabled(); - this.show_search_field_default(); - this.search_field_scale(); - return this.parsing = false; - }; - - Chosen.prototype.result_do_highlight = function(el) { - var high_bottom, high_top, maxHeight, visible_bottom, visible_top; - if (el.length) { - this.result_clear_highlight(); - this.result_highlight = el; - this.result_highlight.addClass("highlighted"); - maxHeight = parseInt(this.search_results.css("maxHeight"), 10); - visible_top = this.search_results.scrollTop(); - visible_bottom = maxHeight + visible_top; - high_top = this.result_highlight.position().top + this.search_results.scrollTop(); - high_bottom = high_top + this.result_highlight.outerHeight(); - if (high_bottom >= visible_bottom) { - return this.search_results.scrollTop((high_bottom - maxHeight) > 0 ? high_bottom - maxHeight : 0); - } else if (high_top < visible_top) { - return this.search_results.scrollTop(high_top); - } - } - }; - - Chosen.prototype.result_clear_highlight = function() { - if (this.result_highlight) { - this.result_highlight.removeClass("highlighted"); - } - return this.result_highlight = null; - }; - - Chosen.prototype.results_show = function() { - if (this.is_multiple && this.max_selected_options <= this.choices_count()) { - this.form_field_jq.trigger("chosen:maxselected", { - chosen: this - }); - return false; - } - this.container.addClass("chosen-with-drop"); - this.results_showing = true; - this.search_field.focus(); - this.search_field.val(this.search_field.val()); - this.winnow_results(); - return this.form_field_jq.trigger("chosen:showing_dropdown", { - chosen: this - }); - }; - - Chosen.prototype.update_results_content = function(content) { - return this.search_results.html(content); - }; - - Chosen.prototype.results_hide = function() { - if (this.results_showing) { - this.result_clear_highlight(); - this.container.removeClass("chosen-with-drop"); - this.form_field_jq.trigger("chosen:hiding_dropdown", { - chosen: this - }); - } - return this.results_showing = false; - }; - - Chosen.prototype.set_tab_index = function(el) { - var ti; - if (this.form_field.tabIndex) { - ti = this.form_field.tabIndex; - this.form_field.tabIndex = -1; - return this.search_field[0].tabIndex = ti; - } - }; - - Chosen.prototype.set_label_behavior = function() { - var _this = this; - this.form_field_label = this.form_field_jq.parents("label"); - if (!this.form_field_label.length && this.form_field.id.length) { - this.form_field_label = $("label[for='" + this.form_field.id + "']"); - } - if (this.form_field_label.length > 0) { - return this.form_field_label.bind('click.chosen', function(evt) { - if (_this.is_multiple) { - return _this.container_mousedown(evt); - } else { - return _this.activate_field(); - } - }); - } - }; - - Chosen.prototype.show_search_field_default = function() { - if (this.is_multiple && this.choices_count() < 1 && !this.active_field) { - this.search_field.val(this.default_text); - return this.search_field.addClass("default"); - } else { - this.search_field.val(""); - return this.search_field.removeClass("default"); - } - }; - - Chosen.prototype.search_results_mouseup = function(evt) { - var target; - target = $(evt.target).hasClass("active-result") ? $(evt.target) : $(evt.target).parents(".active-result").first(); - if (target.length) { - this.result_highlight = target; - this.result_select(evt); - return this.search_field.focus(); - } - }; - - Chosen.prototype.search_results_mouseover = function(evt) { - var target; - target = $(evt.target).hasClass("active-result") ? $(evt.target) : $(evt.target).parents(".active-result").first(); - if (target) { - return this.result_do_highlight(target); - } - }; - - Chosen.prototype.search_results_mouseout = function(evt) { - if ($(evt.target).hasClass("active-result" || $(evt.target).parents('.active-result').first())) { - return this.result_clear_highlight(); - } - }; - - Chosen.prototype.choice_build = function(item) { - var choice, close_link, - _this = this; - choice = $('
                                  • ', { - "class": "search-choice" - }).html("" + item.html + ""); - if (item.disabled) { - choice.addClass('search-choice-disabled'); - } else { - close_link = $('', { - "class": 'search-choice-close', - 'data-option-array-index': item.array_index - }); - close_link.bind('click.chosen', function(evt) { - return _this.choice_destroy_link_click(evt); - }); - choice.append(close_link); - } - return this.search_container.before(choice); - }; - - Chosen.prototype.choice_destroy_link_click = function(evt) { - evt.preventDefault(); - evt.stopPropagation(); - if (!this.is_disabled) { - return this.choice_destroy($(evt.target)); - } - }; - - Chosen.prototype.choice_destroy = function(link) { - if (this.result_deselect(link[0].getAttribute("data-option-array-index"))) { - this.show_search_field_default(); - if (this.is_multiple && this.choices_count() > 0 && this.search_field.val().length < 1) { - this.results_hide(); - } - link.parents('li').first().remove(); - return this.search_field_scale(); - } - }; - - Chosen.prototype.results_reset = function() { - this.reset_single_select_options(); - this.form_field.options[0].selected = true; - this.single_set_selected_text(); - this.show_search_field_default(); - this.results_reset_cleanup(); - this.form_field_jq.trigger("change"); - if (this.active_field) { - return this.results_hide(); - } - }; - - Chosen.prototype.results_reset_cleanup = function() { - this.current_selectedIndex = this.form_field.selectedIndex; - return this.selected_item.find("abbr").remove(); - }; - - Chosen.prototype.result_select = function(evt) { - var high, item; - if (this.result_highlight) { - high = this.result_highlight; - this.result_clear_highlight(); - if (this.is_multiple && this.max_selected_options <= this.choices_count()) { - this.form_field_jq.trigger("chosen:maxselected", { - chosen: this - }); - return false; - } - if (this.is_multiple) { - high.removeClass("active-result"); - } else { - this.reset_single_select_options(); - } - item = this.results_data[high[0].getAttribute("data-option-array-index")]; - item.selected = true; - this.form_field.options[item.options_index].selected = true; - this.selected_option_count = null; - if (this.is_multiple) { - this.choice_build(item); - } else { - this.single_set_selected_text(item.text); - } - if (!((evt.metaKey || evt.ctrlKey) && this.is_multiple)) { - this.results_hide(); - } - this.search_field.val(""); - if (this.is_multiple || this.form_field.selectedIndex !== this.current_selectedIndex) { - this.form_field_jq.trigger("change", { - 'selected': this.form_field.options[item.options_index].value - }); - } - this.current_selectedIndex = this.form_field.selectedIndex; - return this.search_field_scale(); - } - }; - - Chosen.prototype.single_set_selected_text = function(text) { - if (text == null) { - text = this.default_text; - } - if (text === this.default_text) { - this.selected_item.addClass("chosen-default"); - } else { - this.single_deselect_control_build(); - this.selected_item.removeClass("chosen-default"); - } - return this.selected_item.find("span").text(text); - }; - - Chosen.prototype.result_deselect = function(pos) { - var result_data; - result_data = this.results_data[pos]; - if (!this.form_field.options[result_data.options_index].disabled) { - result_data.selected = false; - this.form_field.options[result_data.options_index].selected = false; - this.selected_option_count = null; - this.result_clear_highlight(); - if (this.results_showing) { - this.winnow_results(); - } - this.form_field_jq.trigger("change", { - deselected: this.form_field.options[result_data.options_index].value - }); - this.search_field_scale(); - return true; - } else { - return false; - } - }; - - Chosen.prototype.single_deselect_control_build = function() { - if (!this.allow_single_deselect) { - return; - } - if (!this.selected_item.find("abbr").length) { - this.selected_item.find("span").first().after(""); - } - return this.selected_item.addClass("chosen-single-with-deselect"); - }; - - Chosen.prototype.get_search_text = function() { - if (this.search_field.val() === this.default_text) { - return ""; - } else { - return $('
                                    ').text($.trim(this.search_field.val())).html(); - } - }; - - Chosen.prototype.winnow_results_set_highlight = function() { - var do_high, selected_results; - selected_results = !this.is_multiple ? this.search_results.find(".result-selected.active-result") : []; - do_high = selected_results.length ? selected_results.first() : this.search_results.find(".active-result").first(); - if (do_high != null) { - return this.result_do_highlight(do_high); - } - }; - - Chosen.prototype.no_results = function(terms) { - var no_results_html; - no_results_html = $('
                                  • ' + this.results_none_found + ' ""
                                  • '); - no_results_html.find("span").first().html(terms); - this.search_results.append(no_results_html); - return this.form_field_jq.trigger("chosen:no_results", { - chosen: this - }); - }; - - Chosen.prototype.no_results_clear = function() { - return this.search_results.find(".no-results").remove(); - }; - - Chosen.prototype.keydown_arrow = function() { - var next_sib; - if (this.results_showing && this.result_highlight) { - next_sib = this.result_highlight.nextAll("li.active-result").first(); - if (next_sib) { - return this.result_do_highlight(next_sib); - } - } else { - return this.results_show(); - } - }; - - Chosen.prototype.keyup_arrow = function() { - var prev_sibs; - if (!this.results_showing && !this.is_multiple) { - return this.results_show(); - } else if (this.result_highlight) { - prev_sibs = this.result_highlight.prevAll("li.active-result"); - if (prev_sibs.length) { - return this.result_do_highlight(prev_sibs.first()); - } else { - if (this.choices_count() > 0) { - this.results_hide(); - } - return this.result_clear_highlight(); - } - } - }; - - Chosen.prototype.keydown_backstroke = function() { - var next_available_destroy; - if (this.pending_backstroke) { - this.choice_destroy(this.pending_backstroke.find("a").first()); - return this.clear_backstroke(); - } else { - next_available_destroy = this.search_container.siblings("li.search-choice").last(); - if (next_available_destroy.length && !next_available_destroy.hasClass("search-choice-disabled")) { - this.pending_backstroke = next_available_destroy; - if (this.single_backstroke_delete) { - return this.keydown_backstroke(); - } else { - return this.pending_backstroke.addClass("search-choice-focus"); - } - } - } - }; - - Chosen.prototype.clear_backstroke = function() { - if (this.pending_backstroke) { - this.pending_backstroke.removeClass("search-choice-focus"); - } - return this.pending_backstroke = null; - }; - - Chosen.prototype.keydown_checker = function(evt) { - var stroke, _ref1; - stroke = (_ref1 = evt.which) != null ? _ref1 : evt.keyCode; - this.search_field_scale(); - if (stroke !== 8 && this.pending_backstroke) { - this.clear_backstroke(); - } - switch (stroke) { - case 8: - this.backstroke_length = this.search_field.val().length; - break; - case 9: - if (this.results_showing && !this.is_multiple) { - this.result_select(evt); - } - this.mouse_on_container = false; - break; - case 13: - evt.preventDefault(); - break; - case 38: - evt.preventDefault(); - this.keyup_arrow(); - break; - case 40: - evt.preventDefault(); - this.keydown_arrow(); - break; - } - }; - - Chosen.prototype.search_field_scale = function() { - var div, f_width, h, style, style_block, styles, w, _i, _len; - if (this.is_multiple) { - h = 0; - w = 0; - style_block = "position:absolute; left: -1000px; top: -1000px; display:none;"; - styles = ['font-size', 'font-style', 'font-weight', 'font-family', 'line-height', 'text-transform', 'letter-spacing']; - for (_i = 0, _len = styles.length; _i < _len; _i++) { - style = styles[_i]; - style_block += style + ":" + this.search_field.css(style) + ";"; - } - div = $('
                                    ', { - 'style': style_block - }); - div.text(this.search_field.val()); - $('body').append(div); - w = div.width() + 25; - div.remove(); - f_width = this.container.outerWidth(); - if (w > f_width - 10) { - w = f_width - 10; - } - return this.search_field.css({ - 'width': w + 'px' - }); - } - }; - - return Chosen; - - })(AbstractChosen); - -}).call(this); diff --git a/sites/all/themes/gui/materiobasetheme/js/libs/src/chosen_v1.1.0/chosen.jquery.min.js b/sites/all/themes/gui/materiobasetheme/js/libs/src/chosen_v1.1.0/chosen.jquery.min.js deleted file mode 100644 index cece231b..00000000 --- a/sites/all/themes/gui/materiobasetheme/js/libs/src/chosen_v1.1.0/chosen.jquery.min.js +++ /dev/null @@ -1,2 +0,0 @@ -/* Chosen v1.1.0 | (c) 2011-2013 by Harvest | MIT License, https://github.com/harvesthq/chosen/blob/master/LICENSE.md */ -!function(){var a,AbstractChosen,Chosen,SelectParser,b,c={}.hasOwnProperty,d=function(a,b){function d(){this.constructor=a}for(var e in b)c.call(b,e)&&(a[e]=b[e]);return d.prototype=b.prototype,a.prototype=new d,a.__super__=b.prototype,a};SelectParser=function(){function SelectParser(){this.options_index=0,this.parsed=[]}return SelectParser.prototype.add_node=function(a){return"OPTGROUP"===a.nodeName.toUpperCase()?this.add_group(a):this.add_option(a)},SelectParser.prototype.add_group=function(a){var b,c,d,e,f,g;for(b=this.parsed.length,this.parsed.push({array_index:b,group:!0,label:this.escapeExpression(a.label),children:0,disabled:a.disabled}),f=a.childNodes,g=[],d=0,e=f.length;e>d;d++)c=f[d],g.push(this.add_option(c,b,a.disabled));return g},SelectParser.prototype.add_option=function(a,b,c){return"OPTION"===a.nodeName.toUpperCase()?(""!==a.text?(null!=b&&(this.parsed[b].children+=1),this.parsed.push({array_index:this.parsed.length,options_index:this.options_index,value:a.value,text:a.text,html:a.innerHTML,selected:a.selected,disabled:c===!0?c:a.disabled,group_array_index:b,classes:a.className,style:a.style.cssText})):this.parsed.push({array_index:this.parsed.length,options_index:this.options_index,empty:!0}),this.options_index+=1):void 0},SelectParser.prototype.escapeExpression=function(a){var b,c;return null==a||a===!1?"":/[\&\<\>\"\'\`]/.test(a)?(b={"<":"<",">":">",'"':""","'":"'","`":"`"},c=/&(?!\w+;)|[\<\>\"\'\`]/g,a.replace(c,function(a){return b[a]||"&"})):a},SelectParser}(),SelectParser.select_to_array=function(a){var b,c,d,e,f;for(c=new SelectParser,f=a.childNodes,d=0,e=f.length;e>d;d++)b=f[d],c.add_node(b);return c.parsed},AbstractChosen=function(){function AbstractChosen(a,b){this.form_field=a,this.options=null!=b?b:{},AbstractChosen.browser_is_supported()&&(this.is_multiple=this.form_field.multiple,this.set_default_text(),this.set_default_values(),this.setup(),this.set_up_html(),this.register_observers())}return AbstractChosen.prototype.set_default_values=function(){var a=this;return this.click_test_action=function(b){return a.test_active_click(b)},this.activate_action=function(b){return a.activate_field(b)},this.active_field=!1,this.mouse_on_container=!1,this.results_showing=!1,this.result_highlighted=null,this.allow_single_deselect=null!=this.options.allow_single_deselect&&null!=this.form_field.options[0]&&""===this.form_field.options[0].text?this.options.allow_single_deselect:!1,this.disable_search_threshold=this.options.disable_search_threshold||0,this.disable_search=this.options.disable_search||!1,this.enable_split_word_search=null!=this.options.enable_split_word_search?this.options.enable_split_word_search:!0,this.group_search=null!=this.options.group_search?this.options.group_search:!0,this.search_contains=this.options.search_contains||!1,this.single_backstroke_delete=null!=this.options.single_backstroke_delete?this.options.single_backstroke_delete:!0,this.max_selected_options=this.options.max_selected_options||1/0,this.inherit_select_classes=this.options.inherit_select_classes||!1,this.display_selected_options=null!=this.options.display_selected_options?this.options.display_selected_options:!0,this.display_disabled_options=null!=this.options.display_disabled_options?this.options.display_disabled_options:!0},AbstractChosen.prototype.set_default_text=function(){return this.default_text=this.form_field.getAttribute("data-placeholder")?this.form_field.getAttribute("data-placeholder"):this.is_multiple?this.options.placeholder_text_multiple||this.options.placeholder_text||AbstractChosen.default_multiple_text:this.options.placeholder_text_single||this.options.placeholder_text||AbstractChosen.default_single_text,this.results_none_found=this.form_field.getAttribute("data-no_results_text")||this.options.no_results_text||AbstractChosen.default_no_result_text},AbstractChosen.prototype.mouse_enter=function(){return this.mouse_on_container=!0},AbstractChosen.prototype.mouse_leave=function(){return this.mouse_on_container=!1},AbstractChosen.prototype.input_focus=function(){var a=this;if(this.is_multiple){if(!this.active_field)return setTimeout(function(){return a.container_mousedown()},50)}else if(!this.active_field)return this.activate_field()},AbstractChosen.prototype.input_blur=function(){var a=this;return this.mouse_on_container?void 0:(this.active_field=!1,setTimeout(function(){return a.blur_test()},100))},AbstractChosen.prototype.results_option_build=function(a){var b,c,d,e,f;for(b="",f=this.results_data,d=0,e=f.length;e>d;d++)c=f[d],b+=c.group?this.result_add_group(c):this.result_add_option(c),(null!=a?a.first:void 0)&&(c.selected&&this.is_multiple?this.choice_build(c):c.selected&&!this.is_multiple&&this.single_set_selected_text(c.text));return b},AbstractChosen.prototype.result_add_option=function(a){var b,c;return a.search_match?this.include_option_in_results(a)?(b=[],a.disabled||a.selected&&this.is_multiple||b.push("active-result"),!a.disabled||a.selected&&this.is_multiple||b.push("disabled-result"),a.selected&&b.push("result-selected"),null!=a.group_array_index&&b.push("group-option"),""!==a.classes&&b.push(a.classes),c=document.createElement("li"),c.className=b.join(" "),c.style.cssText=a.style,c.setAttribute("data-option-array-index",a.array_index),c.innerHTML=a.search_text,this.outerHTML(c)):"":""},AbstractChosen.prototype.result_add_group=function(a){var b;return a.search_match||a.group_match?a.active_options>0?(b=document.createElement("li"),b.className="group-result",b.innerHTML=a.search_text,this.outerHTML(b)):"":""},AbstractChosen.prototype.results_update_field=function(){return this.set_default_text(),this.is_multiple||this.results_reset_cleanup(),this.result_clear_highlight(),this.results_build(),this.results_showing?this.winnow_results():void 0},AbstractChosen.prototype.reset_single_select_options=function(){var a,b,c,d,e;for(d=this.results_data,e=[],b=0,c=d.length;c>b;b++)a=d[b],a.selected?e.push(a.selected=!1):e.push(void 0);return e},AbstractChosen.prototype.results_toggle=function(){return this.results_showing?this.results_hide():this.results_show()},AbstractChosen.prototype.results_search=function(){return this.results_showing?this.winnow_results():this.results_show()},AbstractChosen.prototype.winnow_results=function(){var a,b,c,d,e,f,g,h,i,j,k,l,m;for(this.no_results_clear(),e=0,g=this.get_search_text(),a=g.replace(/[-[\]{}()*+?.,\\^$|#\s]/g,"\\$&"),d=this.search_contains?"":"^",c=new RegExp(d+a,"i"),j=new RegExp(a,"i"),m=this.results_data,k=0,l=m.length;l>k;k++)b=m[k],b.search_match=!1,f=null,this.include_option_in_results(b)&&(b.group&&(b.group_match=!1,b.active_options=0),null!=b.group_array_index&&this.results_data[b.group_array_index]&&(f=this.results_data[b.group_array_index],0===f.active_options&&f.search_match&&(e+=1),f.active_options+=1),(!b.group||this.group_search)&&(b.search_text=b.group?b.label:b.html,b.search_match=this.search_string_match(b.search_text,c),b.search_match&&!b.group&&(e+=1),b.search_match?(g.length&&(h=b.search_text.search(j),i=b.search_text.substr(0,h+g.length)+""+b.search_text.substr(h+g.length),b.search_text=i.substr(0,h)+""+i.substr(h)),null!=f&&(f.group_match=!0)):null!=b.group_array_index&&this.results_data[b.group_array_index].search_match&&(b.search_match=!0)));return this.result_clear_highlight(),1>e&&g.length?(this.update_results_content(""),this.no_results(g)):(this.update_results_content(this.results_option_build()),this.winnow_results_set_highlight())},AbstractChosen.prototype.search_string_match=function(a,b){var c,d,e,f;if(b.test(a))return!0;if(this.enable_split_word_search&&(a.indexOf(" ")>=0||0===a.indexOf("["))&&(d=a.replace(/\[|\]/g,"").split(" "),d.length))for(e=0,f=d.length;f>e;e++)if(c=d[e],b.test(c))return!0},AbstractChosen.prototype.choices_count=function(){var a,b,c,d;if(null!=this.selected_option_count)return this.selected_option_count;for(this.selected_option_count=0,d=this.form_field.options,b=0,c=d.length;c>b;b++)a=d[b],a.selected&&(this.selected_option_count+=1);return this.selected_option_count},AbstractChosen.prototype.choices_click=function(a){return a.preventDefault(),this.results_showing||this.is_disabled?void 0:this.results_show()},AbstractChosen.prototype.keyup_checker=function(a){var b,c;switch(b=null!=(c=a.which)?c:a.keyCode,this.search_field_scale(),b){case 8:if(this.is_multiple&&this.backstroke_length<1&&this.choices_count()>0)return this.keydown_backstroke();if(!this.pending_backstroke)return this.result_clear_highlight(),this.results_search();break;case 13:if(a.preventDefault(),this.results_showing)return this.result_select(a);break;case 27:return this.results_showing&&this.results_hide(),!0;case 9:case 38:case 40:case 16:case 91:case 17:break;default:return this.results_search()}},AbstractChosen.prototype.clipboard_event_checker=function(){var a=this;return setTimeout(function(){return a.results_search()},50)},AbstractChosen.prototype.container_width=function(){return null!=this.options.width?this.options.width:""+this.form_field.offsetWidth+"px"},AbstractChosen.prototype.include_option_in_results=function(a){return this.is_multiple&&!this.display_selected_options&&a.selected?!1:!this.display_disabled_options&&a.disabled?!1:a.empty?!1:!0},AbstractChosen.prototype.search_results_touchstart=function(a){return this.touch_started=!0,this.search_results_mouseover(a)},AbstractChosen.prototype.search_results_touchmove=function(a){return this.touch_started=!1,this.search_results_mouseout(a)},AbstractChosen.prototype.search_results_touchend=function(a){return this.touch_started?this.search_results_mouseup(a):void 0},AbstractChosen.prototype.outerHTML=function(a){var b;return a.outerHTML?a.outerHTML:(b=document.createElement("div"),b.appendChild(a),b.innerHTML)},AbstractChosen.browser_is_supported=function(){return"Microsoft Internet Explorer"===window.navigator.appName?document.documentMode>=8:/iP(od|hone)/i.test(window.navigator.userAgent)?!1:/Android/i.test(window.navigator.userAgent)&&/Mobile/i.test(window.navigator.userAgent)?!1:!0},AbstractChosen.default_multiple_text="Select Some Options",AbstractChosen.default_single_text="Select an Option",AbstractChosen.default_no_result_text="No results match",AbstractChosen}(),a=jQuery,a.fn.extend({chosen:function(b){return AbstractChosen.browser_is_supported()?this.each(function(){var c,d;c=a(this),d=c.data("chosen"),"destroy"===b&&d?d.destroy():d||c.data("chosen",new Chosen(this,b))}):this}}),Chosen=function(c){function Chosen(){return b=Chosen.__super__.constructor.apply(this,arguments)}return d(Chosen,c),Chosen.prototype.setup=function(){return this.form_field_jq=a(this.form_field),this.current_selectedIndex=this.form_field.selectedIndex,this.is_rtl=this.form_field_jq.hasClass("chosen-rtl")},Chosen.prototype.set_up_html=function(){var b,c;return b=["chosen-container"],b.push("chosen-container-"+(this.is_multiple?"multi":"single")),this.inherit_select_classes&&this.form_field.className&&b.push(this.form_field.className),this.is_rtl&&b.push("chosen-rtl"),c={"class":b.join(" "),style:"width: "+this.container_width()+";",title:this.form_field.title},this.form_field.id.length&&(c.id=this.form_field.id.replace(/[^\w]/g,"_")+"_chosen"),this.container=a("
                                    ",c),this.is_multiple?this.container.html('
                                      '):this.container.html('
                                      '+this.default_text+'
                                        '),this.form_field_jq.hide().after(this.container),this.dropdown=this.container.find("div.chosen-drop").first(),this.search_field=this.container.find("input").first(),this.search_results=this.container.find("ul.chosen-results").first(),this.search_field_scale(),this.search_no_results=this.container.find("li.no-results").first(),this.is_multiple?(this.search_choices=this.container.find("ul.chosen-choices").first(),this.search_container=this.container.find("li.search-field").first()):(this.search_container=this.container.find("div.chosen-search").first(),this.selected_item=this.container.find(".chosen-single").first()),this.results_build(),this.set_tab_index(),this.set_label_behavior(),this.form_field_jq.trigger("chosen:ready",{chosen:this})},Chosen.prototype.register_observers=function(){var a=this;return this.container.bind("mousedown.chosen",function(b){a.container_mousedown(b)}),this.container.bind("mouseup.chosen",function(b){a.container_mouseup(b)}),this.container.bind("mouseenter.chosen",function(b){a.mouse_enter(b)}),this.container.bind("mouseleave.chosen",function(b){a.mouse_leave(b)}),this.search_results.bind("mouseup.chosen",function(b){a.search_results_mouseup(b)}),this.search_results.bind("mouseover.chosen",function(b){a.search_results_mouseover(b)}),this.search_results.bind("mouseout.chosen",function(b){a.search_results_mouseout(b)}),this.search_results.bind("mousewheel.chosen DOMMouseScroll.chosen",function(b){a.search_results_mousewheel(b)}),this.search_results.bind("touchstart.chosen",function(b){a.search_results_touchstart(b)}),this.search_results.bind("touchmove.chosen",function(b){a.search_results_touchmove(b)}),this.search_results.bind("touchend.chosen",function(b){a.search_results_touchend(b)}),this.form_field_jq.bind("chosen:updated.chosen",function(b){a.results_update_field(b)}),this.form_field_jq.bind("chosen:activate.chosen",function(b){a.activate_field(b)}),this.form_field_jq.bind("chosen:open.chosen",function(b){a.container_mousedown(b)}),this.form_field_jq.bind("chosen:close.chosen",function(b){a.input_blur(b)}),this.search_field.bind("blur.chosen",function(b){a.input_blur(b)}),this.search_field.bind("keyup.chosen",function(b){a.keyup_checker(b)}),this.search_field.bind("keydown.chosen",function(b){a.keydown_checker(b)}),this.search_field.bind("focus.chosen",function(b){a.input_focus(b)}),this.search_field.bind("cut.chosen",function(b){a.clipboard_event_checker(b)}),this.search_field.bind("paste.chosen",function(b){a.clipboard_event_checker(b)}),this.is_multiple?this.search_choices.bind("click.chosen",function(b){a.choices_click(b)}):this.container.bind("click.chosen",function(a){a.preventDefault()})},Chosen.prototype.destroy=function(){return a(this.container[0].ownerDocument).unbind("click.chosen",this.click_test_action),this.search_field[0].tabIndex&&(this.form_field_jq[0].tabIndex=this.search_field[0].tabIndex),this.container.remove(),this.form_field_jq.removeData("chosen"),this.form_field_jq.show()},Chosen.prototype.search_field_disabled=function(){return this.is_disabled=this.form_field_jq[0].disabled,this.is_disabled?(this.container.addClass("chosen-disabled"),this.search_field[0].disabled=!0,this.is_multiple||this.selected_item.unbind("focus.chosen",this.activate_action),this.close_field()):(this.container.removeClass("chosen-disabled"),this.search_field[0].disabled=!1,this.is_multiple?void 0:this.selected_item.bind("focus.chosen",this.activate_action))},Chosen.prototype.container_mousedown=function(b){return this.is_disabled||(b&&"mousedown"===b.type&&!this.results_showing&&b.preventDefault(),null!=b&&a(b.target).hasClass("search-choice-close"))?void 0:(this.active_field?this.is_multiple||!b||a(b.target)[0]!==this.selected_item[0]&&!a(b.target).parents("a.chosen-single").length||(b.preventDefault(),this.results_toggle()):(this.is_multiple&&this.search_field.val(""),a(this.container[0].ownerDocument).bind("click.chosen",this.click_test_action),this.results_show()),this.activate_field())},Chosen.prototype.container_mouseup=function(a){return"ABBR"!==a.target.nodeName||this.is_disabled?void 0:this.results_reset(a)},Chosen.prototype.search_results_mousewheel=function(a){var b;return a.originalEvent&&(b=-a.originalEvent.wheelDelta||a.originalEvent.detail),null!=b?(a.preventDefault(),"DOMMouseScroll"===a.type&&(b=40*b),this.search_results.scrollTop(b+this.search_results.scrollTop())):void 0},Chosen.prototype.blur_test=function(){return!this.active_field&&this.container.hasClass("chosen-container-active")?this.close_field():void 0},Chosen.prototype.close_field=function(){return a(this.container[0].ownerDocument).unbind("click.chosen",this.click_test_action),this.active_field=!1,this.results_hide(),this.container.removeClass("chosen-container-active"),this.clear_backstroke(),this.show_search_field_default(),this.search_field_scale()},Chosen.prototype.activate_field=function(){return this.container.addClass("chosen-container-active"),this.active_field=!0,this.search_field.val(this.search_field.val()),this.search_field.focus()},Chosen.prototype.test_active_click=function(b){var c;return c=a(b.target).closest(".chosen-container"),c.length&&this.container[0]===c[0]?this.active_field=!0:this.close_field()},Chosen.prototype.results_build=function(){return this.parsing=!0,this.selected_option_count=null,this.results_data=SelectParser.select_to_array(this.form_field),this.is_multiple?this.search_choices.find("li.search-choice").remove():this.is_multiple||(this.single_set_selected_text(),this.disable_search||this.form_field.options.length<=this.disable_search_threshold?(this.search_field[0].readOnly=!0,this.container.addClass("chosen-container-single-nosearch")):(this.search_field[0].readOnly=!1,this.container.removeClass("chosen-container-single-nosearch"))),this.update_results_content(this.results_option_build({first:!0})),this.search_field_disabled(),this.show_search_field_default(),this.search_field_scale(),this.parsing=!1},Chosen.prototype.result_do_highlight=function(a){var b,c,d,e,f;if(a.length){if(this.result_clear_highlight(),this.result_highlight=a,this.result_highlight.addClass("highlighted"),d=parseInt(this.search_results.css("maxHeight"),10),f=this.search_results.scrollTop(),e=d+f,c=this.result_highlight.position().top+this.search_results.scrollTop(),b=c+this.result_highlight.outerHeight(),b>=e)return this.search_results.scrollTop(b-d>0?b-d:0);if(f>c)return this.search_results.scrollTop(c)}},Chosen.prototype.result_clear_highlight=function(){return this.result_highlight&&this.result_highlight.removeClass("highlighted"),this.result_highlight=null},Chosen.prototype.results_show=function(){return this.is_multiple&&this.max_selected_options<=this.choices_count()?(this.form_field_jq.trigger("chosen:maxselected",{chosen:this}),!1):(this.container.addClass("chosen-with-drop"),this.results_showing=!0,this.search_field.focus(),this.search_field.val(this.search_field.val()),this.winnow_results(),this.form_field_jq.trigger("chosen:showing_dropdown",{chosen:this}))},Chosen.prototype.update_results_content=function(a){return this.search_results.html(a)},Chosen.prototype.results_hide=function(){return this.results_showing&&(this.result_clear_highlight(),this.container.removeClass("chosen-with-drop"),this.form_field_jq.trigger("chosen:hiding_dropdown",{chosen:this})),this.results_showing=!1},Chosen.prototype.set_tab_index=function(){var a;return this.form_field.tabIndex?(a=this.form_field.tabIndex,this.form_field.tabIndex=-1,this.search_field[0].tabIndex=a):void 0},Chosen.prototype.set_label_behavior=function(){var b=this;return this.form_field_label=this.form_field_jq.parents("label"),!this.form_field_label.length&&this.form_field.id.length&&(this.form_field_label=a("label[for='"+this.form_field.id+"']")),this.form_field_label.length>0?this.form_field_label.bind("click.chosen",function(a){return b.is_multiple?b.container_mousedown(a):b.activate_field()}):void 0},Chosen.prototype.show_search_field_default=function(){return this.is_multiple&&this.choices_count()<1&&!this.active_field?(this.search_field.val(this.default_text),this.search_field.addClass("default")):(this.search_field.val(""),this.search_field.removeClass("default"))},Chosen.prototype.search_results_mouseup=function(b){var c;return c=a(b.target).hasClass("active-result")?a(b.target):a(b.target).parents(".active-result").first(),c.length?(this.result_highlight=c,this.result_select(b),this.search_field.focus()):void 0},Chosen.prototype.search_results_mouseover=function(b){var c;return c=a(b.target).hasClass("active-result")?a(b.target):a(b.target).parents(".active-result").first(),c?this.result_do_highlight(c):void 0},Chosen.prototype.search_results_mouseout=function(b){return a(b.target).hasClass("active-result")?this.result_clear_highlight():void 0},Chosen.prototype.choice_build=function(b){var c,d,e=this;return c=a("
                                      • ",{"class":"search-choice"}).html(""+b.html+""),b.disabled?c.addClass("search-choice-disabled"):(d=a("",{"class":"search-choice-close","data-option-array-index":b.array_index}),d.bind("click.chosen",function(a){return e.choice_destroy_link_click(a)}),c.append(d)),this.search_container.before(c)},Chosen.prototype.choice_destroy_link_click=function(b){return b.preventDefault(),b.stopPropagation(),this.is_disabled?void 0:this.choice_destroy(a(b.target))},Chosen.prototype.choice_destroy=function(a){return this.result_deselect(a[0].getAttribute("data-option-array-index"))?(this.show_search_field_default(),this.is_multiple&&this.choices_count()>0&&this.search_field.val().length<1&&this.results_hide(),a.parents("li").first().remove(),this.search_field_scale()):void 0},Chosen.prototype.results_reset=function(){return this.reset_single_select_options(),this.form_field.options[0].selected=!0,this.single_set_selected_text(),this.show_search_field_default(),this.results_reset_cleanup(),this.form_field_jq.trigger("change"),this.active_field?this.results_hide():void 0},Chosen.prototype.results_reset_cleanup=function(){return this.current_selectedIndex=this.form_field.selectedIndex,this.selected_item.find("abbr").remove()},Chosen.prototype.result_select=function(a){var b,c;return this.result_highlight?(b=this.result_highlight,this.result_clear_highlight(),this.is_multiple&&this.max_selected_options<=this.choices_count()?(this.form_field_jq.trigger("chosen:maxselected",{chosen:this}),!1):(this.is_multiple?b.removeClass("active-result"):this.reset_single_select_options(),c=this.results_data[b[0].getAttribute("data-option-array-index")],c.selected=!0,this.form_field.options[c.options_index].selected=!0,this.selected_option_count=null,this.is_multiple?this.choice_build(c):this.single_set_selected_text(c.text),(a.metaKey||a.ctrlKey)&&this.is_multiple||this.results_hide(),this.search_field.val(""),(this.is_multiple||this.form_field.selectedIndex!==this.current_selectedIndex)&&this.form_field_jq.trigger("change",{selected:this.form_field.options[c.options_index].value}),this.current_selectedIndex=this.form_field.selectedIndex,this.search_field_scale())):void 0},Chosen.prototype.single_set_selected_text=function(a){return null==a&&(a=this.default_text),a===this.default_text?this.selected_item.addClass("chosen-default"):(this.single_deselect_control_build(),this.selected_item.removeClass("chosen-default")),this.selected_item.find("span").text(a)},Chosen.prototype.result_deselect=function(a){var b;return b=this.results_data[a],this.form_field.options[b.options_index].disabled?!1:(b.selected=!1,this.form_field.options[b.options_index].selected=!1,this.selected_option_count=null,this.result_clear_highlight(),this.results_showing&&this.winnow_results(),this.form_field_jq.trigger("change",{deselected:this.form_field.options[b.options_index].value}),this.search_field_scale(),!0)},Chosen.prototype.single_deselect_control_build=function(){return this.allow_single_deselect?(this.selected_item.find("abbr").length||this.selected_item.find("span").first().after(''),this.selected_item.addClass("chosen-single-with-deselect")):void 0},Chosen.prototype.get_search_text=function(){return this.search_field.val()===this.default_text?"":a("
                                        ").text(a.trim(this.search_field.val())).html()},Chosen.prototype.winnow_results_set_highlight=function(){var a,b;return b=this.is_multiple?[]:this.search_results.find(".result-selected.active-result"),a=b.length?b.first():this.search_results.find(".active-result").first(),null!=a?this.result_do_highlight(a):void 0},Chosen.prototype.no_results=function(b){var c;return c=a('
                                      • '+this.results_none_found+' ""
                                      • '),c.find("span").first().html(b),this.search_results.append(c),this.form_field_jq.trigger("chosen:no_results",{chosen:this})},Chosen.prototype.no_results_clear=function(){return this.search_results.find(".no-results").remove()},Chosen.prototype.keydown_arrow=function(){var a;return this.results_showing&&this.result_highlight?(a=this.result_highlight.nextAll("li.active-result").first())?this.result_do_highlight(a):void 0:this.results_show()},Chosen.prototype.keyup_arrow=function(){var a;return this.results_showing||this.is_multiple?this.result_highlight?(a=this.result_highlight.prevAll("li.active-result"),a.length?this.result_do_highlight(a.first()):(this.choices_count()>0&&this.results_hide(),this.result_clear_highlight())):void 0:this.results_show()},Chosen.prototype.keydown_backstroke=function(){var a;return this.pending_backstroke?(this.choice_destroy(this.pending_backstroke.find("a").first()),this.clear_backstroke()):(a=this.search_container.siblings("li.search-choice").last(),a.length&&!a.hasClass("search-choice-disabled")?(this.pending_backstroke=a,this.single_backstroke_delete?this.keydown_backstroke():this.pending_backstroke.addClass("search-choice-focus")):void 0)},Chosen.prototype.clear_backstroke=function(){return this.pending_backstroke&&this.pending_backstroke.removeClass("search-choice-focus"),this.pending_backstroke=null},Chosen.prototype.keydown_checker=function(a){var b,c;switch(b=null!=(c=a.which)?c:a.keyCode,this.search_field_scale(),8!==b&&this.pending_backstroke&&this.clear_backstroke(),b){case 8:this.backstroke_length=this.search_field.val().length;break;case 9:this.results_showing&&!this.is_multiple&&this.result_select(a),this.mouse_on_container=!1;break;case 13:a.preventDefault();break;case 38:a.preventDefault(),this.keyup_arrow();break;case 40:a.preventDefault(),this.keydown_arrow()}},Chosen.prototype.search_field_scale=function(){var b,c,d,e,f,g,h,i,j;if(this.is_multiple){for(d=0,h=0,f="position:absolute; left: -1000px; top: -1000px; display:none;",g=["font-size","font-style","font-weight","font-family","line-height","text-transform","letter-spacing"],i=0,j=g.length;j>i;i++)e=g[i],f+=e+":"+this.search_field.css(e)+";";return b=a("
                                        ",{style:f}),b.text(this.search_field.val()),a("body").append(b),h=b.width()+25,b.remove(),c=this.container.outerWidth(),h>c-10&&(h=c-10),this.search_field.css({width:h+"px"})}},Chosen}(AbstractChosen)}.call(this); \ No newline at end of file diff --git a/sites/all/themes/gui/materiobasetheme/js/libs/src/chosen_v1.1.0/chosen.min.css b/sites/all/themes/gui/materiobasetheme/js/libs/src/chosen_v1.1.0/chosen.min.css deleted file mode 100644 index 9a2baab3..00000000 --- a/sites/all/themes/gui/materiobasetheme/js/libs/src/chosen_v1.1.0/chosen.min.css +++ /dev/null @@ -1,3 +0,0 @@ -/* Chosen v1.1.0 | (c) 2011-2013 by Harvest | MIT License, https://github.com/harvesthq/chosen/blob/master/LICENSE.md */ - -.chosen-container{position:relative;display:inline-block;vertical-align:middle;font-size:13px;zoom:1;*display:inline;-webkit-user-select:none;-moz-user-select:none;user-select:none}.chosen-container .chosen-drop{position:absolute;top:100%;left:-9999px;z-index:1010;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box;width:100%;border:1px solid #aaa;border-top:0;background:#fff;box-shadow:0 4px 5px rgba(0,0,0,.15)}.chosen-container.chosen-with-drop .chosen-drop{left:0}.chosen-container a{cursor:pointer}.chosen-container-single .chosen-single{position:relative;display:block;overflow:hidden;padding:0 0 0 8px;height:23px;border:1px solid #aaa;border-radius:5px;background-color:#fff;background:-webkit-gradient(linear,50% 0,50% 100%,color-stop(20%,#fff),color-stop(50%,#f6f6f6),color-stop(52%,#eee),color-stop(100%,#f4f4f4));background:-webkit-linear-gradient(top,#fff 20%,#f6f6f6 50%,#eee 52%,#f4f4f4 100%);background:-moz-linear-gradient(top,#fff 20%,#f6f6f6 50%,#eee 52%,#f4f4f4 100%);background:-o-linear-gradient(top,#fff 20%,#f6f6f6 50%,#eee 52%,#f4f4f4 100%);background:linear-gradient(top,#fff 20%,#f6f6f6 50%,#eee 52%,#f4f4f4 100%);background-clip:padding-box;box-shadow:0 0 3px #fff inset,0 1px 1px rgba(0,0,0,.1);color:#444;text-decoration:none;white-space:nowrap;line-height:24px}.chosen-container-single .chosen-default{color:#999}.chosen-container-single .chosen-single span{display:block;overflow:hidden;margin-right:26px;text-overflow:ellipsis;white-space:nowrap}.chosen-container-single .chosen-single-with-deselect span{margin-right:38px}.chosen-container-single .chosen-single abbr{position:absolute;top:6px;right:26px;display:block;width:12px;height:12px;background:url(chosen-sprite.png) -42px 1px no-repeat;font-size:1px}.chosen-container-single .chosen-single abbr:hover{background-position:-42px -10px}.chosen-container-single.chosen-disabled .chosen-single abbr:hover{background-position:-42px -10px}.chosen-container-single .chosen-single div{position:absolute;top:0;right:0;display:block;width:18px;height:100%}.chosen-container-single .chosen-single div b{display:block;width:100%;height:100%;background:url(chosen-sprite.png) no-repeat 0 2px}.chosen-container-single .chosen-search{position:relative;z-index:1010;margin:0;padding:3px 4px;white-space:nowrap}.chosen-container-single .chosen-search input[type=text]{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box;margin:1px 0;padding:4px 20px 4px 5px;width:100%;height:auto;outline:0;border:1px solid #aaa;background:#fff url(chosen-sprite.png) no-repeat 100% -20px;background:url(chosen-sprite.png) no-repeat 100% -20px;font-size:1em;font-family:sans-serif;line-height:normal;border-radius:0}.chosen-container-single .chosen-drop{margin-top:-1px;border-radius:0 0 4px 4px;background-clip:padding-box}.chosen-container-single.chosen-container-single-nosearch .chosen-search{position:absolute;left:-9999px}.chosen-container .chosen-results{position:relative;overflow-x:hidden;overflow-y:auto;margin:0 4px 4px 0;padding:0 0 0 4px;max-height:240px;-webkit-overflow-scrolling:touch}.chosen-container .chosen-results li{display:none;margin:0;padding:5px 6px;list-style:none;line-height:15px;-webkit-touch-callout:none}.chosen-container .chosen-results li.active-result{display:list-item;cursor:pointer}.chosen-container .chosen-results li.disabled-result{display:list-item;color:#ccc;cursor:default}.chosen-container .chosen-results li.highlighted{background-color:#3875d7;background-image:-webkit-gradient(linear,50% 0,50% 100%,color-stop(20%,#3875d7),color-stop(90%,#2a62bc));background-image:-webkit-linear-gradient(#3875d7 20%,#2a62bc 90%);background-image:-moz-linear-gradient(#3875d7 20%,#2a62bc 90%);background-image:-o-linear-gradient(#3875d7 20%,#2a62bc 90%);background-image:linear-gradient(#3875d7 20%,#2a62bc 90%);color:#fff}.chosen-container .chosen-results li.no-results{display:list-item;background:#f4f4f4}.chosen-container .chosen-results li.group-result{display:list-item;font-weight:700;cursor:default}.chosen-container .chosen-results li.group-option{padding-left:15px}.chosen-container .chosen-results li em{font-style:normal;text-decoration:underline}.chosen-container-multi .chosen-choices{position:relative;overflow:hidden;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box;margin:0;padding:0;width:100%;height:auto!important;height:1%;border:1px solid #aaa;background-color:#fff;background-image:-webkit-gradient(linear,50% 0,50% 100%,color-stop(1%,#eee),color-stop(15%,#fff));background-image:-webkit-linear-gradient(#eee 1%,#fff 15%);background-image:-moz-linear-gradient(#eee 1%,#fff 15%);background-image:-o-linear-gradient(#eee 1%,#fff 15%);background-image:linear-gradient(#eee 1%,#fff 15%);cursor:text}.chosen-container-multi .chosen-choices li{float:left;list-style:none}.chosen-container-multi .chosen-choices li.search-field{margin:0;padding:0;white-space:nowrap}.chosen-container-multi .chosen-choices li.search-field input[type=text]{margin:1px 0;padding:5px;height:15px;outline:0;border:0!important;background:transparent!important;box-shadow:none;color:#666;font-size:100%;font-family:sans-serif;line-height:normal;border-radius:0}.chosen-container-multi .chosen-choices li.search-field .default{color:#999}.chosen-container-multi .chosen-choices li.search-choice{position:relative;margin:3px 0 3px 5px;padding:3px 20px 3px 5px;border:1px solid #aaa;border-radius:3px;background-color:#e4e4e4;background-image:-webkit-gradient(linear,50% 0,50% 100%,color-stop(20%,#f4f4f4),color-stop(50%,#f0f0f0),color-stop(52%,#e8e8e8),color-stop(100%,#eee));background-image:-webkit-linear-gradient(#f4f4f4 20%,#f0f0f0 50%,#e8e8e8 52%,#eee 100%);background-image:-moz-linear-gradient(#f4f4f4 20%,#f0f0f0 50%,#e8e8e8 52%,#eee 100%);background-image:-o-linear-gradient(#f4f4f4 20%,#f0f0f0 50%,#e8e8e8 52%,#eee 100%);background-image:linear-gradient(#f4f4f4 20%,#f0f0f0 50%,#e8e8e8 52%,#eee 100%);background-clip:padding-box;box-shadow:0 0 2px #fff inset,0 1px 0 rgba(0,0,0,.05);color:#333;line-height:13px;cursor:default}.chosen-container-multi .chosen-choices li.search-choice .search-choice-close{position:absolute;top:4px;right:3px;display:block;width:12px;height:12px;background:url(chosen-sprite.png) -42px 1px no-repeat;font-size:1px}.chosen-container-multi .chosen-choices li.search-choice .search-choice-close:hover{background-position:-42px -10px}.chosen-container-multi .chosen-choices li.search-choice-disabled{padding-right:5px;border:1px solid #ccc;background-color:#e4e4e4;background-image:-webkit-gradient(linear,50% 0,50% 100%,color-stop(20%,#f4f4f4),color-stop(50%,#f0f0f0),color-stop(52%,#e8e8e8),color-stop(100%,#eee));background-image:-webkit-linear-gradient(top,#f4f4f4 20%,#f0f0f0 50%,#e8e8e8 52%,#eee 100%);background-image:-moz-linear-gradient(top,#f4f4f4 20%,#f0f0f0 50%,#e8e8e8 52%,#eee 100%);background-image:-o-linear-gradient(top,#f4f4f4 20%,#f0f0f0 50%,#e8e8e8 52%,#eee 100%);background-image:linear-gradient(top,#f4f4f4 20%,#f0f0f0 50%,#e8e8e8 52%,#eee 100%);color:#666}.chosen-container-multi .chosen-choices li.search-choice-focus{background:#d4d4d4}.chosen-container-multi .chosen-choices li.search-choice-focus .search-choice-close{background-position:-42px -10px}.chosen-container-multi .chosen-results{margin:0;padding:0}.chosen-container-multi .chosen-drop .result-selected{display:list-item;color:#ccc;cursor:default}.chosen-container-active .chosen-single{border:1px solid #5897fb;box-shadow:0 0 5px rgba(0,0,0,.3)}.chosen-container-active.chosen-with-drop .chosen-single{border:1px solid #aaa;-moz-border-radius-bottomright:0;border-bottom-right-radius:0;-moz-border-radius-bottomleft:0;border-bottom-left-radius:0;background-image:-webkit-gradient(linear,50% 0,50% 100%,color-stop(20%,#eee),color-stop(80%,#fff));background-image:-webkit-linear-gradient(#eee 20%,#fff 80%);background-image:-moz-linear-gradient(#eee 20%,#fff 80%);background-image:-o-linear-gradient(#eee 20%,#fff 80%);background-image:linear-gradient(#eee 20%,#fff 80%);box-shadow:0 1px 0 #fff inset}.chosen-container-active.chosen-with-drop .chosen-single div{border-left:0;background:transparent}.chosen-container-active.chosen-with-drop .chosen-single div b{background-position:-18px 2px}.chosen-container-active .chosen-choices{border:1px solid #5897fb;box-shadow:0 0 5px rgba(0,0,0,.3)}.chosen-container-active .chosen-choices li.search-field input[type=text]{color:#111!important}.chosen-disabled{opacity:.5!important;cursor:default}.chosen-disabled .chosen-single{cursor:default}.chosen-disabled .chosen-choices .search-choice .search-choice-close{cursor:default}.chosen-rtl{text-align:right}.chosen-rtl .chosen-single{overflow:visible;padding:0 8px 0 0}.chosen-rtl .chosen-single span{margin-right:0;margin-left:26px;direction:rtl}.chosen-rtl .chosen-single-with-deselect span{margin-left:38px}.chosen-rtl .chosen-single div{right:auto;left:3px}.chosen-rtl .chosen-single abbr{right:auto;left:26px}.chosen-rtl .chosen-choices li{float:right}.chosen-rtl .chosen-choices li.search-field input[type=text]{direction:rtl}.chosen-rtl .chosen-choices li.search-choice{margin:3px 5px 3px 0;padding:3px 5px 3px 19px}.chosen-rtl .chosen-choices li.search-choice .search-choice-close{right:auto;left:4px}.chosen-rtl.chosen-container-single-nosearch .chosen-search,.chosen-rtl .chosen-drop{left:9999px}.chosen-rtl.chosen-container-single .chosen-results{margin:0 0 4px 4px;padding:0 4px 0 0}.chosen-rtl .chosen-results li.group-option{padding-right:15px;padding-left:0}.chosen-rtl.chosen-container-active.chosen-with-drop .chosen-single div{border-right:0}.chosen-rtl .chosen-search input[type=text]{padding:4px 5px 4px 20px;background:#fff url(chosen-sprite.png) no-repeat -30px -20px;background:url(chosen-sprite.png) no-repeat -30px -20px;direction:rtl}.chosen-rtl.chosen-container-single .chosen-single div b{background-position:6px 2px}.chosen-rtl.chosen-container-single.chosen-with-drop .chosen-single div b{background-position:-12px 2px}@media only screen and (-webkit-min-device-pixel-ratio:2),only screen and (min-resolution:144dpi){.chosen-rtl .chosen-search input[type=text],.chosen-container-single .chosen-single abbr,.chosen-container-single .chosen-single div b,.chosen-container-single .chosen-search input[type=text],.chosen-container-multi .chosen-choices .search-choice .search-choice-close,.chosen-container .chosen-results-scroll-down span,.chosen-container .chosen-results-scroll-up span{background-image:url(chosen-sprite@2x.png)!important;background-size:52px 37px!important;background-repeat:no-repeat!important}} \ No newline at end of file diff --git a/sites/all/themes/gui/materiobasetheme/js/libs/src/chosen_v1.1.0/chosen.proto.js b/sites/all/themes/gui/materiobasetheme/js/libs/src/chosen_v1.1.0/chosen.proto.js deleted file mode 100644 index 2054606b..00000000 --- a/sites/all/themes/gui/materiobasetheme/js/libs/src/chosen_v1.1.0/chosen.proto.js +++ /dev/null @@ -1,1231 +0,0 @@ -/*! -Chosen, a Select Box Enhancer for jQuery and Prototype -by Patrick Filler for Harvest, http://getharvest.com - -Version 1.1.0 -Full source at https://github.com/harvesthq/chosen -Copyright (c) 2011 Harvest http://getharvest.com - -MIT License, https://github.com/harvesthq/chosen/blob/master/LICENSE.md -This file is generated by `grunt build`, do not edit it by hand. -*/ - -(function() { - var AbstractChosen, SelectParser, _ref, - __hasProp = {}.hasOwnProperty, - __extends = function(child, parent) { for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; }; - - SelectParser = (function() { - function SelectParser() { - this.options_index = 0; - this.parsed = []; - } - - SelectParser.prototype.add_node = function(child) { - if (child.nodeName.toUpperCase() === "OPTGROUP") { - return this.add_group(child); - } else { - return this.add_option(child); - } - }; - - SelectParser.prototype.add_group = function(group) { - var group_position, option, _i, _len, _ref, _results; - group_position = this.parsed.length; - this.parsed.push({ - array_index: group_position, - group: true, - label: this.escapeExpression(group.label), - children: 0, - disabled: group.disabled - }); - _ref = group.childNodes; - _results = []; - for (_i = 0, _len = _ref.length; _i < _len; _i++) { - option = _ref[_i]; - _results.push(this.add_option(option, group_position, group.disabled)); - } - return _results; - }; - - SelectParser.prototype.add_option = function(option, group_position, group_disabled) { - if (option.nodeName.toUpperCase() === "OPTION") { - if (option.text !== "") { - if (group_position != null) { - this.parsed[group_position].children += 1; - } - this.parsed.push({ - array_index: this.parsed.length, - options_index: this.options_index, - value: option.value, - text: option.text, - html: option.innerHTML, - selected: option.selected, - disabled: group_disabled === true ? group_disabled : option.disabled, - group_array_index: group_position, - classes: option.className, - style: option.style.cssText - }); - } else { - this.parsed.push({ - array_index: this.parsed.length, - options_index: this.options_index, - empty: true - }); - } - return this.options_index += 1; - } - }; - - SelectParser.prototype.escapeExpression = function(text) { - var map, unsafe_chars; - if ((text == null) || text === false) { - return ""; - } - if (!/[\&\<\>\"\'\`]/.test(text)) { - return text; - } - map = { - "<": "<", - ">": ">", - '"': """, - "'": "'", - "`": "`" - }; - unsafe_chars = /&(?!\w+;)|[\<\>\"\'\`]/g; - return text.replace(unsafe_chars, function(chr) { - return map[chr] || "&"; - }); - }; - - return SelectParser; - - })(); - - SelectParser.select_to_array = function(select) { - var child, parser, _i, _len, _ref; - parser = new SelectParser(); - _ref = select.childNodes; - for (_i = 0, _len = _ref.length; _i < _len; _i++) { - child = _ref[_i]; - parser.add_node(child); - } - return parser.parsed; - }; - - AbstractChosen = (function() { - function AbstractChosen(form_field, options) { - this.form_field = form_field; - this.options = options != null ? options : {}; - if (!AbstractChosen.browser_is_supported()) { - return; - } - this.is_multiple = this.form_field.multiple; - this.set_default_text(); - this.set_default_values(); - this.setup(); - this.set_up_html(); - this.register_observers(); - } - - AbstractChosen.prototype.set_default_values = function() { - var _this = this; - this.click_test_action = function(evt) { - return _this.test_active_click(evt); - }; - this.activate_action = function(evt) { - return _this.activate_field(evt); - }; - this.active_field = false; - this.mouse_on_container = false; - this.results_showing = false; - this.result_highlighted = null; - this.allow_single_deselect = (this.options.allow_single_deselect != null) && (this.form_field.options[0] != null) && this.form_field.options[0].text === "" ? this.options.allow_single_deselect : false; - this.disable_search_threshold = this.options.disable_search_threshold || 0; - this.disable_search = this.options.disable_search || false; - this.enable_split_word_search = this.options.enable_split_word_search != null ? this.options.enable_split_word_search : true; - this.group_search = this.options.group_search != null ? this.options.group_search : true; - this.search_contains = this.options.search_contains || false; - this.single_backstroke_delete = this.options.single_backstroke_delete != null ? this.options.single_backstroke_delete : true; - this.max_selected_options = this.options.max_selected_options || Infinity; - this.inherit_select_classes = this.options.inherit_select_classes || false; - this.display_selected_options = this.options.display_selected_options != null ? this.options.display_selected_options : true; - return this.display_disabled_options = this.options.display_disabled_options != null ? this.options.display_disabled_options : true; - }; - - AbstractChosen.prototype.set_default_text = function() { - if (this.form_field.getAttribute("data-placeholder")) { - this.default_text = this.form_field.getAttribute("data-placeholder"); - } else if (this.is_multiple) { - this.default_text = this.options.placeholder_text_multiple || this.options.placeholder_text || AbstractChosen.default_multiple_text; - } else { - this.default_text = this.options.placeholder_text_single || this.options.placeholder_text || AbstractChosen.default_single_text; - } - return this.results_none_found = this.form_field.getAttribute("data-no_results_text") || this.options.no_results_text || AbstractChosen.default_no_result_text; - }; - - AbstractChosen.prototype.mouse_enter = function() { - return this.mouse_on_container = true; - }; - - AbstractChosen.prototype.mouse_leave = function() { - return this.mouse_on_container = false; - }; - - AbstractChosen.prototype.input_focus = function(evt) { - var _this = this; - if (this.is_multiple) { - if (!this.active_field) { - return setTimeout((function() { - return _this.container_mousedown(); - }), 50); - } - } else { - if (!this.active_field) { - return this.activate_field(); - } - } - }; - - AbstractChosen.prototype.input_blur = function(evt) { - var _this = this; - if (!this.mouse_on_container) { - this.active_field = false; - return setTimeout((function() { - return _this.blur_test(); - }), 100); - } - }; - - AbstractChosen.prototype.results_option_build = function(options) { - var content, data, _i, _len, _ref; - content = ''; - _ref = this.results_data; - for (_i = 0, _len = _ref.length; _i < _len; _i++) { - data = _ref[_i]; - if (data.group) { - content += this.result_add_group(data); - } else { - content += this.result_add_option(data); - } - if (options != null ? options.first : void 0) { - if (data.selected && this.is_multiple) { - this.choice_build(data); - } else if (data.selected && !this.is_multiple) { - this.single_set_selected_text(data.text); - } - } - } - return content; - }; - - AbstractChosen.prototype.result_add_option = function(option) { - var classes, option_el; - if (!option.search_match) { - return ''; - } - if (!this.include_option_in_results(option)) { - return ''; - } - classes = []; - if (!option.disabled && !(option.selected && this.is_multiple)) { - classes.push("active-result"); - } - if (option.disabled && !(option.selected && this.is_multiple)) { - classes.push("disabled-result"); - } - if (option.selected) { - classes.push("result-selected"); - } - if (option.group_array_index != null) { - classes.push("group-option"); - } - if (option.classes !== "") { - classes.push(option.classes); - } - option_el = document.createElement("li"); - option_el.className = classes.join(" "); - option_el.style.cssText = option.style; - option_el.setAttribute("data-option-array-index", option.array_index); - option_el.innerHTML = option.search_text; - return this.outerHTML(option_el); - }; - - AbstractChosen.prototype.result_add_group = function(group) { - var group_el; - if (!(group.search_match || group.group_match)) { - return ''; - } - if (!(group.active_options > 0)) { - return ''; - } - group_el = document.createElement("li"); - group_el.className = "group-result"; - group_el.innerHTML = group.search_text; - return this.outerHTML(group_el); - }; - - AbstractChosen.prototype.results_update_field = function() { - this.set_default_text(); - if (!this.is_multiple) { - this.results_reset_cleanup(); - } - this.result_clear_highlight(); - this.results_build(); - if (this.results_showing) { - return this.winnow_results(); - } - }; - - AbstractChosen.prototype.reset_single_select_options = function() { - var result, _i, _len, _ref, _results; - _ref = this.results_data; - _results = []; - for (_i = 0, _len = _ref.length; _i < _len; _i++) { - result = _ref[_i]; - if (result.selected) { - _results.push(result.selected = false); - } else { - _results.push(void 0); - } - } - return _results; - }; - - AbstractChosen.prototype.results_toggle = function() { - if (this.results_showing) { - return this.results_hide(); - } else { - return this.results_show(); - } - }; - - AbstractChosen.prototype.results_search = function(evt) { - if (this.results_showing) { - return this.winnow_results(); - } else { - return this.results_show(); - } - }; - - AbstractChosen.prototype.winnow_results = function() { - var escapedSearchText, option, regex, regexAnchor, results, results_group, searchText, startpos, text, zregex, _i, _len, _ref; - this.no_results_clear(); - results = 0; - searchText = this.get_search_text(); - escapedSearchText = searchText.replace(/[-[\]{}()*+?.,\\^$|#\s]/g, "\\$&"); - regexAnchor = this.search_contains ? "" : "^"; - regex = new RegExp(regexAnchor + escapedSearchText, 'i'); - zregex = new RegExp(escapedSearchText, 'i'); - _ref = this.results_data; - for (_i = 0, _len = _ref.length; _i < _len; _i++) { - option = _ref[_i]; - option.search_match = false; - results_group = null; - if (this.include_option_in_results(option)) { - if (option.group) { - option.group_match = false; - option.active_options = 0; - } - if ((option.group_array_index != null) && this.results_data[option.group_array_index]) { - results_group = this.results_data[option.group_array_index]; - if (results_group.active_options === 0 && results_group.search_match) { - results += 1; - } - results_group.active_options += 1; - } - if (!(option.group && !this.group_search)) { - option.search_text = option.group ? option.label : option.html; - option.search_match = this.search_string_match(option.search_text, regex); - if (option.search_match && !option.group) { - results += 1; - } - if (option.search_match) { - if (searchText.length) { - startpos = option.search_text.search(zregex); - text = option.search_text.substr(0, startpos + searchText.length) + '' + option.search_text.substr(startpos + searchText.length); - option.search_text = text.substr(0, startpos) + '' + text.substr(startpos); - } - if (results_group != null) { - results_group.group_match = true; - } - } else if ((option.group_array_index != null) && this.results_data[option.group_array_index].search_match) { - option.search_match = true; - } - } - } - } - this.result_clear_highlight(); - if (results < 1 && searchText.length) { - this.update_results_content(""); - return this.no_results(searchText); - } else { - this.update_results_content(this.results_option_build()); - return this.winnow_results_set_highlight(); - } - }; - - AbstractChosen.prototype.search_string_match = function(search_string, regex) { - var part, parts, _i, _len; - if (regex.test(search_string)) { - return true; - } else if (this.enable_split_word_search && (search_string.indexOf(" ") >= 0 || search_string.indexOf("[") === 0)) { - parts = search_string.replace(/\[|\]/g, "").split(" "); - if (parts.length) { - for (_i = 0, _len = parts.length; _i < _len; _i++) { - part = parts[_i]; - if (regex.test(part)) { - return true; - } - } - } - } - }; - - AbstractChosen.prototype.choices_count = function() { - var option, _i, _len, _ref; - if (this.selected_option_count != null) { - return this.selected_option_count; - } - this.selected_option_count = 0; - _ref = this.form_field.options; - for (_i = 0, _len = _ref.length; _i < _len; _i++) { - option = _ref[_i]; - if (option.selected) { - this.selected_option_count += 1; - } - } - return this.selected_option_count; - }; - - AbstractChosen.prototype.choices_click = function(evt) { - evt.preventDefault(); - if (!(this.results_showing || this.is_disabled)) { - return this.results_show(); - } - }; - - AbstractChosen.prototype.keyup_checker = function(evt) { - var stroke, _ref; - stroke = (_ref = evt.which) != null ? _ref : evt.keyCode; - this.search_field_scale(); - switch (stroke) { - case 8: - if (this.is_multiple && this.backstroke_length < 1 && this.choices_count() > 0) { - return this.keydown_backstroke(); - } else if (!this.pending_backstroke) { - this.result_clear_highlight(); - return this.results_search(); - } - break; - case 13: - evt.preventDefault(); - if (this.results_showing) { - return this.result_select(evt); - } - break; - case 27: - if (this.results_showing) { - this.results_hide(); - } - return true; - case 9: - case 38: - case 40: - case 16: - case 91: - case 17: - break; - default: - return this.results_search(); - } - }; - - AbstractChosen.prototype.clipboard_event_checker = function(evt) { - var _this = this; - return setTimeout((function() { - return _this.results_search(); - }), 50); - }; - - AbstractChosen.prototype.container_width = function() { - if (this.options.width != null) { - return this.options.width; - } else { - return "" + this.form_field.offsetWidth + "px"; - } - }; - - AbstractChosen.prototype.include_option_in_results = function(option) { - if (this.is_multiple && (!this.display_selected_options && option.selected)) { - return false; - } - if (!this.display_disabled_options && option.disabled) { - return false; - } - if (option.empty) { - return false; - } - return true; - }; - - AbstractChosen.prototype.search_results_touchstart = function(evt) { - this.touch_started = true; - return this.search_results_mouseover(evt); - }; - - AbstractChosen.prototype.search_results_touchmove = function(evt) { - this.touch_started = false; - return this.search_results_mouseout(evt); - }; - - AbstractChosen.prototype.search_results_touchend = function(evt) { - if (this.touch_started) { - return this.search_results_mouseup(evt); - } - }; - - AbstractChosen.prototype.outerHTML = function(element) { - var tmp; - if (element.outerHTML) { - return element.outerHTML; - } - tmp = document.createElement("div"); - tmp.appendChild(element); - return tmp.innerHTML; - }; - - AbstractChosen.browser_is_supported = function() { - if (window.navigator.appName === "Microsoft Internet Explorer") { - return document.documentMode >= 8; - } - if (/iP(od|hone)/i.test(window.navigator.userAgent)) { - return false; - } - if (/Android/i.test(window.navigator.userAgent)) { - if (/Mobile/i.test(window.navigator.userAgent)) { - return false; - } - } - return true; - }; - - AbstractChosen.default_multiple_text = "Select Some Options"; - - AbstractChosen.default_single_text = "Select an Option"; - - AbstractChosen.default_no_result_text = "No results match"; - - return AbstractChosen; - - })(); - - this.Chosen = (function(_super) { - __extends(Chosen, _super); - - function Chosen() { - _ref = Chosen.__super__.constructor.apply(this, arguments); - return _ref; - } - - Chosen.prototype.setup = function() { - this.current_selectedIndex = this.form_field.selectedIndex; - return this.is_rtl = this.form_field.hasClassName("chosen-rtl"); - }; - - Chosen.prototype.set_default_values = function() { - Chosen.__super__.set_default_values.call(this); - this.single_temp = new Template('#{default}
                                          '); - this.multi_temp = new Template('
                                            '); - return this.no_results_temp = new Template('
                                          • ' + this.results_none_found + ' "#{terms}"
                                          • '); - }; - - Chosen.prototype.set_up_html = function() { - var container_classes, container_props; - container_classes = ["chosen-container"]; - container_classes.push("chosen-container-" + (this.is_multiple ? "multi" : "single")); - if (this.inherit_select_classes && this.form_field.className) { - container_classes.push(this.form_field.className); - } - if (this.is_rtl) { - container_classes.push("chosen-rtl"); - } - container_props = { - 'class': container_classes.join(' '), - 'style': "width: " + (this.container_width()) + ";", - 'title': this.form_field.title - }; - if (this.form_field.id.length) { - container_props.id = this.form_field.id.replace(/[^\w]/g, '_') + "_chosen"; - } - this.container = this.is_multiple ? new Element('div', container_props).update(this.multi_temp.evaluate({ - "default": this.default_text - })) : new Element('div', container_props).update(this.single_temp.evaluate({ - "default": this.default_text - })); - this.form_field.hide().insert({ - after: this.container - }); - this.dropdown = this.container.down('div.chosen-drop'); - this.search_field = this.container.down('input'); - this.search_results = this.container.down('ul.chosen-results'); - this.search_field_scale(); - this.search_no_results = this.container.down('li.no-results'); - if (this.is_multiple) { - this.search_choices = this.container.down('ul.chosen-choices'); - this.search_container = this.container.down('li.search-field'); - } else { - this.search_container = this.container.down('div.chosen-search'); - this.selected_item = this.container.down('.chosen-single'); - } - this.results_build(); - this.set_tab_index(); - this.set_label_behavior(); - return this.form_field.fire("chosen:ready", { - chosen: this - }); - }; - - Chosen.prototype.register_observers = function() { - var _this = this; - this.container.observe("mousedown", function(evt) { - return _this.container_mousedown(evt); - }); - this.container.observe("mouseup", function(evt) { - return _this.container_mouseup(evt); - }); - this.container.observe("mouseenter", function(evt) { - return _this.mouse_enter(evt); - }); - this.container.observe("mouseleave", function(evt) { - return _this.mouse_leave(evt); - }); - this.search_results.observe("mouseup", function(evt) { - return _this.search_results_mouseup(evt); - }); - this.search_results.observe("mouseover", function(evt) { - return _this.search_results_mouseover(evt); - }); - this.search_results.observe("mouseout", function(evt) { - return _this.search_results_mouseout(evt); - }); - this.search_results.observe("mousewheel", function(evt) { - return _this.search_results_mousewheel(evt); - }); - this.search_results.observe("DOMMouseScroll", function(evt) { - return _this.search_results_mousewheel(evt); - }); - this.search_results.observe("touchstart", function(evt) { - return _this.search_results_touchstart(evt); - }); - this.search_results.observe("touchmove", function(evt) { - return _this.search_results_touchmove(evt); - }); - this.search_results.observe("touchend", function(evt) { - return _this.search_results_touchend(evt); - }); - this.form_field.observe("chosen:updated", function(evt) { - return _this.results_update_field(evt); - }); - this.form_field.observe("chosen:activate", function(evt) { - return _this.activate_field(evt); - }); - this.form_field.observe("chosen:open", function(evt) { - return _this.container_mousedown(evt); - }); - this.form_field.observe("chosen:close", function(evt) { - return _this.input_blur(evt); - }); - this.search_field.observe("blur", function(evt) { - return _this.input_blur(evt); - }); - this.search_field.observe("keyup", function(evt) { - return _this.keyup_checker(evt); - }); - this.search_field.observe("keydown", function(evt) { - return _this.keydown_checker(evt); - }); - this.search_field.observe("focus", function(evt) { - return _this.input_focus(evt); - }); - this.search_field.observe("cut", function(evt) { - return _this.clipboard_event_checker(evt); - }); - this.search_field.observe("paste", function(evt) { - return _this.clipboard_event_checker(evt); - }); - if (this.is_multiple) { - return this.search_choices.observe("click", function(evt) { - return _this.choices_click(evt); - }); - } else { - return this.container.observe("click", function(evt) { - return evt.preventDefault(); - }); - } - }; - - Chosen.prototype.destroy = function() { - this.container.ownerDocument.stopObserving("click", this.click_test_action); - this.form_field.stopObserving(); - this.container.stopObserving(); - this.search_results.stopObserving(); - this.search_field.stopObserving(); - if (this.form_field_label != null) { - this.form_field_label.stopObserving(); - } - if (this.is_multiple) { - this.search_choices.stopObserving(); - this.container.select(".search-choice-close").each(function(choice) { - return choice.stopObserving(); - }); - } else { - this.selected_item.stopObserving(); - } - if (this.search_field.tabIndex) { - this.form_field.tabIndex = this.search_field.tabIndex; - } - this.container.remove(); - return this.form_field.show(); - }; - - Chosen.prototype.search_field_disabled = function() { - this.is_disabled = this.form_field.disabled; - if (this.is_disabled) { - this.container.addClassName('chosen-disabled'); - this.search_field.disabled = true; - if (!this.is_multiple) { - this.selected_item.stopObserving("focus", this.activate_action); - } - return this.close_field(); - } else { - this.container.removeClassName('chosen-disabled'); - this.search_field.disabled = false; - if (!this.is_multiple) { - return this.selected_item.observe("focus", this.activate_action); - } - } - }; - - Chosen.prototype.container_mousedown = function(evt) { - if (!this.is_disabled) { - if (evt && evt.type === "mousedown" && !this.results_showing) { - evt.stop(); - } - if (!((evt != null) && evt.target.hasClassName("search-choice-close"))) { - if (!this.active_field) { - if (this.is_multiple) { - this.search_field.clear(); - } - this.container.ownerDocument.observe("click", this.click_test_action); - this.results_show(); - } else if (!this.is_multiple && evt && (evt.target === this.selected_item || evt.target.up("a.chosen-single"))) { - this.results_toggle(); - } - return this.activate_field(); - } - } - }; - - Chosen.prototype.container_mouseup = function(evt) { - if (evt.target.nodeName === "ABBR" && !this.is_disabled) { - return this.results_reset(evt); - } - }; - - Chosen.prototype.search_results_mousewheel = function(evt) { - var delta; - delta = -evt.wheelDelta || evt.detail; - if (delta != null) { - evt.preventDefault(); - if (evt.type === 'DOMMouseScroll') { - delta = delta * 40; - } - return this.search_results.scrollTop = delta + this.search_results.scrollTop; - } - }; - - Chosen.prototype.blur_test = function(evt) { - if (!this.active_field && this.container.hasClassName("chosen-container-active")) { - return this.close_field(); - } - }; - - Chosen.prototype.close_field = function() { - this.container.ownerDocument.stopObserving("click", this.click_test_action); - this.active_field = false; - this.results_hide(); - this.container.removeClassName("chosen-container-active"); - this.clear_backstroke(); - this.show_search_field_default(); - return this.search_field_scale(); - }; - - Chosen.prototype.activate_field = function() { - this.container.addClassName("chosen-container-active"); - this.active_field = true; - this.search_field.value = this.search_field.value; - return this.search_field.focus(); - }; - - Chosen.prototype.test_active_click = function(evt) { - if (evt.target.up('.chosen-container') === this.container) { - return this.active_field = true; - } else { - return this.close_field(); - } - }; - - Chosen.prototype.results_build = function() { - this.parsing = true; - this.selected_option_count = null; - this.results_data = SelectParser.select_to_array(this.form_field); - if (this.is_multiple) { - this.search_choices.select("li.search-choice").invoke("remove"); - } else if (!this.is_multiple) { - this.single_set_selected_text(); - if (this.disable_search || this.form_field.options.length <= this.disable_search_threshold) { - this.search_field.readOnly = true; - this.container.addClassName("chosen-container-single-nosearch"); - } else { - this.search_field.readOnly = false; - this.container.removeClassName("chosen-container-single-nosearch"); - } - } - this.update_results_content(this.results_option_build({ - first: true - })); - this.search_field_disabled(); - this.show_search_field_default(); - this.search_field_scale(); - return this.parsing = false; - }; - - Chosen.prototype.result_do_highlight = function(el) { - var high_bottom, high_top, maxHeight, visible_bottom, visible_top; - this.result_clear_highlight(); - this.result_highlight = el; - this.result_highlight.addClassName("highlighted"); - maxHeight = parseInt(this.search_results.getStyle('maxHeight'), 10); - visible_top = this.search_results.scrollTop; - visible_bottom = maxHeight + visible_top; - high_top = this.result_highlight.positionedOffset().top; - high_bottom = high_top + this.result_highlight.getHeight(); - if (high_bottom >= visible_bottom) { - return this.search_results.scrollTop = (high_bottom - maxHeight) > 0 ? high_bottom - maxHeight : 0; - } else if (high_top < visible_top) { - return this.search_results.scrollTop = high_top; - } - }; - - Chosen.prototype.result_clear_highlight = function() { - if (this.result_highlight) { - this.result_highlight.removeClassName('highlighted'); - } - return this.result_highlight = null; - }; - - Chosen.prototype.results_show = function() { - if (this.is_multiple && this.max_selected_options <= this.choices_count()) { - this.form_field.fire("chosen:maxselected", { - chosen: this - }); - return false; - } - this.container.addClassName("chosen-with-drop"); - this.results_showing = true; - this.search_field.focus(); - this.search_field.value = this.search_field.value; - this.winnow_results(); - return this.form_field.fire("chosen:showing_dropdown", { - chosen: this - }); - }; - - Chosen.prototype.update_results_content = function(content) { - return this.search_results.update(content); - }; - - Chosen.prototype.results_hide = function() { - if (this.results_showing) { - this.result_clear_highlight(); - this.container.removeClassName("chosen-with-drop"); - this.form_field.fire("chosen:hiding_dropdown", { - chosen: this - }); - } - return this.results_showing = false; - }; - - Chosen.prototype.set_tab_index = function(el) { - var ti; - if (this.form_field.tabIndex) { - ti = this.form_field.tabIndex; - this.form_field.tabIndex = -1; - return this.search_field.tabIndex = ti; - } - }; - - Chosen.prototype.set_label_behavior = function() { - var _this = this; - this.form_field_label = this.form_field.up("label"); - if (this.form_field_label == null) { - this.form_field_label = $$("label[for='" + this.form_field.id + "']").first(); - } - if (this.form_field_label != null) { - return this.form_field_label.observe("click", function(evt) { - if (_this.is_multiple) { - return _this.container_mousedown(evt); - } else { - return _this.activate_field(); - } - }); - } - }; - - Chosen.prototype.show_search_field_default = function() { - if (this.is_multiple && this.choices_count() < 1 && !this.active_field) { - this.search_field.value = this.default_text; - return this.search_field.addClassName("default"); - } else { - this.search_field.value = ""; - return this.search_field.removeClassName("default"); - } - }; - - Chosen.prototype.search_results_mouseup = function(evt) { - var target; - target = evt.target.hasClassName("active-result") ? evt.target : evt.target.up(".active-result"); - if (target) { - this.result_highlight = target; - this.result_select(evt); - return this.search_field.focus(); - } - }; - - Chosen.prototype.search_results_mouseover = function(evt) { - var target; - target = evt.target.hasClassName("active-result") ? evt.target : evt.target.up(".active-result"); - if (target) { - return this.result_do_highlight(target); - } - }; - - Chosen.prototype.search_results_mouseout = function(evt) { - if (evt.target.hasClassName('active-result') || evt.target.up('.active-result')) { - return this.result_clear_highlight(); - } - }; - - Chosen.prototype.choice_build = function(item) { - var choice, close_link, - _this = this; - choice = new Element('li', { - "class": "search-choice" - }).update("" + item.html + ""); - if (item.disabled) { - choice.addClassName('search-choice-disabled'); - } else { - close_link = new Element('a', { - href: '#', - "class": 'search-choice-close', - rel: item.array_index - }); - close_link.observe("click", function(evt) { - return _this.choice_destroy_link_click(evt); - }); - choice.insert(close_link); - } - return this.search_container.insert({ - before: choice - }); - }; - - Chosen.prototype.choice_destroy_link_click = function(evt) { - evt.preventDefault(); - evt.stopPropagation(); - if (!this.is_disabled) { - return this.choice_destroy(evt.target); - } - }; - - Chosen.prototype.choice_destroy = function(link) { - if (this.result_deselect(link.readAttribute("rel"))) { - this.show_search_field_default(); - if (this.is_multiple && this.choices_count() > 0 && this.search_field.value.length < 1) { - this.results_hide(); - } - link.up('li').remove(); - return this.search_field_scale(); - } - }; - - Chosen.prototype.results_reset = function() { - this.reset_single_select_options(); - this.form_field.options[0].selected = true; - this.single_set_selected_text(); - this.show_search_field_default(); - this.results_reset_cleanup(); - if (typeof Event.simulate === 'function') { - this.form_field.simulate("change"); - } - if (this.active_field) { - return this.results_hide(); - } - }; - - Chosen.prototype.results_reset_cleanup = function() { - var deselect_trigger; - this.current_selectedIndex = this.form_field.selectedIndex; - deselect_trigger = this.selected_item.down("abbr"); - if (deselect_trigger) { - return deselect_trigger.remove(); - } - }; - - Chosen.prototype.result_select = function(evt) { - var high, item; - if (this.result_highlight) { - high = this.result_highlight; - this.result_clear_highlight(); - if (this.is_multiple && this.max_selected_options <= this.choices_count()) { - this.form_field.fire("chosen:maxselected", { - chosen: this - }); - return false; - } - if (this.is_multiple) { - high.removeClassName("active-result"); - } else { - this.reset_single_select_options(); - } - high.addClassName("result-selected"); - item = this.results_data[high.getAttribute("data-option-array-index")]; - item.selected = true; - this.form_field.options[item.options_index].selected = true; - this.selected_option_count = null; - if (this.is_multiple) { - this.choice_build(item); - } else { - this.single_set_selected_text(item.text); - } - if (!((evt.metaKey || evt.ctrlKey) && this.is_multiple)) { - this.results_hide(); - } - this.search_field.value = ""; - if (typeof Event.simulate === 'function' && (this.is_multiple || this.form_field.selectedIndex !== this.current_selectedIndex)) { - this.form_field.simulate("change"); - } - this.current_selectedIndex = this.form_field.selectedIndex; - return this.search_field_scale(); - } - }; - - Chosen.prototype.single_set_selected_text = function(text) { - if (text == null) { - text = this.default_text; - } - if (text === this.default_text) { - this.selected_item.addClassName("chosen-default"); - } else { - this.single_deselect_control_build(); - this.selected_item.removeClassName("chosen-default"); - } - return this.selected_item.down("span").update(text); - }; - - Chosen.prototype.result_deselect = function(pos) { - var result_data; - result_data = this.results_data[pos]; - if (!this.form_field.options[result_data.options_index].disabled) { - result_data.selected = false; - this.form_field.options[result_data.options_index].selected = false; - this.selected_option_count = null; - this.result_clear_highlight(); - if (this.results_showing) { - this.winnow_results(); - } - if (typeof Event.simulate === 'function') { - this.form_field.simulate("change"); - } - this.search_field_scale(); - return true; - } else { - return false; - } - }; - - Chosen.prototype.single_deselect_control_build = function() { - if (!this.allow_single_deselect) { - return; - } - if (!this.selected_item.down("abbr")) { - this.selected_item.down("span").insert({ - after: "" - }); - } - return this.selected_item.addClassName("chosen-single-with-deselect"); - }; - - Chosen.prototype.get_search_text = function() { - if (this.search_field.value === this.default_text) { - return ""; - } else { - return this.search_field.value.strip().escapeHTML(); - } - }; - - Chosen.prototype.winnow_results_set_highlight = function() { - var do_high; - if (!this.is_multiple) { - do_high = this.search_results.down(".result-selected.active-result"); - } - if (do_high == null) { - do_high = this.search_results.down(".active-result"); - } - if (do_high != null) { - return this.result_do_highlight(do_high); - } - }; - - Chosen.prototype.no_results = function(terms) { - this.search_results.insert(this.no_results_temp.evaluate({ - terms: terms - })); - return this.form_field.fire("chosen:no_results", { - chosen: this - }); - }; - - Chosen.prototype.no_results_clear = function() { - var nr, _results; - nr = null; - _results = []; - while (nr = this.search_results.down(".no-results")) { - _results.push(nr.remove()); - } - return _results; - }; - - Chosen.prototype.keydown_arrow = function() { - var next_sib; - if (this.results_showing && this.result_highlight) { - next_sib = this.result_highlight.next('.active-result'); - if (next_sib) { - return this.result_do_highlight(next_sib); - } - } else { - return this.results_show(); - } - }; - - Chosen.prototype.keyup_arrow = function() { - var actives, prevs, sibs; - if (!this.results_showing && !this.is_multiple) { - return this.results_show(); - } else if (this.result_highlight) { - sibs = this.result_highlight.previousSiblings(); - actives = this.search_results.select("li.active-result"); - prevs = sibs.intersect(actives); - if (prevs.length) { - return this.result_do_highlight(prevs.first()); - } else { - if (this.choices_count() > 0) { - this.results_hide(); - } - return this.result_clear_highlight(); - } - } - }; - - Chosen.prototype.keydown_backstroke = function() { - var next_available_destroy; - if (this.pending_backstroke) { - this.choice_destroy(this.pending_backstroke.down("a")); - return this.clear_backstroke(); - } else { - next_available_destroy = this.search_container.siblings().last(); - if (next_available_destroy && next_available_destroy.hasClassName("search-choice") && !next_available_destroy.hasClassName("search-choice-disabled")) { - this.pending_backstroke = next_available_destroy; - if (this.pending_backstroke) { - this.pending_backstroke.addClassName("search-choice-focus"); - } - if (this.single_backstroke_delete) { - return this.keydown_backstroke(); - } else { - return this.pending_backstroke.addClassName("search-choice-focus"); - } - } - } - }; - - Chosen.prototype.clear_backstroke = function() { - if (this.pending_backstroke) { - this.pending_backstroke.removeClassName("search-choice-focus"); - } - return this.pending_backstroke = null; - }; - - Chosen.prototype.keydown_checker = function(evt) { - var stroke, _ref1; - stroke = (_ref1 = evt.which) != null ? _ref1 : evt.keyCode; - this.search_field_scale(); - if (stroke !== 8 && this.pending_backstroke) { - this.clear_backstroke(); - } - switch (stroke) { - case 8: - this.backstroke_length = this.search_field.value.length; - break; - case 9: - if (this.results_showing && !this.is_multiple) { - this.result_select(evt); - } - this.mouse_on_container = false; - break; - case 13: - evt.preventDefault(); - break; - case 38: - evt.preventDefault(); - this.keyup_arrow(); - break; - case 40: - evt.preventDefault(); - this.keydown_arrow(); - break; - } - }; - - Chosen.prototype.search_field_scale = function() { - var div, f_width, h, style, style_block, styles, w, _i, _len; - if (this.is_multiple) { - h = 0; - w = 0; - style_block = "position:absolute; left: -1000px; top: -1000px; display:none;"; - styles = ['font-size', 'font-style', 'font-weight', 'font-family', 'line-height', 'text-transform', 'letter-spacing']; - for (_i = 0, _len = styles.length; _i < _len; _i++) { - style = styles[_i]; - style_block += style + ":" + this.search_field.getStyle(style) + ";"; - } - div = new Element('div', { - 'style': style_block - }).update(this.search_field.value.escapeHTML()); - document.body.appendChild(div); - w = Element.measure(div, 'width') + 25; - div.remove(); - f_width = this.container.getWidth(); - if (w > f_width - 10) { - w = f_width - 10; - } - return this.search_field.setStyle({ - 'width': w + 'px' - }); - } - }; - - return Chosen; - - })(AbstractChosen); - -}).call(this); diff --git a/sites/all/themes/gui/materiobasetheme/js/libs/src/chosen_v1.1.0/chosen.proto.min.js b/sites/all/themes/gui/materiobasetheme/js/libs/src/chosen_v1.1.0/chosen.proto.min.js deleted file mode 100644 index 8f9a1db3..00000000 --- a/sites/all/themes/gui/materiobasetheme/js/libs/src/chosen_v1.1.0/chosen.proto.min.js +++ /dev/null @@ -1,2 +0,0 @@ -/* Chosen v1.1.0 | (c) 2011-2013 by Harvest | MIT License, https://github.com/harvesthq/chosen/blob/master/LICENSE.md */ -!function(){var AbstractChosen,SelectParser,a,b={}.hasOwnProperty,c=function(a,c){function d(){this.constructor=a}for(var e in c)b.call(c,e)&&(a[e]=c[e]);return d.prototype=c.prototype,a.prototype=new d,a.__super__=c.prototype,a};SelectParser=function(){function SelectParser(){this.options_index=0,this.parsed=[]}return SelectParser.prototype.add_node=function(a){return"OPTGROUP"===a.nodeName.toUpperCase()?this.add_group(a):this.add_option(a)},SelectParser.prototype.add_group=function(a){var b,c,d,e,f,g;for(b=this.parsed.length,this.parsed.push({array_index:b,group:!0,label:this.escapeExpression(a.label),children:0,disabled:a.disabled}),f=a.childNodes,g=[],d=0,e=f.length;e>d;d++)c=f[d],g.push(this.add_option(c,b,a.disabled));return g},SelectParser.prototype.add_option=function(a,b,c){return"OPTION"===a.nodeName.toUpperCase()?(""!==a.text?(null!=b&&(this.parsed[b].children+=1),this.parsed.push({array_index:this.parsed.length,options_index:this.options_index,value:a.value,text:a.text,html:a.innerHTML,selected:a.selected,disabled:c===!0?c:a.disabled,group_array_index:b,classes:a.className,style:a.style.cssText})):this.parsed.push({array_index:this.parsed.length,options_index:this.options_index,empty:!0}),this.options_index+=1):void 0},SelectParser.prototype.escapeExpression=function(a){var b,c;return null==a||a===!1?"":/[\&\<\>\"\'\`]/.test(a)?(b={"<":"<",">":">",'"':""","'":"'","`":"`"},c=/&(?!\w+;)|[\<\>\"\'\`]/g,a.replace(c,function(a){return b[a]||"&"})):a},SelectParser}(),SelectParser.select_to_array=function(a){var b,c,d,e,f;for(c=new SelectParser,f=a.childNodes,d=0,e=f.length;e>d;d++)b=f[d],c.add_node(b);return c.parsed},AbstractChosen=function(){function AbstractChosen(a,b){this.form_field=a,this.options=null!=b?b:{},AbstractChosen.browser_is_supported()&&(this.is_multiple=this.form_field.multiple,this.set_default_text(),this.set_default_values(),this.setup(),this.set_up_html(),this.register_observers())}return AbstractChosen.prototype.set_default_values=function(){var a=this;return this.click_test_action=function(b){return a.test_active_click(b)},this.activate_action=function(b){return a.activate_field(b)},this.active_field=!1,this.mouse_on_container=!1,this.results_showing=!1,this.result_highlighted=null,this.allow_single_deselect=null!=this.options.allow_single_deselect&&null!=this.form_field.options[0]&&""===this.form_field.options[0].text?this.options.allow_single_deselect:!1,this.disable_search_threshold=this.options.disable_search_threshold||0,this.disable_search=this.options.disable_search||!1,this.enable_split_word_search=null!=this.options.enable_split_word_search?this.options.enable_split_word_search:!0,this.group_search=null!=this.options.group_search?this.options.group_search:!0,this.search_contains=this.options.search_contains||!1,this.single_backstroke_delete=null!=this.options.single_backstroke_delete?this.options.single_backstroke_delete:!0,this.max_selected_options=this.options.max_selected_options||1/0,this.inherit_select_classes=this.options.inherit_select_classes||!1,this.display_selected_options=null!=this.options.display_selected_options?this.options.display_selected_options:!0,this.display_disabled_options=null!=this.options.display_disabled_options?this.options.display_disabled_options:!0},AbstractChosen.prototype.set_default_text=function(){return this.default_text=this.form_field.getAttribute("data-placeholder")?this.form_field.getAttribute("data-placeholder"):this.is_multiple?this.options.placeholder_text_multiple||this.options.placeholder_text||AbstractChosen.default_multiple_text:this.options.placeholder_text_single||this.options.placeholder_text||AbstractChosen.default_single_text,this.results_none_found=this.form_field.getAttribute("data-no_results_text")||this.options.no_results_text||AbstractChosen.default_no_result_text},AbstractChosen.prototype.mouse_enter=function(){return this.mouse_on_container=!0},AbstractChosen.prototype.mouse_leave=function(){return this.mouse_on_container=!1},AbstractChosen.prototype.input_focus=function(){var a=this;if(this.is_multiple){if(!this.active_field)return setTimeout(function(){return a.container_mousedown()},50)}else if(!this.active_field)return this.activate_field()},AbstractChosen.prototype.input_blur=function(){var a=this;return this.mouse_on_container?void 0:(this.active_field=!1,setTimeout(function(){return a.blur_test()},100))},AbstractChosen.prototype.results_option_build=function(a){var b,c,d,e,f;for(b="",f=this.results_data,d=0,e=f.length;e>d;d++)c=f[d],b+=c.group?this.result_add_group(c):this.result_add_option(c),(null!=a?a.first:void 0)&&(c.selected&&this.is_multiple?this.choice_build(c):c.selected&&!this.is_multiple&&this.single_set_selected_text(c.text));return b},AbstractChosen.prototype.result_add_option=function(a){var b,c;return a.search_match?this.include_option_in_results(a)?(b=[],a.disabled||a.selected&&this.is_multiple||b.push("active-result"),!a.disabled||a.selected&&this.is_multiple||b.push("disabled-result"),a.selected&&b.push("result-selected"),null!=a.group_array_index&&b.push("group-option"),""!==a.classes&&b.push(a.classes),c=document.createElement("li"),c.className=b.join(" "),c.style.cssText=a.style,c.setAttribute("data-option-array-index",a.array_index),c.innerHTML=a.search_text,this.outerHTML(c)):"":""},AbstractChosen.prototype.result_add_group=function(a){var b;return a.search_match||a.group_match?a.active_options>0?(b=document.createElement("li"),b.className="group-result",b.innerHTML=a.search_text,this.outerHTML(b)):"":""},AbstractChosen.prototype.results_update_field=function(){return this.set_default_text(),this.is_multiple||this.results_reset_cleanup(),this.result_clear_highlight(),this.results_build(),this.results_showing?this.winnow_results():void 0},AbstractChosen.prototype.reset_single_select_options=function(){var a,b,c,d,e;for(d=this.results_data,e=[],b=0,c=d.length;c>b;b++)a=d[b],a.selected?e.push(a.selected=!1):e.push(void 0);return e},AbstractChosen.prototype.results_toggle=function(){return this.results_showing?this.results_hide():this.results_show()},AbstractChosen.prototype.results_search=function(){return this.results_showing?this.winnow_results():this.results_show()},AbstractChosen.prototype.winnow_results=function(){var a,b,c,d,e,f,g,h,i,j,k,l,m;for(this.no_results_clear(),e=0,g=this.get_search_text(),a=g.replace(/[-[\]{}()*+?.,\\^$|#\s]/g,"\\$&"),d=this.search_contains?"":"^",c=new RegExp(d+a,"i"),j=new RegExp(a,"i"),m=this.results_data,k=0,l=m.length;l>k;k++)b=m[k],b.search_match=!1,f=null,this.include_option_in_results(b)&&(b.group&&(b.group_match=!1,b.active_options=0),null!=b.group_array_index&&this.results_data[b.group_array_index]&&(f=this.results_data[b.group_array_index],0===f.active_options&&f.search_match&&(e+=1),f.active_options+=1),(!b.group||this.group_search)&&(b.search_text=b.group?b.label:b.html,b.search_match=this.search_string_match(b.search_text,c),b.search_match&&!b.group&&(e+=1),b.search_match?(g.length&&(h=b.search_text.search(j),i=b.search_text.substr(0,h+g.length)+"
                                            "+b.search_text.substr(h+g.length),b.search_text=i.substr(0,h)+""+i.substr(h)),null!=f&&(f.group_match=!0)):null!=b.group_array_index&&this.results_data[b.group_array_index].search_match&&(b.search_match=!0)));return this.result_clear_highlight(),1>e&&g.length?(this.update_results_content(""),this.no_results(g)):(this.update_results_content(this.results_option_build()),this.winnow_results_set_highlight())},AbstractChosen.prototype.search_string_match=function(a,b){var c,d,e,f;if(b.test(a))return!0;if(this.enable_split_word_search&&(a.indexOf(" ")>=0||0===a.indexOf("["))&&(d=a.replace(/\[|\]/g,"").split(" "),d.length))for(e=0,f=d.length;f>e;e++)if(c=d[e],b.test(c))return!0},AbstractChosen.prototype.choices_count=function(){var a,b,c,d;if(null!=this.selected_option_count)return this.selected_option_count;for(this.selected_option_count=0,d=this.form_field.options,b=0,c=d.length;c>b;b++)a=d[b],a.selected&&(this.selected_option_count+=1);return this.selected_option_count},AbstractChosen.prototype.choices_click=function(a){return a.preventDefault(),this.results_showing||this.is_disabled?void 0:this.results_show()},AbstractChosen.prototype.keyup_checker=function(a){var b,c;switch(b=null!=(c=a.which)?c:a.keyCode,this.search_field_scale(),b){case 8:if(this.is_multiple&&this.backstroke_length<1&&this.choices_count()>0)return this.keydown_backstroke();if(!this.pending_backstroke)return this.result_clear_highlight(),this.results_search();break;case 13:if(a.preventDefault(),this.results_showing)return this.result_select(a);break;case 27:return this.results_showing&&this.results_hide(),!0;case 9:case 38:case 40:case 16:case 91:case 17:break;default:return this.results_search()}},AbstractChosen.prototype.clipboard_event_checker=function(){var a=this;return setTimeout(function(){return a.results_search()},50)},AbstractChosen.prototype.container_width=function(){return null!=this.options.width?this.options.width:""+this.form_field.offsetWidth+"px"},AbstractChosen.prototype.include_option_in_results=function(a){return this.is_multiple&&!this.display_selected_options&&a.selected?!1:!this.display_disabled_options&&a.disabled?!1:a.empty?!1:!0},AbstractChosen.prototype.search_results_touchstart=function(a){return this.touch_started=!0,this.search_results_mouseover(a)},AbstractChosen.prototype.search_results_touchmove=function(a){return this.touch_started=!1,this.search_results_mouseout(a)},AbstractChosen.prototype.search_results_touchend=function(a){return this.touch_started?this.search_results_mouseup(a):void 0},AbstractChosen.prototype.outerHTML=function(a){var b;return a.outerHTML?a.outerHTML:(b=document.createElement("div"),b.appendChild(a),b.innerHTML)},AbstractChosen.browser_is_supported=function(){return"Microsoft Internet Explorer"===window.navigator.appName?document.documentMode>=8:/iP(od|hone)/i.test(window.navigator.userAgent)?!1:/Android/i.test(window.navigator.userAgent)&&/Mobile/i.test(window.navigator.userAgent)?!1:!0},AbstractChosen.default_multiple_text="Select Some Options",AbstractChosen.default_single_text="Select an Option",AbstractChosen.default_no_result_text="No results match",AbstractChosen}(),this.Chosen=function(b){function Chosen(){return a=Chosen.__super__.constructor.apply(this,arguments)}return c(Chosen,b),Chosen.prototype.setup=function(){return this.current_selectedIndex=this.form_field.selectedIndex,this.is_rtl=this.form_field.hasClassName("chosen-rtl")},Chosen.prototype.set_default_values=function(){return Chosen.__super__.set_default_values.call(this),this.single_temp=new Template('#{default}
                                              '),this.multi_temp=new Template('
                                                '),this.no_results_temp=new Template('
                                              • '+this.results_none_found+' "#{terms}"
                                              • ')},Chosen.prototype.set_up_html=function(){var a,b;return a=["chosen-container"],a.push("chosen-container-"+(this.is_multiple?"multi":"single")),this.inherit_select_classes&&this.form_field.className&&a.push(this.form_field.className),this.is_rtl&&a.push("chosen-rtl"),b={"class":a.join(" "),style:"width: "+this.container_width()+";",title:this.form_field.title},this.form_field.id.length&&(b.id=this.form_field.id.replace(/[^\w]/g,"_")+"_chosen"),this.container=this.is_multiple?new Element("div",b).update(this.multi_temp.evaluate({"default":this.default_text})):new Element("div",b).update(this.single_temp.evaluate({"default":this.default_text})),this.form_field.hide().insert({after:this.container}),this.dropdown=this.container.down("div.chosen-drop"),this.search_field=this.container.down("input"),this.search_results=this.container.down("ul.chosen-results"),this.search_field_scale(),this.search_no_results=this.container.down("li.no-results"),this.is_multiple?(this.search_choices=this.container.down("ul.chosen-choices"),this.search_container=this.container.down("li.search-field")):(this.search_container=this.container.down("div.chosen-search"),this.selected_item=this.container.down(".chosen-single")),this.results_build(),this.set_tab_index(),this.set_label_behavior(),this.form_field.fire("chosen:ready",{chosen:this})},Chosen.prototype.register_observers=function(){var a=this;return this.container.observe("mousedown",function(b){return a.container_mousedown(b)}),this.container.observe("mouseup",function(b){return a.container_mouseup(b)}),this.container.observe("mouseenter",function(b){return a.mouse_enter(b)}),this.container.observe("mouseleave",function(b){return a.mouse_leave(b)}),this.search_results.observe("mouseup",function(b){return a.search_results_mouseup(b)}),this.search_results.observe("mouseover",function(b){return a.search_results_mouseover(b)}),this.search_results.observe("mouseout",function(b){return a.search_results_mouseout(b)}),this.search_results.observe("mousewheel",function(b){return a.search_results_mousewheel(b)}),this.search_results.observe("DOMMouseScroll",function(b){return a.search_results_mousewheel(b)}),this.search_results.observe("touchstart",function(b){return a.search_results_touchstart(b)}),this.search_results.observe("touchmove",function(b){return a.search_results_touchmove(b)}),this.search_results.observe("touchend",function(b){return a.search_results_touchend(b)}),this.form_field.observe("chosen:updated",function(b){return a.results_update_field(b)}),this.form_field.observe("chosen:activate",function(b){return a.activate_field(b)}),this.form_field.observe("chosen:open",function(b){return a.container_mousedown(b)}),this.form_field.observe("chosen:close",function(b){return a.input_blur(b)}),this.search_field.observe("blur",function(b){return a.input_blur(b)}),this.search_field.observe("keyup",function(b){return a.keyup_checker(b)}),this.search_field.observe("keydown",function(b){return a.keydown_checker(b)}),this.search_field.observe("focus",function(b){return a.input_focus(b)}),this.search_field.observe("cut",function(b){return a.clipboard_event_checker(b)}),this.search_field.observe("paste",function(b){return a.clipboard_event_checker(b)}),this.is_multiple?this.search_choices.observe("click",function(b){return a.choices_click(b)}):this.container.observe("click",function(a){return a.preventDefault()})},Chosen.prototype.destroy=function(){return this.container.ownerDocument.stopObserving("click",this.click_test_action),this.form_field.stopObserving(),this.container.stopObserving(),this.search_results.stopObserving(),this.search_field.stopObserving(),null!=this.form_field_label&&this.form_field_label.stopObserving(),this.is_multiple?(this.search_choices.stopObserving(),this.container.select(".search-choice-close").each(function(a){return a.stopObserving()})):this.selected_item.stopObserving(),this.search_field.tabIndex&&(this.form_field.tabIndex=this.search_field.tabIndex),this.container.remove(),this.form_field.show()},Chosen.prototype.search_field_disabled=function(){return this.is_disabled=this.form_field.disabled,this.is_disabled?(this.container.addClassName("chosen-disabled"),this.search_field.disabled=!0,this.is_multiple||this.selected_item.stopObserving("focus",this.activate_action),this.close_field()):(this.container.removeClassName("chosen-disabled"),this.search_field.disabled=!1,this.is_multiple?void 0:this.selected_item.observe("focus",this.activate_action))},Chosen.prototype.container_mousedown=function(a){return this.is_disabled||(a&&"mousedown"===a.type&&!this.results_showing&&a.stop(),null!=a&&a.target.hasClassName("search-choice-close"))?void 0:(this.active_field?this.is_multiple||!a||a.target!==this.selected_item&&!a.target.up("a.chosen-single")||this.results_toggle():(this.is_multiple&&this.search_field.clear(),this.container.ownerDocument.observe("click",this.click_test_action),this.results_show()),this.activate_field())},Chosen.prototype.container_mouseup=function(a){return"ABBR"!==a.target.nodeName||this.is_disabled?void 0:this.results_reset(a)},Chosen.prototype.search_results_mousewheel=function(a){var b;return b=-a.wheelDelta||a.detail,null!=b?(a.preventDefault(),"DOMMouseScroll"===a.type&&(b=40*b),this.search_results.scrollTop=b+this.search_results.scrollTop):void 0},Chosen.prototype.blur_test=function(){return!this.active_field&&this.container.hasClassName("chosen-container-active")?this.close_field():void 0},Chosen.prototype.close_field=function(){return this.container.ownerDocument.stopObserving("click",this.click_test_action),this.active_field=!1,this.results_hide(),this.container.removeClassName("chosen-container-active"),this.clear_backstroke(),this.show_search_field_default(),this.search_field_scale()},Chosen.prototype.activate_field=function(){return this.container.addClassName("chosen-container-active"),this.active_field=!0,this.search_field.value=this.search_field.value,this.search_field.focus()},Chosen.prototype.test_active_click=function(a){return a.target.up(".chosen-container")===this.container?this.active_field=!0:this.close_field()},Chosen.prototype.results_build=function(){return this.parsing=!0,this.selected_option_count=null,this.results_data=SelectParser.select_to_array(this.form_field),this.is_multiple?this.search_choices.select("li.search-choice").invoke("remove"):this.is_multiple||(this.single_set_selected_text(),this.disable_search||this.form_field.options.length<=this.disable_search_threshold?(this.search_field.readOnly=!0,this.container.addClassName("chosen-container-single-nosearch")):(this.search_field.readOnly=!1,this.container.removeClassName("chosen-container-single-nosearch"))),this.update_results_content(this.results_option_build({first:!0})),this.search_field_disabled(),this.show_search_field_default(),this.search_field_scale(),this.parsing=!1},Chosen.prototype.result_do_highlight=function(a){var b,c,d,e,f;return this.result_clear_highlight(),this.result_highlight=a,this.result_highlight.addClassName("highlighted"),d=parseInt(this.search_results.getStyle("maxHeight"),10),f=this.search_results.scrollTop,e=d+f,c=this.result_highlight.positionedOffset().top,b=c+this.result_highlight.getHeight(),b>=e?this.search_results.scrollTop=b-d>0?b-d:0:f>c?this.search_results.scrollTop=c:void 0},Chosen.prototype.result_clear_highlight=function(){return this.result_highlight&&this.result_highlight.removeClassName("highlighted"),this.result_highlight=null},Chosen.prototype.results_show=function(){return this.is_multiple&&this.max_selected_options<=this.choices_count()?(this.form_field.fire("chosen:maxselected",{chosen:this}),!1):(this.container.addClassName("chosen-with-drop"),this.results_showing=!0,this.search_field.focus(),this.search_field.value=this.search_field.value,this.winnow_results(),this.form_field.fire("chosen:showing_dropdown",{chosen:this}))},Chosen.prototype.update_results_content=function(a){return this.search_results.update(a)},Chosen.prototype.results_hide=function(){return this.results_showing&&(this.result_clear_highlight(),this.container.removeClassName("chosen-with-drop"),this.form_field.fire("chosen:hiding_dropdown",{chosen:this})),this.results_showing=!1},Chosen.prototype.set_tab_index=function(){var a;return this.form_field.tabIndex?(a=this.form_field.tabIndex,this.form_field.tabIndex=-1,this.search_field.tabIndex=a):void 0},Chosen.prototype.set_label_behavior=function(){var a=this;return this.form_field_label=this.form_field.up("label"),null==this.form_field_label&&(this.form_field_label=$$("label[for='"+this.form_field.id+"']").first()),null!=this.form_field_label?this.form_field_label.observe("click",function(b){return a.is_multiple?a.container_mousedown(b):a.activate_field()}):void 0},Chosen.prototype.show_search_field_default=function(){return this.is_multiple&&this.choices_count()<1&&!this.active_field?(this.search_field.value=this.default_text,this.search_field.addClassName("default")):(this.search_field.value="",this.search_field.removeClassName("default"))},Chosen.prototype.search_results_mouseup=function(a){var b;return b=a.target.hasClassName("active-result")?a.target:a.target.up(".active-result"),b?(this.result_highlight=b,this.result_select(a),this.search_field.focus()):void 0},Chosen.prototype.search_results_mouseover=function(a){var b;return b=a.target.hasClassName("active-result")?a.target:a.target.up(".active-result"),b?this.result_do_highlight(b):void 0},Chosen.prototype.search_results_mouseout=function(a){return a.target.hasClassName("active-result")||a.target.up(".active-result")?this.result_clear_highlight():void 0},Chosen.prototype.choice_build=function(a){var b,c,d=this;return b=new Element("li",{"class":"search-choice"}).update(""+a.html+""),a.disabled?b.addClassName("search-choice-disabled"):(c=new Element("a",{href:"#","class":"search-choice-close",rel:a.array_index}),c.observe("click",function(a){return d.choice_destroy_link_click(a)}),b.insert(c)),this.search_container.insert({before:b})},Chosen.prototype.choice_destroy_link_click=function(a){return a.preventDefault(),a.stopPropagation(),this.is_disabled?void 0:this.choice_destroy(a.target)},Chosen.prototype.choice_destroy=function(a){return this.result_deselect(a.readAttribute("rel"))?(this.show_search_field_default(),this.is_multiple&&this.choices_count()>0&&this.search_field.value.length<1&&this.results_hide(),a.up("li").remove(),this.search_field_scale()):void 0},Chosen.prototype.results_reset=function(){return this.reset_single_select_options(),this.form_field.options[0].selected=!0,this.single_set_selected_text(),this.show_search_field_default(),this.results_reset_cleanup(),"function"==typeof Event.simulate&&this.form_field.simulate("change"),this.active_field?this.results_hide():void 0},Chosen.prototype.results_reset_cleanup=function(){var a;return this.current_selectedIndex=this.form_field.selectedIndex,a=this.selected_item.down("abbr"),a?a.remove():void 0},Chosen.prototype.result_select=function(a){var b,c;return this.result_highlight?(b=this.result_highlight,this.result_clear_highlight(),this.is_multiple&&this.max_selected_options<=this.choices_count()?(this.form_field.fire("chosen:maxselected",{chosen:this}),!1):(this.is_multiple?b.removeClassName("active-result"):this.reset_single_select_options(),b.addClassName("result-selected"),c=this.results_data[b.getAttribute("data-option-array-index")],c.selected=!0,this.form_field.options[c.options_index].selected=!0,this.selected_option_count=null,this.is_multiple?this.choice_build(c):this.single_set_selected_text(c.text),(a.metaKey||a.ctrlKey)&&this.is_multiple||this.results_hide(),this.search_field.value="","function"!=typeof Event.simulate||!this.is_multiple&&this.form_field.selectedIndex===this.current_selectedIndex||this.form_field.simulate("change"),this.current_selectedIndex=this.form_field.selectedIndex,this.search_field_scale())):void 0},Chosen.prototype.single_set_selected_text=function(a){return null==a&&(a=this.default_text),a===this.default_text?this.selected_item.addClassName("chosen-default"):(this.single_deselect_control_build(),this.selected_item.removeClassName("chosen-default")),this.selected_item.down("span").update(a)},Chosen.prototype.result_deselect=function(a){var b;return b=this.results_data[a],this.form_field.options[b.options_index].disabled?!1:(b.selected=!1,this.form_field.options[b.options_index].selected=!1,this.selected_option_count=null,this.result_clear_highlight(),this.results_showing&&this.winnow_results(),"function"==typeof Event.simulate&&this.form_field.simulate("change"),this.search_field_scale(),!0)},Chosen.prototype.single_deselect_control_build=function(){return this.allow_single_deselect?(this.selected_item.down("abbr")||this.selected_item.down("span").insert({after:''}),this.selected_item.addClassName("chosen-single-with-deselect")):void 0},Chosen.prototype.get_search_text=function(){return this.search_field.value===this.default_text?"":this.search_field.value.strip().escapeHTML()},Chosen.prototype.winnow_results_set_highlight=function(){var a;return this.is_multiple||(a=this.search_results.down(".result-selected.active-result")),null==a&&(a=this.search_results.down(".active-result")),null!=a?this.result_do_highlight(a):void 0},Chosen.prototype.no_results=function(a){return this.search_results.insert(this.no_results_temp.evaluate({terms:a})),this.form_field.fire("chosen:no_results",{chosen:this})},Chosen.prototype.no_results_clear=function(){var a,b;for(a=null,b=[];a=this.search_results.down(".no-results");)b.push(a.remove());return b},Chosen.prototype.keydown_arrow=function(){var a;return this.results_showing&&this.result_highlight?(a=this.result_highlight.next(".active-result"))?this.result_do_highlight(a):void 0:this.results_show()},Chosen.prototype.keyup_arrow=function(){var a,b,c;return this.results_showing||this.is_multiple?this.result_highlight?(c=this.result_highlight.previousSiblings(),a=this.search_results.select("li.active-result"),b=c.intersect(a),b.length?this.result_do_highlight(b.first()):(this.choices_count()>0&&this.results_hide(),this.result_clear_highlight())):void 0:this.results_show()},Chosen.prototype.keydown_backstroke=function(){var a;return this.pending_backstroke?(this.choice_destroy(this.pending_backstroke.down("a")),this.clear_backstroke()):(a=this.search_container.siblings().last(),a&&a.hasClassName("search-choice")&&!a.hasClassName("search-choice-disabled")?(this.pending_backstroke=a,this.pending_backstroke&&this.pending_backstroke.addClassName("search-choice-focus"),this.single_backstroke_delete?this.keydown_backstroke():this.pending_backstroke.addClassName("search-choice-focus")):void 0)},Chosen.prototype.clear_backstroke=function(){return this.pending_backstroke&&this.pending_backstroke.removeClassName("search-choice-focus"),this.pending_backstroke=null},Chosen.prototype.keydown_checker=function(a){var b,c;switch(b=null!=(c=a.which)?c:a.keyCode,this.search_field_scale(),8!==b&&this.pending_backstroke&&this.clear_backstroke(),b){case 8:this.backstroke_length=this.search_field.value.length;break;case 9:this.results_showing&&!this.is_multiple&&this.result_select(a),this.mouse_on_container=!1;break;case 13:a.preventDefault();break;case 38:a.preventDefault(),this.keyup_arrow();break;case 40:a.preventDefault(),this.keydown_arrow()}},Chosen.prototype.search_field_scale=function(){var a,b,c,d,e,f,g,h,i;if(this.is_multiple){for(c=0,g=0,e="position:absolute; left: -1000px; top: -1000px; display:none;",f=["font-size","font-style","font-weight","font-family","line-height","text-transform","letter-spacing"],h=0,i=f.length;i>h;h++)d=f[h],e+=d+":"+this.search_field.getStyle(d)+";";return a=new Element("div",{style:e}).update(this.search_field.value.escapeHTML()),document.body.appendChild(a),g=Element.measure(a,"width")+25,a.remove(),b=this.container.getWidth(),g>b-10&&(g=b-10),this.search_field.setStyle({width:g+"px"})}},Chosen}(AbstractChosen)}.call(this); \ No newline at end of file diff --git a/sites/all/themes/gui/materiobasetheme/js/libs/src/chosen_v1.1.0/docsupport/chosen.png b/sites/all/themes/gui/materiobasetheme/js/libs/src/chosen_v1.1.0/docsupport/chosen.png deleted file mode 100644 index b81474b3..00000000 Binary files a/sites/all/themes/gui/materiobasetheme/js/libs/src/chosen_v1.1.0/docsupport/chosen.png and /dev/null differ diff --git a/sites/all/themes/gui/materiobasetheme/js/libs/src/chosen_v1.1.0/docsupport/oss-credit.png b/sites/all/themes/gui/materiobasetheme/js/libs/src/chosen_v1.1.0/docsupport/oss-credit.png deleted file mode 100644 index aeed5eec..00000000 Binary files a/sites/all/themes/gui/materiobasetheme/js/libs/src/chosen_v1.1.0/docsupport/oss-credit.png and /dev/null differ diff --git a/sites/all/themes/gui/materiobasetheme/js/libs/src/chosen_v1.1.0/docsupport/prism.css b/sites/all/themes/gui/materiobasetheme/js/libs/src/chosen_v1.1.0/docsupport/prism.css deleted file mode 100644 index b5ba1797..00000000 --- a/sites/all/themes/gui/materiobasetheme/js/libs/src/chosen_v1.1.0/docsupport/prism.css +++ /dev/null @@ -1,108 +0,0 @@ -/** - * okaidia theme for JavaScript, CSS and HTML - * Loosely based on Monokai textmate theme by http://www.monokai.nl/ - * @author ocodia - */ - -code[class*="language-"], -pre[class*="language-"] { - color: #f8f8f2; - text-shadow: 0 1px rgba(0,0,0,0.3); - font-family: Consolas, Monaco, 'Andale Mono', monospace; - direction: ltr; - text-align: left; - white-space: pre; - word-spacing: normal; - - -moz-tab-size: 4; - -o-tab-size: 4; - tab-size: 4; - - -webkit-hyphens: none; - -moz-hyphens: none; - -ms-hyphens: none; - hyphens: none; -} - -/* Code blocks */ -pre[class*="language-"] { - padding: 1em; - margin: .5em 0; - overflow: auto; - border-radius: 0.3em; -} - -:not(pre) > code[class*="language-"], -pre[class*="language-"] { - background: #272822; -} - -/* Inline code */ -:not(pre) > code[class*="language-"] { - padding: .1em; - border-radius: .3em; -} - -.token.comment, -.token.prolog, -.token.doctype, -.token.cdata { - color: slategray; -} - -.token.punctuation { - color: #f8f8f2; -} - -.namespace { - opacity: .7; -} - -.token.property, -.token.tag { - color: #f92672; -} - -.token.boolean, -.token.number{ - color: #ae81ff; -} - -.token.selector, -.token.attr-name, -.token.string { - color: #a6e22e; -} - - -.token.operator, -.token.entity, -.token.url, -.language-css .token.string, -.style .token.string { - color: #f8f8f2; -} - -.token.atrule, -.token.attr-value -{ - color: #e6db74; -} - - -.token.keyword{ -color: #66d9ef; -} - -.token.regex, -.token.important { - color: #fd971f; -} - -.token.important { - font-weight: bold; -} - -.token.entity { - cursor: help; -} diff --git a/sites/all/themes/gui/materiobasetheme/js/libs/src/chosen_v1.1.0/docsupport/prism.js b/sites/all/themes/gui/materiobasetheme/js/libs/src/chosen_v1.1.0/docsupport/prism.js deleted file mode 100644 index 7ed4fa73..00000000 --- a/sites/all/themes/gui/materiobasetheme/js/libs/src/chosen_v1.1.0/docsupport/prism.js +++ /dev/null @@ -1,9 +0,0 @@ -/** - * Prism: Lightweight, robust, elegant syntax highlighting - * MIT license http://www.opensource.org/licenses/mit-license.php/ - * @author Lea Verou http://lea.verou.me - */(function(){var e=/\blang(?:uage)?-(?!\*)(\w+)\b/i,t=self.Prism={util:{type:function(e){return Object.prototype.toString.call(e).match(/\[object (\w+)\]/)[1]},clone:function(e){var n=t.util.type(e);switch(n){case"Object":var r={};for(var i in e)e.hasOwnProperty(i)&&(r[i]=t.util.clone(e[i]));return r;case"Array":return e.slice()}return e}},languages:{extend:function(e,n){var r=t.util.clone(t.languages[e]);for(var i in n)r[i]=n[i];return r},insertBefore:function(e,n,r,i){i=i||t.languages;var s=i[e],o={};for(var u in s)if(s.hasOwnProperty(u)){if(u==n)for(var a in r)r.hasOwnProperty(a)&&(o[a]=r[a]);o[u]=s[u]}return i[e]=o},DFS:function(e,n){for(var r in e){n.call(e,r,e[r]);t.util.type(e)==="Object"&&t.languages.DFS(e[r],n)}}},highlightAll:function(e,n){var r=document.querySelectorAll('code[class*="language-"], [class*="language-"] code, code[class*="lang-"], [class*="lang-"] code');for(var i=0,s;s=r[i++];)t.highlightElement(s,e===!0,n)},highlightElement:function(r,i,s){var o,u,a=r;while(a&&!e.test(a.className))a=a.parentNode;if(a){o=(a.className.match(e)||[,""])[1];u=t.languages[o]}if(!u)return;r.className=r.className.replace(e,"").replace(/\s+/g," ")+" language-"+o;a=r.parentNode;/pre/i.test(a.nodeName)&&(a.className=a.className.replace(e,"").replace(/\s+/g," ")+" language-"+o);var f=r.textContent;if(!f)return;f=f.replace(/&/g,"&").replace(/e.length)break e;if(p instanceof i)continue;a.lastIndex=0;var d=a.exec(p);if(d){l&&(c=d[1].length);var v=d.index-1+c,d=d[0].slice(c),m=d.length,g=v+m,y=p.slice(0,v+1),b=p.slice(g+1),w=[h,1];y&&w.push(y);var E=new i(u,f?t.tokenize(d,f):d);w.push(E);b&&w.push(b);Array.prototype.splice.apply(s,w)}}}return s},hooks:{all:{},add:function(e,n){var r=t.hooks.all;r[e]=r[e]||[];r[e].push(n)},run:function(e,n){var r=t.hooks.all[e];if(!r||!r.length)return;for(var i=0,s;s=r[i++];)s(n)}}},n=t.Token=function(e,t){this.type=e;this.content=t};n.stringify=function(e,r,i){if(typeof e=="string")return e;if(Object.prototype.toString.call(e)=="[object Array]")return e.map(function(t){return n.stringify(t,r,e)}).join("");var s={type:e.type,content:n.stringify(e.content,r,i),tag:"span",classes:["token",e.type],attributes:{},language:r,parent:i};s.type=="comment"&&(s.attributes.spellcheck="true");t.hooks.run("wrap",s);var o="";for(var u in s.attributes)o+=u+'="'+(s.attributes[u]||"")+'"';return"<"+s.tag+' class="'+s.classes.join(" ")+'" '+o+">"+s.content+""};if(!self.document){self.addEventListener("message",function(e){var n=JSON.parse(e.data),r=n.language,i=n.code;self.postMessage(JSON.stringify(t.tokenize(i,t.languages[r])));self.close()},!1);return}var r=document.getElementsByTagName("script");r=r[r.length-1];if(r){t.filename=r.src;document.addEventListener&&!r.hasAttribute("data-manual")&&document.addEventListener("DOMContentLoaded",t.highlightAll)}})();; -Prism.languages.markup={comment:/<!--[\w\W]*?-->/g,prolog:/<\?.+?\?>/,doctype:/<!DOCTYPE.+?>/,cdata:/<!\[CDATA\[[\w\W]*?]]>/i,tag:{pattern:/<\/?[\w:-]+\s*(?:\s+[\w:-]+(?:=(?:("|')(\\?[\w\W])*?\1|\w+))?\s*)*\/?>/gi,inside:{tag:{pattern:/^<\/?[\w:-]+/i,inside:{punctuation:/^<\/?/,namespace:/^[\w-]+?:/}},"attr-value":{pattern:/=(?:('|")[\w\W]*?(\1)|[^\s>]+)/gi,inside:{punctuation:/=|>|"/g}},punctuation:/\/?>/g,"attr-name":{pattern:/[\w:-]+/g,inside:{namespace:/^[\w-]+?:/}}}},entity:/&#?[\da-z]{1,8};/gi};Prism.hooks.add("wrap",function(e){e.type==="entity"&&(e.attributes.title=e.content.replace(/&/,"&"))});; -Prism.languages.css={comment:/\/\*[\w\W]*?\*\//g,atrule:{pattern:/@[\w-]+?.*?(;|(?=\s*{))/gi,inside:{punctuation:/[;:]/g}},url:/url\((["']?).*?\1\)/gi,selector:/[^\{\}\s][^\{\};]*(?=\s*\{)/g,property:/(\b|\B)[\w-]+(?=\s*:)/ig,string:/("|')(\\?.)*?\1/g,important:/\B!important\b/gi,ignore:/&(lt|gt|amp);/gi,punctuation:/[\{\};:]/g};Prism.languages.markup&&Prism.languages.insertBefore("markup","tag",{style:{pattern:/(<|<)style[\w\W]*?(>|>)[\w\W]*?(<|<)\/style(>|>)/ig,inside:{tag:{pattern:/(<|<)style[\w\W]*?(>|>)|(<|<)\/style(>|>)/ig,inside:Prism.languages.markup.tag.inside},rest:Prism.languages.css}}});; -Prism.languages.clike={comment:{pattern:/(^|[^\\])(\/\*[\w\W]*?\*\/|(^|[^:])\/\/.*?(\r?\n|$))/g,lookbehind:!0},string:/("|')(\\?.)*?\1/g,"class-name":{pattern:/((?:(?:class|interface|extends|implements|trait|instanceof|new)\s+)|(?:catch\s+\())[a-z0-9_\.\\]+/ig,lookbehind:!0,inside:{punctuation:/(\.|\\)/}},keyword:/\b(if|else|while|do|for|return|in|instanceof|function|new|try|catch|finally|null|break|continue)\b/g,"boolean":/\b(true|false)\b/g,"function":{pattern:/[a-z0-9_]+\(/ig,inside:{punctuation:/\(/}}, number:/\b-?(0x[\dA-Fa-f]+|\d*\.?\d+([Ee]-?\d+)?)\b/g,operator:/[-+]{1,2}|!|<=?|>=?|={1,3}|(&){1,2}|\|?\||\?|\*|\/|\~|\^|\%/g,ignore:/&(lt|gt|amp);/gi,punctuation:/[{}[\];(),.:]/g};; -Prism.languages.javascript=Prism.languages.extend("clike",{keyword:/\b(var|let|if|else|while|do|for|return|in|instanceof|function|new|with|typeof|try|catch|finally|null|break|continue)\b/g,number:/\b-?(0x[\dA-Fa-f]+|\d*\.?\d+([Ee]-?\d+)?|NaN|-?Infinity)\b/g});Prism.languages.insertBefore("javascript","keyword",{regex:{pattern:/(^|[^/])\/(?!\/)(\[.+?]|\\.|[^/\r\n])+\/[gim]{0,3}(?=\s*($|[\r\n,.;})]))/g,lookbehind:!0}});Prism.languages.markup&&Prism.languages.insertBefore("markup","tag",{script:{pattern:/(<|<)script[\w\W]*?(>|>)[\w\W]*?(<|<)\/script(>|>)/ig,inside:{tag:{pattern:/(<|<)script[\w\W]*?(>|>)|(<|<)\/script(>|>)/ig,inside:Prism.languages.markup.tag.inside},rest:Prism.languages.javascript}}});; diff --git a/sites/all/themes/gui/materiobasetheme/js/libs/src/chosen_v1.1.0/docsupport/style.css b/sites/all/themes/gui/materiobasetheme/js/libs/src/chosen_v1.1.0/docsupport/style.css deleted file mode 100644 index 9962974a..00000000 --- a/sites/all/themes/gui/materiobasetheme/js/libs/src/chosen_v1.1.0/docsupport/style.css +++ /dev/null @@ -1,203 +0,0 @@ -/* Reset */ -html, body, div, span, object, iframe, h1, h2, h3, h4, h5, h6, p, blockquote, pre, abbr, address, cite, code, del, dfn, em, img, ins, kbd, q, samp, small, strong, sub, sup, var, b, i, dl, dt, dd, ol, ul, li, fieldset, form, label, legend, table, caption, tbody, tfoot, thead, tr, th, td, article, aside, canvas, details, figcaption, figure, footer, header, hgroup, menu, nav, section, summary, time, mark, audio, video { margin: 0; padding: 0; border: 0; font-size: 100%; font: inherit; vertical-align: baseline; } - -article, aside, details, figcaption, figure, footer, header, hgroup, menu, nav, section { display: block; } - -blockquote, q { quotes: none; } -blockquote:before, blockquote:after, q:before, q:after { content: ""; content: none; } -ins { background-color: #ff9; color: #000; text-decoration: none; } -mark { background-color: #ff9; color: #000; font-style: italic; font-weight: bold; } -del { text-decoration: line-through; } -abbr[title], dfn[title] { border-bottom: 1px dotted; cursor: help; } -table { border-collapse: collapse; border-spacing: 0; } -hr { display: block; height: 1px; border: 0; border-top: 1px solid #ccc; margin: 1em 0; padding: 0; } -input, select { vertical-align: middle; } - -body { font:13px/1.231 sans-serif; *font-size:small; } /* Hack retained to preserve specificity */ -select, input, textarea, button { font:99% sans-serif; } -pre, code, kbd, samp { font-family: monospace, sans-serif; } - - -body { background: #EEE; color: #444; line-height: 1.4em; } - -header h1 { color: black; font-size: 2em; line-height: 1.1em; display: inline-block; height: 27px; margin: 20px 0 25px; } -header h1 small { font-size: 0.6em; } - -div#content { background: white; border: 1px solid #ccc; border-width: 0 1px 1px; margin: 0 auto; padding: 40px 50px 40px; width: 738px; } - -footer { color: #999; padding-top: 40px; font-size: 0.8em; text-align: center; } - -body { font-family: sans-serif; font-size: 1em; } - -p { margin: 0 0 .7em; max-width: 700px; } - -h2 { border-bottom: 1px solid #ccc; font-size: 1.2em; margin: 3em 0 1em 0; font-weight: bold;} -h3 { font-weight: bold; } - -h2.intro { border-bottom: none; font-size: 1em; font-weight: normal; margin-top:0; } - -ul li { list-style: disc; margin-left: 1em; margin-bottom: 1.25em; } -ol li { margin-left: 1.25em; } -ol ul, ul ul { margin: .25em 0 0; } -ol ul li, ul ul li { list-style-type: circle; margin: 0 0 .25em 1em; } - -li > p { margin-top: .25em; } - -div.side-by-side { width: 100%; margin-bottom: 1em; } -div.side-by-side > div { float: left; width: 49%; } -div.side-by-side > div > em { margin-bottom: 10px; display: block; } - -.faqs em { display: block; } - -.clearfix:after { - content: "\0020"; - display: block; - height: 0; - clear: both; - overflow: hidden; - visibility: hidden; -} - -a { color: #F36C00; outline: none; text-decoration: none; } -a:hover { text-decoration: underline; } - -ul.credits li { margin-bottom: .25em; } - -strong { font-weight: bold; } -i { font-style: italic; } - -.button { - background: #fafafa; - background: -webkit-linear-gradient(top, #ffffff, #eeeeee); - background: -moz-linear-gradient(top, #ffffff, #eeeeee); - background: -o-linear-gradient(top, #ffffff, #eeeeee); - background: linear-gradient(to bottom, #ffffff, #eeeeee); - border: 1px solid #bbbbbb; - border-radius: 4px; - box-shadow: inset 0 1px 1px rgba(255, 255, 255, 0.2); - color: #555555; - cursor: pointer; - display: inline-block; - font-family: "Helvetica Neue", Arial, Verdana, "Nimbus Sans L", sans-serif; - font-size: 13px; - font-weight: 500; - height: 31px; - line-height: 28px; - outline: none; - padding: 0 13px; - text-shadow: 0 1px 0 white; - text-decoration: none; - vertical-align: middle; - white-space: nowrap; - -webkit-font-smoothing: antialiased; - -webkit-box-sizing: border-box; - -moz-box-sizing: border-box; - box-sizing: border-box; -} - -.button-blue { - background: #1385e5; - background: -webkit-linear-gradient(top, #53b2fc, #1385e5); - background: -moz-linear-gradient(top, #53b2fc, #1385e5); - background: -o-linear-gradient(top, #53b2fc, #1385e5); - background: linear-gradient(to bottom, #53b2fc, #1385e5); - border-color: #075fa9; - color: white; - font-weight: bold; - text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.4); -} - - -/* Tweak navbar brand link to be super sleek --------------------------------------------------- */ -.oss-bar { - top: 0; - right: 20px; - position: fixed; - z-index: 1030; -} -.oss-bar ul { - float: right; - margin: 0; - list-style: none; -} -.oss-bar ul li { - list-style: none; - float: left; - line-height: 0; - margin: 0; -} -.oss-bar ul li a { - -moz-box-sizing: border-box; - -webkit-box-sizing: border-box; - -ms-box-sizing: border-box; - box-sizing: border-box; - border: 0; - margin-top: -10px; - display: block; - height: 58px; - background: #F36C00 url(oss-credit.png) no-repeat 20px 22px; - padding: 22px 20px 12px 20px; - text-indent: 120%; /* stupid padding */ - white-space: nowrap; - overflow: hidden; - -webkit-transition: all 0.10s ease-in-out; - -moz-transition: all 0.10s ease-in-out; - transition: all 0.15s ease-in-out; -} -.oss-bar ul li a:hover { - margin-top: 0px; -} -.oss-bar a.harvest { - width: 196px; - background-color: #F36C00; - background-position: -142px 22px; - padding-right: 22px; /* optical illusion */ -} -.oss-bar a.fork { - width: 162px; - background-color: #333333; -} - -.docs-table th, .docs-table td { - border: 1px solid #000; - padding: 4px 6px; - white-space: nowrap; -} - -.docs-table td:last-child { - white-space: normal; -} - -.docs-table th { - font-weight: bold; - text-align: left; -} - -#content pre[class*=language-] { - font-size: 14px; - margin-bottom: 20px; -} - -#content pre[class*=language-] code { - font-size: 14px; - padding: 0; -} - -#content code[class*=language-] { - font-size: 12px; - padding: 2px 4px; -} - -.anchor { - color: inherit; - position: relative; -} - -.anchor:hover { - background: url(data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxNiIgaGVpZ2h0PSI3Ij48ZyBmaWxsPSIjNDE0MDQyIj48cGF0aCBkPSJNOS44IDdoLS45bC0uOS0uMWMtLjctLjMtMS40LS43LTEuOC0xLjMtLjItLjEtLjMtLjMtLjMtLjVsLS4zLS40Yy0uMS0uNC0uMi0uOC0uMi0xLjIgMC0uNC4xLS44LjItMS4yaDEuN2MtLjMuNC0uNC44LS40IDEuMiAwIC40LjEuOC4zIDEuMS4xLjIuMi4zLjQuNC4xLjEuMi4yLjQuMy4zLjIuNy4zIDEgLjNoMy40YzEuMiAwIDIuMi0uOSAyLjItMi4xcy0xLTIuMS0yLjItMi4xaC0xLjRjLS4zLS42LS43LTEtMS4yLTEuNGgyLjZjMiAwIDMuNiAxLjYgMy42IDMuNXMtMS42IDMuNS0zLjYgMy41aC0yLjZ6TTguNCAyYy0uMS0uMS0uMi0uMy0uNC0uMy0uMy0uMi0uNy0uMy0xLS4zaC0zLjRjLTEuMiAwLTIuMi45LTIuMiAyLjEgMCAxLjIgMSAyLjEgMi4yIDIuMWgxLjRjLjMuNS43IDEgMS4yIDEuNGgtMi42Yy0yIDAtMy42LTEuNi0zLjYtMy41czEuNi0zLjUgMy42LTMuNWgzLjUwMDAwMDAwMDAwMDAwMDRsLjkuMWMuNy4yIDEuNC43IDEuOCAxLjMuMS4xLjIuMy4zLjUuMS4xLjIuMy4yLjUuMS40LjIuOC4yIDEuMiAwIC40LS4xLjgtLjIgMS4yaC0xLjZjLjMtLjUuNC0uOS40LTEuM3MtLjEtLjgtLjMtMS4xYy0uMS0uMi0uMi0uMy0uNC0uNHoiLz48L2c+PC9zdmc+) 0 50% no-repeat; - background-size: 21px 9px; - margin-left: -27px; - padding-left: 27px; - text-decoration: none; -} diff --git a/sites/all/themes/gui/materiobasetheme/js/libs/src/chosen_v1.1.0/index.html b/sites/all/themes/gui/materiobasetheme/js/libs/src/chosen_v1.1.0/index.html deleted file mode 100644 index a2def719..00000000 --- a/sites/all/themes/gui/materiobasetheme/js/libs/src/chosen_v1.1.0/index.html +++ /dev/null @@ -1,1479 +0,0 @@ - - - - - Chosen: A jQuery Plugin by Harvest to Tame Unwieldy Select Boxes - - - - - - -
                                                -
                                                -
                                                -
                                                -

                                                Chosen (v1.1.0)

                                                -
                                                -

                                                Chosen is a jQuery plugin that makes long, unwieldy select boxes much more user-friendly.

                                                - -

                                                - Downloads - Project Source - Contribute -

                                                - -

                                                Standard Select

                                                -
                                                -
                                                - Turns This - -
                                                -
                                                - Into This - -
                                                -
                                                - -

                                                Multiple Select

                                                -
                                                -
                                                - Turns This - -
                                                -
                                                - Into This - -
                                                -
                                                - -

                                                <optgroup> Support

                                                -
                                                -
                                                - Single Select with Groups - -
                                                -
                                                - Multiple Select with Groups - -
                                                -
                                                - -

                                                Selected and Disabled Support

                                                -
                                                -

                                                Chosen automatically highlights selected options and removes disabled options.

                                                -
                                                - Single Select - -
                                                -
                                                - Multiple Select - -
                                                -
                                                - -

                                                Hide Search on Single Select

                                                -
                                                -

                                                The disable_search_threshold option can be specified to hide the search input on single selects if there are fewer than (n) options.

                                                -
                                                $(".chosen-select").chosen({disable_search_threshold: 10});
                                                -

                                                -
                                                - -
                                                -
                                                - -

                                                Default Text Support

                                                -
                                                -

                                                Chosen automatically sets the default field text ("Choose a country...") by reading the select element's data-placeholder value. If no data-placeholder value is present, it will default to "Select an Option" or "Select Some Options" depending on whether the select is single or multiple. You can change these elements in the plugin js file as you see fit.

                                                -
                                                <select data-placeholder="Choose a country..." style="width:350px;" multiple class="chosen-select">
                                                -

                                                Note: on single selects, the first element is assumed to be selected by the browser. To take advantage of the default text support, you will need to include a blank option as the first element of your select list.

                                                -
                                                - -

                                                No Results Text Support

                                                -
                                                -

                                                Setting the "No results" search text is as easy as passing an option when you create Chosen:

                                                -
                                                 $(".chosen-select").chosen({no_results_text: "Oops, nothing found!"}); 
                                                -

                                                -
                                                - Single Select - -
                                                -
                                                - Multiple Select - -
                                                -
                                                - -

                                                Limit Selected Options in Multiselect

                                                -
                                                -

                                                You can easily limit how many options the user can select:

                                                -
                                                $(".chosen-select").chosen({max_selected_options: 5});
                                                -

                                                If you try to select another option with limit reached chosen:maxselected event is triggered:

                                                -
                                                 $(".chosen-select").bind("chosen:maxselected", function () { ... }); 
                                                -
                                                - -

                                                Allow Deselect on Single Selects

                                                -
                                                -

                                                When a single select box isn't a required field, you can set allow_single_deselect: true and Chosen will add a UI element for option deselection. This will only work if the first option has blank text.

                                                -
                                                - -
                                                -
                                                - -

                                                Right to Left Support

                                                -
                                                -

                                                Chosen supports right to left select boxes too. just add "chosen-rtl" in addition to "chosen-select" to your select tags and you are good to go.

                                                -
                                                <select class="chosen-select chosen-rtl">
                                                -
                                                - Single right to left select - -
                                                -
                                                - Multiple right to left select - -
                                                -
                                                - -

                                                Change / Update Events

                                                -
                                                -
                                                  -
                                                • -

                                                  Form Field Change

                                                  -

                                                  When working with form fields, you often want to perform some behavior after a value has been selected or deselected. Whenever a user selects a field in Chosen, it triggers a "change" event* on the original form field. That let's you do something like this:

                                                  -
                                                  $("#form_field").chosen().change( … );
                                                  -
                                                • -
                                                • -

                                                  Updating Chosen Dynamically

                                                  -

                                                  If you need to update the options in your select field and want Chosen to pick up the changes, you'll need to trigger the "chosen:updated" event on the field. Chosen will re-build itself based on the updated content.

                                                  -
                                                  $("#form_field").trigger("chosen:updated");
                                                  -
                                                • -
                                                -
                                                - -

                                                Custom Width Support

                                                -
                                                -

                                                Using a custom width with Chosen is as easy as passing an option when you create Chosen:

                                                -
                                                 $(".chosen-select").chosen({width: "95%"}); 
                                                -
                                                - Single Select - -
                                                -
                                                - Multiple Select - -
                                                -
                                                - -

                                                Labels work, too

                                                -
                                                -

                                                Use labels just like you would a standard select

                                                -

                                                -
                                                - - -
                                                -
                                                - - -
                                                -
                                                - -

                                                Setup

                                                -

                                                Using Chosen is easy as can be.

                                                -
                                                  -
                                                1. Download the plugin and copy the chosen files to your app.
                                                2. -
                                                3. Activate the plugin on the select boxes of your choice: $(".chosen-select").chosen()
                                                4. -
                                                5. Disco.
                                                6. -
                                                - -

                                                FAQs

                                                -
                                                  -
                                                • -

                                                  Do you have all the available options documented somewhere?

                                                  -

                                                  Yes! You can find them on the options page.

                                                  -
                                                • -
                                                • -

                                                  Something doesn't work. Can you fix it?

                                                  -

                                                  Yes! Please report all issues using the GitHub issue tracking tool. Please include the plugin version (jQuery or Prototype), browser and OS. The more information provided, the easier it is to fix a problem.

                                                  -
                                                • -
                                                • -

                                                  What browsers are supported?

                                                  -

                                                  All modern desktop browsers are supported (Firefox, Chrome, Safari and IE9). Legacy support for IE8 is also enabled. Chosen is disabled on iPhone, iPod Touch, and Android mobile devices (more information).

                                                  -
                                                • -
                                                • -

                                                  Didn't there used to be a Prototype version of Chosen?

                                                  -

                                                  There still is!

                                                  -
                                                • -
                                                - -

                                                Credits

                                                - - - - - -
                                                -
                                                - - - - -
                                                - - - diff --git a/sites/all/themes/gui/materiobasetheme/js/libs/src/chosen_v1.1.0/index.proto.html b/sites/all/themes/gui/materiobasetheme/js/libs/src/chosen_v1.1.0/index.proto.html deleted file mode 100644 index f32d6312..00000000 --- a/sites/all/themes/gui/materiobasetheme/js/libs/src/chosen_v1.1.0/index.proto.html +++ /dev/null @@ -1,1483 +0,0 @@ - - - - - Chosen: A Prototype Plugin by Harvest to Tame Unwieldy Select Boxes - - - - - - -
                                                -
                                                -
                                                -

                                                Chosen - Prototype Version (v1.1.0)

                                                -
                                                -

                                                Chosen is a Prototype plugin that makes long, unwieldy select boxes much more user-friendly.

                                                - -

                                                - Downloads - Project Source - Contribute -

                                                - -

                                                Looking for the jQuery version?

                                                - -

                                                Standard Select

                                                -
                                                -
                                                - Turns This - -
                                                -
                                                - Into This - -
                                                -
                                                - -

                                                Multiple Select

                                                -
                                                -
                                                - Turns This - -
                                                -
                                                - Into This - -
                                                -
                                                - -

                                                <optgroup> Support

                                                -
                                                -
                                                - Single Select with Groups - -
                                                -
                                                - Multiple Select with Groups - -
                                                -
                                                - -

                                                Selected and Disabled Support

                                                -
                                                -

                                                Chosen automatically highlights selected options and removes disabled options.

                                                -
                                                - Single Select - -
                                                -
                                                - Multiple Select - -
                                                -
                                                - -

                                                Hide Search on Single Select

                                                -
                                                -

                                                The disable_search_threshold option can be specified to hide the search input on single selects if there are fewer than (n) options.

                                                -
                                                 new Chosen($("chosen_select_field"),{disable_search_threshold: 10}); 
                                                -

                                                -
                                                - -
                                                -
                                                - -

                                                Default Text Support

                                                -
                                                -

                                                Chosen automatically sets the default field text ("Choose a country...") by reading the select element's data-placeholder value. If no data-placeholder value is present, it will default to "Select an Option" or "Select Some Options" depending on whether the select is single or multiple. You can change these elements in the plugin js file as you see fit.

                                                -
                                                <select data-placeholder="Choose a country..." style="width:350px;" multiple class="chosen-select">
                                                -

                                                Note: on single selects, the first element is assumed to be selected by the browser. To take advantage of the default text support, you will need to include a blank option as the first element of your select list.

                                                -
                                                - -

                                                No Results Text Support

                                                -
                                                -

                                                Setting the "No results" search text is as easy as passing an option when you create Chosen:

                                                -
                                                new Chosen($("chosen_select_field"),{no_results_text: "Oops, nothing found!"}); 
                                                - -
                                                - Single Select - -
                                                -
                                                - Multiple Select - -
                                                -
                                                - -

                                                Limit Selected Options in Multiselect

                                                -
                                                -

                                                You can easily limit how many options the user can select:

                                                -
                                                new Chosen($("chosen_select_field"),{max_selected_options: 5}); 
                                                -

                                                If you try to select another option with limit reached chosen:maxselected event is triggered:

                                                -
                                                $("chosen_select_field").observe("chosen:maxselected", function(evt) { ... }); 
                                                -
                                                - -

                                                Allow Deselect on Single Selects

                                                -
                                                -

                                                When a single select box isn't a required field, you can set allow_single_deselect: true and Chosen will add a UI element for option deselection. This will only work if the first option has blank text.

                                                -
                                                - -
                                                -
                                                - -

                                                Right to Left Support

                                                -
                                                -

                                                Chosen supports right to left select boxes too. just add "chosen-rtl" in addition to "chosen-select" to your select tags and you are good to go.

                                                -
                                                <select class="chosen-select chosen-rtl">
                                                -
                                                - Single right to left select - -
                                                -
                                                - Multiple right to left select - -
                                                -
                                                - -

                                                Change / Update Events

                                                -
                                                -
                                                  -
                                                • -

                                                  Form Field Change

                                                  -

                                                  When working with form fields, you often want to perform some behavior after a value has been selected or deselected. Whenever a user selects a field in Chosen, it triggers a "change" event* on the original form field. That let's you do something like this:

                                                  -
                                                  $("#form_field").chosen().change( … );
                                                  -

                                                  Note: Prototype doesn't offer support for triggering standard browser events. Event.simulate is required to trigger the change event when using the Prototype version.

                                                  -
                                                • -
                                                • -

                                                  Updating Chosen Dynamically

                                                  -

                                                  If you need to update the options in your select field and want Chosen to pick up the changes, you'll need to trigger the "chosen:updated" event on the field. Chosen will re-build itself based on the updated content.

                                                  -
                                                  Event.fire($("form_field"), "chosen:updated");
                                                  -
                                                • -
                                                -
                                                - -

                                                Custom Width Support

                                                -
                                                -

                                                Using a custom width with Chosen is as easy as passing an option when you create Chosen:

                                                -
                                                new Chosen($("chosen_select_field"),{width: "95%"}); 
                                                -
                                                - Single Select - -
                                                -
                                                - Multiple Select - -
                                                -
                                                - -

                                                Labels work, too

                                                -
                                                -

                                                Use labels just like you would a standard select

                                                -

                                                -
                                                - - -
                                                -
                                                - - -
                                                -
                                                - -

                                                Setup

                                                -

                                                Using Chosen is easy as can be.

                                                -
                                                  -
                                                1. Download the plugin and copy the chosen files to your app.
                                                2. -
                                                3. Activate the plugin by creating a new instance of Chosen: New Chosen(some_form_field,some_options);
                                                4. -
                                                5. Disco.
                                                6. -
                                                - -

                                                FAQs

                                                -
                                                  -
                                                • -

                                                  Do you have all the available options documented somewhere?

                                                  -

                                                  Yes! You can find them on the options page.

                                                  -
                                                • -
                                                • -

                                                  Something doesn't work. Can you fix it?

                                                  -

                                                  Yes! Please report all issues using the GitHub issue tracking tool. Please include the plugin version (jQuery or Prototype), browser and OS. The more information provided, the easier it is to fix a problem.

                                                  -
                                                • -
                                                • -

                                                  What browsers are supported?

                                                  -

                                                  All modern desktop browsers are supported (Firefox, Chrome, Safari and IE9). Legacy support for IE8 is also enabled. Chosen is disabled on iPhone, iPod Touch, and Android mobile devices (more information).

                                                  -
                                                • -
                                                - -

                                                Credits

                                                - - - - - -
                                                -
                                                - - - - - - - diff --git a/sites/all/themes/gui/materiobasetheme/js/libs/src/chosen_v1.1.0/options.html b/sites/all/themes/gui/materiobasetheme/js/libs/src/chosen_v1.1.0/options.html deleted file mode 100644 index 4cedc53b..00000000 --- a/sites/all/themes/gui/materiobasetheme/js/libs/src/chosen_v1.1.0/options.html +++ /dev/null @@ -1,269 +0,0 @@ - - - - - Chosen: A jQuery Plugin by Harvest to Tame Unwieldy Select Boxes - - - - - - -
                                                -
                                                -
                                                -

                                                Chosen (v1.1.0)

                                                -
                                                -

                                                Chosen has a number of options and attributes that allow you to have full control of your select boxes.

                                                - -

                                                Options

                                                -

                                                The following options are available to pass into Chosen on instantiation.

                                                - -

                                                Example:

                                                -
                                                -  $(".my_select_box").chosen({
                                                -    disable_search_threshold: 10,
                                                -    no_results_text: "Oops, nothing found!",
                                                -    width: "95%"
                                                -  });
                                                -
                                                - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
                                                OptionDefaultDescription
                                                allow_single_deselectfalseWhen set to true on a single select, Chosen adds a UI element which selects the first elment (if it is blank).
                                                disable_searchfalseWhen set to true, Chosen will not display the search field (single selects only).
                                                disable_search_threshold0Hide the search input on single selects if there are fewer than (n) options.
                                                enable_split_word_searchtrueBy default, searching will match on any word within an option tag. Set this option to false if you want to only match on the entire text of an option tag.
                                                inherit_select_classesfalseWhen set to true, Chosen will grab any classes on the original select field and add them to Chosen’s container div.
                                                max_selected_optionsInfinityLimits how many options the user can select. When the limit is reached, the chosen:maxselected event is triggered.
                                                no_results_text"No results match"The text to be displayed when no matching results are found. The current search is shown at the end of the text (e.g., - No results match "Bad Search").
                                                placeholder_text_multiple"Select Some Options"The text to be displayed as a placeholder when no options are selected for a multiple select.
                                                placeholder_text_single"Select an Option"The text to be displayed as a placeholder when no options are selected for a single select.
                                                search_containsfalseBy default, Chosen’s search matches starting at the beginning of a word. Setting this option to true allows matches starting from anywhere within a word. This is especially useful for options that include a lot of special characters or phrases in ()s and []s.
                                                single_backstroke_deletetrueBy default, pressing delete/backspace on multiple selects will remove a selected choice. When false, pressing delete/backspace will highlight the last choice, and a second press deselects it.
                                                widthOriginal select width.The width of the Chosen select box. By default, Chosen attempts to match the width of the select box you are replacing. If your select is hidden when Chosen is instantiated, you must specify a width or the select will show up with a width of 0.
                                                display_disabled_optionstrueBy default, Chosen includes disabled options in search results with a special styling. Setting this option to false will hide disabled results and exclude them from searches.
                                                display_selected_optionstrue -

                                                By default, Chosen includes selected options in search results with a special styling. Setting this option to false will hide selected results and exclude them from searches.

                                                -

                                                Note: this is for multiple selects only. In single selects, the selected result will always be displayed.

                                                -
                                                - -

                                                Attributes

                                                -

                                                Certain attributes placed on the select tag or its options can be used to configure Chosen.

                                                - -

                                                Example:

                                                - -
                                                -  <select class="my_select_box" data-placeholder="Select Your Options">
                                                -    <option value="1">Option 1</option>
                                                -    <option value="2" selected>Option 2</option>
                                                -    <option value="3" disabled>Option 3</option>
                                                -  </select>
                                                -
                                                - - - - - - - - - - - - - - - - - -
                                                AttributeDescription
                                                data-placeholder -

                                                The text to be displayed as a placeholder when no options are selected for a select. Defaults to "Select an Option" for single selects or "Select Some Options" for multiple selects.

                                                -

                                                Note:This attribute overrides anything set in the placeholder_text_multiple or placeholder_text_single options.

                                                -
                                                multipleThe attribute multiple on your select box dictates whether Chosen will render a multiple or single select.
                                                selected, disabledChosen automatically highlights selected options and disables disabled options.
                                                - -

                                                Classes

                                                -

                                                Classes placed on the select tag can be used to configure Chosen.

                                                - -

                                                Example:

                                                - -
                                                -  <select class="my_select_box chosen-rtl">
                                                -    <option value="1">Option 1</option>
                                                -    <option value="2">Option 2</option>
                                                -    <option value="3">Option 3</option>
                                                -  </select>
                                                -
                                                - - - - - - - - - - -
                                                ClassnameDescription
                                                chosen-rtl -

                                                Chosen supports right-to-left text in select boxes. Add the class chosen-rtl to your select tag to support right-to-left text options.

                                                -

                                                Note: The chosen-rtl class will pass through to the Chosen select even when the inherit_select_classes option is set to false.

                                                -
                                                - -

                                                Triggered Events

                                                -

                                                Chosen triggers a number of standard and custom events on the original select field.

                                                - -

                                                Example:

                                                - -
                                                -  $('.my_select_box').on('change', function(evt, params) {
                                                -    do_something(evt, params);
                                                -  });
                                                -
                                                - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
                                                EventDescription
                                                change -

                                                Chosen triggers the standard DOM event whenever a selection is made (it also sends a selected or deselected parameter that tells you which option was changed).

                                                -

                                                Note: in order to use change in the Prototype version, you have to include the Event.simulate class. The selected and deselected parameters are not available for Prototype.

                                                -
                                                chosen:readyTriggered after Chosen has been fully instantiated.
                                                chosen:maxselectedTriggered if max_selected_options is set and that total is broken.
                                                chosen:showing_dropdownTriggered when Chosen’s dropdown is opened.
                                                chosen:hiding_dropdownTriggered when Chosen’s dropdown is closed.
                                                chosen:no_resultsTriggered when a search returns no matching results.
                                                - -

                                                - Note: all custom Chosen events (those that being with chosen:) also include the chosen object as a parameter. -

                                                - -

                                                Triggerable Events

                                                -

                                                You can trigger several events on the original select field to invoke a behavior in Chosen.

                                                - -

                                                Example:

                                                - -
                                                -  // tell Chosen that a select has changed
                                                -    $('.my_select_box').trigger('chosen:updated');
                                                -
                                                - - - - - - - - - - - - - - - - - - - - - -
                                                EventDescription
                                                chosen:updatedThis event should be triggered whenever Chosen’s underlying select element changes (such as a change in selected options).
                                                chosen:activateThis is the equivalant of focusing a standard HTML select field. When activated, Chosen will capure keypress events as if you had clicked the field directly.
                                                chosen:openThis event activates Chosen and also displays the search results.
                                                chosen:closeThis event deactivates Chosen and hides the search results.
                                                - - - -
                                                -
                                                - - - - diff --git a/sites/all/themes/gui/materiobasetheme/js/libs/src/minimalect-master/Gruntfile.js b/sites/all/themes/gui/materiobasetheme/js/libs/src/minimalect-master/Gruntfile.js deleted file mode 100644 index cfe737a6..00000000 --- a/sites/all/themes/gui/materiobasetheme/js/libs/src/minimalect-master/Gruntfile.js +++ /dev/null @@ -1,86 +0,0 @@ -/* - minimalect - http://github.com/groenroos/minimalect - - Copyright (c) 2013-2014 Oskari Groenroos and contributors - Licensed under the MIT license. -*/ - -// jshint globalstrict:true, node:true - -"use strict"; - -module.exports = function (grunt) { - - grunt.initConfig({ - - pkg: grunt.file.readJSON("package.json"), - - banner:'/*********************************** \n'+ - '<%= pkg.name %> \n'+ - '<%= pkg.description %> \n\n' + - 'jQuery 1.7+ required. \n' + - 'Developed by @groenroos \n' + - 'http://www.groenroos.fi \n\n' + - 'Github: <%= pkg.repository.url %> w \n\n' + - 'Licensed under the <%= pkg.license %> license.\n\n' + - '************************************/\n', - - clean: { - options: { - force: true - }, - "default": [ - "*.min.*", - '*.css' - ] - }, - uglify: { - options: { - banner:'<%= banner %>', - mangle: true, - compress: true, - preserveComments: "some" - }, - "default": { - files: { - "jquery.minimalect.min.js": ["jquery.minimalect.js"] - } - } - }, - sass: { // Task - dist: { - options:{ - style:"compressed" - }, - files: { // Dictionary of files - 'jquery.minimalect.min.css': 'jquery.minimalect.scss' // 'destination': 'source' - } - }, - dev:{ - files: { // Dictionary of files - 'jquery.minimalect.css': 'jquery.minimalect.scss' // 'destination': 'source' - } - } - }, - usebanner: { - taskName: { - options: { - position: 'top', - banner:'<%= banner %>' - }, - files: { - src: [ '*.css' ] - } - } - } - }); - - grunt.loadNpmTasks("grunt-contrib-clean"); - grunt.loadNpmTasks("grunt-contrib-uglify"); - grunt.loadNpmTasks("grunt-contrib-jasmine"); - grunt.loadNpmTasks('grunt-contrib-sass'); - grunt.loadNpmTasks('grunt-banner'); - - grunt.registerTask("default", ["clean", "uglify", "sass", 'usebanner' ]); -}; diff --git a/sites/all/themes/gui/materiobasetheme/js/libs/src/minimalect-master/README.md b/sites/all/themes/gui/materiobasetheme/js/libs/src/minimalect-master/README.md deleted file mode 100644 index 97593fa2..00000000 --- a/sites/all/themes/gui/materiobasetheme/js/libs/src/minimalect-master/README.md +++ /dev/null @@ -1,117 +0,0 @@ -minimalect ----------- - -Minimal select replacement for jQuery by [@groenroos](http://twitter.com/groenroos). For usage examples, visit [groenroos.github.io/minimalect](http://groenroos.github.io/minimalect/) - -* Replace select elements with a nicer styled control -* Support for optgroups -* Filtering choices by typing -* Keyboard navigation -* Support for themes - -**New in 0.9.0 (28th May 2014)** - -* AJAX search support -* Multiselect support -* Detects dynamic changes to original element automatically -* Disabled element support -* Public methods -* Optional reset functionality -* Combobox functionality now optional -* Less conflict with existing form styles -* Various bugfixes - -### Usage - -Include `jquery.minimalect.min.js` after you load jQuery (1.7 or newer). Then simply do; - - $("select").minimalect(); - -Remember to also include the stylesheet (SCSS and minified CSS available); - - - -The default style is very understated, so it's easy to modify to better suit your needs. By default, no graphics are used; the arrow symbols are Unicode characters. Please be advised that not all typefaces on all devices support this, and depending on your target device, you may want to replace it with pre-rendered graphics. - - -#### AJAX functionality - -You can also use Minimalect as a way to display search results from an AJAX call. For this, pass the `ajax` setting with the URL to the backend. Minimalect will send a POST request with the key `q` containing the value of the user's search. Minimalect will expect a JSON response with an array of objects, each having two keys: `name` and `value`. - -Note, that the response received from the AJAX service will also modify choices available in the original `select` element, so that the selected choice may be appropriately sent with the rest of the form. The original contents of the `select` element are not restored if the user doesn't pick anything. - - -#### Programmatically changing the selected choice - -If you wish to change the current value of the select, you can simply make your changes to the original element like you would normally with `.val()`. Minimalect will take it from there, providing that the `live` setting is set to `true`, like it is by default. - - -#### Programmatically changing the available choices - -Since version 0.9.0, Minimalect will automatically recognize if the original options are changed dynamically, and the changes are reflected in the user-facing element. For this, Minimalect uses the MutationObserver, which has [spotty cross-browser support](http://caniuse.com/#feat=mutationobserver). For support in IE10 and earlier, Firefox 13 and earlier, Chrome 26 and earlier and Safari 5.1 and earlier, either use a [polyfill](https://github.com/Polymer/MutationObservers), or call the `update` method manually. - - -#### Available methods - -You can call various Minimalect methods to control it programmatically. You can call methods by passing the method name as a string in a second call, e.g. `.minimalect("method")` - -* `destroy` — remove all the features of Minimalect and restore the original select. *Warning:* this will unhook any `change`, `focus` or `blur` events you may have connected to the `select` via `.on()` -* `update` — refresh Minimalect's displayed choices from the original `select`. Minimalect will do this automatically in modern browsers. See above for details. - - -#### Available options - -You can pass an object as a parameter for the `.minimalect()` call, to override the default settings. - -You may edit all the CSS classnames that Minimalect uses so that they don't collide with ones you already use, as well as the user-facing messages for customization or internationalization. - -##### Settings - -* `theme` — the currently used theme. Applied as a class to the main div element. Default: *(empty)* -* `transition` — which effect should be used for showing and hiding the dropdown. Default: *fade* -* `transition_time` — how long the effect for showing and hiding the dropdown should take, in milliseconds. Default: *150* -* `remove_empty_option` — whether options with empty values should be removed. Default: `true` -* `show_reset` — whether to show a reset button to deselect a selected choice. Default: `false` -* `searchable` — whether the combobox functionality is enabled or not. Default: `true` -* `ajax` — URL of an AJAX resource for external search results. See above for details. Will not have an effect if `searchable` is `false`. Default: `null` -* `live` — whether Minimalect should automatically detect value changes to the original `select`. Creates an interval that runs indefinitely every 100 ms; may interfere with the DOM inspector. Default: `true` -* `debug` — whether Minimalect should explain in the console what it's doing. Useful for debugging. Default: `false` - -##### Messages - -* `placeholder` — the default text displayed whenever no choice has been selected. Set to `null` to inherit the placeholder from the value of the first option. Default: *Select a choice* -* `empty` — message displayed to the user when no choice matched his filter search term. Default: *No results matched your keyword.* -* `error` — message displayed to the user when an AJAX request fails for any reason. Default: *There was a problem with the request.* - -##### Classes - -* `class_container` — classname for the main div element. Default: *minict_wrapper* -* `class_group` — classname for a list item that represents an optgroup label. Default: *minict_group* -* `class_empty` — classname for the "No results" message when filtering produces no results. Default: *minict_empty* -* `class_active` — classname that is applied to the main div element whenever the dropdown is visible. Default: *active* -* `class_disabled` — classname that is applied to list items or the whole select, if they are disabled. Default: *disabled* -* `class_selected` — classname applied to the list item in the dropdown that is currently selected. Default: *selected* -* `class_hidden` — classname applied to list items in the dropdown that do not match the filter. Default: *hidden* -* `class_highlighted` — classname applied to the list item that is currently highlighted when the user uses keyboard navigation. Default: *highlighted* -* `class_first` — classname that corresponds to the first visible list item in the dropdown, including optgroup labels and the "No results" message. Helpful when rounding corners in CSS. Default: *minict_first* -* `class_last` — classname that corresponds to the last visible list item in the dropdown, including optgroup labels and the "No results" message. Helpful when rounding corners in CSS. Default: *minict_last* -* `class_reset` — classname applied to the optional reset element. Default: *minict_reset* - -##### Callbacks - -* `beforeinit` — Called immediately when the plugin is called, before any initialization work begins. -* `afterinit` — Called after Minimalect has been fully initialized. -* `onchange` — Called whenever the user selects an option in the list. - * `value`; the value of the choice selected. - * `text`; the user-facing text of the choice selected. -* `onopen` — Called when the dropdown list is displayed. -* `onclose` — Called when the dropdown list is closed (either by clicking away, or by selecting an option). -* `onfilter` — Called every time the list is filtered (basically every time the user types a letter into the filter box). - * `match`; a boolean parameter, `true` if there was matches, `false` if no matches are found. - - -### Bugs & Support - -Developed by [@groenroos](http://twitter.com/groenroos). Please list all bugs and feature requests in the [Github issue tracker](https://github.com/groenroos/minimalect/issues). - -Licensed under the MIT license. diff --git a/sites/all/themes/gui/materiobasetheme/js/libs/src/minimalect-master/bower.json b/sites/all/themes/gui/materiobasetheme/js/libs/src/minimalect-master/bower.json deleted file mode 100644 index 21017d7d..00000000 --- a/sites/all/themes/gui/materiobasetheme/js/libs/src/minimalect-master/bower.json +++ /dev/null @@ -1,9 +0,0 @@ -{ - "name": "minimalect", - "version": "0.9.0", - "main": "jquery.minimalect.js", - "ignore": [ - "Gruntfile.js", - "*.md" - ] -} \ No newline at end of file diff --git a/sites/all/themes/gui/materiobasetheme/js/libs/src/minimalect-master/jquery.minimalect.css b/sites/all/themes/gui/materiobasetheme/js/libs/src/minimalect-master/jquery.minimalect.css deleted file mode 100644 index 8ab7543b..00000000 --- a/sites/all/themes/gui/materiobasetheme/js/libs/src/minimalect-master/jquery.minimalect.css +++ /dev/null @@ -1,222 +0,0 @@ -/************************************ - MINIMALECT 0.9 - A minimalistic select replacement - - jQuery 1.7+ required. - Developed by @groenroos - http://www.groenroos.fi - - Github: http://git.io/Xedg9w - - Licensed under the MIT license. - -************************************/ -.minict_wrapper { - font-family: "Segoe UI", Segoe, "Lucida Grande", "Lucida Sans Unicode", Arial, Helvetica, sans-serif; - color: #333; - background: #fff; - position: relative; - width: 300px; - height: 35px; - height: 2.2rem; - border: 1px solid #e5e5e5; - border-radius: 3px; - -webkit-box-sizing: border-box; - -moz-box-sizing: border-box; - box-sizing: border-box; } - .minict_wrapper * { - -webkit-box-sizing: border-box; - -moz-box-sizing: border-box; - box-sizing: border-box; } - .minict_wrapper.disabled { - background: #f5f5f5; - text-shadow: 0 1px 0 #fff; } - .minict_wrapper.disabled span { - color: #bbb !important; } - .minict_wrapper:after { - content: "\25BC"; - display: block; - position: absolute; - height: 33px; - width: 33px; - height: 2.1rem; - width: 2.1rem; - top: 0; - right: 0; - font-size: 10px; - font-size: 0.6rem; - line-height: 32px; - line-height: 1.9rem; - text-align: center; - color: #555; } - .minict_wrapper.active:after { - content: "\25B2"; } - .minict_wrapper.disabled:after { - color: #bbb; } - .minict_wrapper span { - display: block; - border: 0; - outline: none; - background: none; - font-family: "Segoe UI", Segoe, "Lucida Grande", "Lucida Sans Unicode", Arial, Helvetica, sans-serif; - color: #333; - font-size: 16px; - font-size: 1rem; - height: 32px; - height: 2.0rem; - line-height: 23px; - line-height: 1.5rem; - padding: 4px 53px 0 6px; - padding: 4px 3.4rem 0 0.4rem; - cursor: default; - width: 100%; - white-space: nowrap; - overflow: hidden; - text-overflow: ellipsis; } - .minict_wrapper span:empty:before { - content: attr(data-placeholder); - color: #ccc; - line-height: 23px; - line-height: 1.5rem; } - .minict_wrapper ul { - display: none; - list-style: none; - padding: 0; - margin: 0 -1px; - position: absolute; - width: 100%; - width: -webkit-calc(100% + 2px); - width: -moz-calc(100% + 2px); - width: calc(100% + 2px); - border: 1px solid #e5e5e5; - border-top: 1px solid #f9f9f9; - border-bottom-left-radius: 3px; - border-bottom-right-radius: 3px; - top: 33px; - top: 2.0rem; - left: 0; - max-height: 350px; - max-height: 22rem; - overflow-y: auto; - z-index: 999999; } - .minict_wrapper ul li { - list-style: none; - font-size: 1rem; - padding: 0 10px; - padding: 0 0.7rem; - cursor: pointer; - background: #fff; - height: 35px; - height: 2.2rem; - line-height: 32px; - line-height: 2rem; } - .minict_wrapper ul li:hover { - background: #fcfcfc; - color: #111; } - .minict_wrapper ul li.minict_group { - color: #444; - background: #f6f6f6; - font-weight: bold; - cursor: default; } - .minict_wrapper ul li.minict_empty { - display: none; - background: #fff !important; - color: #bbb; - text-align: center; - font-size: 14px; - font-size: 0.9rem; - height: 55px; - height: 3.5rem; - line-height: 50px; - line-height: 3.3rem; } - .minict_wrapper ul li.disabled { - cursor: default; - background: #fff !important; - color: #bbb; } - .minict_wrapper ul li.selected { - color: #819a9a; - background: #f8f9f9; } - .minict_wrapper ul li.highlighted { - color: #fff; - background: #819a9a; } - .minict_wrapper ul li.hidden { - display: none; } - .minict_wrapper .minict_reset { - color: #A9A9A9; - bottom: 0; - display: none; - font-size: 18px; - font-size: 1.1rem; - line-height: 30px; - line-height: 1.9rem; - position: absolute; - right: 35px; - right: 2.2rem; - text-align: center; - top: 0; - text-decoration: none; - width: 20px; - width: 1.2rem; - -webkit-transition: all 0.35s ease-in-out; - transition: all 0.35s ease-in-out; } - .minict_wrapper .minict_reset:hover { - color: #e0e0e0; - -webkit-transition: all 0.15s ease-in-out; - transition: all 0.15s ease-in-out; } - .minict_wrapper .minict_reset:active { - color: #636363; } - .minict_wrapper.disabled .minict_reset { - display: none; } - -.minict_wrapper.bubble { - -webkit-box-shadow: 0px 1px 3px 0px rgba(0, 0, 0, 0.05); - box-shadow: 0px 1px 3px 0px rgba(0, 0, 0, 0.05); - background: -moz-linear-gradient(top, white 0%, #f9f9f9 100%); - background: -webkit-gradient(linear, left top, left bottom, color-stop(0%, white), color-stop(100%, #f9f9f9)); - background: -webkit-linear-gradient(top, white 0%, #f9f9f9 100%); - background: -o-linear-gradient(top, white 0%, #f9f9f9 100%); - background: -ms-linear-gradient(top, white 0%, #f9f9f9 100%); - background: linear-gradient(to bottom, white 0%, #f9f9f9 100%); } - .minict_wrapper.bubble:hover { - border-color: #dcdcdc; } - .minict_wrapper.bubble:after { - border-left: 1px solid #e5e5e5; - -webkit-box-shadow: inset 1px 0px 0px 0px #fff; - box-shadow: inset 1px 0px 0px 0px #fff; - height: 2.05rem; } - .minict_wrapper.bubble ul { - top: 2.7rem; - -webkit-box-shadow: 0px 5px 25px 0px rgba(0, 0, 0, 0.25); - box-shadow: 0px 5px 25px 0px rgba(0, 0, 0, 0.25); - border-radius: 6px; - overflow: visible; } - .minict_wrapper.bubble ul:before { - position: absolute; - top: -11px; - left: 19px; - content: "."; - color: transparent; - width: 0px; - height: 0px; - border-style: solid; - border-width: 0 11px 11px 11px; - border-color: transparent transparent #e5e5e5 transparent; } - .minict_wrapper.bubble ul:after { - position: absolute; - top: -10px; - left: 20px; - content: "."; - color: transparent; - width: 0px; - height: 0px; - border-style: solid; - border-width: 0 10px 10px 10px; - border-color: transparent transparent #ffffff transparent; } - .minict_wrapper.bubble ul li.minict_first { - border-top-left-radius: 6px; - border-top-right-radius: 6px; } - .minict_wrapper.bubble ul li.minict_last { - border-bottom-left-radius: 6px; - border-bottom-right-radius: 6px; } - .minict_wrapper.bubble .minict_reset { - width: 30px; } diff --git a/sites/all/themes/gui/materiobasetheme/js/libs/src/minimalect-master/jquery.minimalect.js b/sites/all/themes/gui/materiobasetheme/js/libs/src/minimalect-master/jquery.minimalect.js deleted file mode 100644 index c2a83b12..00000000 --- a/sites/all/themes/gui/materiobasetheme/js/libs/src/minimalect-master/jquery.minimalect.js +++ /dev/null @@ -1,647 +0,0 @@ -/************************************ - MINIMALECT 0.9 - A minimalistic select replacement - - jQuery 1.7+ required. - Developed by @groenroos - http://www.groenroos.fi - - Github: http://git.io/Xedg9w - - Licensed under the MIT license. - -************************************/ - -;(function ( $, window, document, undefined ) { - - var pluginName = "minimalect", - defaults = { - // settings - theme: "", // name of the theme used - reset: false, - transition: "fade", - transition_time: 150, - remove_empty_option: true, - searchable: true, // whether or not the combobox functionality is enabled - ajax: null, // URL to an external resource - debug: false, // whether to be verbose in the console - live: true, // whether to automatically detect changes - - // messages - placeholder: "Select a choice", // default placeholder when nothing is selected - empty: "No results match your keyword.", // error message when nothing matches the filter search term - error_message: "There was a problem with the request.", // error message when the AJAX call fails - - // classes - class_container: "minict_wrapper", // wrapper div for the element - class_group: "minict_group", // list item for an optgroup - class_empty: "minict_empty", // "No results" message - class_active: "active", // applied to wrapper when the dropdown is displayed - class_disabled: "disabled", // applied to list elements that are disabled - class_selected: "selected", // the currently selected item in the dropdown - class_hidden: "hidden", // an item that doesn't match the filter search term - class_highlighted: "highlighted", // item highlighted by keyboard navigation - class_first: "minict_first", // first visible element - class_last: "minict_last", // last visible element - class_reset: "minict_reset", // reset link - - // callbacks - beforeinit: function(){}, // called before Minimalect is initialized - afterinit: function(){}, // called right after Minimalect is initialized - onchange: function(){}, // called whenever the user changes the selected value - onopen: function(){}, // called when the dropdown is displayed - onclose: function(){}, // called when the dropdown is hidden - onfilter: function(){} // called every time the filter has been activated - }; - - // The actual plugin constructor - function Plugin( element, options ) { - this.element = $(element); - this.options = $.extend( {}, defaults, options ); - this._defaults = defaults; - this._name = pluginName; - this.label = $('[for="'+this.element.attr('id')+'"]').attr('for', 'minict_'+this.element.attr('id')); - - this._init(); - } - - Plugin.prototype = { - - // INITIALIZATION - - _init: function() { - - // before init callback - this.options.beforeinit(); - - // PREPWORK - - var op = this.options, - m = this; - - // create the wrapper - this.wrapper = $('
                                                '); - // hide the original select and add the wrapper - this.element.hide().after(this.wrapper); - // apply the current theme to the wrapper - if(op.theme) this.wrapper.addClass(op.theme); - // reflect disabled status - if(this.element.prop("disabled")) - this.wrapper.addClass(op.class_disabled); - - // create and add the input - this.input = $( - ''+ - (this.element.find("option[selected]").html() || "")+ - '' - ).appendTo(this.wrapper); - - // add the reset link, if it's wanted - if(op.reset) - this.reset = $('×').appendTo(this.wrapper); - - // parse the select itself, and create the dropdown markup - this.ul = $('
                                                  '+this._parseSelect()+'
                                                • '+op.empty+'
                                                ').appendTo(this.wrapper); - this.items = this.wrapper.find('li'); - // if it's preselected, select the option itself as well - if(this.element.find("option[selected]").length) { - this._showResetLink(); - this.items.filter('[data-value="'+this.element.find("option[selected]").val()+'"]').addClass(op.class_selected); - } - - // BIND EVENTS - // hide dropdown when you click elsewhere - $(document).on("click", function(){ m._hideChoices(m.wrapper) }); - // hide dropdown when moving focus outside it - $("*").not(this.wrapper).not(this.wrapper.find('*')).on("focus", function(){ m._hideChoices(m.wrapper) }); - // toggle dropdown when you click on the dropdown itself - this.wrapper.on("click", function(e){ - e.stopPropagation(); - // only close the dropdown when it's not disabled and not multiselect - if(!m.element.prop("multiple") && !m.element.prop("disabled")) - m._toggleChoices() - }); - // toggle dropdown when you click on the associated label, if present - this.label.on("click", function(e){ e.stopPropagation(); m.input.trigger('focus') }); - // select choice when you click on it - this.wrapper.on("click", "li:not(."+op.class_group+", ."+op.class_empty+", ."+op.class_disabled+")", function(){ m._selectChoice($(this)) }); - // stop the dropdown from closing when you click on a group or empty placeholder - this.wrapper.on("click", "li."+op.class_group+", li."+op.class_empty+", li."+op.class_disabled, function(e){ - e.stopPropagation(); - m.input.focus(); - }); - // if the original is focused or blurred manually, mimic it - // also handle the custom update event - this.element.on("focus", function(){ - m.element.blur(); - m._showChoices(); - }) - .on("blur", m._hideChoices) - .on("update", m.update); - - // bind reset only if it's there - if(op.reset){ - this.wrapper.on("click", "a."+op.class_reset, function(e){ - e.stopPropagation(); - m._resetChoice(); - return false; - }); - } - - // key bindings for the input element - this.input.on("focus click", function(e){ - e.stopPropagation(); - if(!m.element.prop("disabled")) m._showChoices(); else m.input.blur(); - }).on("keydown", function(e){ - // keyboard navigation - switch(e.keyCode) { - // up - case 38: - e.preventDefault(); - m._navigateChoices('up'); - break; - // down - case 40: - e.preventDefault(); - m._navigateChoices('down'); - break; - // enter - case 13: - // tab - case 9: - // select the highlighted choice - if(m.items.filter("."+op.class_highlighted).length) - m._selectChoice(m.items.filter("."+op.class_highlighted)); - // or if there is none, select the first choice after filtering - else if(m.input.text()) - m._selectChoice(m.items.not("."+op.class_group+", ."+op.class_empty).filter(':visible').first()); - if(e.keyCode===13){ - e.preventDefault(); - m._hideChoices(m.wrapper); - } - break; - // escape - case 27: - e.preventDefault(); - // close the select and don't change the value - m._hideChoices(m.wrapper); - break; - } - }).on("keyup", function(e){ - // if we're not navigating, filter - if($.inArray(e.keyCode, [38, 40, 13, 9, 27]) === -1){ - m._filterChoices(); - } - }); - - // if mutation observing is supported - if(window.MutationObserver){ - // observe the original for DOM changes so they can be reflected - this.observer = new MutationObserver(function( mutations ) { - // if there were changes... - if(mutations.length > 0){ - // ...reparse the select - m.ul.html(m._parseSelect()+'
                                              • '+op.empty+'
                                              • '); - if(m.options.debug) console.log("Minimalect detected a DOM change for ", m.element); - } - }); - this.observer.observe(m.element[0], {childList: true}); - } - - // poll the original for changes - if(op.live){ - // set cache to the original value - var prevval = this.element.val(); - // set a tight interval to check for the original - setInterval(function(){ - // if we're out of date - if(prevval != m.element.val() && m.element.val() != null && m.element.val() != "") { - // update cache - prevval = m.element.val(); - // update selection - if(typeof prevval == "array") { - prevval.each(function(k,v){ - m._selectChoice(m.wrapper.find("li[data-value='"+v+"']")); - }); - } else { - m._selectChoice(m.wrapper.find("li[data-value='"+prevval+"']")); - } - } else if (m.element.val() == null || m.element.val() == "") { - // update cache - prevval = m.element.val(); - // if it was empty, let's clear it - m.items.removeClass(m.options.class_selected); - m.input.text('').attr('data-placeholder', m.options.placeholder); - } - - // let's also check for disabled - if(m.element.prop("disabled")) - m.wrapper.addClass(op.class_disabled); - else - m.wrapper.removeClass(op.class_disabled); - }, 100); - } - - - // after init callback - op.afterinit(); - }, - - - // PRIVATE METHODS - - // navigate with a keyboard - // dr - direction we're going, either "up" or "down" - _navigateChoices: function(dr) { - var m = this, - wr = this.wrapper, // jQuery reference for the wrapper - op = this.options, // options object - items = this.items; - // list all the elements that aren't navigatable - var ignored = "."+op.class_hidden+", ."+op.class_empty+", ."+op.class_group; - - if(!items.filter("."+op.class_highlighted).length) { // if nothing is selected, select the first or last - if(dr === 'up') { - items.not(ignored).last().addClass(op.class_highlighted); - } else if (dr === 'down') { - items.not(ignored).first().addClass(op.class_highlighted); - } - return false; - } else { // if something is selected... - // ...remove current selection... - cur = items.filter("."+op.class_highlighted); - cur.removeClass(op.class_highlighted); - // ...and figure out the next one - if(dr === 'up') { - if(items.not(ignored).first()[0] != cur[0]) { // if we're not at the first - cur.prevAll("li").not(ignored).first().addClass(op.class_highlighted); // highlight the prev - // make sure it's visible in a scrollable list - var offset = items.filter("."+op.class_highlighted).offset().top - this.ul.offset().top + this.ul.scrollTop(); - if (this.ul.scrollTop() > offset) - this.ul.scrollTop(offset); - } else { // if we are at the first - items.not(ignored).last().addClass(op.class_highlighted); // highlight the last - // make sure it's visible in a scrollable list - this.ul.scrollTop(this.ul.height()); - } - } else if (dr === 'down') { - if(items.not(ignored).last()[0] != cur[0]) { // if we're not at the last - cur.nextAll("li").not(ignored).first().addClass(op.class_highlighted); // highlight the next - // make sure it's visible in a scrollable list - var ddbottom = this.ul.height(), - libottom = items.filter("."+op.class_highlighted).offset().top - this.ul.offset().top + items.filter("."+op.class_highlighted).outerHeight(); - if (ddbottom < libottom) - this.ul.scrollTop(this.ul.scrollTop() + libottom - ddbottom); - } else { // if we are at the last - items.not(ignored).first().addClass(op.class_highlighted); // highlight the first - // make sure it's visible in a scrollable list - this.ul.scrollTop(0); - } - } - } - }, - - // parse the entire select based on whether it has optgroups or not, and return the new markup - _parseSelect: function() { - var m = this, ulcontent = ""; - if( !this.element.find("optgroup").length ) { // if we don't have groups - // just parse the elements regularly - ulcontent = this._parseElements( this.element.html() ); - } else { // if we have groups - // parse each group separately - this.element.find("optgroup").each(function(){ - // create a group element - ulcontent += '
                                              • '+$(this).attr("label")+'
                                              • '; - // and add its children - ulcontent += this._parseElements( $(this).html() ); - }); - } - return ulcontent; - }, - - // turn option elements into li elements - // elhtml - HTML containing the options - _parseElements: function(elhtml) { - var m = this, readyhtml = ""; - // go through each option - $( $.trim(elhtml) ).filter("option").each(function(){ - var $el = $(this); - if ($el.attr('value') === '' && m.options.remove_empty_option) return; - // create an li with a data attribute containing its value - readyhtml += '
                                              • '+$el.text()+'
                                              • '; - }); - // spit it out - return readyhtml; - }, - - // toggle the visibility of the dropdown - _toggleChoices: function(){ - (!this.wrapper.hasClass(this.options.class_active)) ? this._showChoices() : this._hideChoices(this.wrapper); - }, - - // show the dropdown - // cb - callback before the animation plays - _showChoices: function(cb){ - var m = this, - wr = this.wrapper, // jQuery reference for the wrapper - op = this.options; // options object - if (!wr.hasClass(op.class_active)){ - // keep the first and last classes up to date - this._updateFirstLast(false); - // close all other open minimalects - $("."+op.class_container).each(function(){ //todo this doesn't work if the container classes are different - if($(this)[0] !== wr[0]) - m._hideChoices($(this)); - }); - // internal callback - if(typeof cb === 'function') cb.call(); - // add the active class - wr.addClass(op.class_active); - switch(op.transition) { - case "fade": - this.ul.fadeIn(op.transition_time); - break; - default: - this.ul.show(); - break; - } - // make the input editable - this.input.text("").focus(); - // hide the reset link - this._hideResetLink(); - // callback - this.options.onopen(); - } else { - // internal callback - if(typeof cb === 'function') cb.call(); - } - }, - - _resetDropdown: function(cb){ - var op = this.options; // options object - // reset the filtered elements - this.items.removeClass(op.class_hidden); - // hide the empty error message - this.wrapper.find("."+op.class_empty).hide(); - // reset keyboard navigation - this.items.filter("."+op.class_highlighted).removeClass(op.class_highlighted); - // internal callback - if(typeof cb === 'function') cb.call(); - }, - - // hide the dropdown - // wr - jQuery reference for the wrapper - // cb - callback for after the animation has played - _hideChoices: function(wr, cb){ - var op = this.options, // options object - to = op.transition_time, // timeout for the transition to finish - m = this; - - if (wr.hasClass(op.class_active)){ - // remove the active class and fade out - wr.removeClass(op.class_active); - - switch(op.transition) { - case "fade": - wr.children("ul").fadeOut(op.transition_time); - break; - default: - wr.children("ul").hide(); - to = 0; - break; - } - - // set a timeout for clearing the field, so there's no flickering - setTimeout(function(){ - // reset filters - m._resetDropdown(cb); - - // blur the input - m.input.blur(); - - // reset it - if(m.input.attr("data-placeholder") != op.placeholder) { - // if we have a previously selected value, restore that - m.input.text(m.input.attr("data-placeholder")); - } else if(!m.items.filter("."+op.class_selected).length) { - // if we have no selection, empty it to show placeholder - m.input.text(""); - } - }, to); - - // show the reset link - m._showResetLink(); - - // callback - op.onclose(); - } else { - // internal callback - if(typeof cb === 'function') cb.call(); - } - }, - - // filter choices based on user input - _filterChoices: function(){ - var wr = this.wrapper, // jQuery reference for the wrapper - op = this.options, // options object - m = this; - - if(op.ajax) { - // if we're searching from ajax - - $.post(op.ajax, {"q": this.input.text()}) - .success(function(data){ - // we got a response - - if(op.debug) console.log("Minimalect received ", data, " for query '"+m.input.text()+"' in ", m.element); - - if(data.length) { - // if we have results - var new_html = ""; - $.each(data, function(k, choice){ - // parse each data point to an option in the original - new_html += ''; - }); - // populate original element - m.element.html(new_html); - // parse and display it - m.ul.html(m._parseSelect()+'
                                              • '+op.empty+'
                                              • '); - wr.find("."+op.class_empty).hide(); - - // refresh internal cache - m.items = wr.find('li'); - - // callback, results found - m.options.onfilter(true); - } else { - // show a "no results" placeholder if there's nothing to show - m.ul.html('
                                              • '+op.empty+'
                                              • '); - wr.find("."+op.class_empty).show(); - // tell the console if debug mode is on - if(op.debug) console.log("Minimalect didn't find any results for '"+m.input.text()+"' from ", m.element); - // callback, no results found - m.options.onfilter(false); - } - }) - .error(function(data){ - // show feedback for the user - wr.find("."+op.class_empty).text(op.error_message); - wr.find("li").not("."+op.class_empty).addClass(op.class_hidden); - wr.find("."+op.class_empty).show(); - // tell the console if debug mode is on - if(op.debug) console.error("Minimalect's AJAX query failed for ", m.element, " - came back with ", data); - }); - } else { - // traditional filtering - - // get the filter value, escape regex chars (thanks Andrew Clover!) - var filter = this.input.text().replace(/[-\/\\^$*+?.()|[\]{}]/g, '\\$&'); - // reset keyboard navigation - this.items.filter("."+op.class_highlighted).removeClass(op.class_highlighted); - - // filter through each option - this.items.not(op.class_group).each(function(){ - // if there's no match (or if it's disabled), hide it. otherwise, unhide it - if ($(this).text().search(new RegExp(filter, "i")) < 0 || $(this).hasClass(op.class_disabled)) - $(this).addClass(op.class_hidden); - else - $(this).removeClass(op.class_hidden); - }); - - // make sure optgroups with no choices are hidden - // sort of a kludge since we have no hierarchy - this.items.filter("."+op.class_group).removeClass(op.class_hidden).each(function(){ - nextlis = $(this).nextAll("li").not("."+op.class_hidden+", ."+op.class_empty); - if(nextlis.first().hasClass(op.class_group) || !nextlis.length) $(this).addClass(op.class_hidden); - }); - - // show a "no results" placeholder if there's nothing to show - wr.find("."+op.class_empty).hide(); - if(!this.items.not("."+op.class_hidden+", ."+op.class_empty).length) { - wr.find("."+op.class_empty).show(); - // tell the console if debug mode is on - if(op.debug) console.log("Minimalect didn't find any results for '"+this.input.text()+"' from ", this.element); - // callback, no results found - this.options.onfilter(false); - } else { - // callback, results found - this.options.onfilter(true); - } - - // keep the first and last classes up to date - this._updateFirstLast(true); - } - }, - - // select the choice defined - // ch - jQuery reference for the li element the user has chosen - _selectChoice: function(ch){ - var el = this.element, // jQuery reference for the original select element - op = this.options, // options object - vals = [], - names = []; - - // if it's disabled, au revoir - if(ch.hasClass(this.options.class_disabled)) return false; - - // apply the selected class - if(!this.element.prop("multiple")) - this.items.removeClass(op.class_selected); - ch.addClass(op.class_selected); - - this.items.filter("."+op.class_selected).each(function(){ - vals.push($(this).data("value")); - names.push($(this).text()); - }); - - // show it up in the input - this.input.text(names.join(", ")).attr("data-placeholder", names.join(", ")); - - // if the selected choice is different - if(el.val() != ch.data("value") || el.val() != vals){ - // update the original select element - el.val(vals); - // call original select change event - el.trigger("change"); - } - - this._showResetLink(); - - // callback - this.options.onchange(ch.data("value"), ch.text()); - }, - - // clear the select - _resetChoice: function() { - this.element.val('').trigger("change"); - this._hideResetLink(); - }, - - // show the reset link if options.reset is true - _showResetLink: function() { - if(this.input.text().length > 0 || this.ul.find("li."+this.options.class_selected).length > 0) - this.options.reset && this.reset.show(); - }, - - // hide the reset link if options.reset is true - _hideResetLink: function() { - this.options.reset && this.reset.hide(); - }, - - // keep the first and last classes up-to-date - // vi - whether we want to count visibility or not - _updateFirstLast: function(vi){ - var wr = this.wrapper, // jQuery reference for the wrapper - op = this.options; // options object - wr.find("."+op.class_first+", ."+op.class_last).removeClass(op.class_first+" "+op.class_last); - if(vi) { - this.items.filter(":visible").first().addClass(op.class_first); - this.items.filter(":visible").last().addClass(op.class_last); - } else { - this.items.first().addClass(op.class_first); - this.items.not("."+op.class_empty).last().addClass(op.class_last); - } - }, - - - // PUBLIC METHODS - - // uninit Minimalect - destroy: function(){ - // remove (and automatically unbind) all Minimalect stuff - this.wrapper.remove(); - // display and unhook the original - this.element.off("change focus blur").show(); - // stop listening for changes - if (window.MutationObserver) - this.observer.disconnect(); - - // if debug mode is on, let them know upstairs - if(this.options.debug) console.log("Minimalect destroyed for ", this.element); - }, - - // update Minimalect's choice from the original select - update: function(){ - // reparse the select - this.ul.html(this._parseSelect()+'
                                              • '+this.options.empty+'
                                              • '); - } - - }; - - $.fn[pluginName] = function ( options, argument ) { - return this.each(function () { - if ($.isFunction(Plugin.prototype[options]) && options.charAt(0) != "_") { - if(arguments.length == 1) - $.data(this, 'plugin_' + pluginName)[options](); - else - $.data(this, 'plugin_' + pluginName)[options](argument); - } else if (!$.data(this, "plugin_" + pluginName)) { - $.data(this, "plugin_" + pluginName, new Plugin( this, options )); - } - }); - }; - -})( jQuery, window, document ); diff --git a/sites/all/themes/gui/materiobasetheme/js/libs/src/minimalect-master/jquery.minimalect.min.css b/sites/all/themes/gui/materiobasetheme/js/libs/src/minimalect-master/jquery.minimalect.min.css deleted file mode 100644 index 122244b2..00000000 --- a/sites/all/themes/gui/materiobasetheme/js/libs/src/minimalect-master/jquery.minimalect.min.css +++ /dev/null @@ -1 +0,0 @@ -.minict_wrapper{font-family:"Segoe UI",Segoe,"Lucida Grande","Lucida Sans Unicode",Arial,Helvetica,sans-serif;color:#333;background:#fff;position:relative;width:300px;height:35px;height:2.2rem;border:1px solid #e5e5e5;border-radius:3px;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}.minict_wrapper *{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}.minict_wrapper.disabled{background:#f5f5f5;text-shadow:0 1px 0 #fff}.minict_wrapper.disabled span{color:#bbb !important}.minict_wrapper:after{content:"\25BC";display:block;position:absolute;height:33px;width:33px;height:2.1rem;width:2.1rem;top:0;right:0;font-size:10px;font-size:0.6rem;line-height:32px;line-height:1.9rem;text-align:center;color:#555}.minict_wrapper.active:after{content:"\25B2"}.minict_wrapper.disabled:after{color:#bbb}.minict_wrapper span{display:block;border:0;outline:none;background:none;font-family:"Segoe UI",Segoe,"Lucida Grande","Lucida Sans Unicode",Arial,Helvetica,sans-serif;color:#333;font-size:16px;font-size:1rem;height:32px;height:2.0rem;line-height:23px;line-height:1.5rem;padding:4px 53px 0 6px;padding:4px 3.4rem 0 0.4rem;cursor:default;width:100%;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.minict_wrapper span:empty:before{content:attr(data-placeholder);color:#ccc;line-height:23px;line-height:1.5rem}.minict_wrapper ul{display:none;list-style:none;padding:0;margin:0 -1px;position:absolute;width:100%;width:-webkit-calc(100% + 2px);width:-moz-calc(100% + 2px);width:calc(100% + 2px);border:1px solid #e5e5e5;border-top:1px solid #f9f9f9;border-bottom-left-radius:3px;border-bottom-right-radius:3px;top:33px;top:2.0rem;left:0;max-height:350px;max-height:22rem;overflow-y:auto;z-index:999999}.minict_wrapper ul li{list-style:none;font-size:1rem;padding:0 10px;padding:0 0.7rem;cursor:pointer;background:#fff;height:35px;height:2.2rem;line-height:32px;line-height:2rem}.minict_wrapper ul li:hover{background:#fcfcfc;color:#111}.minict_wrapper ul li.minict_group{color:#444;background:#f6f6f6;font-weight:bold;cursor:default}.minict_wrapper ul li.minict_empty{display:none;background:#fff !important;color:#bbb;text-align:center;font-size:14px;font-size:0.9rem;height:55px;height:3.5rem;line-height:50px;line-height:3.3rem}.minict_wrapper ul li.disabled{cursor:default;background:#fff !important;color:#bbb}.minict_wrapper ul li.selected{color:#819a9a;background:#f8f9f9}.minict_wrapper ul li.highlighted{color:#fff;background:#819a9a}.minict_wrapper ul li.hidden{display:none}.minict_wrapper .minict_reset{color:#A9A9A9;bottom:0;display:none;font-size:18px;font-size:1.1rem;line-height:30px;line-height:1.9rem;position:absolute;right:35px;right:2.2rem;text-align:center;top:0;text-decoration:none;width:20px;width:1.2rem;-webkit-transition:all 0.35s ease-in-out;transition:all 0.35s ease-in-out}.minict_wrapper .minict_reset:hover{color:#e0e0e0;-webkit-transition:all 0.15s ease-in-out;transition:all 0.15s ease-in-out}.minict_wrapper .minict_reset:active{color:#636363}.minict_wrapper.disabled .minict_reset{display:none}.minict_wrapper.bubble{-webkit-box-shadow:0px 1px 3px 0px rgba(0,0,0,0.05);box-shadow:0px 1px 3px 0px rgba(0,0,0,0.05);background:-moz-linear-gradient(top, #fff 0%, #f9f9f9 100%);background:-webkit-gradient(linear, left top, left bottom, color-stop(0%, #fff), color-stop(100%, #f9f9f9));background:-webkit-linear-gradient(top, #fff 0%, #f9f9f9 100%);background:-o-linear-gradient(top, #fff 0%, #f9f9f9 100%);background:-ms-linear-gradient(top, #fff 0%, #f9f9f9 100%);background:linear-gradient(to bottom, #fff 0%, #f9f9f9 100%)}.minict_wrapper.bubble:hover{border-color:#dcdcdc}.minict_wrapper.bubble:after{border-left:1px solid #e5e5e5;-webkit-box-shadow:inset 1px 0px 0px 0px #fff;box-shadow:inset 1px 0px 0px 0px #fff;height:2.05rem}.minict_wrapper.bubble ul{top:2.7rem;-webkit-box-shadow:0px 5px 25px 0px rgba(0,0,0,0.25);box-shadow:0px 5px 25px 0px rgba(0,0,0,0.25);border-radius:6px;overflow:visible}.minict_wrapper.bubble ul:before{position:absolute;top:-11px;left:19px;content:".";color:transparent;width:0px;height:0px;border-style:solid;border-width:0 11px 11px 11px;border-color:transparent transparent #e5e5e5 transparent}.minict_wrapper.bubble ul:after{position:absolute;top:-10px;left:20px;content:".";color:transparent;width:0px;height:0px;border-style:solid;border-width:0 10px 10px 10px;border-color:transparent transparent #ffffff transparent}.minict_wrapper.bubble ul li.minict_first{border-top-left-radius:6px;border-top-right-radius:6px}.minict_wrapper.bubble ul li.minict_last{border-bottom-left-radius:6px;border-bottom-right-radius:6px}.minict_wrapper.bubble .minict_reset{width:30px} diff --git a/sites/all/themes/gui/materiobasetheme/js/libs/src/minimalect-master/jquery.minimalect.min.js b/sites/all/themes/gui/materiobasetheme/js/libs/src/minimalect-master/jquery.minimalect.min.js deleted file mode 100644 index c159af0f..00000000 --- a/sites/all/themes/gui/materiobasetheme/js/libs/src/minimalect-master/jquery.minimalect.min.js +++ /dev/null @@ -1,6 +0,0 @@ -/************************************ - MINIMALECT 0.8b - A minimalistic select replacement - http://git.io/Xedg9w -************************************/ -!function(e,t,s){function i(t,s){this.element=e(t),this.options=e.extend({},a,s),this._defaults=a,this._name=l,this.label=e('[for="'+this.element.attr("id")+'"]').attr("for","minict_"+this.element.attr("id")),this._init()}var l="minimalect",a={theme:"",reset:!1,transition:"fade",transition_time:150,remove_empty_option:!0,searchable:!0,ajax:null,debug:!1,live:!0,placeholder:"Select a choice",empty:"No results match your keyword.",error_message:"There was a problem with the request.",class_container:"minict_wrapper",class_group:"minict_group",class_empty:"minict_empty",class_active:"active",class_disabled:"disabled",class_selected:"selected",class_hidden:"hidden",class_highlighted:"highlighted",class_first:"minict_first",class_last:"minict_last",class_reset:"minict_reset",beforeinit:function(){},afterinit:function(){},onchange:function(){},onopen:function(){},onclose:function(){},onfilter:function(){}};i.prototype={_init:function(){this.options.beforeinit();var i=this.options,l=this;if(this.wrapper=e('
                                                '),this.element.hide().after(this.wrapper),i.theme&&this.wrapper.addClass(i.theme),this.element.prop("disabled")&&this.wrapper.addClass(i.class_disabled),this.input=e(""+(this.element.find("option[selected]").html()||"")+"").appendTo(this.wrapper),i.reset&&(this.reset=e('×').appendTo(this.wrapper)),this.ul=e("
                                                  "+this._parseSelect()+'
                                                • '+i.empty+"
                                                ").appendTo(this.wrapper),this.items=this.wrapper.find("li"),this.element.find("option[selected]").length&&(this._showResetLink(),this.items.filter('[data-value="'+this.element.find("option[selected]").val()+'"]').addClass(i.class_selected)),e(s).on("click",function(){l._hideChoices(l.wrapper)}),e("*").not(this.wrapper).not(this.wrapper.find("*")).on("focus",function(){l._hideChoices(l.wrapper)}),this.wrapper.on("click",function(e){e.stopPropagation(),l.element.prop("multiple")||l.element.prop("disabled")||l._toggleChoices()}),this.label.on("click",function(e){e.stopPropagation(),l.input.trigger("focus")}),this.wrapper.on("click","li:not(."+i.class_group+", ."+i.class_empty+", ."+i.class_disabled+")",function(){l._selectChoice(e(this))}),this.wrapper.on("click","li."+i.class_group+", li."+i.class_empty+", li."+i.class_disabled,function(e){e.stopPropagation(),l.input.focus()}),this.element.on("focus",function(){l.element.blur(),l._showChoices()}).on("blur",l._hideChoices).on("update",l.update),i.reset&&this.wrapper.on("click","a."+i.class_reset,function(e){return e.stopPropagation(),l._resetChoice(),!1}),this.input.on("focus click",function(e){e.stopPropagation(),l.element.prop("disabled")?l.input.blur():l._showChoices()}).on("keydown",function(e){switch(e.keyCode){case 38:e.preventDefault(),l._navigateChoices("up");break;case 40:e.preventDefault(),l._navigateChoices("down");break;case 13:case 9:l.items.filter("."+i.class_highlighted).length?l._selectChoice(l.items.filter("."+i.class_highlighted)):l.input.text()&&l._selectChoice(l.items.not("."+i.class_group+", ."+i.class_empty).filter(":visible").first()),13===e.keyCode&&(e.preventDefault(),l._hideChoices(l.wrapper));break;case 27:e.preventDefault(),l._hideChoices(l.wrapper)}}).on("keyup",function(t){-1===e.inArray(t.keyCode,[38,40,13,9,27])&&l._filterChoices()}),t.MutationObserver&&(this.observer=new MutationObserver(function(e){e.length>0&&(l.ul.html(l._parseSelect()+'
                                              • '+i.empty+"
                                              • "),l.options.debug&&console.log("Minimalect detected a DOM change for ",l.element))}),this.observer.observe(l.element[0],{childList:!0})),i.live){var a=this.element.val();setInterval(function(){a!=l.element.val()&&null!=l.element.val()&&""!=l.element.val()?(a=l.element.val(),"array"==typeof a?a.each(function(e,t){l._selectChoice(l.wrapper.find("li[data-value='"+t+"']"))}):l._selectChoice(l.wrapper.find("li[data-value='"+a+"']"))):(null==l.element.val()||""==l.element.val())&&(a=l.element.val(),l.items.removeClass(l.options.class_selected),l.input.text("").attr("data-placeholder",l.options.placeholder)),l.element.prop("disabled")?l.wrapper.addClass(i.class_disabled):l.wrapper.removeClass(i.class_disabled)},100)}i.afterinit()},_navigateChoices:function(e){var t=(this.wrapper,this.options),s=this.items,i="."+t.class_hidden+", ."+t.class_empty+", ."+t.class_group;if(!s.filter("."+t.class_highlighted).length)return"up"===e?s.not(i).last().addClass(t.class_highlighted):"down"===e&&s.not(i).first().addClass(t.class_highlighted),!1;if(cur=s.filter("."+t.class_highlighted),cur.removeClass(t.class_highlighted),"up"===e)if(s.not(i).first()[0]!=cur[0]){cur.prevAll("li").not(i).first().addClass(t.class_highlighted);var l=s.filter("."+t.class_highlighted).offset().top-this.ul.offset().top+this.ul.scrollTop();this.ul.scrollTop()>l&&this.ul.scrollTop(l)}else s.not(i).last().addClass(t.class_highlighted),this.ul.scrollTop(this.ul.height());else if("down"===e)if(s.not(i).last()[0]!=cur[0]){cur.nextAll("li").not(i).first().addClass(t.class_highlighted);var a=this.ul.height(),n=s.filter("."+t.class_highlighted).offset().top-this.ul.offset().top+s.filter("."+t.class_highlighted).outerHeight();n>a&&this.ul.scrollTop(this.ul.scrollTop()+n-a)}else s.not(i).first().addClass(t.class_highlighted),this.ul.scrollTop(0)},_parseSelect:function(){var t="";return this.element.find("optgroup").length?this.element.find("optgroup").each(function(){t+='
                                              • '+e(this).attr("label")+"
                                              • ",t+=this._parseElements(e(this).html())}):t=this._parseElements(this.element.html()),t},_parseElements:function(t){var s=this,i="";return e(e.trim(t)).filter("option").each(function(){var t=e(this);""===t.attr("value")&&s.options.remove_empty_option||(i+='
                                              • '+t.text()+"
                                              • ")}),i},_toggleChoices:function(){this.wrapper.hasClass(this.options.class_active)?this._hideChoices(this.wrapper):this._showChoices()},_showChoices:function(t){var s=this,i=this.wrapper,l=this.options;if(i.hasClass(l.class_active))"function"==typeof t&&t.call();else{switch(this._updateFirstLast(!1),e("."+l.class_container).each(function(){e(this)[0]!==i[0]&&s._hideChoices(e(this))}),"function"==typeof t&&t.call(),i.addClass(l.class_active),l.transition){case"fade":this.ul.fadeIn(l.transition_time);break;default:this.ul.show()}this.input.text("").focus(),this._hideResetLink(),this.options.onopen()}},_resetDropdown:function(e){var t=this.options;this.items.removeClass(t.class_hidden),this.wrapper.find("."+t.class_empty).hide(),this.items.filter("."+t.class_highlighted).removeClass(t.class_highlighted),"function"==typeof e&&e.call()},_hideChoices:function(e,t){var s=this.options,i=s.transition_time,l=this;if(e.hasClass(s.class_active)){switch(e.removeClass(s.class_active),s.transition){case"fade":e.children("ul").fadeOut(s.transition_time);break;default:e.children("ul").hide(),i=0}setTimeout(function(){l._resetDropdown(t),l.input.blur(),l.input.attr("data-placeholder")!=s.placeholder?l.input.text(l.input.attr("data-placeholder")):l.items.filter("."+s.class_selected).length||l.input.text("")},i),l._showResetLink(),s.onclose()}else"function"==typeof t&&t.call()},_filterChoices:function(){var t=this.wrapper,s=this.options,i=this;if(s.ajax)e.post(s.ajax,{q:this.input.text()}).success(function(l){if(s.debug&&console.log("Minimalect received ",l," for query '"+i.input.text()+"' in ",i.element),l.length){var a="";e.each(l,function(e,t){a+='"}),i.element.html(a),i.ul.html(i._parseSelect()+'
                                              • '+s.empty+"
                                              • "),t.find("."+s.class_empty).hide(),i.items=t.find("li"),i.options.onfilter(!0)}else i.ul.html('
                                              • '+s.empty+"
                                              • "),t.find("."+s.class_empty).show(),s.debug&&console.log("Minimalect didn't find any results for '"+i.input.text()+"' from ",i.element),i.options.onfilter(!1)}).error(function(e){t.find("."+s.class_empty).text(s.error_message),t.find("li").not("."+s.class_empty).addClass(s.class_hidden),t.find("."+s.class_empty).show(),s.debug&&console.error("Minimalect's AJAX query failed for ",i.element," - came back with ",e)});else{var l=this.input.text().replace(/[-\/\\^$*+?.()|[\]{}]/g,"\\$&");this.items.filter("."+s.class_highlighted).removeClass(s.class_highlighted),this.items.not(s.class_group).each(function(){e(this).text().search(new RegExp(l,"i"))<0||e(this).hasClass(s.class_disabled)?e(this).addClass(s.class_hidden):e(this).removeClass(s.class_hidden)}),this.items.filter("."+s.class_group).removeClass(s.class_hidden).each(function(){nextlis=e(this).nextAll("li").not("."+s.class_hidden+", ."+s.class_empty),(nextlis.first().hasClass(s.class_group)||!nextlis.length)&&e(this).addClass(s.class_hidden)}),t.find("."+s.class_empty).hide(),this.items.not("."+s.class_hidden+", ."+s.class_empty).length?this.options.onfilter(!0):(t.find("."+s.class_empty).show(),s.debug&&console.log("Minimalect didn't find any results for '"+this.input.text()+"' from ",this.element),this.options.onfilter(!1)),this._updateFirstLast(!0)}},_selectChoice:function(t){var s=this.element,i=this.options,l=[],a=[];return t.hasClass(this.options.class_disabled)?!1:(this.element.prop("multiple")||this.items.removeClass(i.class_selected),t.addClass(i.class_selected),this.items.filter("."+i.class_selected).each(function(){l.push(e(this).data("value")),a.push(e(this).text())}),this.input.text(a.join(", ")).attr("data-placeholder",a.join(", ")),(s.val()!=t.data("value")||s.val()!=l)&&(s.val(l),s.trigger("change")),this._showResetLink(),void this.options.onchange(t.data("value"),t.text()))},_resetChoice:function(){this.element.val("").trigger("change"),this._hideResetLink()},_showResetLink:function(){(this.input.text().length>0||this.ul.find("li."+this.options.class_selected).length>0)&&this.options.reset&&this.reset.show()},_hideResetLink:function(){this.options.reset&&this.reset.hide()},_updateFirstLast:function(e){var t=this.wrapper,s=this.options;t.find("."+s.class_first+", ."+s.class_last).removeClass(s.class_first+" "+s.class_last),e?(this.items.filter(":visible").first().addClass(s.class_first),this.items.filter(":visible").last().addClass(s.class_last)):(this.items.first().addClass(s.class_first),this.items.not("."+s.class_empty).last().addClass(s.class_last))},destroy:function(){this.wrapper.remove(),this.element.off("change focus blur").show(),t.MutationObserver&&this.observer.disconnect(),this.options.debug&&console.log("Minimalect destroyed for ",this.element)},update:function(){this.ul.html(this._parseSelect()+'
                                              • '+this.options.empty+"
                                              • ")}},e.fn[l]=function(t,s){return this.each(function(){e.isFunction(i.prototype[t])&&"_"!=t.charAt(0)?1==arguments.length?e.data(this,"plugin_"+l)[t]():e.data(this,"plugin_"+l)[t](s):e.data(this,"plugin_"+l)||e.data(this,"plugin_"+l,new i(this,t))})}}(jQuery,window,document); \ No newline at end of file diff --git a/sites/all/themes/gui/materiobasetheme/js/libs/src/minimalect-master/jquery.minimalect.scss b/sites/all/themes/gui/materiobasetheme/js/libs/src/minimalect-master/jquery.minimalect.scss deleted file mode 100644 index da207e8b..00000000 --- a/sites/all/themes/gui/materiobasetheme/js/libs/src/minimalect-master/jquery.minimalect.scss +++ /dev/null @@ -1,292 +0,0 @@ -/************************************ - MINIMALECT 0.9 - A minimalistic select replacement - - jQuery 1.7+ required. - Developed by @groenroos - http://www.groenroos.fi - - Github: http://git.io/Xedg9w - - Licensed under the MIT license. - -************************************/ - -$font: "Segoe UI", Segoe, "Lucida Grande", "Lucida Sans Unicode", Arial, Helvetica, sans-serif; -$color: #819a9a; - - - -.minict_wrapper { - font-family: $font; - color: #333; - background: #fff; - - position: relative; - width: 300px; - height: 35px; - height: 2.2rem; - - border: 1px solid #e5e5e5; - border-radius: 3px; - -webkit-box-sizing: border-box; - -moz-box-sizing: border-box; - box-sizing: border-box; - - * { - -webkit-box-sizing: border-box; - -moz-box-sizing: border-box; - box-sizing: border-box; - } - - &.disabled { - background: #f5f5f5; - text-shadow: 0 1px 0 #fff; - - span { - color: #bbb !important; - } - } - - &:after { - content: "\25BC"; - display: block; - position: absolute; - height: 33px; - width: 33px; - height: 2.1rem; - width: 2.1rem; - top: 0; - right: 0; - font-size: 10px; - font-size: 0.6rem; - line-height: 32px; - line-height: 1.9rem; - text-align: center; - color: #555; - } - - &.active:after { - content: "\25B2"; - } - - &.disabled:after { - color: #bbb; - } - - span { - display: block; - border: 0; - outline: none; - background: none; - font-family: $font; - color: #333; - font-size: 16px; - font-size: 1rem; - height: 32px; - height: 2.0rem; - line-height: 23px; - line-height: 1.5rem; - padding: 4px 53px 0 6px; - padding: 4px 3.4rem 0 0.4rem; - cursor: default; - width: 100%; - - white-space: nowrap; - overflow: hidden; - text-overflow: ellipsis; - - &:empty:before { - content: attr(data-placeholder); - color: #ccc; - line-height: 23px; - line-height: 1.5rem; - } - } - - ul { - display: none; - list-style: none; - padding: 0; - margin: 0 -1px; - position: absolute; - width: 100%; - width: -webkit-calc(100% + 2px); - width: -moz-calc(100% + 2px); - width: calc(100% + 2px); - border: 1px solid #e5e5e5; - border-top: 1px solid #f9f9f9; - border-bottom-left-radius: 3px; - border-bottom-right-radius: 3px; - top: 33px; - top: 2.0rem; - left: 0; - max-height: 350px; - max-height: 22rem; - overflow-y: auto; - z-index: 999999; - - li { - list-style: none; - font-size: 1rem; - padding: 0 10px; - padding: 0 0.7rem; - cursor: pointer; - background: #fff; - height: 35px; - height: 2.2rem; - line-height: 32px; - line-height: 2rem; - - &:hover { - background: #fcfcfc; - color: #111; - } - - &.minict_group { - color: #444; - background: #f6f6f6; - font-weight: bold; - cursor: default; - } - - &.minict_empty { - display: none; - background: #fff !important; - color: #bbb; - text-align: center; - font-size: 14px; - font-size: 0.9rem; - height: 55px; - height: 3.5rem; - line-height: 50px; - line-height: 3.3rem; - } - - &.disabled { - cursor: default; - background: #fff !important; - color: #bbb; - } - - &.selected { - color: $color; - background: lighten($color, 42%); - } - - &.highlighted { - color: #fff; - background: $color; - } - - &.hidden { - display: none; - } - } - } - - .minict_reset { - color: #A9A9A9; - bottom: 0; - display: none; - font-size: 18px; - font-size: 1.1rem; - line-height: 30px; - line-height: 1.9rem; - position: absolute; - right: 35px; - right: 2.2rem; - text-align: center; - top: 0; - text-decoration: none; - width: 20px; - width: 1.2rem; - -webkit-transition: all 0.35s ease-in-out; - transition: all 0.35s ease-in-out; - - &:hover { - color: #A9A9A9 + 55; - -webkit-transition: all 0.15s ease-in-out; - transition: all 0.15s ease-in-out; - } - - &:active { - color: #A9A9A9 - 70; - } - } - - &.disabled .minict_reset { - display: none; - } -} - - - -.minict_wrapper.bubble { - -webkit-box-shadow: 0px 1px 3px 0px rgba(0, 0, 0, .05); - box-shadow: 0px 1px 3px 0px rgba(0, 0, 0, .05); - background: -moz-linear-gradient(top, #ffffff 0%, #f9f9f9 100%); - background: -webkit-gradient(linear, left top, left bottom, color-stop(0%,#ffffff), color-stop(100%,#f9f9f9)); - background: -webkit-linear-gradient(top, #ffffff 0%,#f9f9f9 100%); - background: -o-linear-gradient(top, #ffffff 0%,#f9f9f9 100%); - background: -ms-linear-gradient(top, #ffffff 0%,#f9f9f9 100%); - background: linear-gradient(to bottom, #ffffff 0%,#f9f9f9 100%); - - &:hover { - border-color: #dcdcdc; - } - - &:after { - border-left: 1px solid #e5e5e5; - -webkit-box-shadow: inset 1px 0px 0px 0px #fff; - box-shadow: inset 1px 0px 0px 0px #fff; - height: 2.05rem; - } - - ul { - top: 2.7rem; - -webkit-box-shadow: 0px 5px 25px 0px rgba(0, 0, 0, .25); - box-shadow: 0px 5px 25px 0px rgba(0, 0, 0, .25); - border-radius: 6px; - overflow: visible; - - &:before { - position: absolute; - top: -11px; - left: 19px; - content: "."; - color: transparent; - width: 0px; - height: 0px; - border-style: solid; - border-width: 0 11px 11px 11px; - border-color: transparent transparent #e5e5e5 transparent; - } - - &:after { - position: absolute; - top: -10px; - left: 20px; - content: "."; - color: transparent; - width: 0px; - height: 0px; - border-style: solid; - border-width: 0 10px 10px 10px; - border-color: transparent transparent #ffffff transparent; - } - - li.minict_first { - border-top-left-radius: 6px; - border-top-right-radius: 6px; - } - li.minict_last { - border-bottom-left-radius: 6px; - border-bottom-right-radius: 6px; - } - } - - .minict_reset { - width: 30px; - } -} diff --git a/sites/all/themes/gui/materiobasetheme/js/libs/src/minimalect-master/package.json b/sites/all/themes/gui/materiobasetheme/js/libs/src/minimalect-master/package.json deleted file mode 100644 index 9bdf0611..00000000 --- a/sites/all/themes/gui/materiobasetheme/js/libs/src/minimalect-master/package.json +++ /dev/null @@ -1,30 +0,0 @@ -{ - "name": "minimalect", - "version": "0.8.0", - "description": "Minimal select replacement for jQuery", - "main": "jquery.minimalect.js", - "repository": { - "type": "git", - "url": "git://github.com/groenroos/minimalect.git" - }, - "keywords": [ - "jquery", - "minimalect" - ], - "author": "Oskari Groenroos", - "license": "MIT", - "readmeFilename": "README.md", - "bugs": { - "url": "https://github.com/groenroos/minimalect/issues" - }, - "devDependencies": { - "grunt-contrib-clean": "~0.4.1", - "grunt-contrib-concat": "~0.3.0", - "grunt-contrib-uglify": "~0.2.2", - "grunt-cli": "~0.1.9", - "grunt": "~0.4.1", - "grunt-contrib-jasmine": "~0.5.1", - "grunt-contrib-sass": "~0.3.0", - "grunt-banner": "~0.1.4" - } -} diff --git a/sites/all/themes/gui/materiobasetheme/materiobasetheme.info b/sites/all/themes/gui/materiobasetheme/materiobasetheme.info index f962d2e8..aa748560 100644 --- a/sites/all/themes/gui/materiobasetheme/materiobasetheme.info +++ b/sites/all/themes/gui/materiobasetheme/materiobasetheme.info @@ -21,10 +21,10 @@ stylesheets[all][] = "css/nonsemantic.css" ;----------// Scripts -scripts[] = "js/libs/jquery.history.js" -scripts[] = "js/libs/jquery.hotkeys.js" -scripts[] = "js/libs/jquery.columnizer.js" -scripts[] = "js/libs/jquery.lazyload.min.js" +scripts[] = "bower_components/history.js/compressed/history.js" +scripts[] = "bower_components/jquery.hotkeys/jquery.hotkeys.js" +scripts[] = "bower_components/jquery.columnizer/src/jquery.columnizer.min.js" +scripts[] = "bower_components/jquery.lazyload/jquery.lazyload.min.js" scripts[] = "js/script.min.js" diff --git a/sites/all/themes/gui/materiobasetheme/scss/layout.scss b/sites/all/themes/gui/materiobasetheme/scss/layout.scss index 8b959105..f298bd23 100644 --- a/sites/all/themes/gui/materiobasetheme/scss/layout.scss +++ b/sites/all/themes/gui/materiobasetheme/scss/layout.scss @@ -65,6 +65,9 @@ $retina: ( *{ box-sizing: content-box; + &:before, &:after{ + box-sizing: content-box; + } } html, body{ @@ -93,6 +96,23 @@ input[type="checkbox"] + label{ margin:0; } +p{ + font-family: inherit; + font-weight: inherit; + font-size: inherit; + line-height: inherit; + margin-bottom: inherit; +} + +a{ + font-size: inherit; +} + +.column, .columns { + padding: inherit; + float: inherit; +} + $rootminwidth : 320px; /** NIVEAU 0 */ @@ -131,7 +151,7 @@ $header-z-index:1000; html.no-touch .editmenu-enabled &{ @include mt(80px); } html.no-touch .admin-menu &{ @include mt(85px); } } - @media #{$medium-only}{ + @media #{$small-only}{ >.region{@include pt(5px); @include pb(5px);} } //change this z-index:999; diff --git a/sites/all/themes/gui/materiobasetheme/scss/misc.scss b/sites/all/themes/gui/materiobasetheme/scss/misc.scss index f4f13af5..456db9e0 100644 --- a/sites/all/themes/gui/materiobasetheme/scss/misc.scss +++ b/sites/all/themes/gui/materiobasetheme/scss/misc.scss @@ -9,7 +9,7 @@ -moz-border-radius: 5px; -webkit-border-radius: 5px; border-radius: 5px; - @include fs12(); + @include fs12; &.warning { color: #c09853;//#840; @@ -28,7 +28,7 @@ color: #468847;//#036; background-color: #dff0d8;//#bdf; border-color:#d6e9c6;//#ace; - @include fs14(); + @include fs14; } } @@ -138,34 +138,34 @@ div.messages { @include messages();} // .icon(20px); // } -i.icon-materio-viewmode-cardsmall{ - @include icon(20px, -42px, 0); - &.active{@include icon(21px, 0, 0); } - &:hover:not(.active){@include icon(21px, -21px, 0); } -} -i.icon-materio-viewmode-cardmedium{ - @include icon(21px, -42px, -21px); - &.active{@include icon(21px, 0, -21px); } - &:hover:not(.active){@include icon(21px, -21px, -21px); } -} -i.icon-materio-viewmode-cardbig{ - @include icon(21px, -42px, -42px); - &.active{@include icon(21px, 0, -42px); } - &:hover:not(.active){@include icon(21px, -21px, -42px); } -} -i.icon-materio-viewmode-cardfull{ - @include icon(21px, -42px, -63px); - &.active{@include icon(21px, 0, -63px); } - &:hover:not(.active){@include icon(21px, -21px, -63px); } -} +// i.icon-materio-viewmode-cardsmall{ +// @include icon(20px, -42px, 0); +// &.active{@include icon(21px, 0, 0); } +// &:hover:not(.active){@include icon(21px, -21px, 0); } +// } +// i.icon-materio-viewmode-cardmedium{ +// @include icon(21px, -42px, -21px); +// &.active{@include icon(21px, 0, -21px); } +// &:hover:not(.active){@include icon(21px, -21px, -21px); } +// } +// i.icon-materio-viewmode-cardbig{ +// @include icon(21px, -42px, -42px); +// &.active{@include icon(21px, 0, -42px); } +// &:hover:not(.active){@include icon(21px, -21px, -42px); } +// } +// i.icon-materio-viewmode-cardfull{ +// @include icon(21px, -42px, -63px); +// &.active{@include icon(21px, 0, -63px); } +// &:hover:not(.active){@include icon(21px, -21px, -63px); } +// } -i.icon-materio-search{ - @include icon(21px, -63px, -63px); -} +// i.icon-materio-search{ +// @include icon(21px, -63px, -63px); +// } -i.icon-materio-folder{ - @include icon(21px, -84px, -63px); -} +// i.icon-materio-folder{ +// @include icon(21px, -84px, -63px); +// } /** diff --git a/sites/all/themes/gui/materiobasetheme/scss/styles.scss b/sites/all/themes/gui/materiobasetheme/scss/styles.scss index 8c4b9590..97d06946 100644 --- a/sites/all/themes/gui/materiobasetheme/scss/styles.scss +++ b/sites/all/themes/gui/materiobasetheme/scss/styles.scss @@ -346,7 +346,7 @@ $headerouterheight:$headerheight+$headerpaddingtop+$headerpaddingbottom; @include fs12; i{ vertical-align: text-bottom; - margin: 0 2px 1px 0; + margin: 0 5px 1px 0; } a span.account{text-transform: lowercase;} a span.logout{display:none; @include ml(5px); } @@ -852,14 +852,14 @@ $headerouterheight:$headerheight+$headerpaddingtop+$headerpaddingbottom; &.active{cursor:normal;} .inner{display:none;@include fs10; } } - @media #{$medium-only}{ + @media #{$small-only}{ .viewmode-link{ display:block; &:not(.active){display:none;} } } @media #{$small-only}{ html.no-touch &:hover, &.hovered{ .viewmode-link.viewmode-cardsmall, .viewmode-link.viewmode-cardmedium{display:block;} } } - @media #{$medium-only}{ + @media #{$small-only}{ html.no-touch &:hover, &.hovered{ .viewmode-link.viewmode-cardsmall, .viewmode-link.viewmode-cardmedium, .viewmode-link.viewmode-cardbig{display:block;} } } } @@ -894,6 +894,7 @@ $headerouterheight:$headerheight+$headerpaddingtop+$headerpaddingbottom; padding: 4px 5px; height:25px; @include fs12; line-height:1; background-position: 100% 5px; + width:105%; &.throbbing { background-position: 100% -15px; } } @@ -1916,6 +1917,7 @@ body.page-node-11187{ &.flocon{ .get-link{ background-color: #69CDCF; } } &.etoile { .get-link{ background-color: #D476AE; } } &.cinqetoiles { .get-link{ background-color: #E6DE1C; } } + &.ecole-de-neige{float: none}; // &.ecole-de-neige { .list-neige{min-height:80px;} } } // end div.column div.column-demi