diff --git a/.mailmap b/.mailmap index 40bbb70898..7132327b50 100644 --- a/.mailmap +++ b/.mailmap @@ -15,11 +15,13 @@ GITHUB: codeinthehole GITHUB: dandv GITHUB: DenisGorbachev GITHUB: emgee3 +GITHUB: EOT GITHUB: FooBarWidget GITHUB: jacott GITHUB: Maxhodges GITHUB: meawoppl GITHUB: mitar +GITHUB: mitar GITHUB: mizzao GITHUB: mquandalle GITHUB: nathan-muir @@ -28,6 +30,14 @@ GITHUB: ryw GITHUB: rzymek GITHUB: sdarnell GITHUB: timhaines +GITHUB: jfhamlin +GITHUB: marcandre +GITHUB: michaelbishop +GITHUB: OyoKooN +GITHUB: paulswartz +GITHUB: rdickert +GITHUB: icellan +GITHUB: yeputons METEOR: avital METEOR: debergalis @@ -40,3 +50,5 @@ METEOR: karayu METEOR: n1mmy METEOR: sixolet METEOR: Slava +METEOR: stubailo +METEOR: ekatek diff --git a/History.md b/History.md index 9c4cb26bd3..ca5574123c 100644 --- a/History.md +++ b/History.md @@ -1,85 +1,57 @@ ## v.NEXT -* Meteor developer accounts - - `accounts-meteor-developer` package for OAuth support - - managing deployed apps with developer accounts instead of site - passwords. - - New commands: 'meteor authorized', 'meteor claim', 'meteor logout', - 'meteor whoami' +## v0.7.1.1 -* oplog improvements - - support all operators except $where and $near. still not used for - limit and skip - - more optimizations to avoid needless data fetches from MongoDB - - fix "Cannot call method 'has' of null" error #1767 +* Integrate with Meteor developer accounts, a new way of managing your + meteor.com deployed sites. When you use `meteor deploy`, you will be + prompted to create a developer account. + - Once you've created a developer account, you can log in and out + from the command line with `meteor login` and `meteor logout`. + - You can claim legacy sites with `meteor claim`. This command will + prompt you for your site password if you are claiming a + password-protected site; after claiming it, you will not need to + enter the site password again. + - You can add or remove authorized users, and view the list of + authorized users, for a site with `meteor authorized`. + - You can view your current username with `meteor whoami`. + - This release also includes the `accounts-meteor-developer` package + for building Meteor apps that allow users to log in with their own + developer accounts. -* Minimongo improvements - - support $comment - - support 'obj' name in $where - - $regexp matches actual regexps properly - - better support for $nin, $ne, $not - - support using { $in: [/foo/, /bar/] }. #1707 - - support {$exists: false} - - better type-checking for selectors - - support {x: {$elemMatch: {$gt: 5}}} - - match mongo's behavior better when there are arrays in the document - - support $near with sort - - implement updates with { $set: { 'a.$.b': 5 } } - - {$type: 4} queries - - optimize `remove({})` when observers are paused - - make update-by-id constant time +* Improve the oplog tailing implementation for getting real-time database + updates from MongoDB. + - Add support for all operators except `$where` and `$near`. Limit and + skip are not supported yet. + - Add optimizations to avoid needless data fetches from MongoDB. + - Fix an error ("Cannot call method 'has' of null") in an oplog + callback. #1767 -* Add `clientAddress` and `httpHeaders` to `this.connection` in method - calls and publish functions. +* Add and improve support for minimongo operators. + - Support `$comment`. + - Support `obj` name in `$where`. + - `$regexp` matches actual regexps properly. + - Improve support for `$nin`, `$ne`, `$not`. + - Support using `{ $in: [/foo/, /bar/] }`. #1707 + - Support `{$exists: false}`. + - Improve type-checking for selectors. + - Support `{x: {$elemMatch: {$gt: 5}}}`. + - Match Mongo's behavior better when there are arrays in the document. + - Support `$near` with sort. + - Implement updates with `{ $set: { 'a.$.b': 5 } }`. + - Support `{$type: 4}` queries. + - Optimize `remove({})` when observers are paused. + - Make update-by-id constant time. + - Allow `{$set: {'x._id': 1}}`. #1794 -* Hash login tokens before storing them in the database. Legacy unhashed - tokens are upgraded to hashed tokens in the database as they are used - in logins. - -* Cursors with a field specifier containing `{_id: 0}` can no longer be used - with `observeChanges` or `observe`. This includes the implicit calls to these - functions that are done when returning a cursor from a publish function or - using `{{#each}}`. - -* Transform functions must return objects and may not change the `_id` field - (though they may leave it out) - -* XXX sourcemaps support for stylesheets, including less sourcemaps -* XXX css linting (breaks on errors) -* XXX css preprocessing to concatenate files correctly (pulls @imports to the - beginning) -* XXX supports `.import.less` and `.import.styl` to prevent Meteor processing - stylesheets. `.lessimport` is deprecated - -* Patch Underscore to not treat plain objects (`x.constructor === Object`) - with numeric `length` fields as arrays. Among other things, this allows you - to use documents with numeric `length` fields with Mongo. #594 #1737 - -* Fix races when calling login and/or logoutOtherClients from multiple - tabs. #1616 - -* Upgrade `jquery-waypoints` package from 1.1.7 to 2.0.3. (Contains - backward-incompatible changes). - -* Add `frame-src` to `browser-policy-content` and account for - cross-browser CSP disparities. - -* Upgrade CoffeeScript from 1.6.3 to 1.7.1. - -* Make sure that `api.add_files('foo.coffee', {bare: true})` works when - adding CoffeeScript files. #1668 - -* `force-ssl`: don't require SSL during `meteor run` in IPv6 - environments. #1751 - -* Upgraded dependencies: - - node from 0.10.22 to 0.10.25 (removed workaround from 0.7.0 -- now - support 0.10.25+) - - Upgrade jQuery from 1.8.2 to 1.10.2. - XXX see http://jquery.com/upgrade-guide/1.9/ for incompatibilities - XXX consider taking 1.11 instead, which was released this week - - source-map from 0.3.30 to 0.3.32 #1782 - - websocket-driver from 0.3.1 to 0.3.2 +* Upgraded dependencies + - node: 0.10.25 (from 0.10.22). The workaround for specific Node + versions from 0.7.0 is now removed; 0.10.25+ is supported. + - jquery: 1.11.0 (from 1.8.2). See + http://jquery.com/upgrade-guide/1.9/ for upgrade instructions. + - jquery-waypoints: 2.0.4 (from 1.1.7). Contains + backwards-incompatible changes. + - source-map: 0.3.2 (from 0.3.30) #1782 + - websocket-driver: 0.3.2 (from 0.3.1) - http-proxy: 1.0.2 (from a pre-release fork of 1.0) - semver: 2.2.1 (from 2.1.0) - request: 2.33.0 (from 2.27.0) @@ -90,73 +62,138 @@ - source-map-support: 0.2.5 (from 0.2.3) - mongo: 2.4.9 (from 2.4.8) - openssl in mongo: 1.0.1f (from 1.0.1e) - - kexec from 0.1.1 to 0.2.0 - - drop shell-quote from dev bundle - - XXX upgraded `less` from 1.3.3 to 1.6.1 - - XXX upgraded `stylus` from 0.37.0 to 0.42.2 and `nib` from `1.0.0` to `1.0.2` + - kexec: 0.2.0 (from 0.1.1) + - less: 1.6.1 (from 1.3.3) + - stylus: 0.42.2 (from 0.37.0) + - nib: 1.0.2 (from 1.0.0) + - coffeescript: 1.7.1 (from 1.6.3) -* Types added with `EJSON.addType` now have default `clone` and `equals` - implementations. #1745 +* CSS preprocessing and sourcemaps: + - Add sourcemap support for CSS stylesheet preprocessors. Use + sourcemaps for stylesheets compiled with LESS. + - Improve CSS minification to deal with `@import` statements correctly. + - Lint CSS files for invalid `@` directives. + - Change the recommended suffix for imported LESS files from + `.lessimport` to `.import.less`. Add `.import.styl` to allow + `stylus` imports. `.lessimport` continues to work but is deprecated. -* Allow cursors on named local collections to be returned from arrays in publish - functions. #1820 +* Add `clientAddress` and `httpHeaders` to `this.connection` in method + calls and publish functions. -* Don't lose permissions (eg, executable bit) on npm files. #1808 - -* Detect if CSS failed to load and refresh. - -* Don't crash with an empty programs/foo directory or one without a - package.js. - -* Do a better job of handling shrinkwrap files when a npm module depends - on something that isn't a semver. #1684 - -* Fix failures updating npm dependencies when a node_modules directory exists - above the project directory. #1761 - -* In email package, print a message in dev mode when email is not sent. #1196 - -* Meteor accounts logins (or anything else using the `localstorage` package) no - longer persist in IE7. - -* Fix `accounts-password` login with private-browsing Safari (and - generally, the use of the `localstorage` package). #1291 - -* New `retry` package. - -* Pass through `update` and `remove` return values for validated - operations. #1759 +* Hash login tokens before storing them in the database. Legacy unhashed + tokens are upgraded to hashed tokens in the database as they are used + in login requests. * Change default accounts-ui styling and add more CSS classes. -* Don't leak sockets on error in dev-mode proxy. +* Refactor command-line tool. Add test harness and better tests. Run + `meteor self-test --help` for info on running the tools test suite. -* XXX Make springboard actually exec +* Speed up application re-build in development mode by re-using file + hash computation between file change watching code and application + build code.. -* Speed up build by re-using file hashes. +* Fix issues with documents containing a key named `length` with a + numeric value. Underscore treated these as arrays instead of objects, + leading to exceptions when . Patch Underscore to not treat plain + objects (`x.constructor === Object`) with numeric `length` fields as + arrays. #594 #1737 -* Include oauth_verifier as a header rather than a parameter in - `oauth1` package. #1825 +* Deprecate `Accounts.loginServiceConfiguration` in favor of + `ServiceConfiguration.configurations`, exported by the + `service-configuration` package. `Accounts.loginServiceConfiguration` + is maintained for backwards-compatibility, but it is defined in a + `Meteor.startup` block and so cannot be used from top-level code. -* Refactor command-line tool. Add test harness and better tests. +* Cursors with a field specifier containing `{_id: 0}` can no longer be + used with `observeChanges` or `observe`. This includes the implicit + calls to these functions that are done when returning a cursor from a + publish function or using `{{#each}}`. -* Add `Accounts.connection` for using Meteor accounts packages with a - non-default DDP connection. +* Transform functions must return objects and may not change the `_id` + field, though they may leave it out. -* Fix order of setting login token and setting user id on a connection. +* Remove broken IE7 support from the `localstorage` package. Meteor + accounts logins no longer persist in IE7. + +* Fix the `localstorage` package when used with Safari in private + browsing mode. This fixes a problem with login token storage and + account login. #1291 + +* Types added with `EJSON.addType` now have default `clone` and `equals` + implementations. Users may still specify `clone` or `equals` functions + to override the default behavior. #1745 + +* Add `frame-src` to `browser-policy-content` and account for + cross-browser CSP disparities. + +* Deprecate `Oauth.initiateLogin` in favor of `Oauth.showPopup`. + +* Add `WebApp.rawConnectHandlers` for adding connect handlers that run + before any other Meteor handlers, except `connect.compress()`. Raw + connect handlers see the URL's full path (even if ROOT_URL contains a + non-empty path) and they run before static assets are served. + +* Add `Accounts.connection` to allow using Meteor accounts packages with + a non-default DDP connection. + +* Detect and reload if minified CSS files fail to load at startup. This + prevents the application from running unstyled if the page load occurs + while the server is switching versions. + +* Allow Npm.depends to specify any http or https URL containing a full + 40-hex-digit SHA. #1686 + +* Add `retry` package for connection retry with exponential backoff. + +* Pass `update` and `remove` return values correctly when using + collections validated with `allow` and `deny` rules. #1759 * If you're using Deps on the server, computations and invalidation - functions are not allowed to yield. + functions are not allowed to yield. Throw an error instead of behaving + unpredictably. + +* Fix namespacing in coffeescript files added to a package with the + `bare: true` option. #1668 + +* Fix races when calling login and/or logoutOtherClients from multiple + tabs. #1616 + +* Include oauth_verifier as a header rather than a parameter in + the `oauth1` package. #1825 + +* Fix `force-ssl` to allow local development with `meteor run` in IPv6 + environments. #1751` + +* Allow cursors on named local collections to be returned from a publish + function in an array. #1820 + +* Fix build failure caused by a directory in `programs/` without a + package.js file. + +* Do a better job of handling shrinkwrap files when an npm module + depends on something that isn't a semver. #1684 + +* Fix failures updating npm dependencies when a node_modules directory + exists above the project directory. #1761 + +* Preserve permissions (eg, executable bit) on npm files. #1808 * SockJS tweak to support relative base URLs. -* Oauth.initiateLogin is deprecated in favor of Oauth.showPopup. +* Don't leak sockets on error in dev-mode proxy. -* User-supplied connect handlers now see the URL's full path, even if - ROOT_URL contains a non-empty path. +* Clone arguments to `added` and `changed` methods in publish + functions. This allows callers to reuse objects and prevents already + published data from changing after the fact. #1750 -* Don't cache direct references to the fields arguments to the subscription - `added` and `changed` methods. #1750 +* Ensure springboarding to a different meteor tools version always uses + `exec` to run the old version. This simplifies process management for + wrapper scripts. + +Patches contributed by GitHub users DenisGorbachev, EOT, OyoKooN, awwx, +dandv, icellan, jfhamlin, marcandre, michaelbishop, mitar, mizzao, +mquandalle, paulswartz, rdickert, rzymek, timhaines, and yeputons. ## v0.7.0.1 @@ -267,8 +304,6 @@ apply the patch and will instead disable websockets. * Increase the maximum size spiderable will return for a page from 200kB to 5MB. -* New 'facts' package publishes internal statistics about Meteor. - * Upgraded dependencies: * SockJS server from 0.3.7 to 0.3.8, including new faye-websocket module. * Node from 0.10.21 to 0.10.22 diff --git a/LICENSE.txt b/LICENSE.txt index ad05f62cf7..082c5e26ce 100644 --- a/LICENSE.txt +++ b/LICENSE.txt @@ -71,6 +71,13 @@ handlebars: https://github.com/wycats/handlebars.js/ Copyright (C) 2011 by Yehuda Katz +---------- +clean-css: https://github.com/GoalSmashers/clean-css +---------- + +Copyright (c) 2011 GoalSmashers.com + + ---------- progress: https://github.com/visionmedia/node-progress qs: https://github.com/visionmedia/node-querystring @@ -285,6 +292,7 @@ deep-equal: https://github.com/substack/node-deep-equal editor: https://github.com/substack/node-editor minimist: https://github.com/substack/minimist quotemeta: https://github.com/substack/quotemeta +text-table: https://github.com/substack/text-table ---------- Copyright 2010, 2011, 2012, 2013 James Halliday (mail@substack.net) @@ -587,7 +595,7 @@ Copyright 2009 Google Inc. ---------- request: https://github.com/mikeal/request -aws-sign: https://github.com/mikeal/aws-sign +aws-sign2: https://github.com/mikeal/aws-sign cookie-jar: https://github.com/mikeal/cookie-jar forever-agent: https://github.com/mikeal/forever-agent oauth-sign: https://github.com/mikeal/oauth-sign @@ -646,6 +654,35 @@ Diff Match and Patch: http://code.google.com/p/google-diff-match-patch/ Copyright 2006 Google Inc. +---------- +ansicolors: https://github.com/thlorenz/ansicolors +ansistyles: https://github.com/thlorenz/ansistyles +---------- + +Copyright 2013 Thorsten Lorenz. + + +---------- +columnify: https://github.com/timoxley/columnify +---------- + +Copyright Tim Oxley + + +---------- +eventemitter3: https://github.com/3rd-Eden/EventEmitter3 +---------- + +Copyright Arnout Kazemier + + +---------- +punycode: https://github.com/bestiejs/punycode.js +---------- + +Copyright Mathias Bynens + + ============ BSD Licenses @@ -1346,6 +1383,25 @@ required for its use. Other ===== +---------- +heapdump: https://github.com/bnoordhuis/node-heapdump +---------- + +Copyright (c) 2012, Ben Noordhuis + +Permission to use, copy, modify, and/or distribute this software for any +purpose with or without fee is hereby granted, provided that the above +copyright notice and this permission notice appear in all copies. + +THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF +OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + + ---------- mimelib-noiconv: https://github.com/andris9/mimelib mailcomposer: https://github.com/andris9/mailcomposer @@ -1396,6 +1452,7 @@ By Isaac Z. Schlueter (http://blog.izs.me/) ---------- opener: https://github.com/domenic/opener +path-is-inside: https://github.com/domenic/path-is-inside ---------- DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE @@ -1444,6 +1501,91 @@ OTHER DEALINGS IN THE SOFTWARE. For more information, please refer to +---------- +tough-cookie: https://github.com/goinstant/tough-cookie +---------- + +Copyright GoInstant, Inc. and other contributors. All rights reserved. +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to +deal in the Software without restriction, including without limitation the +rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +sell copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +IN THE SOFTWARE. + +The following exceptions apply: + +=== + +`pubSufTest()` of generate-pubsuffix.js is in the public domain. + + // Any copyright is dedicated to the Public Domain. + // http://creativecommons.org/publicdomain/zero/1.0/ + +=== + +`public-suffix.txt` was obtained from + +via . + +That file contains the usual Mozilla triple-license, for which this project uses it +under the terms of the MPL 1.1: + + // ***** BEGIN LICENSE BLOCK ***** + // Version: MPL 1.1/GPL 2.0/LGPL 2.1 + // + // The contents of this file are subject to the Mozilla Public License Version + // 1.1 (the "License"); you may not use this file except in compliance with + // the License. You may obtain a copy of the License at + // http://www.mozilla.org/MPL/ + // + // Software distributed under the License is distributed on an "AS IS" basis, + // WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + // for the specific language governing rights and limitations under the + // License. + // + // The Original Code is the Public Suffix List. + // + // The Initial Developer of the Original Code is + // Jo Hermans . + // Portions created by the Initial Developer are Copyright (C) 2007 + // the Initial Developer. All Rights Reserved. + // + // Contributor(s): + // Ruben Arakelyan + // Gervase Markham + // Pamela Greene + // David Triendl + // Jothan Frakes + // The kind representatives of many TLD registries + // + // Alternatively, the contents of this file may be used under the terms of + // either the GNU General Public License Version 2 or later (the "GPL"), or + // the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + // in which case the provisions of the GPL or the LGPL are applicable instead + // of those above. If you wish to allow use of your version of this file only + // under the terms of either the GPL or the LGPL, and not to allow others to + // use your version of this file under the terms of the MPL, indicate your + // decision by deleting the provisions above and replace them with the notice + // and other provisions required by the GPL or the LGPL. If you do not delete + // the provisions above, a recipient may use your version of this file under + // the terms of any one of the MPL, the GPL or the LGPL. + // + // ***** END LICENSE BLOCK ***** + + + ---------- MongoDB: http://www.mongodb.org/ ---------- diff --git a/docs/.meteor/release b/docs/.meteor/release index 400877328a..7fce57eeba 100644 --- a/docs/.meteor/release +++ b/docs/.meteor/release @@ -1 +1 @@ -sso-1 +0.7.1.1 diff --git a/docs/client/api.html b/docs/client/api.html index cbd73d35a8..284f73fa90 100644 --- a/docs/client/api.html +++ b/docs/client/api.html @@ -1629,6 +1629,16 @@ This function is provided by the `accounts-password` package. See the {{> api_box loginWithExternalService}} +Available functions are: + +* `Meteor.loginWithMeteorDeveloperAccount` +* `Meteor.loginWithFacebook` +* `Meteor.loginWithGithub` +* `Meteor.loginWithGoogle` +* `Meteor.loginWithMeetup` +* `Meteor.loginWithTwitter` +* `Meteor.loginWithWeibo` + These functions initiate the login process with an external service (eg: Facebook, Google, etc), using OAuth. When called they open a new pop-up window that loads the provider's login page. Once the user has logged in @@ -1659,14 +1669,15 @@ External login services typically require registering and configuring your application before use. The easiest way to do this is with the [`accounts-ui` package](#accountsui) which presents a step-by-step guide to configuring each service. However, the data can be also be entered -manually in the `Accounts.loginServiceConfiguration` collection. For -example: +manually in the `ServiceConfiguration.configurations` collection, which +is exported by the `service-configuration` package. For example, after +running `meteor add service-configuration` in your app: // first, remove configuration entry in case service is already configured - Accounts.loginServiceConfiguration.remove({ + ServiceConfiguration.configurations.remove({ service: "weibo" }); - Accounts.loginServiceConfiguration.insert({ + ServiceConfiguration.configurations.insert({ service: "weibo", clientId: "1292962797", secret: "75a730b58f5691de5522789070c319bc" diff --git a/docs/client/concepts.html b/docs/client/concepts.html index a0e7d1e914..8bcac1bfa1 100644 --- a/docs/client/concepts.html +++ b/docs/client/concepts.html @@ -154,21 +154,18 @@ other packages. However sometimes load order dependencies in your application are unavoidable. The JavaScript and CSS files in an application are loaded according to these rules: -* Files in directories named `lib` are loaded first. - -* Files that match `main.*` are loaded after everything else. - -* Files in subdirectories are loaded before files in parent - directories, so that files in the deepest subdirectory are loaded - first (after `lib`), and files in the root directory are loaded last - (other than `main.*`). +* Files in subdirectories are loaded before files in parent directories, so that + files in the deepest subdirectory are loaded first, and files in the root + directory are loaded last. * Within a directory, files are loaded in alphabetical order by filename. -These rules stack, so that within `lib`, for example, files are still -loaded in alphabetical order; and if there are multiple files named -`main.js`, the ones in subdirectories are loaded earlier. +* After sorting as described above, all files under directories named `lib` are + moved before everything else (preserving their order). + +* Finally, all files that match `main.*` are moved after everything else + (preserving their order). {{/better_markdown}} diff --git a/docs/client/docs.js b/docs/client/docs.js index e29ca72685..f5b45aa215 100644 --- a/docs/client/docs.js +++ b/docs/client/docs.js @@ -201,13 +201,7 @@ var toc = [ "Meteor.logout", "Meteor.logoutOtherClients", "Meteor.loginWithPassword", - {name: "Meteor.loginWithMeteorDeveloperAccount", id: "meteor_loginwithexternalservice"}, - {name: "Meteor.loginWithFacebook", id: "meteor_loginwithexternalservice"}, - {name: "Meteor.loginWithGithub", id: "meteor_loginwithexternalservice"}, - {name: "Meteor.loginWithGoogle", id: "meteor_loginwithexternalservice"}, - {name: "Meteor.loginWithMeetup", id: "meteor_loginwithexternalservice"}, - {name: "Meteor.loginWithTwitter", id: "meteor_loginwithexternalservice"}, - {name: "Meteor.loginWithWeibo", id: "meteor_loginwithexternalservice"}, + {name: "Meteor.loginWith", id: "meteor_loginwithexternalservice"}, {type: "spacer"}, {name: "{{currentUser}}", id: "template_currentuser"}, diff --git a/docs/lib/release-override.js b/docs/lib/release-override.js index 60276835d0..646ed35154 100644 --- a/docs/lib/release-override.js +++ b/docs/lib/release-override.js @@ -1,5 +1,5 @@ // While galaxy apps are on their own special meteor releases, override // Meteor.release here. if (Meteor.isClient) { - Meteor.release = Meteor.release ? "0.7.0.1" : undefined; + Meteor.release = Meteor.release ? "0.7.1.1" : undefined; } diff --git a/examples/leaderboard/.meteor/release b/examples/leaderboard/.meteor/release index b6e63167d2..7fce57eeba 100644 --- a/examples/leaderboard/.meteor/release +++ b/examples/leaderboard/.meteor/release @@ -1 +1 @@ -0.7.0.1 +0.7.1.1 diff --git a/examples/parties/.meteor/release b/examples/parties/.meteor/release index b6e63167d2..7fce57eeba 100644 --- a/examples/parties/.meteor/release +++ b/examples/parties/.meteor/release @@ -1 +1 @@ -0.7.0.1 +0.7.1.1 diff --git a/examples/todos/.meteor/release b/examples/todos/.meteor/release index b6e63167d2..7fce57eeba 100644 --- a/examples/todos/.meteor/release +++ b/examples/todos/.meteor/release @@ -1 +1 @@ -0.7.0.1 +0.7.1.1 diff --git a/examples/wordplay/.meteor/release b/examples/wordplay/.meteor/release index b6e63167d2..7fce57eeba 100644 --- a/examples/wordplay/.meteor/release +++ b/examples/wordplay/.meteor/release @@ -1 +1 @@ -0.7.0.1 +0.7.1.1 diff --git a/packages/accounts-meteor-developer/package.js b/packages/accounts-meteor-developer/package.js index 10b44302b2..682c11e058 100644 --- a/packages/accounts-meteor-developer/package.js +++ b/packages/accounts-meteor-developer/package.js @@ -1,6 +1,5 @@ Package.describe({ - summary: "Login service for Meteor developer accounts", - internal: true // XXX for now + summary: "Login service for Meteor developer accounts" }); Package.on_use(function (api) { diff --git a/packages/accounts-ui-unstyled/login_buttons_single.js b/packages/accounts-ui-unstyled/login_buttons_single.js index 13946bef02..79d35a4190 100644 --- a/packages/accounts-ui-unstyled/login_buttons_single.js +++ b/packages/accounts-ui-unstyled/login_buttons_single.js @@ -43,7 +43,7 @@ Template._loginButtonsLoggedOutSingleLoginButton.capitalizedName = function () { // XXX we should allow service packages to set their capitalized name return 'GitHub'; else if (this.name === 'meteor-developer') - return 'a Meteor developer account'; + return 'Meteor'; else return capitalize(this.name); }; diff --git a/packages/appcache/appcache-server.js b/packages/appcache/appcache-server.js index b389b1e650..ce579583d2 100644 --- a/packages/appcache/appcache-server.js +++ b/packages/appcache/appcache-server.js @@ -177,7 +177,8 @@ WebApp.connectHandlers.use(function(req, res, next) { var sizeCheck = function() { var totalSize = 0; _.each(WebApp.clientProgram.manifest, function (resource) { - if (resource.cacheable && resource.where === 'client') { + if (resource.where === 'client' && + ! RoutePolicy.classify(resource.url)) { totalSize += resource.size; } }); diff --git a/packages/autopublish/package.js b/packages/autopublish/package.js index 960a18afd8..f7c106482e 100644 --- a/packages/autopublish/package.js +++ b/packages/autopublish/package.js @@ -1,5 +1,5 @@ Package.describe({ - summary: "Automatically publish the entire database to all clients" + summary: "Publish the entire database to all clients" }); // This package is empty; its presence is detected by livedata and diff --git a/packages/cookies/.gitignore b/packages/cookies/.gitignore deleted file mode 100644 index 677a6fc263..0000000000 --- a/packages/cookies/.gitignore +++ /dev/null @@ -1 +0,0 @@ -.build* diff --git a/packages/cookies/cookies.js b/packages/cookies/cookies.js deleted file mode 100644 index a20443d929..0000000000 --- a/packages/cookies/cookies.js +++ /dev/null @@ -1,59 +0,0 @@ -Cookies = {}; - -// Given the value of a Cookie header, returns a dictionary of cookie -// keys => values. If passed the empty string (or a string that is all -// whitespace), returns {} -// -// cookieString is the value of document.cookies or a Cookie header, -// for example "a=b; c=d". -Cookies.parse = function (cookieString) { - var cookies = {}; - var cookieParts = cookieString.split(/\s*;\s*/); - _.each(cookieParts, function (part) { - var match = part.match(/^([^=]+)=(.*)/); - if (match) - // Browsers are not supposed to send multiple values for the - // same cookie, but if they do, do the easy thing, which is to - // take the last value seen. - cookies[match[1]] = match[2]; - }); - - return cookies; -}; - - -// Given a dictionary of cookie names and values, return a Cookie -// header (as parsed by Cookies.parse). -// -// No attempt is made to sanitize or quote characters in the cookie -// name or value. Behavior varies between browsers, between RFCs, and -// between browsers and RFCs. If you want to play it safe, good advice -// would be to limit cookie names to alphanumerics, dashes, and -// underscores, and limit cookie values to printable ASCII characters -// excluding quote, comma, semicolon, backspace, and whitespace. -Cookies.stringify = function (cookies) { - // RFC6265 says that valid characters in a cookie name are: - // token = - // RFC2616 is HTTP 1.1 and defines 'token' as: - // token = 1* - // separators = "(" | ")" | "<" | ">" | "@" - // | "," | ";" | ":" | "\" | <"> - // | "/" | "[" | "]" | "?" | "=" - // | "{" | "}" | SP | HT - // - // RFC6265 says that valid characters in a cookie value are: - // cookie-value = *cookie-octet / ( DQUOTE *cookie-octet DQUOTE ) - // cookie-octet = %x21 / %x23-2B / %x2D-3A / %x3C-5B / %x5D-7E - // ; US-ASCII characters excluding CTLs, - // ; whitespace DQUOTE, comma, semicolon, - // ; and backslash - // - // In practice, browsers (at least Chrome) permit a wider range of - // characters in cookie values (such as, in Chome, at least comma - // and double quote). So for now we're going to not worry about this - // and trust the user to know what characters their targeted - // browsers tolerate. - return _.map(cookies, function (value, key) { - return key + "=" + value; - }).join(";"); -}; diff --git a/packages/cookies/cookies_client.js b/packages/cookies/cookies_client.js deleted file mode 100644 index 595ff11be5..0000000000 --- a/packages/cookies/cookies_client.js +++ /dev/null @@ -1,55 +0,0 @@ -// If the current origin (and path) has a (non-HttpOnly) cookie for -// 'name', return it. Otherwise return null. -Cookies.get = function (name) { - var cookies = Cookies.parse(document.cookie || ''); - return _.has(cookies, name) ? cookies[name] : null; -}; - -// Set a cookie 'name'='value on the current origin. It is the -// caller's responsibility to ensure that 'name' and 'value' contain -// only characters that are legal in cookie names and values. -// -// Options may include: -// -// - path: Path prefix for which the cookie should be sent. If not -// specified, defaults to the current path of document.location. -// -// - domain: Domain for which the cookie should be sent. Default to -// the current domain (more precisely, the host part of the current -// document.location). Use ".mysite.com" to send to mysite.com and -// all of mysite's subdomains. -// -// - maxAge: How long the cookie should live (in seconds). If not -// provided, the cookie will expire at the end of the browser -// session. -// -// - secure: If true, provide this cookie only for secure (https) -// connections. If you call this from a page that was loaded over -// http, the cookie will be set but you won't be able to read it -// back unless the user reloads the page over https. -// -// To delete a cookie, set maxAge to zero, passing the same name, -// domain, and path. -Cookies.set = function (name, value, options) { - options = options || {}; - - var cmd = name + '=' + value; - if (_.has(options, 'path')) - cmd += ";path=" + options.path; - if (_.has(options, 'domain')) - cmd += ";domain=" + options.domain; - if (_.has(options, "maxAge")) { - // Not all browsers support 'max-age', but all support 'expires'. - var when = new Date((new Date).getTime() + options.maxAge * 1000); - cmd += ";expires=" + when.toUTCString(); - } - if (_.has(options, "secure")) - cmd += ";secure"; - - // This does not set document.cookie. It causes the browser to - // behave as if it had received a Set-Cookie header with the value - // 'cmd'. - // - // "This is the worst interface I have ever seen in my life." -- Emily - document.cookie = cmd; -}; diff --git a/packages/cookies/cookies_client_test.js b/packages/cookies/cookies_client_test.js deleted file mode 100644 index fd2f31a51e..0000000000 --- a/packages/cookies/cookies_client_test.js +++ /dev/null @@ -1,14 +0,0 @@ -Tinytest.add("cookies - browser set/get", function (test) { - var name = Random.id(); - - test.equal(Cookies.get(name), null); - Cookies.set(name, "hello"); - test.equal(Cookies.get(name), "hello"); - Cookies.set(name, "hello again"); - test.equal(Cookies.get(name), "hello again"); - Cookies.set(name, "stuff", { maxAge: 0 }); - test.equal(Cookies.get(name), null); - Cookies.set(name, "kitten", { path: "/somewhere-else" }); - test.equal(Cookies.get(name), null); - Cookies.set(name, "kitten", { path: "/somewhere-else", maxAge: 0 }); -}); diff --git a/packages/cookies/cookies_test.js b/packages/cookies/cookies_test.js deleted file mode 100644 index 21a94f66ff..0000000000 --- a/packages/cookies/cookies_test.js +++ /dev/null @@ -1,12 +0,0 @@ -Tinytest.add("cookies - parse and stringify", function (test) { - test.equal(Cookies.parse("a=b; c=d"), {a: "b", c: "d"}); - test.equal(Cookies.parse("a=b;c=d"), {a: "b", c: "d"}); - test.equal(Cookies.parse("a=b;c=d;e=12"), {a: "b", c: "d", e: "12"}); - test.equal(Cookies.parse("a=b=c;d=e=f"), {a: "b=c", d: "e=f"}); - - // results depends on object key order being preserved, but it will - // probably work in all of our test hosts - test.equal(Cookies.stringify({a: "1"}), "a=1"); - test.equal(Cookies.stringify({a: "1", b: "2"}), "a=1;b=2"); - test.equal(Cookies.stringify({a: "a=1", b: "b=2"}), "a=a=1;b=b=2"); -}); diff --git a/packages/cookies/package.js b/packages/cookies/package.js deleted file mode 100644 index fc17b0677c..0000000000 --- a/packages/cookies/package.js +++ /dev/null @@ -1,20 +0,0 @@ -Package.describe({ - summary: "Parsing cookies", - internal: true -}); - -Package.on_use(function (api) { - api.use('underscore', ['client', 'server']); - api.export('Cookies', ['client', 'server']); - api.add_files('cookies.js', ['client', 'server']); - api.add_files('cookies_client.js', ['client']); -}); - -Package.on_test(function (api) { - api.use('cookies', ['client', 'server']); - api.use('tinytest', ['client', 'server']); - api.use('random', ['client']); - - api.add_files('cookies_test.js', ['client', 'server']); - api.add_files('cookies_client_test.js', ['client']); -}); diff --git a/packages/deps/deps.js b/packages/deps/deps.js index ef9629cbad..a1e101f416 100644 --- a/packages/deps/deps.js +++ b/packages/deps/deps.js @@ -22,6 +22,15 @@ var _debugFunc = function () { function () {})); }; +var _throwOrLog = function (from, e) { + if (throwFirstError) { + throw e; + } else { + _debugFunc()("Exception from Deps " + from + " function:", + e.stack || e.message); + } +}; + var nextId = 1; // computations whose callbacks we should call at flush time var pendingComputations = []; @@ -34,6 +43,12 @@ var inFlush = false; // Deps.nonreactive, which nullfies currentComputation even though // an enclosing computation may still be running. var inCompute = false; +// `true` if the `_throwFirstError` option was passed in to the call +// to Deps.flush that we are in. When set, throw rather than log the +// first error encountered while flushing. Before throwing the error, +// finish flushing (from a catch block), logging any subsequent +// errors. +var throwFirstError = false; var afterFlushCallbacks = []; @@ -159,20 +174,23 @@ _.extend(Deps.Computation.prototype, { var self = this; self._recomputing = true; - while (self.invalidated && ! self.stopped) { - try { - self._compute(); - } catch (e) { - _debugFunc()("Exception from Deps recompute:", e.stack || e.message); + try { + while (self.invalidated && ! self.stopped) { + try { + self._compute(); + } catch (e) { + _throwOrLog("recompute", e); + } + // If _compute() invalidated us, we run again immediately. + // A computation that invalidates itself indefinitely is an + // infinite loop, of course. + // + // We could put an iteration counter here and catch run-away + // loops. } - // If _compute() invalidated us, we run again immediately. - // A computation that invalidates itself indefinitely is an - // infinite loop, of course. - // - // We could put an iteration counter here and catch run-away - // loops. + } finally { + self._recomputing = false; } - self._recomputing = false; } }); @@ -227,7 +245,7 @@ _.extend(Deps.Dependency.prototype, { _.extend(Deps, { // http://docs.meteor.com/#deps_flush - flush: function () { + flush: function (_opts) { // Nested flush could plausibly happen if, say, a flush causes // DOM mutation, which causes a "blur" event, which runs an // app event handler that calls Deps.flush. At the moment @@ -244,32 +262,37 @@ _.extend(Deps, { inFlush = true; willFlush = true; + throwFirstError = !! (_opts && _opts._throwFirstError); - while (pendingComputations.length || - afterFlushCallbacks.length) { + try { + while (pendingComputations.length || + afterFlushCallbacks.length) { - // recompute all pending computations - var comps = pendingComputations; - pendingComputations = []; + // recompute all pending computations + while (pendingComputations.length) { + var comp = pendingComputations.shift(); + comp._recompute(); + } - for (var i = 0, comp; comp = comps[i]; i++) - comp._recompute(); - - if (afterFlushCallbacks.length) { - // call one afterFlush callback, which may - // invalidate more computations - var func = afterFlushCallbacks.shift(); - try { - func(); - } catch (e) { - _debugFunc()("Exception from Deps afterFlush function:", - e.stack || e.message); + if (afterFlushCallbacks.length) { + // call one afterFlush callback, which may + // invalidate more computations + var func = afterFlushCallbacks.shift(); + try { + func(); + } catch (e) { + _throwOrLog("afterFlush function", e); + } } } + } catch (e) { + inFlush = false; // needed before calling `Deps.flush()` again + Deps.flush({_throwFirstError: false}); // finish flushing + throw e; + } finally { + willFlush = false; + inFlush = false; } - - inFlush = false; - willFlush = false; }, // http://docs.meteor.com/#deps_autorun diff --git a/packages/deps/deps_tests.js b/packages/deps/deps_tests.js index 320092aaa1..8fde93564d 100644 --- a/packages/deps/deps_tests.js +++ b/packages/deps/deps_tests.js @@ -371,4 +371,60 @@ Tinytest.add("deps - onInvalidate", function (test) { c1.stop(); test.equal(buf, 'm'); Deps.flush(); -}); \ No newline at end of file +}); + +Tinytest.add('deps - invalidate at flush time', function (test) { + // Test this sentence of the docs: Functions are guaranteed to be + // called at a time when there are no invalidated computations that + // need rerunning. + + var buf = []; + + Deps.afterFlush(function () { + buf.push('C'); + }); + + // When c1 is invalidated, it invalidates c2, then stops. + var c1 = Deps.autorun(function (c) { + if (! c.firstRun) { + buf.push('A'); + c2.invalidate(); + c.stop(); + } + }); + + var c2 = Deps.autorun(function (c) { + if (! c.firstRun) { + buf.push('B'); + c.stop(); + } + }); + + // Invalidate c1. If all goes well, the re-running of + // c2 should happen before the afterFlush. + c1.invalidate(); + Deps.flush(); + + test.equal(buf.join(''), 'ABC'); + +}); + +Tinytest.add('deps - throwFirstError', function (test) { + var d = new Deps.Dependency; + Deps.autorun(function (c) { + d.depend(); + + if (!c.firstRun) + throw new Error("foo"); + }); + + d.changed(); + // doesn't throw; logs instead. + Meteor._suppress_log(1); + Deps.flush(); + + d.changed(); + test.throws(function () { + Deps.flush({_throwFirstError: true}); + }, /foo/); +}); diff --git a/packages/force-ssl/package.js b/packages/force-ssl/package.js index 11eddfc516..ee7780482f 100644 --- a/packages/force-ssl/package.js +++ b/packages/force-ssl/package.js @@ -1,5 +1,5 @@ Package.describe({ - summary: "Require this application to use secure transport (HTTPS)" + summary: "Require this application to use HTTPS" }); Package.on_use(function (api) { diff --git a/packages/jquery-waypoints/package.js b/packages/jquery-waypoints/package.js index 598df4893f..80c25aa893 100644 --- a/packages/jquery-waypoints/package.js +++ b/packages/jquery-waypoints/package.js @@ -1,8 +1,9 @@ Package.describe({ - summary: "Execute a function when the user scrolls past an element" + summary: "Run a function when the user scrolls past an element" }); Package.on_use(function (api) { api.use('jquery'); - api.add_files('waypoints.js', 'client'); + api.use('coffeescript'); + api.add_files('waypoints.coffee', 'client'); }); diff --git a/packages/jquery-waypoints/waypoints.coffee b/packages/jquery-waypoints/waypoints.coffee new file mode 100644 index 0000000000..5e89aff0fe --- /dev/null +++ b/packages/jquery-waypoints/waypoints.coffee @@ -0,0 +1,692 @@ +### +jQuery Waypoints - v2.0.4 +Copyright (c) 2011-2014 Caleb Troughton +Dual licensed under the MIT license and GPL license. +https://github.com/imakewebthings/jquery-waypoints/blob/master/licenses.txt +### +((root, factory) -> + if typeof define is 'function' and define.amd + define 'waypoints', ['jquery'], ($) -> + factory $, root + else + factory root.jQuery, root +) this, ($, window) -> + $w = $ window + + # Touch support feature test + isTouch = 'ontouchstart' in window + + # Internal plugin-wide variables: + + # - allWaypoints: A hash containing two hashes, one for vertical waypoints + # and one for horizontal waypoints. In each hash they value is a Waypoint + # instance and the key is that waypoint's unique ID. + + # - contextCounter: A counter that is incremented with each instantiation + # of the Context class, used in its unique ID. + + # - contexts: A hash of all contexts. The value of each entry is a Context + # instance and the key is that context's unique ID. + + # - contextKey: The DOM element for each context keeps a reference to the + # context's unique ID in the jQuery .data() object. This is the key for + # that data entry. + + # - resizeEvent: The namespaced resize event used by contexts. + + # - scrollEvent: The namespaced scroll event used by contexts. + + # - waypointCounter: A counter that is incremented with each instantiation + # of the Waypoint class, used in its unique ID. + + # - waypointKey: The DOM element for each waypoint keeps a reference to an + # array of the unique IDs of all waypoints attached to that element. This + # array is kept in the jQuery .data() object, and this is the key for + # that entry. + + # - wp: A variable shortcut for the waypoint method name on the $.fn object. + # Using this variable just helps with minification. + + # - wps: A variable shortcut for the waypoints method name on the $ object. + # Using this variable just helps with minification. + + allWaypoints = + horizontal: {} + vertical: {} + contextCounter = 1 + contexts = {} + contextKey = 'waypoints-context-id' + resizeEvent = 'resize.waypoints' + scrollEvent = 'scroll.waypoints' + waypointCounter = 1 + waypointKey = 'waypoints-waypoint-ids' + wp = 'waypoint' + wps = 'waypoints' + + # Context: Represents a single scrolling element in which waypoints live. + # For most users there will only be one Context, the window, but users can + # use other scrollable elements as a context using the "context" option + # when creating waypoints. + + # Properties: + + # - $element: jQuery object containing the context element. + + # - element: The raw HTMLNode of the context element. + + # - didResize: A flag used in throttling the resize event. + + # - didScroll: A flag used in throttling the scroll event. + + # - id: A unique identifier for the context. + + # - oldScroll: A hash containing... + # - x: The context's last known horizontal scroll value. + # - y: The context's last known vertical scroll value. + + # - waypoints: A hash containing two hashes with all waypoints in the context. + # Entries are in the same style as the allWaypoints hashes: + # (key = waypoint.id, value = waypoint) + # - horizontal: A hash of all horizontal waypoints. + # - vertical: A hash of all vertical waypoints. + + class Context + constructor: ($element) -> + @$element = $element + @element = $element[0] + @didResize = no + @didScroll = no + @id = 'context' + contextCounter++ + @oldScroll = + x: $element.scrollLeft() + y: $element.scrollTop() + @waypoints = + horizontal: {} + vertical: {} + + # We need to keep a reference to this Context instance on the DOM node + # so we can look it up later based on the node. + @element[contextKey] = @id + + # To do that look up, we need to have this instance in the global hash. + contexts[@id] = this + + # Run scroll checks on scroll, but throttle it for performance reasons. + $element.bind scrollEvent, => + unless @didScroll or isTouch + @didScroll = yes + scrollHandler = => + @doScroll() + @didScroll = no + window.setTimeout scrollHandler, $[wps].settings.scrollThrottle + + # Run a refresh on resize, but throttle it for performance reasons. + $element.bind resizeEvent, => + unless @didResize + @didResize = yes + resizeHandler = => + $[wps] 'refresh' + @didResize = no + window.setTimeout resizeHandler, $[wps].settings.resizeThrottle + + # doScroll() + + # Looks at the new scroll values for the context, compares them to the old + # scroll values, and checks to see if any waypoints should be triggered + # by that change. + doScroll: -> + + # We use some hashes with common values for each axis so that we can + # just iterate over it rather than write the whole thing twice for + # each axis. + axes = + horizontal: + newScroll: @$element.scrollLeft() + oldScroll: @oldScroll.x + forward: 'right' + backward: 'left' + vertical: + newScroll: @$element.scrollTop() + oldScroll: @oldScroll.y + forward: 'down' + backward: 'up' + + # This is a small "hack" for iOS, needed because scrolls in mobile + # Safari that start or end with the URL bar showing will cause window + # height changes without firing a resize event. + if isTouch and (!axes.vertical.oldScroll or !axes.vertical.newScroll) + $[wps] 'refresh' + + # For each axis, check to see if any waypoints have been crossed. + # Also determine the direction it's being crossed and sort/reverse all + # crossed waypoints accordingly. And, of course, trigger the waypoints. + $.each axes, (aKey, axis) => + triggered = [] + isForward = axis.newScroll > axis.oldScroll + direction = if isForward then axis.forward else axis.backward + $.each @waypoints[aKey], (wKey, waypoint) -> + if axis.oldScroll < waypoint.offset <= axis.newScroll + triggered.push waypoint + else if axis.newScroll < waypoint.offset <= axis.oldScroll + triggered.push waypoint + triggered.sort (a, b) -> a.offset - b.offset + triggered.reverse() unless isForward + $.each triggered, (i, waypoint) -> + if waypoint.options.continuous or i is triggered.length - 1 + waypoint.trigger [direction] + + # Now that we're done with the check, the new scroll values become + # the old scroll values for the next check. + @oldScroll = + x: axes.horizontal.newScroll + y: axes.vertical.newScroll + + # refresh() + # Runs through all of the waypoints in the context and recalculates + # their offsets (the scroll value at which the waypoint is triggered.) + # If a change in offset also happens to cross the context's current + # scroll value, the waypoint will be triggered in the appropriate direction + # unless prevented by the "onlyOnScroll" waypoint option. + refresh: () -> + isWin = $.isWindow @element + cOffset = @$element.offset() + + # Make sure we have the most up-to-date scroll values for our context. + @doScroll() + + # Each axis recalculation needs to know some things: + + # - contextOffset: The distance between the edge of the document and + # the context element. + + # - contextScroll: The scroll value of the context. However, if the + # context is the window this needs to be 0 because this value only + # comes into play when used in adjustment calculations for non-window + # context waypoints. + + # - contextDimension: Width or height of the context. + + # - oldScroll: The scroll value of the context. Unlike "contextScroll", + # this is the same no matter the type of context, and is used when + # determining whether a newly added waypoint should immediately fire + # on its first offset calculation. + + # - forward: Direction string passed to forward waypoint triggers. + + # - backward: Direction string passed to backward waypoint triggers. + + # - offsetProp: Key of the .offset() object for this axis. + axes = + horizontal: + contextOffset: if isWin then 0 else cOffset.left + contextScroll: if isWin then 0 else @oldScroll.x + contextDimension: @$element.width() + oldScroll: @oldScroll.x + forward: 'right' + backward: 'left' + offsetProp: 'left' + vertical: + contextOffset: if isWin then 0 else cOffset.top + contextScroll: if isWin then 0 else @oldScroll.y + contextDimension: if isWin then $[wps]('viewportHeight') else \ + @$element.height() + oldScroll: @oldScroll.y + forward: 'down' + backward: 'up' + offsetProp: 'top' + + # For each axis, run through the waypoints. Store the old offset. + # Recalculate the new offset. Check the difference against the context's + # current scroll value and trigger any crossed waypoints accordingly. + $.each axes, (aKey, axis) => + $.each @waypoints[aKey], (i, waypoint) -> + adjustment = waypoint.options.offset + oldOffset = waypoint.offset + elementOffset = if $.isWindow waypoint.element then 0 else \ + waypoint.$element.offset()[axis.offsetProp] + + # The "offset" waypoint option (which we call "adjustment" here) can + # be a number, percentage string, keyword string (bottom-in-view), + # or a function. So we deal with all of these types here. + if $.isFunction adjustment + adjustment = adjustment.apply waypoint.element + else if typeof adjustment is 'string' + adjustment = parseFloat adjustment + if waypoint.options.offset.indexOf('%') > -1 + adjustment = Math.ceil(axis.contextDimension * adjustment / 100) + + # We've finally calculated all the crazy little adjustments that + # can come from using non-window contexts and the "offset" option. + # Store the damn thing. + waypoint.offset = elementOffset \ + - axis.contextOffset \ + + axis.contextScroll \ + - adjustment + + # "onlyOnScroll" tells us to not even consider triggering waypoints + # during refresh, so we can eject early. + return if (waypoint.options.onlyOnScroll and oldOffset?) or \ + !waypoint.enabled + + # Case where the refresh causes a backward trigger. + if oldOffset isnt null and \ + oldOffset < axis.oldScroll <= waypoint.offset + waypoint.trigger [axis.backward] + + # Now the forward case. + else if oldOffset isnt null and \ + oldOffset > axis.oldScroll >= waypoint.offset + waypoint.trigger [axis.forward] + + # "oldOffset" values of null mean this is the first calculation of + # the waypoint's offset. It's a special time in a waypoint's life. + else if oldOffset is null and axis.oldScroll >= waypoint.offset + waypoint.trigger [axis.forward] + + # checkEmpty() + + # Looks at the waypoints hashes. If they are empty, the context removes + # itself from the global contexts hash. + checkEmpty: -> + if $.isEmptyObject(@waypoints.horizontal) and \ + $.isEmptyObject(@waypoints.vertical) + @$element.unbind [resizeEvent, scrollEvent].join(' ') + delete contexts[@id] + + # Waypoint: Represents a single callback function tied to an element. An + # element can have multiple waypoints with multiple offsets. + + # Properties: + + # - $element: jQuery object containing the waypoint element. + + # - element: The raw HTMLNode of the waypoint element. + + # - axis: 'horizontal' || 'vertical' - The axis on which this waypoint lives. + + # - callback: The function that is fired when the waypoint is triggered. + + # - context: A reference to the context this waypoint belongs to. + + # - enabled: Boolean indicating whether this waypoint is enabled or not. + # Disabled waypoints are still returned in functions that aggregate + # waypoints, but do not fire their callbacks. + + # - id: A unique identifier for the waypoint. + + # - offset: The scroll offset at which the waypoint should trigger. + + # - options: A hash containing the various waypoint options. + # See $.fn.waypoint.defaults for more information on those options. + class Waypoint + constructor: ($element, context, options) -> + options = $.extend {}, $.fn[wp].defaults, options + if options.offset is 'bottom-in-view' + options.offset = -> + contextHeight = $[wps] 'viewportHeight' + unless $.isWindow context.element + contextHeight = context.$element.height() + contextHeight - $(this).outerHeight() + + @$element = $element + @element = $element[0] + @axis = if options.horizontal then 'horizontal' else 'vertical' + @callback = options.handler + @context = context + @enabled = options.enabled + @id = 'waypoints' + waypointCounter++ + @offset = null + @options = options + + # Add our new waypoint to its context. + context.waypoints[@axis][@id] = this + + # Add it to the global hash. + allWaypoints[@axis][@id] = this + + # Add the waypoint's id to the element's waypoint id list. + idList = @element[waypointKey] ? [] + idList.push @id + @element[waypointKey] = idList + + # trigger(array) + + # Calls the waypoint's callback function, passing to it the arguments + # supplied in the "args" array. + trigger: (args) -> + return unless @enabled + if @callback? + @callback.apply @element, args + if @options.triggerOnce + @destroy() + + # disable() + + # Temporarily disables a waypoint from firing its callback. + disable: -> + @enabled = false + + # enable() + + # Breathe life back into the waypoint. + enable: -> + @context.refresh() + @enabled = true + + # destroy() + + # Kills the waypoint for good. + destroy: -> + delete allWaypoints[@axis][@id] + delete @context.waypoints[@axis][@id] + @context.checkEmpty() + + # Waypoint.getWaypointsByElement(HTMLNode) + + # Returns an array of all Waypoint instances attached to the "element" + # HTMLNode. Returns an empty array if there are no attached waypoints. + @getWaypointsByElement: (element) -> + ids = element[waypointKey] + return [] unless ids + all = $.extend {}, allWaypoints.horizontal, allWaypoints.vertical + $.map ids, (id) -> + all[id] + + # These methods are available on the $.fn object by using the method + # name as the first argument to .waypoint. Ex: $('div').waypoint('destroy') + methods = + + # init(function, object) + + # Creates a new waypoint (and if needed, a new context) using the supplied + # callback function and options. + + # The "f" function and the "options" object are both optional, but at least + # one must be supplied. So acceptable signatures are: + + # - .waypoint(f) + # - .waypoint(options) + # - .waypoint(f, options) + + # This "init" method should never need to be called explicity by the user. + # It is the default method that is delegated to when .waypoint is called + # with one of the above signatures. + + # Ex: $('div').waypoint(function(direction) { + # // Do things + # }, { offset: '100%' }); + init: (f, options) -> + options ?= {} + options.handler ?= f + + @each -> + $this = $ this + contextElement = options.context ? $.fn[wp].defaults.context + unless $.isWindow contextElement + contextElement = $this.closest contextElement + contextElement = $ contextElement + context = contexts[contextElement[0][contextKey]] + context = new Context contextElement unless context + new Waypoint $this, context, options + $[wps] 'refresh' + this + + # Disable, enable, and destroy all just delegate to the instance methods + # of the waypoints attached to the subject elements. + disable: -> methods._invoke.call this, 'disable' + enable: -> methods._invoke.call this, 'enable' + destroy: -> methods._invoke.call this, 'destroy' + + # .waypoint('prev', string, string|HTMLNode|jQuery) + + # Returns a jQuery object containing previous waypoint elements. This + # creates a new entry in the jQuery object stack just like jQuery's prev + # function. "axis" indicates the axis on which to traverse + # ('horizontal' | 'vertical') and "selector" indicates which context + # element to use. The defaults are 'vertical' and window respectively. + prev: (axis, selector) -> + methods._traverse.call this, axis, selector, (stack, index, waypoints) -> + stack.push waypoints[index-1] if index > 0 + + # .waypoint('next', string, string|HTMLNode|jQuery) + + # Returns a jQuery object containing next waypoint elements. This + # creates a new entry in the jQuery object stack just like jQuery's next + # function. "axis" indicates the axis on which to traverse + # ('horizontal' | 'vertical') and "selector" indicates which context + # element to use. The defaults are 'vertical' and window respectively. + next: (axis, selector) -> + methods._traverse.call this, axis, selector, (stack, index, waypoints) -> + stack.push waypoints[index+1] if index < waypoints.length-1 + + # Internal: Aggregates waypoints on a given axis of a context, and applies + # a "push" callback for each element in the subject jQuery object. This + # callback builds the element array to push to the jQuery stack. + _traverse: (axis = 'vertical', selector = window, push) -> + waypoints = jQMethods.aggregate selector + stack = [] + @each -> + index = $.inArray this, waypoints[axis] + push stack, index, waypoints[axis] + @pushStack stack + + # Internal: Finds all waypoints on a given set of "$elements" and invokes + # "method" on each instance. + _invoke: (method) -> + this.each -> + waypoints = Waypoint.getWaypointsByElement this + $.each waypoints, (i, waypoint) -> + waypoint[method]() + true + this + + # $.fn.waypoint. Let's just hook this guy up to our methods hash and + # add some trivial error reporting for bogus calls. + $.fn[wp] = (method, args...) -> + if methods[method] + methods[method].apply this, args + else if $.isFunction(method) + methods.init.apply this, arguments + else if $.isPlainObject(method) + methods.init.apply this, [null, method] + else if !method + $.error "jQuery Waypoints needs a callback function or handler option." + else + $.error "The #{method} method does not exist in jQuery Waypoints." + + # The default options object for a waypoint. + + # - context: string|HTMLNode|jQuery - The scrollable element that the + # waypoint acts within. The waypoint will look for the closest ancestor + # element that matches this selector or node. + + # - continuous: Multiple waypoints may be triggered by a single scroll check. + # If you would like a waypoint to only trigger if it is the last waypoint + # in a scroll check, set this to false. + + # - enabled: Should this waypoint start enabled (true) or disabled (false)? + + # - handler: This option is not defined by default, but can be used as an + # alternate way to pass the waypoint callback function, rather than as + # the first argument to .waypoint. + + # Ex: $('div').waypoint({ + # handler: function(direction) { ... } + # }); + + # - horizontal: Set this to true if the waypoint is, well, horizontal. + + # - offset: number|string|function - Determines how far from the top (or left + # if the waypoint is horizontal) of the context's viewport to trigger the + # waypoint. The default of 0 means that the waypoint is triggered when the + # top of the waypoint element hits the top of the window/context-element. + # An offset of 50 would mean the waypoint triggers when the top of the + # element is 50 pixels from the top of the window. + + # A % string is translated into a percentage of the width/height of + # the context. + + # If a function is passed, that function should return a number. The "this" + # keyword within this function will be set to the raw HTMLNode of the + # waypoint element. + + # - triggerOnce: If true, the waypoint will destroy itself after + # first trigger. + $.fn[wp].defaults = + context: window + continuous: true + enabled: true + horizontal: false + offset: 0 + triggerOnce: false + + # These methods are available on the $ object by using the method name as + # the first argument to .waypoint. Ex: $.waypoints('refresh') + jQMethods = + + # $.waypoints('refresh') + + # Forces a refresh on all contexts, recalculating all waypoint offsets. + # This is done automatically on waypoint addition and during resize events, + # but if a user does something to change the DOM, CSS, or in some way + # change the layout of a page and its elements, they might need to call + # this method manually. + refresh: -> + $.each contexts, (i, context) -> context.refresh() + + # $.waypoints('viewportHeight') + + # A utility method that returns the window height, but takes into account + # inconsistencies that come with just using jQuery's .height() on iOS. + viewportHeight: -> + window.innerHeight ? $w.height() + + # $.waypoints(['aggregate'], [contextSelector]) + + # Returns an object containing two HTMLNode arrays, one for each axis: + + # { + # horizontal: [ HTMLNode... ] + # vertical: [ HTMLNode... ] + # } + + # This is the default method used when calling $.waypoints(). If + # "contextSelector" is not supplied, it returns all waypoints. If + # "contextSelector" is supplied it only returns waypoints for that context. + + # The array of waypoint elements is returned sorted by calculated offset, + # the order in which they would be triggered on the page. + aggregate: (contextSelector) -> + collection = allWaypoints + if contextSelector + collection = contexts[$(contextSelector)[0][contextKey]]?.waypoints + return [] unless collection + waypoints = + horizontal: [] + vertical: [] + $.each waypoints, (axis, arr) -> + $.each collection[axis], (key, waypoint) -> + arr.push waypoint + arr.sort (a, b) -> a.offset - b.offset + waypoints[axis] = $.map arr, (waypoint) -> waypoint.element + waypoints[axis] = $.unique waypoints[axis] + waypoints + + # $.waypoints('above', [string|HTMLNode|jQuery]) + + # Returns all vertical waypoints that lie above the current scroll position + # of the context specified by "contextSelector". If no "contextSelector" + # is supplied, it defaults to the window. + above: (contextSelector = window) -> + jQMethods._filter contextSelector, 'vertical', (context, waypoint) -> + waypoint.offset <= context.oldScroll.y + + # $.waypoints('below', [string|HTMLNode|jQuery]) + + # Returns all vertical waypoints that lie below the current scroll position + # of the context specified by "contextSelector". If no "contextSelector" + # is supplied, it defaults to the window. + below: (contextSelector = window) -> + jQMethods._filter contextSelector, 'vertical', (context, waypoint) -> + waypoint.offset > context.oldScroll.y + + # $.waypoints('left', [string|HTMLNode|jQuery]) + + # Returns all horizontal waypoints left of the current scroll position + # of the context specified by "contextSelector". If no "contextSelector" + # is supplied, it defaults to the window. + left: (contextSelector = window) -> + jQMethods._filter contextSelector, 'horizontal', (context, waypoint) -> + waypoint.offset <= context.oldScroll.x + + # $.waypoints('right', [string|HTMLNode|jQuery]) + + # Returns all horizontal waypoints right of the current scroll position + # of the context specified by "contextSelector". If no "contextSelector" + # is supplied, it defaults to the window. + right: (contextSelector = window) -> + jQMethods._filter contextSelector, 'horizontal', (context, waypoint) -> + waypoint.offset > context.oldScroll.x + + # $.waypoints('enable/disable/destroy') + + # These methods delegate to the enable/disable/destroy instance methods + # for all waypoints. + enable: -> jQMethods._invoke 'enable' + disable: -> jQMethods._invoke 'disable' + destroy: -> jQMethods._invoke 'destroy' + + # $.waypoints('extendFn', string, function) + + # Extends the $.fn.waypoint method object with a new method, "f". This + # just lets other modules piggyback on the .waypoint namespace. + extendFn: (methodName, f) -> + methods[methodName] = f + + # Internal: Invokes "method" on all waypoints. + _invoke: (method) -> + waypoints = $.extend {}, allWaypoints.vertical, allWaypoints.horizontal + $.each waypoints, (key, waypoint) -> + waypoint[method]() + true + + # Internal: Returns an array of all HTMLNodes for each waypoint that passes + # the "test" function. Only waypoints within the "selector" context on the + # "axis" axis are tested. As with .aggregate, the array is sorted by + # calculated offset (trigger order). + _filter: (selector, axis, test) -> + context = contexts[$(selector)[0][contextKey]] + return [] unless context + waypoints = [] + $.each context.waypoints[axis], (i, waypoint) -> + waypoints.push waypoint if test context, waypoint + waypoints.sort (a, b) -> a.offset - b.offset + $.map waypoints, (waypoint) -> waypoint.element + + # Hook up jQMethods to the $.waypoints namespace. + $[wps] = (method, args...) -> + if jQMethods[method] + jQMethods[method].apply null, args + else + jQMethods.aggregate.call null, method + + # Plugin-wide settings: + + # - resizeThrottle: For performance reasons, the refresh performed during + # resizes is throttled. This value is the rate-limit in milliseconds + # between resize refreshes. For more information on throttling, check out + # Ben Alman’s throttle / debounce plugin. + # http://benalman.com/projects/jquery-throttle-debounce-plugin/ + + # - scrollThrottle: For performance reasons, checking for any crossed + # waypoints during a scroll event is throttled. This value is the + # rate-limit in milliseconds between scroll checks. For more information + # on throttling, check out Ben Alman’s throttle / debounce plugin. + # http://benalman.com/projects/jquery-throttle-debounce-plugin/ + + $[wps].settings = + resizeThrottle: 100 + scrollThrottle: 30 + + # Ensure a refresh on page load. Newly loaded images often shift layout. + $w.load -> $[wps] 'refresh' diff --git a/packages/jquery-waypoints/waypoints.js b/packages/jquery-waypoints/waypoints.js deleted file mode 100644 index 81da414443..0000000000 --- a/packages/jquery-waypoints/waypoints.js +++ /dev/null @@ -1,520 +0,0 @@ -// Generated by CoffeeScript 1.6.2 -/* -jQuery Waypoints - v2.0.3 -Copyright (c) 2011-2013 Caleb Troughton -Dual licensed under the MIT license and GPL license. -https://github.com/imakewebthings/jquery-waypoints/blob/master/licenses.txt -*/ - - -(function() { - var __indexOf = [].indexOf || function(item) { for (var i = 0, l = this.length; i < l; i++) { if (i in this && this[i] === item) return i; } return -1; }, - __slice = [].slice; - - (function(root, factory) { - if (typeof define === 'function' && define.amd) { - return define('waypoints', ['jquery'], function($) { - return factory($, root); - }); - } else { - return factory(root.jQuery, root); - } - })(this, function($, window) { - var $w, Context, Waypoint, allWaypoints, contextCounter, contextKey, contexts, isTouch, jQMethods, methods, resizeEvent, scrollEvent, waypointCounter, waypointKey, wp, wps; - - $w = $(window); - isTouch = __indexOf.call(window, 'ontouchstart') >= 0; - allWaypoints = { - horizontal: {}, - vertical: {} - }; - contextCounter = 1; - contexts = {}; - contextKey = 'waypoints-context-id'; - resizeEvent = 'resize.waypoints'; - scrollEvent = 'scroll.waypoints'; - waypointCounter = 1; - waypointKey = 'waypoints-waypoint-ids'; - wp = 'waypoint'; - wps = 'waypoints'; - Context = (function() { - function Context($element) { - var _this = this; - - this.$element = $element; - this.element = $element[0]; - this.didResize = false; - this.didScroll = false; - this.id = 'context' + contextCounter++; - this.oldScroll = { - x: $element.scrollLeft(), - y: $element.scrollTop() - }; - this.waypoints = { - horizontal: {}, - vertical: {} - }; - $element.data(contextKey, this.id); - contexts[this.id] = this; - $element.bind(scrollEvent, function() { - var scrollHandler; - - if (!(_this.didScroll || isTouch)) { - _this.didScroll = true; - scrollHandler = function() { - _this.doScroll(); - return _this.didScroll = false; - }; - return window.setTimeout(scrollHandler, $[wps].settings.scrollThrottle); - } - }); - $element.bind(resizeEvent, function() { - var resizeHandler; - - if (!_this.didResize) { - _this.didResize = true; - resizeHandler = function() { - $[wps]('refresh'); - return _this.didResize = false; - }; - return window.setTimeout(resizeHandler, $[wps].settings.resizeThrottle); - } - }); - } - - Context.prototype.doScroll = function() { - var axes, - _this = this; - - axes = { - horizontal: { - newScroll: this.$element.scrollLeft(), - oldScroll: this.oldScroll.x, - forward: 'right', - backward: 'left' - }, - vertical: { - newScroll: this.$element.scrollTop(), - oldScroll: this.oldScroll.y, - forward: 'down', - backward: 'up' - } - }; - if (isTouch && (!axes.vertical.oldScroll || !axes.vertical.newScroll)) { - $[wps]('refresh'); - } - $.each(axes, function(aKey, axis) { - var direction, isForward, triggered; - - triggered = []; - isForward = axis.newScroll > axis.oldScroll; - direction = isForward ? axis.forward : axis.backward; - $.each(_this.waypoints[aKey], function(wKey, waypoint) { - var _ref, _ref1; - - if ((axis.oldScroll < (_ref = waypoint.offset) && _ref <= axis.newScroll)) { - return triggered.push(waypoint); - } else if ((axis.newScroll < (_ref1 = waypoint.offset) && _ref1 <= axis.oldScroll)) { - return triggered.push(waypoint); - } - }); - triggered.sort(function(a, b) { - return a.offset - b.offset; - }); - if (!isForward) { - triggered.reverse(); - } - return $.each(triggered, function(i, waypoint) { - if (waypoint.options.continuous || i === triggered.length - 1) { - return waypoint.trigger([direction]); - } - }); - }); - return this.oldScroll = { - x: axes.horizontal.newScroll, - y: axes.vertical.newScroll - }; - }; - - Context.prototype.refresh = function() { - var axes, cOffset, isWin, - _this = this; - - isWin = $.isWindow(this.element); - cOffset = this.$element.offset(); - this.doScroll(); - axes = { - horizontal: { - contextOffset: isWin ? 0 : cOffset.left, - contextScroll: isWin ? 0 : this.oldScroll.x, - contextDimension: this.$element.width(), - oldScroll: this.oldScroll.x, - forward: 'right', - backward: 'left', - offsetProp: 'left' - }, - vertical: { - contextOffset: isWin ? 0 : cOffset.top, - contextScroll: isWin ? 0 : this.oldScroll.y, - contextDimension: isWin ? $[wps]('viewportHeight') : this.$element.height(), - oldScroll: this.oldScroll.y, - forward: 'down', - backward: 'up', - offsetProp: 'top' - } - }; - return $.each(axes, function(aKey, axis) { - return $.each(_this.waypoints[aKey], function(i, waypoint) { - var adjustment, elementOffset, oldOffset, _ref, _ref1; - - adjustment = waypoint.options.offset; - oldOffset = waypoint.offset; - elementOffset = $.isWindow(waypoint.element) ? 0 : waypoint.$element.offset()[axis.offsetProp]; - if ($.isFunction(adjustment)) { - adjustment = adjustment.apply(waypoint.element); - } else if (typeof adjustment === 'string') { - adjustment = parseFloat(adjustment); - if (waypoint.options.offset.indexOf('%') > -1) { - adjustment = Math.ceil(axis.contextDimension * adjustment / 100); - } - } - waypoint.offset = elementOffset - axis.contextOffset + axis.contextScroll - adjustment; - if ((waypoint.options.onlyOnScroll && (oldOffset != null)) || !waypoint.enabled) { - return; - } - if (oldOffset !== null && (oldOffset < (_ref = axis.oldScroll) && _ref <= waypoint.offset)) { - return waypoint.trigger([axis.backward]); - } else if (oldOffset !== null && (oldOffset > (_ref1 = axis.oldScroll) && _ref1 >= waypoint.offset)) { - return waypoint.trigger([axis.forward]); - } else if (oldOffset === null && axis.oldScroll >= waypoint.offset) { - return waypoint.trigger([axis.forward]); - } - }); - }); - }; - - Context.prototype.checkEmpty = function() { - if ($.isEmptyObject(this.waypoints.horizontal) && $.isEmptyObject(this.waypoints.vertical)) { - this.$element.unbind([resizeEvent, scrollEvent].join(' ')); - return delete contexts[this.id]; - } - }; - - return Context; - - })(); - Waypoint = (function() { - function Waypoint($element, context, options) { - var idList, _ref; - - options = $.extend({}, $.fn[wp].defaults, options); - if (options.offset === 'bottom-in-view') { - options.offset = function() { - var contextHeight; - - contextHeight = $[wps]('viewportHeight'); - if (!$.isWindow(context.element)) { - contextHeight = context.$element.height(); - } - return contextHeight - $(this).outerHeight(); - }; - } - this.$element = $element; - this.element = $element[0]; - this.axis = options.horizontal ? 'horizontal' : 'vertical'; - this.callback = options.handler; - this.context = context; - this.enabled = options.enabled; - this.id = 'waypoints' + waypointCounter++; - this.offset = null; - this.options = options; - context.waypoints[this.axis][this.id] = this; - allWaypoints[this.axis][this.id] = this; - idList = (_ref = $element.data(waypointKey)) != null ? _ref : []; - idList.push(this.id); - $element.data(waypointKey, idList); - } - - Waypoint.prototype.trigger = function(args) { - if (!this.enabled) { - return; - } - if (this.callback != null) { - this.callback.apply(this.element, args); - } - if (this.options.triggerOnce) { - return this.destroy(); - } - }; - - Waypoint.prototype.disable = function() { - return this.enabled = false; - }; - - Waypoint.prototype.enable = function() { - this.context.refresh(); - return this.enabled = true; - }; - - Waypoint.prototype.destroy = function() { - delete allWaypoints[this.axis][this.id]; - delete this.context.waypoints[this.axis][this.id]; - return this.context.checkEmpty(); - }; - - Waypoint.getWaypointsByElement = function(element) { - var all, ids; - - ids = $(element).data(waypointKey); - if (!ids) { - return []; - } - all = $.extend({}, allWaypoints.horizontal, allWaypoints.vertical); - return $.map(ids, function(id) { - return all[id]; - }); - }; - - return Waypoint; - - })(); - methods = { - init: function(f, options) { - var _ref; - - if (options == null) { - options = {}; - } - if ((_ref = options.handler) == null) { - options.handler = f; - } - this.each(function() { - var $this, context, contextElement, _ref1; - - $this = $(this); - contextElement = (_ref1 = options.context) != null ? _ref1 : $.fn[wp].defaults.context; - if (!$.isWindow(contextElement)) { - contextElement = $this.closest(contextElement); - } - contextElement = $(contextElement); - context = contexts[contextElement.data(contextKey)]; - if (!context) { - context = new Context(contextElement); - } - return new Waypoint($this, context, options); - }); - $[wps]('refresh'); - return this; - }, - disable: function() { - return methods._invoke(this, 'disable'); - }, - enable: function() { - return methods._invoke(this, 'enable'); - }, - destroy: function() { - return methods._invoke(this, 'destroy'); - }, - prev: function(axis, selector) { - return methods._traverse.call(this, axis, selector, function(stack, index, waypoints) { - if (index > 0) { - return stack.push(waypoints[index - 1]); - } - }); - }, - next: function(axis, selector) { - return methods._traverse.call(this, axis, selector, function(stack, index, waypoints) { - if (index < waypoints.length - 1) { - return stack.push(waypoints[index + 1]); - } - }); - }, - _traverse: function(axis, selector, push) { - var stack, waypoints; - - if (axis == null) { - axis = 'vertical'; - } - if (selector == null) { - selector = window; - } - waypoints = jQMethods.aggregate(selector); - stack = []; - this.each(function() { - var index; - - index = $.inArray(this, waypoints[axis]); - return push(stack, index, waypoints[axis]); - }); - return this.pushStack(stack); - }, - _invoke: function($elements, method) { - $elements.each(function() { - var waypoints; - - waypoints = Waypoint.getWaypointsByElement(this); - return $.each(waypoints, function(i, waypoint) { - waypoint[method](); - return true; - }); - }); - return this; - } - }; - $.fn[wp] = function() { - var args, method; - - method = arguments[0], args = 2 <= arguments.length ? __slice.call(arguments, 1) : []; - if (methods[method]) { - return methods[method].apply(this, args); - } else if ($.isFunction(method)) { - return methods.init.apply(this, arguments); - } else if ($.isPlainObject(method)) { - return methods.init.apply(this, [null, method]); - } else if (!method) { - return $.error("jQuery Waypoints needs a callback function or handler option."); - } else { - return $.error("The " + method + " method does not exist in jQuery Waypoints."); - } - }; - $.fn[wp].defaults = { - context: window, - continuous: true, - enabled: true, - horizontal: false, - offset: 0, - triggerOnce: false - }; - jQMethods = { - refresh: function() { - return $.each(contexts, function(i, context) { - return context.refresh(); - }); - }, - viewportHeight: function() { - var _ref; - - return (_ref = window.innerHeight) != null ? _ref : $w.height(); - }, - aggregate: function(contextSelector) { - var collection, waypoints, _ref; - - collection = allWaypoints; - if (contextSelector) { - collection = (_ref = contexts[$(contextSelector).data(contextKey)]) != null ? _ref.waypoints : void 0; - } - if (!collection) { - return []; - } - waypoints = { - horizontal: [], - vertical: [] - }; - $.each(waypoints, function(axis, arr) { - $.each(collection[axis], function(key, waypoint) { - return arr.push(waypoint); - }); - arr.sort(function(a, b) { - return a.offset - b.offset; - }); - waypoints[axis] = $.map(arr, function(waypoint) { - return waypoint.element; - }); - return waypoints[axis] = $.unique(waypoints[axis]); - }); - return waypoints; - }, - above: function(contextSelector) { - if (contextSelector == null) { - contextSelector = window; - } - return jQMethods._filter(contextSelector, 'vertical', function(context, waypoint) { - return waypoint.offset <= context.oldScroll.y; - }); - }, - below: function(contextSelector) { - if (contextSelector == null) { - contextSelector = window; - } - return jQMethods._filter(contextSelector, 'vertical', function(context, waypoint) { - return waypoint.offset > context.oldScroll.y; - }); - }, - left: function(contextSelector) { - if (contextSelector == null) { - contextSelector = window; - } - return jQMethods._filter(contextSelector, 'horizontal', function(context, waypoint) { - return waypoint.offset <= context.oldScroll.x; - }); - }, - right: function(contextSelector) { - if (contextSelector == null) { - contextSelector = window; - } - return jQMethods._filter(contextSelector, 'horizontal', function(context, waypoint) { - return waypoint.offset > context.oldScroll.x; - }); - }, - enable: function() { - return jQMethods._invoke('enable'); - }, - disable: function() { - return jQMethods._invoke('disable'); - }, - destroy: function() { - return jQMethods._invoke('destroy'); - }, - extendFn: function(methodName, f) { - return methods[methodName] = f; - }, - _invoke: function(method) { - var waypoints; - - waypoints = $.extend({}, allWaypoints.vertical, allWaypoints.horizontal); - return $.each(waypoints, function(key, waypoint) { - waypoint[method](); - return true; - }); - }, - _filter: function(selector, axis, test) { - var context, waypoints; - - context = contexts[$(selector).data(contextKey)]; - if (!context) { - return []; - } - waypoints = []; - $.each(context.waypoints[axis], function(i, waypoint) { - if (test(context, waypoint)) { - return waypoints.push(waypoint); - } - }); - waypoints.sort(function(a, b) { - return a.offset - b.offset; - }); - return $.map(waypoints, function(waypoint) { - return waypoint.element; - }); - } - }; - $[wps] = function() { - var args, method; - - method = arguments[0], args = 2 <= arguments.length ? __slice.call(arguments, 1) : []; - if (jQMethods[method]) { - return jQMethods[method].apply(null, args); - } else { - return jQMethods.aggregate.call(null, method); - } - }; - $[wps].settings = { - resizeThrottle: 100, - scrollThrottle: 30 - }; - return $w.load(function() { - return $[wps]('refresh'); - }); - }); - -}).call(this); diff --git a/packages/jquery/jquery.js b/packages/jquery/jquery.js index c5c648255c..3c88fa8b7f 100644 --- a/packages/jquery/jquery.js +++ b/packages/jquery/jquery.js @@ -1,91 +1,83 @@ /*! - * jQuery JavaScript Library v1.10.2 + * jQuery JavaScript Library v1.11.0 * http://jquery.com/ * * Includes Sizzle.js * http://sizzlejs.com/ * - * Copyright 2005, 2013 jQuery Foundation, Inc. and other contributors + * Copyright 2005, 2014 jQuery Foundation, Inc. and other contributors * Released under the MIT license * http://jquery.org/license * - * Date: 2013-07-03T13:48Z + * Date: 2014-01-23T21:02Z */ -(function( window, undefined ) { + +(function( global, factory ) { + + if ( typeof module === "object" && typeof module.exports === "object" ) { + // For CommonJS and CommonJS-like environments where a proper window is present, + // execute the factory and get jQuery + // For environments that do not inherently posses a window with a document + // (such as Node.js), expose a jQuery-making factory as module.exports + // This accentuates the need for the creation of a real window + // e.g. var jQuery = require("jquery")(window); + // See ticket #14549 for more info + module.exports = global.document ? + factory( global, true ) : + function( w ) { + if ( !w.document ) { + throw new Error( "jQuery requires a window with a document" ); + } + return factory( w ); + }; + } else { + factory( global ); + } + +// Pass this if window is not defined yet +}(typeof window !== "undefined" ? window : this, function( window, noGlobal ) { // Can't do this because several apps including ASP.NET trace // the stack via arguments.caller.callee and Firefox dies if // you try to trace through "use strict" call chains. (#13335) // Support: Firefox 18+ -//"use strict"; +// + +var deletedIds = []; + +var slice = deletedIds.slice; + +var concat = deletedIds.concat; + +var push = deletedIds.push; + +var indexOf = deletedIds.indexOf; + +var class2type = {}; + +var toString = class2type.toString; + +var hasOwn = class2type.hasOwnProperty; + +var trim = "".trim; + +var support = {}; + + + var - // The deferred used on DOM ready - readyList, - - // A central reference to the root jQuery(document) - rootjQuery, - - // Support: IE<10 - // For `typeof xmlNode.method` instead of `xmlNode.method !== undefined` - core_strundefined = typeof undefined, - - // Use the correct document accordingly with window argument (sandbox) - location = window.location, - document = window.document, - docElem = document.documentElement, - - // Map over jQuery in case of overwrite - _jQuery = window.jQuery, - - // Map over the $ in case of overwrite - _$ = window.$, - - // [[Class]] -> type pairs - class2type = {}, - - // List of deleted data cache ids, so we can reuse them - core_deletedIds = [], - - core_version = "1.10.2", - - // Save a reference to some core methods - core_concat = core_deletedIds.concat, - core_push = core_deletedIds.push, - core_slice = core_deletedIds.slice, - core_indexOf = core_deletedIds.indexOf, - core_toString = class2type.toString, - core_hasOwn = class2type.hasOwnProperty, - core_trim = core_version.trim, + version = "1.11.0", // Define a local copy of jQuery jQuery = function( selector, context ) { // The jQuery object is actually just the init constructor 'enhanced' - return new jQuery.fn.init( selector, context, rootjQuery ); + // Need init if jQuery is called (just allow error to be thrown if not included) + return new jQuery.fn.init( selector, context ); }, - // Used for matching numbers - core_pnum = /[+-]?(?:\d*\.|)\d+(?:[eE][+-]?\d+|)/.source, - - // Used for splitting on whitespace - core_rnotwhite = /\S+/g, - // Make sure we trim BOM and NBSP (here's looking at you, Safari 5.0 and IE) rtrim = /^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g, - // A simple way to check for HTML strings - // Prioritize #id over to avoid XSS via location.hash (#9521) - // Strict HTML recognition (#11290: must start with <) - rquickExpr = /^(?:\s*(<[\w\W]+>)[^>]*|#([\w-]*))$/, - - // Match a standalone tag - rsingleTag = /^<(\w+)\s*\/?>(?:<\/\1>|)$/, - - // JSON RegExp - rvalidchars = /^[\],:{}\s]*$/, - rvalidbraces = /(?:^|:|,)(?:\s*\[)+/g, - rvalidescape = /\\(?:["\\\/bfnrt]|u[\da-fA-F]{4})/g, - rvalidtokens = /"[^"\\\r\n]*"|true|false|null|-?(?:\d+\.|)\d+(?:[eE][+-]?\d+|)/g, - // Matches dashed string for camelizing rmsPrefix = /^-ms-/, rdashAlpha = /-([\da-z])/gi, @@ -93,134 +85,13 @@ var // Used by jQuery.camelCase as callback to replace() fcamelCase = function( all, letter ) { return letter.toUpperCase(); - }, - - // The ready event handler - completed = function( event ) { - - // readyState === "complete" is good enough for us to call the dom ready in oldIE - if ( document.addEventListener || event.type === "load" || document.readyState === "complete" ) { - detach(); - jQuery.ready(); - } - }, - // Clean-up method for dom ready events - detach = function() { - if ( document.addEventListener ) { - document.removeEventListener( "DOMContentLoaded", completed, false ); - window.removeEventListener( "load", completed, false ); - - } else { - document.detachEvent( "onreadystatechange", completed ); - window.detachEvent( "onload", completed ); - } }; jQuery.fn = jQuery.prototype = { // The current version of jQuery being used - jquery: core_version, + jquery: version, constructor: jQuery, - init: function( selector, context, rootjQuery ) { - var match, elem; - - // HANDLE: $(""), $(null), $(undefined), $(false) - if ( !selector ) { - return this; - } - - // Handle HTML strings - if ( typeof selector === "string" ) { - if ( selector.charAt(0) === "<" && selector.charAt( selector.length - 1 ) === ">" && selector.length >= 3 ) { - // Assume that strings that start and end with <> are HTML and skip the regex check - match = [ null, selector, null ]; - - } else { - match = rquickExpr.exec( selector ); - } - - // Match html or make sure no context is specified for #id - if ( match && (match[1] || !context) ) { - - // HANDLE: $(html) -> $(array) - if ( match[1] ) { - context = context instanceof jQuery ? context[0] : context; - - // scripts is true for back-compat - jQuery.merge( this, jQuery.parseHTML( - match[1], - context && context.nodeType ? context.ownerDocument || context : document, - true - ) ); - - // HANDLE: $(html, props) - if ( rsingleTag.test( match[1] ) && jQuery.isPlainObject( context ) ) { - for ( match in context ) { - // Properties of context are called as methods if possible - if ( jQuery.isFunction( this[ match ] ) ) { - this[ match ]( context[ match ] ); - - // ...and otherwise set as attributes - } else { - this.attr( match, context[ match ] ); - } - } - } - - return this; - - // HANDLE: $(#id) - } else { - elem = document.getElementById( match[2] ); - - // Check parentNode to catch when Blackberry 4.6 returns - // nodes that are no longer in the document #6963 - if ( elem && elem.parentNode ) { - // Handle the case where IE and Opera return items - // by name instead of ID - if ( elem.id !== match[2] ) { - return rootjQuery.find( selector ); - } - - // Otherwise, we inject the element directly into the jQuery object - this.length = 1; - this[0] = elem; - } - - this.context = document; - this.selector = selector; - return this; - } - - // HANDLE: $(expr, $(...)) - } else if ( !context || context.jquery ) { - return ( context || rootjQuery ).find( selector ); - - // HANDLE: $(expr, context) - // (which is just equivalent to: $(context).find(expr) - } else { - return this.constructor( context ).find( selector ); - } - - // HANDLE: $(DOMElement) - } else if ( selector.nodeType ) { - this.context = this[0] = selector; - this.length = 1; - return this; - - // HANDLE: $(function) - // Shortcut for document ready - } else if ( jQuery.isFunction( selector ) ) { - return rootjQuery.ready( selector ); - } - - if ( selector.selector !== undefined ) { - this.selector = selector.selector; - this.context = selector.context; - } - - return jQuery.makeArray( selector, this ); - }, // Start with an empty selector selector: "", @@ -229,19 +100,19 @@ jQuery.fn = jQuery.prototype = { length: 0, toArray: function() { - return core_slice.call( this ); + return slice.call( this ); }, // Get the Nth element in the matched element set OR // Get the whole matched element set as a clean array get: function( num ) { - return num == null ? + return num != null ? // Return a 'clean' array - this.toArray() : + ( num < 0 ? this[ num + this.length ] : this[ num ] ) : // Return just the object - ( num < 0 ? this[ this.length + num ] : this[ num ] ); + slice.call( this ); }, // Take an array of elements and push it onto the stack @@ -266,15 +137,14 @@ jQuery.fn = jQuery.prototype = { return jQuery.each( this, callback, args ); }, - ready: function( fn ) { - // Add the callback - jQuery.ready.promise().done( fn ); - - return this; + map: function( callback ) { + return this.pushStack( jQuery.map(this, function( elem, i ) { + return callback.call( elem, i, elem ); + })); }, slice: function() { - return this.pushStack( core_slice.apply( this, arguments ) ); + return this.pushStack( slice.apply( this, arguments ) ); }, first: function() { @@ -291,26 +161,17 @@ jQuery.fn = jQuery.prototype = { return this.pushStack( j >= 0 && j < len ? [ this[j] ] : [] ); }, - map: function( callback ) { - return this.pushStack( jQuery.map(this, function( elem, i ) { - return callback.call( elem, i, elem ); - })); - }, - end: function() { return this.prevObject || this.constructor(null); }, // For internal use only. // Behaves like an Array's method, not like a jQuery method. - push: core_push, - sort: [].sort, - splice: [].splice + push: push, + sort: deletedIds.sort, + splice: deletedIds.splice }; -// Give the init function the jQuery prototype for later instantiation -jQuery.fn.init.prototype = jQuery.fn; - jQuery.extend = jQuery.fn.extend = function() { var src, copyIsArray, copy, name, options, clone, target = arguments[0] || {}, @@ -321,9 +182,10 @@ jQuery.extend = jQuery.fn.extend = function() { // Handle a deep copy situation if ( typeof target === "boolean" ) { deep = target; - target = arguments[1] || {}; + // skip the boolean and the target - i = 2; + target = arguments[ i ] || {}; + i++; } // Handle case when target is a string or something (possible in deep copy) @@ -332,9 +194,9 @@ jQuery.extend = jQuery.fn.extend = function() { } // extend jQuery itself if only one argument is passed - if ( length === i ) { + if ( i === length ) { target = this; - --i; + i--; } for ( ; i < length; i++ ) { @@ -377,66 +239,16 @@ jQuery.extend = jQuery.fn.extend = function() { jQuery.extend({ // Unique for each copy of jQuery on the page - // Non-digits removed to match rinlinejQuery - expando: "jQuery" + ( core_version + Math.random() ).replace( /\D/g, "" ), + expando: "jQuery" + ( version + Math.random() ).replace( /\D/g, "" ), - noConflict: function( deep ) { - if ( window.$ === jQuery ) { - window.$ = _$; - } + // Assume jQuery is ready without the ready module + isReady: true, - if ( deep && window.jQuery === jQuery ) { - window.jQuery = _jQuery; - } - - return jQuery; + error: function( msg ) { + throw new Error( msg ); }, - // Is the DOM ready to be used? Set to true once it occurs. - isReady: false, - - // A counter to track how many items to wait for before - // the ready event fires. See #6781 - readyWait: 1, - - // Hold (or release) the ready event - holdReady: function( hold ) { - if ( hold ) { - jQuery.readyWait++; - } else { - jQuery.ready( true ); - } - }, - - // Handle when the DOM is ready - ready: function( wait ) { - - // Abort if there are pending holds or we're already ready - if ( wait === true ? --jQuery.readyWait : jQuery.isReady ) { - return; - } - - // Make sure body exists, at least, in case IE gets a little overzealous (ticket #5443). - if ( !document.body ) { - return setTimeout( jQuery.ready ); - } - - // Remember that the DOM is ready - jQuery.isReady = true; - - // If a normal DOM Ready event fired, decrement, and wait if need be - if ( wait !== true && --jQuery.readyWait > 0 ) { - return; - } - - // If there are functions bound, to execute - readyList.resolveWith( document, [ jQuery ] ); - - // Trigger any bound ready events - if ( jQuery.fn.trigger ) { - jQuery( document ).trigger("ready").off("ready"); - } - }, + noop: function() {}, // See test/unit/core.js for details concerning isFunction. // Since version 1.3, DOM methods and functions like alert @@ -455,16 +267,18 @@ jQuery.extend({ }, isNumeric: function( obj ) { - return !isNaN( parseFloat(obj) ) && isFinite( obj ); + // parseFloat NaNs numeric-cast false positives (null|true|false|"") + // ...but misinterprets leading-number strings, particularly hex literals ("0x...") + // subtraction forces infinities to NaN + return obj - parseFloat( obj ) >= 0; }, - type: function( obj ) { - if ( obj == null ) { - return String( obj ); + isEmptyObject: function( obj ) { + var name; + for ( name in obj ) { + return false; } - return typeof obj === "object" || typeof obj === "function" ? - class2type[ core_toString.call(obj) ] || "object" : - typeof obj; + return true; }, isPlainObject: function( obj ) { @@ -480,8 +294,8 @@ jQuery.extend({ try { // Not own constructor property must be Object if ( obj.constructor && - !core_hasOwn.call(obj, "constructor") && - !core_hasOwn.call(obj.constructor.prototype, "isPrototypeOf") ) { + !hasOwn.call(obj, "constructor") && + !hasOwn.call(obj.constructor.prototype, "isPrototypeOf") ) { return false; } } catch ( e ) { @@ -491,9 +305,9 @@ jQuery.extend({ // Support: IE<9 // Handle iteration over inherited properties before own properties. - if ( jQuery.support.ownLast ) { + if ( support.ownLast ) { for ( key in obj ) { - return core_hasOwn.call( obj, key ); + return hasOwn.call( obj, key ); } } @@ -501,105 +315,18 @@ jQuery.extend({ // if last one is own, then all properties are own. for ( key in obj ) {} - return key === undefined || core_hasOwn.call( obj, key ); + return key === undefined || hasOwn.call( obj, key ); }, - isEmptyObject: function( obj ) { - var name; - for ( name in obj ) { - return false; + type: function( obj ) { + if ( obj == null ) { + return obj + ""; } - return true; + return typeof obj === "object" || typeof obj === "function" ? + class2type[ toString.call(obj) ] || "object" : + typeof obj; }, - error: function( msg ) { - throw new Error( msg ); - }, - - // data: string of html - // context (optional): If specified, the fragment will be created in this context, defaults to document - // keepScripts (optional): If true, will include scripts passed in the html string - parseHTML: function( data, context, keepScripts ) { - if ( !data || typeof data !== "string" ) { - return null; - } - if ( typeof context === "boolean" ) { - keepScripts = context; - context = false; - } - context = context || document; - - var parsed = rsingleTag.exec( data ), - scripts = !keepScripts && []; - - // Single tag - if ( parsed ) { - return [ context.createElement( parsed[1] ) ]; - } - - parsed = jQuery.buildFragment( [ data ], context, scripts ); - if ( scripts ) { - jQuery( scripts ).remove(); - } - return jQuery.merge( [], parsed.childNodes ); - }, - - parseJSON: function( data ) { - // Attempt to parse using the native JSON parser first - if ( window.JSON && window.JSON.parse ) { - return window.JSON.parse( data ); - } - - if ( data === null ) { - return data; - } - - if ( typeof data === "string" ) { - - // Make sure leading/trailing whitespace is removed (IE can't handle it) - data = jQuery.trim( data ); - - if ( data ) { - // Make sure the incoming data is actual JSON - // Logic borrowed from http://json.org/json2.js - if ( rvalidchars.test( data.replace( rvalidescape, "@" ) - .replace( rvalidtokens, "]" ) - .replace( rvalidbraces, "")) ) { - - return ( new Function( "return " + data ) )(); - } - } - } - - jQuery.error( "Invalid JSON: " + data ); - }, - - // Cross-browser xml parsing - parseXML: function( data ) { - var xml, tmp; - if ( !data || typeof data !== "string" ) { - return null; - } - try { - if ( window.DOMParser ) { // Standard - tmp = new DOMParser(); - xml = tmp.parseFromString( data , "text/xml" ); - } else { // IE - xml = new ActiveXObject( "Microsoft.XMLDOM" ); - xml.async = "false"; - xml.loadXML( data ); - } - } catch( e ) { - xml = undefined; - } - if ( !xml || !xml.documentElement || xml.getElementsByTagName( "parsererror" ).length ) { - jQuery.error( "Invalid XML: " + data ); - } - return xml; - }, - - noop: function() {}, - // Evaluates a script in a global context // Workarounds based on findings by Jim Driscoll // http://weblogs.java.net/blog/driscoll/archive/2009/09/08/eval-javascript-global-context @@ -675,11 +402,11 @@ jQuery.extend({ }, // Use native String.trim function wherever possible - trim: core_trim && !core_trim.call("\uFEFF\xA0") ? + trim: trim && !trim.call("\uFEFF\xA0") ? function( text ) { return text == null ? "" : - core_trim.call( text ); + trim.call( text ); } : // Otherwise use our own trimming functionality @@ -700,7 +427,7 @@ jQuery.extend({ [ arr ] : arr ); } else { - core_push.call( ret, arr ); + push.call( ret, arr ); } } @@ -711,8 +438,8 @@ jQuery.extend({ var len; if ( arr ) { - if ( core_indexOf ) { - return core_indexOf.call( arr, elem, i ); + if ( indexOf ) { + return indexOf.call( arr, elem, i ); } len = arr.length; @@ -730,15 +457,17 @@ jQuery.extend({ }, merge: function( first, second ) { - var l = second.length, - i = first.length, - j = 0; + var len = +second.length, + j = 0, + i = first.length; - if ( typeof l === "number" ) { - for ( ; j < l; j++ ) { - first[ i++ ] = second[ j ]; - } - } else { + while ( j < len ) { + first[ i++ ] = second[ j++ ]; + } + + // Support: IE<9 + // Workaround casting of .length to NaN on otherwise arraylike objects (e.g., NodeLists) + if ( len !== len ) { while ( second[j] !== undefined ) { first[ i++ ] = second[ j++ ]; } @@ -749,23 +478,23 @@ jQuery.extend({ return first; }, - grep: function( elems, callback, inv ) { - var retVal, - ret = [], + grep: function( elems, callback, invert ) { + var callbackInverse, + matches = [], i = 0, - length = elems.length; - inv = !!inv; + length = elems.length, + callbackExpect = !invert; // Go through the array, only saving the items // that pass the validator function for ( ; i < length; i++ ) { - retVal = !!callback( elems[ i ], i ); - if ( inv !== retVal ) { - ret.push( elems[ i ] ); + callbackInverse = !callback( elems[ i ], i ); + if ( callbackInverse !== callbackExpect ) { + matches.push( elems[ i ] ); } } - return ret; + return matches; }, // arg is for internal usage only @@ -776,13 +505,13 @@ jQuery.extend({ isArray = isArraylike( elems ), ret = []; - // Go through the array, translating each of the items to their + // Go through the array, translating each of the items to their new values if ( isArray ) { for ( ; i < length; i++ ) { value = callback( elems[ i ], i, arg ); if ( value != null ) { - ret[ ret.length ] = value; + ret.push( value ); } } @@ -792,13 +521,13 @@ jQuery.extend({ value = callback( elems[ i ], i, arg ); if ( value != null ) { - ret[ ret.length ] = value; + ret.push( value ); } } } // Flatten any nested arrays - return core_concat.apply( [], ret ); + return concat.apply( [], ret ); }, // A global GUID counter for objects @@ -822,9 +551,9 @@ jQuery.extend({ } // Simulated bind - args = core_slice.call( arguments, 2 ); + args = slice.call( arguments, 2 ); proxy = function() { - return fn.apply( context || this, args.concat( core_slice.call( arguments ) ) ); + return fn.apply( context || this, args.concat( slice.call( arguments ) ) ); }; // Set the guid of unique handler to the same of original handler, so it can be removed @@ -833,148 +562,15 @@ jQuery.extend({ return proxy; }, - // Multifunctional method to get and set values of a collection - // The value/s can optionally be executed if it's a function - access: function( elems, fn, key, value, chainable, emptyGet, raw ) { - var i = 0, - length = elems.length, - bulk = key == null; - - // Sets many values - if ( jQuery.type( key ) === "object" ) { - chainable = true; - for ( i in key ) { - jQuery.access( elems, fn, i, key[i], true, emptyGet, raw ); - } - - // Sets one value - } else if ( value !== undefined ) { - chainable = true; - - if ( !jQuery.isFunction( value ) ) { - raw = true; - } - - if ( bulk ) { - // Bulk operations run against the entire set - if ( raw ) { - fn.call( elems, value ); - fn = null; - - // ...except when executing function values - } else { - bulk = fn; - fn = function( elem, key, value ) { - return bulk.call( jQuery( elem ), value ); - }; - } - } - - if ( fn ) { - for ( ; i < length; i++ ) { - fn( elems[i], key, raw ? value : value.call( elems[i], i, fn( elems[i], key ) ) ); - } - } - } - - return chainable ? - elems : - - // Gets - bulk ? - fn.call( elems ) : - length ? fn( elems[0], key ) : emptyGet; - }, - now: function() { - return ( new Date() ).getTime(); + return +( new Date() ); }, - // A method for quickly swapping in/out CSS properties to get correct calculations. - // Note: this method belongs to the css module but it's needed here for the support module. - // If support gets modularized, this method should be moved back to the css module. - swap: function( elem, options, callback, args ) { - var ret, name, - old = {}; - - // Remember the old values, and insert the new ones - for ( name in options ) { - old[ name ] = elem.style[ name ]; - elem.style[ name ] = options[ name ]; - } - - ret = callback.apply( elem, args || [] ); - - // Revert the old values - for ( name in options ) { - elem.style[ name ] = old[ name ]; - } - - return ret; - } + // jQuery.support is not used in Core but other projects attach their + // properties to it so it needs to exist. + support: support }); -jQuery.ready.promise = function( obj ) { - if ( !readyList ) { - - readyList = jQuery.Deferred(); - - // Catch cases where $(document).ready() is called after the browser event has already occurred. - // we once tried to use readyState "interactive" here, but it caused issues like the one - // discovered by ChrisS here: http://bugs.jquery.com/ticket/12282#comment:15 - if ( document.readyState === "complete" ) { - // Handle it asynchronously to allow scripts the opportunity to delay ready - setTimeout( jQuery.ready ); - - // Standards-based browsers support DOMContentLoaded - } else if ( document.addEventListener ) { - // Use the handy event callback - document.addEventListener( "DOMContentLoaded", completed, false ); - - // A fallback to window.onload, that will always work - window.addEventListener( "load", completed, false ); - - // If IE event model is used - } else { - // Ensure firing before onload, maybe late but safe also for iframes - document.attachEvent( "onreadystatechange", completed ); - - // A fallback to window.onload, that will always work - window.attachEvent( "onload", completed ); - - // If IE and not a frame - // continually check to see if the document is ready - var top = false; - - try { - top = window.frameElement == null && document.documentElement; - } catch(e) {} - - if ( top && top.doScroll ) { - (function doScrollCheck() { - if ( !jQuery.isReady ) { - - try { - // Use the trick by Diego Perini - // http://javascript.nwbox.com/IEContentLoaded/ - top.doScroll("left"); - } catch(e) { - return setTimeout( doScrollCheck, 50 ); - } - - // detach all dom ready events - detach(); - - // and execute any waiting functions - jQuery.ready(); - } - })(); - } - } - } - return readyList.promise( obj ); -}; - // Populate the class2type map jQuery.each("Boolean Number String Function Array Date RegExp Object Error".split(" "), function(i, name) { class2type[ "[object " + name + "]" ] = name.toLowerCase(); @@ -984,7 +580,7 @@ function isArraylike( obj ) { var length = obj.length, type = jQuery.type( obj ); - if ( jQuery.isWindow( obj ) ) { + if ( type === "function" || jQuery.isWindow( obj ) ) { return false; } @@ -992,34 +588,31 @@ function isArraylike( obj ) { return true; } - return type === "array" || type !== "function" && - ( length === 0 || - typeof length === "number" && length > 0 && ( length - 1 ) in obj ); + return type === "array" || length === 0 || + typeof length === "number" && length > 0 && ( length - 1 ) in obj; } - -// All jQuery objects should point back to these -rootjQuery = jQuery(document); +var Sizzle = /*! - * Sizzle CSS Selector Engine v1.10.2 + * Sizzle CSS Selector Engine v1.10.16 * http://sizzlejs.com/ * * Copyright 2013 jQuery Foundation, Inc. and other contributors * Released under the MIT license * http://jquery.org/license * - * Date: 2013-07-03 + * Date: 2014-01-13 */ -(function( window, undefined ) { +(function( window ) { var i, support, - cachedruns, Expr, getText, isXML, compile, outermostContext, sortInput, + hasDuplicate, // Local document vars setDocument, @@ -1039,11 +632,9 @@ var i, classCache = createCache(), tokenCache = createCache(), compilerCache = createCache(), - hasDuplicate = false, sortOrder = function( a, b ) { if ( a === b ) { hasDuplicate = true; - return 0; } return 0; }, @@ -1103,8 +694,7 @@ var i, rcomma = new RegExp( "^" + whitespace + "*," + whitespace + "*" ), rcombinators = new RegExp( "^" + whitespace + "*([>+~]|" + whitespace + ")" + whitespace + "*" ), - rsibling = new RegExp( whitespace + "*[+~]" ), - rattributeQuotes = new RegExp( "=" + whitespace + "*([^\\]'\"]*)" + whitespace + "*\\]", "g" ), + rattributeQuotes = new RegExp( "=" + whitespace + "*([^\\]'\"]*?)" + whitespace + "*\\]", "g" ), rpseudo = new RegExp( pseudos ), ridentifier = new RegExp( "^" + identifier + "$" ), @@ -1125,14 +715,15 @@ var i, whitespace + "*((?:-\\d)?\\d*)" + whitespace + "*\\)|)(?=[^-]|$)", "i" ) }, + rinputs = /^(?:input|select|textarea|button)$/i, + rheader = /^h\d$/i, + rnative = /^[^{]+\{\s*\[native \w/, // Easily-parseable/retrievable ID or TAG or CLASS selectors rquickExpr = /^(?:#([\w-]+)|(\w+)|\.([\w-]+))$/, - rinputs = /^(?:input|select|textarea|button)$/i, - rheader = /^h\d$/i, - + rsibling = /[+~]/, rescape = /'|\\/g, // CSS escapes http://www.w3.org/TR/CSS21/syndata.html#escaped-characters @@ -1144,8 +735,8 @@ var i, // Workaround erroneous numeric interpretation of +"0x" return high !== high || escapedWhitespace ? escaped : - // BMP codepoint high < 0 ? + // BMP codepoint String.fromCharCode( high + 0x10000 ) : // Supplemental Plane codepoint (surrogate pair) String.fromCharCode( high >> 10 | 0xD800, high & 0x3FF | 0xDC00 ); @@ -1209,7 +800,7 @@ function Sizzle( selector, context, results, seed ) { if ( nodeType === 9 ) { elem = context.getElementById( m ); // Check parentNode to catch when Blackberry 4.6 returns - // nodes that are no longer in the document #6963 + // nodes that are no longer in the document (jQuery #6963) if ( elem && elem.parentNode ) { // Handle the case where IE, Opera, and Webkit return items // by name instead of ID @@ -1265,7 +856,7 @@ function Sizzle( selector, context, results, seed ) { while ( i-- ) { groups[i] = nid + toSelector( groups[i] ); } - newContext = rsibling.test( selector ) && context.parentNode || context; + newContext = rsibling.test( selector ) && testContext( context.parentNode ) || context; newSelector = groups.join(","); } @@ -1300,11 +891,11 @@ function createCache() { function cache( key, value ) { // Use (key + " ") to avoid collision with native prototype properties (see Issue #157) - if ( keys.push( key += " " ) > Expr.cacheLength ) { + if ( keys.push( key + " " ) > Expr.cacheLength ) { // Only keep the most recent entries delete cache[ keys.shift() ]; } - return (cache[ key ] = value); + return (cache[ key + " " ] = value); } return cache; } @@ -1427,8 +1018,21 @@ function createPositionalPseudo( fn ) { } /** - * Detect xml + * Checks a node for validity as a Sizzle context + * @param {Element|Object=} context + * @returns {Element|Object|Boolean} The input node if acceptable, otherwise a falsy value + */ +function testContext( context ) { + return context && typeof context.getElementsByTagName !== strundefined && context; +} + +// Expose support vars for convenience +support = Sizzle.support = {}; + +/** + * Detects XML nodes * @param {Element|Object} elem An element or a document + * @returns {Boolean} True iff elem is a non-HTML XML node */ isXML = Sizzle.isXML = function( elem ) { // documentElement is verified for cases where it doesn't yet exist @@ -1437,16 +1041,14 @@ isXML = Sizzle.isXML = function( elem ) { return documentElement ? documentElement.nodeName !== "HTML" : false; }; -// Expose support vars for convenience -support = Sizzle.support = {}; - /** * Sets document-related variables once based on the current document * @param {Element|Object} [doc] An element or document object to use to set the document * @returns {Object} Returns the current document */ setDocument = Sizzle.setDocument = function( node ) { - var doc = node ? node.ownerDocument || node : preferredDoc, + var hasCompare, + doc = node ? node.ownerDocument || node : preferredDoc, parent = doc.defaultView; // If no document and documentElement is available, return @@ -1465,10 +1067,17 @@ setDocument = Sizzle.setDocument = function( node ) { // If iframe document is assigned to "document" variable and if iframe has been reloaded, // IE will throw "permission denied" error when accessing "document" variable, see jQuery #13936 // IE6-8 do not support the defaultView property so parent will be undefined - if ( parent && parent.attachEvent && parent !== parent.top ) { - parent.attachEvent( "onbeforeunload", function() { - setDocument(); - }); + if ( parent && parent !== parent.top ) { + // IE11 does not have attachEvent, so all must suffer + if ( parent.addEventListener ) { + parent.addEventListener( "unload", function() { + setDocument(); + }, false ); + } else if ( parent.attachEvent ) { + parent.attachEvent( "onunload", function() { + setDocument(); + }); + } } /* Attributes @@ -1491,7 +1100,7 @@ setDocument = Sizzle.setDocument = function( node ) { }); // Check if getElementsByClassName can be trusted - support.getElementsByClassName = assert(function( div ) { + support.getElementsByClassName = rnative.test( doc.getElementsByClassName ) && assert(function( div ) { div.innerHTML = "
"; // Support: Safari<4 @@ -1598,7 +1207,13 @@ setDocument = Sizzle.setDocument = function( node ) { // setting a boolean content attribute, // since its presence should be enough // http://bugs.jquery.com/ticket/12359 - div.innerHTML = ""; + div.innerHTML = ""; + + // Support: IE8, Opera 10-12 + // Nothing should be selected when empty strings follow ^= or $= or *= + if ( div.querySelectorAll("[t^='']").length ) { + rbuggyQSA.push( "[*^$]=" + whitespace + "*(?:''|\"\")" ); + } // Support: IE8 // Boolean attributes and "value" are not treated correctly @@ -1615,18 +1230,16 @@ setDocument = Sizzle.setDocument = function( node ) { }); assert(function( div ) { - - // Support: Opera 10-12/IE8 - // ^= $= *= and empty values - // Should not select anything // Support: Windows 8 Native Apps - // The type attribute is restricted during .innerHTML assignment + // The type and name attributes are restricted during .innerHTML assignment var input = doc.createElement("input"); input.setAttribute( "type", "hidden" ); - div.appendChild( input ).setAttribute( "t", "" ); + div.appendChild( input ).setAttribute( "name", "D" ); - if ( div.querySelectorAll("[t^='']").length ) { - rbuggyQSA.push( "[*^$]=" + whitespace + "*(?:''|\"\")" ); + // Support: IE8 + // Enforce case-sensitivity of name attribute + if ( div.querySelectorAll("[name=d]").length ) { + rbuggyQSA.push( "name" + whitespace + "*[*^$|!~]?=" ); } // FF 3.5 - :enabled/:disabled and hidden elements (hidden elements are still enabled) @@ -1663,11 +1276,12 @@ setDocument = Sizzle.setDocument = function( node ) { /* Contains ---------------------------------------------------------------------- */ + hasCompare = rnative.test( docElem.compareDocumentPosition ); // Element contains another // Purposefully does not implement inclusive descendent // As in, an element does not contain itself - contains = rnative.test( docElem.contains ) || docElem.compareDocumentPosition ? + contains = hasCompare || rnative.test( docElem.contains ) ? function( a, b ) { var adown = a.nodeType === 9 ? a.documentElement : a, bup = b && b.parentNode; @@ -1692,7 +1306,7 @@ setDocument = Sizzle.setDocument = function( node ) { ---------------------------------------------------------------------- */ // Document order sorting - sortOrder = docElem.compareDocumentPosition ? + sortOrder = hasCompare ? function( a, b ) { // Flag for duplicate removal @@ -1701,34 +1315,46 @@ setDocument = Sizzle.setDocument = function( node ) { return 0; } - var compare = b.compareDocumentPosition && a.compareDocumentPosition && a.compareDocumentPosition( b ); - + // Sort on method existence if only one input has compareDocumentPosition + var compare = !a.compareDocumentPosition - !b.compareDocumentPosition; if ( compare ) { - // Disconnected nodes - if ( compare & 1 || - (!support.sortDetached && b.compareDocumentPosition( a ) === compare) ) { - - // Choose the first element that is related to our preferred document - if ( a === doc || contains(preferredDoc, a) ) { - return -1; - } - if ( b === doc || contains(preferredDoc, b) ) { - return 1; - } - - // Maintain original order - return sortInput ? - ( indexOf.call( sortInput, a ) - indexOf.call( sortInput, b ) ) : - 0; - } - - return compare & 4 ? -1 : 1; + return compare; } - // Not directly comparable, sort on existence of method - return a.compareDocumentPosition ? -1 : 1; + // Calculate position if both inputs belong to the same document + compare = ( a.ownerDocument || a ) === ( b.ownerDocument || b ) ? + a.compareDocumentPosition( b ) : + + // Otherwise we know they are disconnected + 1; + + // Disconnected nodes + if ( compare & 1 || + (!support.sortDetached && b.compareDocumentPosition( a ) === compare) ) { + + // Choose the first element that is related to our preferred document + if ( a === doc || a.ownerDocument === preferredDoc && contains(preferredDoc, a) ) { + return -1; + } + if ( b === doc || b.ownerDocument === preferredDoc && contains(preferredDoc, b) ) { + return 1; + } + + // Maintain original order + return sortInput ? + ( indexOf.call( sortInput, a ) - indexOf.call( sortInput, b ) ) : + 0; + } + + return compare & 4 ? -1 : 1; } : function( a, b ) { + // Exit early if the nodes are identical + if ( a === b ) { + hasDuplicate = true; + return 0; + } + var cur, i = 0, aup = a.parentNode, @@ -1736,13 +1362,8 @@ setDocument = Sizzle.setDocument = function( node ) { ap = [ a ], bp = [ b ]; - // Exit early if the nodes are identical - if ( a === b ) { - hasDuplicate = true; - return 0; - // Parentless nodes are either documents or disconnected - } else if ( !aup || !bup ) { + if ( !aup || !bup ) { return a === doc ? -1 : b === doc ? 1 : aup ? -1 : @@ -1837,13 +1458,13 @@ Sizzle.attr = function( elem, name ) { fn( elem, name, !documentIsHTML ) : undefined; - return val === undefined ? + return val !== undefined ? + val : support.attributes || !documentIsHTML ? elem.getAttribute( name ) : (val = elem.getAttributeNode(name)) && val.specified ? val.value : - null : - val; + null; }; Sizzle.error = function( msg ) { @@ -1876,6 +1497,10 @@ Sizzle.uniqueSort = function( results ) { } } + // Clear input after sorting to release objects + // See https://github.com/jquery/sizzle/pull/225 + sortInput = null; + return results; }; @@ -1891,13 +1516,13 @@ getText = Sizzle.getText = function( elem ) { if ( !nodeType ) { // If no nodeType, this is expected to be an array - for ( ; (node = elem[i]); i++ ) { + while ( (node = elem[i++]) ) { // Do not traverse comment nodes ret += getText( node ); } } else if ( nodeType === 1 || nodeType === 9 || nodeType === 11 ) { // Use textContent for elements - // innerText usage removed for consistency of new lines (see #11153) + // innerText usage removed for consistency of new lines (jQuery #11153) if ( typeof elem.textContent === "string" ) { return elem.textContent; } else { @@ -2294,12 +1919,11 @@ Expr = Sizzle.selectors = { // Contents "empty": function( elem ) { // http://www.w3.org/TR/selectors/#empty-pseudo - // :empty is only affected by element nodes and content nodes(including text(3), cdata(4)), - // not comment, processing instructions, or others - // Thanks to Diego Perini for the nodeName shortcut - // Greater than "@" means alpha characters (specifically not starting with "#" or "?") + // :empty is negated by element (1) or content nodes (text: 3; cdata: 4; entity ref: 5), + // but not by others (comment: 8; processing instruction: 7; etc.) + // nodeType < 6 works because attributes (2) do not appear as children for ( elem = elem.firstChild; elem; elem = elem.nextSibling ) { - if ( elem.nodeName > "@" || elem.nodeType === 3 || elem.nodeType === 4 ) { + if ( elem.nodeType < 6 ) { return false; } } @@ -2326,11 +1950,12 @@ Expr = Sizzle.selectors = { "text": function( elem ) { var attr; - // IE6 and 7 will map elem.type to 'text' for new HTML5 types (search, etc) - // use getAttribute instead to test this case return elem.nodeName.toLowerCase() === "input" && elem.type === "text" && - ( (attr = elem.getAttribute("type")) == null || attr.toLowerCase() === elem.type ); + + // Support: IE<8 + // New HTML5 attribute values (e.g., "search") appear with elem.type === "text" + ( (attr = elem.getAttribute("type")) == null || attr.toLowerCase() === "text" ); }, // Position-in-collection @@ -2416,7 +2041,7 @@ function tokenize( selector, parseOnly ) { // Don't consume trailing commas as valid soFar = soFar.slice( match[0].length ) || soFar; } - groups.push( tokens = [] ); + groups.push( (tokens = []) ); } matched = false; @@ -2489,8 +2114,8 @@ function addCombinator( matcher, combinator, base ) { // Check against all ancestor/preceding elements function( elem, context, xml ) { - var data, cache, outerCache, - dirkey = dirruns + " " + doneName; + var oldCache, outerCache, + newCache = [ dirruns, doneName ]; // We can't set arbitrary data on XML nodes, so they don't benefit from dir caching if ( xml ) { @@ -2505,14 +2130,17 @@ function addCombinator( matcher, combinator, base ) { while ( (elem = elem[ dir ]) ) { if ( elem.nodeType === 1 || checkNonElements ) { outerCache = elem[ expando ] || (elem[ expando ] = {}); - if ( (cache = outerCache[ dir ]) && cache[0] === dirkey ) { - if ( (data = cache[1]) === true || data === cachedruns ) { - return data === true; - } + if ( (oldCache = outerCache[ dir ]) && + oldCache[ 0 ] === dirruns && oldCache[ 1 ] === doneName ) { + + // Assign to newCache so results back-propagate to previous elements + return (newCache[ 2 ] = oldCache[ 2 ]); } else { - cache = outerCache[ dir ] = [ dirkey ]; - cache[1] = matcher( elem, context, xml ) || cachedruns; - if ( cache[1] === true ) { + // Reuse newcache so results back-propagate to previous elements + outerCache[ dir ] = newCache; + + // A match means we're done; a fail means we have to keep checking + if ( (newCache[ 2 ] = matcher( elem, context, xml )) ) { return true; } } @@ -2706,31 +2334,30 @@ function matcherFromTokens( tokens ) { } function matcherFromGroupMatchers( elementMatchers, setMatchers ) { - // A counter to specify which element is currently being matched - var matcherCachedRuns = 0, - bySet = setMatchers.length > 0, + var bySet = setMatchers.length > 0, byElement = elementMatchers.length > 0, - superMatcher = function( seed, context, xml, results, expandContext ) { + superMatcher = function( seed, context, xml, results, outermost ) { var elem, j, matcher, - setMatched = [], matchedCount = 0, i = "0", unmatched = seed && [], - outermost = expandContext != null, + setMatched = [], contextBackup = outermostContext, - // We must always have either seed elements or context - elems = seed || byElement && Expr.find["TAG"]( "*", expandContext && context.parentNode || context ), + // We must always have either seed elements or outermost context + elems = seed || byElement && Expr.find["TAG"]( "*", outermost ), // Use integer dirruns iff this is the outermost matcher - dirrunsUnique = (dirruns += contextBackup == null ? 1 : Math.random() || 0.1); + dirrunsUnique = (dirruns += contextBackup == null ? 1 : Math.random() || 0.1), + len = elems.length; if ( outermost ) { outermostContext = context !== document && context; - cachedruns = matcherCachedRuns; } // Add elements passing elementMatchers directly to results // Keep `i` a string if there are no elements so `matchedCount` will be "00" below - for ( ; (elem = elems[i]) != null; i++ ) { + // Support: IE<9, Safari + // Tolerate NodeList properties (IE: "length"; Safari: ) matching elements by id + for ( ; i !== len && (elem = elems[i]) != null; i++ ) { if ( byElement && elem ) { j = 0; while ( (matcher = elementMatchers[j++]) ) { @@ -2741,7 +2368,6 @@ function matcherFromGroupMatchers( elementMatchers, setMatchers ) { } if ( outermost ) { dirruns = dirrunsUnique; - cachedruns = ++matcherCachedRuns; } } @@ -2876,7 +2502,7 @@ function select( selector, context, results, seed ) { // Search, expanding context for leading sibling combinators if ( (seed = find( token.matches[0].replace( runescape, funescape ), - rsibling.test( tokens[0].type ) && context.parentNode || context + rsibling.test( tokens[0].type ) && testContext( context.parentNode ) || context )) ) { // If seed is empty or no tokens remain, we can return early @@ -2901,7 +2527,7 @@ function select( selector, context, results, seed ) { context, !documentIsHTML, results, - rsibling.test( selector ) + rsibling.test( selector ) && testContext( context.parentNode ) || context ); return results; } @@ -2913,7 +2539,7 @@ support.sortStable = expando.split("").sort( sortOrder ).join("") === expando; // Support: Chrome<14 // Always assume duplicates if they aren't passed to the comparison function -support.detectDuplicates = hasDuplicate; +support.detectDuplicates = !!hasDuplicate; // Initialize against the default document setDocument(); @@ -2961,13 +2587,20 @@ if ( !assert(function( div ) { addHandle( booleans, function( elem, name, isXML ) { var val; if ( !isXML ) { - return (val = elem.getAttributeNode( name )) && val.specified ? - val.value : - elem[ name ] === true ? name.toLowerCase() : null; + return elem[ name ] === true ? name.toLowerCase() : + (val = elem.getAttributeNode( name )) && val.specified ? + val.value : + null; } }); } +return Sizzle; + +})( window ); + + + jQuery.find = Sizzle; jQuery.expr = Sizzle.selectors; jQuery.expr[":"] = jQuery.expr.pseudos; @@ -2977,14 +2610,432 @@ jQuery.isXMLDoc = Sizzle.isXML; jQuery.contains = Sizzle.contains; -})( window ); + +var rneedsContext = jQuery.expr.match.needsContext; + +var rsingleTag = (/^<(\w+)\s*\/?>(?:<\/\1>|)$/); + + + +var risSimple = /^.[^:#\[\.,]*$/; + +// Implement the identical functionality for filter and not +function winnow( elements, qualifier, not ) { + if ( jQuery.isFunction( qualifier ) ) { + return jQuery.grep( elements, function( elem, i ) { + /* jshint -W018 */ + return !!qualifier.call( elem, i, elem ) !== not; + }); + + } + + if ( qualifier.nodeType ) { + return jQuery.grep( elements, function( elem ) { + return ( elem === qualifier ) !== not; + }); + + } + + if ( typeof qualifier === "string" ) { + if ( risSimple.test( qualifier ) ) { + return jQuery.filter( qualifier, elements, not ); + } + + qualifier = jQuery.filter( qualifier, elements ); + } + + return jQuery.grep( elements, function( elem ) { + return ( jQuery.inArray( elem, qualifier ) >= 0 ) !== not; + }); +} + +jQuery.filter = function( expr, elems, not ) { + var elem = elems[ 0 ]; + + if ( not ) { + expr = ":not(" + expr + ")"; + } + + return elems.length === 1 && elem.nodeType === 1 ? + jQuery.find.matchesSelector( elem, expr ) ? [ elem ] : [] : + jQuery.find.matches( expr, jQuery.grep( elems, function( elem ) { + return elem.nodeType === 1; + })); +}; + +jQuery.fn.extend({ + find: function( selector ) { + var i, + ret = [], + self = this, + len = self.length; + + if ( typeof selector !== "string" ) { + return this.pushStack( jQuery( selector ).filter(function() { + for ( i = 0; i < len; i++ ) { + if ( jQuery.contains( self[ i ], this ) ) { + return true; + } + } + }) ); + } + + for ( i = 0; i < len; i++ ) { + jQuery.find( selector, self[ i ], ret ); + } + + // Needed because $( selector, context ) becomes $( context ).find( selector ) + ret = this.pushStack( len > 1 ? jQuery.unique( ret ) : ret ); + ret.selector = this.selector ? this.selector + " " + selector : selector; + return ret; + }, + filter: function( selector ) { + return this.pushStack( winnow(this, selector || [], false) ); + }, + not: function( selector ) { + return this.pushStack( winnow(this, selector || [], true) ); + }, + is: function( selector ) { + return !!winnow( + this, + + // If this is a positional/relative selector, check membership in the returned set + // so $("p:first").is("p:last") won't return true for a doc with two "p". + typeof selector === "string" && rneedsContext.test( selector ) ? + jQuery( selector ) : + selector || [], + false + ).length; + } +}); + + +// Initialize a jQuery object + + +// A central reference to the root jQuery(document) +var rootjQuery, + + // Use the correct document accordingly with window argument (sandbox) + document = window.document, + + // A simple way to check for HTML strings + // Prioritize #id over to avoid XSS via location.hash (#9521) + // Strict HTML recognition (#11290: must start with <) + rquickExpr = /^(?:\s*(<[\w\W]+>)[^>]*|#([\w-]*))$/, + + init = jQuery.fn.init = function( selector, context ) { + var match, elem; + + // HANDLE: $(""), $(null), $(undefined), $(false) + if ( !selector ) { + return this; + } + + // Handle HTML strings + if ( typeof selector === "string" ) { + if ( selector.charAt(0) === "<" && selector.charAt( selector.length - 1 ) === ">" && selector.length >= 3 ) { + // Assume that strings that start and end with <> are HTML and skip the regex check + match = [ null, selector, null ]; + + } else { + match = rquickExpr.exec( selector ); + } + + // Match html or make sure no context is specified for #id + if ( match && (match[1] || !context) ) { + + // HANDLE: $(html) -> $(array) + if ( match[1] ) { + context = context instanceof jQuery ? context[0] : context; + + // scripts is true for back-compat + // Intentionally let the error be thrown if parseHTML is not present + jQuery.merge( this, jQuery.parseHTML( + match[1], + context && context.nodeType ? context.ownerDocument || context : document, + true + ) ); + + // HANDLE: $(html, props) + if ( rsingleTag.test( match[1] ) && jQuery.isPlainObject( context ) ) { + for ( match in context ) { + // Properties of context are called as methods if possible + if ( jQuery.isFunction( this[ match ] ) ) { + this[ match ]( context[ match ] ); + + // ...and otherwise set as attributes + } else { + this.attr( match, context[ match ] ); + } + } + } + + return this; + + // HANDLE: $(#id) + } else { + elem = document.getElementById( match[2] ); + + // Check parentNode to catch when Blackberry 4.6 returns + // nodes that are no longer in the document #6963 + if ( elem && elem.parentNode ) { + // Handle the case where IE and Opera return items + // by name instead of ID + if ( elem.id !== match[2] ) { + return rootjQuery.find( selector ); + } + + // Otherwise, we inject the element directly into the jQuery object + this.length = 1; + this[0] = elem; + } + + this.context = document; + this.selector = selector; + return this; + } + + // HANDLE: $(expr, $(...)) + } else if ( !context || context.jquery ) { + return ( context || rootjQuery ).find( selector ); + + // HANDLE: $(expr, context) + // (which is just equivalent to: $(context).find(expr) + } else { + return this.constructor( context ).find( selector ); + } + + // HANDLE: $(DOMElement) + } else if ( selector.nodeType ) { + this.context = this[0] = selector; + this.length = 1; + return this; + + // HANDLE: $(function) + // Shortcut for document ready + } else if ( jQuery.isFunction( selector ) ) { + return typeof rootjQuery.ready !== "undefined" ? + rootjQuery.ready( selector ) : + // Execute immediately if ready is not present + selector( jQuery ); + } + + if ( selector.selector !== undefined ) { + this.selector = selector.selector; + this.context = selector.context; + } + + return jQuery.makeArray( selector, this ); + }; + +// Give the init function the jQuery prototype for later instantiation +init.prototype = jQuery.fn; + +// Initialize central reference +rootjQuery = jQuery( document ); + + +var rparentsprev = /^(?:parents|prev(?:Until|All))/, + // methods guaranteed to produce a unique set when starting from a unique set + guaranteedUnique = { + children: true, + contents: true, + next: true, + prev: true + }; + +jQuery.extend({ + dir: function( elem, dir, until ) { + var matched = [], + cur = elem[ dir ]; + + while ( cur && cur.nodeType !== 9 && (until === undefined || cur.nodeType !== 1 || !jQuery( cur ).is( until )) ) { + if ( cur.nodeType === 1 ) { + matched.push( cur ); + } + cur = cur[dir]; + } + return matched; + }, + + sibling: function( n, elem ) { + var r = []; + + for ( ; n; n = n.nextSibling ) { + if ( n.nodeType === 1 && n !== elem ) { + r.push( n ); + } + } + + return r; + } +}); + +jQuery.fn.extend({ + has: function( target ) { + var i, + targets = jQuery( target, this ), + len = targets.length; + + return this.filter(function() { + for ( i = 0; i < len; i++ ) { + if ( jQuery.contains( this, targets[i] ) ) { + return true; + } + } + }); + }, + + closest: function( selectors, context ) { + var cur, + i = 0, + l = this.length, + matched = [], + pos = rneedsContext.test( selectors ) || typeof selectors !== "string" ? + jQuery( selectors, context || this.context ) : + 0; + + for ( ; i < l; i++ ) { + for ( cur = this[i]; cur && cur !== context; cur = cur.parentNode ) { + // Always skip document fragments + if ( cur.nodeType < 11 && (pos ? + pos.index(cur) > -1 : + + // Don't pass non-elements to Sizzle + cur.nodeType === 1 && + jQuery.find.matchesSelector(cur, selectors)) ) { + + matched.push( cur ); + break; + } + } + } + + return this.pushStack( matched.length > 1 ? jQuery.unique( matched ) : matched ); + }, + + // Determine the position of an element within + // the matched set of elements + index: function( elem ) { + + // No argument, return index in parent + if ( !elem ) { + return ( this[0] && this[0].parentNode ) ? this.first().prevAll().length : -1; + } + + // index in selector + if ( typeof elem === "string" ) { + return jQuery.inArray( this[0], jQuery( elem ) ); + } + + // Locate the position of the desired element + return jQuery.inArray( + // If it receives a jQuery object, the first element is used + elem.jquery ? elem[0] : elem, this ); + }, + + add: function( selector, context ) { + return this.pushStack( + jQuery.unique( + jQuery.merge( this.get(), jQuery( selector, context ) ) + ) + ); + }, + + addBack: function( selector ) { + return this.add( selector == null ? + this.prevObject : this.prevObject.filter(selector) + ); + } +}); + +function sibling( cur, dir ) { + do { + cur = cur[ dir ]; + } while ( cur && cur.nodeType !== 1 ); + + return cur; +} + +jQuery.each({ + parent: function( elem ) { + var parent = elem.parentNode; + return parent && parent.nodeType !== 11 ? parent : null; + }, + parents: function( elem ) { + return jQuery.dir( elem, "parentNode" ); + }, + parentsUntil: function( elem, i, until ) { + return jQuery.dir( elem, "parentNode", until ); + }, + next: function( elem ) { + return sibling( elem, "nextSibling" ); + }, + prev: function( elem ) { + return sibling( elem, "previousSibling" ); + }, + nextAll: function( elem ) { + return jQuery.dir( elem, "nextSibling" ); + }, + prevAll: function( elem ) { + return jQuery.dir( elem, "previousSibling" ); + }, + nextUntil: function( elem, i, until ) { + return jQuery.dir( elem, "nextSibling", until ); + }, + prevUntil: function( elem, i, until ) { + return jQuery.dir( elem, "previousSibling", until ); + }, + siblings: function( elem ) { + return jQuery.sibling( ( elem.parentNode || {} ).firstChild, elem ); + }, + children: function( elem ) { + return jQuery.sibling( elem.firstChild ); + }, + contents: function( elem ) { + return jQuery.nodeName( elem, "iframe" ) ? + elem.contentDocument || elem.contentWindow.document : + jQuery.merge( [], elem.childNodes ); + } +}, function( name, fn ) { + jQuery.fn[ name ] = function( until, selector ) { + var ret = jQuery.map( this, fn, until ); + + if ( name.slice( -5 ) !== "Until" ) { + selector = until; + } + + if ( selector && typeof selector === "string" ) { + ret = jQuery.filter( selector, ret ); + } + + if ( this.length > 1 ) { + // Remove duplicates + if ( !guaranteedUnique[ name ] ) { + ret = jQuery.unique( ret ); + } + + // Reverse order for parents* and prev-derivatives + if ( rparentsprev.test( name ) ) { + ret = ret.reverse(); + } + } + + return this.pushStack( ret ); + }; +}); +var rnotwhite = (/\S+/g); + + + // String to Object options format cache var optionsCache = {}; // Convert String-formatted options into Object-formatted ones and store in cache function createOptions( options ) { var object = optionsCache[ options ] = {}; - jQuery.each( options.match( core_rnotwhite ) || [], function( _, flag ) { + jQuery.each( options.match( rnotwhite ) || [], function( _, flag ) { object[ flag ] = true; }); return object; @@ -3101,7 +3152,7 @@ jQuery.Callbacks = function( options ) { if ( list ) { jQuery.each( arguments, function( _, arg ) { var index; - while( ( index = jQuery.inArray( arg, list, index ) ) > -1 ) { + while ( ( index = jQuery.inArray( arg, list, index ) ) > -1 ) { list.splice( index, 1 ); // Handle firing indexes if ( firing ) { @@ -3175,6 +3226,8 @@ jQuery.Callbacks = function( options ) { return self; }; + + jQuery.extend({ Deferred: function( func ) { @@ -3197,8 +3250,7 @@ jQuery.extend({ var fns = arguments; return jQuery.Deferred(function( newDefer ) { jQuery.each( tuples, function( i, tuple ) { - var action = tuple[ 0 ], - fn = jQuery.isFunction( fns[ i ] ) && fns[ i ]; + var fn = jQuery.isFunction( fns[ i ] ) && fns[ i ]; // deferred[ done | fail | progress ] for forwarding actions to newDefer deferred[ tuple[1] ](function() { var returned = fn && fn.apply( this, arguments ); @@ -3208,7 +3260,7 @@ jQuery.extend({ .fail( newDefer.reject ) .progress( newDefer.notify ); } else { - newDefer[ action + "With" ]( this === promise ? newDefer.promise() : this, fn ? [ returned ] : arguments ); + newDefer[ tuple[ 0 ] + "With" ]( this === promise ? newDefer.promise() : this, fn ? [ returned ] : arguments ); } }); }); @@ -3267,7 +3319,7 @@ jQuery.extend({ // Deferred helper when: function( subordinate /* , ..., subordinateN */ ) { var i = 0, - resolveValues = core_slice.call( arguments ), + resolveValues = slice.call( arguments ), length = resolveValues.length, // the count of uncompleted subordinates @@ -3280,10 +3332,11 @@ jQuery.extend({ updateFunc = function( i, contexts, values ) { return function( value ) { contexts[ i ] = this; - values[ i ] = arguments.length > 1 ? core_slice.call( arguments ) : value; - if( values === progressValues ) { + values[ i ] = arguments.length > 1 ? slice.call( arguments ) : value; + if ( values === progressValues ) { deferred.notifyWith( contexts, values ); - } else if ( !( --remaining ) ) { + + } else if ( !(--remaining) ) { deferred.resolveWith( contexts, values ); } }; @@ -3316,256 +3369,299 @@ jQuery.extend({ return deferred.promise(); } }); -jQuery.support = (function( support ) { - var all, a, input, select, fragment, opt, eventName, isSupported, i, - div = document.createElement("div"); - // Setup - div.setAttribute( "className", "t" ); - div.innerHTML = "
a"; +// The deferred used on DOM ready +var readyList; - // Finish early in limited (non-browser) environments - all = div.getElementsByTagName("*") || []; - a = div.getElementsByTagName("a")[ 0 ]; - if ( !a || !a.style || !all.length ) { - return support; - } +jQuery.fn.ready = function( fn ) { + // Add the callback + jQuery.ready.promise().done( fn ); - // First batch of tests - select = document.createElement("select"); - opt = select.appendChild( document.createElement("option") ); - input = div.getElementsByTagName("input")[ 0 ]; + return this; +}; - a.style.cssText = "top:1px;float:left;opacity:.5"; +jQuery.extend({ + // Is the DOM ready to be used? Set to true once it occurs. + isReady: false, - // Test setAttribute on camelCase class. If it works, we need attrFixes when doing get/setAttribute (ie6/7) - support.getSetAttribute = div.className !== "t"; + // A counter to track how many items to wait for before + // the ready event fires. See #6781 + readyWait: 1, - // IE strips leading whitespace when .innerHTML is used - support.leadingWhitespace = div.firstChild.nodeType === 3; + // Hold (or release) the ready event + holdReady: function( hold ) { + if ( hold ) { + jQuery.readyWait++; + } else { + jQuery.ready( true ); + } + }, - // Make sure that tbody elements aren't automatically inserted - // IE will insert them into empty tables - support.tbody = !div.getElementsByTagName("tbody").length; + // Handle when the DOM is ready + ready: function( wait ) { - // Make sure that link elements get serialized correctly by innerHTML - // This requires a wrapper element in IE - support.htmlSerialize = !!div.getElementsByTagName("link").length; - - // Get the style information from getAttribute - // (IE uses .cssText instead) - support.style = /top/.test( a.getAttribute("style") ); - - // Make sure that URLs aren't manipulated - // (IE normalizes it by default) - support.hrefNormalized = a.getAttribute("href") === "/a"; - - // Make sure that element opacity exists - // (IE uses filter instead) - // Use a regex to work around a WebKit issue. See #5145 - support.opacity = /^0.5/.test( a.style.opacity ); - - // Verify style float existence - // (IE uses styleFloat instead of cssFloat) - support.cssFloat = !!a.style.cssFloat; - - // Check the default checkbox/radio value ("" on WebKit; "on" elsewhere) - support.checkOn = !!input.value; - - // Make sure that a selected-by-default option has a working selected property. - // (WebKit defaults to false instead of true, IE too, if it's in an optgroup) - support.optSelected = opt.selected; - - // Tests for enctype support on a form (#6743) - support.enctype = !!document.createElement("form").enctype; - - // Makes sure cloning an html5 element does not cause problems - // Where outerHTML is undefined, this still works - support.html5Clone = document.createElement("nav").cloneNode( true ).outerHTML !== "<:nav>"; - - // Will be defined later - support.inlineBlockNeedsLayout = false; - support.shrinkWrapBlocks = false; - support.pixelPosition = false; - support.deleteExpando = true; - support.noCloneEvent = true; - support.reliableMarginRight = true; - support.boxSizingReliable = true; - - // Make sure checked status is properly cloned - input.checked = true; - support.noCloneChecked = input.cloneNode( true ).checked; - - // Make sure that the options inside disabled selects aren't marked as disabled - // (WebKit marks them as disabled) - select.disabled = true; - support.optDisabled = !opt.disabled; - - // Support: IE<9 - try { - delete div.test; - } catch( e ) { - support.deleteExpando = false; - } - - // Check if we can trust getAttribute("value") - input = document.createElement("input"); - input.setAttribute( "value", "" ); - support.input = input.getAttribute( "value" ) === ""; - - // Check if an input maintains its value after becoming a radio - input.value = "t"; - input.setAttribute( "type", "radio" ); - support.radioValue = input.value === "t"; - - // #11217 - WebKit loses check when the name is after the checked attribute - input.setAttribute( "checked", "t" ); - input.setAttribute( "name", "t" ); - - fragment = document.createDocumentFragment(); - fragment.appendChild( input ); - - // Check if a disconnected checkbox will retain its checked - // value of true after appended to the DOM (IE6/7) - support.appendChecked = input.checked; - - // WebKit doesn't clone checked state correctly in fragments - support.checkClone = fragment.cloneNode( true ).cloneNode( true ).lastChild.checked; - - // Support: IE<9 - // Opera does not clone events (and typeof div.attachEvent === undefined). - // IE9-10 clones events bound via attachEvent, but they don't trigger with .click() - if ( div.attachEvent ) { - div.attachEvent( "onclick", function() { - support.noCloneEvent = false; - }); - - div.cloneNode( true ).click(); - } - - // Support: IE<9 (lack submit/change bubble), Firefox 17+ (lack focusin event) - // Beware of CSP restrictions (https://developer.mozilla.org/en/Security/CSP) - for ( i in { submit: true, change: true, focusin: true }) { - div.setAttribute( eventName = "on" + i, "t" ); - - support[ i + "Bubbles" ] = eventName in window || div.attributes[ eventName ].expando === false; - } - - div.style.backgroundClip = "content-box"; - div.cloneNode( true ).style.backgroundClip = ""; - support.clearCloneStyle = div.style.backgroundClip === "content-box"; - - // Support: IE<9 - // Iteration over object's inherited properties before its own. - for ( i in jQuery( support ) ) { - break; - } - support.ownLast = i !== "0"; - - // Run tests that need a body at doc ready - jQuery(function() { - var container, marginDiv, tds, - divReset = "padding:0;margin:0;border:0;display:block;box-sizing:content-box;-moz-box-sizing:content-box;-webkit-box-sizing:content-box;", - body = document.getElementsByTagName("body")[0]; - - if ( !body ) { - // Return for frameset docs that don't have a body + // Abort if there are pending holds or we're already ready + if ( wait === true ? --jQuery.readyWait : jQuery.isReady ) { return; } - container = document.createElement("div"); - container.style.cssText = "border:0;width:0;height:0;position:absolute;top:0;left:-9999px;margin-top:1px"; - - body.appendChild( container ).appendChild( div ); - - // Support: IE8 - // Check if table cells still have offsetWidth/Height when they are set - // to display:none and there are still other visible table cells in a - // table row; if so, offsetWidth/Height are not reliable for use when - // determining if an element has been hidden directly using - // display:none (it is still safe to use offsets if a parent element is - // hidden; don safety goggles and see bug #4512 for more information). - div.innerHTML = "
t
"; - tds = div.getElementsByTagName("td"); - tds[ 0 ].style.cssText = "padding:0;margin:0;border:0;display:none"; - isSupported = ( tds[ 0 ].offsetHeight === 0 ); - - tds[ 0 ].style.display = ""; - tds[ 1 ].style.display = "none"; - - // Support: IE8 - // Check if empty table cells still have offsetWidth/Height - support.reliableHiddenOffsets = isSupported && ( tds[ 0 ].offsetHeight === 0 ); - - // Check box-sizing and margin behavior. - div.innerHTML = ""; - div.style.cssText = "box-sizing:border-box;-moz-box-sizing:border-box;-webkit-box-sizing:border-box;padding:1px;border:1px;display:block;width:4px;margin-top:1%;position:absolute;top:1%;"; - - // Workaround failing boxSizing test due to offsetWidth returning wrong value - // with some non-1 values of body zoom, ticket #13543 - jQuery.swap( body, body.style.zoom != null ? { zoom: 1 } : {}, function() { - support.boxSizing = div.offsetWidth === 4; - }); - - // Use window.getComputedStyle because jsdom on node.js will break without it. - if ( window.getComputedStyle ) { - support.pixelPosition = ( window.getComputedStyle( div, null ) || {} ).top !== "1%"; - support.boxSizingReliable = ( window.getComputedStyle( div, null ) || { width: "4px" } ).width === "4px"; - - // Check if div with explicit width and no margin-right incorrectly - // gets computed margin-right based on width of container. (#3333) - // Fails in WebKit before Feb 2011 nightlies - // WebKit Bug 13343 - getComputedStyle returns wrong value for margin-right - marginDiv = div.appendChild( document.createElement("div") ); - marginDiv.style.cssText = div.style.cssText = divReset; - marginDiv.style.marginRight = marginDiv.style.width = "0"; - div.style.width = "1px"; - - support.reliableMarginRight = - !parseFloat( ( window.getComputedStyle( marginDiv, null ) || {} ).marginRight ); + // Make sure body exists, at least, in case IE gets a little overzealous (ticket #5443). + if ( !document.body ) { + return setTimeout( jQuery.ready ); } - if ( typeof div.style.zoom !== core_strundefined ) { - // Support: IE<8 - // Check if natively block-level elements act like inline-block - // elements when setting their display to 'inline' and giving - // them layout - div.innerHTML = ""; - div.style.cssText = divReset + "width:1px;padding:1px;display:inline;zoom:1"; - support.inlineBlockNeedsLayout = ( div.offsetWidth === 3 ); + // Remember that the DOM is ready + jQuery.isReady = true; - // Support: IE6 - // Check if elements with layout shrink-wrap their children - div.style.display = "block"; - div.innerHTML = "
"; - div.firstChild.style.width = "5px"; - support.shrinkWrapBlocks = ( div.offsetWidth !== 3 ); + // If a normal DOM Ready event fired, decrement, and wait if need be + if ( wait !== true && --jQuery.readyWait > 0 ) { + return; + } - if ( support.inlineBlockNeedsLayout ) { - // Prevent IE 6 from affecting layout for positioned elements #11048 - // Prevent IE from shrinking the body in IE 7 mode #12869 - // Support: IE<8 - body.style.zoom = 1; + // If there are functions bound, to execute + readyList.resolveWith( document, [ jQuery ] ); + + // Trigger any bound ready events + if ( jQuery.fn.trigger ) { + jQuery( document ).trigger("ready").off("ready"); + } + } +}); + +/** + * Clean-up method for dom ready events + */ +function detach() { + if ( document.addEventListener ) { + document.removeEventListener( "DOMContentLoaded", completed, false ); + window.removeEventListener( "load", completed, false ); + + } else { + document.detachEvent( "onreadystatechange", completed ); + window.detachEvent( "onload", completed ); + } +} + +/** + * The ready event handler and self cleanup method + */ +function completed() { + // readyState === "complete" is good enough for us to call the dom ready in oldIE + if ( document.addEventListener || event.type === "load" || document.readyState === "complete" ) { + detach(); + jQuery.ready(); + } +} + +jQuery.ready.promise = function( obj ) { + if ( !readyList ) { + + readyList = jQuery.Deferred(); + + // Catch cases where $(document).ready() is called after the browser event has already occurred. + // we once tried to use readyState "interactive" here, but it caused issues like the one + // discovered by ChrisS here: http://bugs.jquery.com/ticket/12282#comment:15 + if ( document.readyState === "complete" ) { + // Handle it asynchronously to allow scripts the opportunity to delay ready + setTimeout( jQuery.ready ); + + // Standards-based browsers support DOMContentLoaded + } else if ( document.addEventListener ) { + // Use the handy event callback + document.addEventListener( "DOMContentLoaded", completed, false ); + + // A fallback to window.onload, that will always work + window.addEventListener( "load", completed, false ); + + // If IE event model is used + } else { + // Ensure firing before onload, maybe late but safe also for iframes + document.attachEvent( "onreadystatechange", completed ); + + // A fallback to window.onload, that will always work + window.attachEvent( "onload", completed ); + + // If IE and not a frame + // continually check to see if the document is ready + var top = false; + + try { + top = window.frameElement == null && document.documentElement; + } catch(e) {} + + if ( top && top.doScroll ) { + (function doScrollCheck() { + if ( !jQuery.isReady ) { + + try { + // Use the trick by Diego Perini + // http://javascript.nwbox.com/IEContentLoaded/ + top.doScroll("left"); + } catch(e) { + return setTimeout( doScrollCheck, 50 ); + } + + // detach all dom ready events + detach(); + + // and execute any waiting functions + jQuery.ready(); + } + })(); } } + } + return readyList.promise( obj ); +}; - body.removeChild( container ); - // Null elements to avoid leaks in IE - container = div = tds = marginDiv = null; - }); +var strundefined = typeof undefined; + + + +// Support: IE<9 +// Iteration over object's inherited properties before its own +var i; +for ( i in jQuery( support ) ) { + break; +} +support.ownLast = i !== "0"; + +// Note: most support tests are defined in their respective modules. +// false until the test is run +support.inlineBlockNeedsLayout = false; + +jQuery(function() { + // We need to execute this one support test ASAP because we need to know + // if body.style.zoom needs to be set. + + var container, div, + body = document.getElementsByTagName("body")[0]; + + if ( !body ) { + // Return for frameset docs that don't have a body + return; + } + + // Setup + container = document.createElement( "div" ); + container.style.cssText = "border:0;width:0;height:0;position:absolute;top:0;left:-9999px;margin-top:1px"; + + div = document.createElement( "div" ); + body.appendChild( container ).appendChild( div ); + + if ( typeof div.style.zoom !== strundefined ) { + // Support: IE<8 + // Check if natively block-level elements act like inline-block + // elements when setting their display to 'inline' and giving + // them layout + div.style.cssText = "border:0;margin:0;width:1px;padding:1px;display:inline;zoom:1"; + + if ( (support.inlineBlockNeedsLayout = ( div.offsetWidth === 3 )) ) { + // Prevent IE 6 from affecting layout for positioned elements #11048 + // Prevent IE from shrinking the body in IE 7 mode #12869 + // Support: IE<8 + body.style.zoom = 1; + } + } + + body.removeChild( container ); // Null elements to avoid leaks in IE - all = select = fragment = opt = a = input = null; + container = div = null; +}); - return support; -})({}); -var rbrace = /(?:\{[\s\S]*\}|\[[\s\S]*\])$/, + + +(function() { + var div = document.createElement( "div" ); + + // Execute the test only if not already executed in another module. + if (support.deleteExpando == null) { + // Support: IE<9 + support.deleteExpando = true; + try { + delete div.test; + } catch( e ) { + support.deleteExpando = false; + } + } + + // Null elements to avoid leaks in IE. + div = null; +})(); + + +/** + * Determines whether an object can have data + */ +jQuery.acceptData = function( elem ) { + var noData = jQuery.noData[ (elem.nodeName + " ").toLowerCase() ], + nodeType = +elem.nodeType || 1; + + // Do not set data on non-element DOM nodes because it will not be cleared (#8335). + return nodeType !== 1 && nodeType !== 9 ? + false : + + // Nodes accept data unless otherwise specified; rejection can be conditional + !noData || noData !== true && elem.getAttribute("classid") === noData; +}; + + +var rbrace = /^(?:\{[\w\W]*\}|\[[\w\W]*\])$/, rmultiDash = /([A-Z])/g; -function internalData( elem, name, data, pvt /* Internal Use Only */ ){ +function dataAttr( elem, key, data ) { + // If nothing was found internally, try to fetch any + // data from the HTML5 data-* attribute + if ( data === undefined && elem.nodeType === 1 ) { + + var name = "data-" + key.replace( rmultiDash, "-$1" ).toLowerCase(); + + data = elem.getAttribute( name ); + + if ( typeof data === "string" ) { + try { + data = data === "true" ? true : + data === "false" ? false : + data === "null" ? null : + // Only convert to a number if it doesn't change the string + +data + "" === data ? +data : + rbrace.test( data ) ? jQuery.parseJSON( data ) : + data; + } catch( e ) {} + + // Make sure we set the data so it isn't changed later + jQuery.data( elem, key, data ); + + } else { + data = undefined; + } + } + + return data; +} + +// checks a cache object for emptiness +function isEmptyDataObject( obj ) { + var name; + for ( name in obj ) { + + // if the public data object is empty, the private is still empty + if ( name === "data" && jQuery.isEmptyObject( obj[name] ) ) { + continue; + } + if ( name !== "toJSON" ) { + return false; + } + } + + return true; +} + +function internalData( elem, name, data, pvt /* Internal Use Only */ ) { if ( !jQuery.acceptData( elem ) ) { return; } @@ -3595,7 +3691,7 @@ function internalData( elem, name, data, pvt /* Internal Use Only */ ){ // Only DOM nodes need a new unique ID for each element since their data // ends up in the global cache if ( isNode ) { - id = elem[ internalKey ] = core_deletedIds.pop() || jQuery.guid++; + id = elem[ internalKey ] = deletedIds.pop() || jQuery.guid++; } else { id = internalKey; } @@ -3734,7 +3830,7 @@ function internalRemoveData( elem, name, pvt ) { // Use delete when supported for expandos or `cache` is not a window per isWindow (#10080) /* jshint eqeqeq: false */ - } else if ( jQuery.support.deleteExpando || cache != cache.window ) { + } else if ( support.deleteExpando || cache != cache.window ) { /* jshint eqeqeq: true */ delete cache[ id ]; @@ -3747,13 +3843,13 @@ function internalRemoveData( elem, name, pvt ) { jQuery.extend({ cache: {}, - // The following elements throw uncatchable exceptions if you - // attempt to add expando properties to them. + // The following elements (space-suffixed to avoid Object.prototype collisions) + // throw uncatchable exceptions if you attempt to set expando properties noData: { - "applet": true, - "embed": true, - // Ban all objects except for Flash (which handle expandos) - "object": "clsid:D27CDB6E-AE6D-11cf-96B8-444553540000" + "applet ": true, + "embed ": true, + // ...but Flash objects (which have this classid) *can* handle expandos + "object ": "clsid:D27CDB6E-AE6D-11cf-96B8-444553540000" }, hasData: function( elem ) { @@ -3776,28 +3872,14 @@ jQuery.extend({ _removeData: function( elem, name ) { return internalRemoveData( elem, name, true ); - }, - - // A method for determining if a DOM node can handle the data expando - acceptData: function( elem ) { - // Do not set data on non-element because it will not be cleared (#8335). - if ( elem.nodeType && elem.nodeType !== 1 && elem.nodeType !== 9 ) { - return false; - } - - var noData = elem.nodeName && jQuery.noData[ elem.nodeName.toLowerCase() ]; - - // nodes accept data unless otherwise specified; rejection can be conditional - return !noData || noData !== true && elem.getAttribute("classid") === noData; } }); jQuery.fn.extend({ data: function( key, value ) { - var attrs, name, - data = null, - i = 0, - elem = this[0]; + var i, name, data, + elem = this[0], + attrs = elem && elem.attributes; // Special expections of .data basically thwart jQuery.access, // so implement the relevant behavior ourselves @@ -3808,8 +3890,8 @@ jQuery.fn.extend({ data = jQuery.data( elem ); if ( elem.nodeType === 1 && !jQuery._data( elem, "parsedAttrs" ) ) { - attrs = elem.attributes; - for ( ; i < attrs.length; i++ ) { + i = attrs.length; + while ( i-- ) { name = attrs[i].name; if ( name.indexOf("data-") === 0 ) { @@ -3841,7 +3923,7 @@ jQuery.fn.extend({ // Gets one value // Try to fetch any internally stored data first - elem ? dataAttr( elem, key, jQuery.data( elem, key ) ) : null; + elem ? dataAttr( elem, key, jQuery.data( elem, key ) ) : undefined; }, removeData: function( key ) { @@ -3851,53 +3933,7 @@ jQuery.fn.extend({ } }); -function dataAttr( elem, key, data ) { - // If nothing was found internally, try to fetch any - // data from the HTML5 data-* attribute - if ( data === undefined && elem.nodeType === 1 ) { - var name = "data-" + key.replace( rmultiDash, "-$1" ).toLowerCase(); - - data = elem.getAttribute( name ); - - if ( typeof data === "string" ) { - try { - data = data === "true" ? true : - data === "false" ? false : - data === "null" ? null : - // Only convert to a number if it doesn't change the string - +data + "" === data ? +data : - rbrace.test( data ) ? jQuery.parseJSON( data ) : - data; - } catch( e ) {} - - // Make sure we set the data so it isn't changed later - jQuery.data( elem, key, data ); - - } else { - data = undefined; - } - } - - return data; -} - -// checks a cache object for emptiness -function isEmptyDataObject( obj ) { - var name; - for ( name in obj ) { - - // if the public data object is empty, the private is still empty - if ( name === "data" && jQuery.isEmptyObject( obj[name] ) ) { - continue; - } - if ( name !== "toJSON" ) { - return false; - } - } - - return true; -} jQuery.extend({ queue: function( elem, type, data ) { var queue; @@ -3997,19 +4033,6 @@ jQuery.fn.extend({ jQuery.dequeue( this, type ); }); }, - // Based off of the plugin by Clint Helfers, with permission. - // http://blindsignals.com/index.php/2009/07/jquery-delay/ - delay: function( time, type ) { - time = jQuery.fx ? jQuery.fx.speeds[ time ] || time : time; - type = type || "fx"; - - return this.queue( type, function( next, hooks ) { - var timeout = setTimeout( next, time ); - hooks.stop = function() { - clearTimeout( timeout ); - }; - }); - }, clearQueue: function( type ) { return this.queue( type || "fx", [] ); }, @@ -4033,7 +4056,7 @@ jQuery.fn.extend({ } type = type || "fx"; - while( i-- ) { + while ( i-- ) { tmp = jQuery._data( elements[ i ], type + "queueHooks" ); if ( tmp && tmp.empty ) { count++; @@ -4044,665 +4067,168 @@ jQuery.fn.extend({ return defer.promise( obj ); } }); -var nodeHook, boolHook, - rclass = /[\t\r\n\f]/g, - rreturn = /\r/g, - rfocusable = /^(?:input|select|textarea|button|object)$/i, - rclickable = /^(?:a|area)$/i, - ruseDefault = /^(?:checked|selected)$/i, - getSetAttribute = jQuery.support.getSetAttribute, - getSetInput = jQuery.support.input; +var pnum = (/[+-]?(?:\d*\.|)\d+(?:[eE][+-]?\d+|)/).source; -jQuery.fn.extend({ - attr: function( name, value ) { - return jQuery.access( this, jQuery.attr, name, value, arguments.length > 1 ); - }, +var cssExpand = [ "Top", "Right", "Bottom", "Left" ]; - removeAttr: function( name ) { - return this.each(function() { - jQuery.removeAttr( this, name ); - }); - }, +var isHidden = function( elem, el ) { + // isHidden might be called from jQuery#filter function; + // in that case, element will be second argument + elem = el || elem; + return jQuery.css( elem, "display" ) === "none" || !jQuery.contains( elem.ownerDocument, elem ); + }; - prop: function( name, value ) { - return jQuery.access( this, jQuery.prop, name, value, arguments.length > 1 ); - }, - removeProp: function( name ) { - name = jQuery.propFix[ name ] || name; - return this.each(function() { - // try/catch handles cases where IE balks (such as removing a property on window) - try { - this[ name ] = undefined; - delete this[ name ]; - } catch( e ) {} - }); - }, - addClass: function( value ) { - var classes, elem, cur, clazz, j, - i = 0, - len = this.length, - proceed = typeof value === "string" && value; +// Multifunctional method to get and set values of a collection +// The value/s can optionally be executed if it's a function +var access = jQuery.access = function( elems, fn, key, value, chainable, emptyGet, raw ) { + var i = 0, + length = elems.length, + bulk = key == null; - if ( jQuery.isFunction( value ) ) { - return this.each(function( j ) { - jQuery( this ).addClass( value.call( this, j, this.className ) ); - }); + // Sets many values + if ( jQuery.type( key ) === "object" ) { + chainable = true; + for ( i in key ) { + jQuery.access( elems, fn, i, key[i], true, emptyGet, raw ); } - if ( proceed ) { - // The disjunction here is for better compressibility (see removeClass) - classes = ( value || "" ).match( core_rnotwhite ) || []; + // Sets one value + } else if ( value !== undefined ) { + chainable = true; - for ( ; i < len; i++ ) { - elem = this[ i ]; - cur = elem.nodeType === 1 && ( elem.className ? - ( " " + elem.className + " " ).replace( rclass, " " ) : - " " - ); - - if ( cur ) { - j = 0; - while ( (clazz = classes[j++]) ) { - if ( cur.indexOf( " " + clazz + " " ) < 0 ) { - cur += clazz + " "; - } - } - elem.className = jQuery.trim( cur ); - - } - } + if ( !jQuery.isFunction( value ) ) { + raw = true; } - return this; - }, + if ( bulk ) { + // Bulk operations run against the entire set + if ( raw ) { + fn.call( elems, value ); + fn = null; - removeClass: function( value ) { - var classes, elem, cur, clazz, j, - i = 0, - len = this.length, - proceed = arguments.length === 0 || typeof value === "string" && value; - - if ( jQuery.isFunction( value ) ) { - return this.each(function( j ) { - jQuery( this ).removeClass( value.call( this, j, this.className ) ); - }); - } - if ( proceed ) { - classes = ( value || "" ).match( core_rnotwhite ) || []; - - for ( ; i < len; i++ ) { - elem = this[ i ]; - // This expression is here for better compressibility (see addClass) - cur = elem.nodeType === 1 && ( elem.className ? - ( " " + elem.className + " " ).replace( rclass, " " ) : - "" - ); - - if ( cur ) { - j = 0; - while ( (clazz = classes[j++]) ) { - // Remove *all* instances - while ( cur.indexOf( " " + clazz + " " ) >= 0 ) { - cur = cur.replace( " " + clazz + " ", " " ); - } - } - elem.className = value ? jQuery.trim( cur ) : ""; - } - } - } - - return this; - }, - - toggleClass: function( value, stateVal ) { - var type = typeof value; - - if ( typeof stateVal === "boolean" && type === "string" ) { - return stateVal ? this.addClass( value ) : this.removeClass( value ); - } - - if ( jQuery.isFunction( value ) ) { - return this.each(function( i ) { - jQuery( this ).toggleClass( value.call(this, i, this.className, stateVal), stateVal ); - }); - } - - return this.each(function() { - if ( type === "string" ) { - // toggle individual class names - var className, - i = 0, - self = jQuery( this ), - classNames = value.match( core_rnotwhite ) || []; - - while ( (className = classNames[ i++ ]) ) { - // check each className given, space separated list - if ( self.hasClass( className ) ) { - self.removeClass( className ); - } else { - self.addClass( className ); - } - } - - // Toggle whole class name - } else if ( type === core_strundefined || type === "boolean" ) { - if ( this.className ) { - // store className if set - jQuery._data( this, "__className__", this.className ); - } - - // If the element has a class name or if we're passed "false", - // then remove the whole classname (if there was one, the above saved it). - // Otherwise bring back whatever was previously saved (if anything), - // falling back to the empty string if nothing was stored. - this.className = this.className || value === false ? "" : jQuery._data( this, "__className__" ) || ""; - } - }); - }, - - hasClass: function( selector ) { - var className = " " + selector + " ", - i = 0, - l = this.length; - for ( ; i < l; i++ ) { - if ( this[i].nodeType === 1 && (" " + this[i].className + " ").replace(rclass, " ").indexOf( className ) >= 0 ) { - return true; - } - } - - return false; - }, - - val: function( value ) { - var ret, hooks, isFunction, - elem = this[0]; - - if ( !arguments.length ) { - if ( elem ) { - hooks = jQuery.valHooks[ elem.type ] || jQuery.valHooks[ elem.nodeName.toLowerCase() ]; - - if ( hooks && "get" in hooks && (ret = hooks.get( elem, "value" )) !== undefined ) { - return ret; - } - - ret = elem.value; - - return typeof ret === "string" ? - // handle most common string cases - ret.replace(rreturn, "") : - // handle cases where value is null/undef or number - ret == null ? "" : ret; - } - - return; - } - - isFunction = jQuery.isFunction( value ); - - return this.each(function( i ) { - var val; - - if ( this.nodeType !== 1 ) { - return; - } - - if ( isFunction ) { - val = value.call( this, i, jQuery( this ).val() ); + // ...except when executing function values } else { - val = value; - } - - // Treat null/undefined as ""; convert numbers to string - if ( val == null ) { - val = ""; - } else if ( typeof val === "number" ) { - val += ""; - } else if ( jQuery.isArray( val ) ) { - val = jQuery.map(val, function ( value ) { - return value == null ? "" : value + ""; - }); - } - - hooks = jQuery.valHooks[ this.type ] || jQuery.valHooks[ this.nodeName.toLowerCase() ]; - - // If set returns undefined, fall back to normal setting - if ( !hooks || !("set" in hooks) || hooks.set( this, val, "value" ) === undefined ) { - this.value = val; - } - }); - } -}); - -jQuery.extend({ - valHooks: { - option: { - get: function( elem ) { - // Use proper attribute retrieval(#6932, #12072) - var val = jQuery.find.attr( elem, "value" ); - return val != null ? - val : - elem.text; - } - }, - select: { - get: function( elem ) { - var value, option, - options = elem.options, - index = elem.selectedIndex, - one = elem.type === "select-one" || index < 0, - values = one ? null : [], - max = one ? index + 1 : options.length, - i = index < 0 ? - max : - one ? index : 0; - - // Loop through all the selected options - for ( ; i < max; i++ ) { - option = options[ i ]; - - // oldIE doesn't update selected after form reset (#2551) - if ( ( option.selected || i === index ) && - // Don't return options that are disabled or in a disabled optgroup - ( jQuery.support.optDisabled ? !option.disabled : option.getAttribute("disabled") === null ) && - ( !option.parentNode.disabled || !jQuery.nodeName( option.parentNode, "optgroup" ) ) ) { - - // Get the specific value for the option - value = jQuery( option ).val(); - - // We don't need an array for one selects - if ( one ) { - return value; - } - - // Multi-Selects return an array - values.push( value ); - } - } - - return values; - }, - - set: function( elem, value ) { - var optionSet, option, - options = elem.options, - values = jQuery.makeArray( value ), - i = options.length; - - while ( i-- ) { - option = options[ i ]; - if ( (option.selected = jQuery.inArray( jQuery(option).val(), values ) >= 0) ) { - optionSet = true; - } - } - - // force browsers to behave consistently when non-matching value is set - if ( !optionSet ) { - elem.selectedIndex = -1; - } - return values; + bulk = fn; + fn = function( elem, key, value ) { + return bulk.call( jQuery( elem ), value ); + }; } } - }, - attr: function( elem, name, value ) { - var hooks, ret, - nType = elem.nodeType; - - // don't get/set attributes on text, comment and attribute nodes - if ( !elem || nType === 3 || nType === 8 || nType === 2 ) { - return; - } - - // Fallback to prop when attributes are not supported - if ( typeof elem.getAttribute === core_strundefined ) { - return jQuery.prop( elem, name, value ); - } - - // All attributes are lowercase - // Grab necessary hook if one is defined - if ( nType !== 1 || !jQuery.isXMLDoc( elem ) ) { - name = name.toLowerCase(); - hooks = jQuery.attrHooks[ name ] || - ( jQuery.expr.match.bool.test( name ) ? boolHook : nodeHook ); - } - - if ( value !== undefined ) { - - if ( value === null ) { - jQuery.removeAttr( elem, name ); - - } else if ( hooks && "set" in hooks && (ret = hooks.set( elem, value, name )) !== undefined ) { - return ret; - - } else { - elem.setAttribute( name, value + "" ); - return value; - } - - } else if ( hooks && "get" in hooks && (ret = hooks.get( elem, name )) !== null ) { - return ret; - - } else { - ret = jQuery.find.attr( elem, name ); - - // Non-existent attributes return null, we normalize to undefined - return ret == null ? - undefined : - ret; - } - }, - - removeAttr: function( elem, value ) { - var name, propName, - i = 0, - attrNames = value && value.match( core_rnotwhite ); - - if ( attrNames && elem.nodeType === 1 ) { - while ( (name = attrNames[i++]) ) { - propName = jQuery.propFix[ name ] || name; - - // Boolean attributes get special treatment (#10870) - if ( jQuery.expr.match.bool.test( name ) ) { - // Set corresponding property to false - if ( getSetInput && getSetAttribute || !ruseDefault.test( name ) ) { - elem[ propName ] = false; - // Support: IE<9 - // Also clear defaultChecked/defaultSelected (if appropriate) - } else { - elem[ jQuery.camelCase( "default-" + name ) ] = - elem[ propName ] = false; - } - - // See #9699 for explanation of this approach (setting first, then removal) - } else { - jQuery.attr( elem, name, "" ); - } - - elem.removeAttribute( getSetAttribute ? name : propName ); - } - } - }, - - attrHooks: { - type: { - set: function( elem, value ) { - if ( !jQuery.support.radioValue && value === "radio" && jQuery.nodeName(elem, "input") ) { - // Setting the type on a radio button after the value resets the value in IE6-9 - // Reset value to default in case type is set after value during creation - var val = elem.value; - elem.setAttribute( "type", value ); - if ( val ) { - elem.value = val; - } - return value; - } - } - } - }, - - propFix: { - "for": "htmlFor", - "class": "className" - }, - - prop: function( elem, name, value ) { - var ret, hooks, notxml, - nType = elem.nodeType; - - // don't get/set properties on text, comment and attribute nodes - if ( !elem || nType === 3 || nType === 8 || nType === 2 ) { - return; - } - - notxml = nType !== 1 || !jQuery.isXMLDoc( elem ); - - if ( notxml ) { - // Fix name and attach hooks - name = jQuery.propFix[ name ] || name; - hooks = jQuery.propHooks[ name ]; - } - - if ( value !== undefined ) { - return hooks && "set" in hooks && (ret = hooks.set( elem, value, name )) !== undefined ? - ret : - ( elem[ name ] = value ); - - } else { - return hooks && "get" in hooks && (ret = hooks.get( elem, name )) !== null ? - ret : - elem[ name ]; - } - }, - - propHooks: { - tabIndex: { - get: function( elem ) { - // elem.tabIndex doesn't always return the correct value when it hasn't been explicitly set - // http://fluidproject.org/blog/2008/01/09/getting-setting-and-removing-tabindex-values-with-javascript/ - // Use proper attribute retrieval(#12072) - var tabindex = jQuery.find.attr( elem, "tabindex" ); - - return tabindex ? - parseInt( tabindex, 10 ) : - rfocusable.test( elem.nodeName ) || rclickable.test( elem.nodeName ) && elem.href ? - 0 : - -1; + if ( fn ) { + for ( ; i < length; i++ ) { + fn( elems[i], key, raw ? value : value.call( elems[i], i, fn( elems[i], key ) ) ); } } } -}); -// Hooks for boolean attributes -boolHook = { - set: function( elem, value, name ) { - if ( value === false ) { - // Remove boolean attributes when set to false - jQuery.removeAttr( elem, name ); - } else if ( getSetInput && getSetAttribute || !ruseDefault.test( name ) ) { - // IE<8 needs the *property* name - elem.setAttribute( !getSetAttribute && jQuery.propFix[ name ] || name, name ); + return chainable ? + elems : - // Use defaultChecked and defaultSelected for oldIE - } else { - elem[ jQuery.camelCase( "default-" + name ) ] = elem[ name ] = true; - } - - return name; - } + // Gets + bulk ? + fn.call( elems ) : + length ? fn( elems[0], key ) : emptyGet; }; -jQuery.each( jQuery.expr.match.bool.source.match( /\w+/g ), function( i, name ) { - var getter = jQuery.expr.attrHandle[ name ] || jQuery.find.attr; - - jQuery.expr.attrHandle[ name ] = getSetInput && getSetAttribute || !ruseDefault.test( name ) ? - function( elem, name, isXML ) { - var fn = jQuery.expr.attrHandle[ name ], - ret = isXML ? - undefined : - /* jshint eqeqeq: false */ - (jQuery.expr.attrHandle[ name ] = undefined) != - getter( elem, name, isXML ) ? - - name.toLowerCase() : - null; - jQuery.expr.attrHandle[ name ] = fn; - return ret; - } : - function( elem, name, isXML ) { - return isXML ? - undefined : - elem[ jQuery.camelCase( "default-" + name ) ] ? - name.toLowerCase() : - null; - }; -}); - -// fix oldIE attroperties -if ( !getSetInput || !getSetAttribute ) { - jQuery.attrHooks.value = { - set: function( elem, value, name ) { - if ( jQuery.nodeName( elem, "input" ) ) { - // Does not return so that setAttribute is also used - elem.defaultValue = value; - } else { - // Use nodeHook if defined (#1954); otherwise setAttribute is fine - return nodeHook && nodeHook.set( elem, value, name ); - } - } - }; -} - -// IE6/7 do not support getting/setting some attributes with get/setAttribute -if ( !getSetAttribute ) { - - // Use this for any attribute in IE6/7 - // This fixes almost every IE6/7 issue - nodeHook = { - set: function( elem, value, name ) { - // Set the existing or create a new attribute node - var ret = elem.getAttributeNode( name ); - if ( !ret ) { - elem.setAttributeNode( - (ret = elem.ownerDocument.createAttribute( name )) - ); - } - - ret.value = value += ""; - - // Break association with cloned elements by also using setAttribute (#9646) - return name === "value" || value === elem.getAttribute( name ) ? - value : - undefined; - } - }; - jQuery.expr.attrHandle.id = jQuery.expr.attrHandle.name = jQuery.expr.attrHandle.coords = - // Some attributes are constructed with empty-string values when not defined - function( elem, name, isXML ) { - var ret; - return isXML ? - undefined : - (ret = elem.getAttributeNode( name )) && ret.value !== "" ? - ret.value : - null; - }; - jQuery.valHooks.button = { - get: function( elem, name ) { - var ret = elem.getAttributeNode( name ); - return ret && ret.specified ? - ret.value : - undefined; - }, - set: nodeHook.set - }; - - // Set contenteditable to false on removals(#10429) - // Setting to empty string throws an error as an invalid value - jQuery.attrHooks.contenteditable = { - set: function( elem, value, name ) { - nodeHook.set( elem, value === "" ? false : value, name ); - } - }; - - // Set width and height to auto instead of 0 on empty string( Bug #8150 ) - // This is for removals - jQuery.each([ "width", "height" ], function( i, name ) { - jQuery.attrHooks[ name ] = { - set: function( elem, value ) { - if ( value === "" ) { - elem.setAttribute( name, "auto" ); - return value; - } - } - }; - }); -} +var rcheckableType = (/^(?:checkbox|radio)$/i); -// Some attributes require a special call on IE -// http://msdn.microsoft.com/en-us/library/ms536429%28VS.85%29.aspx -if ( !jQuery.support.hrefNormalized ) { - // href/src property should get the full normalized URL (#10299/#12915) - jQuery.each([ "href", "src" ], function( i, name ) { - jQuery.propHooks[ name ] = { - get: function( elem ) { - return elem.getAttribute( name, 4 ); - } - }; - }); -} -if ( !jQuery.support.style ) { - jQuery.attrHooks.style = { - get: function( elem ) { - // Return undefined in the case of empty string - // Note: IE uppercases css property names, but if we were to .toLowerCase() - // .cssText, that would destroy case senstitivity in URL's, like in "background" - return elem.style.cssText || undefined; - }, - set: function( elem, value ) { - return ( elem.style.cssText = value + "" ); - } - }; -} +(function() { + var fragment = document.createDocumentFragment(), + div = document.createElement("div"), + input = document.createElement("input"); -// Safari mis-reports the default selected property of an option -// Accessing the parent's selectedIndex property fixes it -if ( !jQuery.support.optSelected ) { - jQuery.propHooks.selected = { - get: function( elem ) { - var parent = elem.parentNode; + // Setup + div.setAttribute( "className", "t" ); + div.innerHTML = "
a"; - if ( parent ) { - parent.selectedIndex; + // IE strips leading whitespace when .innerHTML is used + support.leadingWhitespace = div.firstChild.nodeType === 3; - // Make sure that it also works with optgroups, see #5701 - if ( parent.parentNode ) { - parent.parentNode.selectedIndex; - } - } - return null; - } - }; -} + // Make sure that tbody elements aren't automatically inserted + // IE will insert them into empty tables + support.tbody = !div.getElementsByTagName( "tbody" ).length; -jQuery.each([ - "tabIndex", - "readOnly", - "maxLength", - "cellSpacing", - "cellPadding", - "rowSpan", - "colSpan", - "useMap", - "frameBorder", - "contentEditable" -], function() { - jQuery.propFix[ this.toLowerCase() ] = this; -}); + // Make sure that link elements get serialized correctly by innerHTML + // This requires a wrapper element in IE + support.htmlSerialize = !!div.getElementsByTagName( "link" ).length; -// IE6/7 call enctype encoding -if ( !jQuery.support.enctype ) { - jQuery.propFix.enctype = "encoding"; -} + // Makes sure cloning an html5 element does not cause problems + // Where outerHTML is undefined, this still works + support.html5Clone = + document.createElement( "nav" ).cloneNode( true ).outerHTML !== "<:nav>"; -// Radios and checkboxes getter/setter -jQuery.each([ "radio", "checkbox" ], function() { - jQuery.valHooks[ this ] = { - set: function( elem, value ) { - if ( jQuery.isArray( value ) ) { - return ( elem.checked = jQuery.inArray( jQuery(elem).val(), value ) >= 0 ); - } - } - }; - if ( !jQuery.support.checkOn ) { - jQuery.valHooks[ this ].get = function( elem ) { - // Support: Webkit - // "" is returned instead of "on" if a value isn't specified - return elem.getAttribute("value") === null ? "on" : elem.value; - }; + // Check if a disconnected checkbox will retain its checked + // value of true after appended to the DOM (IE6/7) + input.type = "checkbox"; + input.checked = true; + fragment.appendChild( input ); + support.appendChecked = input.checked; + + // Make sure textarea (and checkbox) defaultValue is properly cloned + // Support: IE6-IE11+ + div.innerHTML = ""; + support.noCloneChecked = !!div.cloneNode( true ).lastChild.defaultValue; + + // #11217 - WebKit loses check when the name is after the checked attribute + fragment.appendChild( div ); + div.innerHTML = ""; + + // Support: Safari 5.1, iOS 5.1, Android 4.x, Android 2.3 + // old WebKit doesn't clone checked state correctly in fragments + support.checkClone = div.cloneNode( true ).cloneNode( true ).lastChild.checked; + + // Support: IE<9 + // Opera does not clone events (and typeof div.attachEvent === undefined). + // IE9-10 clones events bound via attachEvent, but they don't trigger with .click() + support.noCloneEvent = true; + if ( div.attachEvent ) { + div.attachEvent( "onclick", function() { + support.noCloneEvent = false; + }); + + div.cloneNode( true ).click(); } -}); + + // Execute the test only if not already executed in another module. + if (support.deleteExpando == null) { + // Support: IE<9 + support.deleteExpando = true; + try { + delete div.test; + } catch( e ) { + support.deleteExpando = false; + } + } + + // Null elements to avoid leaks in IE. + fragment = div = input = null; +})(); + + +(function() { + var i, eventName, + div = document.createElement( "div" ); + + // Support: IE<9 (lack submit/change bubble), Firefox 23+ (lack focusin event) + for ( i in { submit: true, change: true, focusin: true }) { + eventName = "on" + i; + + if ( !(support[ i + "Bubbles" ] = eventName in window) ) { + // Beware of CSP restrictions (https://developer.mozilla.org/en/Security/CSP) + div.setAttribute( eventName, "t" ); + support[ i + "Bubbles" ] = div.attributes[ eventName ].expando === false; + } + } + + // Null elements to avoid leaks in IE. + div = null; +})(); + + var rformElems = /^(?:input|select|textarea)$/i, rkeyEvent = /^key/, rmouseEvent = /^(?:mouse|contextmenu)|click/, @@ -4762,7 +4288,7 @@ jQuery.event = { eventHandle = elemData.handle = function( e ) { // Discard the second event of a jQuery.event.trigger() and // when an event is called after a page has unloaded - return typeof jQuery !== core_strundefined && (!e || jQuery.event.triggered !== e.type) ? + return typeof jQuery !== strundefined && (!e || jQuery.event.triggered !== e.type) ? jQuery.event.dispatch.apply( eventHandle.elem, arguments ) : undefined; }; @@ -4771,7 +4297,7 @@ jQuery.event = { } // Handle multiple events separated by a space - types = ( types || "" ).match( core_rnotwhite ) || [""]; + types = ( types || "" ).match( rnotwhite ) || [ "" ]; t = types.length; while ( t-- ) { tmp = rtypenamespace.exec( types[t] ) || []; @@ -4857,7 +4383,7 @@ jQuery.event = { } // Once for each type.namespace in types; type may be omitted - types = ( types || "" ).match( core_rnotwhite ) || [""]; + types = ( types || "" ).match( rnotwhite ) || [ "" ]; t = types.length; while ( t-- ) { tmp = rtypenamespace.exec( types[t] ) || []; @@ -4922,8 +4448,8 @@ jQuery.event = { var handle, ontype, cur, bubbleType, special, tmp, i, eventPath = [ elem || document ], - type = core_hasOwn.call( event, "type" ) ? event.type : event, - namespaces = core_hasOwn.call( event, "namespace" ) ? event.namespace.split(".") : []; + type = hasOwn.call( event, "type" ) ? event.type : event, + namespaces = hasOwn.call( event, "namespace" ) ? event.namespace.split(".") : []; cur = tmp = elem = elem || document; @@ -5009,8 +4535,11 @@ jQuery.event = { // Native handler handle = ontype && cur[ ontype ]; - if ( handle && jQuery.acceptData( cur ) && handle.apply && handle.apply( cur, data ) === false ) { - event.preventDefault(); + if ( handle && handle.apply && jQuery.acceptData( cur ) ) { + event.result = handle.apply( cur, data ); + if ( event.result === false ) { + event.preventDefault(); + } } } event.type = type; @@ -5060,7 +4589,7 @@ jQuery.event = { var i, ret, handleObj, matched, j, handlerQueue = [], - args = core_slice.call( arguments ), + args = slice.call( arguments ), handlers = ( jQuery._data( this, "events" ) || {} )[ event.type ] || [], special = jQuery.event.special[ event.type ] || {}; @@ -5350,7 +4879,7 @@ jQuery.removeEvent = document.removeEventListener ? // #8545, #7054, preventing memory leaks for custom events in IE6-8 // detachEvent needed property on element, by name of that event, to properly expose it to GC - if ( typeof elem[ name ] === core_strundefined ) { + if ( typeof elem[ name ] === strundefined ) { elem[ name ] = null; } @@ -5371,8 +4900,14 @@ jQuery.Event = function( src, props ) { // Events bubbling up the document may have been marked as prevented // by a handler lower down the tree; reflect the correct value. - this.isDefaultPrevented = ( src.defaultPrevented || src.returnValue === false || - src.getPreventDefault && src.getPreventDefault() ) ? returnTrue : returnFalse; + this.isDefaultPrevented = src.defaultPrevented || + src.defaultPrevented === undefined && ( + // Support: IE < 9 + src.returnValue === false || + // Support: Android < 4.0 + src.getPreventDefault && src.getPreventDefault() ) ? + returnTrue : + returnFalse; // Event type } else { @@ -5466,7 +5001,7 @@ jQuery.each({ }); // IE submit delegation -if ( !jQuery.support.submitBubbles ) { +if ( !support.submitBubbles ) { jQuery.event.special.submit = { setup: function() { @@ -5513,7 +5048,7 @@ if ( !jQuery.support.submitBubbles ) { } // IE change delegation and checkbox/radio fix -if ( !jQuery.support.changeBubbles ) { +if ( !support.changeBubbles ) { jQuery.event.special.change = { @@ -5572,24 +5107,33 @@ if ( !jQuery.support.changeBubbles ) { } // Create "bubbling" focus and blur events -if ( !jQuery.support.focusinBubbles ) { +if ( !support.focusinBubbles ) { jQuery.each({ focus: "focusin", blur: "focusout" }, function( orig, fix ) { - // Attach a single capturing handler while someone wants focusin/focusout - var attaches = 0, - handler = function( event ) { + // Attach a single capturing handler on the document while someone wants focusin/focusout + var handler = function( event ) { jQuery.event.simulate( fix, event.target, jQuery.event.fix( event ), true ); }; jQuery.event.special[ fix ] = { setup: function() { - if ( attaches++ === 0 ) { - document.addEventListener( orig, handler, true ); + var doc = this.ownerDocument || this, + attaches = jQuery._data( doc, fix ); + + if ( !attaches ) { + doc.addEventListener( orig, handler, true ); } + jQuery._data( doc, fix, ( attaches || 0 ) + 1 ); }, teardown: function() { - if ( --attaches === 0 ) { - document.removeEventListener( orig, handler, true ); + var doc = this.ownerDocument || this, + attaches = jQuery._data( doc, fix ) - 1; + + if ( !attaches ) { + doc.removeEventListener( orig, handler, true ); + jQuery._removeData( doc, fix ); + } else { + jQuery._data( doc, fix, attaches ); } } }; @@ -5698,289 +5242,8 @@ jQuery.fn.extend({ } } }); -var isSimple = /^.[^:#\[\.,]*$/, - rparentsprev = /^(?:parents|prev(?:Until|All))/, - rneedsContext = jQuery.expr.match.needsContext, - // methods guaranteed to produce a unique set when starting from a unique set - guaranteedUnique = { - children: true, - contents: true, - next: true, - prev: true - }; -jQuery.fn.extend({ - find: function( selector ) { - var i, - ret = [], - self = this, - len = self.length; - if ( typeof selector !== "string" ) { - return this.pushStack( jQuery( selector ).filter(function() { - for ( i = 0; i < len; i++ ) { - if ( jQuery.contains( self[ i ], this ) ) { - return true; - } - } - }) ); - } - - for ( i = 0; i < len; i++ ) { - jQuery.find( selector, self[ i ], ret ); - } - - // Needed because $( selector, context ) becomes $( context ).find( selector ) - ret = this.pushStack( len > 1 ? jQuery.unique( ret ) : ret ); - ret.selector = this.selector ? this.selector + " " + selector : selector; - return ret; - }, - - has: function( target ) { - var i, - targets = jQuery( target, this ), - len = targets.length; - - return this.filter(function() { - for ( i = 0; i < len; i++ ) { - if ( jQuery.contains( this, targets[i] ) ) { - return true; - } - } - }); - }, - - not: function( selector ) { - return this.pushStack( winnow(this, selector || [], true) ); - }, - - filter: function( selector ) { - return this.pushStack( winnow(this, selector || [], false) ); - }, - - is: function( selector ) { - return !!winnow( - this, - - // If this is a positional/relative selector, check membership in the returned set - // so $("p:first").is("p:last") won't return true for a doc with two "p". - typeof selector === "string" && rneedsContext.test( selector ) ? - jQuery( selector ) : - selector || [], - false - ).length; - }, - - closest: function( selectors, context ) { - var cur, - i = 0, - l = this.length, - ret = [], - pos = rneedsContext.test( selectors ) || typeof selectors !== "string" ? - jQuery( selectors, context || this.context ) : - 0; - - for ( ; i < l; i++ ) { - for ( cur = this[i]; cur && cur !== context; cur = cur.parentNode ) { - // Always skip document fragments - if ( cur.nodeType < 11 && (pos ? - pos.index(cur) > -1 : - - // Don't pass non-elements to Sizzle - cur.nodeType === 1 && - jQuery.find.matchesSelector(cur, selectors)) ) { - - cur = ret.push( cur ); - break; - } - } - } - - return this.pushStack( ret.length > 1 ? jQuery.unique( ret ) : ret ); - }, - - // Determine the position of an element within - // the matched set of elements - index: function( elem ) { - - // No argument, return index in parent - if ( !elem ) { - return ( this[0] && this[0].parentNode ) ? this.first().prevAll().length : -1; - } - - // index in selector - if ( typeof elem === "string" ) { - return jQuery.inArray( this[0], jQuery( elem ) ); - } - - // Locate the position of the desired element - return jQuery.inArray( - // If it receives a jQuery object, the first element is used - elem.jquery ? elem[0] : elem, this ); - }, - - add: function( selector, context ) { - var set = typeof selector === "string" ? - jQuery( selector, context ) : - jQuery.makeArray( selector && selector.nodeType ? [ selector ] : selector ), - all = jQuery.merge( this.get(), set ); - - return this.pushStack( jQuery.unique(all) ); - }, - - addBack: function( selector ) { - return this.add( selector == null ? - this.prevObject : this.prevObject.filter(selector) - ); - } -}); - -function sibling( cur, dir ) { - do { - cur = cur[ dir ]; - } while ( cur && cur.nodeType !== 1 ); - - return cur; -} - -jQuery.each({ - parent: function( elem ) { - var parent = elem.parentNode; - return parent && parent.nodeType !== 11 ? parent : null; - }, - parents: function( elem ) { - return jQuery.dir( elem, "parentNode" ); - }, - parentsUntil: function( elem, i, until ) { - return jQuery.dir( elem, "parentNode", until ); - }, - next: function( elem ) { - return sibling( elem, "nextSibling" ); - }, - prev: function( elem ) { - return sibling( elem, "previousSibling" ); - }, - nextAll: function( elem ) { - return jQuery.dir( elem, "nextSibling" ); - }, - prevAll: function( elem ) { - return jQuery.dir( elem, "previousSibling" ); - }, - nextUntil: function( elem, i, until ) { - return jQuery.dir( elem, "nextSibling", until ); - }, - prevUntil: function( elem, i, until ) { - return jQuery.dir( elem, "previousSibling", until ); - }, - siblings: function( elem ) { - return jQuery.sibling( ( elem.parentNode || {} ).firstChild, elem ); - }, - children: function( elem ) { - return jQuery.sibling( elem.firstChild ); - }, - contents: function( elem ) { - return jQuery.nodeName( elem, "iframe" ) ? - elem.contentDocument || elem.contentWindow.document : - jQuery.merge( [], elem.childNodes ); - } -}, function( name, fn ) { - jQuery.fn[ name ] = function( until, selector ) { - var ret = jQuery.map( this, fn, until ); - - if ( name.slice( -5 ) !== "Until" ) { - selector = until; - } - - if ( selector && typeof selector === "string" ) { - ret = jQuery.filter( selector, ret ); - } - - if ( this.length > 1 ) { - // Remove duplicates - if ( !guaranteedUnique[ name ] ) { - ret = jQuery.unique( ret ); - } - - // Reverse order for parents* and prev-derivatives - if ( rparentsprev.test( name ) ) { - ret = ret.reverse(); - } - } - - return this.pushStack( ret ); - }; -}); - -jQuery.extend({ - filter: function( expr, elems, not ) { - var elem = elems[ 0 ]; - - if ( not ) { - expr = ":not(" + expr + ")"; - } - - return elems.length === 1 && elem.nodeType === 1 ? - jQuery.find.matchesSelector( elem, expr ) ? [ elem ] : [] : - jQuery.find.matches( expr, jQuery.grep( elems, function( elem ) { - return elem.nodeType === 1; - })); - }, - - dir: function( elem, dir, until ) { - var matched = [], - cur = elem[ dir ]; - - while ( cur && cur.nodeType !== 9 && (until === undefined || cur.nodeType !== 1 || !jQuery( cur ).is( until )) ) { - if ( cur.nodeType === 1 ) { - matched.push( cur ); - } - cur = cur[dir]; - } - return matched; - }, - - sibling: function( n, elem ) { - var r = []; - - for ( ; n; n = n.nextSibling ) { - if ( n.nodeType === 1 && n !== elem ) { - r.push( n ); - } - } - - return r; - } -}); - -// Implement the identical functionality for filter and not -function winnow( elements, qualifier, not ) { - if ( jQuery.isFunction( qualifier ) ) { - return jQuery.grep( elements, function( elem, i ) { - /* jshint -W018 */ - return !!qualifier.call( elem, i, elem ) !== not; - }); - - } - - if ( qualifier.nodeType ) { - return jQuery.grep( elements, function( elem ) { - return ( elem === qualifier ) !== not; - }); - - } - - if ( typeof qualifier === "string" ) { - if ( isSimple.test( qualifier ) ) { - return jQuery.filter( qualifier, elements, not ); - } - - qualifier = jQuery.filter( qualifier, elements ); - } - - return jQuery.grep( elements, function( elem ) { - return ( jQuery.inArray( elem, qualifier ) >= 0 ) !== not; - }); -} function createSafeFragment( document ) { var list = nodeNames.split( "|" ), safeFrag = document.createDocumentFragment(); @@ -6005,7 +5268,6 @@ var nodeNames = "abbr|article|aside|audio|bdi|canvas|data|datalist|details|figca rtbody = /", "" ] + _default: support.htmlSerialize ? [ 0, "", "" ] : [ 1, "X
", "
" ] }, safeFragment = createSafeFragment( document ), fragmentDiv = safeFragment.appendChild( document.createElement("div") ); @@ -6034,270 +5296,40 @@ wrapMap.optgroup = wrapMap.option; wrapMap.tbody = wrapMap.tfoot = wrapMap.colgroup = wrapMap.caption = wrapMap.thead; wrapMap.th = wrapMap.td; -jQuery.fn.extend({ - text: function( value ) { - return jQuery.access( this, function( value ) { - return value === undefined ? - jQuery.text( this ) : - this.empty().append( ( this[0] && this[0].ownerDocument || document ).createTextNode( value ) ); - }, null, value, arguments.length ); - }, +function getAll( context, tag ) { + var elems, elem, + i = 0, + found = typeof context.getElementsByTagName !== strundefined ? context.getElementsByTagName( tag || "*" ) : + typeof context.querySelectorAll !== strundefined ? context.querySelectorAll( tag || "*" ) : + undefined; - append: function() { - return this.domManip( arguments, function( elem ) { - if ( this.nodeType === 1 || this.nodeType === 11 || this.nodeType === 9 ) { - var target = manipulationTarget( this, elem ); - target.appendChild( elem ); - } - }); - }, - - prepend: function() { - return this.domManip( arguments, function( elem ) { - if ( this.nodeType === 1 || this.nodeType === 11 || this.nodeType === 9 ) { - var target = manipulationTarget( this, elem ); - target.insertBefore( elem, target.firstChild ); - } - }); - }, - - before: function() { - return this.domManip( arguments, function( elem ) { - if ( this.parentNode ) { - this.parentNode.insertBefore( elem, this ); - } - }); - }, - - after: function() { - return this.domManip( arguments, function( elem ) { - if ( this.parentNode ) { - this.parentNode.insertBefore( elem, this.nextSibling ); - } - }); - }, - - // keepData is for internal use only--do not document - remove: function( selector, keepData ) { - var elem, - elems = selector ? jQuery.filter( selector, this ) : this, - i = 0; - - for ( ; (elem = elems[i]) != null; i++ ) { - - if ( !keepData && elem.nodeType === 1 ) { - jQuery.cleanData( getAll( elem ) ); - } - - if ( elem.parentNode ) { - if ( keepData && jQuery.contains( elem.ownerDocument, elem ) ) { - setGlobalEval( getAll( elem, "script" ) ); - } - elem.parentNode.removeChild( elem ); + if ( !found ) { + for ( found = [], elems = context.childNodes || context; (elem = elems[i]) != null; i++ ) { + if ( !tag || jQuery.nodeName( elem, tag ) ) { + found.push( elem ); + } else { + jQuery.merge( found, getAll( elem, tag ) ); } } - - return this; - }, - - empty: function() { - var elem, - i = 0; - - for ( ; (elem = this[i]) != null; i++ ) { - // Remove element nodes and prevent memory leaks - if ( elem.nodeType === 1 ) { - jQuery.cleanData( getAll( elem, false ) ); - } - - // Remove any remaining nodes - while ( elem.firstChild ) { - elem.removeChild( elem.firstChild ); - } - - // If this is a select, ensure that it displays empty (#12336) - // Support: IE<9 - if ( elem.options && jQuery.nodeName( elem, "select" ) ) { - elem.options.length = 0; - } - } - - return this; - }, - - clone: function( dataAndEvents, deepDataAndEvents ) { - dataAndEvents = dataAndEvents == null ? false : dataAndEvents; - deepDataAndEvents = deepDataAndEvents == null ? dataAndEvents : deepDataAndEvents; - - return this.map( function () { - return jQuery.clone( this, dataAndEvents, deepDataAndEvents ); - }); - }, - - html: function( value ) { - return jQuery.access( this, function( value ) { - var elem = this[0] || {}, - i = 0, - l = this.length; - - if ( value === undefined ) { - return elem.nodeType === 1 ? - elem.innerHTML.replace( rinlinejQuery, "" ) : - undefined; - } - - // See if we can take a shortcut and just use innerHTML - if ( typeof value === "string" && !rnoInnerhtml.test( value ) && - ( jQuery.support.htmlSerialize || !rnoshimcache.test( value ) ) && - ( jQuery.support.leadingWhitespace || !rleadingWhitespace.test( value ) ) && - !wrapMap[ ( rtagName.exec( value ) || ["", ""] )[1].toLowerCase() ] ) { - - value = value.replace( rxhtmlTag, "<$1>" ); - - try { - for (; i < l; i++ ) { - // Remove element nodes and prevent memory leaks - elem = this[i] || {}; - if ( elem.nodeType === 1 ) { - jQuery.cleanData( getAll( elem, false ) ); - elem.innerHTML = value; - } - } - - elem = 0; - - // If using innerHTML throws an exception, use the fallback method - } catch(e) {} - } - - if ( elem ) { - this.empty().append( value ); - } - }, null, value, arguments.length ); - }, - - replaceWith: function() { - var - // Snapshot the DOM in case .domManip sweeps something relevant into its fragment - args = jQuery.map( this, function( elem ) { - return [ elem.nextSibling, elem.parentNode ]; - }), - i = 0; - - // Make the changes, replacing each context element with the new content - this.domManip( arguments, function( elem ) { - var next = args[ i++ ], - parent = args[ i++ ]; - - if ( parent ) { - // Don't use the snapshot next if it has moved (#13810) - if ( next && next.parentNode !== parent ) { - next = this.nextSibling; - } - jQuery( this ).remove(); - parent.insertBefore( elem, next ); - } - // Allow new content to include elements from the context set - }, true ); - - // Force removal if there was no new content (e.g., from empty arguments) - return i ? this : this.remove(); - }, - - detach: function( selector ) { - return this.remove( selector, true ); - }, - - domManip: function( args, callback, allowIntersection ) { - - // Flatten any nested arrays - args = core_concat.apply( [], args ); - - var first, node, hasScripts, - scripts, doc, fragment, - i = 0, - l = this.length, - set = this, - iNoClone = l - 1, - value = args[0], - isFunction = jQuery.isFunction( value ); - - // We can't cloneNode fragments that contain checked, in WebKit - if ( isFunction || !( l <= 1 || typeof value !== "string" || jQuery.support.checkClone || !rchecked.test( value ) ) ) { - return this.each(function( index ) { - var self = set.eq( index ); - if ( isFunction ) { - args[0] = value.call( this, index, self.html() ); - } - self.domManip( args, callback, allowIntersection ); - }); - } - - if ( l ) { - fragment = jQuery.buildFragment( args, this[ 0 ].ownerDocument, false, !allowIntersection && this ); - first = fragment.firstChild; - - if ( fragment.childNodes.length === 1 ) { - fragment = first; - } - - if ( first ) { - scripts = jQuery.map( getAll( fragment, "script" ), disableScript ); - hasScripts = scripts.length; - - // Use the original fragment for the last item instead of the first because it can end up - // being emptied incorrectly in certain situations (#8070). - for ( ; i < l; i++ ) { - node = fragment; - - if ( i !== iNoClone ) { - node = jQuery.clone( node, true, true ); - - // Keep references to cloned scripts for later restoration - if ( hasScripts ) { - jQuery.merge( scripts, getAll( node, "script" ) ); - } - } - - callback.call( this[i], node, i ); - } - - if ( hasScripts ) { - doc = scripts[ scripts.length - 1 ].ownerDocument; - - // Reenable scripts - jQuery.map( scripts, restoreScript ); - - // Evaluate executable scripts on first document insertion - for ( i = 0; i < hasScripts; i++ ) { - node = scripts[ i ]; - if ( rscriptType.test( node.type || "" ) && - !jQuery._data( node, "globalEval" ) && jQuery.contains( doc, node ) ) { - - if ( node.src ) { - // Hope ajax is available... - jQuery._evalUrl( node.src ); - } else { - jQuery.globalEval( ( node.text || node.textContent || node.innerHTML || "" ).replace( rcleanScript, "" ) ); - } - } - } - } - - // Fix #11809: Avoid leaking memory - fragment = first = null; - } - } - - return this; } -}); + + return tag === undefined || tag && jQuery.nodeName( context, tag ) ? + jQuery.merge( [ context ], found ) : + found; +} + +// Used in buildFragment, fixes the defaultChecked property +function fixDefaultChecked( elem ) { + if ( rcheckableType.test( elem.type ) ) { + elem.defaultChecked = elem.checked; + } +} // Support: IE<8 // Manipulating tables requires a tbody function manipulationTarget( elem, content ) { return jQuery.nodeName( elem, "table" ) && - jQuery.nodeName( content.nodeType === 1 ? content : content.firstChild, "tr" ) ? + jQuery.nodeName( content.nodeType !== 11 ? content : content.firstChild, "tr" ) ? elem.getElementsByTagName("tbody")[0] || elem.appendChild( elem.ownerDocument.createElement("tbody") ) : @@ -6367,7 +5399,7 @@ function fixCloneNodeIssues( src, dest ) { nodeName = dest.nodeName.toLowerCase(); // IE6-8 copies events bound via attachEvent when using cloneNode. - if ( !jQuery.support.noCloneEvent && dest[ jQuery.expando ] ) { + if ( !support.noCloneEvent && dest[ jQuery.expando ] ) { data = jQuery._data( dest ); for ( e in data.events ) { @@ -6394,11 +5426,11 @@ function fixCloneNodeIssues( src, dest ) { // element in IE9, the outerHTML strategy above is not sufficient. // If the src has innerHTML and the destination does not, // copy the src.innerHTML into the dest.innerHTML. #10324 - if ( jQuery.support.html5Clone && ( src.innerHTML && !jQuery.trim(dest.innerHTML) ) ) { + if ( support.html5Clone && ( src.innerHTML && !jQuery.trim(dest.innerHTML) ) ) { dest.innerHTML = src.innerHTML; } - } else if ( nodeName === "input" && manipulation_rcheckableType.test( src.type ) ) { + } else if ( nodeName === "input" && rcheckableType.test( src.type ) ) { // IE6-8 fails to persist the checked state of a cloned checkbox // or radio button. Worse, IE6-7 fail to give the cloned element // a checked appearance if the defaultChecked value isn't also set @@ -6423,67 +5455,12 @@ function fixCloneNodeIssues( src, dest ) { } } -jQuery.each({ - appendTo: "append", - prependTo: "prepend", - insertBefore: "before", - insertAfter: "after", - replaceAll: "replaceWith" -}, function( name, original ) { - jQuery.fn[ name ] = function( selector ) { - var elems, - i = 0, - ret = [], - insert = jQuery( selector ), - last = insert.length - 1; - - for ( ; i <= last; i++ ) { - elems = i === last ? this : this.clone(true); - jQuery( insert[i] )[ original ]( elems ); - - // Modern browsers can apply jQuery collections as arrays, but oldIE needs a .get() - core_push.apply( ret, elems.get() ); - } - - return this.pushStack( ret ); - }; -}); - -function getAll( context, tag ) { - var elems, elem, - i = 0, - found = typeof context.getElementsByTagName !== core_strundefined ? context.getElementsByTagName( tag || "*" ) : - typeof context.querySelectorAll !== core_strundefined ? context.querySelectorAll( tag || "*" ) : - undefined; - - if ( !found ) { - for ( found = [], elems = context.childNodes || context; (elem = elems[i]) != null; i++ ) { - if ( !tag || jQuery.nodeName( elem, tag ) ) { - found.push( elem ); - } else { - jQuery.merge( found, getAll( elem, tag ) ); - } - } - } - - return tag === undefined || tag && jQuery.nodeName( context, tag ) ? - jQuery.merge( [ context ], found ) : - found; -} - -// Used in buildFragment, fixes the defaultChecked property -function fixDefaultChecked( elem ) { - if ( manipulation_rcheckableType.test( elem.type ) ) { - elem.defaultChecked = elem.checked; - } -} - jQuery.extend({ clone: function( elem, dataAndEvents, deepDataAndEvents ) { var destElements, node, clone, i, srcElements, inPage = jQuery.contains( elem.ownerDocument, elem ); - if ( jQuery.support.html5Clone || jQuery.isXMLDoc(elem) || !rnoshimcache.test( "<" + elem.nodeName + ">" ) ) { + if ( support.html5Clone || jQuery.isXMLDoc(elem) || !rnoshimcache.test( "<" + elem.nodeName + ">" ) ) { clone = elem.cloneNode( true ); // IE<=8 does not properly clone detached, unknown element nodes @@ -6492,7 +5469,7 @@ jQuery.extend({ fragmentDiv.removeChild( clone = fragmentDiv.firstChild ); } - if ( (!jQuery.support.noCloneEvent || !jQuery.support.noCloneChecked) && + if ( (!support.noCloneEvent || !support.noCloneChecked) && (elem.nodeType === 1 || elem.nodeType === 11) && !jQuery.isXMLDoc(elem) ) { // We eschew Sizzle here for performance reasons: http://jsperf.com/getall-vs-sizzle/2 @@ -6563,7 +5540,7 @@ jQuery.extend({ tmp = tmp || safe.appendChild( context.createElement("div") ); // Deserialize a standard representation - tag = ( rtagName.exec( elem ) || ["", ""] )[1].toLowerCase(); + tag = (rtagName.exec( elem ) || [ "", "" ])[ 1 ].toLowerCase(); wrap = wrapMap[ tag ] || wrapMap._default; tmp.innerHTML = wrap[1] + elem.replace( rxhtmlTag, "<$1>" ) + wrap[2]; @@ -6575,12 +5552,12 @@ jQuery.extend({ } // Manually add leading whitespace removed by IE - if ( !jQuery.support.leadingWhitespace && rleadingWhitespace.test( elem ) ) { + if ( !support.leadingWhitespace && rleadingWhitespace.test( elem ) ) { nodes.push( context.createTextNode( rleadingWhitespace.exec( elem )[0] ) ); } // Remove IE's autoinserted from table fragments - if ( !jQuery.support.tbody ) { + if ( !support.tbody ) { // String was a , *may* have spurious elem = tag === "table" && !rtbody.test( elem ) ? @@ -6622,7 +5599,7 @@ jQuery.extend({ // Reset defaultChecked for any radios and checkboxes // about to be appended to the DOM in IE 6/7 (#8060) - if ( !jQuery.support.appendChecked ) { + if ( !support.appendChecked ) { jQuery.grep( getAll( nodes, "input" ), fixDefaultChecked ); } @@ -6666,11 +5643,10 @@ jQuery.extend({ i = 0, internalKey = jQuery.expando, cache = jQuery.cache, - deleteExpando = jQuery.support.deleteExpando, + deleteExpando = support.deleteExpando, special = jQuery.event.special; for ( ; (elem = elems[i]) != null; i++ ) { - if ( acceptData || jQuery.acceptData( elem ) ) { id = elem[ internalKey ]; @@ -6700,399 +5676,452 @@ jQuery.extend({ if ( deleteExpando ) { delete elem[ internalKey ]; - } else if ( typeof elem.removeAttribute !== core_strundefined ) { + } else if ( typeof elem.removeAttribute !== strundefined ) { elem.removeAttribute( internalKey ); } else { elem[ internalKey ] = null; } - core_deletedIds.push( id ); + deletedIds.push( id ); } } } } - }, - - _evalUrl: function( url ) { - return jQuery.ajax({ - url: url, - type: "GET", - dataType: "script", - async: false, - global: false, - "throws": true - }); } }); + jQuery.fn.extend({ - wrapAll: function( html ) { - if ( jQuery.isFunction( html ) ) { - return this.each(function(i) { - jQuery(this).wrapAll( html.call(this, i) ); - }); - } + text: function( value ) { + return access( this, function( value ) { + return value === undefined ? + jQuery.text( this ) : + this.empty().append( ( this[0] && this[0].ownerDocument || document ).createTextNode( value ) ); + }, null, value, arguments.length ); + }, - if ( this[0] ) { - // The elements to wrap the target around - var wrap = jQuery( html, this[0].ownerDocument ).eq(0).clone(true); + append: function() { + return this.domManip( arguments, function( elem ) { + if ( this.nodeType === 1 || this.nodeType === 11 || this.nodeType === 9 ) { + var target = manipulationTarget( this, elem ); + target.appendChild( elem ); + } + }); + }, - if ( this[0].parentNode ) { - wrap.insertBefore( this[0] ); + prepend: function() { + return this.domManip( arguments, function( elem ) { + if ( this.nodeType === 1 || this.nodeType === 11 || this.nodeType === 9 ) { + var target = manipulationTarget( this, elem ); + target.insertBefore( elem, target.firstChild ); + } + }); + }, + + before: function() { + return this.domManip( arguments, function( elem ) { + if ( this.parentNode ) { + this.parentNode.insertBefore( elem, this ); + } + }); + }, + + after: function() { + return this.domManip( arguments, function( elem ) { + if ( this.parentNode ) { + this.parentNode.insertBefore( elem, this.nextSibling ); + } + }); + }, + + remove: function( selector, keepData /* Internal Use Only */ ) { + var elem, + elems = selector ? jQuery.filter( selector, this ) : this, + i = 0; + + for ( ; (elem = elems[i]) != null; i++ ) { + + if ( !keepData && elem.nodeType === 1 ) { + jQuery.cleanData( getAll( elem ) ); } - wrap.map(function() { - var elem = this; - - while ( elem.firstChild && elem.firstChild.nodeType === 1 ) { - elem = elem.firstChild; + if ( elem.parentNode ) { + if ( keepData && jQuery.contains( elem.ownerDocument, elem ) ) { + setGlobalEval( getAll( elem, "script" ) ); } - - return elem; - }).append( this ); + elem.parentNode.removeChild( elem ); + } } return this; }, - wrapInner: function( html ) { - if ( jQuery.isFunction( html ) ) { - return this.each(function(i) { - jQuery(this).wrapInner( html.call(this, i) ); - }); + empty: function() { + var elem, + i = 0; + + for ( ; (elem = this[i]) != null; i++ ) { + // Remove element nodes and prevent memory leaks + if ( elem.nodeType === 1 ) { + jQuery.cleanData( getAll( elem, false ) ); + } + + // Remove any remaining nodes + while ( elem.firstChild ) { + elem.removeChild( elem.firstChild ); + } + + // If this is a select, ensure that it displays empty (#12336) + // Support: IE<9 + if ( elem.options && jQuery.nodeName( elem, "select" ) ) { + elem.options.length = 0; + } } - return this.each(function() { - var self = jQuery( this ), - contents = self.contents(); + return this; + }, - if ( contents.length ) { - contents.wrapAll( html ); + clone: function( dataAndEvents, deepDataAndEvents ) { + dataAndEvents = dataAndEvents == null ? false : dataAndEvents; + deepDataAndEvents = deepDataAndEvents == null ? dataAndEvents : deepDataAndEvents; - } else { - self.append( html ); - } + return this.map(function() { + return jQuery.clone( this, dataAndEvents, deepDataAndEvents ); }); }, - wrap: function( html ) { - var isFunction = jQuery.isFunction( html ); + html: function( value ) { + return access( this, function( value ) { + var elem = this[ 0 ] || {}, + i = 0, + l = this.length; - return this.each(function(i) { - jQuery( this ).wrapAll( isFunction ? html.call(this, i) : html ); - }); - }, - - unwrap: function() { - return this.parent().each(function() { - if ( !jQuery.nodeName( this, "body" ) ) { - jQuery( this ).replaceWith( this.childNodes ); - } - }).end(); - } -}); -var iframe, getStyles, curCSS, - ralpha = /alpha\([^)]*\)/i, - ropacity = /opacity\s*=\s*([^)]*)/, - rposition = /^(top|right|bottom|left)$/, - // swappable if display is none or starts with table except "table", "table-cell", or "table-caption" - // see here for display values: https://developer.mozilla.org/en-US/docs/CSS/display - rdisplayswap = /^(none|table(?!-c[ea]).+)/, - rmargin = /^margin/, - rnumsplit = new RegExp( "^(" + core_pnum + ")(.*)$", "i" ), - rnumnonpx = new RegExp( "^(" + core_pnum + ")(?!px)[a-z%]+$", "i" ), - rrelNum = new RegExp( "^([+-])=(" + core_pnum + ")", "i" ), - elemdisplay = { BODY: "block" }, - - cssShow = { position: "absolute", visibility: "hidden", display: "block" }, - cssNormalTransform = { - letterSpacing: 0, - fontWeight: 400 - }, - - cssExpand = [ "Top", "Right", "Bottom", "Left" ], - cssPrefixes = [ "Webkit", "O", "Moz", "ms" ]; - -// return a css property mapped to a potentially vendor prefixed property -function vendorPropName( style, name ) { - - // shortcut for names that are not vendor prefixed - if ( name in style ) { - return name; - } - - // check for vendor prefixed names - var capName = name.charAt(0).toUpperCase() + name.slice(1), - origName = name, - i = cssPrefixes.length; - - while ( i-- ) { - name = cssPrefixes[ i ] + capName; - if ( name in style ) { - return name; - } - } - - return origName; -} - -function isHidden( elem, el ) { - // isHidden might be called from jQuery#filter function; - // in that case, element will be second argument - elem = el || elem; - return jQuery.css( elem, "display" ) === "none" || !jQuery.contains( elem.ownerDocument, elem ); -} - -function showHide( elements, show ) { - var display, elem, hidden, - values = [], - index = 0, - length = elements.length; - - for ( ; index < length; index++ ) { - elem = elements[ index ]; - if ( !elem.style ) { - continue; - } - - values[ index ] = jQuery._data( elem, "olddisplay" ); - display = elem.style.display; - if ( show ) { - // Reset the inline display of this element to learn if it is - // being hidden by cascaded rules or not - if ( !values[ index ] && display === "none" ) { - elem.style.display = ""; + if ( value === undefined ) { + return elem.nodeType === 1 ? + elem.innerHTML.replace( rinlinejQuery, "" ) : + undefined; } - // Set elements which have been overridden with display: none - // in a stylesheet to whatever the default browser style is - // for such an element - if ( elem.style.display === "" && isHidden( elem ) ) { - values[ index ] = jQuery._data( elem, "olddisplay", css_defaultDisplay(elem.nodeName) ); - } - } else { + // See if we can take a shortcut and just use innerHTML + if ( typeof value === "string" && !rnoInnerhtml.test( value ) && + ( support.htmlSerialize || !rnoshimcache.test( value ) ) && + ( support.leadingWhitespace || !rleadingWhitespace.test( value ) ) && + !wrapMap[ (rtagName.exec( value ) || [ "", "" ])[ 1 ].toLowerCase() ] ) { - if ( !values[ index ] ) { - hidden = isHidden( elem ); + value = value.replace( rxhtmlTag, "<$1>" ); - if ( display && display !== "none" || !hidden ) { - jQuery._data( elem, "olddisplay", hidden ? display : jQuery.css( elem, "display" ) ); - } - } - } - } - - // Set the display of most of the elements in a second loop - // to avoid the constant reflow - for ( index = 0; index < length; index++ ) { - elem = elements[ index ]; - if ( !elem.style ) { - continue; - } - if ( !show || elem.style.display === "none" || elem.style.display === "" ) { - elem.style.display = show ? values[ index ] || "" : "none"; - } - } - - return elements; -} - -jQuery.fn.extend({ - css: function( name, value ) { - return jQuery.access( this, function( elem, name, value ) { - var len, styles, - map = {}, - i = 0; - - if ( jQuery.isArray( name ) ) { - styles = getStyles( elem ); - len = name.length; - - for ( ; i < len; i++ ) { - map[ name[ i ] ] = jQuery.css( elem, name[ i ], false, styles ); - } - - return map; - } - - return value !== undefined ? - jQuery.style( elem, name, value ) : - jQuery.css( elem, name ); - }, name, value, arguments.length > 1 ); - }, - show: function() { - return showHide( this, true ); - }, - hide: function() { - return showHide( this ); - }, - toggle: function( state ) { - if ( typeof state === "boolean" ) { - return state ? this.show() : this.hide(); - } - - return this.each(function() { - if ( isHidden( this ) ) { - jQuery( this ).show(); - } else { - jQuery( this ).hide(); - } - }); - } -}); - -jQuery.extend({ - // Add in style property hooks for overriding the default - // behavior of getting and setting a style property - cssHooks: { - opacity: { - get: function( elem, computed ) { - if ( computed ) { - // We should always get a number back from opacity - var ret = curCSS( elem, "opacity" ); - return ret === "" ? "1" : ret; - } - } - } - }, - - // Don't automatically add "px" to these possibly-unitless properties - cssNumber: { - "columnCount": true, - "fillOpacity": true, - "fontWeight": true, - "lineHeight": true, - "opacity": true, - "order": true, - "orphans": true, - "widows": true, - "zIndex": true, - "zoom": true - }, - - // Add in properties whose names you wish to fix before - // setting or getting the value - cssProps: { - // normalize float css property - "float": jQuery.support.cssFloat ? "cssFloat" : "styleFloat" - }, - - // Get and set the style property on a DOM Node - style: function( elem, name, value, extra ) { - // Don't set styles on text and comment nodes - if ( !elem || elem.nodeType === 3 || elem.nodeType === 8 || !elem.style ) { - return; - } - - // Make sure that we're working with the right name - var ret, type, hooks, - origName = jQuery.camelCase( name ), - style = elem.style; - - name = jQuery.cssProps[ origName ] || ( jQuery.cssProps[ origName ] = vendorPropName( style, origName ) ); - - // gets hook for the prefixed version - // followed by the unprefixed version - hooks = jQuery.cssHooks[ name ] || jQuery.cssHooks[ origName ]; - - // Check if we're setting a value - if ( value !== undefined ) { - type = typeof value; - - // convert relative number strings (+= or -=) to relative numbers. #7345 - if ( type === "string" && (ret = rrelNum.exec( value )) ) { - value = ( ret[1] + 1 ) * ret[2] + parseFloat( jQuery.css( elem, name ) ); - // Fixes bug #9237 - type = "number"; - } - - // Make sure that NaN and null values aren't set. See: #7116 - if ( value == null || type === "number" && isNaN( value ) ) { - return; - } - - // If a number was passed in, add 'px' to the (except for certain CSS properties) - if ( type === "number" && !jQuery.cssNumber[ origName ] ) { - value += "px"; - } - - // Fixes #8908, it can be done more correctly by specifing setters in cssHooks, - // but it would mean to define eight (for every problematic property) identical functions - if ( !jQuery.support.clearCloneStyle && value === "" && name.indexOf("background") === 0 ) { - style[ name ] = "inherit"; - } - - // If a hook was provided, use that value, otherwise just set the specified value - if ( !hooks || !("set" in hooks) || (value = hooks.set( elem, value, extra )) !== undefined ) { - - // Wrapped to prevent IE from throwing errors when 'invalid' values are provided - // Fixes bug #5509 try { - style[ name ] = value; + for (; i < l; i++ ) { + // Remove element nodes and prevent memory leaks + elem = this[i] || {}; + if ( elem.nodeType === 1 ) { + jQuery.cleanData( getAll( elem, false ) ); + elem.innerHTML = value; + } + } + + elem = 0; + + // If using innerHTML throws an exception, use the fallback method } catch(e) {} } - } else { - // If a hook was provided get the non-computed value from there - if ( hooks && "get" in hooks && (ret = hooks.get( elem, false, extra )) !== undefined ) { - return ret; + if ( elem ) { + this.empty().append( value ); } - - // Otherwise just get the value from the style object - return style[ name ]; - } + }, null, value, arguments.length ); }, - css: function( elem, name, extra, styles ) { - var num, val, hooks, - origName = jQuery.camelCase( name ); + replaceWith: function() { + var arg = arguments[ 0 ]; - // Make sure that we're working with the right name - name = jQuery.cssProps[ origName ] || ( jQuery.cssProps[ origName ] = vendorPropName( elem.style, origName ) ); + // Make the changes, replacing each context element with the new content + this.domManip( arguments, function( elem ) { + arg = this.parentNode; - // gets hook for the prefixed version - // followed by the unprefixed version - hooks = jQuery.cssHooks[ name ] || jQuery.cssHooks[ origName ]; + jQuery.cleanData( getAll( this ) ); - // If a hook was provided get the computed value from there - if ( hooks && "get" in hooks ) { - val = hooks.get( elem, true, extra ); + if ( arg ) { + arg.replaceChild( elem, this ); + } + }); + + // Force removal if there was no new content (e.g., from empty arguments) + return arg && (arg.length || arg.nodeType) ? this : this.remove(); + }, + + detach: function( selector ) { + return this.remove( selector, true ); + }, + + domManip: function( args, callback ) { + + // Flatten any nested arrays + args = concat.apply( [], args ); + + var first, node, hasScripts, + scripts, doc, fragment, + i = 0, + l = this.length, + set = this, + iNoClone = l - 1, + value = args[0], + isFunction = jQuery.isFunction( value ); + + // We can't cloneNode fragments that contain checked, in WebKit + if ( isFunction || + ( l > 1 && typeof value === "string" && + !support.checkClone && rchecked.test( value ) ) ) { + return this.each(function( index ) { + var self = set.eq( index ); + if ( isFunction ) { + args[0] = value.call( this, index, self.html() ); + } + self.domManip( args, callback ); + }); } - // Otherwise, if a way to get the computed value exists, use that - if ( val === undefined ) { - val = curCSS( elem, name, styles ); + if ( l ) { + fragment = jQuery.buildFragment( args, this[ 0 ].ownerDocument, false, this ); + first = fragment.firstChild; + + if ( fragment.childNodes.length === 1 ) { + fragment = first; + } + + if ( first ) { + scripts = jQuery.map( getAll( fragment, "script" ), disableScript ); + hasScripts = scripts.length; + + // Use the original fragment for the last item instead of the first because it can end up + // being emptied incorrectly in certain situations (#8070). + for ( ; i < l; i++ ) { + node = fragment; + + if ( i !== iNoClone ) { + node = jQuery.clone( node, true, true ); + + // Keep references to cloned scripts for later restoration + if ( hasScripts ) { + jQuery.merge( scripts, getAll( node, "script" ) ); + } + } + + callback.call( this[i], node, i ); + } + + if ( hasScripts ) { + doc = scripts[ scripts.length - 1 ].ownerDocument; + + // Reenable scripts + jQuery.map( scripts, restoreScript ); + + // Evaluate executable scripts on first document insertion + for ( i = 0; i < hasScripts; i++ ) { + node = scripts[ i ]; + if ( rscriptType.test( node.type || "" ) && + !jQuery._data( node, "globalEval" ) && jQuery.contains( doc, node ) ) { + + if ( node.src ) { + // Optional AJAX dependency, but won't run scripts if not present + if ( jQuery._evalUrl ) { + jQuery._evalUrl( node.src ); + } + } else { + jQuery.globalEval( ( node.text || node.textContent || node.innerHTML || "" ).replace( rcleanScript, "" ) ); + } + } + } + } + + // Fix #11809: Avoid leaking memory + fragment = first = null; + } } - //convert "normal" to computed value - if ( val === "normal" && name in cssNormalTransform ) { - val = cssNormalTransform[ name ]; - } - - // Return, converting to number if forced or a qualifier was provided and val looks numeric - if ( extra === "" || extra ) { - num = parseFloat( val ); - return extra === true || jQuery.isNumeric( num ) ? num || 0 : val; - } - return val; + return this; } }); -// NOTE: we've included the "window" in window.getComputedStyle -// because jsdom on node.js will break without it. -if ( window.getComputedStyle ) { - getStyles = function( elem ) { - return window.getComputedStyle( elem, null ); +jQuery.each({ + appendTo: "append", + prependTo: "prepend", + insertBefore: "before", + insertAfter: "after", + replaceAll: "replaceWith" +}, function( name, original ) { + jQuery.fn[ name ] = function( selector ) { + var elems, + i = 0, + ret = [], + insert = jQuery( selector ), + last = insert.length - 1; + + for ( ; i <= last; i++ ) { + elems = i === last ? this : this.clone(true); + jQuery( insert[i] )[ original ]( elems ); + + // Modern browsers can apply jQuery collections as arrays, but oldIE needs a .get() + push.apply( ret, elems.get() ); + } + + return this.pushStack( ret ); + }; +}); + + +var iframe, + elemdisplay = {}; + +/** + * Retrieve the actual display of a element + * @param {String} name nodeName of the element + * @param {Object} doc Document object + */ +// Called only from within defaultDisplay +function actualDisplay( name, doc ) { + var elem = jQuery( doc.createElement( name ) ).appendTo( doc.body ), + + // getDefaultComputedStyle might be reliably used only on attached element + display = window.getDefaultComputedStyle ? + + // Use of this method is a temporary fix (more like optmization) until something better comes along, + // since it was removed from specification and supported only in FF + window.getDefaultComputedStyle( elem[ 0 ] ).display : jQuery.css( elem[ 0 ], "display" ); + + // We don't have any data stored on the element, + // so use "detach" method as fast way to get rid of the element + elem.detach(); + + return display; +} + +/** + * Try to determine the default display value of an element + * @param {String} nodeName + */ +function defaultDisplay( nodeName ) { + var doc = document, + display = elemdisplay[ nodeName ]; + + if ( !display ) { + display = actualDisplay( nodeName, doc ); + + // If the simple way fails, read from inside an iframe + if ( display === "none" || !display ) { + + // Use the already-created iframe if possible + iframe = (iframe || jQuery( "