epuber 0.5.6 → 0.7.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (208) hide show
  1. checksums.yaml +4 -4
  2. data/Gemfile +5 -2
  3. data/README.md +20 -26
  4. data/bin/epuber +2 -3
  5. data/epuber.gemspec +10 -12
  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 -2
  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 +6 -2
  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 +5 -3
  46. data/lib/epuber/compiler.rb +7 -11
  47. data/lib/epuber/config.rb +3 -4
  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_priv.js → dataPriv.js} +2 -2
  115. data/lib/epuber/third_party/bower/bower_components/jquery/src/data/var/{data_user.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 +78 -48
  204. data/lib/epuber/ruby_extensions/string.rb +0 -16
  205. data/lib/epuber/third_party/bower/bower_components/jquery/src/sizzle/dist/sizzle.min.js +0 -3
  206. data/lib/epuber/third_party/bower/bower_components/jquery/src/sizzle/dist/sizzle.min.map +0 -1
  207. data/lib/epuber/third_party/bower/bower_components/jquery/src/var/strundefined.js +0 -3
  208. 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
  };