epuber 0.6.0 → 0.7.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (207) hide show
  1. checksums.yaml +4 -4
  2. data/Gemfile +5 -3
  3. data/README.md +3 -11
  4. data/bin/epuber +2 -3
  5. data/epuber.gemspec +3 -6
  6. data/lib/epuber/book/contributor.rb +1 -1
  7. data/lib/epuber/book/file_request.rb +1 -1
  8. data/lib/epuber/book/target.rb +1 -2
  9. data/lib/epuber/book/toc_item.rb +1 -2
  10. data/lib/epuber/book.rb +1 -2
  11. data/lib/epuber/checker/text_checker.rb +1 -1
  12. data/lib/epuber/checker.rb +1 -2
  13. data/lib/epuber/checker_transformer_base.rb +1 -0
  14. data/lib/epuber/command/build.rb +1 -2
  15. data/lib/epuber/command/compile.rb +1 -1
  16. data/lib/epuber/command/init.rb +1 -2
  17. data/lib/epuber/command/server.rb +1 -2
  18. data/lib/epuber/command.rb +1 -1
  19. data/lib/epuber/compiler/compilation_context.rb +1 -1
  20. data/lib/epuber/compiler/file_database.rb +3 -5
  21. data/lib/epuber/compiler/file_finders/abstract.rb +1 -1
  22. data/lib/epuber/compiler/file_finders/imaginary.rb +1 -2
  23. data/lib/epuber/compiler/file_finders/normal.rb +1 -1
  24. data/lib/epuber/compiler/file_resolver.rb +1 -1
  25. data/lib/epuber/compiler/file_stat.rb +0 -1
  26. data/lib/epuber/compiler/file_types/abstract_file.rb +1 -2
  27. data/lib/epuber/compiler/file_types/bade_file.rb +1 -2
  28. data/lib/epuber/compiler/file_types/coffee_script_file.rb +1 -2
  29. data/lib/epuber/compiler/file_types/container_xml_file.rb +1 -2
  30. data/lib/epuber/compiler/file_types/generated_file.rb +1 -2
  31. data/lib/epuber/compiler/file_types/ibooks_display_options_file.rb +1 -7
  32. data/lib/epuber/compiler/file_types/image_file.rb +1 -2
  33. data/lib/epuber/compiler/file_types/mime_type_file.rb +1 -2
  34. data/lib/epuber/compiler/file_types/nav_file.rb +1 -2
  35. data/lib/epuber/compiler/file_types/opf_file.rb +1 -2
  36. data/lib/epuber/compiler/file_types/source_file.rb +1 -2
  37. data/lib/epuber/compiler/file_types/static_file.rb +1 -2
  38. data/lib/epuber/compiler/file_types/stylus_file.rb +1 -2
  39. data/lib/epuber/compiler/file_types/xhtml_file.rb +2 -4
  40. data/lib/epuber/compiler/generator.rb +1 -1
  41. data/lib/epuber/compiler/meta_inf_generator.rb +1 -1
  42. data/lib/epuber/compiler/nav_generator.rb +1 -1
  43. data/lib/epuber/compiler/opf_generator.rb +1 -1
  44. data/lib/epuber/compiler/problem.rb +1 -2
  45. data/lib/epuber/compiler/xhtml_processor.rb +3 -1
  46. data/lib/epuber/compiler.rb +7 -11
  47. data/lib/epuber/config.rb +1 -2
  48. data/lib/epuber/dsl/attribute.rb +1 -1
  49. data/lib/epuber/dsl/attribute_support.rb +2 -2
  50. data/lib/epuber/dsl/object.rb +1 -1
  51. data/lib/epuber/dsl/tree_object.rb +1 -1
  52. data/lib/epuber/helper.rb +1 -1
  53. data/lib/epuber/lockfile.rb +1 -1
  54. data/lib/epuber/plugin.rb +1 -1
  55. data/lib/epuber/ruby_extensions/match_data.rb +1 -0
  56. data/lib/epuber/ruby_extensions/thread.rb +1 -0
  57. data/lib/epuber/server/handlers.rb +1 -1
  58. data/lib/epuber/server.rb +2 -2
  59. data/lib/epuber/templates.rb +2 -1
  60. data/lib/epuber/third_party/bower/bower.json +3 -3
  61. data/lib/epuber/third_party/bower/bower_components/cookies-js/bower.json +1 -1
  62. data/lib/epuber/third_party/bower/bower_components/cookies-js/dist/cookies.js +2 -3
  63. data/lib/epuber/third_party/bower/bower_components/cookies-js/dist/cookies.min.js +6 -6
  64. data/lib/epuber/third_party/bower/bower_components/jquery/AUTHORS.txt +278 -0
  65. data/lib/epuber/third_party/bower/bower_components/jquery/{MIT-LICENSE.txt → LICENSE.txt} +17 -2
  66. data/lib/epuber/third_party/bower/bower_components/jquery/README.md +65 -0
  67. data/lib/epuber/third_party/bower/bower_components/jquery/bower.json +2 -16
  68. data/lib/epuber/third_party/bower/bower_components/jquery/dist/jquery.js +2566 -1962
  69. data/lib/epuber/third_party/bower/bower_components/jquery/dist/jquery.min.js +4 -5
  70. data/lib/epuber/third_party/bower/bower_components/jquery/dist/jquery.min.map +1 -1
  71. data/lib/epuber/third_party/bower/bower_components/jquery/external/sizzle/LICENSE.txt +36 -0
  72. data/lib/epuber/third_party/bower/bower_components/jquery/{src → external}/sizzle/dist/sizzle.js +236 -160
  73. data/lib/epuber/third_party/bower/bower_components/jquery/external/sizzle/dist/sizzle.min.js +3 -0
  74. data/lib/epuber/third_party/bower/bower_components/jquery/external/sizzle/dist/sizzle.min.map +1 -0
  75. data/lib/epuber/third_party/bower/bower_components/jquery/src/ajax/jsonp.js +25 -14
  76. data/lib/epuber/third_party/bower/bower_components/jquery/src/ajax/load.js +20 -12
  77. data/lib/epuber/third_party/bower/bower_components/jquery/src/ajax/parseJSON.js +2 -2
  78. data/lib/epuber/third_party/bower/bower_components/jquery/src/ajax/parseXML.js +4 -5
  79. data/lib/epuber/third_party/bower/bower_components/jquery/src/ajax/script.js +16 -12
  80. data/lib/epuber/third_party/bower/bower_components/jquery/src/ajax/var/location.js +3 -0
  81. data/lib/epuber/third_party/bower/bower_components/jquery/src/ajax/var/nonce.js +2 -2
  82. data/lib/epuber/third_party/bower/bower_components/jquery/src/ajax/var/rquery.js +3 -3
  83. data/lib/epuber/third_party/bower/bower_components/jquery/src/ajax/xhr.js +73 -42
  84. data/lib/epuber/third_party/bower/bower_components/jquery/src/ajax.js +116 -57
  85. data/lib/epuber/third_party/bower/bower_components/jquery/src/attributes/attr.js +49 -48
  86. data/lib/epuber/third_party/bower/bower_components/jquery/src/attributes/classes.js +86 -67
  87. data/lib/epuber/third_party/bower/bower_components/jquery/src/attributes/prop.js +63 -32
  88. data/lib/epuber/third_party/bower/bower_components/jquery/src/attributes/support.js +6 -5
  89. data/lib/epuber/third_party/bower/bower_components/jquery/src/attributes/val.js +40 -24
  90. data/lib/epuber/third_party/bower/bower_components/jquery/src/attributes.js +2 -2
  91. data/lib/epuber/third_party/bower/bower_components/jquery/src/callbacks.js +114 -87
  92. data/lib/epuber/third_party/bower/bower_components/jquery/src/core/access.js +11 -6
  93. data/lib/epuber/third_party/bower/bower_components/jquery/src/core/init.js +27 -16
  94. data/lib/epuber/third_party/bower/bower_components/jquery/src/core/parseHTML.js +10 -8
  95. data/lib/epuber/third_party/bower/bower_components/jquery/src/core/ready.js +20 -14
  96. data/lib/epuber/third_party/bower/bower_components/jquery/src/core/var/rsingleTag.js +4 -3
  97. data/lib/epuber/third_party/bower/bower_components/jquery/src/core.js +77 -85
  98. data/lib/epuber/third_party/bower/bower_components/jquery/src/css/addGetHookIf.js +5 -3
  99. data/lib/epuber/third_party/bower/bower_components/jquery/src/css/adjustCSS.js +65 -0
  100. data/lib/epuber/third_party/bower/bower_components/jquery/src/css/curCSS.js +20 -17
  101. data/lib/epuber/third_party/bower/bower_components/jquery/src/css/defaultDisplay.js +16 -14
  102. data/lib/epuber/third_party/bower/bower_components/jquery/src/css/hiddenVisibleSelectors.js +9 -6
  103. data/lib/epuber/third_party/bower/bower_components/jquery/src/css/showHide.js +48 -0
  104. data/lib/epuber/third_party/bower/bower_components/jquery/src/css/support.js +86 -61
  105. data/lib/epuber/third_party/bower/bower_components/jquery/src/css/var/cssExpand.js +2 -2
  106. data/lib/epuber/third_party/bower/bower_components/jquery/src/css/var/getStyles.js +8 -5
  107. data/lib/epuber/third_party/bower/bower_components/jquery/src/css/var/isHidden.js +6 -3
  108. data/lib/epuber/third_party/bower/bower_components/jquery/src/css/var/rmargin.js +3 -3
  109. data/lib/epuber/third_party/bower/bower_components/jquery/src/css/var/rnumnonpx.js +2 -2
  110. data/lib/epuber/third_party/bower/bower_components/jquery/src/css/{swap.js → var/swap.js} +3 -7
  111. data/lib/epuber/third_party/bower/bower_components/jquery/src/css.js +107 -55
  112. data/lib/epuber/third_party/bower/bower_components/jquery/src/data/Data.js +93 -74
  113. data/lib/epuber/third_party/bower/bower_components/jquery/src/data/{accepts.js → var/acceptData.js} +4 -6
  114. data/lib/epuber/third_party/bower/bower_components/jquery/src/data/var/{data_user.js → dataPriv.js} +2 -2
  115. data/lib/epuber/third_party/bower/bower_components/jquery/src/data/var/{data_priv.js → dataUser.js} +2 -2
  116. data/lib/epuber/third_party/bower/bower_components/jquery/src/data.js +49 -40
  117. data/lib/epuber/third_party/bower/bower_components/jquery/src/deferred.js +34 -25
  118. data/lib/epuber/third_party/bower/bower_components/jquery/src/deprecated.js +27 -8
  119. data/lib/epuber/third_party/bower/bower_components/jquery/src/dimensions.js +9 -5
  120. data/lib/epuber/third_party/bower/bower_components/jquery/src/effects/Tween.js +14 -7
  121. data/lib/epuber/third_party/bower/bower_components/jquery/src/effects/animatedSelector.js +4 -4
  122. data/lib/epuber/third_party/bower/bower_components/jquery/src/effects.js +96 -115
  123. data/lib/epuber/third_party/bower/bower_components/jquery/src/event/ajax.js +11 -4
  124. data/lib/epuber/third_party/bower/bower_components/jquery/src/event/alias.js +11 -23
  125. data/lib/epuber/third_party/bower/bower_components/jquery/src/event/focusin.js +53 -0
  126. data/lib/epuber/third_party/bower/bower_components/jquery/src/event/support.js +3 -3
  127. data/lib/epuber/third_party/bower/bower_components/jquery/src/event/trigger.js +183 -0
  128. data/lib/epuber/third_party/bower/bower_components/jquery/src/event.js +168 -325
  129. data/lib/epuber/third_party/bower/bower_components/jquery/src/exports/amd.js +3 -3
  130. data/lib/epuber/third_party/bower/bower_components/jquery/src/exports/global.js +2 -8
  131. data/lib/epuber/third_party/bower/bower_components/jquery/src/intro.js +1 -1
  132. data/lib/epuber/third_party/bower/bower_components/jquery/src/jquery.js +5 -5
  133. data/lib/epuber/third_party/bower/bower_components/jquery/src/manipulation/_evalUrl.js +6 -4
  134. data/lib/epuber/third_party/bower/bower_components/jquery/src/manipulation/buildFragment.js +102 -0
  135. data/lib/epuber/third_party/bower/bower_components/jquery/src/manipulation/getAll.js +21 -0
  136. data/lib/epuber/third_party/bower/bower_components/jquery/src/manipulation/setGlobalEval.js +20 -0
  137. data/lib/epuber/third_party/bower/bower_components/jquery/src/manipulation/support.js +7 -6
  138. data/lib/epuber/third_party/bower/bower_components/jquery/src/manipulation/var/rcheckableType.js +3 -3
  139. data/lib/epuber/third_party/bower/bower_components/jquery/src/manipulation/var/rscriptType.js +3 -0
  140. data/lib/epuber/third_party/bower/bower_components/jquery/src/manipulation/var/rtagName.js +3 -0
  141. data/lib/epuber/third_party/bower/bower_components/jquery/src/manipulation/wrapMap.js +27 -0
  142. data/lib/epuber/third_party/bower/bower_components/jquery/src/manipulation.js +206 -305
  143. data/lib/epuber/third_party/bower/bower_components/jquery/src/offset.js +40 -29
  144. data/lib/epuber/third_party/bower/bower_components/jquery/src/outro.js +1 -0
  145. data/lib/epuber/third_party/bower/bower_components/jquery/src/queue/delay.js +6 -6
  146. data/lib/epuber/third_party/bower/bower_components/jquery/src/queue.js +23 -22
  147. data/lib/epuber/third_party/bower/bower_components/jquery/src/selector-native.js +107 -68
  148. data/lib/epuber/third_party/bower/bower_components/jquery/src/selector-sizzle.js +5 -5
  149. data/lib/epuber/third_party/bower/bower_components/jquery/src/selector.js +1 -1
  150. data/lib/epuber/third_party/bower/bower_components/jquery/src/serialize.js +28 -14
  151. data/lib/epuber/third_party/bower/bower_components/jquery/src/traversing/findFilter.js +13 -13
  152. data/lib/epuber/third_party/bower/bower_components/jquery/src/traversing/var/dir.js +20 -0
  153. data/lib/epuber/third_party/bower/bower_components/jquery/src/traversing/var/rneedsContext.js +2 -2
  154. data/lib/epuber/third_party/bower/bower_components/jquery/src/traversing/var/siblings.js +15 -0
  155. data/lib/epuber/third_party/bower/bower_components/jquery/src/traversing.js +32 -56
  156. data/lib/epuber/third_party/bower/bower_components/jquery/src/var/arr.js +2 -2
  157. data/lib/epuber/third_party/bower/bower_components/jquery/src/var/class2type.js +3 -2
  158. data/lib/epuber/third_party/bower/bower_components/jquery/src/var/concat.js +2 -2
  159. data/lib/epuber/third_party/bower/bower_components/jquery/src/var/document.js +3 -0
  160. data/lib/epuber/third_party/bower/bower_components/jquery/src/var/documentElement.js +5 -0
  161. data/lib/epuber/third_party/bower/bower_components/jquery/src/var/hasOwn.js +2 -2
  162. data/lib/epuber/third_party/bower/bower_components/jquery/src/var/indexOf.js +2 -2
  163. data/lib/epuber/third_party/bower/bower_components/jquery/src/var/pnum.js +3 -3
  164. data/lib/epuber/third_party/bower/bower_components/jquery/src/var/push.js +2 -2
  165. data/lib/epuber/third_party/bower/bower_components/jquery/src/var/rcssNum.js +7 -0
  166. data/lib/epuber/third_party/bower/bower_components/jquery/src/var/rnotwhite.js +3 -3
  167. data/lib/epuber/third_party/bower/bower_components/jquery/src/var/slice.js +2 -2
  168. data/lib/epuber/third_party/bower/bower_components/jquery/src/var/support.js +3 -2
  169. data/lib/epuber/third_party/bower/bower_components/jquery/src/var/toString.js +2 -2
  170. data/lib/epuber/third_party/bower/bower_components/jquery/src/wrap.js +19 -19
  171. data/lib/epuber/third_party/bower/bower_components/spin.js/{LICENSE.txt → LICENSE.md} +2 -1
  172. data/lib/epuber/third_party/bower/bower_components/spin.js/README.md +21 -21
  173. data/lib/epuber/third_party/bower/bower_components/spin.js/bower.json +0 -1
  174. data/lib/epuber/third_party/bower/bower_components/spin.js/jquery.spin.js +23 -24
  175. data/lib/epuber/third_party/bower/bower_components/spin.js/spin.js +153 -113
  176. data/lib/epuber/third_party/bower/bower_components/spin.js/spin.min.js +2 -0
  177. data/lib/epuber/third_party/bower/bower_components/uri.js/CHANGELOG.md +424 -0
  178. data/lib/epuber/third_party/bower/bower_components/uri.js/README.md +23 -308
  179. data/lib/epuber/third_party/bower/bower_components/uri.js/SECURITY.md +12 -0
  180. data/lib/epuber/third_party/bower/bower_components/uri.js/bower.json +2 -2
  181. data/lib/epuber/third_party/bower/bower_components/uri.js/contributing.md +0 -4
  182. data/lib/epuber/third_party/bower/bower_components/uri.js/src/IPv6.js +3 -6
  183. data/lib/epuber/third_party/bower/bower_components/uri.js/src/SecondLevelDomains.js +8 -4
  184. data/lib/epuber/third_party/bower/bower_components/uri.js/src/URI.fragmentQuery.js +21 -4
  185. data/lib/epuber/third_party/bower/bower_components/uri.js/src/URI.fragmentURI.js +1 -1
  186. data/lib/epuber/third_party/bower/bower_components/uri.js/src/URI.js +312 -69
  187. data/lib/epuber/third_party/bower/bower_components/uri.js/src/URI.min.js +85 -77
  188. data/lib/epuber/third_party/bower/bower_components/uri.js/src/URITemplate.js +28 -11
  189. data/lib/epuber/third_party/bower/bower_components/uri.js/src/jquery.URI.js +17 -18
  190. data/lib/epuber/third_party/bower/bower_components/uri.js/src/jquery.URI.min.js +6 -6
  191. data/lib/epuber/third_party/bower/bower_components/uri.js/src/punycode.js +63 -38
  192. data/lib/epuber/third_party/bower.rb +2 -0
  193. data/lib/epuber/transformer/text_transformer.rb +1 -2
  194. data/lib/epuber/transformer.rb +1 -2
  195. data/lib/epuber/user_interface.rb +1 -1
  196. data/lib/epuber/vendor/hash_binding.rb +1 -1
  197. data/lib/epuber/vendor/nokogiri_extensions.rb +24 -21
  198. data/lib/epuber/vendor/ruby_templater.rb +1 -2
  199. data/lib/epuber/vendor/size.rb +1 -0
  200. data/lib/epuber/vendor/version.rb +1 -1
  201. data/lib/epuber/version.rb +2 -1
  202. data/lib/epuber.rb +1 -1
  203. metadata +48 -30
  204. data/lib/epuber/third_party/bower/bower_components/jquery/src/sizzle/dist/sizzle.min.js +0 -3
  205. data/lib/epuber/third_party/bower/bower_components/jquery/src/sizzle/dist/sizzle.min.map +0 -1
  206. data/lib/epuber/third_party/bower/bower_components/jquery/src/var/strundefined.js +0 -3
  207. data/lib/epuber/vendor/globals_context.rb +0 -26
@@ -1,12 +1,12 @@
1
1
  /*!
2
- * Sizzle CSS Selector Engine v2.2.0-pre
2
+ * Sizzle CSS Selector Engine v2.2.1
3
3
  * http://sizzlejs.com/
4
4
  *
5
- * Copyright 2008, 2014 jQuery Foundation, Inc. and other contributors
5
+ * Copyright jQuery Foundation and other contributors
6
6
  * Released under the MIT license
7
7
  * http://jquery.org/license
8
8
  *
9
- * Date: 2014-12-16
9
+ * Date: 2015-10-17
10
10
  */
11
11
  (function( window ) {
12
12
 
@@ -74,25 +74,21 @@ var i,
74
74
 
75
75
  // Regular expressions
76
76
 
77
- // Whitespace characters http://www.w3.org/TR/css3-selectors/#whitespace
77
+ // http://www.w3.org/TR/css3-selectors/#whitespace
78
78
  whitespace = "[\\x20\\t\\r\\n\\f]",
79
- // http://www.w3.org/TR/css3-syntax/#characters
80
- characterEncoding = "(?:\\\\.|[\\w-]|[^\\x00-\\xa0])+",
81
79
 
82
- // Loosely modeled on CSS identifier characters
83
- // An unquoted value should be a CSS identifier http://www.w3.org/TR/css3-selectors/#attribute-selectors
84
- // Proper syntax: http://www.w3.org/TR/CSS21/syndata.html#value-def-identifier
85
- identifier = characterEncoding.replace( "w", "w#" ),
80
+ // http://www.w3.org/TR/CSS21/syndata.html#value-def-identifier
81
+ identifier = "(?:\\\\.|[\\w-]|[^\\x00-\\xa0])+",
86
82
 
87
83
  // Attribute selectors: http://www.w3.org/TR/selectors/#attribute-selectors
88
- attributes = "\\[" + whitespace + "*(" + characterEncoding + ")(?:" + whitespace +
84
+ attributes = "\\[" + whitespace + "*(" + identifier + ")(?:" + whitespace +
89
85
  // Operator (capture 2)
90
86
  "*([*^$|!~]?=)" + whitespace +
91
87
  // "Attribute values must be CSS identifiers [capture 5] or strings [capture 3 or capture 4]"
92
88
  "*(?:'((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\"|(" + identifier + "))|)" + whitespace +
93
89
  "*\\]",
94
90
 
95
- pseudos = ":(" + characterEncoding + ")(?:\\((" +
91
+ pseudos = ":(" + identifier + ")(?:\\((" +
96
92
  // To reduce the number of selectors needing tokenize in the preFilter, prefer arguments:
97
93
  // 1. quoted (capture 3; capture 4 or capture 5)
98
94
  "('((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\")|" +
@@ -115,9 +111,9 @@ var i,
115
111
  ridentifier = new RegExp( "^" + identifier + "$" ),
116
112
 
117
113
  matchExpr = {
118
- "ID": new RegExp( "^#(" + characterEncoding + ")" ),
119
- "CLASS": new RegExp( "^\\.(" + characterEncoding + ")" ),
120
- "TAG": new RegExp( "^(" + characterEncoding.replace( "w", "w*" ) + ")" ),
114
+ "ID": new RegExp( "^#(" + identifier + ")" ),
115
+ "CLASS": new RegExp( "^\\.(" + identifier + ")" ),
116
+ "TAG": new RegExp( "^(" + identifier + "|[*])" ),
121
117
  "ATTR": new RegExp( "^" + attributes ),
122
118
  "PSEUDO": new RegExp( "^" + pseudos ),
123
119
  "CHILD": new RegExp( "^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\(" + whitespace +
@@ -195,103 +191,129 @@ try {
195
191
  }
196
192
 
197
193
  function Sizzle( selector, context, results, seed ) {
198
- var match, elem, m, nodeType,
199
- // QSA vars
200
- i, groups, old, nid, newContext, newSelector;
194
+ var m, i, elem, nid, nidselect, match, groups, newSelector,
195
+ newContext = context && context.ownerDocument,
201
196
 
202
- if ( ( context ? context.ownerDocument || context : preferredDoc ) !== document ) {
203
- setDocument( context );
204
- }
197
+ // nodeType defaults to 9, since context defaults to document
198
+ nodeType = context ? context.nodeType : 9;
205
199
 
206
- context = context || document;
207
200
  results = results || [];
208
- nodeType = context.nodeType;
209
201
 
202
+ // Return early from calls with invalid selector or context
210
203
  if ( typeof selector !== "string" || !selector ||
211
204
  nodeType !== 1 && nodeType !== 9 && nodeType !== 11 ) {
212
205
 
213
206
  return results;
214
207
  }
215
208
 
216
- if ( !seed && documentIsHTML ) {
217
-
218
- // Try to shortcut find operations when possible (e.g., not under DocumentFragment)
219
- if ( nodeType !== 11 && (match = rquickExpr.exec( selector )) ) {
220
- // Speed-up: Sizzle("#ID")
221
- if ( (m = match[1]) ) {
222
- if ( nodeType === 9 ) {
223
- elem = context.getElementById( m );
224
- // Check parentNode to catch when Blackberry 4.6 returns
225
- // nodes that are no longer in the document (jQuery #6963)
226
- if ( elem && elem.parentNode ) {
227
- // Handle the case where IE, Opera, and Webkit return items
228
- // by name instead of ID
229
- if ( elem.id === m ) {
230
- results.push( elem );
209
+ // Try to shortcut find operations (as opposed to filters) in HTML documents
210
+ if ( !seed ) {
211
+
212
+ if ( ( context ? context.ownerDocument || context : preferredDoc ) !== document ) {
213
+ setDocument( context );
214
+ }
215
+ context = context || document;
216
+
217
+ if ( documentIsHTML ) {
218
+
219
+ // If the selector is sufficiently simple, try using a "get*By*" DOM method
220
+ // (excepting DocumentFragment context, where the methods don't exist)
221
+ if ( nodeType !== 11 && (match = rquickExpr.exec( selector )) ) {
222
+
223
+ // ID selector
224
+ if ( (m = match[1]) ) {
225
+
226
+ // Document context
227
+ if ( nodeType === 9 ) {
228
+ if ( (elem = context.getElementById( m )) ) {
229
+
230
+ // Support: IE, Opera, Webkit
231
+ // TODO: identify versions
232
+ // getElementById can match elements by name instead of ID
233
+ if ( elem.id === m ) {
234
+ results.push( elem );
235
+ return results;
236
+ }
237
+ } else {
231
238
  return results;
232
239
  }
240
+
241
+ // Element context
233
242
  } else {
234
- return results;
235
- }
236
- } else {
237
- // Context is not a document
238
- if ( context.ownerDocument && (elem = context.ownerDocument.getElementById( m )) &&
239
- contains( context, elem ) && elem.id === m ) {
240
- results.push( elem );
241
- return results;
243
+
244
+ // Support: IE, Opera, Webkit
245
+ // TODO: identify versions
246
+ // getElementById can match elements by name instead of ID
247
+ if ( newContext && (elem = newContext.getElementById( m )) &&
248
+ contains( context, elem ) &&
249
+ elem.id === m ) {
250
+
251
+ results.push( elem );
252
+ return results;
253
+ }
242
254
  }
243
- }
244
255
 
245
- // Speed-up: Sizzle("TAG")
246
- } else if ( match[2] ) {
247
- push.apply( results, context.getElementsByTagName( selector ) );
248
- return results;
256
+ // Type selector
257
+ } else if ( match[2] ) {
258
+ push.apply( results, context.getElementsByTagName( selector ) );
259
+ return results;
249
260
 
250
- // Speed-up: Sizzle(".CLASS")
251
- } else if ( (m = match[3]) && support.getElementsByClassName ) {
252
- push.apply( results, context.getElementsByClassName( m ) );
253
- return results;
254
- }
255
- }
261
+ // Class selector
262
+ } else if ( (m = match[3]) && support.getElementsByClassName &&
263
+ context.getElementsByClassName ) {
256
264
 
257
- // QSA path
258
- if ( support.qsa && (!rbuggyQSA || !rbuggyQSA.test( selector )) ) {
259
- nid = old = expando;
260
- newContext = context;
261
- newSelector = nodeType !== 1 && selector;
262
-
263
- // qSA works strangely on Element-rooted queries
264
- // We can work around this by specifying an extra ID on the root
265
- // and working up from there (Thanks to Andrew Dupont for the technique)
266
- // IE 8 doesn't work on object elements
267
- if ( nodeType === 1 && context.nodeName.toLowerCase() !== "object" ) {
268
- groups = tokenize( selector );
269
-
270
- if ( (old = context.getAttribute("id")) ) {
271
- nid = old.replace( rescape, "\\$&" );
272
- } else {
273
- context.setAttribute( "id", nid );
265
+ push.apply( results, context.getElementsByClassName( m ) );
266
+ return results;
274
267
  }
275
- nid = "[id='" + nid + "'] ";
268
+ }
276
269
 
277
- i = groups.length;
278
- while ( i-- ) {
279
- groups[i] = nid + toSelector( groups[i] );
270
+ // Take advantage of querySelectorAll
271
+ if ( support.qsa &&
272
+ !compilerCache[ selector + " " ] &&
273
+ (!rbuggyQSA || !rbuggyQSA.test( selector )) ) {
274
+
275
+ if ( nodeType !== 1 ) {
276
+ newContext = context;
277
+ newSelector = selector;
278
+
279
+ // qSA looks outside Element context, which is not what we want
280
+ // Thanks to Andrew Dupont for this workaround technique
281
+ // Support: IE <=8
282
+ // Exclude object elements
283
+ } else if ( context.nodeName.toLowerCase() !== "object" ) {
284
+
285
+ // Capture the context ID, setting it first if necessary
286
+ if ( (nid = context.getAttribute( "id" )) ) {
287
+ nid = nid.replace( rescape, "\\$&" );
288
+ } else {
289
+ context.setAttribute( "id", (nid = expando) );
290
+ }
291
+
292
+ // Prefix every selector in the list
293
+ groups = tokenize( selector );
294
+ i = groups.length;
295
+ nidselect = ridentifier.test( nid ) ? "#" + nid : "[id='" + nid + "']";
296
+ while ( i-- ) {
297
+ groups[i] = nidselect + " " + toSelector( groups[i] );
298
+ }
299
+ newSelector = groups.join( "," );
300
+
301
+ // Expand context for sibling selectors
302
+ newContext = rsibling.test( selector ) && testContext( context.parentNode ) ||
303
+ context;
280
304
  }
281
- newContext = rsibling.test( selector ) && testContext( context.parentNode ) || context;
282
- newSelector = groups.join(",");
283
- }
284
305
 
285
- if ( newSelector ) {
286
- try {
287
- push.apply( results,
288
- newContext.querySelectorAll( newSelector )
289
- );
290
- return results;
291
- } catch(qsaError) {
292
- } finally {
293
- if ( !old ) {
294
- context.removeAttribute("id");
306
+ if ( newSelector ) {
307
+ try {
308
+ push.apply( results,
309
+ newContext.querySelectorAll( newSelector )
310
+ );
311
+ return results;
312
+ } catch ( qsaError ) {
313
+ } finally {
314
+ if ( nid === expando ) {
315
+ context.removeAttribute( "id" );
316
+ }
295
317
  }
296
318
  }
297
319
  }
@@ -304,7 +326,7 @@ function Sizzle( selector, context, results, seed ) {
304
326
 
305
327
  /**
306
328
  * Create key-value caches of limited size
307
- * @returns {Function(string, Object)} Returns the Object data after storing it on itself with
329
+ * @returns {function(string, object)} Returns the Object data after storing it on itself with
308
330
  * property name the (space-suffixed) string and (if the cache is larger than Expr.cacheLength)
309
331
  * deleting the oldest entry
310
332
  */
@@ -359,7 +381,7 @@ function assert( fn ) {
359
381
  */
360
382
  function addHandle( attrs, handler ) {
361
383
  var arr = attrs.split("|"),
362
- i = attrs.length;
384
+ i = arr.length;
363
385
 
364
386
  while ( i-- ) {
365
387
  Expr.attrHandle[ arr[i] ] = handler;
@@ -472,33 +494,29 @@ setDocument = Sizzle.setDocument = function( node ) {
472
494
  var hasCompare, parent,
473
495
  doc = node ? node.ownerDocument || node : preferredDoc;
474
496
 
475
- // If no document and documentElement is available, return
497
+ // Return early if doc is invalid or already selected
476
498
  if ( doc === document || doc.nodeType !== 9 || !doc.documentElement ) {
477
499
  return document;
478
500
  }
479
501
 
480
- // Set our document
502
+ // Update global variables
481
503
  document = doc;
482
- docElem = doc.documentElement;
483
- parent = doc.defaultView;
484
-
485
- // Support: IE>8
486
- // If iframe document is assigned to "document" variable and if iframe has been reloaded,
487
- // IE will throw "permission denied" error when accessing "document" variable, see jQuery #13936
488
- // IE6-8 do not support the defaultView property so parent will be undefined
489
- if ( parent && parent !== parent.top ) {
490
- // IE11 does not have attachEvent, so all must suffer
504
+ docElem = document.documentElement;
505
+ documentIsHTML = !isXML( document );
506
+
507
+ // Support: IE 9-11, Edge
508
+ // Accessing iframe documents after unload throws "permission denied" errors (jQuery #13936)
509
+ if ( (parent = document.defaultView) && parent.top !== parent ) {
510
+ // Support: IE 11
491
511
  if ( parent.addEventListener ) {
492
512
  parent.addEventListener( "unload", unloadHandler, false );
513
+
514
+ // Support: IE 9 - 10 only
493
515
  } else if ( parent.attachEvent ) {
494
516
  parent.attachEvent( "onunload", unloadHandler );
495
517
  }
496
518
  }
497
519
 
498
- /* Support tests
499
- ---------------------------------------------------------------------- */
500
- documentIsHTML = !isXML( doc );
501
-
502
520
  /* Attributes
503
521
  ---------------------------------------------------------------------- */
504
522
 
@@ -515,12 +533,12 @@ setDocument = Sizzle.setDocument = function( node ) {
515
533
 
516
534
  // Check if getElementsByTagName("*") returns only elements
517
535
  support.getElementsByTagName = assert(function( div ) {
518
- div.appendChild( doc.createComment("") );
536
+ div.appendChild( document.createComment("") );
519
537
  return !div.getElementsByTagName("*").length;
520
538
  });
521
539
 
522
540
  // Support: IE<9
523
- support.getElementsByClassName = rnative.test( doc.getElementsByClassName );
541
+ support.getElementsByClassName = rnative.test( document.getElementsByClassName );
524
542
 
525
543
  // Support: IE<10
526
544
  // Check if getElementById returns elements by name
@@ -528,7 +546,7 @@ setDocument = Sizzle.setDocument = function( node ) {
528
546
  // so use a roundabout getElementsByName test
529
547
  support.getById = assert(function( div ) {
530
548
  docElem.appendChild( div ).id = expando;
531
- return !doc.getElementsByName || !doc.getElementsByName( expando ).length;
549
+ return !document.getElementsByName || !document.getElementsByName( expando ).length;
532
550
  });
533
551
 
534
552
  // ID find and filter
@@ -536,9 +554,7 @@ setDocument = Sizzle.setDocument = function( node ) {
536
554
  Expr.find["ID"] = function( id, context ) {
537
555
  if ( typeof context.getElementById !== "undefined" && documentIsHTML ) {
538
556
  var m = context.getElementById( id );
539
- // Check parentNode to catch when Blackberry 4.6 returns
540
- // nodes that are no longer in the document #6963
541
- return m && m.parentNode ? [ m ] : [];
557
+ return m ? [ m ] : [];
542
558
  }
543
559
  };
544
560
  Expr.filter["ID"] = function( id ) {
@@ -555,7 +571,8 @@ setDocument = Sizzle.setDocument = function( node ) {
555
571
  Expr.filter["ID"] = function( id ) {
556
572
  var attrId = id.replace( runescape, funescape );
557
573
  return function( elem ) {
558
- var node = typeof elem.getAttributeNode !== "undefined" && elem.getAttributeNode("id");
574
+ var node = typeof elem.getAttributeNode !== "undefined" &&
575
+ elem.getAttributeNode("id");
559
576
  return node && node.value === attrId;
560
577
  };
561
578
  };
@@ -595,7 +612,7 @@ setDocument = Sizzle.setDocument = function( node ) {
595
612
 
596
613
  // Class
597
614
  Expr.find["CLASS"] = support.getElementsByClassName && function( className, context ) {
598
- if ( documentIsHTML ) {
615
+ if ( typeof context.getElementsByClassName !== "undefined" && documentIsHTML ) {
599
616
  return context.getElementsByClassName( className );
600
617
  }
601
618
  };
@@ -615,7 +632,7 @@ setDocument = Sizzle.setDocument = function( node ) {
615
632
  // See http://bugs.jquery.com/ticket/13378
616
633
  rbuggyQSA = [];
617
634
 
618
- if ( (support.qsa = rnative.test( doc.querySelectorAll )) ) {
635
+ if ( (support.qsa = rnative.test( document.querySelectorAll )) ) {
619
636
  // Build QSA regex
620
637
  // Regex strategy adopted from Diego Perini
621
638
  assert(function( div ) {
@@ -625,7 +642,7 @@ setDocument = Sizzle.setDocument = function( node ) {
625
642
  // since its presence should be enough
626
643
  // http://bugs.jquery.com/ticket/12359
627
644
  docElem.appendChild( div ).innerHTML = "<a id='" + expando + "'></a>" +
628
- "<select id='" + expando + "-\f]' msallowcapture=''>" +
645
+ "<select id='" + expando + "-\r\\' msallowcapture=''>" +
629
646
  "<option selected=''></option></select>";
630
647
 
631
648
  // Support: IE8, Opera 11-12.16
@@ -642,7 +659,7 @@ setDocument = Sizzle.setDocument = function( node ) {
642
659
  rbuggyQSA.push( "\\[" + whitespace + "*(?:value|" + booleans + ")" );
643
660
  }
644
661
 
645
- // Support: Chrome<29, Android<4.2+, Safari<7.0+, iOS<7.0+, PhantomJS<1.9.7+
662
+ // Support: Chrome<29, Android<4.4, Safari<7.0+, iOS<7.0+, PhantomJS<1.9.8+
646
663
  if ( !div.querySelectorAll( "[id~=" + expando + "-]" ).length ) {
647
664
  rbuggyQSA.push("~=");
648
665
  }
@@ -665,7 +682,7 @@ setDocument = Sizzle.setDocument = function( node ) {
665
682
  assert(function( div ) {
666
683
  // Support: Windows 8 Native Apps
667
684
  // The type and name attributes are restricted during .innerHTML assignment
668
- var input = doc.createElement("input");
685
+ var input = document.createElement("input");
669
686
  input.setAttribute( "type", "hidden" );
670
687
  div.appendChild( input ).setAttribute( "name", "D" );
671
688
 
@@ -713,7 +730,7 @@ setDocument = Sizzle.setDocument = function( node ) {
713
730
  hasCompare = rnative.test( docElem.compareDocumentPosition );
714
731
 
715
732
  // Element contains another
716
- // Purposefully does not implement inclusive descendent
733
+ // Purposefully self-exclusive
717
734
  // As in, an element does not contain itself
718
735
  contains = hasCompare || rnative.test( docElem.contains ) ?
719
736
  function( a, b ) {
@@ -767,10 +784,10 @@ setDocument = Sizzle.setDocument = function( node ) {
767
784
  (!support.sortDetached && b.compareDocumentPosition( a ) === compare) ) {
768
785
 
769
786
  // Choose the first element that is related to our preferred document
770
- if ( a === doc || a.ownerDocument === preferredDoc && contains(preferredDoc, a) ) {
787
+ if ( a === document || a.ownerDocument === preferredDoc && contains(preferredDoc, a) ) {
771
788
  return -1;
772
789
  }
773
- if ( b === doc || b.ownerDocument === preferredDoc && contains(preferredDoc, b) ) {
790
+ if ( b === document || b.ownerDocument === preferredDoc && contains(preferredDoc, b) ) {
774
791
  return 1;
775
792
  }
776
793
 
@@ -798,8 +815,8 @@ setDocument = Sizzle.setDocument = function( node ) {
798
815
 
799
816
  // Parentless nodes are either documents or disconnected
800
817
  if ( !aup || !bup ) {
801
- return a === doc ? -1 :
802
- b === doc ? 1 :
818
+ return a === document ? -1 :
819
+ b === document ? 1 :
803
820
  aup ? -1 :
804
821
  bup ? 1 :
805
822
  sortInput ?
@@ -836,7 +853,7 @@ setDocument = Sizzle.setDocument = function( node ) {
836
853
  0;
837
854
  };
838
855
 
839
- return doc;
856
+ return document;
840
857
  };
841
858
 
842
859
  Sizzle.matches = function( expr, elements ) {
@@ -853,6 +870,7 @@ Sizzle.matchesSelector = function( elem, expr ) {
853
870
  expr = expr.replace( rattributeQuotes, "='$1']" );
854
871
 
855
872
  if ( support.matchesSelector && documentIsHTML &&
873
+ !compilerCache[ expr + " " ] &&
856
874
  ( !rbuggyMatches || !rbuggyMatches.test( expr ) ) &&
857
875
  ( !rbuggyQSA || !rbuggyQSA.test( expr ) ) ) {
858
876
 
@@ -1126,11 +1144,12 @@ Expr = Sizzle.selectors = {
1126
1144
  } :
1127
1145
 
1128
1146
  function( elem, context, xml ) {
1129
- var cache, outerCache, node, diff, nodeIndex, start,
1147
+ var cache, uniqueCache, outerCache, node, nodeIndex, start,
1130
1148
  dir = simple !== forward ? "nextSibling" : "previousSibling",
1131
1149
  parent = elem.parentNode,
1132
1150
  name = ofType && elem.nodeName.toLowerCase(),
1133
- useCache = !xml && !ofType;
1151
+ useCache = !xml && !ofType,
1152
+ diff = false;
1134
1153
 
1135
1154
  if ( parent ) {
1136
1155
 
@@ -1139,7 +1158,10 @@ Expr = Sizzle.selectors = {
1139
1158
  while ( dir ) {
1140
1159
  node = elem;
1141
1160
  while ( (node = node[ dir ]) ) {
1142
- if ( ofType ? node.nodeName.toLowerCase() === name : node.nodeType === 1 ) {
1161
+ if ( ofType ?
1162
+ node.nodeName.toLowerCase() === name :
1163
+ node.nodeType === 1 ) {
1164
+
1143
1165
  return false;
1144
1166
  }
1145
1167
  }
@@ -1153,11 +1175,21 @@ Expr = Sizzle.selectors = {
1153
1175
 
1154
1176
  // non-xml :nth-child(...) stores cache data on `parent`
1155
1177
  if ( forward && useCache ) {
1178
+
1156
1179
  // Seek `elem` from a previously-cached index
1157
- outerCache = parent[ expando ] || (parent[ expando ] = {});
1158
- cache = outerCache[ type ] || [];
1159
- nodeIndex = cache[0] === dirruns && cache[1];
1160
- diff = cache[0] === dirruns && cache[2];
1180
+
1181
+ // ...in a gzip-friendly way
1182
+ node = parent;
1183
+ outerCache = node[ expando ] || (node[ expando ] = {});
1184
+
1185
+ // Support: IE <9 only
1186
+ // Defend against cloned attroperties (jQuery gh-1709)
1187
+ uniqueCache = outerCache[ node.uniqueID ] ||
1188
+ (outerCache[ node.uniqueID ] = {});
1189
+
1190
+ cache = uniqueCache[ type ] || [];
1191
+ nodeIndex = cache[ 0 ] === dirruns && cache[ 1 ];
1192
+ diff = nodeIndex && cache[ 2 ];
1161
1193
  node = nodeIndex && parent.childNodes[ nodeIndex ];
1162
1194
 
1163
1195
  while ( (node = ++nodeIndex && node && node[ dir ] ||
@@ -1167,29 +1199,55 @@ Expr = Sizzle.selectors = {
1167
1199
 
1168
1200
  // When found, cache indexes on `parent` and break
1169
1201
  if ( node.nodeType === 1 && ++diff && node === elem ) {
1170
- outerCache[ type ] = [ dirruns, nodeIndex, diff ];
1202
+ uniqueCache[ type ] = [ dirruns, nodeIndex, diff ];
1171
1203
  break;
1172
1204
  }
1173
1205
  }
1174
1206
 
1175
- // Use previously-cached element index if available
1176
- } else if ( useCache && (cache = (elem[ expando ] || (elem[ expando ] = {}))[ type ]) && cache[0] === dirruns ) {
1177
- diff = cache[1];
1178
-
1179
- // xml :nth-child(...) or :nth-last-child(...) or :nth(-last)?-of-type(...)
1180
1207
  } else {
1181
- // Use the same loop as above to seek `elem` from the start
1182
- while ( (node = ++nodeIndex && node && node[ dir ] ||
1183
- (diff = nodeIndex = 0) || start.pop()) ) {
1208
+ // Use previously-cached element index if available
1209
+ if ( useCache ) {
1210
+ // ...in a gzip-friendly way
1211
+ node = elem;
1212
+ outerCache = node[ expando ] || (node[ expando ] = {});
1184
1213
 
1185
- if ( ( ofType ? node.nodeName.toLowerCase() === name : node.nodeType === 1 ) && ++diff ) {
1186
- // Cache the index of each encountered element
1187
- if ( useCache ) {
1188
- (node[ expando ] || (node[ expando ] = {}))[ type ] = [ dirruns, diff ];
1189
- }
1214
+ // Support: IE <9 only
1215
+ // Defend against cloned attroperties (jQuery gh-1709)
1216
+ uniqueCache = outerCache[ node.uniqueID ] ||
1217
+ (outerCache[ node.uniqueID ] = {});
1190
1218
 
1191
- if ( node === elem ) {
1192
- break;
1219
+ cache = uniqueCache[ type ] || [];
1220
+ nodeIndex = cache[ 0 ] === dirruns && cache[ 1 ];
1221
+ diff = nodeIndex;
1222
+ }
1223
+
1224
+ // xml :nth-child(...)
1225
+ // or :nth-last-child(...) or :nth(-last)?-of-type(...)
1226
+ if ( diff === false ) {
1227
+ // Use the same loop as above to seek `elem` from the start
1228
+ while ( (node = ++nodeIndex && node && node[ dir ] ||
1229
+ (diff = nodeIndex = 0) || start.pop()) ) {
1230
+
1231
+ if ( ( ofType ?
1232
+ node.nodeName.toLowerCase() === name :
1233
+ node.nodeType === 1 ) &&
1234
+ ++diff ) {
1235
+
1236
+ // Cache the index of each encountered element
1237
+ if ( useCache ) {
1238
+ outerCache = node[ expando ] || (node[ expando ] = {});
1239
+
1240
+ // Support: IE <9 only
1241
+ // Defend against cloned attroperties (jQuery gh-1709)
1242
+ uniqueCache = outerCache[ node.uniqueID ] ||
1243
+ (outerCache[ node.uniqueID ] = {});
1244
+
1245
+ uniqueCache[ type ] = [ dirruns, diff ];
1246
+ }
1247
+
1248
+ if ( node === elem ) {
1249
+ break;
1250
+ }
1193
1251
  }
1194
1252
  }
1195
1253
  }
@@ -1551,10 +1609,10 @@ function addCombinator( matcher, combinator, base ) {
1551
1609
 
1552
1610
  // Check against all ancestor/preceding elements
1553
1611
  function( elem, context, xml ) {
1554
- var oldCache, outerCache,
1612
+ var oldCache, uniqueCache, outerCache,
1555
1613
  newCache = [ dirruns, doneName ];
1556
1614
 
1557
- // We can't set arbitrary data on XML nodes, so they don't benefit from dir caching
1615
+ // We can't set arbitrary data on XML nodes, so they don't benefit from combinator caching
1558
1616
  if ( xml ) {
1559
1617
  while ( (elem = elem[ dir ]) ) {
1560
1618
  if ( elem.nodeType === 1 || checkNonElements ) {
@@ -1567,14 +1625,19 @@ function addCombinator( matcher, combinator, base ) {
1567
1625
  while ( (elem = elem[ dir ]) ) {
1568
1626
  if ( elem.nodeType === 1 || checkNonElements ) {
1569
1627
  outerCache = elem[ expando ] || (elem[ expando ] = {});
1570
- if ( (oldCache = outerCache[ dir ]) &&
1628
+
1629
+ // Support: IE <9 only
1630
+ // Defend against cloned attroperties (jQuery gh-1709)
1631
+ uniqueCache = outerCache[ elem.uniqueID ] || (outerCache[ elem.uniqueID ] = {});
1632
+
1633
+ if ( (oldCache = uniqueCache[ dir ]) &&
1571
1634
  oldCache[ 0 ] === dirruns && oldCache[ 1 ] === doneName ) {
1572
1635
 
1573
1636
  // Assign to newCache so results back-propagate to previous elements
1574
1637
  return (newCache[ 2 ] = oldCache[ 2 ]);
1575
1638
  } else {
1576
1639
  // Reuse newcache so results back-propagate to previous elements
1577
- outerCache[ dir ] = newCache;
1640
+ uniqueCache[ dir ] = newCache;
1578
1641
 
1579
1642
  // A match means we're done; a fail means we have to keep checking
1580
1643
  if ( (newCache[ 2 ] = matcher( elem, context, xml )) ) {
@@ -1799,18 +1862,21 @@ function matcherFromGroupMatchers( elementMatchers, setMatchers ) {
1799
1862
  len = elems.length;
1800
1863
 
1801
1864
  if ( outermost ) {
1802
- outermostContext = context !== document && context;
1865
+ outermostContext = context === document || context || outermost;
1803
1866
  }
1804
1867
 
1805
1868
  // Add elements passing elementMatchers directly to results
1806
- // Keep `i` a string if there are no elements so `matchedCount` will be "00" below
1807
1869
  // Support: IE<9, Safari
1808
1870
  // Tolerate NodeList properties (IE: "length"; Safari: <number>) matching elements by id
1809
1871
  for ( ; i !== len && (elem = elems[i]) != null; i++ ) {
1810
1872
  if ( byElement && elem ) {
1811
1873
  j = 0;
1874
+ if ( !context && elem.ownerDocument !== document ) {
1875
+ setDocument( elem );
1876
+ xml = !documentIsHTML;
1877
+ }
1812
1878
  while ( (matcher = elementMatchers[j++]) ) {
1813
- if ( matcher( elem, context, xml ) ) {
1879
+ if ( matcher( elem, context || document, xml) ) {
1814
1880
  results.push( elem );
1815
1881
  break;
1816
1882
  }
@@ -1834,8 +1900,17 @@ function matcherFromGroupMatchers( elementMatchers, setMatchers ) {
1834
1900
  }
1835
1901
  }
1836
1902
 
1837
- // Apply set filters to unmatched elements
1903
+ // `i` is now the count of elements visited above, and adding it to `matchedCount`
1904
+ // makes the latter nonnegative.
1838
1905
  matchedCount += i;
1906
+
1907
+ // Apply set filters to unmatched elements
1908
+ // NOTE: This can be skipped if there are no unmatched elements (i.e., `matchedCount`
1909
+ // equals `i`), unless we didn't visit _any_ elements in the above loop because we have
1910
+ // no element matchers and no seed.
1911
+ // Incrementing an initially-string "0" `i` allows `i` to remain a string only in that
1912
+ // case, which will result in a "00" `matchedCount` that differs from `i` but is also
1913
+ // numerically zero.
1839
1914
  if ( bySet && i !== matchedCount ) {
1840
1915
  j = 0;
1841
1916
  while ( (matcher = setMatchers[j++]) ) {
@@ -1927,10 +2002,11 @@ select = Sizzle.select = function( selector, context, results, seed ) {
1927
2002
 
1928
2003
  results = results || [];
1929
2004
 
1930
- // Try to minimize operations if there is no seed and only one group
2005
+ // Try to minimize operations if there is only one selector in the list and no seed
2006
+ // (the latter of which guarantees us context)
1931
2007
  if ( match.length === 1 ) {
1932
2008
 
1933
- // Take a shortcut and set the context if the root selector is an ID
2009
+ // Reduce context if the leading compound selector is an ID
1934
2010
  tokens = match[0] = match[0].slice( 0 );
1935
2011
  if ( tokens.length > 2 && (token = tokens[0]).type === "ID" &&
1936
2012
  support.getById && context.nodeType === 9 && documentIsHTML &&
@@ -1985,7 +2061,7 @@ select = Sizzle.select = function( selector, context, results, seed ) {
1985
2061
  context,
1986
2062
  !documentIsHTML,
1987
2063
  results,
1988
- rsibling.test( selector ) && testContext( context.parentNode ) || context
2064
+ !context || rsibling.test( selector ) && testContext( context.parentNode ) || context
1989
2065
  );
1990
2066
  return results;
1991
2067
  };