1e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles)/*
2e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles) * Copyright (C) 1999 Lars Knoll (knoll@kde.org)
3e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles) *           (C) 1999 Antti Koivisto (koivisto@kde.org)
4e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles) *           (C) 2001 Dirk Mueller (mueller@kde.org)
5e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles) *           (C) 2006 Alexey Proskuryakov (ap@webkit.org)
6e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles) * Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2012 Apple Inc. All rights reserved.
7e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles) * Copyright (C) 2008, 2009 Torch Mobile Inc. All rights reserved. (http://www.torchmobile.com/)
8e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles) * Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies)
9e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles) * Copyright (C) 2013 Google Inc. All rights reserved.
10e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles) *
11e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles) * This library is free software; you can redistribute it and/or
12e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles) * modify it under the terms of the GNU Library General Public
13e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles) * License as published by the Free Software Foundation; either
14e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles) * version 2 of the License, or (at your option) any later version.
15e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles) *
16e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles) * This library is distributed in the hope that it will be useful,
17e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles) * but WITHOUT ANY WARRANTY; without even the implied warranty of
18e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles) * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
19e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles) * Library General Public License for more details.
20e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles) *
21e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles) * You should have received a copy of the GNU Library General Public License
22e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles) * along with this library; see the file COPYING.LIB.  If not, write to
23e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles) * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
24e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles) * Boston, MA 02110-1301, USA.
25e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles) */
26e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles)
27e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles)#include "config.h"
28e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles)#include "core/dom/ShadowTreeStyleSheetCollection.h"
29e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles)
305d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles)#include "core/HTMLNames.h"
31e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles)#include "core/css/CSSStyleSheet.h"
32e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles)#include "core/css/resolver/StyleResolver.h"
33e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles)#include "core/dom/Element.h"
349bbd2f5e390b01907d97ecffde80aa1b06113aacTorne (Richard Coles)#include "core/dom/StyleEngine.h"
35e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles)#include "core/dom/shadow/ShadowRoot.h"
36e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles)#include "core/html/HTMLStyleElement.h"
37e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles)
38c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)namespace blink {
39e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles)
40e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles)using namespace HTMLNames;
41e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles)
428abfc5808a4e34d6e03867af8bc440dee641886fTorne (Richard Coles)ShadowTreeStyleSheetCollection::ShadowTreeStyleSheetCollection(ShadowRoot& shadowRoot)
4309380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    : TreeScopeStyleSheetCollection(shadowRoot)
44e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles){
45e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles)}
46e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles)
4709380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)void ShadowTreeStyleSheetCollection::collectStyleSheets(StyleEngine* engine, StyleSheetCollection& collection)
48e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles){
49e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles)    DocumentOrderedList::iterator begin = m_styleSheetCandidateNodes.begin();
50e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles)    DocumentOrderedList::iterator end = m_styleSheetCandidateNodes.end();
51e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles)    for (DocumentOrderedList::iterator it = begin; it != end; ++it) {
52e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles)        Node* node = *it;
53e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles)        StyleSheet* sheet = 0;
54e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles)        CSSStyleSheet* activeSheet = 0;
55e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles)
56d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)        if (!isHTMLStyleElement(*node))
57e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles)            continue;
58e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles)
59d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)        HTMLStyleElement* element = toHTMLStyleElement(node);
6009380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)        const AtomicString& title = element->fastGetAttribute(titleAttr);
61e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles)        bool enabledViaScript = false;
62e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles)
63d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)        sheet = element->sheet();
64e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles)        if (sheet && !sheet->disabled() && sheet->isCSSStyleSheet())
6551b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)            activeSheet = toCSSStyleSheet(sheet);
66e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles)
67e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles)        // FIXME: clarify how PREFERRED or ALTERNATE works in shadow trees.
68e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles)        // Should we set preferred/selected stylesheets name in shadow trees and
69e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles)        // use the name in document?
70e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles)        if (!enabledViaScript && sheet && !title.isEmpty()) {
7151b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)            if (engine->preferredStylesheetSetName().isEmpty()) {
7207a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch                engine->setPreferredStylesheetSetName(title);
7307a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch                engine->setSelectedStylesheetSetName(title);
74e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles)            }
7551b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)            if (title != engine->preferredStylesheetSetName())
76e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles)                activeSheet = 0;
77e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles)        }
78e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles)
7907a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch        const AtomicString& rel = element->fastGetAttribute(relAttr);
80e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles)        if (rel.contains("alternate") && title.isEmpty())
81e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles)            activeSheet = 0;
82e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles)
83e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles)        if (sheet)
8451b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)            collection.appendSheetForList(sheet);
85e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles)        if (activeSheet)
8651b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)            collection.appendActiveStyleSheet(activeSheet);
87e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles)    }
88e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles)}
89e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles)
905d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles)void ShadowTreeStyleSheetCollection::updateActiveStyleSheets(StyleEngine* engine, StyleResolverUpdateMode updateMode)
91e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles){
9209380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    StyleSheetCollection collection;
9351b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)    collectStyleSheets(engine, collection);
94e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles)
9551b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)    StyleSheetChange change;
9651b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)    analyzeStyleSheetChange(updateMode, collection, change);
97e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles)
98a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles)    if (StyleResolver* styleResolver = engine->resolver()) {
9951b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)        if (change.styleResolverUpdateType != Additive) {
100e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles)            // We should not destroy StyleResolver when we find any stylesheet update in a shadow tree.
101e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles)            // In this case, we will reset rulesets created from style elements in the shadow tree.
102c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)            styleResolver->resetAuthorStyle(treeScope());
10351b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)            styleResolver->removePendingAuthorStyleSheets(m_activeAuthorStyleSheets);
10451b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)            styleResolver->lazyAppendAuthorStyleSheets(0, collection.activeAuthorStyleSheets());
105e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles)        } else {
10651b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)            styleResolver->lazyAppendAuthorStyleSheets(m_activeAuthorStyleSheets.size(), collection.activeAuthorStyleSheets());
107e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles)        }
108e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles)    }
10951b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)    if (change.requiresFullStyleRecalc)
110c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)        toShadowRoot(treeScope().rootNode()).host()->setNeedsStyleRecalc(SubtreeStyleChange);
1111e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)
11251b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)    collection.swap(*this);
113e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles)    updateUsesRemUnits();
114e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles)}
115e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles)
116e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles)}
117