Commit 21b0e6e9 authored by Sindre Sorhus's avatar Sindre Sorhus

new app ui - backbone

parent 05a858f4
node_modules/backbone/*
!node_modules/backbone/backbone.js
node_modules/backbone.localstorage/*
!node_modules/backbone.localstorage/backbone.localStorage.js
node_modules/jquery/*
!node_modules/jquery/dist
node_modules/jquery/dist/*
!node_modules/jquery/dist/jquery.js
node_modules/todomvc-app-css/*
!node_modules/todomvc-app-css/index.css
node_modules/todomvc-common/*
!node_modules/todomvc-common/base.css
!node_modules/todomvc-common/base.js
node_modules/underscore/*
!node_modules/underscore/underscore.js
{
"name": "todomvc-backbone",
"version": "0.0.0",
"dependencies": {
"backbone": "~1.1.1",
"underscore": "~1.7.0",
"jquery": "~2.1.0",
"todomvc-common": "~0.3.0",
"backbone.localStorage": "~1.1.0"
}
}
...@@ -3,7 +3,8 @@ ...@@ -3,7 +3,8 @@
<head> <head>
<meta charset="utf-8"> <meta charset="utf-8">
<title>Backbone.js • TodoMVC</title> <title>Backbone.js • TodoMVC</title>
<link rel="stylesheet" href="bower_components/todomvc-common/base.css"> <link rel="stylesheet" href="node_modules/todomvc-common/base.css">
<link rel="stylesheet" href="node_modules/todomvc-app-css/index.css">
</head> </head>
<body> <body>
<section id="todoapp"> <section id="todoapp">
...@@ -48,11 +49,11 @@ ...@@ -48,11 +49,11 @@
<button id="clear-completed">Clear completed (<%= completed %>)</button> <button id="clear-completed">Clear completed (<%= completed %>)</button>
<% } %> <% } %>
</script> </script>
<script src="bower_components/todomvc-common/base.js"></script> <script src="node_modules/todomvc-common/base.js"></script>
<script src="bower_components/jquery/dist/jquery.js"></script> <script src="node_modules/jquery/dist/jquery.js"></script>
<script src="bower_components/underscore/underscore.js"></script> <script src="node_modules/underscore/underscore.js"></script>
<script src="bower_components/backbone/backbone.js"></script> <script src="node_modules/backbone/backbone.js"></script>
<script src="bower_components/backbone.localStorage/backbone.localStorage.js"></script> <script src="node_modules/backbone.localstorage/backbone.localStorage.js"></script>
<script src="js/models/todo.js"></script> <script src="js/models/todo.js"></script>
<script src="js/collections/todos.js"></script> <script src="js/collections/todos.js"></script>
<script src="js/views/todo-view.js"></script> <script src="js/views/todo-view.js"></script>
......
/** /**
* Backbone localStorage Adapter * Backbone localStorage Adapter
* Version 1.1.14 * Version 1.1.16
* *
* https://github.com/jeromegn/Backbone.localStorage * https://github.com/jeromegn/Backbone.localStorage
*/ */
...@@ -238,8 +238,10 @@ Backbone.LocalStorage.sync = window.Store.sync = Backbone.localSync = function(m ...@@ -238,8 +238,10 @@ Backbone.LocalStorage.sync = window.Store.sync = Backbone.localSync = function(m
Backbone.ajaxSync = Backbone.sync; Backbone.ajaxSync = Backbone.sync;
Backbone.getSyncMethod = function(model) { Backbone.getSyncMethod = function(model, options) {
if(model.localStorage || (model.collection && model.collection.localStorage)) { var forceAjaxSync = options && options.ajaxSync;
if(!forceAjaxSync && (result(model, 'localStorage') || result(model.collection, 'localStorage'))) {
return Backbone.localSync; return Backbone.localSync;
} }
...@@ -249,7 +251,7 @@ Backbone.getSyncMethod = function(model) { ...@@ -249,7 +251,7 @@ Backbone.getSyncMethod = function(model) {
// Override 'Backbone.sync' to default to localSync, // Override 'Backbone.sync' to default to localSync,
// the original 'Backbone.sync' is still available in 'Backbone.ajaxSync' // the original 'Backbone.sync' is still available in 'Backbone.ajaxSync'
Backbone.sync = function(method, model, options) { Backbone.sync = function(method, model, options) {
return Backbone.getSyncMethod(model).apply(this, [method, model, options]); return Backbone.getSyncMethod(model, options).apply(this, [method, model, options]);
}; };
return Backbone.LocalStorage; return Backbone.LocalStorage;
......
/*! /*!
* jQuery JavaScript Library v2.1.1 * jQuery JavaScript Library v2.1.3
* http://jquery.com/ * http://jquery.com/
* *
* Includes Sizzle.js * Includes Sizzle.js
...@@ -9,19 +9,19 @@ ...@@ -9,19 +9,19 @@
* Released under the MIT license * Released under the MIT license
* http://jquery.org/license * http://jquery.org/license
* *
* Date: 2014-05-01T17:11Z * Date: 2014-12-18T15:11Z
*/ */
(function( global, factory ) { (function( global, factory ) {
if ( typeof module === "object" && typeof module.exports === "object" ) { if ( typeof module === "object" && typeof module.exports === "object" ) {
// For CommonJS and CommonJS-like environments where a proper window is present, // For CommonJS and CommonJS-like environments where a proper `window`
// execute the factory and get jQuery // is present, execute the factory and get jQuery.
// For environments that do not inherently posses a window with a document // For environments that do not have a `window` with a `document`
// (such as Node.js), expose a jQuery-making factory as module.exports // (such as Node.js), expose a factory as module.exports.
// This accentuates the need for the creation of a real window // This accentuates the need for the creation of a real `window`.
// e.g. var jQuery = require("jquery")(window); // e.g. var jQuery = require("jquery")(window);
// See ticket #14549 for more info // See ticket #14549 for more info.
module.exports = global.document ? module.exports = global.document ?
factory( global, true ) : factory( global, true ) :
function( w ) { function( w ) {
...@@ -37,10 +37,10 @@ ...@@ -37,10 +37,10 @@
// Pass this if window is not defined yet // Pass this if window is not defined yet
}(typeof window !== "undefined" ? window : this, function( window, noGlobal ) { }(typeof window !== "undefined" ? window : this, function( window, noGlobal ) {
// Can't do this because several apps including ASP.NET trace // Support: Firefox 18+
// Can't be in strict mode, several libs including ASP.NET trace
// the stack via arguments.caller.callee and Firefox dies if // the stack via arguments.caller.callee and Firefox dies if
// you try to trace through "use strict" call chains. (#13335) // you try to trace through "use strict" call chains. (#13335)
// Support: Firefox 18+
// //
var arr = []; var arr = [];
...@@ -67,7 +67,7 @@ var ...@@ -67,7 +67,7 @@ var
// Use the correct document accordingly with window argument (sandbox) // Use the correct document accordingly with window argument (sandbox)
document = window.document, document = window.document,
version = "2.1.1", version = "2.1.3",
// Define a local copy of jQuery // Define a local copy of jQuery
jQuery = function( selector, context ) { jQuery = function( selector, context ) {
...@@ -185,7 +185,7 @@ jQuery.extend = jQuery.fn.extend = function() { ...@@ -185,7 +185,7 @@ jQuery.extend = jQuery.fn.extend = function() {
if ( typeof target === "boolean" ) { if ( typeof target === "boolean" ) {
deep = target; deep = target;
// skip the boolean and the target // Skip the boolean and the target
target = arguments[ i ] || {}; target = arguments[ i ] || {};
i++; i++;
} }
...@@ -195,7 +195,7 @@ jQuery.extend = jQuery.fn.extend = function() { ...@@ -195,7 +195,7 @@ jQuery.extend = jQuery.fn.extend = function() {
target = {}; target = {};
} }
// extend jQuery itself if only one argument is passed // Extend jQuery itself if only one argument is passed
if ( i === length ) { if ( i === length ) {
target = this; target = this;
i--; i--;
...@@ -252,9 +252,6 @@ jQuery.extend({ ...@@ -252,9 +252,6 @@ jQuery.extend({
noop: function() {}, noop: function() {},
// See test/unit/core.js for details concerning isFunction.
// Since version 1.3, DOM methods and functions like alert
// aren't supported. They return false on IE (#2968).
isFunction: function( obj ) { isFunction: function( obj ) {
return jQuery.type(obj) === "function"; return jQuery.type(obj) === "function";
}, },
...@@ -269,7 +266,8 @@ jQuery.extend({ ...@@ -269,7 +266,8 @@ jQuery.extend({
// parseFloat NaNs numeric-cast false positives (null|true|false|"") // parseFloat NaNs numeric-cast false positives (null|true|false|"")
// ...but misinterprets leading-number strings, particularly hex literals ("0x...") // ...but misinterprets leading-number strings, particularly hex literals ("0x...")
// subtraction forces infinities to NaN // subtraction forces infinities to NaN
return !jQuery.isArray( obj ) && obj - parseFloat( obj ) >= 0; // adding 1 corrects loss of precision from parseFloat (#15100)
return !jQuery.isArray( obj ) && (obj - parseFloat( obj ) + 1) >= 0;
}, },
isPlainObject: function( obj ) { isPlainObject: function( obj ) {
...@@ -303,7 +301,7 @@ jQuery.extend({ ...@@ -303,7 +301,7 @@ jQuery.extend({
if ( obj == null ) { if ( obj == null ) {
return obj + ""; return obj + "";
} }
// Support: Android < 4.0, iOS < 6 (functionish RegExp) // Support: Android<4.0, iOS<6 (functionish RegExp)
return typeof obj === "object" || typeof obj === "function" ? return typeof obj === "object" || typeof obj === "function" ?
class2type[ toString.call(obj) ] || "object" : class2type[ toString.call(obj) ] || "object" :
typeof obj; typeof obj;
...@@ -333,6 +331,7 @@ jQuery.extend({ ...@@ -333,6 +331,7 @@ jQuery.extend({
}, },
// Convert dashed to camelCase; used by the css and data modules // Convert dashed to camelCase; used by the css and data modules
// Support: IE9-11+
// Microsoft forgot to hump their vendor prefix (#9572) // Microsoft forgot to hump their vendor prefix (#9572)
camelCase: function( string ) { camelCase: function( string ) {
return string.replace( rmsPrefix, "ms-" ).replace( rdashAlpha, fcamelCase ); return string.replace( rmsPrefix, "ms-" ).replace( rdashAlpha, fcamelCase );
...@@ -548,14 +547,14 @@ function isArraylike( obj ) { ...@@ -548,14 +547,14 @@ function isArraylike( obj ) {
} }
var Sizzle = var Sizzle =
/*! /*!
* Sizzle CSS Selector Engine v1.10.19 * Sizzle CSS Selector Engine v2.2.0-pre
* http://sizzlejs.com/ * http://sizzlejs.com/
* *
* Copyright 2013 jQuery Foundation, Inc. and other contributors * Copyright 2008, 2014 jQuery Foundation, Inc. and other contributors
* Released under the MIT license * Released under the MIT license
* http://jquery.org/license * http://jquery.org/license
* *
* Date: 2014-04-18 * Date: 2014-12-16
*/ */
(function( window ) { (function( window ) {
...@@ -582,7 +581,7 @@ var i, ...@@ -582,7 +581,7 @@ var i,
contains, contains,
// Instance-specific data // Instance-specific data
expando = "sizzle" + -(new Date()), expando = "sizzle" + 1 * new Date(),
preferredDoc = window.document, preferredDoc = window.document,
dirruns = 0, dirruns = 0,
done = 0, done = 0,
...@@ -597,7 +596,6 @@ var i, ...@@ -597,7 +596,6 @@ var i,
}, },
// General-purpose constants // General-purpose constants
strundefined = typeof undefined,
MAX_NEGATIVE = 1 << 31, MAX_NEGATIVE = 1 << 31,
// Instance methods // Instance methods
...@@ -607,12 +605,13 @@ var i, ...@@ -607,12 +605,13 @@ var i,
push_native = arr.push, push_native = arr.push,
push = arr.push, push = arr.push,
slice = arr.slice, slice = arr.slice,
// Use a stripped-down indexOf if we can't use a native one // Use a stripped-down indexOf as it's faster than native
indexOf = arr.indexOf || function( elem ) { // http://jsperf.com/thor-indexof-vs-for/5
indexOf = function( list, elem ) {
var i = 0, var i = 0,
len = this.length; len = list.length;
for ( ; i < len; i++ ) { for ( ; i < len; i++ ) {
if ( this[i] === elem ) { if ( list[i] === elem ) {
return i; return i;
} }
} }
...@@ -652,6 +651,7 @@ var i, ...@@ -652,6 +651,7 @@ var i,
")\\)|)", ")\\)|)",
// Leading and non-escaped trailing whitespace, capturing some non-whitespace characters preceding the latter // Leading and non-escaped trailing whitespace, capturing some non-whitespace characters preceding the latter
rwhitespace = new RegExp( whitespace + "+", "g" ),
rtrim = new RegExp( "^" + whitespace + "+|((?:^|[^\\\\])(?:\\\\.)*)" + whitespace + "+$", "g" ), rtrim = new RegExp( "^" + whitespace + "+|((?:^|[^\\\\])(?:\\\\.)*)" + whitespace + "+$", "g" ),
rcomma = new RegExp( "^" + whitespace + "*," + whitespace + "*" ), rcomma = new RegExp( "^" + whitespace + "*," + whitespace + "*" ),
...@@ -703,6 +703,14 @@ var i, ...@@ -703,6 +703,14 @@ var i,
String.fromCharCode( high + 0x10000 ) : String.fromCharCode( high + 0x10000 ) :
// Supplemental Plane codepoint (surrogate pair) // Supplemental Plane codepoint (surrogate pair)
String.fromCharCode( high >> 10 | 0xD800, high & 0x3FF | 0xDC00 ); String.fromCharCode( high >> 10 | 0xD800, high & 0x3FF | 0xDC00 );
},
// Used for iframes
// See setDocument()
// Removing the function wrapper causes a "Permission Denied"
// error in IE
unloadHandler = function() {
setDocument();
}; };
// Optimize for push.apply( _, NodeList ) // Optimize for push.apply( _, NodeList )
...@@ -745,19 +753,18 @@ function Sizzle( selector, context, results, seed ) { ...@@ -745,19 +753,18 @@ function Sizzle( selector, context, results, seed ) {
context = context || document; context = context || document;
results = results || []; results = results || [];
nodeType = context.nodeType;
if ( !selector || typeof selector !== "string" ) { if ( typeof selector !== "string" || !selector ||
return results; nodeType !== 1 && nodeType !== 9 && nodeType !== 11 ) {
}
if ( (nodeType = context.nodeType) !== 1 && nodeType !== 9 ) { return results;
return [];
} }
if ( documentIsHTML && !seed ) { if ( !seed && documentIsHTML ) {
// Shortcuts // Try to shortcut find operations when possible (e.g., not under DocumentFragment)
if ( (match = rquickExpr.exec( selector )) ) { if ( nodeType !== 11 && (match = rquickExpr.exec( selector )) ) {
// Speed-up: Sizzle("#ID") // Speed-up: Sizzle("#ID")
if ( (m = match[1]) ) { if ( (m = match[1]) ) {
if ( nodeType === 9 ) { if ( nodeType === 9 ) {
...@@ -789,7 +796,7 @@ function Sizzle( selector, context, results, seed ) { ...@@ -789,7 +796,7 @@ function Sizzle( selector, context, results, seed ) {
return results; return results;
// Speed-up: Sizzle(".CLASS") // Speed-up: Sizzle(".CLASS")
} else if ( (m = match[3]) && support.getElementsByClassName && context.getElementsByClassName ) { } else if ( (m = match[3]) && support.getElementsByClassName ) {
push.apply( results, context.getElementsByClassName( m ) ); push.apply( results, context.getElementsByClassName( m ) );
return results; return results;
} }
...@@ -799,7 +806,7 @@ function Sizzle( selector, context, results, seed ) { ...@@ -799,7 +806,7 @@ function Sizzle( selector, context, results, seed ) {
if ( support.qsa && (!rbuggyQSA || !rbuggyQSA.test( selector )) ) { if ( support.qsa && (!rbuggyQSA || !rbuggyQSA.test( selector )) ) {
nid = old = expando; nid = old = expando;
newContext = context; newContext = context;
newSelector = nodeType === 9 && selector; newSelector = nodeType !== 1 && selector;
// qSA works strangely on Element-rooted queries // qSA works strangely on Element-rooted queries
// We can work around this by specifying an extra ID on the root // We can work around this by specifying an extra ID on the root
...@@ -986,7 +993,7 @@ function createPositionalPseudo( fn ) { ...@@ -986,7 +993,7 @@ function createPositionalPseudo( fn ) {
* @returns {Element|Object|Boolean} The input node if acceptable, otherwise a falsy value * @returns {Element|Object|Boolean} The input node if acceptable, otherwise a falsy value
*/ */
function testContext( context ) { function testContext( context ) {
return context && typeof context.getElementsByTagName !== strundefined && context; return context && typeof context.getElementsByTagName !== "undefined" && context;
} }
// Expose support vars for convenience // Expose support vars for convenience
...@@ -1010,9 +1017,8 @@ isXML = Sizzle.isXML = function( elem ) { ...@@ -1010,9 +1017,8 @@ isXML = Sizzle.isXML = function( elem ) {
* @returns {Object} Returns the current document * @returns {Object} Returns the current document
*/ */
setDocument = Sizzle.setDocument = function( node ) { setDocument = Sizzle.setDocument = function( node ) {
var hasCompare, var hasCompare, parent,
doc = node ? node.ownerDocument || node : preferredDoc, doc = node ? node.ownerDocument || node : preferredDoc;
parent = doc.defaultView;
// If no document and documentElement is available, return // If no document and documentElement is available, return
if ( doc === document || doc.nodeType !== 9 || !doc.documentElement ) { if ( doc === document || doc.nodeType !== 9 || !doc.documentElement ) {
...@@ -1022,9 +1028,7 @@ setDocument = Sizzle.setDocument = function( node ) { ...@@ -1022,9 +1028,7 @@ setDocument = Sizzle.setDocument = function( node ) {
// Set our document // Set our document
document = doc; document = doc;
docElem = doc.documentElement; docElem = doc.documentElement;
parent = doc.defaultView;
// Support tests
documentIsHTML = !isXML( doc );
// Support: IE>8 // Support: IE>8
// If iframe document is assigned to "document" variable and if iframe has been reloaded, // If iframe document is assigned to "document" variable and if iframe has been reloaded,
...@@ -1033,21 +1037,22 @@ setDocument = Sizzle.setDocument = function( node ) { ...@@ -1033,21 +1037,22 @@ setDocument = Sizzle.setDocument = function( node ) {
if ( parent && parent !== parent.top ) { if ( parent && parent !== parent.top ) {
// IE11 does not have attachEvent, so all must suffer // IE11 does not have attachEvent, so all must suffer
if ( parent.addEventListener ) { if ( parent.addEventListener ) {
parent.addEventListener( "unload", function() { parent.addEventListener( "unload", unloadHandler, false );
setDocument();
}, false );
} else if ( parent.attachEvent ) { } else if ( parent.attachEvent ) {
parent.attachEvent( "onunload", function() { parent.attachEvent( "onunload", unloadHandler );
setDocument();
});
} }
} }
/* Support tests
---------------------------------------------------------------------- */
documentIsHTML = !isXML( doc );
/* Attributes /* Attributes
---------------------------------------------------------------------- */ ---------------------------------------------------------------------- */
// Support: IE<8 // Support: IE<8
// Verify that getAttribute really returns attributes and not properties (excepting IE8 booleans) // Verify that getAttribute really returns attributes and not properties
// (excepting IE8 booleans)
support.attributes = assert(function( div ) { support.attributes = assert(function( div ) {
div.className = "i"; div.className = "i";
return !div.getAttribute("className"); return !div.getAttribute("className");
...@@ -1062,17 +1067,8 @@ setDocument = Sizzle.setDocument = function( node ) { ...@@ -1062,17 +1067,8 @@ setDocument = Sizzle.setDocument = function( node ) {
return !div.getElementsByTagName("*").length; return !div.getElementsByTagName("*").length;
}); });
// Check if getElementsByClassName can be trusted // Support: IE<9
support.getElementsByClassName = rnative.test( doc.getElementsByClassName ) && assert(function( div ) { support.getElementsByClassName = rnative.test( doc.getElementsByClassName );
div.innerHTML = "<div class='a'></div><div class='a i'></div>";
// Support: Safari<4
// Catch class over-caching
div.firstChild.className = "i";
// Support: Opera<10
// Catch gEBCN failure to find non-leading classes
return div.getElementsByClassName("i").length === 2;
});
// Support: IE<10 // Support: IE<10
// Check if getElementById returns elements by name // Check if getElementById returns elements by name
...@@ -1086,7 +1082,7 @@ setDocument = Sizzle.setDocument = function( node ) { ...@@ -1086,7 +1082,7 @@ setDocument = Sizzle.setDocument = function( node ) {
// ID find and filter // ID find and filter
if ( support.getById ) { if ( support.getById ) {
Expr.find["ID"] = function( id, context ) { Expr.find["ID"] = function( id, context ) {
if ( typeof context.getElementById !== strundefined && documentIsHTML ) { if ( typeof context.getElementById !== "undefined" && documentIsHTML ) {
var m = context.getElementById( id ); var m = context.getElementById( id );
// Check parentNode to catch when Blackberry 4.6 returns // 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 #6963
...@@ -1107,7 +1103,7 @@ setDocument = Sizzle.setDocument = function( node ) { ...@@ -1107,7 +1103,7 @@ setDocument = Sizzle.setDocument = function( node ) {
Expr.filter["ID"] = function( id ) { Expr.filter["ID"] = function( id ) {
var attrId = id.replace( runescape, funescape ); var attrId = id.replace( runescape, funescape );
return function( elem ) { return function( elem ) {
var node = typeof elem.getAttributeNode !== strundefined && elem.getAttributeNode("id"); var node = typeof elem.getAttributeNode !== "undefined" && elem.getAttributeNode("id");
return node && node.value === attrId; return node && node.value === attrId;
}; };
}; };
...@@ -1116,14 +1112,20 @@ setDocument = Sizzle.setDocument = function( node ) { ...@@ -1116,14 +1112,20 @@ setDocument = Sizzle.setDocument = function( node ) {
// Tag // Tag
Expr.find["TAG"] = support.getElementsByTagName ? Expr.find["TAG"] = support.getElementsByTagName ?
function( tag, context ) { function( tag, context ) {
if ( typeof context.getElementsByTagName !== strundefined ) { if ( typeof context.getElementsByTagName !== "undefined" ) {
return context.getElementsByTagName( tag ); return context.getElementsByTagName( tag );
// DocumentFragment nodes don't have gEBTN
} else if ( support.qsa ) {
return context.querySelectorAll( tag );
} }
} : } :
function( tag, context ) { function( tag, context ) {
var elem, var elem,
tmp = [], tmp = [],
i = 0, i = 0,
// By happy coincidence, a (broken) gEBTN appears on DocumentFragment nodes too
results = context.getElementsByTagName( tag ); results = context.getElementsByTagName( tag );
// Filter out possible comments // Filter out possible comments
...@@ -1141,7 +1143,7 @@ setDocument = Sizzle.setDocument = function( node ) { ...@@ -1141,7 +1143,7 @@ setDocument = Sizzle.setDocument = function( node ) {
// Class // Class
Expr.find["CLASS"] = support.getElementsByClassName && function( className, context ) { Expr.find["CLASS"] = support.getElementsByClassName && function( className, context ) {
if ( typeof context.getElementsByClassName !== strundefined && documentIsHTML ) { if ( documentIsHTML ) {
return context.getElementsByClassName( className ); return context.getElementsByClassName( className );
} }
}; };
...@@ -1170,13 +1172,15 @@ setDocument = Sizzle.setDocument = function( node ) { ...@@ -1170,13 +1172,15 @@ setDocument = Sizzle.setDocument = function( node ) {
// setting a boolean content attribute, // setting a boolean content attribute,
// since its presence should be enough // since its presence should be enough
// http://bugs.jquery.com/ticket/12359 // http://bugs.jquery.com/ticket/12359
div.innerHTML = "<select msallowclip=''><option selected=''></option></select>"; docElem.appendChild( div ).innerHTML = "<a id='" + expando + "'></a>" +
"<select id='" + expando + "-\f]' msallowcapture=''>" +
"<option selected=''></option></select>";
// Support: IE8, Opera 11-12.16 // Support: IE8, Opera 11-12.16
// Nothing should be selected when empty strings follow ^= or $= or *= // Nothing should be selected when empty strings follow ^= or $= or *=
// The test attribute must be unknown in Opera but "safe" for WinRT // The test attribute must be unknown in Opera but "safe" for WinRT
// http://msdn.microsoft.com/en-us/library/ie/hh465388.aspx#attribute_section // http://msdn.microsoft.com/en-us/library/ie/hh465388.aspx#attribute_section
if ( div.querySelectorAll("[msallowclip^='']").length ) { if ( div.querySelectorAll("[msallowcapture^='']").length ) {
rbuggyQSA.push( "[*^$]=" + whitespace + "*(?:''|\"\")" ); rbuggyQSA.push( "[*^$]=" + whitespace + "*(?:''|\"\")" );
} }
...@@ -1186,12 +1190,24 @@ setDocument = Sizzle.setDocument = function( node ) { ...@@ -1186,12 +1190,24 @@ setDocument = Sizzle.setDocument = function( node ) {
rbuggyQSA.push( "\\[" + whitespace + "*(?:value|" + booleans + ")" ); rbuggyQSA.push( "\\[" + whitespace + "*(?:value|" + booleans + ")" );
} }
// Support: Chrome<29, Android<4.2+, Safari<7.0+, iOS<7.0+, PhantomJS<1.9.7+
if ( !div.querySelectorAll( "[id~=" + expando + "-]" ).length ) {
rbuggyQSA.push("~=");
}
// Webkit/Opera - :checked should return selected option elements // Webkit/Opera - :checked should return selected option elements
// http://www.w3.org/TR/2011/REC-css3-selectors-20110929/#checked // http://www.w3.org/TR/2011/REC-css3-selectors-20110929/#checked
// IE8 throws error here and will not see later tests // IE8 throws error here and will not see later tests
if ( !div.querySelectorAll(":checked").length ) { if ( !div.querySelectorAll(":checked").length ) {
rbuggyQSA.push(":checked"); rbuggyQSA.push(":checked");
} }
// Support: Safari 8+, iOS 8+
// https://bugs.webkit.org/show_bug.cgi?id=136851
// In-page `selector#id sibing-combinator selector` fails
if ( !div.querySelectorAll( "a#" + expando + "+*" ).length ) {
rbuggyQSA.push(".#.+[+~]");
}
}); });
assert(function( div ) { assert(function( div ) {
...@@ -1308,7 +1324,7 @@ setDocument = Sizzle.setDocument = function( node ) { ...@@ -1308,7 +1324,7 @@ setDocument = Sizzle.setDocument = function( node ) {
// Maintain original order // Maintain original order
return sortInput ? return sortInput ?
( indexOf.call( sortInput, a ) - indexOf.call( sortInput, b ) ) : ( indexOf( sortInput, a ) - indexOf( sortInput, b ) ) :
0; 0;
} }
...@@ -1335,7 +1351,7 @@ setDocument = Sizzle.setDocument = function( node ) { ...@@ -1335,7 +1351,7 @@ setDocument = Sizzle.setDocument = function( node ) {
aup ? -1 : aup ? -1 :
bup ? 1 : bup ? 1 :
sortInput ? sortInput ?
( indexOf.call( sortInput, a ) - indexOf.call( sortInput, b ) ) : ( indexOf( sortInput, a ) - indexOf( sortInput, b ) ) :
0; 0;
// If the nodes are siblings, we can do a quick check // If the nodes are siblings, we can do a quick check
...@@ -1398,7 +1414,7 @@ Sizzle.matchesSelector = function( elem, expr ) { ...@@ -1398,7 +1414,7 @@ Sizzle.matchesSelector = function( elem, expr ) {
elem.document && elem.document.nodeType !== 11 ) { elem.document && elem.document.nodeType !== 11 ) {
return ret; return ret;
} }
} catch(e) {} } catch (e) {}
} }
return Sizzle( expr, document, null, [ elem ] ).length > 0; return Sizzle( expr, document, null, [ elem ] ).length > 0;
...@@ -1617,7 +1633,7 @@ Expr = Sizzle.selectors = { ...@@ -1617,7 +1633,7 @@ Expr = Sizzle.selectors = {
return pattern || return pattern ||
(pattern = new RegExp( "(^|" + whitespace + ")" + className + "(" + whitespace + "|$)" )) && (pattern = new RegExp( "(^|" + whitespace + ")" + className + "(" + whitespace + "|$)" )) &&
classCache( className, function( elem ) { classCache( className, function( elem ) {
return pattern.test( typeof elem.className === "string" && elem.className || typeof elem.getAttribute !== strundefined && elem.getAttribute("class") || "" ); return pattern.test( typeof elem.className === "string" && elem.className || typeof elem.getAttribute !== "undefined" && elem.getAttribute("class") || "" );
}); });
}, },
...@@ -1639,7 +1655,7 @@ Expr = Sizzle.selectors = { ...@@ -1639,7 +1655,7 @@ Expr = Sizzle.selectors = {
operator === "^=" ? check && result.indexOf( check ) === 0 : operator === "^=" ? check && result.indexOf( check ) === 0 :
operator === "*=" ? check && result.indexOf( check ) > -1 : operator === "*=" ? check && result.indexOf( check ) > -1 :
operator === "$=" ? check && result.slice( -check.length ) === check : operator === "$=" ? check && result.slice( -check.length ) === check :
operator === "~=" ? ( " " + result + " " ).indexOf( check ) > -1 : operator === "~=" ? ( " " + result.replace( rwhitespace, " " ) + " " ).indexOf( check ) > -1 :
operator === "|=" ? result === check || result.slice( 0, check.length + 1 ) === check + "-" : operator === "|=" ? result === check || result.slice( 0, check.length + 1 ) === check + "-" :
false; false;
}; };
...@@ -1759,7 +1775,7 @@ Expr = Sizzle.selectors = { ...@@ -1759,7 +1775,7 @@ Expr = Sizzle.selectors = {
matched = fn( seed, argument ), matched = fn( seed, argument ),
i = matched.length; i = matched.length;
while ( i-- ) { while ( i-- ) {
idx = indexOf.call( seed, matched[i] ); idx = indexOf( seed, matched[i] );
seed[ idx ] = !( matches[ idx ] = matched[i] ); seed[ idx ] = !( matches[ idx ] = matched[i] );
} }
}) : }) :
...@@ -1798,6 +1814,8 @@ Expr = Sizzle.selectors = { ...@@ -1798,6 +1814,8 @@ Expr = Sizzle.selectors = {
function( elem, context, xml ) { function( elem, context, xml ) {
input[0] = elem; input[0] = elem;
matcher( input, null, xml, results ); matcher( input, null, xml, results );
// Don't keep the element (issue #299)
input[0] = null;
return !results.pop(); return !results.pop();
}; };
}), }),
...@@ -1809,6 +1827,7 @@ Expr = Sizzle.selectors = { ...@@ -1809,6 +1827,7 @@ Expr = Sizzle.selectors = {
}), }),
"contains": markFunction(function( text ) { "contains": markFunction(function( text ) {
text = text.replace( runescape, funescape );
return function( elem ) { return function( elem ) {
return ( elem.textContent || elem.innerText || getText( elem ) ).indexOf( text ) > -1; return ( elem.textContent || elem.innerText || getText( elem ) ).indexOf( text ) > -1;
}; };
...@@ -2230,7 +2249,7 @@ function setMatcher( preFilter, selector, matcher, postFilter, postFinder, postS ...@@ -2230,7 +2249,7 @@ function setMatcher( preFilter, selector, matcher, postFilter, postFinder, postS
i = matcherOut.length; i = matcherOut.length;
while ( i-- ) { while ( i-- ) {
if ( (elem = matcherOut[i]) && if ( (elem = matcherOut[i]) &&
(temp = postFinder ? indexOf.call( seed, elem ) : preMap[i]) > -1 ) { (temp = postFinder ? indexOf( seed, elem ) : preMap[i]) > -1 ) {
seed[temp] = !(results[temp] = elem); seed[temp] = !(results[temp] = elem);
} }
...@@ -2265,13 +2284,16 @@ function matcherFromTokens( tokens ) { ...@@ -2265,13 +2284,16 @@ function matcherFromTokens( tokens ) {
return elem === checkContext; return elem === checkContext;
}, implicitRelative, true ), }, implicitRelative, true ),
matchAnyContext = addCombinator( function( elem ) { matchAnyContext = addCombinator( function( elem ) {
return indexOf.call( checkContext, elem ) > -1; return indexOf( checkContext, elem ) > -1;
}, implicitRelative, true ), }, implicitRelative, true ),
matchers = [ function( elem, context, xml ) { matchers = [ function( elem, context, xml ) {
return ( !leadingRelative && ( xml || context !== outermostContext ) ) || ( var ret = ( !leadingRelative && ( xml || context !== outermostContext ) ) || (
(checkContext = context).nodeType ? (checkContext = context).nodeType ?
matchContext( elem, context, xml ) : matchContext( elem, context, xml ) :
matchAnyContext( elem, context, xml ) ); matchAnyContext( elem, context, xml ) );
// Avoid hanging onto element (issue #299)
checkContext = null;
return ret;
} ]; } ];
for ( ; i < len; i++ ) { for ( ; i < len; i++ ) {
...@@ -2521,7 +2543,7 @@ select = Sizzle.select = function( selector, context, results, seed ) { ...@@ -2521,7 +2543,7 @@ select = Sizzle.select = function( selector, context, results, seed ) {
// Sort stability // Sort stability
support.sortStable = expando.split("").sort( sortOrder ).join("") === expando; support.sortStable = expando.split("").sort( sortOrder ).join("") === expando;
// Support: Chrome<14 // Support: Chrome 14-35+
// Always assume duplicates if they aren't passed to the comparison function // Always assume duplicates if they aren't passed to the comparison function
support.detectDuplicates = !!hasDuplicate; support.detectDuplicates = !!hasDuplicate;
...@@ -2730,7 +2752,7 @@ var rootjQuery, ...@@ -2730,7 +2752,7 @@ var rootjQuery,
if ( match[1] ) { if ( match[1] ) {
context = context instanceof jQuery ? context[0] : context; context = context instanceof jQuery ? context[0] : context;
// scripts is true for back-compat // Option to run scripts is true for back-compat
// Intentionally let the error be thrown if parseHTML is not present // Intentionally let the error be thrown if parseHTML is not present
jQuery.merge( this, jQuery.parseHTML( jQuery.merge( this, jQuery.parseHTML(
match[1], match[1],
...@@ -2758,8 +2780,8 @@ var rootjQuery, ...@@ -2758,8 +2780,8 @@ var rootjQuery,
} else { } else {
elem = document.getElementById( match[2] ); elem = document.getElementById( match[2] );
// Check parentNode to catch when Blackberry 4.6 returns // Support: Blackberry 4.6
// nodes that are no longer in the document #6963 // gEBID returns nodes no longer in the document (#6963)
if ( elem && elem.parentNode ) { if ( elem && elem.parentNode ) {
// Inject the element directly into the jQuery object // Inject the element directly into the jQuery object
this.length = 1; this.length = 1;
...@@ -2812,7 +2834,7 @@ rootjQuery = jQuery( document ); ...@@ -2812,7 +2834,7 @@ rootjQuery = jQuery( document );
var rparentsprev = /^(?:parents|prev(?:Until|All))/, var rparentsprev = /^(?:parents|prev(?:Until|All))/,
// methods guaranteed to produce a unique set when starting from a unique set // Methods guaranteed to produce a unique set when starting from a unique set
guaranteedUnique = { guaranteedUnique = {
children: true, children: true,
contents: true, contents: true,
...@@ -2892,8 +2914,7 @@ jQuery.fn.extend({ ...@@ -2892,8 +2914,7 @@ jQuery.fn.extend({
return this.pushStack( matched.length > 1 ? jQuery.unique( matched ) : matched ); return this.pushStack( matched.length > 1 ? jQuery.unique( matched ) : matched );
}, },
// Determine the position of an element within // Determine the position of an element within the set
// the matched set of elements
index: function( elem ) { index: function( elem ) {
// No argument, return index in parent // No argument, return index in parent
...@@ -2901,7 +2922,7 @@ jQuery.fn.extend({ ...@@ -2901,7 +2922,7 @@ jQuery.fn.extend({
return ( this[ 0 ] && this[ 0 ].parentNode ) ? this.first().prevAll().length : -1; return ( this[ 0 ] && this[ 0 ].parentNode ) ? this.first().prevAll().length : -1;
} }
// index in selector // Index in selector
if ( typeof elem === "string" ) { if ( typeof elem === "string" ) {
return indexOf.call( jQuery( elem ), this[ 0 ] ); return indexOf.call( jQuery( elem ), this[ 0 ] );
} }
...@@ -3317,7 +3338,7 @@ jQuery.extend({ ...@@ -3317,7 +3338,7 @@ jQuery.extend({
progressValues, progressContexts, resolveContexts; progressValues, progressContexts, resolveContexts;
// add listeners to Deferred subordinates; treat others as resolved // Add listeners to Deferred subordinates; treat others as resolved
if ( length > 1 ) { if ( length > 1 ) {
progressValues = new Array( length ); progressValues = new Array( length );
progressContexts = new Array( length ); progressContexts = new Array( length );
...@@ -3334,7 +3355,7 @@ jQuery.extend({ ...@@ -3334,7 +3355,7 @@ jQuery.extend({
} }
} }
// if we're not waiting on anything, resolve the master // If we're not waiting on anything, resolve the master
if ( !remaining ) { if ( !remaining ) {
deferred.resolveWith( resolveContexts, resolveValues ); deferred.resolveWith( resolveContexts, resolveValues );
} }
...@@ -3413,7 +3434,7 @@ jQuery.ready.promise = function( obj ) { ...@@ -3413,7 +3434,7 @@ jQuery.ready.promise = function( obj ) {
readyList = jQuery.Deferred(); readyList = jQuery.Deferred();
// Catch cases where $(document).ready() is called after the browser event has already occurred. // 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 // 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 // discovered by ChrisS here: http://bugs.jquery.com/ticket/12282#comment:15
if ( document.readyState === "complete" ) { if ( document.readyState === "complete" ) {
// Handle it asynchronously to allow scripts the opportunity to delay ready // Handle it asynchronously to allow scripts the opportunity to delay ready
...@@ -3507,7 +3528,7 @@ jQuery.acceptData = function( owner ) { ...@@ -3507,7 +3528,7 @@ jQuery.acceptData = function( owner ) {
function Data() { function Data() {
// Support: Android < 4, // Support: Android<4,
// Old WebKit does not have Object.preventExtensions/freeze method, // Old WebKit does not have Object.preventExtensions/freeze method,
// return new empty object instead with no [[set]] accessor // return new empty object instead with no [[set]] accessor
Object.defineProperty( this.cache = {}, 0, { Object.defineProperty( this.cache = {}, 0, {
...@@ -3516,7 +3537,7 @@ function Data() { ...@@ -3516,7 +3537,7 @@ function Data() {
} }
}); });
this.expando = jQuery.expando + Math.random(); this.expando = jQuery.expando + Data.uid++;
} }
Data.uid = 1; Data.uid = 1;
...@@ -3544,7 +3565,7 @@ Data.prototype = { ...@@ -3544,7 +3565,7 @@ Data.prototype = {
descriptor[ this.expando ] = { value: unlock }; descriptor[ this.expando ] = { value: unlock };
Object.defineProperties( owner, descriptor ); Object.defineProperties( owner, descriptor );
// Support: Android < 4 // Support: Android<4
// Fallback to a less secure definition // Fallback to a less secure definition
} catch ( e ) { } catch ( e ) {
descriptor[ this.expando ] = unlock; descriptor[ this.expando ] = unlock;
...@@ -3684,17 +3705,16 @@ var data_user = new Data(); ...@@ -3684,17 +3705,16 @@ var data_user = new Data();
/* // Implementation Summary
Implementation Summary //
// 1. Enforce API surface and semantic compatibility with 1.9.x branch
1. Enforce API surface and semantic compatibility with 1.9.x branch // 2. Improve the module's maintainability by reducing the storage
2. Improve the module's maintainability by reducing the storage // paths to a single mechanism.
paths to a single mechanism. // 3. Use the same single mechanism to support "private" and "user" data.
3. Use the same single mechanism to support "private" and "user" data. // 4. _Never_ expose "private" data to user code (TODO: Drop _data, _removeData)
4. _Never_ expose "private" data to user code (TODO: Drop _data, _removeData) // 5. Avoid exposing implementation details on user objects (eg. expando properties)
5. Avoid exposing implementation details on user objects (eg. expando properties) // 6. Provide a clear path for implementation upgrade to WeakMap in 2014
6. Provide a clear path for implementation upgrade to WeakMap in 2014
*/
var rbrace = /^(?:\{[\w\W]*\}|\[[\w\W]*\])$/, var rbrace = /^(?:\{[\w\W]*\}|\[[\w\W]*\])$/,
rmultiDash = /([A-Z])/g; rmultiDash = /([A-Z])/g;
...@@ -3899,7 +3919,7 @@ jQuery.extend({ ...@@ -3899,7 +3919,7 @@ jQuery.extend({
queue.unshift( "inprogress" ); queue.unshift( "inprogress" );
} }
// clear up the last queue stop function // Clear up the last queue stop function
delete hooks.stop; delete hooks.stop;
fn.call( elem, next, hooks ); fn.call( elem, next, hooks );
} }
...@@ -3909,7 +3929,7 @@ jQuery.extend({ ...@@ -3909,7 +3929,7 @@ jQuery.extend({
} }
}, },
// not intended for public consumption - generates a queueHooks object, or returns the current one // Not public - generate a queueHooks object, or return the current one
_queueHooks: function( elem, type ) { _queueHooks: function( elem, type ) {
var key = type + "queueHooks"; var key = type + "queueHooks";
return data_priv.get( elem, key ) || data_priv.access( elem, key, { return data_priv.get( elem, key ) || data_priv.access( elem, key, {
...@@ -3939,7 +3959,7 @@ jQuery.fn.extend({ ...@@ -3939,7 +3959,7 @@ jQuery.fn.extend({
this.each(function() { this.each(function() {
var queue = jQuery.queue( this, type, data ); var queue = jQuery.queue( this, type, data );
// ensure a hooks for this queue // Ensure a hooks for this queue
jQuery._queueHooks( this, type ); jQuery._queueHooks( this, type );
if ( type === "fx" && queue[0] !== "inprogress" ) { if ( type === "fx" && queue[0] !== "inprogress" ) {
...@@ -4006,21 +4026,22 @@ var rcheckableType = (/^(?:checkbox|radio)$/i); ...@@ -4006,21 +4026,22 @@ var rcheckableType = (/^(?:checkbox|radio)$/i);
div = fragment.appendChild( document.createElement( "div" ) ), div = fragment.appendChild( document.createElement( "div" ) ),
input = document.createElement( "input" ); input = document.createElement( "input" );
// #11217 - WebKit loses check when the name is after the checked attribute // Support: Safari<=5.1
// Check state lost if the name is set (#11217)
// Support: Windows Web Apps (WWA) // Support: Windows Web Apps (WWA)
// `name` and `type` need .setAttribute for WWA // `name` and `type` must use .setAttribute for WWA (#14901)
input.setAttribute( "type", "radio" ); input.setAttribute( "type", "radio" );
input.setAttribute( "checked", "checked" ); input.setAttribute( "checked", "checked" );
input.setAttribute( "name", "t" ); input.setAttribute( "name", "t" );
div.appendChild( input ); div.appendChild( input );
// Support: Safari 5.1, iOS 5.1, Android 4.x, Android 2.3 // Support: Safari<=5.1, Android<4.2
// old WebKit doesn't clone checked state correctly in fragments // Older WebKit doesn't clone checked state correctly in fragments
support.checkClone = div.cloneNode( true ).cloneNode( true ).lastChild.checked; support.checkClone = div.cloneNode( true ).cloneNode( true ).lastChild.checked;
// Support: IE<=11+
// Make sure textarea (and checkbox) defaultValue is properly cloned // Make sure textarea (and checkbox) defaultValue is properly cloned
// Support: IE9-IE11+
div.innerHTML = "<textarea>x</textarea>"; div.innerHTML = "<textarea>x</textarea>";
support.noCloneChecked = !!div.cloneNode( true ).lastChild.defaultValue; support.noCloneChecked = !!div.cloneNode( true ).lastChild.defaultValue;
})(); })();
...@@ -4398,8 +4419,8 @@ jQuery.event = { ...@@ -4398,8 +4419,8 @@ jQuery.event = {
j = 0; j = 0;
while ( (handleObj = matched.handlers[ j++ ]) && !event.isImmediatePropagationStopped() ) { while ( (handleObj = matched.handlers[ j++ ]) && !event.isImmediatePropagationStopped() ) {
// Triggered event must either 1) have no namespace, or // Triggered event must either 1) have no namespace, or 2) have namespace(s)
// 2) have namespace(s) a subset or equal to those in the bound event (both can have no namespace). // a subset or equal to those in the bound event (both can have no namespace).
if ( !event.namespace_re || event.namespace_re.test( handleObj.namespace ) ) { if ( !event.namespace_re || event.namespace_re.test( handleObj.namespace ) ) {
event.handleObj = handleObj; event.handleObj = handleObj;
...@@ -4549,7 +4570,7 @@ jQuery.event = { ...@@ -4549,7 +4570,7 @@ jQuery.event = {
event.target = document; event.target = document;
} }
// Support: Safari 6.0+, Chrome < 28 // Support: Safari 6.0+, Chrome<28
// Target should not be a text node (#504, #13143) // Target should not be a text node (#504, #13143)
if ( event.target.nodeType === 3 ) { if ( event.target.nodeType === 3 ) {
event.target = event.target.parentNode; event.target = event.target.parentNode;
...@@ -4654,7 +4675,7 @@ jQuery.Event = function( src, props ) { ...@@ -4654,7 +4675,7 @@ jQuery.Event = function( src, props ) {
// by a handler lower down the tree; reflect the correct value. // by a handler lower down the tree; reflect the correct value.
this.isDefaultPrevented = src.defaultPrevented || this.isDefaultPrevented = src.defaultPrevented ||
src.defaultPrevented === undefined && src.defaultPrevented === undefined &&
// Support: Android < 4.0 // Support: Android<4.0
src.returnValue === false ? src.returnValue === false ?
returnTrue : returnTrue :
returnFalse; returnFalse;
...@@ -4744,8 +4765,8 @@ jQuery.each({ ...@@ -4744,8 +4765,8 @@ jQuery.each({
}; };
}); });
// Create "bubbling" focus and blur events
// Support: Firefox, Chrome, Safari // Support: Firefox, Chrome, Safari
// Create "bubbling" focus and blur events
if ( !support.focusinBubbles ) { if ( !support.focusinBubbles ) {
jQuery.each({ focus: "focusin", blur: "focusout" }, function( orig, fix ) { jQuery.each({ focus: "focusin", blur: "focusout" }, function( orig, fix ) {
...@@ -4898,7 +4919,7 @@ var ...@@ -4898,7 +4919,7 @@ var
// We have to close these tags to support XHTML (#13200) // We have to close these tags to support XHTML (#13200)
wrapMap = { wrapMap = {
// Support: IE 9 // Support: IE9
option: [ 1, "<select multiple='multiple'>", "</select>" ], option: [ 1, "<select multiple='multiple'>", "</select>" ],
thead: [ 1, "<table>", "</table>" ], thead: [ 1, "<table>", "</table>" ],
...@@ -4909,7 +4930,7 @@ var ...@@ -4909,7 +4930,7 @@ var
_default: [ 0, "", "" ] _default: [ 0, "", "" ]
}; };
// Support: IE 9 // Support: IE9
wrapMap.optgroup = wrapMap.option; wrapMap.optgroup = wrapMap.option;
wrapMap.tbody = wrapMap.tfoot = wrapMap.colgroup = wrapMap.caption = wrapMap.thead; wrapMap.tbody = wrapMap.tfoot = wrapMap.colgroup = wrapMap.caption = wrapMap.thead;
...@@ -4999,7 +5020,7 @@ function getAll( context, tag ) { ...@@ -4999,7 +5020,7 @@ function getAll( context, tag ) {
ret; ret;
} }
// Support: IE >= 9 // Fix IE bugs, see support tests
function fixInput( src, dest ) { function fixInput( src, dest ) {
var nodeName = dest.nodeName.toLowerCase(); var nodeName = dest.nodeName.toLowerCase();
...@@ -5019,8 +5040,7 @@ jQuery.extend({ ...@@ -5019,8 +5040,7 @@ jQuery.extend({
clone = elem.cloneNode( true ), clone = elem.cloneNode( true ),
inPage = jQuery.contains( elem.ownerDocument, elem ); inPage = jQuery.contains( elem.ownerDocument, elem );
// Support: IE >= 9 // Fix IE cloning issues
// Fix Cloning issues
if ( !support.noCloneChecked && ( elem.nodeType === 1 || elem.nodeType === 11 ) && if ( !support.noCloneChecked && ( elem.nodeType === 1 || elem.nodeType === 11 ) &&
!jQuery.isXMLDoc( elem ) ) { !jQuery.isXMLDoc( elem ) ) {
...@@ -5071,8 +5091,8 @@ jQuery.extend({ ...@@ -5071,8 +5091,8 @@ jQuery.extend({
// Add nodes directly // Add nodes directly
if ( jQuery.type( elem ) === "object" ) { if ( jQuery.type( elem ) === "object" ) {
// Support: QtWebKit // Support: QtWebKit, PhantomJS
// jQuery.merge because push.apply(_, arraylike) throws // push.apply(_, arraylike) throws on ancient WebKit
jQuery.merge( nodes, elem.nodeType ? [ elem ] : elem ); jQuery.merge( nodes, elem.nodeType ? [ elem ] : elem );
// Convert non-html into a text node // Convert non-html into a text node
...@@ -5094,15 +5114,14 @@ jQuery.extend({ ...@@ -5094,15 +5114,14 @@ jQuery.extend({
tmp = tmp.lastChild; tmp = tmp.lastChild;
} }
// Support: QtWebKit // Support: QtWebKit, PhantomJS
// jQuery.merge because push.apply(_, arraylike) throws // push.apply(_, arraylike) throws on ancient WebKit
jQuery.merge( nodes, tmp.childNodes ); jQuery.merge( nodes, tmp.childNodes );
// Remember the top-level container // Remember the top-level container
tmp = fragment.firstChild; tmp = fragment.firstChild;
// Fixes #12346 // Ensure the created nodes are orphaned (#12392)
// Support: Webkit, IE
tmp.textContent = ""; tmp.textContent = "";
} }
} }
...@@ -5464,7 +5483,7 @@ function actualDisplay( name, doc ) { ...@@ -5464,7 +5483,7 @@ function actualDisplay( name, doc ) {
// getDefaultComputedStyle might be reliably used only on attached element // getDefaultComputedStyle might be reliably used only on attached element
display = window.getDefaultComputedStyle && ( style = window.getDefaultComputedStyle( elem[ 0 ] ) ) ? display = window.getDefaultComputedStyle && ( style = window.getDefaultComputedStyle( elem[ 0 ] ) ) ?
// Use of this method is a temporary fix (more like optmization) until something better comes along, // Use of this method is a temporary fix (more like optimization) until something better comes along,
// since it was removed from specification and supported only in FF // since it was removed from specification and supported only in FF
style.display : jQuery.css( elem[ 0 ], "display" ); style.display : jQuery.css( elem[ 0 ], "display" );
...@@ -5514,7 +5533,14 @@ var rmargin = (/^margin/); ...@@ -5514,7 +5533,14 @@ var rmargin = (/^margin/);
var rnumnonpx = new RegExp( "^(" + pnum + ")(?!px)[a-z%]+$", "i" ); var rnumnonpx = new RegExp( "^(" + pnum + ")(?!px)[a-z%]+$", "i" );
var getStyles = function( elem ) { var getStyles = function( elem ) {
// Support: IE<=11+, Firefox<=30+ (#15098, #14150)
// IE throws on elements created in popups
// FF meanwhile throws on frame elements through "defaultView.getComputedStyle"
if ( elem.ownerDocument.defaultView.opener ) {
return elem.ownerDocument.defaultView.getComputedStyle( elem, null ); return elem.ownerDocument.defaultView.getComputedStyle( elem, null );
}
return window.getComputedStyle( elem, null );
}; };
...@@ -5526,7 +5552,7 @@ function curCSS( elem, name, computed ) { ...@@ -5526,7 +5552,7 @@ function curCSS( elem, name, computed ) {
computed = computed || getStyles( elem ); computed = computed || getStyles( elem );
// Support: IE9 // Support: IE9
// getPropertyValue is only needed for .css('filter') in IE9, see #12537 // getPropertyValue is only needed for .css('filter') (#12537)
if ( computed ) { if ( computed ) {
ret = computed.getPropertyValue( name ) || computed[ name ]; ret = computed.getPropertyValue( name ) || computed[ name ];
} }
...@@ -5572,15 +5598,13 @@ function addGetHookIf( conditionFn, hookFn ) { ...@@ -5572,15 +5598,13 @@ function addGetHookIf( conditionFn, hookFn ) {
return { return {
get: function() { get: function() {
if ( conditionFn() ) { if ( conditionFn() ) {
// Hook not needed (or it's not possible to use it due to missing dependency), // Hook not needed (or it's not possible to use it due
// remove it. // to missing dependency), remove it.
// Since there are no other hooks for marginRight, remove the whole object.
delete this.get; delete this.get;
return; return;
} }
// Hook needed; redefine it so that the support test is not executed again. // Hook needed; redefine it so that the support test is not executed again.
return (this.get = hookFn).apply( this, arguments ); return (this.get = hookFn).apply( this, arguments );
} }
}; };
...@@ -5597,6 +5621,8 @@ function addGetHookIf( conditionFn, hookFn ) { ...@@ -5597,6 +5621,8 @@ function addGetHookIf( conditionFn, hookFn ) {
return; return;
} }
// Support: IE9-11+
// Style of cloned element affects source element cloned (#8908)
div.style.backgroundClip = "content-box"; div.style.backgroundClip = "content-box";
div.cloneNode( true ).style.backgroundClip = ""; div.cloneNode( true ).style.backgroundClip = "";
support.clearCloneStyle = div.style.backgroundClip === "content-box"; support.clearCloneStyle = div.style.backgroundClip === "content-box";
...@@ -5629,6 +5655,7 @@ function addGetHookIf( conditionFn, hookFn ) { ...@@ -5629,6 +5655,7 @@ function addGetHookIf( conditionFn, hookFn ) {
if ( window.getComputedStyle ) { if ( window.getComputedStyle ) {
jQuery.extend( support, { jQuery.extend( support, {
pixelPosition: function() { pixelPosition: function() {
// This test is executed only once but we still do memoizing // This test is executed only once but we still do memoizing
// since we can use the boxSizingReliable pre-computing. // since we can use the boxSizingReliable pre-computing.
// No need to check if the test was already performed, though. // No need to check if the test was already performed, though.
...@@ -5642,6 +5669,7 @@ function addGetHookIf( conditionFn, hookFn ) { ...@@ -5642,6 +5669,7 @@ function addGetHookIf( conditionFn, hookFn ) {
return boxSizingReliableVal; return boxSizingReliableVal;
}, },
reliableMarginRight: function() { reliableMarginRight: function() {
// Support: Android 2.3 // Support: Android 2.3
// Check if div with explicit width and no margin-right incorrectly // Check if div with explicit width and no margin-right incorrectly
// gets computed margin-right based on width of container. (#3333) // gets computed margin-right based on width of container. (#3333)
...@@ -5663,6 +5691,7 @@ function addGetHookIf( conditionFn, hookFn ) { ...@@ -5663,6 +5691,7 @@ function addGetHookIf( conditionFn, hookFn ) {
ret = !parseFloat( window.getComputedStyle( marginDiv, null ).marginRight ); ret = !parseFloat( window.getComputedStyle( marginDiv, null ).marginRight );
docElem.removeChild( container ); docElem.removeChild( container );
div.removeChild( marginDiv );
return ret; return ret;
} }
...@@ -5694,8 +5723,8 @@ jQuery.swap = function( elem, options, callback, args ) { ...@@ -5694,8 +5723,8 @@ jQuery.swap = function( elem, options, callback, args ) {
var var
// swappable if display is none or starts with table except "table", "table-cell", or "table-caption" // 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 // See here for display values: https://developer.mozilla.org/en-US/docs/CSS/display
rdisplayswap = /^(none|table(?!-c[ea]).+)/, rdisplayswap = /^(none|table(?!-c[ea]).+)/,
rnumsplit = new RegExp( "^(" + pnum + ")(.*)$", "i" ), rnumsplit = new RegExp( "^(" + pnum + ")(.*)$", "i" ),
rrelNum = new RegExp( "^([+-])=(" + pnum + ")", "i" ), rrelNum = new RegExp( "^([+-])=(" + pnum + ")", "i" ),
...@@ -5708,15 +5737,15 @@ var ...@@ -5708,15 +5737,15 @@ var
cssPrefixes = [ "Webkit", "O", "Moz", "ms" ]; cssPrefixes = [ "Webkit", "O", "Moz", "ms" ];
// return a css property mapped to a potentially vendor prefixed property // Return a css property mapped to a potentially vendor prefixed property
function vendorPropName( style, name ) { function vendorPropName( style, name ) {
// shortcut for names that are not vendor prefixed // Shortcut for names that are not vendor prefixed
if ( name in style ) { if ( name in style ) {
return name; return name;
} }
// check for vendor prefixed names // Check for vendor prefixed names
var capName = name[0].toUpperCase() + name.slice(1), var capName = name[0].toUpperCase() + name.slice(1),
origName = name, origName = name,
i = cssPrefixes.length; i = cssPrefixes.length;
...@@ -5749,7 +5778,7 @@ function augmentWidthOrHeight( elem, name, extra, isBorderBox, styles ) { ...@@ -5749,7 +5778,7 @@ function augmentWidthOrHeight( elem, name, extra, isBorderBox, styles ) {
val = 0; val = 0;
for ( ; i < 4; i += 2 ) { for ( ; i < 4; i += 2 ) {
// both box models exclude margin, so add it if we want it // Both box models exclude margin, so add it if we want it
if ( extra === "margin" ) { if ( extra === "margin" ) {
val += jQuery.css( elem, extra + cssExpand[ i ], true, styles ); val += jQuery.css( elem, extra + cssExpand[ i ], true, styles );
} }
...@@ -5760,15 +5789,15 @@ function augmentWidthOrHeight( elem, name, extra, isBorderBox, styles ) { ...@@ -5760,15 +5789,15 @@ function augmentWidthOrHeight( elem, name, extra, isBorderBox, styles ) {
val -= jQuery.css( elem, "padding" + cssExpand[ i ], true, styles ); val -= jQuery.css( elem, "padding" + cssExpand[ i ], true, styles );
} }
// at this point, extra isn't border nor margin, so remove border // At this point, extra isn't border nor margin, so remove border
if ( extra !== "margin" ) { if ( extra !== "margin" ) {
val -= jQuery.css( elem, "border" + cssExpand[ i ] + "Width", true, styles ); val -= jQuery.css( elem, "border" + cssExpand[ i ] + "Width", true, styles );
} }
} else { } else {
// at this point, extra isn't content, so add padding // At this point, extra isn't content, so add padding
val += jQuery.css( elem, "padding" + cssExpand[ i ], true, styles ); val += jQuery.css( elem, "padding" + cssExpand[ i ], true, styles );
// at this point, extra isn't content nor padding, so add border // At this point, extra isn't content nor padding, so add border
if ( extra !== "padding" ) { if ( extra !== "padding" ) {
val += jQuery.css( elem, "border" + cssExpand[ i ] + "Width", true, styles ); val += jQuery.css( elem, "border" + cssExpand[ i ] + "Width", true, styles );
} }
...@@ -5786,7 +5815,7 @@ function getWidthOrHeight( elem, name, extra ) { ...@@ -5786,7 +5815,7 @@ function getWidthOrHeight( elem, name, extra ) {
styles = getStyles( elem ), styles = getStyles( elem ),
isBorderBox = jQuery.css( elem, "boxSizing", false, styles ) === "border-box"; isBorderBox = jQuery.css( elem, "boxSizing", false, styles ) === "border-box";
// some non-html elements return undefined for offsetWidth, so check for null/undefined // Some non-html elements return undefined for offsetWidth, so check for null/undefined
// svg - https://bugzilla.mozilla.org/show_bug.cgi?id=649285 // svg - https://bugzilla.mozilla.org/show_bug.cgi?id=649285
// MathML - https://bugzilla.mozilla.org/show_bug.cgi?id=491668 // MathML - https://bugzilla.mozilla.org/show_bug.cgi?id=491668
if ( val <= 0 || val == null ) { if ( val <= 0 || val == null ) {
...@@ -5801,7 +5830,7 @@ function getWidthOrHeight( elem, name, extra ) { ...@@ -5801,7 +5830,7 @@ function getWidthOrHeight( elem, name, extra ) {
return val; return val;
} }
// we need the check for style in case a browser which returns unreliable values // Check for style in case a browser which returns unreliable values
// for getComputedStyle silently falls back to the reliable elem.style // for getComputedStyle silently falls back to the reliable elem.style
valueIsBorderBox = isBorderBox && valueIsBorderBox = isBorderBox &&
( support.boxSizingReliable() || val === elem.style[ name ] ); ( support.boxSizingReliable() || val === elem.style[ name ] );
...@@ -5810,7 +5839,7 @@ function getWidthOrHeight( elem, name, extra ) { ...@@ -5810,7 +5839,7 @@ function getWidthOrHeight( elem, name, extra ) {
val = parseFloat( val ) || 0; val = parseFloat( val ) || 0;
} }
// use the active box-sizing model to add/subtract irrelevant styles // Use the active box-sizing model to add/subtract irrelevant styles
return ( val + return ( val +
augmentWidthOrHeight( augmentWidthOrHeight(
elem, elem,
...@@ -5874,12 +5903,14 @@ function showHide( elements, show ) { ...@@ -5874,12 +5903,14 @@ function showHide( elements, show ) {
} }
jQuery.extend({ jQuery.extend({
// Add in style property hooks for overriding the default // Add in style property hooks for overriding the default
// behavior of getting and setting a style property // behavior of getting and setting a style property
cssHooks: { cssHooks: {
opacity: { opacity: {
get: function( elem, computed ) { get: function( elem, computed ) {
if ( computed ) { if ( computed ) {
// We should always get a number back from opacity // We should always get a number back from opacity
var ret = curCSS( elem, "opacity" ); var ret = curCSS( elem, "opacity" );
return ret === "" ? "1" : ret; return ret === "" ? "1" : ret;
...@@ -5907,12 +5938,12 @@ jQuery.extend({ ...@@ -5907,12 +5938,12 @@ jQuery.extend({
// Add in properties whose names you wish to fix before // Add in properties whose names you wish to fix before
// setting or getting the value // setting or getting the value
cssProps: { cssProps: {
// normalize float css property
"float": "cssFloat" "float": "cssFloat"
}, },
// Get and set the style property on a DOM Node // Get and set the style property on a DOM Node
style: function( elem, name, value, extra ) { style: function( elem, name, value, extra ) {
// Don't set styles on text and comment nodes // Don't set styles on text and comment nodes
if ( !elem || elem.nodeType === 3 || elem.nodeType === 8 || !elem.style ) { if ( !elem || elem.nodeType === 3 || elem.nodeType === 8 || !elem.style ) {
return; return;
...@@ -5925,33 +5956,32 @@ jQuery.extend({ ...@@ -5925,33 +5956,32 @@ jQuery.extend({
name = jQuery.cssProps[ origName ] || ( jQuery.cssProps[ origName ] = vendorPropName( style, origName ) ); name = jQuery.cssProps[ origName ] || ( jQuery.cssProps[ origName ] = vendorPropName( style, origName ) );
// gets hook for the prefixed version // Gets hook for the prefixed version, then unprefixed version
// followed by the unprefixed version
hooks = jQuery.cssHooks[ name ] || jQuery.cssHooks[ origName ]; hooks = jQuery.cssHooks[ name ] || jQuery.cssHooks[ origName ];
// Check if we're setting a value // Check if we're setting a value
if ( value !== undefined ) { if ( value !== undefined ) {
type = typeof value; type = typeof value;
// convert relative number strings (+= or -=) to relative numbers. #7345 // Convert "+=" or "-=" to relative numbers (#7345)
if ( type === "string" && (ret = rrelNum.exec( value )) ) { if ( type === "string" && (ret = rrelNum.exec( value )) ) {
value = ( ret[1] + 1 ) * ret[2] + parseFloat( jQuery.css( elem, name ) ); value = ( ret[1] + 1 ) * ret[2] + parseFloat( jQuery.css( elem, name ) );
// Fixes bug #9237 // Fixes bug #9237
type = "number"; type = "number";
} }
// Make sure that null and NaN values aren't set. See: #7116 // Make sure that null and NaN values aren't set (#7116)
if ( value == null || value !== value ) { if ( value == null || value !== value ) {
return; return;
} }
// If a number was passed in, add 'px' to the (except for certain CSS properties) // If a number, add 'px' to the (except for certain CSS properties)
if ( type === "number" && !jQuery.cssNumber[ origName ] ) { if ( type === "number" && !jQuery.cssNumber[ origName ] ) {
value += "px"; value += "px";
} }
// Fixes #8908, it can be done more correctly by specifying setters in cssHooks, // Support: IE9-11+
// but it would mean to define eight (for every problematic property) identical functions // background-* props affect original clone's values
if ( !support.clearCloneStyle && value === "" && name.indexOf( "background" ) === 0 ) { if ( !support.clearCloneStyle && value === "" && name.indexOf( "background" ) === 0 ) {
style[ name ] = "inherit"; style[ name ] = "inherit";
} }
...@@ -5979,8 +6009,7 @@ jQuery.extend({ ...@@ -5979,8 +6009,7 @@ jQuery.extend({
// Make sure that we're working with the right name // Make sure that we're working with the right name
name = jQuery.cssProps[ origName ] || ( jQuery.cssProps[ origName ] = vendorPropName( elem.style, origName ) ); name = jQuery.cssProps[ origName ] || ( jQuery.cssProps[ origName ] = vendorPropName( elem.style, origName ) );
// gets hook for the prefixed version // Try prefixed name followed by the unprefixed name
// followed by the unprefixed version
hooks = jQuery.cssHooks[ name ] || jQuery.cssHooks[ origName ]; hooks = jQuery.cssHooks[ name ] || jQuery.cssHooks[ origName ];
// If a hook was provided get the computed value from there // If a hook was provided get the computed value from there
...@@ -5993,12 +6022,12 @@ jQuery.extend({ ...@@ -5993,12 +6022,12 @@ jQuery.extend({
val = curCSS( elem, name, styles ); val = curCSS( elem, name, styles );
} }
//convert "normal" to computed value // Convert "normal" to computed value
if ( val === "normal" && name in cssNormalTransform ) { if ( val === "normal" && name in cssNormalTransform ) {
val = cssNormalTransform[ name ]; val = cssNormalTransform[ name ];
} }
// Return, converting to number if forced or a qualifier was provided and val looks numeric // Make numeric if forced or a qualifier was provided and val looks numeric
if ( extra === "" || extra ) { if ( extra === "" || extra ) {
num = parseFloat( val ); num = parseFloat( val );
return extra === true || jQuery.isNumeric( num ) ? num || 0 : val; return extra === true || jQuery.isNumeric( num ) ? num || 0 : val;
...@@ -6011,8 +6040,9 @@ jQuery.each([ "height", "width" ], function( i, name ) { ...@@ -6011,8 +6040,9 @@ jQuery.each([ "height", "width" ], function( i, name ) {
jQuery.cssHooks[ name ] = { jQuery.cssHooks[ name ] = {
get: function( elem, computed, extra ) { get: function( elem, computed, extra ) {
if ( computed ) { if ( computed ) {
// certain elements can have dimension info if we invisibly show them
// however, it must have a current display style that would benefit from this // Certain elements can have dimension info if we invisibly show them
// but it must have a current display style that would benefit
return rdisplayswap.test( jQuery.css( elem, "display" ) ) && elem.offsetWidth === 0 ? return rdisplayswap.test( jQuery.css( elem, "display" ) ) && elem.offsetWidth === 0 ?
jQuery.swap( elem, cssShow, function() { jQuery.swap( elem, cssShow, function() {
return getWidthOrHeight( elem, name, extra ); return getWidthOrHeight( elem, name, extra );
...@@ -6040,8 +6070,6 @@ jQuery.each([ "height", "width" ], function( i, name ) { ...@@ -6040,8 +6070,6 @@ jQuery.each([ "height", "width" ], function( i, name ) {
jQuery.cssHooks.marginRight = addGetHookIf( support.reliableMarginRight, jQuery.cssHooks.marginRight = addGetHookIf( support.reliableMarginRight,
function( elem, computed ) { function( elem, computed ) {
if ( computed ) { if ( computed ) {
// WebKit Bug 13343 - getComputedStyle returns wrong value for margin-right
// Work around by temporarily setting element display to inline-block
return jQuery.swap( elem, { "display": "inline-block" }, return jQuery.swap( elem, { "display": "inline-block" },
curCSS, [ elem, "marginRight" ] ); curCSS, [ elem, "marginRight" ] );
} }
...@@ -6059,7 +6087,7 @@ jQuery.each({ ...@@ -6059,7 +6087,7 @@ jQuery.each({
var i = 0, var i = 0,
expanded = {}, expanded = {},
// assumes a single number if not a string // Assumes a single number if not a string
parts = typeof value === "string" ? value.split(" ") : [ value ]; parts = typeof value === "string" ? value.split(" ") : [ value ];
for ( ; i < 4; i++ ) { for ( ; i < 4; i++ ) {
...@@ -6182,17 +6210,18 @@ Tween.propHooks = { ...@@ -6182,17 +6210,18 @@ Tween.propHooks = {
return tween.elem[ tween.prop ]; return tween.elem[ tween.prop ];
} }
// passing an empty string as a 3rd parameter to .css will automatically // Passing an empty string as a 3rd parameter to .css will automatically
// attempt a parseFloat and fallback to a string if the parse fails // attempt a parseFloat and fallback to a string if the parse fails.
// so, simple values such as "10px" are parsed to Float. // Simple values such as "10px" are parsed to Float;
// complex values such as "rotate(1rad)" are returned as is. // complex values such as "rotate(1rad)" are returned as-is.
result = jQuery.css( tween.elem, tween.prop, "" ); result = jQuery.css( tween.elem, tween.prop, "" );
// Empty strings, null, undefined and "auto" are converted to 0. // Empty strings, null, undefined and "auto" are converted to 0.
return !result || result === "auto" ? 0 : result; return !result || result === "auto" ? 0 : result;
}, },
set: function( tween ) { set: function( tween ) {
// use step hook for back compat - use cssHook if its there - use .style if its // Use step hook for back compat.
// available and use plain properties where available // Use cssHook if its there.
// Use .style if available and use plain properties where available.
if ( jQuery.fx.step[ tween.prop ] ) { if ( jQuery.fx.step[ tween.prop ] ) {
jQuery.fx.step[ tween.prop ]( tween ); jQuery.fx.step[ tween.prop ]( tween );
} else if ( tween.elem.style && ( tween.elem.style[ jQuery.cssProps[ tween.prop ] ] != null || jQuery.cssHooks[ tween.prop ] ) ) { } else if ( tween.elem.style && ( tween.elem.style[ jQuery.cssProps[ tween.prop ] ] != null || jQuery.cssHooks[ tween.prop ] ) ) {
...@@ -6206,7 +6235,6 @@ Tween.propHooks = { ...@@ -6206,7 +6235,6 @@ Tween.propHooks = {
// Support: IE9 // Support: IE9
// Panic based approach to setting things on disconnected nodes // Panic based approach to setting things on disconnected nodes
Tween.propHooks.scrollTop = Tween.propHooks.scrollLeft = { Tween.propHooks.scrollTop = Tween.propHooks.scrollLeft = {
set: function( tween ) { set: function( tween ) {
if ( tween.elem.nodeType && tween.elem.parentNode ) { if ( tween.elem.nodeType && tween.elem.parentNode ) {
...@@ -6262,16 +6290,16 @@ var ...@@ -6262,16 +6290,16 @@ var
start = +target || 1; start = +target || 1;
do { do {
// If previous iteration zeroed out, double until we get *something* // If previous iteration zeroed out, double until we get *something*.
// Use a string for doubling factor so we don't accidentally see scale as unchanged below // Use string for doubling so we don't accidentally see scale as unchanged below
scale = scale || ".5"; scale = scale || ".5";
// Adjust and apply // Adjust and apply
start = start / scale; start = start / scale;
jQuery.style( tween.elem, prop, start + unit ); jQuery.style( tween.elem, prop, start + unit );
// Update scale, tolerating zero or NaN from tween.cur() // Update scale, tolerating zero or NaN from tween.cur(),
// And breaking the loop if scale is unchanged or perfect, or if we've just had enough // break the loop if scale is unchanged or perfect, or if we've just had enough
} while ( scale !== (scale = tween.cur() / target) && scale !== 1 && --maxIterations ); } while ( scale !== (scale = tween.cur() / target) && scale !== 1 && --maxIterations );
} }
...@@ -6303,8 +6331,8 @@ function genFx( type, includeWidth ) { ...@@ -6303,8 +6331,8 @@ function genFx( type, includeWidth ) {
i = 0, i = 0,
attrs = { height: type }; attrs = { height: type };
// if we include width, step value is 1 to do all cssExpand values, // If we include width, step value is 1 to do all cssExpand values,
// if we don't include width, step value is 2 to skip over Left and Right // otherwise step value is 2 to skip over Left and Right
includeWidth = includeWidth ? 1 : 0; includeWidth = includeWidth ? 1 : 0;
for ( ; i < 4 ; i += 2 - includeWidth ) { for ( ; i < 4 ; i += 2 - includeWidth ) {
which = cssExpand[ i ]; which = cssExpand[ i ];
...@@ -6326,7 +6354,7 @@ function createTween( value, prop, animation ) { ...@@ -6326,7 +6354,7 @@ function createTween( value, prop, animation ) {
for ( ; index < length; index++ ) { for ( ; index < length; index++ ) {
if ( (tween = collection[ index ].call( animation, prop, value )) ) { if ( (tween = collection[ index ].call( animation, prop, value )) ) {
// we're done with this property // We're done with this property
return tween; return tween;
} }
} }
...@@ -6341,7 +6369,7 @@ function defaultPrefilter( elem, props, opts ) { ...@@ -6341,7 +6369,7 @@ function defaultPrefilter( elem, props, opts ) {
hidden = elem.nodeType && isHidden( elem ), hidden = elem.nodeType && isHidden( elem ),
dataShow = data_priv.get( elem, "fxshow" ); dataShow = data_priv.get( elem, "fxshow" );
// handle queue: false promises // Handle queue: false promises
if ( !opts.queue ) { if ( !opts.queue ) {
hooks = jQuery._queueHooks( elem, "fx" ); hooks = jQuery._queueHooks( elem, "fx" );
if ( hooks.unqueued == null ) { if ( hooks.unqueued == null ) {
...@@ -6356,8 +6384,7 @@ function defaultPrefilter( elem, props, opts ) { ...@@ -6356,8 +6384,7 @@ function defaultPrefilter( elem, props, opts ) {
hooks.unqueued++; hooks.unqueued++;
anim.always(function() { anim.always(function() {
// doing this makes sure that the complete handler will be called // Ensure the complete handler is called before this completes
// before this completes
anim.always(function() { anim.always(function() {
hooks.unqueued--; hooks.unqueued--;
if ( !jQuery.queue( elem, "fx" ).length ) { if ( !jQuery.queue( elem, "fx" ).length ) {
...@@ -6367,7 +6394,7 @@ function defaultPrefilter( elem, props, opts ) { ...@@ -6367,7 +6394,7 @@ function defaultPrefilter( elem, props, opts ) {
}); });
} }
// height/width overflow pass // Height/width overflow pass
if ( elem.nodeType === 1 && ( "height" in props || "width" in props ) ) { if ( elem.nodeType === 1 && ( "height" in props || "width" in props ) ) {
// Make sure that nothing sneaks out // Make sure that nothing sneaks out
// Record all 3 overflow attributes because IE9-10 do not // Record all 3 overflow attributes because IE9-10 do not
...@@ -6429,7 +6456,7 @@ function defaultPrefilter( elem, props, opts ) { ...@@ -6429,7 +6456,7 @@ function defaultPrefilter( elem, props, opts ) {
dataShow = data_priv.access( elem, "fxshow", {} ); dataShow = data_priv.access( elem, "fxshow", {} );
} }
// store state if its toggle - enables .stop().toggle() to "reverse" // Store state if its toggle - enables .stop().toggle() to "reverse"
if ( toggle ) { if ( toggle ) {
dataShow.hidden = !hidden; dataShow.hidden = !hidden;
} }
...@@ -6489,8 +6516,8 @@ function propFilter( props, specialEasing ) { ...@@ -6489,8 +6516,8 @@ function propFilter( props, specialEasing ) {
value = hooks.expand( value ); value = hooks.expand( value );
delete props[ name ]; delete props[ name ];
// not quite $.extend, this wont overwrite keys already present. // Not quite $.extend, this won't overwrite existing keys.
// also - reusing 'index' from above because we have the correct "name" // Reusing 'index' because we have the correct "name"
for ( index in value ) { for ( index in value ) {
if ( !( index in props ) ) { if ( !( index in props ) ) {
props[ index ] = value[ index ]; props[ index ] = value[ index ];
...@@ -6509,7 +6536,7 @@ function Animation( elem, properties, options ) { ...@@ -6509,7 +6536,7 @@ function Animation( elem, properties, options ) {
index = 0, index = 0,
length = animationPrefilters.length, length = animationPrefilters.length,
deferred = jQuery.Deferred().always( function() { deferred = jQuery.Deferred().always( function() {
// don't match elem in the :animated selector // Don't match elem in the :animated selector
delete tick.elem; delete tick.elem;
}), }),
tick = function() { tick = function() {
...@@ -6518,7 +6545,8 @@ function Animation( elem, properties, options ) { ...@@ -6518,7 +6545,8 @@ function Animation( elem, properties, options ) {
} }
var currentTime = fxNow || createFxNow(), var currentTime = fxNow || createFxNow(),
remaining = Math.max( 0, animation.startTime + animation.duration - currentTime ), remaining = Math.max( 0, animation.startTime + animation.duration - currentTime ),
// archaic crash bug won't allow us to use 1 - ( 0.5 || 0 ) (#12497) // Support: Android 2.3
// Archaic crash bug won't allow us to use `1 - ( 0.5 || 0 )` (#12497)
temp = remaining / animation.duration || 0, temp = remaining / animation.duration || 0,
percent = 1 - temp, percent = 1 - temp,
index = 0, index = 0,
...@@ -6554,7 +6582,7 @@ function Animation( elem, properties, options ) { ...@@ -6554,7 +6582,7 @@ function Animation( elem, properties, options ) {
}, },
stop: function( gotoEnd ) { stop: function( gotoEnd ) {
var index = 0, var index = 0,
// if we are going to the end, we want to run all the tweens // If we are going to the end, we want to run all the tweens
// otherwise we skip this part // otherwise we skip this part
length = gotoEnd ? animation.tweens.length : 0; length = gotoEnd ? animation.tweens.length : 0;
if ( stopped ) { if ( stopped ) {
...@@ -6565,8 +6593,7 @@ function Animation( elem, properties, options ) { ...@@ -6565,8 +6593,7 @@ function Animation( elem, properties, options ) {
animation.tweens[ index ].run( 1 ); animation.tweens[ index ].run( 1 );
} }
// resolve when we played the last frame // Resolve when we played the last frame; otherwise, reject
// otherwise, reject
if ( gotoEnd ) { if ( gotoEnd ) {
deferred.resolveWith( elem, [ animation, gotoEnd ] ); deferred.resolveWith( elem, [ animation, gotoEnd ] );
} else { } else {
...@@ -6648,7 +6675,7 @@ jQuery.speed = function( speed, easing, fn ) { ...@@ -6648,7 +6675,7 @@ jQuery.speed = function( speed, easing, fn ) {
opt.duration = jQuery.fx.off ? 0 : typeof opt.duration === "number" ? opt.duration : opt.duration = jQuery.fx.off ? 0 : typeof opt.duration === "number" ? opt.duration :
opt.duration in jQuery.fx.speeds ? jQuery.fx.speeds[ opt.duration ] : jQuery.fx.speeds._default; opt.duration in jQuery.fx.speeds ? jQuery.fx.speeds[ opt.duration ] : jQuery.fx.speeds._default;
// normalize opt.queue - true/undefined/null -> "fx" // Normalize opt.queue - true/undefined/null -> "fx"
if ( opt.queue == null || opt.queue === true ) { if ( opt.queue == null || opt.queue === true ) {
opt.queue = "fx"; opt.queue = "fx";
} }
...@@ -6672,10 +6699,10 @@ jQuery.speed = function( speed, easing, fn ) { ...@@ -6672,10 +6699,10 @@ jQuery.speed = function( speed, easing, fn ) {
jQuery.fn.extend({ jQuery.fn.extend({
fadeTo: function( speed, to, easing, callback ) { fadeTo: function( speed, to, easing, callback ) {
// show any hidden elements after setting opacity to 0 // Show any hidden elements after setting opacity to 0
return this.filter( isHidden ).css( "opacity", 0 ).show() return this.filter( isHidden ).css( "opacity", 0 ).show()
// animate to the value specified // Animate to the value specified
.end().animate({ opacity: to }, speed, easing, callback ); .end().animate({ opacity: to }, speed, easing, callback );
}, },
animate: function( prop, speed, easing, callback ) { animate: function( prop, speed, easing, callback ) {
...@@ -6738,9 +6765,9 @@ jQuery.fn.extend({ ...@@ -6738,9 +6765,9 @@ jQuery.fn.extend({
} }
} }
// start the next in the queue if the last step wasn't forced // Start the next in the queue if the last step wasn't forced.
// timers currently will call their complete callbacks, which will dequeue // Timers currently will call their complete callbacks, which
// but only if they were gotoEnd // will dequeue but only if they were gotoEnd.
if ( dequeue || !gotoEnd ) { if ( dequeue || !gotoEnd ) {
jQuery.dequeue( this, type ); jQuery.dequeue( this, type );
} }
...@@ -6758,17 +6785,17 @@ jQuery.fn.extend({ ...@@ -6758,17 +6785,17 @@ jQuery.fn.extend({
timers = jQuery.timers, timers = jQuery.timers,
length = queue ? queue.length : 0; length = queue ? queue.length : 0;
// enable finishing flag on private data // Enable finishing flag on private data
data.finish = true; data.finish = true;
// empty the queue first // Empty the queue first
jQuery.queue( this, type, [] ); jQuery.queue( this, type, [] );
if ( hooks && hooks.stop ) { if ( hooks && hooks.stop ) {
hooks.stop.call( this, true ); hooks.stop.call( this, true );
} }
// look for any active animations, and finish them // Look for any active animations, and finish them
for ( index = timers.length; index--; ) { for ( index = timers.length; index--; ) {
if ( timers[ index ].elem === this && timers[ index ].queue === type ) { if ( timers[ index ].elem === this && timers[ index ].queue === type ) {
timers[ index ].anim.stop( true ); timers[ index ].anim.stop( true );
...@@ -6776,14 +6803,14 @@ jQuery.fn.extend({ ...@@ -6776,14 +6803,14 @@ jQuery.fn.extend({
} }
} }
// look for any animations in the old queue and finish them // Look for any animations in the old queue and finish them
for ( index = 0; index < length; index++ ) { for ( index = 0; index < length; index++ ) {
if ( queue[ index ] && queue[ index ].finish ) { if ( queue[ index ] && queue[ index ].finish ) {
queue[ index ].finish.call( this ); queue[ index ].finish.call( this );
} }
} }
// turn off finishing flag // Turn off finishing flag
delete data.finish; delete data.finish;
}); });
} }
...@@ -6886,21 +6913,21 @@ jQuery.fn.delay = function( time, type ) { ...@@ -6886,21 +6913,21 @@ jQuery.fn.delay = function( time, type ) {
input.type = "checkbox"; input.type = "checkbox";
// Support: iOS 5.1, Android 4.x, Android 2.3 // Support: iOS<=5.1, Android<=4.2+
// Check the default checkbox/radio value ("" on old WebKit; "on" elsewhere) // Default value for a checkbox should be "on"
support.checkOn = input.value !== ""; support.checkOn = input.value !== "";
// Must access the parent to make an option select properly // Support: IE<=11+
// Support: IE9, IE10 // Must access selectedIndex to make default options select
support.optSelected = opt.selected; support.optSelected = opt.selected;
// Make sure that the options inside disabled selects aren't marked as disabled // Support: Android<=2.3
// (WebKit marks them as disabled) // Options inside disabled selects are incorrectly marked as disabled
select.disabled = true; select.disabled = true;
support.optDisabled = !opt.disabled; support.optDisabled = !opt.disabled;
// Check if an input maintains its value after becoming a radio // Support: IE<=11+
// Support: IE9, IE10 // An input loses its value after becoming a radio
input = document.createElement( "input" ); input = document.createElement( "input" );
input.value = "t"; input.value = "t";
input.type = "radio"; input.type = "radio";
...@@ -6997,8 +7024,6 @@ jQuery.extend({ ...@@ -6997,8 +7024,6 @@ jQuery.extend({
set: function( elem, value ) { set: function( elem, value ) {
if ( !support.radioValue && value === "radio" && if ( !support.radioValue && value === "radio" &&
jQuery.nodeName( elem, "input" ) ) { 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; var val = elem.value;
elem.setAttribute( "type", value ); elem.setAttribute( "type", value );
if ( val ) { if ( val ) {
...@@ -7068,7 +7093,7 @@ jQuery.extend({ ...@@ -7068,7 +7093,7 @@ jQuery.extend({
var ret, hooks, notxml, var ret, hooks, notxml,
nType = elem.nodeType; nType = elem.nodeType;
// don't get/set properties on text, comment and attribute nodes // Don't get/set properties on text, comment and attribute nodes
if ( !elem || nType === 3 || nType === 8 || nType === 2 ) { if ( !elem || nType === 3 || nType === 8 || nType === 2 ) {
return; return;
} }
...@@ -7104,8 +7129,6 @@ jQuery.extend({ ...@@ -7104,8 +7129,6 @@ jQuery.extend({
} }
}); });
// Support: IE9+
// Selectedness for an option in an optgroup can be inaccurate
if ( !support.optSelected ) { if ( !support.optSelected ) {
jQuery.propHooks.selected = { jQuery.propHooks.selected = {
get: function( elem ) { get: function( elem ) {
...@@ -7213,7 +7236,7 @@ jQuery.fn.extend({ ...@@ -7213,7 +7236,7 @@ jQuery.fn.extend({
} }
} }
// only assign if different to avoid unneeded rendering. // Only assign if different to avoid unneeded rendering.
finalValue = value ? jQuery.trim( cur ) : ""; finalValue = value ? jQuery.trim( cur ) : "";
if ( elem.className !== finalValue ) { if ( elem.className !== finalValue ) {
elem.className = finalValue; elem.className = finalValue;
...@@ -7240,14 +7263,14 @@ jQuery.fn.extend({ ...@@ -7240,14 +7263,14 @@ jQuery.fn.extend({
return this.each(function() { return this.each(function() {
if ( type === "string" ) { if ( type === "string" ) {
// toggle individual class names // Toggle individual class names
var className, var className,
i = 0, i = 0,
self = jQuery( this ), self = jQuery( this ),
classNames = value.match( rnotwhite ) || []; classNames = value.match( rnotwhite ) || [];
while ( (className = classNames[ i++ ]) ) { while ( (className = classNames[ i++ ]) ) {
// check each className given, space separated list // Check each className given, space separated list
if ( self.hasClass( className ) ) { if ( self.hasClass( className ) ) {
self.removeClass( className ); self.removeClass( className );
} else { } else {
...@@ -7262,7 +7285,7 @@ jQuery.fn.extend({ ...@@ -7262,7 +7285,7 @@ jQuery.fn.extend({
data_priv.set( this, "__className__", this.className ); data_priv.set( this, "__className__", this.className );
} }
// If the element has a class name or if we're passed "false", // 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). // then remove the whole classname (if there was one, the above saved it).
// Otherwise bring back whatever was previously saved (if anything), // Otherwise bring back whatever was previously saved (if anything),
// falling back to the empty string if nothing was stored. // falling back to the empty string if nothing was stored.
...@@ -7306,9 +7329,9 @@ jQuery.fn.extend({ ...@@ -7306,9 +7329,9 @@ jQuery.fn.extend({
ret = elem.value; ret = elem.value;
return typeof ret === "string" ? return typeof ret === "string" ?
// handle most common string cases // Handle most common string cases
ret.replace(rreturn, "") : ret.replace(rreturn, "") :
// handle cases where value is null/undef or number // Handle cases where value is null/undef or number
ret == null ? "" : ret; ret == null ? "" : ret;
} }
...@@ -7416,7 +7439,7 @@ jQuery.extend({ ...@@ -7416,7 +7439,7 @@ jQuery.extend({
} }
} }
// force browsers to behave consistently when non-matching value is set // Force browsers to behave consistently when non-matching value is set
if ( !optionSet ) { if ( !optionSet ) {
elem.selectedIndex = -1; elem.selectedIndex = -1;
} }
...@@ -7437,8 +7460,6 @@ jQuery.each([ "radio", "checkbox" ], function() { ...@@ -7437,8 +7460,6 @@ jQuery.each([ "radio", "checkbox" ], function() {
}; };
if ( !support.checkOn ) { if ( !support.checkOn ) {
jQuery.valHooks[ this ].get = function( elem ) { 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; return elem.getAttribute("value") === null ? "on" : elem.value;
}; };
} }
...@@ -7520,10 +7541,6 @@ jQuery.parseXML = function( data ) { ...@@ -7520,10 +7541,6 @@ jQuery.parseXML = function( data ) {
var var
// Document location
ajaxLocParts,
ajaxLocation,
rhash = /#.*$/, rhash = /#.*$/,
rts = /([?&])_=[^&]*/, rts = /([?&])_=[^&]*/,
rheaders = /^(.*?):[ \t]*([^\r\n]*)$/mg, rheaders = /^(.*?):[ \t]*([^\r\n]*)$/mg,
...@@ -7552,22 +7569,13 @@ var ...@@ -7552,22 +7569,13 @@ var
transports = {}, transports = {},
// Avoid comment-prolog char sequence (#10098); must appease lint and evade compression // Avoid comment-prolog char sequence (#10098); must appease lint and evade compression
allTypes = "*/".concat("*"); allTypes = "*/".concat( "*" ),
// #8138, IE may throw an exception when accessing // Document location
// a field from window.location if document.domain has been set ajaxLocation = window.location.href,
try {
ajaxLocation = location.href;
} catch( e ) {
// Use the href attribute of an A element
// since IE will modify it given document.location
ajaxLocation = document.createElement( "a" );
ajaxLocation.href = "";
ajaxLocation = ajaxLocation.href;
}
// Segment location into parts // Segment location into parts
ajaxLocParts = rurl.exec( ajaxLocation.toLowerCase() ) || []; ajaxLocParts = rurl.exec( ajaxLocation.toLowerCase() ) || [];
// Base "constructor" for jQuery.ajaxPrefilter and jQuery.ajaxTransport // Base "constructor" for jQuery.ajaxPrefilter and jQuery.ajaxTransport
function addToPrefiltersOrTransports( structure ) { function addToPrefiltersOrTransports( structure ) {
...@@ -8046,7 +8054,8 @@ jQuery.extend({ ...@@ -8046,7 +8054,8 @@ jQuery.extend({
} }
// We can fire global events as of now if asked to // We can fire global events as of now if asked to
fireGlobals = s.global; // Don't fire events if jQuery.event is undefined in an AMD-usage scenario (#15118)
fireGlobals = jQuery.event && s.global;
// Watch for a new set of requests // Watch for a new set of requests
if ( fireGlobals && jQuery.active++ === 0 ) { if ( fireGlobals && jQuery.active++ === 0 ) {
...@@ -8119,7 +8128,7 @@ jQuery.extend({ ...@@ -8119,7 +8128,7 @@ jQuery.extend({
return jqXHR.abort(); return jqXHR.abort();
} }
// aborting is no longer a cancellation // Aborting is no longer a cancellation
strAbort = "abort"; strAbort = "abort";
// Install callbacks on deferreds // Install callbacks on deferreds
...@@ -8231,8 +8240,7 @@ jQuery.extend({ ...@@ -8231,8 +8240,7 @@ jQuery.extend({
isSuccess = !error; isSuccess = !error;
} }
} else { } else {
// We extract error from statusText // Extract error from statusText and normalize for non-aborts
// then normalize statusText and status for non-aborts
error = statusText; error = statusText;
if ( status || !statusText ) { if ( status || !statusText ) {
statusText = "error"; statusText = "error";
...@@ -8288,7 +8296,7 @@ jQuery.extend({ ...@@ -8288,7 +8296,7 @@ jQuery.extend({
jQuery.each( [ "get", "post" ], function( i, method ) { jQuery.each( [ "get", "post" ], function( i, method ) {
jQuery[ method ] = function( url, data, callback, type ) { jQuery[ method ] = function( url, data, callback, type ) {
// shift arguments if data argument was omitted // Shift arguments if data argument was omitted
if ( jQuery.isFunction( data ) ) { if ( jQuery.isFunction( data ) ) {
type = type || callback; type = type || callback;
callback = data; callback = data;
...@@ -8305,13 +8313,6 @@ jQuery.each( [ "get", "post" ], function( i, method ) { ...@@ -8305,13 +8313,6 @@ jQuery.each( [ "get", "post" ], function( i, method ) {
}; };
}); });
// Attach a bunch of functions for handling common AJAX events
jQuery.each( [ "ajaxStart", "ajaxStop", "ajaxComplete", "ajaxError", "ajaxSuccess", "ajaxSend" ], function( i, type ) {
jQuery.fn[ type ] = function( fn ) {
return this.on( type, fn );
};
});
jQuery._evalUrl = function( url ) { jQuery._evalUrl = function( url ) {
return jQuery.ajax({ return jQuery.ajax({
...@@ -8529,8 +8530,9 @@ var xhrId = 0, ...@@ -8529,8 +8530,9 @@ var xhrId = 0,
// Support: IE9 // Support: IE9
// Open requests must be manually aborted on unload (#5280) // Open requests must be manually aborted on unload (#5280)
if ( window.ActiveXObject ) { // See https://support.microsoft.com/kb/2856746 for more info
jQuery( window ).on( "unload", function() { if ( window.attachEvent ) {
window.attachEvent( "onunload", function() {
for ( var key in xhrCallbacks ) { for ( var key in xhrCallbacks ) {
xhrCallbacks[ key ](); xhrCallbacks[ key ]();
} }
...@@ -8883,6 +8885,16 @@ jQuery.fn.load = function( url, params, callback ) { ...@@ -8883,6 +8885,16 @@ jQuery.fn.load = function( url, params, callback ) {
// Attach a bunch of functions for handling common AJAX events
jQuery.each( [ "ajaxStart", "ajaxStop", "ajaxComplete", "ajaxError", "ajaxSuccess", "ajaxSend" ], function( i, type ) {
jQuery.fn[ type ] = function( fn ) {
return this.on( type, fn );
};
});
jQuery.expr.filters.animated = function( elem ) { jQuery.expr.filters.animated = function( elem ) {
return jQuery.grep(jQuery.timers, function( fn ) { return jQuery.grep(jQuery.timers, function( fn ) {
return elem === fn.elem; return elem === fn.elem;
...@@ -8919,7 +8931,8 @@ jQuery.offset = { ...@@ -8919,7 +8931,8 @@ jQuery.offset = {
calculatePosition = ( position === "absolute" || position === "fixed" ) && calculatePosition = ( position === "absolute" || position === "fixed" ) &&
( curCSSTop + curCSSLeft ).indexOf("auto") > -1; ( curCSSTop + curCSSLeft ).indexOf("auto") > -1;
// Need to be able to calculate position if either top or left is auto and position is either absolute or fixed // Need to be able to calculate position if either
// top or left is auto and position is either absolute or fixed
if ( calculatePosition ) { if ( calculatePosition ) {
curPosition = curElem.position(); curPosition = curElem.position();
curTop = curPosition.top; curTop = curPosition.top;
...@@ -8976,8 +8989,8 @@ jQuery.fn.extend({ ...@@ -8976,8 +8989,8 @@ jQuery.fn.extend({
return box; return box;
} }
// Support: BlackBerry 5, iOS 3 (original iPhone)
// If we don't have gBCR, just use 0,0 rather than error // If we don't have gBCR, just use 0,0 rather than error
// BlackBerry 5, iOS 3 (original iPhone)
if ( typeof elem.getBoundingClientRect !== strundefined ) { if ( typeof elem.getBoundingClientRect !== strundefined ) {
box = elem.getBoundingClientRect(); box = elem.getBoundingClientRect();
} }
...@@ -8999,7 +9012,7 @@ jQuery.fn.extend({ ...@@ -8999,7 +9012,7 @@ jQuery.fn.extend({
// Fixed elements are offset from window (parentOffset = {top:0, left: 0}, because it is its only offset parent // Fixed elements are offset from window (parentOffset = {top:0, left: 0}, because it is its only offset parent
if ( jQuery.css( elem, "position" ) === "fixed" ) { if ( jQuery.css( elem, "position" ) === "fixed" ) {
// We assume that getBoundingClientRect is available when computed position is fixed // Assume getBoundingClientRect is there when computed position is fixed
offset = elem.getBoundingClientRect(); offset = elem.getBoundingClientRect();
} else { } else {
...@@ -9062,16 +9075,18 @@ jQuery.each( { scrollLeft: "pageXOffset", scrollTop: "pageYOffset" }, function( ...@@ -9062,16 +9075,18 @@ jQuery.each( { scrollLeft: "pageXOffset", scrollTop: "pageYOffset" }, function(
}; };
}); });
// Support: Safari<7+, Chrome<37+
// Add the top/left cssHooks using jQuery.fn.position // Add the top/left cssHooks using jQuery.fn.position
// Webkit bug: https://bugs.webkit.org/show_bug.cgi?id=29084 // Webkit bug: https://bugs.webkit.org/show_bug.cgi?id=29084
// getComputedStyle returns percent when specified for top/left/bottom/right // Blink bug: https://code.google.com/p/chromium/issues/detail?id=229280
// rather than make the css module depend on the offset module, we just check for it here // getComputedStyle returns percent when specified for top/left/bottom/right;
// rather than make the css module depend on the offset module, just check for it here
jQuery.each( [ "top", "left" ], function( i, prop ) { jQuery.each( [ "top", "left" ], function( i, prop ) {
jQuery.cssHooks[ prop ] = addGetHookIf( support.pixelPosition, jQuery.cssHooks[ prop ] = addGetHookIf( support.pixelPosition,
function( elem, computed ) { function( elem, computed ) {
if ( computed ) { if ( computed ) {
computed = curCSS( elem, prop ); computed = curCSS( elem, prop );
// if curCSS returns percentage, fallback to offset // If curCSS returns percentage, fallback to offset
return rnumnonpx.test( computed ) ? return rnumnonpx.test( computed ) ?
jQuery( elem ).position()[ prop ] + "px" : jQuery( elem ).position()[ prop ] + "px" :
computed; computed;
...@@ -9084,7 +9099,7 @@ jQuery.each( [ "top", "left" ], function( i, prop ) { ...@@ -9084,7 +9099,7 @@ jQuery.each( [ "top", "left" ], function( i, prop ) {
// Create innerHeight, innerWidth, height, width, outerHeight and outerWidth methods // Create innerHeight, innerWidth, height, width, outerHeight and outerWidth methods
jQuery.each( { Height: "height", Width: "width" }, function( name, type ) { jQuery.each( { Height: "height", Width: "width" }, function( name, type ) {
jQuery.each( { padding: "inner" + name, content: type, "": "outer" + name }, function( defaultExtra, funcName ) { jQuery.each( { padding: "inner" + name, content: type, "": "outer" + name }, function( defaultExtra, funcName ) {
// margin is only for outerHeight, outerWidth // Margin is only for outerHeight, outerWidth
jQuery.fn[ funcName ] = function( margin, value ) { jQuery.fn[ funcName ] = function( margin, value ) {
var chainable = arguments.length && ( defaultExtra || typeof margin !== "boolean" ), var chainable = arguments.length && ( defaultExtra || typeof margin !== "boolean" ),
extra = defaultExtra || ( margin === true || value === true ? "margin" : "border" ); extra = defaultExtra || ( margin === true || value === true ? "margin" : "border" );
...@@ -9175,8 +9190,8 @@ jQuery.noConflict = function( deep ) { ...@@ -9175,8 +9190,8 @@ jQuery.noConflict = function( deep ) {
return jQuery; return jQuery;
}; };
// Expose jQuery and $ identifiers, even in // Expose jQuery and $ identifiers, even in AMD
// AMD (#7102#comment:10, https://github.com/jquery/jquery/pull/557) // (#7102#comment:10, https://github.com/jquery/jquery/pull/557)
// and CommonJS for browser emulators (#13566) // and CommonJS for browser emulators (#13566)
if ( typeof noGlobal === strundefined ) { if ( typeof noGlobal === strundefined ) {
window.jQuery = window.$ = jQuery; window.jQuery = window.$ = jQuery;
......
...@@ -12,25 +12,30 @@ button { ...@@ -12,25 +12,30 @@ button {
font-size: 100%; font-size: 100%;
vertical-align: baseline; vertical-align: baseline;
font-family: inherit; font-family: inherit;
font-weight: inherit;
color: inherit; color: inherit;
-webkit-appearance: none; -webkit-appearance: none;
-ms-appearance: none; -ms-appearance: none;
-o-appearance: none;
appearance: none; appearance: none;
-webkit-font-smoothing: antialiased;
-moz-font-smoothing: antialiased;
-ms-font-smoothing: antialiased;
font-smoothing: antialiased;
} }
body { body {
font: 14px 'Helvetica Neue', Helvetica, Arial, sans-serif; font: 14px 'Helvetica Neue', Helvetica, Arial, sans-serif;
line-height: 1.4em; line-height: 1.4em;
background: #eaeaea url('bg.png'); background: #f5f5f5;
color: #4d4d4d; color: #4d4d4d;
width: 550px; min-width: 230px;
max-width: 550px;
margin: 0 auto; margin: 0 auto;
-webkit-font-smoothing: antialiased; -webkit-font-smoothing: antialiased;
-moz-font-smoothing: antialiased; -moz-font-smoothing: antialiased;
-ms-font-smoothing: antialiased; -ms-font-smoothing: antialiased;
-o-font-smoothing: antialiased;
font-smoothing: antialiased; font-smoothing: antialiased;
font-weight: 300;
} }
button, button,
...@@ -38,78 +43,50 @@ input[type="checkbox"] { ...@@ -38,78 +43,50 @@ input[type="checkbox"] {
outline: none; outline: none;
} }
.hidden {
display: none;
}
#todoapp { #todoapp {
background: #fff; background: #fff;
background: rgba(255, 255, 255, 0.9);
margin: 130px 0 40px 0; margin: 130px 0 40px 0;
border: 1px solid #ccc;
position: relative; position: relative;
border-top-left-radius: 2px; box-shadow: 0 2px 4px 0 rgba(0, 0, 0, 0.2),
border-top-right-radius: 2px; 0 25px 50px 0 rgba(0, 0, 0, 0.1);
box-shadow: 0 2px 6px 0 rgba(0, 0, 0, 0.2),
0 25px 50px 0 rgba(0, 0, 0, 0.15);
}
#todoapp:before {
content: '';
border-left: 1px solid #f5d6d6;
border-right: 1px solid #f5d6d6;
width: 2px;
position: absolute;
top: 0;
left: 40px;
height: 100%;
} }
#todoapp input::-webkit-input-placeholder { #todoapp input::-webkit-input-placeholder {
font-style: italic; font-style: italic;
font-weight: 300;
color: #e6e6e6;
} }
#todoapp input::-moz-placeholder { #todoapp input::-moz-placeholder {
font-style: italic; font-style: italic;
color: #a9a9a9; font-weight: 300;
color: #e6e6e6;
}
#todoapp input::input-placeholder {
font-style: italic;
font-weight: 300;
color: #e6e6e6;
} }
#todoapp h1 { #todoapp h1 {
position: absolute; position: absolute;
top: -120px; top: -155px;
width: 100%; width: 100%;
font-size: 70px; font-size: 100px;
font-weight: bold; font-weight: 100;
text-align: center; text-align: center;
color: #b3b3b3; color: rgba(175, 47, 47, 0.15);
color: rgba(255, 255, 255, 0.3);
text-shadow: -1px -1px rgba(0, 0, 0, 0.2);
-webkit-text-rendering: optimizeLegibility; -webkit-text-rendering: optimizeLegibility;
-moz-text-rendering: optimizeLegibility; -moz-text-rendering: optimizeLegibility;
-ms-text-rendering: optimizeLegibility; -ms-text-rendering: optimizeLegibility;
-o-text-rendering: optimizeLegibility;
text-rendering: optimizeLegibility; text-rendering: optimizeLegibility;
} }
#header {
padding-top: 15px;
border-radius: inherit;
}
#header:before {
content: '';
position: absolute;
top: 0;
right: 0;
left: 0;
height: 15px;
z-index: 2;
border-bottom: 1px solid #6c615c;
background: #8d7d77;
background: -webkit-gradient(linear, left top, left bottom, from(rgba(132, 110, 100, 0.8)),to(rgba(101, 84, 76, 0.8)));
background: -webkit-linear-gradient(top, rgba(132, 110, 100, 0.8), rgba(101, 84, 76, 0.8));
background: linear-gradient(top, rgba(132, 110, 100, 0.8), rgba(101, 84, 76, 0.8));
filter: progid:DXImageTransform.Microsoft.gradient(GradientType=0,StartColorStr='#9d8b83', EndColorStr='#847670');
border-top-left-radius: 1px;
border-top-right-radius: 1px;
}
#new-todo, #new-todo,
.edit { .edit {
position: relative; position: relative;
...@@ -117,6 +94,7 @@ input[type="checkbox"] { ...@@ -117,6 +94,7 @@ input[type="checkbox"] {
width: 100%; width: 100%;
font-size: 24px; font-size: 24px;
font-family: inherit; font-family: inherit;
font-weight: inherit;
line-height: 1.4em; line-height: 1.4em;
border: 0; border: 0;
outline: none; outline: none;
...@@ -124,29 +102,25 @@ input[type="checkbox"] { ...@@ -124,29 +102,25 @@ input[type="checkbox"] {
padding: 6px; padding: 6px;
border: 1px solid #999; border: 1px solid #999;
box-shadow: inset 0 -1px 5px 0 rgba(0, 0, 0, 0.2); box-shadow: inset 0 -1px 5px 0 rgba(0, 0, 0, 0.2);
-moz-box-sizing: border-box;
-ms-box-sizing: border-box; -ms-box-sizing: border-box;
-o-box-sizing: border-box;
box-sizing: border-box; box-sizing: border-box;
-webkit-font-smoothing: antialiased; -webkit-font-smoothing: antialiased;
-moz-font-smoothing: antialiased; -moz-font-smoothing: antialiased;
-ms-font-smoothing: antialiased; -ms-font-smoothing: antialiased;
-o-font-smoothing: antialiased;
font-smoothing: antialiased; font-smoothing: antialiased;
} }
#new-todo { #new-todo {
padding: 16px 16px 16px 60px; padding: 16px 16px 16px 60px;
border: none; border: none;
background: rgba(0, 0, 0, 0.02); background: rgba(0, 0, 0, 0.003);
z-index: 2; box-shadow: inset 0 -2px 1px rgba(0,0,0,0.03);
box-shadow: none;
} }
#main { #main {
position: relative; position: relative;
z-index: 2; z-index: 2;
border-top: 1px dotted #adadad; border-top: 1px solid #e6e6e6;
} }
label[for='toggle-all'] { label[for='toggle-all'] {
...@@ -155,19 +129,19 @@ label[for='toggle-all'] { ...@@ -155,19 +129,19 @@ label[for='toggle-all'] {
#toggle-all { #toggle-all {
position: absolute; position: absolute;
top: -42px; top: -55px;
left: -4px; left: -12px;
width: 40px; width: 60px;
height: 34px;
text-align: center; text-align: center;
/* Mobile Safari */ border: none; /* Mobile Safari */
border: none;
} }
#toggle-all:before { #toggle-all:before {
content: '»'; content: '';
font-size: 28px; font-size: 22px;
color: #d9d9d9; color: #e6e6e6;
padding: 0 25px 7px; padding: 10px 27px 10px 27px;
} }
#toggle-all:checked:before { #toggle-all:checked:before {
...@@ -183,7 +157,7 @@ label[for='toggle-all'] { ...@@ -183,7 +157,7 @@ label[for='toggle-all'] {
#todo-list li { #todo-list li {
position: relative; position: relative;
font-size: 24px; font-size: 24px;
border-bottom: 1px dotted #ccc; border-bottom: 1px solid #ededed;
} }
#todo-list li:last-child { #todo-list li:last-child {
...@@ -215,28 +189,18 @@ label[for='toggle-all'] { ...@@ -215,28 +189,18 @@ label[for='toggle-all'] {
top: 0; top: 0;
bottom: 0; bottom: 0;
margin: auto 0; margin: auto 0;
/* Mobile Safari */ border: none; /* Mobile Safari */
border: none;
-webkit-appearance: none; -webkit-appearance: none;
-ms-appearance: none; -ms-appearance: none;
-o-appearance: none;
appearance: none; appearance: none;
} }
#todo-list li .toggle:after { #todo-list li .toggle:after {
content: '✔'; content: url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" width="40" height="40" viewBox="-10 -18 100 135"><circle cx="50" cy="50" r="50" fill="none" stroke="#ededed" stroke-width="3"/></svg>');
/* 40 + a couple of pixels visual adjustment */
line-height: 43px;
font-size: 20px;
color: #d9d9d9;
text-shadow: 0 -1px 0 #bfbfbf;
} }
#todo-list li .toggle:checked:after { #todo-list li .toggle:checked:after {
color: #85ada7; content: url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" width="40" height="40" viewBox="-10 -18 100 135"><circle cx="50" cy="50" r="50" fill="none" stroke="#bddad5" stroke-width="3"/><path fill="#5dc2af" d="M72 25L42 71 27 56l-4 4 20 20 34-52z"/></svg>');
text-shadow: 0 1px 0 #669991;
bottom: 1px;
position: relative;
} }
#todo-list li label { #todo-list li label {
...@@ -246,12 +210,11 @@ label[for='toggle-all'] { ...@@ -246,12 +210,11 @@ label[for='toggle-all'] {
margin-left: 45px; margin-left: 45px;
display: block; display: block;
line-height: 1.2; line-height: 1.2;
-webkit-transition: color 0.4s;
transition: color 0.4s; transition: color 0.4s;
} }
#todo-list li.completed label { #todo-list li.completed label {
color: #a9a9a9; color: #d9d9d9;
text-decoration: line-through; text-decoration: line-through;
} }
...@@ -264,21 +227,18 @@ label[for='toggle-all'] { ...@@ -264,21 +227,18 @@ label[for='toggle-all'] {
width: 40px; width: 40px;
height: 40px; height: 40px;
margin: auto 0; margin: auto 0;
font-size: 22px; font-size: 30px;
color: #a88a8a; color: #cc9a9a;
-webkit-transition: all 0.2s; margin-bottom: 11px;
transition: all 0.2s; transition: colo 0.2s ease-out;
} }
#todo-list li .destroy:hover { #todo-list li .destroy:hover {
text-shadow: 0 0 1px #000, color: #af5b5e;
0 0 10px rgba(199, 107, 107, 0.8);
-webkit-transform: scale(1.3);
transform: scale(1.3);
} }
#todo-list li .destroy:after { #todo-list li .destroy:after {
content: ''; content: '×';
} }
#todo-list li:hover .destroy { #todo-list li:hover .destroy {
...@@ -295,29 +255,25 @@ label[for='toggle-all'] { ...@@ -295,29 +255,25 @@ label[for='toggle-all'] {
#footer { #footer {
color: #777; color: #777;
padding: 0 15px; padding: 10px 15px;
position: absolute;
right: 0;
bottom: -31px;
left: 0;
height: 20px; height: 20px;
z-index: 1;
text-align: center; text-align: center;
border-top: 1px solid #e6e6e6;
} }
#footer:before { #footer:before {
content: ''; content: '';
position: absolute; position: absolute;
right: 0; right: 0;
bottom: 31px; bottom: 0;
left: 0; left: 0;
height: 50px; height: 50px;
z-index: -1; overflow: hidden;
box-shadow: 0 1px 1px rgba(0, 0, 0, 0.3), box-shadow: 0 1px 1px rgba(0, 0, 0, 0.2),
0 6px 0 -3px rgba(255, 255, 255, 0.8), 0 8px 0 -3px #f6f6f6,
0 7px 1px -3px rgba(0, 0, 0, 0.3), 0 9px 1px -3px rgba(0, 0, 0, 0.2),
0 43px 0 -6px rgba(255, 255, 255, 0.8), 0 16px 0 -6px #f6f6f6,
0 44px 2px -6px rgba(0, 0, 0, 0.2); 0 17px 2px -6px rgba(0, 0, 0, 0.2);
} }
#todo-count { #todo-count {
...@@ -325,6 +281,10 @@ label[for='toggle-all'] { ...@@ -325,6 +281,10 @@ label[for='toggle-all'] {
text-align: left; text-align: left;
} }
#todo-count strong {
font-weight: 300;
}
#filters { #filters {
margin: 0; margin: 0;
padding: 0; padding: 0;
...@@ -339,49 +299,72 @@ label[for='toggle-all'] { ...@@ -339,49 +299,72 @@ label[for='toggle-all'] {
} }
#filters li a { #filters li a {
color: #83756f; color: inherit;
margin: 2px; margin: 3px;
padding: 3px 7px;
text-decoration: none; text-decoration: none;
border: 1px solid transparent;
border-radius: 3px;
}
#filters li a.selected,
#filters li a:hover {
border-color: rgba(175, 47, 47, 0.1);
} }
#filters li a.selected { #filters li a.selected {
font-weight: bold; border-color: rgba(175, 47, 47, 0.2);
} }
#clear-completed { #clear-completed,
html #clear-completed:active {
float: right; float: right;
position: relative; position: relative;
line-height: 20px; line-height: 20px;
text-decoration: none; text-decoration: none;
background: rgba(0, 0, 0, 0.1); cursor: pointer;
font-size: 11px; visibility: hidden;
padding: 0 10px; position: relative;
border-radius: 3px; }
box-shadow: 0 -1px 0 0 rgba(0, 0, 0, 0.2);
#clear-completed::after {
visibility: visible;
content: 'Clear completed';
position: absolute;
right: 0;
white-space: nowrap;
} }
#clear-completed:hover { #clear-completed:hover::after {
background: rgba(0, 0, 0, 0.15); text-decoration: underline;
box-shadow: 0 -1px 0 0 rgba(0, 0, 0, 0.3);
} }
#info { #info {
margin: 65px auto 0; margin: 65px auto 0;
color: #a6a6a6; color: #bfbfbf;
font-size: 12px; font-size: 10px;
text-shadow: 0 1px 0 rgba(255, 255, 255, 0.7); text-shadow: 0 1px 0 rgba(255, 255, 255, 0.5);
text-align: center; text-align: center;
} }
#info p {
line-height: 1;
}
#info a { #info a {
color: inherit; color: inherit;
text-decoration: none;
font-weight: 400;
}
#info a:hover {
text-decoration: underline;
} }
/* /*
Hack to remove background from Mobile Safari. Hack to remove background from Mobile Safari.
Can't use it globally since it destroys checkboxes in Firefox and Opera Can't use it globally since it destroys checkboxes in Firefox
*/ */
@media screen and (-webkit-min-device-pixel-ratio:0) { @media screen and (-webkit-min-device-pixel-ratio:0) {
#toggle-all, #toggle-all,
#todo-list li .toggle { #todo-list li .toggle {
...@@ -393,10 +376,6 @@ label[for='toggle-all'] { ...@@ -393,10 +376,6 @@ label[for='toggle-all'] {
} }
#toggle-all { #toggle-all {
top: -56px;
left: -15px;
width: 65px;
height: 41px;
-webkit-transform: rotate(90deg); -webkit-transform: rotate(90deg);
transform: rotate(90deg); transform: rotate(90deg);
-webkit-appearance: none; -webkit-appearance: none;
...@@ -404,151 +383,12 @@ label[for='toggle-all'] { ...@@ -404,151 +383,12 @@ label[for='toggle-all'] {
} }
} }
.hidden { @media (max-width: 430px) {
display: none; #footer {
} height: 50px;
hr {
margin: 20px 0;
border: 0;
border-top: 1px dashed #C5C5C5;
border-bottom: 1px dashed #F7F7F7;
}
.learn a {
font-weight: normal;
text-decoration: none;
color: #b83f45;
}
.learn a:hover {
text-decoration: underline;
color: #787e7e;
}
.learn h3,
.learn h4,
.learn h5 {
margin: 10px 0;
font-weight: 500;
line-height: 1.2;
color: #000;
}
.learn h3 {
font-size: 24px;
}
.learn h4 {
font-size: 18px;
}
.learn h5 {
margin-bottom: 0;
font-size: 14px;
}
.learn ul {
padding: 0;
margin: 0 0 30px 25px;
}
.learn li {
line-height: 20px;
}
.learn p {
font-size: 15px;
font-weight: 300;
line-height: 1.3;
margin-top: 0;
margin-bottom: 0;
}
.quote {
border: none;
margin: 20px 0 60px 0;
}
.quote p {
font-style: italic;
}
.quote p:before {
content: '“';
font-size: 50px;
opacity: .15;
position: absolute;
top: -20px;
left: 3px;
}
.quote p:after {
content: '”';
font-size: 50px;
opacity: .15;
position: absolute;
bottom: -42px;
right: 3px;
}
.quote footer {
position: absolute;
bottom: -40px;
right: 0;
}
.quote footer img {
border-radius: 3px;
}
.quote footer a {
margin-left: 5px;
vertical-align: middle;
}
.speech-bubble {
position: relative;
padding: 10px;
background: rgba(0, 0, 0, .04);
border-radius: 5px;
}
.speech-bubble:after {
content: '';
position: absolute;
top: 100%;
right: 30px;
border: 13px solid transparent;
border-top-color: rgba(0, 0, 0, .04);
}
.learn-bar > .learn {
position: absolute;
width: 272px;
top: 8px;
left: -300px;
padding: 10px;
border-radius: 5px;
background-color: rgba(255, 255, 255, .6);
-webkit-transition-property: left;
transition-property: left;
-webkit-transition-duration: 500ms;
transition-duration: 500ms;
}
@media (min-width: 899px) {
.learn-bar {
width: auto;
margin: 0 0 0 300px;
}
.learn-bar > .learn {
left: 8px;
} }
.learn-bar #todoapp { #filters {
width: 550px; bottom: 10px;
margin: 130px auto 40px auto;
} }
} }
hr {
margin: 20px 0;
border: 0;
border-top: 1px dashed #c5c5c5;
border-bottom: 1px dashed #f7f7f7;
}
.learn a {
font-weight: normal;
text-decoration: none;
color: #b83f45;
}
.learn a:hover {
text-decoration: underline;
color: #787e7e;
}
.learn h3,
.learn h4,
.learn h5 {
margin: 10px 0;
font-weight: 500;
line-height: 1.2;
color: #000;
}
.learn h3 {
font-size: 24px;
}
.learn h4 {
font-size: 18px;
}
.learn h5 {
margin-bottom: 0;
font-size: 14px;
}
.learn ul {
padding: 0;
margin: 0 0 30px 25px;
}
.learn li {
line-height: 20px;
}
.learn p {
font-size: 15px;
font-weight: 300;
line-height: 1.3;
margin-top: 0;
margin-bottom: 0;
}
#issue-count {
display: none;
}
.quote {
border: none;
margin: 20px 0 60px 0;
}
.quote p {
font-style: italic;
}
.quote p:before {
content: '“';
font-size: 50px;
opacity: .15;
position: absolute;
top: -20px;
left: 3px;
}
.quote p:after {
content: '”';
font-size: 50px;
opacity: .15;
position: absolute;
bottom: -42px;
right: 3px;
}
.quote footer {
position: absolute;
bottom: -40px;
right: 0;
}
.quote footer img {
border-radius: 3px;
}
.quote footer a {
margin-left: 5px;
vertical-align: middle;
}
.speech-bubble {
position: relative;
padding: 10px;
background: rgba(0, 0, 0, .04);
border-radius: 5px;
}
.speech-bubble:after {
content: '';
position: absolute;
top: 100%;
right: 30px;
border: 13px solid transparent;
border-top-color: rgba(0, 0, 0, .04);
}
.learn-bar > .learn {
position: absolute;
width: 272px;
top: 8px;
left: -300px;
padding: 10px;
border-radius: 5px;
background-color: rgba(255, 255, 255, .6);
transition-property: left;
transition-duration: 500ms;
}
@media (min-width: 899px) {
.learn-bar {
width: auto;
padding-left: 300px;
}
.learn-bar > .learn {
left: 8px;
}
}
/* global _ */
(function () { (function () {
'use strict'; 'use strict';
/* jshint ignore:start */
// Underscore's Template Module // Underscore's Template Module
// Courtesy of underscorejs.org // Courtesy of underscorejs.org
var _ = (function (_) { var _ = (function (_) {
...@@ -114,6 +116,7 @@ ...@@ -114,6 +116,7 @@
if (location.hostname === 'todomvc.com') { if (location.hostname === 'todomvc.com') {
window._gaq = [['_setAccount','UA-31081062-1'],['_trackPageview']];(function(d,t){var g=d.createElement(t),s=d.getElementsByTagName(t)[0];g.src='//www.google-analytics.com/ga.js';s.parentNode.insertBefore(g,s)}(document,'script')); window._gaq = [['_setAccount','UA-31081062-1'],['_trackPageview']];(function(d,t){var g=d.createElement(t),s=d.getElementsByTagName(t)[0];g.src='//www.google-analytics.com/ga.js';s.parentNode.insertBefore(g,s)}(document,'script'));
} }
/* jshint ignore:end */
function redirect() { function redirect() {
if (location.hostname === 'tastejs.github.io') { if (location.hostname === 'tastejs.github.io') {
...@@ -175,13 +178,17 @@ ...@@ -175,13 +178,17 @@
if (learnJSON.backend) { if (learnJSON.backend) {
this.frameworkJSON = learnJSON.backend; this.frameworkJSON = learnJSON.backend;
this.frameworkJSON.issueLabel = framework;
this.append({ this.append({
backend: true backend: true
}); });
} else if (learnJSON[framework]) { } else if (learnJSON[framework]) {
this.frameworkJSON = learnJSON[framework]; this.frameworkJSON = learnJSON[framework];
this.frameworkJSON.issueLabel = framework;
this.append(); this.append();
} }
this.fetchIssueCount();
} }
Learn.prototype.append = function (opts) { Learn.prototype.append = function (opts) {
...@@ -212,6 +219,26 @@ ...@@ -212,6 +219,26 @@
document.body.insertAdjacentHTML('afterBegin', aside.outerHTML); document.body.insertAdjacentHTML('afterBegin', aside.outerHTML);
}; };
Learn.prototype.fetchIssueCount = function () {
var issueLink = document.getElementById('issue-count-link');
if (issueLink) {
var url = issueLink.href.replace('https://github.com', 'https://api.github.com/repos');
var xhr = new XMLHttpRequest();
xhr.open('GET', url, true);
xhr.onload = function (e) {
var parsedResponse = JSON.parse(e.target.responseText);
if (parsedResponse instanceof Array) {
var count = parsedResponse.length
if (count !== 0) {
issueLink.innerHTML = 'This app has ' + count + ' open issues';
document.getElementById('issue-count').style.display = 'inline';
}
}
};
xhr.send();
}
};
redirect(); redirect();
getFile('learn.json', Learn); getFile('learn.json', Learn);
})(); })();
{
"private": true,
"dependencies": {
"backbone": "^1.1.2",
"backbone.localstorage": "^1.1.16",
"jquery": "^2.1.3",
"todomvc-app-css": "^1.0.0",
"todomvc-common": "^1.0.1",
"underscore": "^1.7.0"
}
}
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment