18e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project/*
28e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * Copyright (C) 1999 Lars Knoll (knoll@kde.org)
38e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project *           (C) 1999 Antti Koivisto (koivisto@kde.org)
48e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project *           (C) 2001 Dirk Mueller (mueller@kde.org)
506ea8e899e48f1f2f396b70e63fae369f2f23232Kristian Monsen * Copyright (C) 2003, 2006, 2007, 2008, 2009, 2010 Apple Inc. All rights reserved.
65f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian * Copyright (C) 2009 Rob Buis (rwlbuis@gmail.com)
78e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project *
88e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * This library is free software; you can redistribute it and/or
98e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * modify it under the terms of the GNU Library General Public
108e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * License as published by the Free Software Foundation; either
118e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * version 2 of the License, or (at your option) any later version.
128e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project *
138e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * This library is distributed in the hope that it will be useful,
148e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * but WITHOUT ANY WARRANTY; without even the implied warranty of
158e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
168e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * Library General Public License for more details.
178e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project *
188e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * You should have received a copy of the GNU Library General Public License
198e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * along with this library; see the file COPYING.LIB.  If not, write to
208e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
218e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * Boston, MA 02110-1301, USA.
228e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project */
238e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
248e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "config.h"
258e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "HTMLLinkElement.h"
268e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
27e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block#include "Attribute.h"
288e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "CachedCSSStyleSheet.h"
292daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch#include "CachedResource.h"
305abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick#include "CachedResourceLoader.h"
31f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch#include "CSSStyleSelector.h"
328e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "Document.h"
338e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "Frame.h"
348e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "FrameLoader.h"
358e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "FrameLoaderClient.h"
368e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "FrameTree.h"
37f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch#include "FrameView.h"
388e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "HTMLNames.h"
39a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch#include "HTMLParserIdioms.h"
408e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "MediaList.h"
418e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "MediaQueryEvaluator.h"
428e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "Page.h"
43dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block#include "ResourceHandle.h"
44231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block#include "ScriptEventListener.h"
458e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "Settings.h"
46d0825bca7fe65beaee391d30da42e937db621564Steve Block#include <wtf/StdLibExtras.h>
478e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
488e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectnamespace WebCore {
498e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
508e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectusing namespace HTMLNames;
518e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
525af96e2c7b73ebc627c6894727826a7576d31758Leon Clarkeinline HTMLLinkElement::HTMLLinkElement(const QualifiedName& tagName, Document* document, bool createdByParser)
535af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke    : HTMLElement(tagName, document)
54f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch#if ENABLE(LINK_PREFETCH)
55f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch    , m_onloadTimer(this, &HTMLLinkElement::onloadTimerFired)
56f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch#endif
576c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen    , m_disabledState(Unset)
588e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    , m_loading(false)
59635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project    , m_createdByParser(createdByParser)
602fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    , m_isInShadowTree(false)
61f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch    , m_pendingSheetType(None)
628e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
63635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project    ASSERT(hasTagName(linkTag));
648e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
658e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
665af96e2c7b73ebc627c6894727826a7576d31758Leon ClarkePassRefPtr<HTMLLinkElement> HTMLLinkElement::create(const QualifiedName& tagName, Document* document, bool createdByParser)
675af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke{
6806ea8e899e48f1f2f396b70e63fae369f2f23232Kristian Monsen    return adoptRef(new HTMLLinkElement(tagName, document, createdByParser));
695af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke}
705af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke
718e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source ProjectHTMLLinkElement::~HTMLLinkElement()
728e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
736b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner    if (m_sheet)
746b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner        m_sheet->clearOwnerNode();
756b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner
768e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (m_cachedSheet) {
77f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch        m_cachedSheet->removeClient(this);
78f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch        removePendingSheet();
798e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
80f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch
81f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch#if ENABLE(LINK_PREFETCH)
822daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch    if (m_cachedLinkResource)
832daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch        m_cachedLinkResource->removeClient(this);
84f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch#endif
858e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
868e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
878e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectvoid HTMLLinkElement::setDisabledState(bool _disabled)
888e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
896c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen    DisabledState oldDisabledState = m_disabledState;
906c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen    m_disabledState = _disabled ? Disabled : EnabledViaScript;
918e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (oldDisabledState != m_disabledState) {
928e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        // If we change the disabled state while the sheet is still loading, then we have to
938e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        // perform three checks:
948e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        if (isLoading()) {
95f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch            // Check #1: The sheet becomes disabled while loading.
96f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch            if (m_disabledState == Disabled)
97f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch                removePendingSheet();
986c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen
996c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen            // Check #2: An alternate sheet becomes enabled while it is still loading.
1006c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen            if (m_relAttribute.m_isAlternate && m_disabledState == EnabledViaScript)
101f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch                addPendingSheet(Blocking);
1028e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1038e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            // Check #3: A main sheet becomes enabled while it was still loading and
1048e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            // after it was disabled via script.  It takes really terrible code to make this
1058e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            // happen (a double toggle for no reason essentially).  This happens on
1068e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            // virtualplastic.net, which manages to do about 12 enable/disables on only 3
1078e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            // sheets. :)
1086c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen            if (!m_relAttribute.m_isAlternate && m_disabledState == EnabledViaScript && oldDisabledState == Disabled)
109f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch                addPendingSheet(Blocking);
1108e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1118e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            // If the sheet is already loading just bail.
1128e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            return;
1138e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        }
1148e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1158e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        // Load the sheet, since it's never been loaded before.
1166c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen        if (!m_sheet && m_disabledState == EnabledViaScript)
1178e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            process();
1188e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        else
1195ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen            document()->styleSelectorChanged(DeferRecalcStyle); // Update the style selector.
1208e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
1218e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
1228e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1238e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source ProjectStyleSheet* HTMLLinkElement::sheet() const
1248e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
1258e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    return m_sheet.get();
1268e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
1278e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
128e78cbe89e6f337f2f1fe40315be88f742b547151Steve Blockvoid HTMLLinkElement::parseMappedAttribute(Attribute* attr)
1298e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
1308e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (attr->name() == relAttr) {
1316c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen        tokenizeRelAttribute(attr->value(), m_relAttribute);
1328e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        process();
1338e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    } else if (attr->name() == hrefAttr) {
134a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        m_url = document()->completeURL(stripLeadingAndTrailingHTMLSpaces(attr->value()));
1358e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        process();
1368e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    } else if (attr->name() == typeAttr) {
1378e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        m_type = attr->value();
1388e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        process();
1398e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    } else if (attr->name() == mediaAttr) {
1408e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        m_media = attr->value().string().lower();
1418e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        process();
1426c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen    } else if (attr->name() == disabledAttr)
1438e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        setDisabledState(!attr->isNull());
1446c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen    else if (attr->name() == onbeforeloadAttr)
145231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block        setAttributeEventListener(eventNames().beforeloadEvent, createAttributeEventListener(this, attr));
146f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch#if ENABLE(LINK_PREFETCH)
147f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch    else if (attr->name() == onloadAttr)
148f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch        setAttributeEventListener(eventNames().loadEvent, createAttributeEventListener(this, attr));
1492bde8e466a4451c7319e3a072d118917957d6554Steve Block    else if (attr->name() == onerrorAttr)
1502bde8e466a4451c7319e3a072d118917957d6554Steve Block        setAttributeEventListener(eventNames().errorEvent, createAttributeEventListener(this, attr));
151f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch#endif
15292f04dcc93ce5d84e28b0ac2b113dad5cc99a0d9Kristian Monsen    else {
1538e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        if (attr->name() == titleAttr && m_sheet)
1548e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            m_sheet->setTitle(attr->value());
1558e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        HTMLElement::parseMappedAttribute(attr);
1568e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
1578e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
1588e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
15992f04dcc93ce5d84e28b0ac2b113dad5cc99a0d9Kristian Monsenvoid HTMLLinkElement::tokenizeRelAttribute(const AtomicString& rel, RelAttribute& relAttribute)
1608e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
16192f04dcc93ce5d84e28b0ac2b113dad5cc99a0d9Kristian Monsen    relAttribute.m_isStyleSheet = false;
16292f04dcc93ce5d84e28b0ac2b113dad5cc99a0d9Kristian Monsen    relAttribute.m_isIcon = false;
16392f04dcc93ce5d84e28b0ac2b113dad5cc99a0d9Kristian Monsen    relAttribute.m_isAlternate = false;
16492f04dcc93ce5d84e28b0ac2b113dad5cc99a0d9Kristian Monsen    relAttribute.m_isDNSPrefetch = false;
1655d6f8ef31d11ee66598999b1b749ba9ff767e4d5Leon Clarke#if ENABLE(LINK_PREFETCH)
16692f04dcc93ce5d84e28b0ac2b113dad5cc99a0d9Kristian Monsen    relAttribute.m_isLinkPrefetch = false;
1672daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch    relAttribute.m_isLinkSubresource = false;
168f91ac8eab3399adb5325701bebe0590a77e49df7Leon Clarke#endif
169c6fbc06882c120f5f51090203775eb0421550d13Patrick Scott#ifdef ANDROID_APPLE_TOUCH_ICON
17092f04dcc93ce5d84e28b0ac2b113dad5cc99a0d9Kristian Monsen    relAttribute.m_isTouchIcon = false;
17192f04dcc93ce5d84e28b0ac2b113dad5cc99a0d9Kristian Monsen    relAttribute.m_isPrecomposedTouchIcon = false;
172c6fbc06882c120f5f51090203775eb0421550d13Patrick Scott#endif
1738e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (equalIgnoringCase(rel, "stylesheet"))
17492f04dcc93ce5d84e28b0ac2b113dad5cc99a0d9Kristian Monsen        relAttribute.m_isStyleSheet = true;
1758e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    else if (equalIgnoringCase(rel, "icon") || equalIgnoringCase(rel, "shortcut icon"))
17692f04dcc93ce5d84e28b0ac2b113dad5cc99a0d9Kristian Monsen        relAttribute.m_isIcon = true;
177f1c0bbb9bf698154c206e842f94b72d277a96094Patrick Scott#ifdef ANDROID_APPLE_TOUCH_ICON
178f1c0bbb9bf698154c206e842f94b72d277a96094Patrick Scott    else if (equalIgnoringCase(rel, "apple-touch-icon"))
17992f04dcc93ce5d84e28b0ac2b113dad5cc99a0d9Kristian Monsen        relAttribute.m_isTouchIcon = true;
180c6fbc06882c120f5f51090203775eb0421550d13Patrick Scott    else if (equalIgnoringCase(rel, "apple-touch-icon-precomposed"))
18192f04dcc93ce5d84e28b0ac2b113dad5cc99a0d9Kristian Monsen        relAttribute.m_isPrecomposedTouchIcon = true;
182f1c0bbb9bf698154c206e842f94b72d277a96094Patrick Scott#endif
1838e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    else if (equalIgnoringCase(rel, "dns-prefetch"))
18492f04dcc93ce5d84e28b0ac2b113dad5cc99a0d9Kristian Monsen        relAttribute.m_isDNSPrefetch = true;
1858e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    else if (equalIgnoringCase(rel, "alternate stylesheet") || equalIgnoringCase(rel, "stylesheet alternate")) {
1866c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen        relAttribute.m_isStyleSheet = true;
1876c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen        relAttribute.m_isAlternate = true;
1888e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    } else {
1898e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        // Tokenize the rel attribute and set bits based on specific keywords that we find.
1908e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        String relString = rel.string();
1918e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        relString.replace('\n', ' ');
1928e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        Vector<String> list;
1938e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        relString.split(' ', list);
1948e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        Vector<String>::const_iterator end = list.end();
1958e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        for (Vector<String>::const_iterator it = list.begin(); it != end; ++it) {
1968e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            if (equalIgnoringCase(*it, "stylesheet"))
1976c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen                relAttribute.m_isStyleSheet = true;
1986c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen            else if (equalIgnoringCase(*it, "alternate"))
1996c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen                relAttribute.m_isAlternate = true;
2006c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen            else if (equalIgnoringCase(*it, "icon"))
2016c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen                relAttribute.m_isIcon = true;
2022daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch#if ENABLE(LINK_PREFETCH)
2032daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch            else if (equalIgnoringCase(*it, "prefetch"))
2042daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch              relAttribute.m_isLinkPrefetch = true;
2052daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch            else if (equalIgnoringCase(*it, "subresource"))
2062daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch              relAttribute.m_isLinkSubresource = true;
2072daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch#endif
2088e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        }
2098e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
2108e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
2118e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
2122bde8e466a4451c7319e3a072d118917957d6554Steve Blockbool HTMLLinkElement::checkBeforeLoadEvent()
2132bde8e466a4451c7319e3a072d118917957d6554Steve Block{
2142bde8e466a4451c7319e3a072d118917957d6554Steve Block    RefPtr<Document> originalDocument = document();
2152bde8e466a4451c7319e3a072d118917957d6554Steve Block    if (!dispatchBeforeLoadEvent(m_url))
2162bde8e466a4451c7319e3a072d118917957d6554Steve Block        return false;
2172bde8e466a4451c7319e3a072d118917957d6554Steve Block    // A beforeload handler might have removed us from the document or changed the document.
2182bde8e466a4451c7319e3a072d118917957d6554Steve Block    if (!inDocument() || document() != originalDocument)
2192bde8e466a4451c7319e3a072d118917957d6554Steve Block        return false;
2202bde8e466a4451c7319e3a072d118917957d6554Steve Block    return true;
2212bde8e466a4451c7319e3a072d118917957d6554Steve Block}
2222bde8e466a4451c7319e3a072d118917957d6554Steve Block
2238e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectvoid HTMLLinkElement::process()
2248e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
2252fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    if (!inDocument() || m_isInShadowTree) {
2266b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner        ASSERT(!m_sheet);
2278e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return;
2286b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner    }
2298e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
2308e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    String type = m_type.lower();
2318e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
2328e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // IE extension: location of small icon for locationbar / bookmarks
2338e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // We'll record this URL per document, even if we later only use it in top level frames
2342bde8e466a4451c7319e3a072d118917957d6554Steve Block    if (m_relAttribute.m_isIcon && m_url.isValid() && !m_url.isEmpty()) {
2352bde8e466a4451c7319e3a072d118917957d6554Steve Block        if (!checkBeforeLoadEvent())
2362bde8e466a4451c7319e3a072d118917957d6554Steve Block            return;
237635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project        document()->setIconURL(m_url.string(), type);
2382bde8e466a4451c7319e3a072d118917957d6554Steve Block    }
2398e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
240f1c0bbb9bf698154c206e842f94b72d277a96094Patrick Scott#ifdef ANDROID_APPLE_TOUCH_ICON
24192f04dcc93ce5d84e28b0ac2b113dad5cc99a0d9Kristian Monsen    if ((m_relAttribute.m_isTouchIcon || m_relAttribute.m_isPrecomposedTouchIcon) && m_url.isValid()
2421b7019689392c62db7283d1378025c2835765a85Leon Clarke        && !m_url.isEmpty() && document()->frame())
243f1c0bbb9bf698154c206e842f94b72d277a96094Patrick Scott        document()->frame()->loader()->client()
244c6fbc06882c120f5f51090203775eb0421550d13Patrick Scott                ->dispatchDidReceiveTouchIconURL(m_url.string(),
24592f04dcc93ce5d84e28b0ac2b113dad5cc99a0d9Kristian Monsen                        m_relAttribute.m_isPrecomposedTouchIcon);
246f1c0bbb9bf698154c206e842f94b72d277a96094Patrick Scott#endif
247f1c0bbb9bf698154c206e842f94b72d277a96094Patrick Scott
24828040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu    if (m_relAttribute.m_isDNSPrefetch) {
24928040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu        Settings* settings = document()->settings();
25028040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu        // FIXME: The href attribute of the link element can be in "//hostname" form, and we shouldn't attempt
25128040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu        // to complete that as URL <https://bugs.webkit.org/show_bug.cgi?id=48857>.
25228040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu        if (settings && settings->dnsPrefetchingEnabled() && m_url.isValid() && !m_url.isEmpty())
25328040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu            ResourceHandle::prepareForURL(m_url);
25428040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu    }
2558e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
2565d6f8ef31d11ee66598999b1b749ba9ff767e4d5Leon Clarke#if ENABLE(LINK_PREFETCH)
2572daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch    if ((m_relAttribute.m_isLinkPrefetch || m_relAttribute.m_isLinkSubresource) && m_url.isValid() && document()->frame()) {
2582bde8e466a4451c7319e3a072d118917957d6554Steve Block        if (!checkBeforeLoadEvent())
2592bde8e466a4451c7319e3a072d118917957d6554Steve Block            return;
2602daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch        ResourceLoadPriority priority = ResourceLoadPriorityUnresolved;
2612daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch        if (m_relAttribute.m_isLinkSubresource)
2622daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch            priority = ResourceLoadPriorityLow;
2632daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch
2642daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch        m_cachedLinkResource = document()->cachedResourceLoader()->requestLinkResource(m_url, priority);
2652daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch        if (m_cachedLinkResource)
2662daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch            m_cachedLinkResource->addClient(this);
267f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch    }
268f91ac8eab3399adb5325701bebe0590a77e49df7Leon Clarke#endif
269f91ac8eab3399adb5325701bebe0590a77e49df7Leon Clarke
2700bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    bool acceptIfTypeContainsTextCSS = document()->page() && document()->page()->settings() && document()->page()->settings()->treatsAnyTextCSSLinkAsStylesheet();
271f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch
272f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch    if (m_disabledState != Disabled && (m_relAttribute.m_isStyleSheet || (acceptIfTypeContainsTextCSS && type.contains("text/css")))
273f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch        && document()->frame() && m_url.isValid()) {
274231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block
2755f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian        String charset = getAttribute(charsetAttr);
2765f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian        if (charset.isEmpty() && document()->frame())
2772fc2651226baac27029e38c9d6ef883fa32084dbSteve Block            charset = document()->charset();
278f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch
2795f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian        if (m_cachedSheet) {
280f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch            removePendingSheet();
2815f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian            m_cachedSheet->removeClient(this);
282231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block            m_cachedSheet = 0;
2835f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian        }
284231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block
2852bde8e466a4451c7319e3a072d118917957d6554Steve Block        if (!checkBeforeLoadEvent())
286cad810f21b803229eb11403f9209855525a25d57Steve Block            return;
287cad810f21b803229eb11403f9209855525a25d57Steve Block
2885f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian        m_loading = true;
289231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block
290f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch        bool mediaQueryMatches = true;
291f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch        if (!m_media.isEmpty()) {
292f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch            RefPtr<RenderStyle> documentStyle = CSSStyleSelector::styleForDocument(document());
293f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch            RefPtr<MediaList> media = MediaList::createAllowingDescriptionSyntax(m_media);
294f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch            MediaQueryEvaluator evaluator(document()->frame()->view()->mediaType(), document()->frame(), documentStyle.get());
295f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch            mediaQueryMatches = evaluator.eval(media.get());
296f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch        }
297f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch
298f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch        // Don't hold up render tree construction and script execution on stylesheets
299f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch        // that are not needed for the rendering at the moment.
300f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch        bool blocking = mediaQueryMatches && !isAlternate();
301f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch        addPendingSheet(blocking ? Blocking : NonBlocking);
302f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch
303f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch        // Load stylesheets that are not needed for the rendering immediately with low priority.
304f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch        ResourceLoadPriority priority = blocking ? ResourceLoadPriorityUnresolved : ResourceLoadPriorityVeryLow;
305f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch        m_cachedSheet = document()->cachedResourceLoader()->requestCSSStyleSheet(m_url, charset, priority);
306231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block
3075f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian        if (m_cachedSheet)
3085f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian            m_cachedSheet->addClient(this);
309231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block        else {
310231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block            // The request may have been denied if (for example) the stylesheet is local and the document is remote.
3115f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian            m_loading = false;
312f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch            removePendingSheet();
3138e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        }
3148e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    } else if (m_sheet) {
3158e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        // we no longer contain a stylesheet, e.g. perhaps rel or type was changed
3168e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        m_sheet = 0;
3175ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen        document()->styleSelectorChanged(DeferRecalcStyle);
3188e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
3198e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
3208e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
3218e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectvoid HTMLLinkElement::insertedIntoDocument()
3228e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
3238e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    HTMLElement::insertedIntoDocument();
3242fc2651226baac27029e38c9d6ef883fa32084dbSteve Block
3252fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    m_isInShadowTree = isInShadowTree();
3262fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    if (m_isInShadowTree)
3272fc2651226baac27029e38c9d6ef883fa32084dbSteve Block        return;
3282fc2651226baac27029e38c9d6ef883fa32084dbSteve Block
3298e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    document()->addStyleSheetCandidateNode(this, m_createdByParser);
33006ea8e899e48f1f2f396b70e63fae369f2f23232Kristian Monsen
3310617145a89917ae7735fe1c9538688ab9a577df5Kristian Monsen    process();
3328e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
3338e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
3348e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectvoid HTMLLinkElement::removedFromDocument()
3358e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
3368e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    HTMLElement::removedFromDocument();
3378e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
3382fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    if (m_isInShadowTree) {
3392fc2651226baac27029e38c9d6ef883fa32084dbSteve Block        ASSERT(!m_sheet);
3402fc2651226baac27029e38c9d6ef883fa32084dbSteve Block        return;
3412fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    }
3420bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    document()->removeStyleSheetCandidateNode(this);
3430bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch
3446b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner    if (m_sheet) {
3456b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner        ASSERT(m_sheet->ownerNode() == this);
3466b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner        m_sheet->clearOwnerNode();
3476b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner        m_sheet = 0;
3486b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner    }
3496b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner
3500bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    if (document()->renderer())
3515ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen        document()->styleSelectorChanged(DeferRecalcStyle);
3528e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
3538e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
3548e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectvoid HTMLLinkElement::finishParsingChildren()
3558e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
3568e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    m_createdByParser = false;
3578e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    HTMLElement::finishParsingChildren();
3588e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
3598e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
360d0825bca7fe65beaee391d30da42e937db621564Steve Blockvoid HTMLLinkElement::setCSSStyleSheet(const String& href, const KURL& baseURL, const String& charset, const CachedCSSStyleSheet* sheet)
3618e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
3626b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner    if (!inDocument()) {
3636b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner        ASSERT(!m_sheet);
3646b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner        return;
3656b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner    }
3666b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner
367d0825bca7fe65beaee391d30da42e937db621564Steve Block    m_sheet = CSSStyleSheet::create(this, href, baseURL, charset);
3688e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
3695ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen    bool strictParsing = !document()->inQuirksMode();
3708e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    bool enforceMIMEType = strictParsing;
371d0825bca7fe65beaee391d30da42e937db621564Steve Block    bool crossOriginCSS = false;
372d0825bca7fe65beaee391d30da42e937db621564Steve Block    bool validMIMEType = false;
373d0825bca7fe65beaee391d30da42e937db621564Steve Block    bool needsSiteSpecificQuirks = document()->page() && document()->page()->settings()->needsSiteSpecificQuirks();
3748e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
3758e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // Check to see if we should enforce the MIME type of the CSS resource in strict mode.
3768e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // Running in iWeb 2 is one example of where we don't want to - <rdar://problem/6099748>
3775ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen    if (enforceMIMEType && document()->page() && !document()->page()->settings()->enforceCSSMIMETypeInNoQuirksMode())
3788e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        enforceMIMEType = false;
3798e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
380d0825bca7fe65beaee391d30da42e937db621564Steve Block#if defined(BUILDING_ON_TIGER) || defined(BUILDING_ON_LEOPARD)
381d0825bca7fe65beaee391d30da42e937db621564Steve Block    if (enforceMIMEType && needsSiteSpecificQuirks) {
382d0825bca7fe65beaee391d30da42e937db621564Steve Block        // Covers both http and https, with or without "www."
383d0825bca7fe65beaee391d30da42e937db621564Steve Block        if (baseURL.string().contains("mcafee.com/japan/", false))
384d0825bca7fe65beaee391d30da42e937db621564Steve Block            enforceMIMEType = false;
385d0825bca7fe65beaee391d30da42e937db621564Steve Block    }
386d0825bca7fe65beaee391d30da42e937db621564Steve Block#endif
387d0825bca7fe65beaee391d30da42e937db621564Steve Block
388d0825bca7fe65beaee391d30da42e937db621564Steve Block    String sheetText = sheet->sheetText(enforceMIMEType, &validMIMEType);
389231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block    m_sheet->parseString(sheetText, strictParsing);
390231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block
391d0825bca7fe65beaee391d30da42e937db621564Steve Block    // If we're loading a stylesheet cross-origin, and the MIME type is not
392d0825bca7fe65beaee391d30da42e937db621564Steve Block    // standard, require the CSS to at least start with a syntactically
393d0825bca7fe65beaee391d30da42e937db621564Steve Block    // valid CSS rule.
394d0825bca7fe65beaee391d30da42e937db621564Steve Block    // This prevents an attacker playing games by injecting CSS strings into
395d0825bca7fe65beaee391d30da42e937db621564Steve Block    // HTML, XML, JSON, etc. etc.
396d0825bca7fe65beaee391d30da42e937db621564Steve Block    if (!document()->securityOrigin()->canRequest(baseURL))
397d0825bca7fe65beaee391d30da42e937db621564Steve Block        crossOriginCSS = true;
398d0825bca7fe65beaee391d30da42e937db621564Steve Block
399d0825bca7fe65beaee391d30da42e937db621564Steve Block    if (crossOriginCSS && !validMIMEType && !m_sheet->hasSyntacticallyValidCSSHeader())
400d0825bca7fe65beaee391d30da42e937db621564Steve Block        m_sheet = CSSStyleSheet::create(this, href, baseURL, charset);
401d0825bca7fe65beaee391d30da42e937db621564Steve Block
402d0825bca7fe65beaee391d30da42e937db621564Steve Block    if (strictParsing && needsSiteSpecificQuirks) {
403231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block        // Work around <https://bugs.webkit.org/show_bug.cgi?id=28350>.
404231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block        DEFINE_STATIC_LOCAL(const String, slashKHTMLFixesDotCss, ("/KHTMLFixes.css"));
405231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block        DEFINE_STATIC_LOCAL(const String, mediaWikiKHTMLFixesStyleSheet, ("/* KHTML fix stylesheet */\n/* work around the horizontal scrollbars */\n#column-content { margin-left: 0; }\n\n"));
406231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block        // There are two variants of KHTMLFixes.css. One is equal to mediaWikiKHTMLFixesStyleSheet,
407231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block        // while the other lacks the second trailing newline.
408d0825bca7fe65beaee391d30da42e937db621564Steve Block        if (baseURL.string().endsWith(slashKHTMLFixesDotCss) && !sheetText.isNull() && mediaWikiKHTMLFixesStyleSheet.startsWith(sheetText)
409231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block                && sheetText.length() >= mediaWikiKHTMLFixesStyleSheet.length() - 1) {
410231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block            ASSERT(m_sheet->length() == 1);
411231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block            ExceptionCode ec;
412231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block            m_sheet->deleteRule(0, ec);
413231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block        }
414231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block    }
415231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block
4168e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    m_sheet->setTitle(title());
4178e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
4188e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    RefPtr<MediaList> media = MediaList::createAllowingDescriptionSyntax(m_media);
4198e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    m_sheet->setMedia(media.get());
4208e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
4218e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    m_loading = false;
4228e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    m_sheet->checkLoaded();
4238e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
4248e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
4258e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectbool HTMLLinkElement::isLoading() const
4268e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
4278e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (m_loading)
4288e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return true;
4298e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (!m_sheet)
4308e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return false;
4318e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    return static_cast<CSSStyleSheet *>(m_sheet.get())->isLoading();
4328e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
4338e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
434f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch#if ENABLE(LINK_PREFETCH)
435f05b935882198ccf7d81675736e3aeb089c5113aBen Murdochvoid HTMLLinkElement::onloadTimerFired(Timer<HTMLLinkElement>* timer)
436f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch{
437f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch    ASSERT_UNUSED(timer, timer == &m_onloadTimer);
4382daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch    if (m_cachedLinkResource->errorOccurred())
4392bde8e466a4451c7319e3a072d118917957d6554Steve Block        dispatchEvent(Event::create(eventNames().errorEvent, false, false));
4402bde8e466a4451c7319e3a072d118917957d6554Steve Block    else
4412bde8e466a4451c7319e3a072d118917957d6554Steve Block        dispatchEvent(Event::create(eventNames().loadEvent, false, false));
4422bde8e466a4451c7319e3a072d118917957d6554Steve Block
4432daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch    m_cachedLinkResource->removeClient(this);
4442daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch    m_cachedLinkResource = 0;
445f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch}
446f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch
447f05b935882198ccf7d81675736e3aeb089c5113aBen Murdochvoid HTMLLinkElement::notifyFinished(CachedResource* resource)
448f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch{
449f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch    m_onloadTimer.startOneShot(0);
4502daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch    ASSERT(m_cachedLinkResource.get() == resource);
451f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch}
452f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch#endif
453f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch
4548e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectbool HTMLLinkElement::sheetLoaded()
4558e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
456f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch    if (!isLoading()) {
457f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch        removePendingSheet();
4588e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return true;
4598e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
4608e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    return false;
4618e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
4628e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
4638e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectbool HTMLLinkElement::isURLAttribute(Attribute *attr) const
4648e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
4658e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    return attr->name() == hrefAttr;
4668e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
4678e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
4688e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source ProjectKURL HTMLLinkElement::href() const
4698e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
4708e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    return document()->completeURL(getAttribute(hrefAttr));
4718e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
4728e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
4738e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source ProjectString HTMLLinkElement::rel() const
4748e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
4758e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    return getAttribute(relAttr);
4768e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
4778e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
4788e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source ProjectString HTMLLinkElement::target() const
4798e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
4808e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    return getAttribute(targetAttr);
4818e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
4828e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
4838e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source ProjectString HTMLLinkElement::type() const
4848e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
4858e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    return getAttribute(typeAttr);
4868e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
4878e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
488635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Projectvoid HTMLLinkElement::addSubresourceAttributeURLs(ListHashSet<KURL>& urls) const
489635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project{
490635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project    HTMLElement::addSubresourceAttributeURLs(urls);
491635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project
492635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project    // Favicons are handled by a special case in LegacyWebArchive::create()
4936c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen    if (m_relAttribute.m_isIcon)
4946c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen        return;
4956c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen
4966c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen    if (!m_relAttribute.m_isStyleSheet)
4978e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return;
498635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project
4998e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // Append the URL of this link element.
500635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project    addSubresourceURL(urls, href());
5018e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
5028e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // Walk the URLs linked by the linked-to stylesheet.
503635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project    if (StyleSheet* styleSheet = const_cast<HTMLLinkElement*>(this)->sheet())
504635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project        styleSheet->addSubresourceStyleURLs(urls);
5058e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
5068e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
507f05b935882198ccf7d81675736e3aeb089c5113aBen Murdochvoid HTMLLinkElement::addPendingSheet(PendingSheetType type)
508f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch{
509f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch    if (type <= m_pendingSheetType)
510f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch        return;
511f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch    m_pendingSheetType = type;
512f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch
513f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch    if (m_pendingSheetType == NonBlocking)
514f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch        return;
515f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch    document()->addPendingSheet();
516f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch}
517f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch
518f05b935882198ccf7d81675736e3aeb089c5113aBen Murdochvoid HTMLLinkElement::removePendingSheet()
519f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch{
520f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch    PendingSheetType type = m_pendingSheetType;
521f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch    m_pendingSheetType = None;
522f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch
523f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch    if (type == None)
524f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch        return;
525f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch    if (type == NonBlocking) {
526f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch        // Document::removePendingSheet() triggers the style selector recalc for blocking sheets.
527f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch        document()->styleSelectorChanged(RecalcStyleImmediately);
528f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch        return;
529f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch    }
530f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch    document()->removePendingSheet();
531f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch}
53247300b36ce11d38290d3933277fc9906493505d4Grace Kloba
5338e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
534