File indexing completed on 2024-04-28 15:24:49

0001 /*
0002  * This file is part of the DOM implementation for KDE.
0003  *
0004  * Copyright (C) 1999 Lars Knoll (knoll@kde.org)
0005  *           (C) 1999 Antti Koivisto (koivisto@kde.org)
0006  *           (C) 2001 Dirk Mueller (mueller@kde.org)
0007  *           (C) 2002-2003 Apple Computer, Inc.
0008  *           (C) 2006 Allan Sandfeld Jensen(kde@carewolf.com)
0009  *
0010  * This library is free software; you can redistribute it and/or
0011  * modify it under the terms of the GNU Library General Public
0012  * License as published by the Free Software Foundation; either
0013  * version 2 of the License, or (at your option) any later version.
0014  *
0015  * This library is distributed in the hope that it will be useful,
0016  * but WITHOUT ANY WARRANTY; without even the implied warranty of
0017  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
0018  * Library General Public License for more details.
0019  *
0020  * You should have received a copy of the GNU Library General Public License
0021  * along with this library; see the file COPYING.LIB.  If not, write to
0022  * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
0023  * Boston, MA 02110-1301, USA.
0024  *
0025  */
0026 
0027 #ifndef _DOM_DocumentImpl_h_
0028 #define _DOM_DocumentImpl_h_
0029 
0030 #include "xml/dom_elementimpl.h"
0031 #include "xml/dom_nodelistimpl.h"
0032 #include "xml/dom_textimpl.h"
0033 #include "xml/dom2_traversalimpl.h"
0034 #include "xml/security_origin.h"
0035 #include "misc/shared.h"
0036 #include "misc/loader.h"
0037 #include "misc/seed.h"
0038 
0039 #include <QStringList>
0040 #include <QObject>
0041 #include <QList>
0042 #include <QHash>
0043 #include <QMap>
0044 #include <QUrl>
0045 
0046 //Added by qt3to4:
0047 #include <QTimerEvent>
0048 
0049 class QPaintDevice;
0050 class QTextCodec;
0051 class KHTMLView;
0052 class QEventLoop;
0053 class KEncodingDetector;
0054 
0055 namespace khtml
0056 {
0057 class Tokenizer;
0058 class CSSStyleSelector;
0059 class DocLoader;
0060 class RenderArena;
0061 class EditCommand;
0062 class RenderObject;
0063 class CounterNode;
0064 class CachedObject;
0065 class CachedCSSStyleSheet;
0066 class DynamicDomRestyler;
0067 
0068 class XPathResultImpl;
0069 class XPathExpressionImpl;
0070 class XPathNSResolverImpl;
0071 }
0072 
0073 namespace KJS
0074 {
0075 class Window;
0076 }
0077 
0078 namespace WebCore
0079 {
0080 class SVGDocumentExtensions;
0081 class SVGDocument;
0082 } // namespace WebCore
0083 
0084 namespace DOM
0085 {
0086 
0087 class AbstractViewImpl;
0088 class AttrImpl;
0089 class CDATASectionImpl;
0090 class CSSStyleSheetImpl;
0091 class CommentImpl;
0092 class DocumentFragmentImpl;
0093 class DocumentImpl;
0094 class XMLDocumentImpl;
0095 class DocumentType;
0096 class DocumentTypeImpl;
0097 class EditingTextImpl;
0098 class ElementImpl;
0099 class EntityReferenceImpl;
0100 class EventImpl;
0101 class EventListener;
0102 class HTMLDocumentImpl;
0103 class HTMLElementImpl;
0104 class HTMLPartContainerElementImpl;
0105 class HTMLImageElementImpl;
0106 class JSEditor;
0107 class NodeFilter;
0108 class NodeFilterImpl;
0109 class NodeIteratorImpl;
0110 class NodeListImpl;
0111 class ProcessingInstructionImpl;
0112 class RangeImpl;
0113 class StyleSheetImpl;
0114 class StyleSheetListImpl;
0115 class TextImpl;
0116 class TreeWalkerImpl;
0117 class WindowEventTargetImpl;
0118 
0119 class DOMImplementationImpl : public khtml::Shared<DOMImplementationImpl>
0120 {
0121 public:
0122     DOMImplementationImpl();
0123     ~DOMImplementationImpl();
0124 
0125     // DOM methods & attributes for DOMImplementation.
0126     static bool hasFeature(const DOMString &feature, const DOMString &version);
0127     DocumentTypeImpl *createDocumentType(const DOMString &qualifiedName, const DOMString &publicId,
0128                                          const DOMString &systemId, int &exceptioncode);
0129     static DocumentImpl *createDocument(const DOMString &namespaceURI, const DOMString &qualifiedName,
0130                                         DocumentTypeImpl *dtype,
0131                                         KHTMLView *v, int &exceptioncode);
0132 
0133     // From the DOMImplementationCSS interface
0134     static CSSStyleSheetImpl *createCSSStyleSheet(DOMStringImpl *title, DOMStringImpl *media, int &exceptioncode);
0135 
0136     // From the HTMLDOMImplementation interface
0137     static HTMLDocumentImpl *createHTMLDocument(const DOMString &title);
0138 
0139     // Other methods (not part of DOM)
0140     static DocumentImpl *createDocument(KHTMLView *v = nullptr);
0141     static XMLDocumentImpl *createXMLDocument(KHTMLView *v = nullptr);
0142     static HTMLDocumentImpl *createHTMLDocument(KHTMLView *v = nullptr);
0143     static WebCore::SVGDocument *createSVGDocument(KHTMLView *v = nullptr);
0144 };
0145 
0146 /**
0147  * @internal A cache of element name (or id) to pointer
0148  */
0149 // TODO: QHash: better to store values here
0150 class ElementMappingCache
0151 {
0152 public:
0153     /**
0154      For each name, we hold a reference count, and a
0155      pointer. If the item is in the table, which implies
0156      reference count is > 1, the name is a valid key.
0157      If the pointer is non-null, it points to the appropriate
0158      mapping
0159     */
0160     struct ItemInfo {
0161         int       ref;
0162         ElementImpl *nd;
0163     };
0164 
0165     ElementMappingCache();
0166     ~ElementMappingCache();
0167 
0168     /**
0169      Add a pointer as just one of candidates, not neccesserily the proper one
0170     */
0171     void add(const DOMString &id, ElementImpl *nd);
0172 
0173     /**
0174      Set the pointer as the definite mapping; it must have already been added
0175     */
0176     void set(const DOMString &id, ElementImpl *nd);
0177 
0178     /**
0179      Remove the item; it must have already been added.
0180     */
0181     void remove(const DOMString &id, ElementImpl *nd);
0182 
0183     /**
0184      Returns true if the item exists
0185     */
0186     bool contains(const DOMString &id);
0187 
0188     /**
0189      Returns the information for the given ID
0190     */
0191     ItemInfo *get(const DOMString &id);
0192 private:
0193     QHash<DOMString, ItemInfo *> m_dict;
0194 };
0195 
0196 /**
0197  * @internal
0198  */
0199 class DocumentImpl : public QObject, private khtml::CachedObjectClient, public NodeBaseImpl
0200 {
0201     Q_OBJECT
0202 public:
0203     DocumentImpl(KHTMLView *v);
0204     ~DocumentImpl();
0205 
0206     // DOM methods & attributes for Document
0207 
0208     DocumentTypeImpl *doctype() const;
0209 
0210     DOMImplementationImpl *implementation() const;
0211     ElementImpl *documentElement() const;
0212     void childrenChanged() override;
0213     virtual ElementImpl *createElement(const DOMString &tagName, int *pExceptioncode = nullptr);
0214     virtual AttrImpl *createAttribute(const DOMString &tagName, int *pExceptioncode = nullptr);
0215     DocumentFragmentImpl *createDocumentFragment();
0216     TextImpl *createTextNode(DOMStringImpl *data)
0217     {
0218         return new TextImpl(docPtr(), data);
0219     }
0220     TextImpl *createTextNode(const QString &data)
0221     {
0222         return createTextNode(new DOMStringImpl(data.unicode(), data.length()));
0223     }
0224     TextImpl *createTextNode(const DOMString &data)
0225     {
0226         return createTextNode(data.implementation());
0227     }
0228     TextImpl *createTextNode(const char *latin1)
0229     {
0230         return createTextNode(DOMString(latin1));
0231     }
0232     CommentImpl *createComment(DOMStringImpl *data);
0233     CDATASectionImpl *createCDATASection(DOMStringImpl *data, int &exceptioncode);
0234     ProcessingInstructionImpl *createProcessingInstruction(const DOMString &target, DOMStringImpl *data);
0235     EntityReferenceImpl *createEntityReference(const DOMString &name, int &exceptioncode);
0236     NodeImpl *importNode(NodeImpl *importedNode, bool deep, int &exceptioncode);
0237     virtual ElementImpl *createElementNS(const DOMString &_namespaceURI, const DOMString &_qualifiedName,
0238                                          int *pExceptioncode = nullptr);
0239     virtual AttrImpl *createAttributeNS(const DOMString &_namespaceURI, const DOMString &_qualifiedName,
0240                                         int *pExceptioncode = nullptr);
0241     ElementImpl *getElementById(const DOMString &elementId) const;
0242 
0243     // DOM3 XPath, from XPathEvaluator interface
0244     khtml::XPathExpressionImpl *createExpression(DOM::DOMString &expression,
0245             khtml::XPathNSResolverImpl *resolver,
0246             int &exceptioncode);
0247     khtml::XPathNSResolverImpl *createNSResolver(NodeImpl *nodeResolver);
0248     khtml::XPathResultImpl *evaluate(DOM::DOMString &expression,
0249                                      NodeImpl *contextNode,
0250                                      khtml::XPathNSResolverImpl *resolver,
0251                                      unsigned short type,
0252                                      khtml::XPathResultImpl *result,
0253                                      int &exceptioncode);
0254 
0255     // Actually part of HTMLDocument, but used for giving XML documents a window title as well
0256     DOMString title() const
0257     {
0258         return m_title;
0259     }
0260     void setTitle(const DOMString &_title);
0261 
0262     // DOM methods overridden from  parent classes
0263 
0264     DOMString nodeName() const override;
0265     unsigned short nodeType() const override;
0266 
0267     // Other methods (not part of DOM)
0268     bool isDocumentNode() const override
0269     {
0270         return true;
0271     }
0272     virtual bool isHTMLDocument() const
0273     {
0274         return false;
0275     }
0276     virtual bool isSVGDocument() const;
0277 
0278     virtual ElementImpl *createHTMLElement(const DOMString &tagName, bool caseInsensitive = true);
0279     // SVG
0280     virtual ElementImpl *createSVGElement(const QualifiedName &name);
0281 
0282     khtml::CSSStyleSelector *styleSelector()
0283     {
0284         return m_styleSelector;
0285     }
0286 
0287     /**
0288     * Updates the pending sheet count and then calls updateStyleSelector.
0289     */
0290     void styleSheetLoaded();
0291 
0292     /**
0293      * This method returns true if all top-level stylesheets have loaded (including
0294      * any \@imports that they may be loading).
0295      */
0296     bool haveStylesheetsLoaded() const
0297     {
0298         return m_pendingStylesheets <= 0 || m_ignorePendingStylesheets;
0299     }
0300 
0301     /**
0302      * Increments the number of pending sheets.  The \<link\> elements
0303      * invoke this to add themselves to the loading list.
0304      */
0305     void addPendingSheet();
0306 
0307     /**
0308      * Returns true if the document has pending stylesheets
0309      * loading.
0310      */
0311     bool hasPendingSheets() const
0312     {
0313         return m_pendingStylesheets;
0314     }
0315 
0316     /**
0317      * Called when one or more stylesheets in the document may have been added, removed or changed.
0318      *
0319      * Creates a new style selector and assign it to this document. This is done by iterating through all nodes in
0320      * document (or those before \<BODY\> in a HTML document), searching for stylesheets. Stylesheets can be contained in
0321      * \<LINK\>, \<STYLE\> or \<BODY\> elements, as well as processing instructions (XML documents only). A list is
0322      * constructed from these which is used to create the a new style selector which collates all of the stylesheets
0323      * found and is used to calculate the derived styles for all rendering objects.
0324      *
0325      * @param shallow If the stylesheet list for the document is unchanged, with only added or removed rules
0326      * in existing sheets, then set this argument to true for efficiency.
0327      */
0328     void updateStyleSelector(bool shallow = false);
0329 
0330     void ensureStyleSheetListUpToDate()
0331     {
0332         if (m_styleSheetListDirty) {
0333             rebuildStyleSheetList(true);
0334         }
0335     }
0336 
0337     bool readyForLayout() const;
0338 
0339     // DOM representation of the JS Window object, for event handling
0340     WindowEventTargetImpl *windowEventTarget() const
0341     {
0342         return m_windowEventTarget;
0343     }
0344 private:
0345     void rebuildStyleSheetList(bool force = false);
0346     void rebuildStyleSelector();
0347     bool m_styleSheetListDirty;
0348 public:
0349 
0350     // Tries to restore the elements value from the doc state,
0351     // if it seems like the same thing
0352     void attemptRestoreState(NodeImpl *e);
0353 
0354     // Query all registered elements for their state
0355     QStringList docState();
0356     bool unsubmittedFormChanges();
0357     void registerMaintainsState(NodeImpl *e)
0358     {
0359         m_maintainsState.append(e);
0360     }
0361     void deregisterMaintainsState(NodeImpl *e)
0362     {
0363         int i;
0364         if ((i = m_maintainsState.indexOf(e)) != -1) {
0365             m_maintainsState.removeAt(i);
0366         }
0367     }
0368 
0369     // Set the state the document should restore to
0370     void setRestoreState(const QStringList &s);
0371 
0372     KHTMLView *view() const;
0373     KHTMLPart *part() const;
0374 
0375     RangeImpl *createRange();
0376 
0377     NodeIteratorImpl *createNodeIterator(NodeImpl *root, unsigned long whatToShow,
0378                                          NodeFilterImpl *filter, bool entityReferenceExpansion, int &exceptioncode);
0379 
0380     TreeWalkerImpl *createTreeWalker(NodeImpl *root, unsigned long whatToShow, NodeFilterImpl *filter,
0381                                      bool entityReferenceExpansion, int &exceptioncode);
0382 
0383     EditingTextImpl *createEditingTextNode(const DOMString &text);
0384 
0385     void recalcStyle(StyleChange = NoChange) override;
0386     virtual void updateRendering();
0387     void updateLayout();
0388     static void updateDocumentsRendering();
0389     khtml::DocLoader *docLoader()
0390     {
0391         return m_docLoader;
0392     }
0393 
0394     void attach() override;
0395     void detach() override;
0396 
0397     khtml::RenderArena *renderArena()
0398     {
0399         return m_renderArena.get();
0400     }
0401 
0402     // to get visually ordered hebrew and arabic pages right
0403     void setVisuallyOrdered();
0404     // to get URL decoding right
0405     //void setDecoderCodec(const QTextCodec *codec);
0406 
0407     // ### elide the two after designMode merge
0408     void setSelection(NodeImpl *s, int sp, NodeImpl *e, int ep);
0409     void clearSelection();
0410     void updateSelection();
0411 
0412     void open(bool clearEventListeners = true);
0413     void close() override;
0414     virtual void contentLoaded() {}
0415     void write(const DOMString &text);
0416     void write(const QString &text);
0417     void writeln(const DOMString &text);
0418     void finishParsing();
0419 
0420     QUrl URL() const
0421     {
0422         return m_url;
0423     }
0424     void setURL(const QString &url)
0425     {
0426         m_url = QUrl(url);
0427     }
0428 
0429     QUrl baseURL() const
0430     {
0431         return m_baseURL.isEmpty() ? m_url : m_baseURL;
0432     }
0433     void setBaseURL(const QUrl &baseURL);
0434 
0435     QString baseTarget() const
0436     {
0437         return m_baseTarget;
0438     }
0439     void setBaseTarget(const QString &baseTarget)
0440     {
0441         m_baseTarget = baseTarget;
0442     }
0443 
0444     QString completeURL(const QString &url) const;
0445     DOMString canonURL(const DOMString &url) const
0446     {
0447         return url.isEmpty() ? url : completeURL(url.string());
0448     }
0449 
0450     void setUserStyleSheet(const QString &sheet);
0451     QString userStyleSheet() const
0452     {
0453         return m_usersheet;
0454     }
0455     void setPrintStyleSheet(const QString &sheet)
0456     {
0457         m_printSheet = sheet;
0458     }
0459     QString printStyleSheet() const
0460     {
0461         return m_printSheet;
0462     }
0463 
0464     CSSStyleSheetImpl *elementSheet();
0465     virtual khtml::Tokenizer *createTokenizer();
0466     khtml::Tokenizer *tokenizer()
0467     {
0468         return m_tokenizer;
0469     }
0470     KEncodingDetector *decoder()
0471     {
0472         return m_decoder;
0473     }
0474     void setDecoder(KEncodingDetector *enc)
0475     {
0476         m_decoder = enc;
0477     }
0478 
0479     void setPaintDevice(QPaintDevice *dev)
0480     {
0481         m_paintDevice = dev;
0482     }
0483     QPaintDevice *paintDevice() const
0484     {
0485         return m_paintDevice;
0486     }
0487     int logicalDpiY();
0488 
0489     enum HTMLMode {
0490         Html3 = 0,
0491         Html4 = 1,
0492         XHtml = 2
0493     };
0494 
0495     enum ParseMode {
0496         Unknown,
0497         Compat,
0498         Transitional,
0499         Strict
0500     };
0501     virtual void determineParseMode();
0502     void setParseMode(ParseMode m)
0503     {
0504         pMode = m;
0505     }
0506     ParseMode parseMode() const
0507     {
0508         return pMode;
0509     }
0510 
0511     bool inCompatMode() const
0512     {
0513         return pMode == Compat;
0514     }
0515     bool inTransitionalMode() const
0516     {
0517         return pMode == Transitional;
0518     }
0519     bool inStrictMode() const
0520     {
0521         return pMode == Strict;
0522     }
0523 
0524     //void setHTMLMode( HTMLMode m ) { hMode = m; }
0525     HTMLMode htmlMode() const
0526     {
0527         return hMode;
0528     }
0529 
0530     void setParsing(bool b)
0531     {
0532         m_bParsing = b;
0533     }
0534     bool parsing() const
0535     {
0536         return m_bParsing;
0537     }
0538 
0539     void setHasVariableLength(bool b = true)
0540     {
0541         m_bVariableLength = b;
0542     }
0543     bool hasVariableLength() const
0544     {
0545         return m_bVariableLength;
0546     }
0547 
0548     void setTextColor(QColor color)
0549     {
0550         m_textColor = color;
0551     }
0552     QColor textColor() const
0553     {
0554         return m_textColor;
0555     }
0556 
0557     void setDesignMode(bool b);
0558     bool designMode() const;
0559 
0560     // internal
0561     bool prepareMouseEvent(bool readonly, int x, int y, MouseEvent *ev);
0562 
0563     bool childTypeAllowed(unsigned short nodeType) override;
0564     WTF::PassRefPtr<NodeImpl> cloneNode(bool deep) override;
0565 
0566     StyleSheetListImpl *styleSheets()
0567     {
0568         return m_styleSheets;
0569     }
0570 
0571     DOMString preferredStylesheetSet() const
0572     {
0573         return m_preferredStylesheetSet;
0574     }
0575     DOMString selectedStylesheetSet() const;
0576     void setSelectedStylesheetSet(const DOMString &);
0577     void setPreferredStylesheetSet(const DOMString &s)
0578     {
0579         m_preferredStylesheetSet = s;
0580     }
0581 
0582     void addStyleSheet(StyleSheetImpl *, int *exceptioncode = nullptr);
0583     void removeStyleSheet(StyleSheetImpl *, int *exceptioncode = nullptr);
0584 
0585     QStringList availableStyleSheets() const
0586     {
0587         return m_availableSheets;
0588     }
0589 
0590     NodeImpl *hoverNode() const
0591     {
0592         return m_hoverNode;
0593     }
0594     void setHoverNode(NodeImpl *newHoverNode);
0595     NodeImpl *focusNode() const
0596     {
0597         return m_focusNode;
0598     }
0599     void quietResetFocus(); // Removes focus from active node without attempting to emit any events
0600     void setFocusNode(NodeImpl *newFocusNode);
0601     NodeImpl *activeNode() const
0602     {
0603         return m_activeNode;
0604     }
0605     void setActiveNode(NodeImpl *newActiveNode);
0606 
0607     // Updates for :target (CSS3 selector).
0608     void setCSSTarget(NodeImpl *n);
0609     NodeImpl *getCSSTarget()
0610     {
0611         return m_cssTarget;
0612     }
0613 
0614     bool isDocumentChanged()
0615     {
0616         return m_docChanged;
0617     }
0618     virtual void setDocumentChanged(bool = true);
0619     void attachNodeIterator(NodeIteratorImpl *ni);
0620     void detachNodeIterator(NodeIteratorImpl *ni);
0621     void notifyBeforeNodeRemoval(NodeImpl *n);
0622     AbstractViewImpl *defaultView() const
0623     {
0624         return m_defaultView;
0625     }
0626     EventImpl *createEvent(const DOMString &eventType, int &exceptioncode);
0627 
0628     // keep track of what types of event listeners are registered, so we don't
0629     // dispatch events unnecessarily
0630     enum ListenerType {
0631         DOMSUBTREEMODIFIED_LISTENER          = 0x01,
0632         DOMNODEINSERTED_LISTENER             = 0x02,
0633         DOMNODEREMOVED_LISTENER              = 0x04,
0634         DOMNODEREMOVEDFROMDOCUMENT_LISTENER  = 0x08,
0635         DOMNODEINSERTEDINTODOCUMENT_LISTENER = 0x10,
0636         DOMATTRMODIFIED_LISTENER             = 0x20,
0637         DOMCHARACTERDATAMODIFIED_LISTENER    = 0x40
0638     };
0639 
0640     bool hasListenerType(ListenerType listenerType) const
0641     {
0642         return (m_listenerTypes & listenerType);
0643     }
0644     void addListenerType(ListenerType listenerType)
0645     {
0646         m_listenerTypes = m_listenerTypes | listenerType;
0647     }
0648 
0649     CSSStyleDeclarationImpl *getOverrideStyle(ElementImpl *elt, DOMStringImpl *pseudoElt);
0650 
0651     bool async() const
0652     {
0653         return m_async;
0654     }
0655     void setAsync(bool b)
0656     {
0657         m_async = b;
0658     }
0659     void abort();
0660     void load(const DOMString &uri);
0661     void loadXML(const DOMString &source);
0662     // from cachedObjectClient
0663     void setStyleSheet(const DOM::DOMString &url, const DOM::DOMString &sheet, const DOM::DOMString &charset, const DOM::DOMString &mimetype) override;
0664     void error(int err, const QString &text) override;
0665 
0666     typedef QMap<QString, ProcessingInstructionImpl *> LocalStyleRefs;
0667     LocalStyleRefs *localStyleRefs()
0668     {
0669         return &m_localStyleRefs;
0670     }
0671 
0672     void defaultEventHandler(EventImpl *evt) override;
0673 
0674     void setHTMLWindowEventListener(EventName id, EventListener *listener);
0675     void setHTMLWindowEventListener(unsigned id, EventListener *listener);
0676 
0677     EventListener *getHTMLWindowEventListener(EventName id);
0678     EventListener *getHTMLWindowEventListener(unsigned id);
0679 
0680     EventListener *createHTMLEventListener(const QString &code, const QString &name, NodeImpl *node);
0681 
0682     void addWindowEventListener(EventName id, EventListener *listener, const bool useCapture);
0683     void removeWindowEventListener(EventName id, EventListener *listener, bool useCapture);
0684     bool hasWindowEventListener(EventName id);
0685 
0686     EventListener *createHTMLEventListener(QString code);
0687 
0688     /**
0689      * Searches through the document, starting from fromNode, for the next selectable element that comes after fromNode.
0690      * The order followed is as specified in section 17.11.1 of the HTML4 spec, which is elements with tab indexes
0691      * first (from lowest to highest), and then elements without tab indexes (in document order).
0692      *
0693      * @param fromNode The node from which to start searching. The node after this will be focused. May be null.
0694      *
0695      * @return The focus node that comes after fromNode
0696      *
0697      * See https://www.w3.org/TR/html4/interact/forms.html#h-17.11.1
0698      */
0699     NodeImpl *nextFocusNode(NodeImpl *fromNode);
0700 
0701     /**
0702      * Searches through the document, starting from fromNode, for the previous selectable element (that comes _before_)
0703      * fromNode. The order followed is as specified in section 17.11.1 of the HTML4 spec, which is elements with tab
0704      * indexes first (from lowest to highest), and then elements without tab indexes (in document order).
0705      *
0706      * @param fromNode The node from which to start searching. The node before this will be focused. May be null.
0707      *
0708      * @return The focus node that comes before fromNode
0709      *
0710      * See https://www.w3.org/TR/html4/interact/forms.html#h-17.11.1
0711      */
0712     NodeImpl *previousFocusNode(NodeImpl *fromNode);
0713 
0714     ElementImpl *findAccessKeyElement(QChar c);
0715 
0716     int nodeAbsIndex(NodeImpl *node);
0717     NodeImpl *nodeWithAbsIndex(int absIndex);
0718 
0719     /**
0720      * Handles a HTTP header equivalent set by a meta tag using <meta http-equiv="..." content="...">. This is called
0721      * when a meta tag is encountered during document parsing, and also when a script dynamically changes or adds a meta
0722      * tag. This enables scripts to use meta tags to perform refreshes and set expiry dates in addition to them being
0723      * specified in a HTML file.
0724      *
0725      * @param equiv The http header name (value of the meta tag's "equiv" attribute)
0726      * @param content The header value (value of the meta tag's "content" attribute)
0727      */
0728     void processHttpEquiv(const DOMString &equiv, const DOMString &content);
0729 
0730     void dispatchImageLoadEventSoon(HTMLImageElementImpl *);
0731     void dispatchImageLoadEventsNow();
0732     void removeImage(HTMLImageElementImpl *);
0733     void timerEvent(QTimerEvent *) override;
0734 
0735     // Returns the owning element in the parent document.
0736     // Returns 0 if this is the top level document.
0737     HTMLPartContainerElementImpl *ownerElement() const;
0738 
0739     khtml::SecurityOrigin *origin() const;
0740     void setOrigin(khtml::SecurityOrigin *);
0741 
0742     // These represent JS operations on domain strings, rather than full-blown origins.
0743     // (so no port, protocol, etc.)
0744     void setDomain(const DOMString &newDomain);
0745     DOMString domain() const;
0746 
0747     bool isURLAllowed(const QString &url) const;
0748 
0749     HTMLElementImpl *body() const;
0750 
0751     DOMString toString() const override;
0752 
0753     bool execCommand(const DOMString &command, bool userInterface, const DOMString &value);
0754     bool queryCommandEnabled(const DOMString &command);
0755     bool queryCommandIndeterm(const DOMString &command);
0756     bool queryCommandState(const DOMString &command);
0757     bool queryCommandSupported(const DOMString &command);
0758     DOMString queryCommandValue(const DOMString &command);
0759 
0760     // We version the tree to help determine which collection caches are
0761     // valid. All collections depend on the structural changes; and may depend
0762     // on some set of attributes.
0763     enum TreeVersion {
0764         TV_Structural,
0765         TV_IDNameHref,
0766         TV_Class,
0767         NumTreeVersions
0768     };
0769 
0770     void incDOMTreeVersion(unsigned ver)
0771     {
0772         ++m_domTreeVersions[ver];
0773     }
0774     unsigned int domTreeVersion(unsigned ver) const
0775     {
0776         return m_domTreeVersions[ver];
0777     }
0778 
0779     // Since applications often re-creat nodelists all over the place, we cache
0780     // their caches in the documents. For now, we only do it for things that can be
0781     // parametrices by type + base node.
0782     DynamicNodeListImpl::Cache *acquireCachedNodeListInfo(DynamicNodeListImpl::CacheFactory *fact,
0783             NodeImpl *base, int type);
0784     void releaseCachedNodeListInfo(DynamicNodeListImpl::Cache *cache);
0785 
0786     JSEditor *jsEditor();
0787 
0788     QHash<DOMString, khtml::CounterNode *> *counters(const khtml::RenderObject *o)
0789     {
0790         return m_counterDict.value(o);
0791     }
0792     void setCounters(const khtml::RenderObject *o, QHash<DOMString, khtml::CounterNode *> *dict)
0793     {
0794         m_counterDict.insert(o, dict);
0795     }
0796     void removeCounters(const khtml::RenderObject *o)
0797     {
0798         delete m_counterDict.take(o);
0799     }
0800 
0801     ElementMappingCache &underDocNamedCache()
0802     {
0803         return m_underDocNamedCache;
0804     }
0805 
0806     ElementMappingCache &getElementByIdCache() const
0807     {
0808         return m_getElementByIdCache;
0809     }
0810 
0811     DOMString contentLanguage() const
0812     {
0813         return m_contentLanguage;
0814     }
0815     void setContentLanguage(const QString &cl)
0816     {
0817         m_contentLanguage = cl;
0818     }
0819 
0820     khtml::DynamicDomRestyler &dynamicDomRestyler()
0821     {
0822         return *m_dynamicDomRestyler;
0823     }
0824     const khtml::DynamicDomRestyler &dynamicDomRestyler() const
0825     {
0826         return *m_dynamicDomRestyler;
0827     }
0828 
0829     // WebCore compatibility
0830     const WebCore::SVGDocumentExtensions *svgExtensions();
0831     WebCore::SVGDocumentExtensions *accessSVGExtensions();
0832 
0833 Q_SIGNALS:
0834     void finishedParsing();
0835 
0836 protected:
0837     khtml::CSSStyleSelector *m_styleSelector;
0838     KHTMLView *m_view;
0839     QStringList m_state;
0840     int         m_stateRestorePos;
0841 
0842     khtml::DocLoader *m_docLoader;
0843     khtml::Tokenizer *m_tokenizer;
0844     KEncodingDetector *m_decoder;
0845     QUrl m_url;
0846     QUrl m_baseURL;
0847     QString m_baseTarget;
0848 
0849     mutable DocumentTypeImpl *m_doctype;
0850 
0851     mutable DOMImplementationImpl *m_implementation; // lazily created
0852 
0853     QString m_usersheet;
0854     QString m_printSheet;
0855     QStringList m_availableSheets;
0856 
0857     DOMString m_contentLanguage;
0858 
0859     // Track the number of currently loading top-level stylesheets.  Sheets
0860     // loaded using the @import directive are not included in this count.
0861     // We use this count of pending sheets to detect when we can begin attaching
0862     // elements.
0863     int m_pendingStylesheets;
0864     bool m_ignorePendingStylesheets;
0865 
0866     CSSStyleSheetImpl *m_elemSheet;
0867 
0868     QPaintDevice *m_paintDevice;
0869     ParseMode pMode;
0870     HTMLMode hMode;
0871 
0872     QColor m_textColor;
0873     NodeImpl *m_hoverNode;
0874     NodeImpl *m_focusNode;
0875     NodeImpl *m_activeNode;
0876     NodeImpl *m_cssTarget;
0877 
0878     unsigned int m_domTreeVersions[NumTreeVersions];
0879 
0880     WebCore::SVGDocumentExtensions *m_svgExtensions;
0881 
0882     QList<NodeIteratorImpl *> m_nodeIterators;
0883     AbstractViewImpl *m_defaultView;
0884 
0885     unsigned short m_listenerTypes;
0886     StyleSheetListImpl *m_styleSheets;
0887     StyleSheetListImpl *m_addedStyleSheets; // programmatically added style sheets
0888     LocalStyleRefs m_localStyleRefs; // references to inlined style elements
0889     WindowEventTargetImpl *m_windowEventTarget;
0890     RegisteredListenerList m_windowEventListeners;
0891     QList<NodeImpl *> m_maintainsState;
0892 
0893     // ### evaluate for placement in RenderStyle
0894     QHash<const khtml::RenderObject *, QHash<DOMString, khtml::CounterNode *> *> m_counterDict;
0895 
0896     khtml::DynamicDomRestyler *m_dynamicDomRestyler;
0897 
0898     bool visuallyOrdered;
0899     bool m_bParsing;
0900     bool m_docChanged;
0901     bool m_styleSelectorDirty;
0902     bool m_inStyleRecalc;
0903     bool m_async;
0904     bool m_hadLoadError;
0905     bool m_docLoading;
0906     bool m_bVariableLength;
0907 
0908     QEventLoop *m_inSyncLoad;
0909 
0910     DOMString m_title;
0911     DOMString m_preferredStylesheetSet;
0912     khtml::CachedCSSStyleSheet *m_loadingXMLDoc;
0913 
0914     mutable ElementImpl *m_documentElement;
0915 
0916     //int m_decoderMibEnum;
0917 
0918     //Forms, images, etc., must be quickly accessible via document.name.
0919     ElementMappingCache m_underDocNamedCache;
0920 
0921     //Cache for nodelists and collections.
0922     QHash<long, DynamicNodeListImpl::Cache *> m_nodeListCache;
0923 
0924     QLinkedList<HTMLImageElementImpl *> m_imageLoadEventDispatchSoonList;
0925     QLinkedList<HTMLImageElementImpl *> m_imageLoadEventDispatchingList;
0926     int m_imageLoadEventTimer;
0927 
0928     //Cache for getElementById
0929     mutable ElementMappingCache m_getElementByIdCache;
0930 
0931     SharedPtr<khtml::RenderArena> m_renderArena;
0932 private:
0933     JSEditor *m_jsEditor;
0934     mutable RefPtr<khtml::SecurityOrigin> m_origin;
0935 
0936     int m_selfOnlyRefCount;
0937 public:
0938     // Nodes belonging to this document hold "self-only" references -
0939     // these are enough to keep the document from being destroyed, but
0940     // not enough to keep it from removing its children. This allows a
0941     // node that outlives its document to still have a valid document
0942     // pointer without introducing reference cycles
0943 
0944     void selfOnlyRef()
0945     {
0946         ++m_selfOnlyRefCount;
0947     }
0948     void selfOnlyDeref()
0949     {
0950         --m_selfOnlyRefCount;
0951         if (!m_selfOnlyRefCount && !refCount()) {
0952             delete this;
0953         }
0954     }
0955 
0956     // This is called when our last outside reference dies
0957     void removedLastRef() override;
0958 };
0959 
0960 /*
0961  * This represent the Window object at the DOM level --- for now it only plays
0962  * the role of an event dispatch target, and isn't accessible directly
0963  * (it turns into Window in JS land)
0964  */
0965 class WindowEventTargetImpl : public EventTargetImpl
0966 {
0967 public:
0968     WindowEventTargetImpl(DOM::DocumentImpl *owner);
0969 
0970     Type eventTargetType() const override;
0971     DocumentImpl *eventTargetDocument() override;
0972     KJS::Window *window();
0973 private:
0974     DOM::DocumentImpl *m_owner;
0975 };
0976 
0977 class DocumentFragmentImpl : public NodeBaseImpl
0978 {
0979 public:
0980     DocumentFragmentImpl(DocumentImpl *doc);
0981 
0982     // DOM methods overridden from  parent classes
0983     DOMString nodeName() const override;
0984     unsigned short nodeType() const override;
0985     WTF::PassRefPtr<NodeImpl> cloneNode(bool deep) override;
0986 
0987     // Other methods (not part of DOM)
0988     bool childTypeAllowed(unsigned short type) override;
0989 
0990     DOMString toString() const override;
0991 };
0992 
0993 class DocumentTypeImpl : public NodeImpl
0994 {
0995 public:
0996     DocumentTypeImpl(DOMImplementationImpl *_implementation, DocumentImpl *doc,
0997                      const DOMString &qualifiedName, const DOMString &publicId,
0998                      const DOMString &systemId);
0999     ~DocumentTypeImpl();
1000 
1001     // DOM methods & attributes for DocumentType
1002     NamedNodeMapImpl *entities() const;
1003     NamedNodeMapImpl *notations() const;
1004 
1005     DOMString name() const
1006     {
1007         return m_qualifiedName;
1008     }
1009     DOMString publicId() const
1010     {
1011         return m_publicId;
1012     }
1013     DOMString systemId() const
1014     {
1015         return m_systemId;
1016     }
1017     DOMString internalSubset() const
1018     {
1019         return m_subset;
1020     }
1021 
1022     // DOM methods overridden from  parent classes
1023     DOMString nodeName() const override;
1024     unsigned short nodeType() const override;
1025     bool childTypeAllowed(unsigned short type) override;
1026     WTF::PassRefPtr<NodeImpl> cloneNode(bool deep) override;
1027 
1028     // Other methods (not part of DOM)
1029     void setName(const DOMString &n)
1030     {
1031         m_qualifiedName = n;
1032     }
1033     void setPublicId(const DOMString &publicId)
1034     {
1035         m_publicId = publicId;
1036     }
1037     void setSystemId(const DOMString &systemId)
1038     {
1039         m_systemId = systemId;
1040     }
1041     void setInternalSubset(const DOMString &subset)
1042     {
1043         m_subset = subset;
1044     }
1045     DOMImplementationImpl *implementation() const
1046     {
1047         return m_implementation;
1048     }
1049 
1050     DOMString toString() const override;
1051 
1052 protected:
1053     DOMImplementationImpl *m_implementation;
1054     mutable NamedNodeMapImpl *m_entities;
1055     mutable NamedNodeMapImpl *m_notations;
1056 
1057     DOMString m_qualifiedName;
1058     DOMString m_publicId;
1059     DOMString m_systemId;
1060     DOMString m_subset;
1061 };
1062 
1063 class XMLDocumentImpl : public DocumentImpl
1064 {
1065 public:
1066     XMLDocumentImpl(KHTMLView *v) : DocumentImpl(v) { }
1067 
1068     void close() override;
1069 };
1070 
1071 } //namespace
1072 #endif