Commit 01fa05c1 authored by Takayoshi Kochi's avatar Takayoshi Kochi Committed by Commit Bot

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: default avatarRune Lillesveen <rune@opera.com>
Cr-Commit-Position: refs/heads/master@{#481911}
parent a55316f4
<!DOCTYPE html>
<html>
<head>
<script src="../../../resources/testharness.js"></script>
<script src="../../../resources/testharnessreport.js"></script>
<link rel="import" href="resources/import-quirks.html">
<link rel="import" href="resources/import-no-quirks.html">
</head>
<body>
<div id="MyElement">MyElement</div>
<div class="MyClass" id="OtherElement">OtherElement</div>
</body>
<script>
'use strict';
let master_my_el = document.getElementById('MyElement');
let master_my_class = document.getElementById('OtherElement');
test(() => {
assert_equals(document.compatMode, 'CSS1Compat');
}, 'This document should be in no quirks mode.');
test(() => {
assert_equals(document.getElementById('myelement'), null);
assert_equals(document.getElementById('MyElement'), master_my_el);
assert_equals(document.getElementById('MYELEMENT'), null);
}, 'getElementById should be case sensitive regardless of mode.');
test(() => {
assert_equals(document.getElementsByClassName('myclass').length, 0);
assert_equals(document.getElementsByClassName('MyClass')[0],
master_my_class);
assert_equals(document.getElementsByClassName('MYCLASS').length, 0);
}, 'getElementsByClassName should be case sensitive in no quirks mode.');
test(() => {
assert_equals(document.querySelector('#myelement'), null);
assert_equals(document.querySelector('#MyElement'), master_my_el);
assert_equals(document.querySelector('#MYELEMENT'), null);
assert_equals(document.querySelector('.myclass'), null);
assert_equals(document.querySelector('.MyClass'), master_my_class);
assert_equals(document.querySelector('.MYCLASS'), null);
}, 'querySelector should be case sensitive when in no quirks mode.');
</script>
</html>
<!-- quirks mode -->
<html>
<head>
<script src="../../../resources/testharness.js"></script>
<script src="../../../resources/testharnessreport.js"></script>
<link rel="import" href="resources/import-quirks.html">
<link rel="import" href="resources/import-no-quirks.html">
</head>
<body>
<div id="MyElement">MyElement</div>
<div class="MyClass" id="OtherElement">OtherElement</div>
</body>
<script>
'use strict';
let master_my_el = document.getElementById('MyElement');
let master_my_class = document.getElementById('OtherElement');
test(() => {
assert_equals(document.compatMode, 'BackCompat');
}, 'This document should be in quirks mode.');
test(() => {
assert_equals(document.getElementById('myelement'), null);
assert_equals(document.getElementById('MyElement'), master_my_el);
assert_equals(document.getElementById('MYELEMENT'), null);
}, 'getElementById should be case sensitive regardless of mode.');
test(() => {
assert_equals(document.getElementsByClassName('myclass')[0],
master_my_class);
assert_equals(document.getElementsByClassName('MyClass')[0],
master_my_class);
assert_equals(document.getElementsByClassName('MYCLASS')[0],
master_my_class);
}, 'getElementsByClassName should be case insensitive in quirks mode.');
test(() => {
assert_equals(document.querySelector('#myelement'), master_my_el);
assert_equals(document.querySelector('#MyElement'), master_my_el);
assert_equals(document.querySelector('#MYELEMENT'), master_my_el);
assert_equals(document.querySelector('.myclass'), master_my_class);
assert_equals(document.querySelector('.MyClass'), master_my_class);
assert_equals(document.querySelector('.MYCLASS'), master_my_class);
}, 'querySelector should be case insensitive when in quirks mode.');
</script>
</html>
<!DOCTYPE html>
<body>
<div id="MyElement">MyElement</div>
<div class="MyClass" id="OtherElement">OtherElement</div>
</body>
<script>
'use strict';
let noquirks_doc = document.currentScript.ownerDocument;
let noquirks_my_el = noquirks_doc.getElementById('MyElement');
let noquirks_my_class = noquirks_doc.getElementById('OtherElement');
test(() => {
assert_equals(quirks_doc.compatMode, 'CSS1Compat');
}, 'This import should be no quirks mode.');
test(() => {
assert_equals(quirks_doc.getElementById('myelement'), null);
assert_equals(quirks_doc.getElementById('MyElement'), quirks_my_el);
assert_equals(quirks_doc.getElementById('MYELEMENT'), null);
}, 'getElementById should be case sensitive in import with doctype.');
test(() => {
assert_equals(quirks_doc.getElementsByClassName('myclass').length, 0);
assert_equals(quirks_doc.getElementsByClassName('MyClass')[0],
quirks_my_class);
assert_equals(quirks_doc.getElementsByClassName('MYCLASS').length, 0);
}, 'getElementsByClassName should be case sensitive in import with doctype.');
test(() => {
assert_equals(quirks_doc.querySelector('#myelement'), null);
assert_equals(quirks_doc.querySelector('#MyElement'), quirks_my_el);
assert_equals(quirks_doc.querySelector('#MYELEMENT'), null);
assert_equals(quirks_doc.querySelector('.myclass'), null);
assert_equals(quirks_doc.querySelector('.MyClass'), quirks_my_class);
assert_equals(quirks_doc.querySelector('.MYCLASS'), null);
}, 'querySelector should be case sensitive in import with doctype.');
</script>
<!--
Note: All HTML Import files are treated as no quirks mode, and omitting doctype
is not turning on quirks mode, therefore this file is in no quirks mode,
on contrary to the filename.
-->
<body>
<div id="MyElement">MyElement</div>
<div class="MyClass" id="OtherElement">OtherElement</div>
</body>
<script>
'use strict';
let quirks_doc = document.currentScript.ownerDocument;
let quirks_my_el = quirks_doc.getElementById('MyElement');
let quirks_my_class = quirks_doc.getElementById('OtherElement');
test(() => {
assert_equals(quirks_doc.compatMode, 'CSS1Compat');
}, 'This import should be in no quirks mode without doctype.');
test(() => {
assert_equals(quirks_doc.getElementById('myelement'), null);
assert_equals(quirks_doc.getElementById('MyElement'), quirks_my_el);
assert_equals(quirks_doc.getElementById('MYELEMENT'), null);
}, 'getElementById should be case sensitive in import without doctype.');
test(() => {
assert_equals(quirks_doc.getElementsByClassName('myclass').length, 0);
assert_equals(quirks_doc.getElementsByClassName('MyClass')[0],
quirks_my_class);
assert_equals(quirks_doc.getElementsByClassName('MYCLASS').length, 0);
}, 'getElementsByClassName should be case sensitive in import without doctype.');
test(() => {
assert_equals(quirks_doc.querySelector('#myelement'), null);
assert_equals(quirks_doc.querySelector('#MyElement'), quirks_my_el);
assert_equals(quirks_doc.querySelector('#MYELEMENT'), null);
assert_equals(quirks_doc.querySelector('.myclass'), null);
assert_equals(quirks_doc.querySelector('.MyClass'), quirks_my_class);
assert_equals(quirks_doc.querySelector('.MYCLASS'), null);
}, 'querySelector should be case sensitive in import wihout doctype.');
</script>
......@@ -83,8 +83,8 @@ CSSParserContext* CSSParserContext::Create(
CSSParserMode mode =
document.InQuirksMode() ? kHTMLQuirksMode : kHTMLStandardMode;
CSSParserMode match_mode;
if (HTMLImportsController* imports_controller =
document.ImportsController()) {
HTMLImportsController* imports_controller = document.ImportsController();
if (imports_controller && profile == kDynamicProfile) {
match_mode = imports_controller->Master()->InQuirksMode()
? kHTMLQuirksMode
: kHTMLStandardMode;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment