18e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project/*
28e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * (C) 1999-2003 Lars Knoll (knoll@kde.org)
38e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * Copyright (C) 2004, 2006, 2007 Apple Inc. All rights reserved.
48e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project *
58e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * This library is free software; you can redistribute it and/or
68e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * modify it under the terms of the GNU Library General Public
78e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * License as published by the Free Software Foundation; either
88e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * version 2 of the License, or (at your option) any later version.
98e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project *
108e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * This library is distributed in the hope that it will be useful,
118e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * but WITHOUT ANY WARRANTY; without even the implied warranty of
128e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
138e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * Library General Public License for more details.
148e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project *
158e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * You should have received a copy of the GNU Library General Public License
168e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * along with this library; see the file COPYING.LIB.  If not, write to
178e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
188e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * Boston, MA 02110-1301, USA.
198e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project */
208e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
218e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "config.h"
228e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "CSSStyleSheet.h"
238e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
248e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "CSSImportRule.h"
258e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "CSSNamespace.h"
268e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "CSSParser.h"
278e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "CSSRuleList.h"
288e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "Document.h"
298e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "ExceptionCode.h"
304576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang#include "HTMLNames.h"
318e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "Node.h"
324576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang#include "SVGNames.h"
33643ca7872b450ea4efacab6188849e5aac2ba161Steve Block#include "SecurityOrigin.h"
34635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project#include "TextEncoding.h"
35635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project#include <wtf/Deque.h>
368e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
378e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectnamespace WebCore {
388e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
394576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang#if !ASSERT_DISABLED
404576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wangstatic bool isAcceptableCSSStyleSheetParent(Node* parentNode)
414576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang{
424576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang    // Only these nodes can be parents of StyleSheets, and they need to call clearOwnerNode() when moved out of document.
434576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang    return !parentNode
444576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang        || parentNode->isDocumentNode()
454576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang        || parentNode->hasTagName(HTMLNames::linkTag)
464576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang        || parentNode->hasTagName(HTMLNames::styleTag)
474576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang#if ENABLE(SVG)
484576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang        || parentNode->hasTagName(SVGNames::styleTag)
494576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang#endif
504576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang        || parentNode->nodeType() == Node::PROCESSING_INSTRUCTION_NODE;
514576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang}
524576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang#endif
534576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang
54d0825bca7fe65beaee391d30da42e937db621564Steve BlockCSSStyleSheet::CSSStyleSheet(CSSStyleSheet* parentSheet, const String& href, const KURL& baseURL, const String& charset)
55d0825bca7fe65beaee391d30da42e937db621564Steve Block    : StyleSheet(parentSheet, href, baseURL)
568e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    , m_charset(charset)
578e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    , m_loadCompleted(false)
58635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project    , m_strictParsing(!parentSheet || parentSheet->useStrictParsing())
59231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block    , m_isUserStyleSheet(parentSheet ? parentSheet->isUserStyleSheet() : false)
60d0825bca7fe65beaee391d30da42e937db621564Steve Block    , m_hasSyntacticallyValidCSSHeader(true)
618e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
628e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
638e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
64d0825bca7fe65beaee391d30da42e937db621564Steve BlockCSSStyleSheet::CSSStyleSheet(Node* parentNode, const String& href, const KURL& baseURL, const String& charset)
65d0825bca7fe65beaee391d30da42e937db621564Steve Block    : StyleSheet(parentNode, href, baseURL)
668e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    , m_charset(charset)
678e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    , m_loadCompleted(false)
68635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project    , m_strictParsing(false)
69231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block    , m_isUserStyleSheet(false)
70d0825bca7fe65beaee391d30da42e937db621564Steve Block    , m_hasSyntacticallyValidCSSHeader(true)
718e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
724576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang    ASSERT(isAcceptableCSSStyleSheetParent(parentNode));
738e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
748e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
75d0825bca7fe65beaee391d30da42e937db621564Steve BlockCSSStyleSheet::CSSStyleSheet(CSSRule* ownerRule, const String& href, const KURL& baseURL, const String& charset)
76d0825bca7fe65beaee391d30da42e937db621564Steve Block    : StyleSheet(ownerRule, href, baseURL)
778e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    , m_charset(charset)
788e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    , m_loadCompleted(false)
79635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project    , m_strictParsing(!ownerRule || ownerRule->useStrictParsing())
80d0825bca7fe65beaee391d30da42e937db621564Steve Block    , m_hasSyntacticallyValidCSSHeader(true)
818e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
828e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    CSSStyleSheet* parentSheet = ownerRule ? ownerRule->parentStyleSheet() : 0;
83231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block    m_isUserStyleSheet = parentSheet ? parentSheet->isUserStyleSheet() : false;
848e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
858e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
868e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source ProjectCSSStyleSheet::~CSSStyleSheet()
878e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
888e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
898e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
908e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source ProjectCSSRule *CSSStyleSheet::ownerRule() const
918e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
928e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    return (parent() && parent()->isRule()) ? static_cast<CSSRule*>(parent()) : 0;
938e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
948e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
958e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectunsigned CSSStyleSheet::insertRule(const String& rule, unsigned index, ExceptionCode& ec)
968e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
978e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    ec = 0;
988e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (index > length()) {
998e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        ec = INDEX_SIZE_ERR;
1008e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return 0;
1018e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
1028e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    CSSParser p(useStrictParsing());
1038e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    RefPtr<CSSRule> r = p.parseRule(this, rule);
1048e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1058e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (!r) {
1068e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        ec = SYNTAX_ERR;
1078e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return 0;
1088e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
1098e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
110dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    // Throw a HIERARCHY_REQUEST_ERR exception if the rule cannot be inserted at the specified index.  The best
111dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    // example of this is an @import rule inserted after regular rules.
112dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    if (index > 0) {
113dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        if (r->isImportRule()) {
114dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block            // Check all the rules that come before this one to make sure they are only @charset and @import rules.
115dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block            for (unsigned i = 0; i < index; ++i) {
116dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block                if (!item(i)->isCharsetRule() && !item(i)->isImportRule()) {
117dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block                    ec = HIERARCHY_REQUEST_ERR;
118dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block                    return 0;
119dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block                }
120dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block            }
121dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        } else if (r->isCharsetRule()) {
122dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block            // The @charset rule has to come first and there can be only one.
123dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block            ec = HIERARCHY_REQUEST_ERR;
124dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block            return 0;
125dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        }
126dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    }
127dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block
1288e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    insert(index, r.release());
1298e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1308e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    styleSheetChanged();
1318e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1328e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    return index;
1338e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
1348e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1358e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectint CSSStyleSheet::addRule(const String& selector, const String& style, int index, ExceptionCode& ec)
1368e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
1378e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    insertRule(selector + " { " + style + " }", index, ec);
1388e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1398e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // As per Microsoft documentation, always return -1.
1408e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    return -1;
1418e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
1428e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1438e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectint CSSStyleSheet::addRule(const String& selector, const String& style, ExceptionCode& ec)
1448e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
1458e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    return addRule(selector, style, length(), ec);
1468e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
1478e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1488e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source ProjectPassRefPtr<CSSRuleList> CSSStyleSheet::cssRules(bool omitCharsetRules)
1498e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
15006ea8e899e48f1f2f396b70e63fae369f2f23232Kristian Monsen    KURL url = finalURL();
1515ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen    if (!url.isEmpty() && document() && !document()->securityOrigin()->canRequest(url))
152e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block        return 0;
1538e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    return CSSRuleList::create(this, omitCharsetRules);
1548e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
1558e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1568e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectvoid CSSStyleSheet::deleteRule(unsigned index, ExceptionCode& ec)
1578e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
1588e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (index >= length()) {
1598e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        ec = INDEX_SIZE_ERR;
1608e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return;
1618e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
1628e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1638e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    ec = 0;
164cad810f21b803229eb11403f9209855525a25d57Steve Block    item(index)->setParent(0);
1658e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    remove(index);
1668e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    styleSheetChanged();
1678e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
1688e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1698e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectvoid CSSStyleSheet::addNamespace(CSSParser* p, const AtomicString& prefix, const AtomicString& uri)
1708e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
171643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    if (uri.isNull())
1728e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return;
1738e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1745ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen    m_namespaces = adoptPtr(new CSSNamespace(prefix, uri, m_namespaces.release()));
1758e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1768e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (prefix.isEmpty())
1778e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        // Set the default namespace on the parser so that selectors that omit namespace info will
1788e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        // be able to pick it up easily.
1798e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        p->m_defaultNamespace = uri;
1808e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
1818e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1828e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectconst AtomicString& CSSStyleSheet::determineNamespace(const AtomicString& prefix)
1838e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
184643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    if (prefix.isNull())
1858e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return nullAtom; // No namespace. If an element/attribute has a namespace, we won't match it.
186643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    if (prefix == starAtom)
1878e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return starAtom; // We'll match any namespace.
188643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    if (m_namespaces) {
1895ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen        if (CSSNamespace* namespaceForPrefix = m_namespaces->namespaceForPrefix(prefix))
1905ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen            return namespaceForPrefix->uri;
1918e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
1925ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen    return nullAtom; // Assume we won't match any namespaces.
1938e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
1948e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1958e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectbool CSSStyleSheet::parseString(const String &string, bool strict)
1968e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
197e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke    return parseStringAtLine(string, strict, 0);
198e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke}
199e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke
200e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarkebool CSSStyleSheet::parseStringAtLine(const String& string, bool strict, int startLineNumber)
201e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke{
2028e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    setStrictParsing(strict);
2038e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    CSSParser p(strict);
204e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke    p.parseSheet(this, string, startLineNumber);
2058e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    return true;
2068e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
2078e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
2088e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectbool CSSStyleSheet::isLoading()
2098e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
2108e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    unsigned len = length();
2118e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    for (unsigned i = 0; i < len; ++i) {
2128e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        StyleBase* rule = item(i);
2138e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        if (rule->isImportRule() && static_cast<CSSImportRule*>(rule)->isLoading())
2148e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            return true;
2158e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
2168e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    return false;
2178e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
2188e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
2198e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectvoid CSSStyleSheet::checkLoaded()
2208e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
2218e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (isLoading())
2228e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return;
2238e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (parent())
2248e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        parent()->checkLoaded();
2258f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian
226ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block    // Avoid |this| being deleted by scripts that run via
227ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block    // ScriptableDocumentParser::executeScriptsWaitingForStylesheets().
2288f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    // See <rdar://problem/6622300>.
2298f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    RefPtr<CSSStyleSheet> protector(this);
2308e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    m_loadCompleted = ownerNode() ? ownerNode()->sheetLoaded() : true;
2318e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
2328e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
2332fc2651226baac27029e38c9d6ef883fa32084dbSteve BlockDocument* CSSStyleSheet::document()
2342fc2651226baac27029e38c9d6ef883fa32084dbSteve Block{
2352fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    StyleBase* styleObject = this;
2362fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    while (styleObject) {
2372fc2651226baac27029e38c9d6ef883fa32084dbSteve Block        if (styleObject->isCSSStyleSheet()) {
2382fc2651226baac27029e38c9d6ef883fa32084dbSteve Block            Node* ownerNode = static_cast<CSSStyleSheet*>(styleObject)->ownerNode();
2392fc2651226baac27029e38c9d6ef883fa32084dbSteve Block            if (ownerNode)
2402fc2651226baac27029e38c9d6ef883fa32084dbSteve Block                return ownerNode->document();
2412fc2651226baac27029e38c9d6ef883fa32084dbSteve Block        }
2422fc2651226baac27029e38c9d6ef883fa32084dbSteve Block        if (styleObject->isRule())
2432fc2651226baac27029e38c9d6ef883fa32084dbSteve Block            styleObject = static_cast<CSSRule*>(styleObject)->parentStyleSheet();
2442fc2651226baac27029e38c9d6ef883fa32084dbSteve Block        else
2452fc2651226baac27029e38c9d6ef883fa32084dbSteve Block            styleObject = styleObject->parent();
2462fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    }
2472fc2651226baac27029e38c9d6ef883fa32084dbSteve Block
2482fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    return 0;
2492fc2651226baac27029e38c9d6ef883fa32084dbSteve Block}
2502fc2651226baac27029e38c9d6ef883fa32084dbSteve Block
2518e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectvoid CSSStyleSheet::styleSheetChanged()
2528e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
2538e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    StyleBase* root = this;
2548e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    while (StyleBase* parent = root->parent())
2558e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        root = parent;
2565ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen    Document* documentToUpdate = root->isCSSStyleSheet() ? static_cast<CSSStyleSheet*>(root)->document() : 0;
2578e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
2588e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    /* FIXME: We don't need to do everything updateStyleSelector does,
2598e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project     * basically we just need to recreate the document's selector with the
2608e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project     * already existing style sheets.
2618e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project     */
2628e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (documentToUpdate)
2635ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen        documentToUpdate->styleSelectorChanged(DeferRecalcStyle);
2648e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
2658e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
266635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source ProjectKURL CSSStyleSheet::completeURL(const String& url) const
267635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project{
268635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project    // Always return a null URL when passed a null string.
269635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project    // FIXME: Should we change the KURL constructor to have this behavior?
270635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project    // See also Document::completeURL(const String&)
271635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project    if (url.isNull() || m_charset.isEmpty())
272635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project        return StyleSheet::completeURL(url);
273635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project    const TextEncoding encoding = TextEncoding(m_charset);
274635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project    return KURL(baseURL(), url, encoding);
275635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project}
276635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project
277635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Projectvoid CSSStyleSheet::addSubresourceStyleURLs(ListHashSet<KURL>& urls)
278635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project{
279635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project    Deque<CSSStyleSheet*> styleSheetQueue;
280635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project    styleSheetQueue.append(this);
281635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project
282635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project    while (!styleSheetQueue.isEmpty()) {
283545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch        CSSStyleSheet* styleSheet = styleSheetQueue.takeFirst();
284635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project
285643ca7872b450ea4efacab6188849e5aac2ba161Steve Block        for (unsigned i = 0; i < styleSheet->length(); ++i) {
286643ca7872b450ea4efacab6188849e5aac2ba161Steve Block            StyleBase* styleBase = styleSheet->item(i);
287643ca7872b450ea4efacab6188849e5aac2ba161Steve Block            if (!styleBase->isRule())
288643ca7872b450ea4efacab6188849e5aac2ba161Steve Block                continue;
289643ca7872b450ea4efacab6188849e5aac2ba161Steve Block
290643ca7872b450ea4efacab6188849e5aac2ba161Steve Block            CSSRule* rule = static_cast<CSSRule*>(styleBase);
291635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project            if (rule->isImportRule()) {
292635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project                if (CSSStyleSheet* ruleStyleSheet = static_cast<CSSImportRule*>(rule)->styleSheet())
293635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project                    styleSheetQueue.append(ruleStyleSheet);
294635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project            }
295635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project            rule->addSubresourceStyleURLs(urls);
296635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project        }
2978e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
2988e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
2998e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
3008e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
301