File indexing completed on 2024-04-28 15:22:41

0001 /*
0002  * This file is part of the DOM implementation for KDE.
0003  *
0004  * Copyright 1999-2003 Lars Knoll (knoll@kde.org)
0005  * Copyright 2004 Apple Computer, Inc.
0006  *
0007  * This library is free software; you can redistribute it and/or
0008  * modify it under the terms of the GNU Library General Public
0009  * License as published by the Free Software Foundation; either
0010  * version 2 of the License, or (at your option) any later version.
0011  *
0012  * This library is distributed in the hope that it will be useful,
0013  * but WITHOUT ANY WARRANTY; without even the implied warranty of
0014  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
0015  * Library General Public License for more details.
0016  *
0017  * You should have received a copy of the GNU Library General Public License
0018  * along with this library; see the file COPYING.LIB.  If not, write to
0019  * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
0020  * Boston, MA 02110-1301, USA.
0021  *
0022  */
0023 #ifndef _CSS_css_stylesheetimpl_h_
0024 #define _CSS_css_stylesheetimpl_h_
0025 
0026 #include "dom/dom_string.h"
0027 #include "css/css_base.h"
0028 #include "misc/loader_client.h"
0029 #include "xml/dom_docimpl.h"
0030 #include <QPointer>
0031 
0032 namespace khtml
0033 {
0034 class CachedCSSStyleSheet;
0035 class DocLoader;
0036 class MediaQuery;
0037 }
0038 
0039 namespace DOM
0040 {
0041 
0042 class StyleSheet;
0043 class CSSStyleSheet;
0044 class CSSParser;
0045 class MediaListImpl;
0046 class CSSRuleImpl;
0047 class CSSNamespaceRuleImpl;
0048 class CSSRuleListImpl;
0049 class NodeImpl;
0050 class DocumentImpl;
0051 
0052 class StyleSheetImpl : public StyleListImpl
0053 {
0054 public:
0055     StyleSheetImpl(DOM::NodeImpl *ownerNode, DOM::DOMString href = DOMString());
0056     StyleSheetImpl(StyleSheetImpl *parentSheet, DOM::DOMString href = DOMString());
0057     StyleSheetImpl(StyleBaseImpl *owner, DOM::DOMString href  = DOMString());
0058     StyleSheetImpl(khtml::CachedCSSStyleSheet *cached, DOM::DOMString href  = DOMString());
0059     virtual ~StyleSheetImpl();
0060 
0061     bool isStyleSheet() const override
0062     {
0063         return true;
0064     }
0065 
0066     virtual DOM::DOMString type() const
0067     {
0068         return DOMString();
0069     }
0070 
0071     bool disabled() const
0072     {
0073         return m_disabled;
0074     }
0075     void setDisabled(bool disabled);
0076     DOM::NodeImpl *ownerNode() const
0077     {
0078         return m_parentNode;
0079     }
0080     StyleSheetImpl *parentStyleSheet() const;
0081     DOM::DOMString href() const
0082     {
0083         return m_strHref;
0084     }
0085     void setHref(const DOM::DOMString &href)
0086     {
0087         m_strHref = href;
0088     }
0089     DOM::DOMString title() const
0090     {
0091         return m_strTitle;
0092     }
0093     MediaListImpl *media() const
0094     {
0095         return m_media;
0096     }
0097     void setMedia(MediaListImpl *media);
0098     void setTitle(const DOM::DOMString &title)
0099     {
0100         m_strTitle = title;
0101     }
0102 
0103 protected:
0104     DOM::NodeImpl *m_parentNode;
0105     DOM::DOMString m_strHref;
0106     DOM::DOMString m_strTitle;
0107     MediaListImpl *m_media;
0108     bool m_disabled;
0109 };
0110 
0111 class CSSStyleSheetImpl : public StyleSheetImpl
0112 {
0113 public:
0114     CSSStyleSheetImpl(DOM::NodeImpl *parentNode, DOM::DOMString href = DOMString(), bool _implicit = false);
0115     CSSStyleSheetImpl(CSSStyleSheetImpl *parentSheet, DOM::DOMString href = DOMString());
0116     CSSStyleSheetImpl(CSSRuleImpl *ownerRule, DOM::DOMString href = DOMString());
0117     // clone from a cached version of the sheet
0118     CSSStyleSheetImpl(DOM::NodeImpl *parentNode, CSSStyleSheetImpl *orig);
0119     CSSStyleSheetImpl(CSSRuleImpl *ownerRule, CSSStyleSheetImpl *orig);
0120 
0121     ~CSSStyleSheetImpl()
0122     {
0123         delete m_namespaces;
0124     }
0125 
0126     bool isCSSStyleSheet() const override
0127     {
0128         return true;
0129     }
0130 
0131     DOM::DOMString type() const override
0132     {
0133         return "text/css";
0134     }
0135 
0136     CSSRuleImpl *ownerRule() const;
0137     CSSRuleListImpl *cssRules(bool omitCharsetRule = false);
0138     unsigned long insertRule(const DOM::DOMString &rule, unsigned long index, int &exceptioncode);
0139     void deleteRule(unsigned long index, int &exceptioncode);
0140 
0141     void determineNamespace(NamespaceName &namespacename, const DOM::DOMString &prefix);
0142     quint32 defaultNamespace()
0143     {
0144         return m_defaultNamespace.id();
0145     }
0146     void appendNamespaceRule(CSSNamespaceRuleImpl *ns);
0147 
0148     void setCharset(const DOMString &charset)
0149     {
0150         m_charset = charset;
0151     }
0152     const DOMString &charset() const
0153     {
0154         return m_charset;
0155     }
0156 
0157     bool parseString(const DOMString &string, bool strict = true) override;
0158 
0159     bool isLoading() const;
0160 
0161     void checkLoaded() const override;
0162     void checkPending() const override;
0163     bool loadedHint() const
0164     {
0165         return m_loadedHint;
0166     }
0167 
0168     // ### remove? (clients should use sheet->doc()->docLoader())
0169     khtml::DocLoader *docLoader() const
0170     {
0171         return m_doc ? m_doc->docLoader() : nullptr;
0172     }
0173 
0174     DocumentImpl *doc() const
0175     {
0176         return m_doc;
0177     }
0178     bool implicit() const
0179     {
0180         return m_implicit;
0181     }
0182 protected:
0183     void recomputeNamespaceInfo(); // updates m_defaultNamespace and m_namespaces
0184     // we update m_namespaces lazily, but
0185     // m_defaulNamespace eagerly.
0186     void dirtyNamespaceInfo()
0187     {
0188         delete m_namespaces;
0189         m_namespaces = nullptr;
0190     }
0191 
0192     DocumentImpl *m_doc;
0193     bool m_implicit;
0194     mutable bool m_loadedHint;
0195     NamespaceName m_defaultNamespace;
0196     QList<CSSNamespaceRuleImpl *> *m_namespaces;
0197     DOMString m_charset;
0198 };
0199 
0200 // ----------------------------------------------------------------------------
0201 
0202 class StyleSheetListImpl : public khtml::Shared<StyleSheetListImpl>
0203 {
0204 public:
0205     // the manager argument should be passed only when this is
0206     // document.styleSheets.
0207     StyleSheetListImpl(DocumentImpl *manager = nullptr): managerDocument(manager) {}
0208     ~StyleSheetListImpl();
0209 
0210     // the following two ignore implicit stylesheets
0211     unsigned long length() const;
0212     StyleSheetImpl *item(unsigned long index);
0213 
0214     void add(StyleSheetImpl *s);
0215     void remove(StyleSheetImpl *s);
0216 
0217     QList<StyleSheetImpl *> styleSheets;
0218 
0219     // we need the document pointer to make it update the stylesheet list
0220     // if needed for the global list. Luckily, we don't care about that if the
0221     // document dies, so we use QPointer to break the cycle
0222     QPointer<DocumentImpl> managerDocument;
0223 };
0224 
0225 // ----------------------------------------------------------------------------
0226 
0227 class MediaListImpl : public StyleBaseImpl
0228 {
0229 public:
0230     MediaListImpl(bool fallbackToDescription = false)
0231         : StyleBaseImpl(nullptr), m_fallback(fallbackToDescription) {}
0232     MediaListImpl(CSSStyleSheetImpl *parentSheet, bool fallbackToDescription = false)
0233         : StyleBaseImpl(parentSheet), m_fallback(fallbackToDescription) {}
0234     MediaListImpl(CSSStyleSheetImpl *parentSheet,
0235                   const DOM::DOMString &media, bool fallbackToDescription = false);
0236     MediaListImpl(CSSRuleImpl *parentRule, const DOM::DOMString &media, bool fallbackToDescription = false);
0237     ~MediaListImpl();
0238 
0239     bool isMediaList() const override
0240     {
0241         return true;
0242     }
0243 
0244     CSSStyleSheetImpl *parentStyleSheet() const;
0245     CSSRuleImpl *parentRule() const;
0246     unsigned long length() const
0247     {
0248         return  m_queries.size();
0249     }
0250     DOM::DOMString item(unsigned long index) const;
0251     void deleteMedium(const DOM::DOMString &oldMedium, int &ec);
0252     void appendMedium(const DOM::DOMString &newMedium, int &ec);
0253 
0254     DOM::DOMString mediaText() const;
0255     void setMediaText(const DOM::DOMString &value, int &ec);
0256 
0257     void appendMediaQuery(khtml::MediaQuery *mediaQuery);
0258     const QList<khtml::MediaQuery *> *mediaQueries() const
0259     {
0260         return &m_queries;
0261     }
0262 
0263 protected:
0264     QList<khtml::MediaQuery *> m_queries;
0265     bool m_fallback; // true if failed media query parsing should fallback to media description parsing
0266 };
0267 
0268 } // namespace
0269 
0270 #endif
0271