+2007-03-24 Darin Adler <darin@apple.com>
+
+ Reviewed by Mitz.
+
+ - test for http://bugs.webkit.org/show_bug.cgi?id=13123
+ CSS selectors that use :lang, :not, and namespaces do not serialize correctly
+
+ * fast/css/css-selector-text-expected.txt: Added.
+ * fast/css/css-selector-text.html: Added.
+
2007-03-24 Nikolas Zimmermann <zimmermann@kde.org>
Reviewed by Oliver.
--- /dev/null
+This tests parsing and re-serialization of some CSS selectors.
+
+On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
+
+
+PASS parseThenSerializeRule('* { }') is '* { }'
+PASS parseThenSerializeRule('a { }') is 'a { }'
+PASS parseThenSerializeRule('#a { }') is '#a { }'
+PASS parseThenSerializeRule('.a { }') is '.a { }'
+PASS parseThenSerializeRule(':active { }') is ':active { }'
+PASS parseThenSerializeRule('[a] { }') is '[a] { }'
+PASS parseThenSerializeRule('[a="b"] { }') is '[a="b"] { }'
+PASS parseThenSerializeRule('[a~="b"] { }') is '[a~="b"] { }'
+PASS parseThenSerializeRule('[a|="b"] { }') is '[a|="b"] { }'
+PASS parseThenSerializeRule('[a^="b"] { }') is '[a^="b"] { }'
+PASS parseThenSerializeRule('[a$="b"] { }') is '[a$="b"] { }'
+PASS parseThenSerializeRule('[a*="b"] { }') is '[a*="b"] { }'
+
+PASS parseThenSerializeRule('*|a { }') is '*|a { }'
+PASS parseThenSerializeRule('n|a { }') is 'n|a { }'
+PASS parseThenSerializeRule('*|* { }') is '*|* { }'
+PASS parseThenSerializeRule('n|* { }') is 'n|* { }'
+PASS parseThenSerializeRule('[*|a] { }') is '[*|a] { }'
+PASS parseThenSerializeRule('[n|a] { }') is '[n|a] { }'
+
+PASS parseThenSerializeRule('a:active { }') is 'a:active { }'
+PASS parseThenSerializeRule('a b { }') is 'a b { }'
+PASS parseThenSerializeRule('a + b { }') is 'a + b { }'
+PASS parseThenSerializeRule('a ~ b { }') is 'a ~ b { }'
+PASS parseThenSerializeRule('a > b { }') is 'a > b { }'
+
+PASS parseThenSerializeRule(':active { }') is ':active { }'
+PASS parseThenSerializeRule(':checked { }') is ':checked { }'
+PASS parseThenSerializeRule(':disabled { }') is ':disabled { }'
+PASS parseThenSerializeRule(':empty { }') is ':empty { }'
+PASS parseThenSerializeRule(':enabled { }') is ':enabled { }'
+PASS parseThenSerializeRule(':first-child { }') is ':first-child { }'
+PASS parseThenSerializeRule(':first-of-type { }') is ':first-of-type { }'
+PASS parseThenSerializeRule(':focus { }') is ':focus { }'
+PASS parseThenSerializeRule(':hover { }') is ':hover { }'
+PASS parseThenSerializeRule(':indeterminate { }') is ':indeterminate { }'
+PASS parseThenSerializeRule(':link { }') is ':link { }'
+PASS parseThenSerializeRule(':root { }') is ':root { }'
+PASS parseThenSerializeRule(':target { }') is ':target { }'
+PASS parseThenSerializeRule(':visited { }') is ':visited { }'
+
+PASS parseThenSerializeRule(':lang(a) { }') is ':lang(a) { }'
+PASS parseThenSerializeRule(':not(a) { }') is ':not(a) { }'
+
+PASS parseThenSerializeRule('::after { }') is '::after { }'
+PASS parseThenSerializeRule('::before { }') is '::before { }'
+PASS parseThenSerializeRule('::first-letter { }') is '::first-letter { }'
+PASS parseThenSerializeRule('::first-line { }') is '::first-line { }'
+PASS parseThenSerializeRule('::selection { }') is '::selection { }'
+
+PASS parseThenSerializeRule(':-webkit-any-link { }') is ':-webkit-any-link { }'
+PASS parseThenSerializeRule(':-webkit-autofill { }') is ':-webkit-autofill { }'
+PASS parseThenSerializeRule(':-webkit-drag { }') is ':-webkit-drag { }'
+
+PASS parseThenSerializeRule('::-webkit-file-upload-button { }') is '::-webkit-file-upload-button { }'
+PASS parseThenSerializeRule('::-webkit-search-cancel-button { }') is '::-webkit-search-cancel-button { }'
+PASS parseThenSerializeRule('::-webkit-search-decoration { }') is '::-webkit-search-decoration { }'
+PASS parseThenSerializeRule('::-webkit-search-results-button { }') is '::-webkit-search-results-button { }'
+PASS parseThenSerializeRule('::-webkit-search-results-decoration { }') is '::-webkit-search-results-decoration { }'
+PASS parseThenSerializeRule('::-webkit-slider-thumb { }') is '::-webkit-slider-thumb { }'
+
+PASS parseThenSerializeRule('input:not([type="file"]):focus { }') is 'input:not([type="file"]):focus { }'
+
+PASS parseThenSerializeRule('*:active { }') is ':active { }'
+PASS parseThenSerializeRule('|a { }') is 'a { }'
+
+PASS parseThenSerializeRule('input[type=file]:focus { }') is 'input[type="file"]:focus { }'
+
+PASS parseThenSerializeRule('a+b { }') is 'a + b { }'
+PASS parseThenSerializeRule('a~b { }') is 'a ~ b { }'
+PASS parseThenSerializeRule('a>b { }') is 'a > b { }'
+
+PASS parseThenSerializeRule(':after { }') is '::after { }'
+PASS parseThenSerializeRule(':before { }') is '::before { }'
+PASS parseThenSerializeRule(':first-letter { }') is '::first-letter { }'
+PASS parseThenSerializeRule(':first-line { }') is '::first-line { }'
+
+PASS successfullyParsed is true
+
+TEST COMPLETE
+
--- /dev/null
+<html>
+<head>
+<link rel="stylesheet" href="../js/resources/js-test-style.css">
+<script src="../js/resources/js-test-pre.js"></script>
+</head>
+<body>
+<p id="description"></p>
+<div id="console"></div>
+<script>
+
+description("This tests parsing and re-serialization of some CSS selectors.");
+
+function parseThenSerializeRule(rule)
+{
+ var styleElement = document.createElement("style");
+ styleElement.appendChild(document.createTextNode(rule));
+ return styleElement.sheet.cssRules[0].cssText;
+}
+
+function testSelectorRoundTrip(selector)
+{
+ shouldBe("parseThenSerializeRule('" + selector + " { }')", "'" + selector + " { }'");
+}
+
+testSelectorRoundTrip('*');
+testSelectorRoundTrip('a');
+testSelectorRoundTrip('#a');
+testSelectorRoundTrip('.a');
+testSelectorRoundTrip(':active');
+testSelectorRoundTrip('[a]');
+testSelectorRoundTrip('[a="b"]');
+testSelectorRoundTrip('[a~="b"]');
+testSelectorRoundTrip('[a|="b"]');
+testSelectorRoundTrip('[a^="b"]');
+testSelectorRoundTrip('[a$="b"]');
+testSelectorRoundTrip('[a*="b"]');
+
+debug('');
+
+testSelectorRoundTrip('*|a');
+testSelectorRoundTrip('n|a');
+testSelectorRoundTrip('*|*');
+testSelectorRoundTrip('n|*');
+testSelectorRoundTrip('[*|a]');
+testSelectorRoundTrip('[n|a]');
+
+debug('');
+
+testSelectorRoundTrip('a:active');
+testSelectorRoundTrip('a b');
+testSelectorRoundTrip('a + b');
+testSelectorRoundTrip('a ~ b');
+testSelectorRoundTrip('a > b');
+
+debug('');
+
+testSelectorRoundTrip(":active");
+testSelectorRoundTrip(":checked");
+testSelectorRoundTrip(":disabled");
+testSelectorRoundTrip(":empty");
+testSelectorRoundTrip(":enabled");
+testSelectorRoundTrip(":first-child");
+testSelectorRoundTrip(":first-of-type");
+testSelectorRoundTrip(":focus");
+testSelectorRoundTrip(":hover");
+testSelectorRoundTrip(":indeterminate");
+testSelectorRoundTrip(":link");
+testSelectorRoundTrip(":root");
+testSelectorRoundTrip(":target");
+testSelectorRoundTrip(":visited");
+
+debug('');
+
+testSelectorRoundTrip(":lang(a)");
+testSelectorRoundTrip(":not(a)");
+
+debug('');
+
+testSelectorRoundTrip("::after");
+testSelectorRoundTrip("::before");
+testSelectorRoundTrip("::first-letter");
+testSelectorRoundTrip("::first-line");
+testSelectorRoundTrip("::selection");
+
+debug('');
+
+testSelectorRoundTrip(":-webkit-any-link");
+testSelectorRoundTrip(":-webkit-autofill");
+testSelectorRoundTrip(":-webkit-drag");
+
+debug('');
+
+testSelectorRoundTrip("::-webkit-file-upload-button");
+testSelectorRoundTrip("::-webkit-search-cancel-button");
+testSelectorRoundTrip("::-webkit-search-decoration");
+testSelectorRoundTrip("::-webkit-search-results-button");
+testSelectorRoundTrip("::-webkit-search-results-decoration");
+testSelectorRoundTrip("::-webkit-slider-thumb");
+
+debug('');
+
+testSelectorRoundTrip('input:not([type="file"]):focus');
+
+debug('');
+
+shouldBe("parseThenSerializeRule('*:active { }')", "':active { }'");
+shouldBe("parseThenSerializeRule('|a { }')", "'a { }'");
+
+debug('');
+
+shouldBe("parseThenSerializeRule('input[type=file]:focus { }')", "'input[type=\"file\"]:focus { }'");
+
+debug('');
+
+shouldBe("parseThenSerializeRule('a+b { }')", "'a + b { }'");
+shouldBe("parseThenSerializeRule('a~b { }')", "'a ~ b { }'");
+shouldBe("parseThenSerializeRule('a>b { }')", "'a > b { }'");
+
+debug('');
+
+shouldBe("parseThenSerializeRule(':after { }')", "'::after { }'");
+shouldBe("parseThenSerializeRule(':before { }')", "'::before { }'");
+shouldBe("parseThenSerializeRule(':first-letter { }')", "'::first-letter { }'");
+shouldBe("parseThenSerializeRule(':first-line { }')", "'::first-line { }'");
+
+debug('');
+
+successfullyParsed = true;
+
+</script>
+<script src="../js/resources/js-test-post.js"></script>
+</body>
+</html>
+2007-03-24 Darin Adler <darin@apple.com>
+
+ Reviewed by Mitz.
+
+ - fix http://bugs.webkit.org/show_bug.cgi?id=13123
+ CSS selectors that use :lang, :not, and namespaces do not serialize correctly
+
+ Test: fast/css/css-selector-text.html
+
+ * css/CSSSelector.cpp: (WebCore::CSSSelector::selectorText): Add the namespace
+ prefix for tag or attribute names, the sub-selector for :not, and the argument
+ for :lang.
+
2007-03-24 Brady Eidson <beidson@apple.com>
Reviewed by Adam
/*
- * This file is part of the DOM implementation for KDE.
- *
* Copyright (C) 1999-2003 Lars Knoll (knoll@kde.org)
* 1999 Waldo Bastian (bastian@kde.org)
* 2001 Andreas Schlapbach (schlpbch@iam.unibe.ch)
* 2001-2003 Dirk Mueller (mueller@kde.org)
- * Copyright (C) 2002, 2006 Apple Computer, Inc.
+ * Copyright (C) 2002, 2006, 2007 Apple Inc. All rights reserved.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
String CSSSelector::selectorText() const
{
- // FIXME: Support namespaces when dumping the selector text. -dwh
- String str;
- const CSSSelector* cs = this;
- const AtomicString& localName = cs->m_tag.localName();
+ String str = "";
- if (cs->m_match == CSSSelector::None || localName != starAtom)
- str = localName;
+ const AtomicString& prefix = m_tag.prefix();
+ const AtomicString& localName = m_tag.localName();
+ if (m_match == CSSSelector::None || !prefix.isNull() || localName != starAtom) {
+ if (prefix.isNull())
+ str = localName;
+ else
+ str = prefix + "|" + localName;
+ }
+ const CSSSelector* cs = this;
while (true) {
if (cs->m_match == CSSSelector::Id) {
str += "#";
} else if (cs->m_match == CSSSelector::PseudoClass) {
str += ":";
str += cs->m_value;
+ if (cs->pseudoType() == PseudoNot) {
+ if (CSSSelector* subSel = cs->m_simpleSelector)
+ str += subSel->selectorText();
+ str += ")";
+ } else if (cs->pseudoType() == PseudoLang) {
+ str += cs->m_argument;
+ str += ")";
+ }
} else if (cs->m_match == CSSSelector::PseudoElement) {
str += "::";
str += cs->m_value;
} else if (cs->hasAttribute()) {
- // FIXME: Add support for dumping namespaces.
- String attrName = cs->m_attr.localName();
str += "[";
- str += attrName;
+ const AtomicString& prefix = cs->m_attr.prefix();
+ if (!prefix.isNull())
+ str += prefix + "|";
+ str += cs->m_attr.localName();
switch (cs->m_match) {
case CSSSelector::Exact:
str += "=";