1 /*
2  * This file is part of the DOM implementation for KDE.
3  *
4  * Copyright (C) 1999 Lars Knoll (knoll@kde.org)
5  *           (C) 1999 Antti Koivisto (koivisto@kde.org)
6  *           (C) 2001 Dirk Mueller (mueller@kde.org)
7  *           (C) 2002-2003 Apple Computer, Inc.
8  *           (C) 2006 Allan Sandfeld Jensen(kde@carewolf.com)
9  *
10  * This library is free software; you can redistribute it and/or
11  * modify it under the terms of the GNU Library General Public
12  * License as published by the Free Software Foundation; either
13  * version 2 of the License, or (at your option) any later version.
14  *
15  * This library is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
18  * Library General Public License for more details.
19  *
20  * You should have received a copy of the GNU Library General Public License
21  * along with this library; see the file COPYING.LIB.  If not, write to
22  * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
23  * Boston, MA 02110-1301, USA.
24  *
25  */
26 
27 #ifndef _DOM_DocumentImpl_h_
28 #define _DOM_DocumentImpl_h_
29 
30 #include "xml/dom_elementimpl.h"
31 #include "xml/dom_nodelistimpl.h"
32 #include "xml/dom_textimpl.h"
33 #include "xml/dom2_traversalimpl.h"
34 #include "xml/security_origin.h"
35 #include "misc/shared.h"
36 #include "misc/loader.h"
37 #include "misc/seed.h"
38 
39 #include <QStringList>
40 #include <QObject>
41 #include <QList>
42 #include <QHash>
43 #include <QMap>
44 #include <QUrl>
45 
46 //Added by qt3to4:
47 #include <QTimerEvent>
48 
49 class QPaintDevice;
50 class QTextCodec;
51 class KHTMLView;
52 class QEventLoop;
53 class KEncodingDetector;
54 
55 namespace khtml
56 {
57 class Tokenizer;
58 class CSSStyleSelector;
59 class DocLoader;
60 class RenderArena;
61 class EditCommand;
62 class RenderObject;
63 class CounterNode;
64 class CachedObject;
65 class CachedCSSStyleSheet;
66 class DynamicDomRestyler;
67 
68 class XPathResultImpl;
69 class XPathExpressionImpl;
70 class XPathNSResolverImpl;
71 }
72 
73 namespace KJS
74 {
75 class Window;
76 }
77 
78 namespace WebCore
79 {
80 class SVGDocumentExtensions;
81 class SVGDocument;
82 } // namespace WebCore
83 
84 namespace DOM
85 {
86 
87 class AbstractViewImpl;
88 class AttrImpl;
89 class CDATASectionImpl;
90 class CSSStyleSheetImpl;
91 class CommentImpl;
92 class DocumentFragmentImpl;
93 class DocumentImpl;
94 class XMLDocumentImpl;
95 class DocumentType;
96 class DocumentTypeImpl;
97 class EditingTextImpl;
98 class ElementImpl;
99 class EntityReferenceImpl;
100 class EventImpl;
101 class EventListener;
102 class HTMLDocumentImpl;
103 class HTMLElementImpl;
104 class HTMLPartContainerElementImpl;
105 class HTMLImageElementImpl;
106 class JSEditor;
107 class NodeFilter;
108 class NodeFilterImpl;
109 class NodeIteratorImpl;
110 class NodeListImpl;
111 class ProcessingInstructionImpl;
112 class RangeImpl;
113 class StyleSheetImpl;
114 class StyleSheetListImpl;
115 class TextImpl;
116 class TreeWalkerImpl;
117 class WindowEventTargetImpl;
118 
119 class DOMImplementationImpl : public khtml::Shared<DOMImplementationImpl>
120 {
121 public:
122     DOMImplementationImpl();
123     ~DOMImplementationImpl();
124 
125     // DOM methods & attributes for DOMImplementation.
126     static bool hasFeature(const DOMString &feature, const DOMString &version);
127     DocumentTypeImpl *createDocumentType(const DOMString &qualifiedName, const DOMString &publicId,
128                                          const DOMString &systemId, int &exceptioncode);
129     static DocumentImpl *createDocument(const DOMString &namespaceURI, const DOMString &qualifiedName,
130                                         DocumentTypeImpl *dtype,
131                                         KHTMLView *v, int &exceptioncode);
132 
133     // From the DOMImplementationCSS interface
134     static CSSStyleSheetImpl *createCSSStyleSheet(DOMStringImpl *title, DOMStringImpl *media, int &exceptioncode);
135 
136     // From the HTMLDOMImplementation interface
137     static HTMLDocumentImpl *createHTMLDocument(const DOMString &title);
138 
139     // Other methods (not part of DOM)
140     static DocumentImpl *createDocument(KHTMLView *v = nullptr);
141     static XMLDocumentImpl *createXMLDocument(KHTMLView *v = nullptr);
142     static HTMLDocumentImpl *createHTMLDocument(KHTMLView *v = nullptr);
143     static WebCore::SVGDocument *createSVGDocument(KHTMLView *v = nullptr);
144 };
145 
146 /**
147  * @internal A cache of element name (or id) to pointer
148  */
149 // TODO: QHash: better to store values here
150 class ElementMappingCache
151 {
152 public:
153     /**
154      For each name, we hold a reference count, and a
155      pointer. If the item is in the table, which implies
156      reference count is > 1, the name is a valid key.
157      If the pointer is non-null, it points to the appropriate
158      mapping
159     */
160     struct ItemInfo {
161         int       ref;
162         ElementImpl *nd;
163     };
164 
165     ElementMappingCache();
166     ~ElementMappingCache();
167 
168     /**
169      Add a pointer as just one of candidates, not neccesserily the proper one
170     */
171     void add(const DOMString &id, ElementImpl *nd);
172 
173     /**
174      Set the pointer as the definite mapping; it must have already been added
175     */
176     void set(const DOMString &id, ElementImpl *nd);
177 
178     /**
179      Remove the item; it must have already been added.
180     */
181     void remove(const DOMString &id, ElementImpl *nd);
182 
183     /**
184      Returns true if the item exists
185     */
186     bool contains(const DOMString &id);
187 
188     /**
189      Returns the information for the given ID
190     */
191     ItemInfo *get(const DOMString &id);
192 private:
193     QHash<DOMString, ItemInfo *> m_dict;
194 };
195 
196 /**
197  * @internal
198  */
199 class DocumentImpl : public QObject, private khtml::CachedObjectClient, public NodeBaseImpl
200 {
201     Q_OBJECT
202 public:
203     DocumentImpl(KHTMLView *v);
204     ~DocumentImpl();
205 
206     // DOM methods & attributes for Document
207 
208     DocumentTypeImpl *doctype() const;
209 
210     DOMImplementationImpl *implementation() const;
211     ElementImpl *documentElement() const;
212     void childrenChanged() override;
213     virtual ElementImpl *createElement(const DOMString &tagName, int *pExceptioncode = nullptr);
214     virtual AttrImpl *createAttribute(const DOMString &tagName, int *pExceptioncode = nullptr);
215     DocumentFragmentImpl *createDocumentFragment();
createTextNode(DOMStringImpl * data)216     TextImpl *createTextNode(DOMStringImpl *data)
217     {
218         return new TextImpl(docPtr(), data);
219     }
createTextNode(const QString & data)220     TextImpl *createTextNode(const QString &data)
221     {
222         return createTextNode(new DOMStringImpl(data.unicode(), data.length()));
223     }
createTextNode(const DOMString & data)224     TextImpl *createTextNode(const DOMString &data)
225     {
226         return createTextNode(data.implementation());
227     }
createTextNode(const char * latin1)228     TextImpl *createTextNode(const char *latin1)
229     {
230         return createTextNode(DOMString(latin1));
231     }
232     CommentImpl *createComment(DOMStringImpl *data);
233     CDATASectionImpl *createCDATASection(DOMStringImpl *data, int &exceptioncode);
234     ProcessingInstructionImpl *createProcessingInstruction(const DOMString &target, DOMStringImpl *data);
235     EntityReferenceImpl *createEntityReference(const DOMString &name, int &exceptioncode);
236     NodeImpl *importNode(NodeImpl *importedNode, bool deep, int &exceptioncode);
237     virtual ElementImpl *createElementNS(const DOMString &_namespaceURI, const DOMString &_qualifiedName,
238                                          int *pExceptioncode = nullptr);
239     virtual AttrImpl *createAttributeNS(const DOMString &_namespaceURI, const DOMString &_qualifiedName,
240                                         int *pExceptioncode = nullptr);
241     ElementImpl *getElementById(const DOMString &elementId) const;
242 
243     // DOM3 XPath, from XPathEvaluator interface
244     khtml::XPathExpressionImpl *createExpression(DOM::DOMString &expression,
245             khtml::XPathNSResolverImpl *resolver,
246             int &exceptioncode);
247     khtml::XPathNSResolverImpl *createNSResolver(NodeImpl *nodeResolver);
248     khtml::XPathResultImpl *evaluate(DOM::DOMString &expression,
249                                      NodeImpl *contextNode,
250                                      khtml::XPathNSResolverImpl *resolver,
251                                      unsigned short type,
252                                      khtml::XPathResultImpl *result,
253                                      int &exceptioncode);
254 
255     // Actually part of HTMLDocument, but used for giving XML documents a window title as well
title()256     DOMString title() const
257     {
258         return m_title;
259     }
260     void setTitle(const DOMString &_title);
261 
262     // DOM methods overridden from  parent classes
263 
264     DOMString nodeName() const override;
265     unsigned short nodeType() const override;
266 
267     // Other methods (not part of DOM)
isDocumentNode()268     bool isDocumentNode() const override
269     {
270         return true;
271     }
isHTMLDocument()272     virtual bool isHTMLDocument() const
273     {
274         return false;
275     }
276     virtual bool isSVGDocument() const;
277 
278     virtual ElementImpl *createHTMLElement(const DOMString &tagName, bool caseInsensitive = true);
279     // SVG
280     virtual ElementImpl *createSVGElement(const QualifiedName &name);
281 
styleSelector()282     khtml::CSSStyleSelector *styleSelector()
283     {
284         return m_styleSelector;
285     }
286 
287     /**
288     * Updates the pending sheet count and then calls updateStyleSelector.
289     */
290     void styleSheetLoaded();
291 
292     /**
293      * This method returns true if all top-level stylesheets have loaded (including
294      * any \@imports that they may be loading).
295      */
haveStylesheetsLoaded()296     bool haveStylesheetsLoaded() const
297     {
298         return m_pendingStylesheets <= 0 || m_ignorePendingStylesheets;
299     }
300 
301     /**
302      * Increments the number of pending sheets.  The \<link\> elements
303      * invoke this to add themselves to the loading list.
304      */
305     void addPendingSheet();
306 
307     /**
308      * Returns true if the document has pending stylesheets
309      * loading.
310      */
hasPendingSheets()311     bool hasPendingSheets() const
312     {
313         return m_pendingStylesheets;
314     }
315 
316     /**
317      * Called when one or more stylesheets in the document may have been added, removed or changed.
318      *
319      * Creates a new style selector and assign it to this document. This is done by iterating through all nodes in
320      * document (or those before \<BODY\> in a HTML document), searching for stylesheets. Stylesheets can be contained in
321      * \<LINK\>, \<STYLE\> or \<BODY\> elements, as well as processing instructions (XML documents only). A list is
322      * constructed from these which is used to create the a new style selector which collates all of the stylesheets
323      * found and is used to calculate the derived styles for all rendering objects.
324      *
325      * @param shallow If the stylesheet list for the document is unchanged, with only added or removed rules
326      * in existing sheets, then set this argument to true for efficiency.
327      */
328     void updateStyleSelector(bool shallow = false);
329 
ensureStyleSheetListUpToDate()330     void ensureStyleSheetListUpToDate()
331     {
332         if (m_styleSheetListDirty) {
333             rebuildStyleSheetList(true);
334         }
335     }
336 
337     bool readyForLayout() const;
338 
339     // DOM representation of the JS Window object, for event handling
windowEventTarget()340     WindowEventTargetImpl *windowEventTarget() const
341     {
342         return m_windowEventTarget;
343     }
344 private:
345     void rebuildStyleSheetList(bool force = false);
346     void rebuildStyleSelector();
347     bool m_styleSheetListDirty;
348 public:
349 
350     // Tries to restore the elements value from the doc state,
351     // if it seems like the same thing
352     void attemptRestoreState(NodeImpl *e);
353 
354     // Query all registered elements for their state
355     QStringList docState();
356     bool unsubmittedFormChanges();
registerMaintainsState(NodeImpl * e)357     void registerMaintainsState(NodeImpl *e)
358     {
359         m_maintainsState.append(e);
360     }
deregisterMaintainsState(NodeImpl * e)361     void deregisterMaintainsState(NodeImpl *e)
362     {
363         int i;
364         if ((i = m_maintainsState.indexOf(e)) != -1) {
365             m_maintainsState.removeAt(i);
366         }
367     }
368 
369     // Set the state the document should restore to
370     void setRestoreState(const QStringList &s);
371 
372     KHTMLView *view() const;
373     KHTMLPart *part() const;
374 
375     RangeImpl *createRange();
376 
377     NodeIteratorImpl *createNodeIterator(NodeImpl *root, unsigned long whatToShow,
378                                          NodeFilterImpl *filter, bool entityReferenceExpansion, int &exceptioncode);
379 
380     TreeWalkerImpl *createTreeWalker(NodeImpl *root, unsigned long whatToShow, NodeFilterImpl *filter,
381                                      bool entityReferenceExpansion, int &exceptioncode);
382 
383     EditingTextImpl *createEditingTextNode(const DOMString &text);
384 
385     void recalcStyle(StyleChange = NoChange) override;
386     virtual void updateRendering();
387     void updateLayout();
388     static void updateDocumentsRendering();
docLoader()389     khtml::DocLoader *docLoader()
390     {
391         return m_docLoader;
392     }
393 
394     void attach() override;
395     void detach() override;
396 
renderArena()397     khtml::RenderArena *renderArena()
398     {
399         return m_renderArena.get();
400     }
401 
402     // to get visually ordered hebrew and arabic pages right
403     void setVisuallyOrdered();
404     // to get URL decoding right
405     //void setDecoderCodec(const QTextCodec *codec);
406 
407     // ### elide the two after designMode merge
408     void setSelection(NodeImpl *s, int sp, NodeImpl *e, int ep);
409     void clearSelection();
410     void updateSelection();
411 
412     void open(bool clearEventListeners = true);
413     void close() override;
contentLoaded()414     virtual void contentLoaded() {}
415     void write(const DOMString &text);
416     void write(const QString &text);
417     void writeln(const DOMString &text);
418     void finishParsing();
419 
URL()420     QUrl URL() const
421     {
422         return m_url;
423     }
setURL(const QString & url)424     void setURL(const QString &url)
425     {
426         m_url = QUrl(url);
427     }
428 
baseURL()429     QUrl baseURL() const
430     {
431         return m_baseURL.isEmpty() ? m_url : m_baseURL;
432     }
433     void setBaseURL(const QUrl &baseURL);
434 
baseTarget()435     QString baseTarget() const
436     {
437         return m_baseTarget;
438     }
setBaseTarget(const QString & baseTarget)439     void setBaseTarget(const QString &baseTarget)
440     {
441         m_baseTarget = baseTarget;
442     }
443 
444     QString completeURL(const QString &url) const;
canonURL(const DOMString & url)445     DOMString canonURL(const DOMString &url) const
446     {
447         return url.isEmpty() ? url : completeURL(url.string());
448     }
449 
450     void setUserStyleSheet(const QString &sheet);
userStyleSheet()451     QString userStyleSheet() const
452     {
453         return m_usersheet;
454     }
setPrintStyleSheet(const QString & sheet)455     void setPrintStyleSheet(const QString &sheet)
456     {
457         m_printSheet = sheet;
458     }
printStyleSheet()459     QString printStyleSheet() const
460     {
461         return m_printSheet;
462     }
463 
464     CSSStyleSheetImpl *elementSheet();
465     virtual khtml::Tokenizer *createTokenizer();
tokenizer()466     khtml::Tokenizer *tokenizer()
467     {
468         return m_tokenizer;
469     }
decoder()470     KEncodingDetector *decoder()
471     {
472         return m_decoder;
473     }
setDecoder(KEncodingDetector * enc)474     void setDecoder(KEncodingDetector *enc)
475     {
476         m_decoder = enc;
477     }
478 
setPaintDevice(QPaintDevice * dev)479     void setPaintDevice(QPaintDevice *dev)
480     {
481         m_paintDevice = dev;
482     }
paintDevice()483     QPaintDevice *paintDevice() const
484     {
485         return m_paintDevice;
486     }
487     int logicalDpiY();
488 
489     enum HTMLMode {
490         Html3 = 0,
491         Html4 = 1,
492         XHtml = 2
493     };
494 
495     enum ParseMode {
496         Unknown,
497         Compat,
498         Transitional,
499         Strict
500     };
501     virtual void determineParseMode();
setParseMode(ParseMode m)502     void setParseMode(ParseMode m)
503     {
504         pMode = m;
505     }
parseMode()506     ParseMode parseMode() const
507     {
508         return pMode;
509     }
510 
inCompatMode()511     bool inCompatMode() const
512     {
513         return pMode == Compat;
514     }
inTransitionalMode()515     bool inTransitionalMode() const
516     {
517         return pMode == Transitional;
518     }
inStrictMode()519     bool inStrictMode() const
520     {
521         return pMode == Strict;
522     }
523 
524     //void setHTMLMode( HTMLMode m ) { hMode = m; }
htmlMode()525     HTMLMode htmlMode() const
526     {
527         return hMode;
528     }
529 
setParsing(bool b)530     void setParsing(bool b)
531     {
532         m_bParsing = b;
533     }
parsing()534     bool parsing() const
535     {
536         return m_bParsing;
537     }
538 
539     void setHasVariableLength(bool b = true)
540     {
541         m_bVariableLength = b;
542     }
hasVariableLength()543     bool hasVariableLength() const
544     {
545         return m_bVariableLength;
546     }
547 
setTextColor(QColor color)548     void setTextColor(QColor color)
549     {
550         m_textColor = color;
551     }
textColor()552     QColor textColor() const
553     {
554         return m_textColor;
555     }
556 
557     void setDesignMode(bool b);
558     bool designMode() const;
559 
560     // internal
561     bool prepareMouseEvent(bool readonly, int x, int y, MouseEvent *ev);
562 
563     bool childTypeAllowed(unsigned short nodeType) override;
564     WTF::PassRefPtr<NodeImpl> cloneNode(bool deep) override;
565 
styleSheets()566     StyleSheetListImpl *styleSheets()
567     {
568         return m_styleSheets;
569     }
570 
preferredStylesheetSet()571     DOMString preferredStylesheetSet() const
572     {
573         return m_preferredStylesheetSet;
574     }
575     DOMString selectedStylesheetSet() const;
576     void setSelectedStylesheetSet(const DOMString &);
setPreferredStylesheetSet(const DOMString & s)577     void setPreferredStylesheetSet(const DOMString &s)
578     {
579         m_preferredStylesheetSet = s;
580     }
581 
582     void addStyleSheet(StyleSheetImpl *, int *exceptioncode = nullptr);
583     void removeStyleSheet(StyleSheetImpl *, int *exceptioncode = nullptr);
584 
availableStyleSheets()585     QStringList availableStyleSheets() const
586     {
587         return m_availableSheets;
588     }
589 
hoverNode()590     NodeImpl *hoverNode() const
591     {
592         return m_hoverNode;
593     }
594     void setHoverNode(NodeImpl *newHoverNode);
focusNode()595     NodeImpl *focusNode() const
596     {
597         return m_focusNode;
598     }
599     void quietResetFocus(); // Removes focus from active node without attempting to emit any events
600     void setFocusNode(NodeImpl *newFocusNode);
activeNode()601     NodeImpl *activeNode() const
602     {
603         return m_activeNode;
604     }
605     void setActiveNode(NodeImpl *newActiveNode);
606 
607     // Updates for :target (CSS3 selector).
608     void setCSSTarget(NodeImpl *n);
getCSSTarget()609     NodeImpl *getCSSTarget()
610     {
611         return m_cssTarget;
612     }
613 
isDocumentChanged()614     bool isDocumentChanged()
615     {
616         return m_docChanged;
617     }
618     virtual void setDocumentChanged(bool = true);
619     void attachNodeIterator(NodeIteratorImpl *ni);
620     void detachNodeIterator(NodeIteratorImpl *ni);
621     void notifyBeforeNodeRemoval(NodeImpl *n);
defaultView()622     AbstractViewImpl *defaultView() const
623     {
624         return m_defaultView;
625     }
626     EventImpl *createEvent(const DOMString &eventType, int &exceptioncode);
627 
628     // keep track of what types of event listeners are registered, so we don't
629     // dispatch events unnecessarily
630     enum ListenerType {
631         DOMSUBTREEMODIFIED_LISTENER          = 0x01,
632         DOMNODEINSERTED_LISTENER             = 0x02,
633         DOMNODEREMOVED_LISTENER              = 0x04,
634         DOMNODEREMOVEDFROMDOCUMENT_LISTENER  = 0x08,
635         DOMNODEINSERTEDINTODOCUMENT_LISTENER = 0x10,
636         DOMATTRMODIFIED_LISTENER             = 0x20,
637         DOMCHARACTERDATAMODIFIED_LISTENER    = 0x40
638     };
639 
hasListenerType(ListenerType listenerType)640     bool hasListenerType(ListenerType listenerType) const
641     {
642         return (m_listenerTypes & listenerType);
643     }
addListenerType(ListenerType listenerType)644     void addListenerType(ListenerType listenerType)
645     {
646         m_listenerTypes = m_listenerTypes | listenerType;
647     }
648 
649     CSSStyleDeclarationImpl *getOverrideStyle(ElementImpl *elt, DOMStringImpl *pseudoElt);
650 
async()651     bool async() const
652     {
653         return m_async;
654     }
setAsync(bool b)655     void setAsync(bool b)
656     {
657         m_async = b;
658     }
659     void abort();
660     void load(const DOMString &uri);
661     void loadXML(const DOMString &source);
662     // from cachedObjectClient
663     void setStyleSheet(const DOM::DOMString &url, const DOM::DOMString &sheet, const DOM::DOMString &charset, const DOM::DOMString &mimetype) override;
664     void error(int err, const QString &text) override;
665 
666     typedef QMap<QString, ProcessingInstructionImpl *> LocalStyleRefs;
localStyleRefs()667     LocalStyleRefs *localStyleRefs()
668     {
669         return &m_localStyleRefs;
670     }
671 
672     void defaultEventHandler(EventImpl *evt) override;
673 
674     void setHTMLWindowEventListener(EventName id, EventListener *listener);
675     void setHTMLWindowEventListener(unsigned id, EventListener *listener);
676 
677     EventListener *getHTMLWindowEventListener(EventName id);
678     EventListener *getHTMLWindowEventListener(unsigned id);
679 
680     EventListener *createHTMLEventListener(const QString &code, const QString &name, NodeImpl *node);
681 
682     void addWindowEventListener(EventName id, EventListener *listener, const bool useCapture);
683     void removeWindowEventListener(EventName id, EventListener *listener, bool useCapture);
684     bool hasWindowEventListener(EventName id);
685 
686     EventListener *createHTMLEventListener(QString code);
687 
688     /**
689      * Searches through the document, starting from fromNode, for the next selectable element that comes after fromNode.
690      * The order followed is as specified in section 17.11.1 of the HTML4 spec, which is elements with tab indexes
691      * first (from lowest to highest), and then elements without tab indexes (in document order).
692      *
693      * @param fromNode The node from which to start searching. The node after this will be focused. May be null.
694      *
695      * @return The focus node that comes after fromNode
696      *
697      * See https://www.w3.org/TR/html4/interact/forms.html#h-17.11.1
698      */
699     NodeImpl *nextFocusNode(NodeImpl *fromNode);
700 
701     /**
702      * Searches through the document, starting from fromNode, for the previous selectable element (that comes _before_)
703      * fromNode. The order followed is as specified in section 17.11.1 of the HTML4 spec, which is elements with tab
704      * indexes first (from lowest to highest), and then elements without tab indexes (in document order).
705      *
706      * @param fromNode The node from which to start searching. The node before this will be focused. May be null.
707      *
708      * @return The focus node that comes before fromNode
709      *
710      * See https://www.w3.org/TR/html4/interact/forms.html#h-17.11.1
711      */
712     NodeImpl *previousFocusNode(NodeImpl *fromNode);
713 
714     ElementImpl *findAccessKeyElement(QChar c);
715 
716     int nodeAbsIndex(NodeImpl *node);
717     NodeImpl *nodeWithAbsIndex(int absIndex);
718 
719     /**
720      * Handles a HTTP header equivalent set by a meta tag using <meta http-equiv="..." content="...">. This is called
721      * when a meta tag is encountered during document parsing, and also when a script dynamically changes or adds a meta
722      * tag. This enables scripts to use meta tags to perform refreshes and set expiry dates in addition to them being
723      * specified in a HTML file.
724      *
725      * @param equiv The http header name (value of the meta tag's "equiv" attribute)
726      * @param content The header value (value of the meta tag's "content" attribute)
727      */
728     void processHttpEquiv(const DOMString &equiv, const DOMString &content);
729 
730     void dispatchImageLoadEventSoon(HTMLImageElementImpl *);
731     void dispatchImageLoadEventsNow();
732     void removeImage(HTMLImageElementImpl *);
733     void timerEvent(QTimerEvent *) override;
734 
735     // Returns the owning element in the parent document.
736     // Returns 0 if this is the top level document.
737     HTMLPartContainerElementImpl *ownerElement() const;
738 
739     khtml::SecurityOrigin *origin() const;
740     void setOrigin(khtml::SecurityOrigin *);
741 
742     // These represent JS operations on domain strings, rather than full-blown origins.
743     // (so no port, protocol, etc.)
744     void setDomain(const DOMString &newDomain);
745     DOMString domain() const;
746 
747     bool isURLAllowed(const QString &url) const;
748 
749     HTMLElementImpl *body() const;
750 
751     DOMString toString() const override;
752 
753     bool execCommand(const DOMString &command, bool userInterface, const DOMString &value);
754     bool queryCommandEnabled(const DOMString &command);
755     bool queryCommandIndeterm(const DOMString &command);
756     bool queryCommandState(const DOMString &command);
757     bool queryCommandSupported(const DOMString &command);
758     DOMString queryCommandValue(const DOMString &command);
759 
760     // We version the tree to help determine which collection caches are
761     // valid. All collections depend on the structural changes; and may depend
762     // on some set of attributes.
763     enum TreeVersion {
764         TV_Structural,
765         TV_IDNameHref,
766         TV_Class,
767         NumTreeVersions
768     };
769 
incDOMTreeVersion(unsigned ver)770     void incDOMTreeVersion(unsigned ver)
771     {
772         ++m_domTreeVersions[ver];
773     }
domTreeVersion(unsigned ver)774     unsigned int domTreeVersion(unsigned ver) const
775     {
776         return m_domTreeVersions[ver];
777     }
778 
779     // Since applications often re-creat nodelists all over the place, we cache
780     // their caches in the documents. For now, we only do it for things that can be
781     // parametrices by type + base node.
782     DynamicNodeListImpl::Cache *acquireCachedNodeListInfo(DynamicNodeListImpl::CacheFactory *fact,
783             NodeImpl *base, int type);
784     void releaseCachedNodeListInfo(DynamicNodeListImpl::Cache *cache);
785 
786     JSEditor *jsEditor();
787 
counters(const khtml::RenderObject * o)788     QHash<DOMString, khtml::CounterNode *> *counters(const khtml::RenderObject *o)
789     {
790         return m_counterDict.value(o);
791     }
setCounters(const khtml::RenderObject * o,QHash<DOMString,khtml::CounterNode * > * dict)792     void setCounters(const khtml::RenderObject *o, QHash<DOMString, khtml::CounterNode *> *dict)
793     {
794         m_counterDict.insert(o, dict);
795     }
removeCounters(const khtml::RenderObject * o)796     void removeCounters(const khtml::RenderObject *o)
797     {
798         delete m_counterDict.take(o);
799     }
800 
underDocNamedCache()801     ElementMappingCache &underDocNamedCache()
802     {
803         return m_underDocNamedCache;
804     }
805 
getElementByIdCache()806     ElementMappingCache &getElementByIdCache() const
807     {
808         return m_getElementByIdCache;
809     }
810 
contentLanguage()811     DOMString contentLanguage() const
812     {
813         return m_contentLanguage;
814     }
setContentLanguage(const QString & cl)815     void setContentLanguage(const QString &cl)
816     {
817         m_contentLanguage = cl;
818     }
819 
dynamicDomRestyler()820     khtml::DynamicDomRestyler &dynamicDomRestyler()
821     {
822         return *m_dynamicDomRestyler;
823     }
dynamicDomRestyler()824     const khtml::DynamicDomRestyler &dynamicDomRestyler() const
825     {
826         return *m_dynamicDomRestyler;
827     }
828 
829     // WebCore compatibility
830     const WebCore::SVGDocumentExtensions *svgExtensions();
831     WebCore::SVGDocumentExtensions *accessSVGExtensions();
832 
833 Q_SIGNALS:
834     void finishedParsing();
835 
836 protected:
837     khtml::CSSStyleSelector *m_styleSelector;
838     KHTMLView *m_view;
839     QStringList m_state;
840     int         m_stateRestorePos;
841 
842     khtml::DocLoader *m_docLoader;
843     khtml::Tokenizer *m_tokenizer;
844     KEncodingDetector *m_decoder;
845     QUrl m_url;
846     QUrl m_baseURL;
847     QString m_baseTarget;
848 
849     mutable DocumentTypeImpl *m_doctype;
850 
851     mutable DOMImplementationImpl *m_implementation; // lazily created
852 
853     QString m_usersheet;
854     QString m_printSheet;
855     QStringList m_availableSheets;
856 
857     DOMString m_contentLanguage;
858 
859     // Track the number of currently loading top-level stylesheets.  Sheets
860     // loaded using the @import directive are not included in this count.
861     // We use this count of pending sheets to detect when we can begin attaching
862     // elements.
863     int m_pendingStylesheets;
864     bool m_ignorePendingStylesheets;
865 
866     CSSStyleSheetImpl *m_elemSheet;
867 
868     QPaintDevice *m_paintDevice;
869     ParseMode pMode;
870     HTMLMode hMode;
871 
872     QColor m_textColor;
873     NodeImpl *m_hoverNode;
874     NodeImpl *m_focusNode;
875     NodeImpl *m_activeNode;
876     NodeImpl *m_cssTarget;
877 
878     unsigned int m_domTreeVersions[NumTreeVersions];
879 
880     WebCore::SVGDocumentExtensions *m_svgExtensions;
881 
882     QList<NodeIteratorImpl *> m_nodeIterators;
883     AbstractViewImpl *m_defaultView;
884 
885     unsigned short m_listenerTypes;
886     StyleSheetListImpl *m_styleSheets;
887     StyleSheetListImpl *m_addedStyleSheets; // programmatically added style sheets
888     LocalStyleRefs m_localStyleRefs; // references to inlined style elements
889     WindowEventTargetImpl *m_windowEventTarget;
890     RegisteredListenerList m_windowEventListeners;
891     QList<NodeImpl *> m_maintainsState;
892 
893     // ### evaluate for placement in RenderStyle
894     QHash<const khtml::RenderObject *, QHash<DOMString, khtml::CounterNode *> *> m_counterDict;
895 
896     khtml::DynamicDomRestyler *m_dynamicDomRestyler;
897 
898     bool visuallyOrdered;
899     bool m_bParsing;
900     bool m_docChanged;
901     bool m_styleSelectorDirty;
902     bool m_inStyleRecalc;
903     bool m_async;
904     bool m_hadLoadError;
905     bool m_docLoading;
906     bool m_bVariableLength;
907 
908     QEventLoop *m_inSyncLoad;
909 
910     DOMString m_title;
911     DOMString m_preferredStylesheetSet;
912     khtml::CachedCSSStyleSheet *m_loadingXMLDoc;
913 
914     mutable ElementImpl *m_documentElement;
915 
916     //int m_decoderMibEnum;
917 
918     //Forms, images, etc., must be quickly accessible via document.name.
919     ElementMappingCache m_underDocNamedCache;
920 
921     //Cache for nodelists and collections.
922     QHash<long, DynamicNodeListImpl::Cache *> m_nodeListCache;
923 
924     QLinkedList<HTMLImageElementImpl *> m_imageLoadEventDispatchSoonList;
925     QLinkedList<HTMLImageElementImpl *> m_imageLoadEventDispatchingList;
926     int m_imageLoadEventTimer;
927 
928     //Cache for getElementById
929     mutable ElementMappingCache m_getElementByIdCache;
930 
931     SharedPtr<khtml::RenderArena> m_renderArena;
932 private:
933     JSEditor *m_jsEditor;
934     mutable RefPtr<khtml::SecurityOrigin> m_origin;
935 
936     int m_selfOnlyRefCount;
937 public:
938     // Nodes belonging to this document hold "self-only" references -
939     // these are enough to keep the document from being destroyed, but
940     // not enough to keep it from removing its children. This allows a
941     // node that outlives its document to still have a valid document
942     // pointer without introducing reference cycles
943 
selfOnlyRef()944     void selfOnlyRef()
945     {
946         ++m_selfOnlyRefCount;
947     }
selfOnlyDeref()948     void selfOnlyDeref()
949     {
950         --m_selfOnlyRefCount;
951         if (!m_selfOnlyRefCount && !refCount()) {
952             delete this;
953         }
954     }
955 
956     // This is called when our last outside reference dies
957     void removedLastRef() override;
958 };
959 
960 /*
961  * This represent the Window object at the DOM level --- for now it only plays
962  * the role of an event dispatch target, and isn't accessible directly
963  * (it turns into Window in JS land)
964  */
965 class WindowEventTargetImpl : public EventTargetImpl
966 {
967 public:
968     WindowEventTargetImpl(DOM::DocumentImpl *owner);
969 
970     Type eventTargetType() const override;
971     DocumentImpl *eventTargetDocument() override;
972     KJS::Window *window();
973 private:
974     DOM::DocumentImpl *m_owner;
975 };
976 
977 class DocumentFragmentImpl : public NodeBaseImpl
978 {
979 public:
980     DocumentFragmentImpl(DocumentImpl *doc);
981 
982     // DOM methods overridden from  parent classes
983     DOMString nodeName() const override;
984     unsigned short nodeType() const override;
985     WTF::PassRefPtr<NodeImpl> cloneNode(bool deep) override;
986 
987     // Other methods (not part of DOM)
988     bool childTypeAllowed(unsigned short type) override;
989 
990     DOMString toString() const override;
991 };
992 
993 class DocumentTypeImpl : public NodeImpl
994 {
995 public:
996     DocumentTypeImpl(DOMImplementationImpl *_implementation, DocumentImpl *doc,
997                      const DOMString &qualifiedName, const DOMString &publicId,
998                      const DOMString &systemId);
999     ~DocumentTypeImpl();
1000 
1001     // DOM methods & attributes for DocumentType
1002     NamedNodeMapImpl *entities() const;
1003     NamedNodeMapImpl *notations() const;
1004 
name()1005     DOMString name() const
1006     {
1007         return m_qualifiedName;
1008     }
publicId()1009     DOMString publicId() const
1010     {
1011         return m_publicId;
1012     }
systemId()1013     DOMString systemId() const
1014     {
1015         return m_systemId;
1016     }
internalSubset()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)
setName(const DOMString & n)1029     void setName(const DOMString &n)
1030     {
1031         m_qualifiedName = n;
1032     }
setPublicId(const DOMString & publicId)1033     void setPublicId(const DOMString &publicId)
1034     {
1035         m_publicId = publicId;
1036     }
setSystemId(const DOMString & systemId)1037     void setSystemId(const DOMString &systemId)
1038     {
1039         m_systemId = systemId;
1040     }
setInternalSubset(const DOMString & subset)1041     void setInternalSubset(const DOMString &subset)
1042     {
1043         m_subset = subset;
1044     }
implementation()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:
XMLDocumentImpl(KHTMLView * v)1066     XMLDocumentImpl(KHTMLView *v) : DocumentImpl(v) { }
1067 
1068     void close() override;
1069 };
1070 
1071 } //namespace
1072 #endif
1073