New issue
Advanced search Search tips
Note: Color blocks (like or ) mean that a user may not be available. Tooltip shows the reason.

Issue 621172 link

Starred by 6 users

Issue metadata

Status: Verified
Owner:
Last visit > 30 days ago
Closed: Jun 2017
Cc:
Components:
EstimatedDays: ----
NextAction: ----
OS: Linux , Android , Windows , Chrome , Mac
Pri: 2
Type: Bug



Sign in to add a comment

querySelector and getElementById behave differently when accessing HTML template by id within HTML import

Reported by marciot....@gmail.com, Jun 17 2016

Issue description

Chrome 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.

 
chrome-bug-report.zip
2.6 KB Download
Components: Blink>HTML
Labels: Needs-Feedback
Tested the issue on Windows 7, Mac 10.11.5, Ubuntu 14.04 using latest stable 51.0.2704.103, canary 53.0.2773.0 with below steps:

1.Unzipped chrome-bug-report.zip file and added as unpacked extension in chrome://extensions page.
2.Getting error, not loaded.
3.Got blank page when opened index.html in new tab of chrome.

marciot.freeshell.org@Could you please provide detailed reproducible steps, OS details with actual and expected behavior screencast for better understanding the issue to triage it further.
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.
Project Member

Comment 3 by sheriffbot@chromium.org, Jun 22 2016

Labels: -Needs-Feedback Needs-Review
Owner: ssamanoori@chromium.org
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

Comment 4 by tkent@chromium.org, Jun 24 2016

Components: -Blink>HTML Blink>WebComponents
Labels: -Needs-Review Needs-Feedback
Owner: ----
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.
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>​
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.
Attached source code of improved demo (also available at http://marciot.freeshell.org/chromium_issue_621172)
chrome-bug-report-updated.zip
1.3 KB Download
Project Member

Comment 9 by sheriffbot@chromium.org, Jul 13 2016

Labels: -Needs-Feedback Needs-Review
Owner: ssamanoori@chromium.org
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
Cc: kojii@chromium.org ssamanoori@chromium.org
Labels: -Pri-3 -Needs-Review OS-Android OS-Chrome OS-Linux OS-Mac OS-Windows Pri-2
Owner: dominicc@chromium.org
Status: Available (was: Unconfirmed)
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.

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 :)
Components: -Blink>WebComponents Blink>HTML>Modules Blink>DOM

Comment 13 by kochi@chromium.org, Feb 24 2017

Cc: dominicc@chromium.org tkonch...@chromium.org hayato@chromium.org kochi@chromium.org
 Issue 605900  has been merged into this issue.
Owner: kochi@chromium.org
Kochi, could you have a look at this bug? It relates to the compatMode of import documents.

Comment 15 by kochi@chromium.org, Jun 21 2017

Status: Started (was: Available)
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.
Project Member

Comment 16 by bugdroid1@chromium.org, 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

Comment 17 by kochi@chromium.org, Jun 26 2017

Status: Fixed (was: Started)

Comment 18 by kochi@chromium.org, Jun 26 2017

Status: Verified (was: Fixed)
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