querySelector and getElementById behave differently when accessing HTML template by id within HTML import
Reported by
marciot....@gmail.com,
Jun 17 2016
|
||||||||||||
Issue descriptionChrome Version : 51.0.2704.103 (Official Build) (64-bit) URL : See attachment Behavior in Safari 9.1.1 (11601.6.17): OK (when using webcomponents.org polyfill) Behavior in Firefox 47.0: OK (when using webcomponents.org polyfill) What steps will reproduce the problem? (1) Put the attached files on a web server (2) View index.html What is the expected result? On the page: "I'm in Shadow DOM. My markup was stamped from a <template>." in orange In the JavaScript console: The output of querySelector and getElementById are both non-null What happens instead? On the page: "querySelector failed" In the JavaScript console: The output of querySelector is null and the output of getElementById is non-null Please provide any additional information below. Attach a screenshot if possible.
,
Jun 21 2016
Hi ssamanoori, This is not an Chrome extension (sorry if I posted this in the wrong place). The two files are regular HTML files that need to be served up by a web server. If you don't have access to one, I have placed them here: http://marciot.freeshell.org/chromium_issue_621172/ To reproduce, open Chrome and go to that URL.
,
Jun 22 2016
Thank you for providing more feedback. Adding requester "ssamanoori@chromium.org" for another review and adding "Needs-Review" label for tracking. For more details visit https://www.chromium.org/issue-tracking/autotriage - Your friendly Sheriffbot
,
Jun 24 2016
,
Jul 12 2016
Got error message 'querySelector failed' when opened chrome and navigated to 'http://marciot.freeshell.org/chromium_issue_621172/' URL. marciot.freeshell.org@Could you please provide another sample html file or URL with actual and expected behavior screencast for further triaging the issue.
,
Jul 12 2016
Ssamanoori, The message "querySelector failed" is the error condition which should not be happening. It only happens in Chrome because the function querySelector is returning "null" when it should be returning a template element. You can also look in the JavaScript developer's console. It prints out: null <template id="MyTemplate">…</template> Instead, it should print out: <template id="MyTemplate">…</template> <template id="MyTemplate">…</template>
,
Jul 12 2016
I realize my initial demo was not very clear. I have updated http://marciot.freeshell.org/chromium_issue_621172/ with a clearer version. Expected output: The value of importDoc.querySelector('#MyTemplate') is [object HTMLTemplateElement] The value of importDoc.getElementById('MyTemplate') is [object HTMLTemplateElement] The two values should be the same. I'm in Shadow DOM. My markup was stamped from a <template>. Current output: The value of importDoc.querySelector('#MyTemplate') is null The value of importDoc.getElementById('MyTemplate') is [object HTMLTemplateElement] The two values should be the same. If you see this, the test has failed You can now compare the results from Chrome and Firefox and see that the results are correct under Firefox.
,
Jul 12 2016
Attached source code of improved demo (also available at http://marciot.freeshell.org/chromium_issue_621172)
,
Jul 13 2016
Thank you for providing more feedback. Adding requester "ssamanoori@chromium.org" for another review and adding "Needs-Review" label for tracking. For more details visit https://www.chromium.org/issue-tracking/autotriage - Your friendly Sheriffbot
,
Jul 15 2016
Interesting bug. I think this is caused by the master document being in quirks mode; which you can see with document.compatMode. This probably shouldn't affect how IDs are matched in the import document, but it does. I think as a workaround you could use a slightly different selector, like *[id=MyTemplate]; or make your IDs lowercase; or make the master document not be in quirks mode.
,
Jul 15 2016
I think the workaround is simpler than that, simply use getElementById when instantiating your template. querySelector is a convenience method in most cases. What makes this bug insidious is that several WebComponents tutorials out there uses querySelector, so beginners are sure to be tripped up by this bug -- I know it sure tripped me up :)
,
Oct 12 2016
,
Feb 24 2017
Issue 605900 has been merged into this issue.
,
Jun 20 2017
Kochi, could you have a look at this bug? It relates to the compatMode of import documents.
,
Jun 21 2017
Started to look into, but it looks more complicated than expected. For styles in <style> element in imports, as they are applied to the main document, it follows the mode of the master document. For querySelector() API, it should follow its context object's ownerDocument's mode. The immediate problem is CSSSelectorParser assumes the former as the master document is in quirks mode, and lowercases the #ID query identifier assuming that all the queries are executed in querySelector API, but in imports the mode is treated as standard mode and all IDs are stored case-sensitive. I'll start with making tests for comprehensive combinations of quirks/standard mix.
,
Jun 23 2017
The following revision refers to this bug: https://chromium.googlesource.com/chromium/src.git/+/01fa05c1eb8ef98c17664cbd582bef31af811b77 commit 01fa05c1eb8ef98c17664cbd582bef31af811b77 Author: Takayoshi Kochi <kochi@chromium.org> Date: Fri Jun 23 16:06:03 2017 Honor context object's document's quirks mode in querySelector. When CSSParserContext is created, it determines whether the context is in quirks mode or not, by looking at master document's quirks mode flag instead of context object's document. This worked for stylesheets in <style> element in an import, because the style rules defined there actually applies to the master document. This caused problem for querySelector/querySelectorAll because the query mode mismatches when the master document is in quirks mode. HTML Imports are always in no quirks mode without DOCTYPE declaration[1][2]. As we optimize ID match for quirks mode by lowercasing IDs in HTML and ID selectors in CSS, but when the master document is in quirks mode, querySelector in import ran in quirks mode (thus selector was lowercased) while IDs in import are preserving case, and never matched. The fix for this is to check if it is in querySelector (i.e. not using dynamic profile), use the document's mode, rather than its master document's mode. [1] http://w3c.github.io/webcomponents/spec/imports/#additions-to-tree-construction-algorithm [2] https://www.w3.org/Bugs/Public/show_bug.cgi?id=24349 Bug: 621172 Change-Id: I110bd62df962009ee015239fbc0e5fe24a1e6893 Reviewed-on: https://chromium-review.googlesource.com/544732 Commit-Queue: Takayoshi Kochi <kochi@chromium.org> Reviewed-by: Rune Lillesveen <rune@opera.com> Cr-Commit-Position: refs/heads/master@{#481911} [add] https://crrev.com/01fa05c1eb8ef98c17664cbd582bef31af811b77/third_party/WebKit/LayoutTests/fast/html/imports/import-style-no-quirks.html [add] https://crrev.com/01fa05c1eb8ef98c17664cbd582bef31af811b77/third_party/WebKit/LayoutTests/fast/html/imports/import-style-quirks.html [add] https://crrev.com/01fa05c1eb8ef98c17664cbd582bef31af811b77/third_party/WebKit/LayoutTests/fast/html/imports/resources/import-no-quirks.html [add] https://crrev.com/01fa05c1eb8ef98c17664cbd582bef31af811b77/third_party/WebKit/LayoutTests/fast/html/imports/resources/import-quirks.html [modify] https://crrev.com/01fa05c1eb8ef98c17664cbd582bef31af811b77/third_party/WebKit/Source/core/css/parser/CSSParserContext.cpp
,
Jun 26 2017
,
Jun 26 2017
Verified the fix (with the provided test case in #8) on Mac canary 61.0.3141.0 (Official Build) canary (64-bit) |
||||||||||||
►
Sign in to add a comment |
||||||||||||
Comment 1 by ssamanoori@chromium.org
, Jun 21 2016Labels: Needs-Feedback