File indexing completed on 2024-04-28 15:23:19

0001 /*
0002  *  This file is part of the KDE libraries
0003  *  Copyright (C) 2000 Harri Porten (porten@kde.org)
0004  *  Copyright (C) 2003 Apple Computer, Inc.
0005  *
0006  *  This library is free software; you can redistribute it and/or
0007  *  modify it under the terms of the GNU Library General Public
0008  *  License as published by the Free Software Foundation; either
0009  *  version 2 of the License, or (at your option) any later version.
0010  *
0011  *  This library is distributed in the hope that it will be useful,
0012  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
0013  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
0014  *  Library General Public License for more details.
0015  *
0016  *  You should have received a copy of the GNU Library General Public
0017  *  License along with this library; if not, write to the Free Software
0018  *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
0019  */
0020 
0021 #ifndef _KJS_WINDOW_H_
0022 #define _KJS_WINDOW_H_
0023 
0024 #include <QObject>
0025 #include <QPointer>
0026 #include <QMap>
0027 #include <QList>
0028 #include <QDate>
0029 
0030 #include "khtmlpart_p.h"
0031 #include "kjs_binding.h"
0032 #include "kjs_views.h"
0033 
0034 class QTimer;
0035 class KHTMLView;
0036 class KHTMLPart;
0037 
0038 namespace KParts
0039 {
0040 class ReadOnlyPart;
0041 }
0042 
0043 namespace khtml
0044 {
0045 class ChildFrame;
0046 }
0047 
0048 namespace DOM
0049 {
0050 class EventImpl;
0051 }
0052 
0053 namespace KJS
0054 {
0055 
0056 class WindowFunc;
0057 class WindowQObject;
0058 class Location;
0059 class History;
0060 class External;
0061 class ScheduledAction;
0062 class JSEventListener;
0063 class JSLazyEventListener;
0064 
0065 class Screen : public JSObject
0066 {
0067 public:
0068     Screen(ExecState *exec);
0069     enum {
0070         Height, Width, ColorDepth, PixelDepth, AvailLeft, AvailTop, AvailHeight,
0071         AvailWidth
0072     };
0073     using KJS::JSObject::getOwnPropertySlot;
0074     bool getOwnPropertySlot(ExecState *exec, const Identifier &propertyName, PropertySlot &slot) override;
0075     JSValue *getValueProperty(ExecState *exec, int token) const;
0076 private:
0077     KHTMLView *view;
0078     const ClassInfo *classInfo() const override
0079     {
0080         return &info;
0081     }
0082     static const ClassInfo info;
0083 };
0084 
0085 class Console : public JSObject
0086 {
0087 public:
0088     Console(ExecState *exec);
0089     enum {
0090         Assert, Log, Debug, Info, Warn, Error, Clear
0091     };
0092 
0093     enum MessageType {
0094         LogType     = 1,
0095         DebugType   = 1 << 1,
0096         InfoType    = 1 << 2,
0097         WarnType    = 1 << 3,
0098         ErrorType   = 1 << 4
0099     };
0100     using KJS::JSObject::getOwnPropertySlot;
0101     bool getOwnPropertySlot(ExecState *exec, const Identifier &propertyName, PropertySlot &slot) override;
0102 private:
0103     const ClassInfo *classInfo() const override
0104     {
0105         return &info;
0106     }
0107     static const ClassInfo info;
0108 };
0109 
0110 class Window : public JSGlobalObject
0111 {
0112     friend QPointer<KHTMLPart> getInstance();
0113     friend class KJS::Location;
0114     friend class KJS::WindowFunc;
0115     friend class KJS::WindowQObject;
0116     friend class KJS::ScheduledAction;
0117 public:
0118     Window(khtml::ChildFrame *p);
0119 public:
0120     ~Window();
0121     /**
0122      * Returns and registers a window object. In case there's already a Window
0123      * for the specified part p this will be returned in order to have unique
0124      * bindings.
0125      */
0126     static JSValue *retrieve(KParts::ReadOnlyPart *p);
0127     /**
0128      * Returns the Window object for a given part
0129      */
0130     static Window *retrieveWindow(KParts::ReadOnlyPart *p);
0131     /**
0132      * returns a pointer to the Window object this javascript interpreting instance
0133      * was called from.
0134      */
0135     static Window *retrieveActive(ExecState *exec);
0136     KParts::ReadOnlyPart *part() const
0137     {
0138         return m_frame.isNull() ? nullptr : m_frame->m_part.data();
0139     }
0140 
0141     void mark() override;
0142     JSValue *getValueProperty(ExecState *exec, int token);
0143     using KJS::JSObject::getOwnPropertySlot;
0144     bool getOwnPropertySlot(ExecState *exec, const Identifier &propertyName, PropertySlot &slot) override;
0145     using KJS::JSObject::put;
0146     void put(ExecState *exec, const Identifier &propertyName, JSValue *value, int attr = None) override;
0147     bool toBoolean(ExecState *exec) const override;
0148     virtual DOM::AbstractViewImpl *toAbstractView() const;
0149     void scheduleClose();
0150     void closeNow();
0151     void delayedGoHistory(int steps);
0152     void goHistory(int steps);
0153     void goURL(ExecState *exec, const QString &url, bool lockHistory = false);
0154 
0155     static bool targetIsExistingWindow(KHTMLPart *part, const QString &frameName);
0156     JSValue *openWindow(ExecState *exec, const List &args);
0157     JSValue *executeOpenWindow(ExecState *exec, const QUrl &url, const QString &frameName, const QString &features);
0158     void resizeTo(QWidget *tl, int width, int height);
0159     void afterScriptExecution();
0160     bool isSafeScript(ExecState *exec) const
0161     {
0162         KParts::ReadOnlyPart *activePart = static_cast<KJS::ScriptInterpreter *>(exec->dynamicInterpreter())->part();
0163         if (activePart == part()) {
0164             return true;
0165         }
0166         return checkIsSafeScript(activePart);
0167     }
0168     Location *location() const;
0169     JSEventListener *getJSEventListener(JSValue *val, bool html = false);
0170     JSLazyEventListener *getJSLazyEventListener(const QString &code, const QString &sourceUrl, int lineNo,
0171             const QString &name, DOM::NodeImpl *node, bool svg = false);
0172     void clear(ExecState *exec);
0173     UString toString(ExecState *exec) const override;
0174 
0175     // Set the current "event" object
0176     void setCurrentEvent(DOM::EventImpl *evt);
0177 
0178     QHash<const QPair<void *, bool>, JSEventListener *> jsEventListeners;
0179     const ClassInfo *classInfo() const override
0180     {
0181         return &info;
0182     }
0183     static const ClassInfo info;
0184     enum { Closed, Crypto, DefaultStatus, Status, Document, Node, EventCtor, Range,
0185            NodeFilter, NodeList, DOMException, RangeException, CSSRule, Frames, _History, _External, Event, InnerHeight,
0186            InnerWidth, Length, _Location, Navigate, Name, _Navigator, _Konqueror, ClientInformation,
0187            OffscreenBuffering, Opener, OuterHeight, OuterWidth, PageXOffset, PageYOffset,
0188            Parent, Personalbar, ScreenX, ScreenY, Scrollbars, Scroll, ScrollBy,
0189            ScreenTop, ScreenLeft, AToB, BToA, FrameElement, GetComputedStyle,
0190            ScrollTo, ScrollX, ScrollY, MoveBy, MoveTo, PostMessage, ResizeBy, ResizeTo, Self, _Window, Top, _Screen,
0191            _Console, Audio, Image, Option, Alert, Confirm, Prompt, Open, SetTimeout, ClearTimeout,
0192            XMLHttpRequest, XMLSerializer, DOMParser, ArrayBuffer, Int8Array, Uint8Array,
0193            Int16Array, Uint16Array, Int32Array, Uint32Array, Float32Array, Float64Array,
0194            Focus, Blur, Close, SetInterval, ClearInterval, CaptureEvents, ReleaseEvents,
0195            Print, AddEventListener, RemoveEventListener, SideBar, GetSelection,
0196            ValueOf, ToString,
0197            Onabort, Onblur,
0198            Onchange, Onclick, Ondblclick, Ondragdrop, Onerror, Onfocus,
0199            Onkeydown, Onkeypress, Onkeyup, Onload,  Onmessage, Onmousedown, Onmousemove,
0200            Onmouseout, Onmouseover, Onmouseup, Onmove, Onreset, Onresize,
0201            Onscroll, Onselect, Onsubmit, Onunload, Onhashchange,
0202            MutationEventCtor, MessageEventCtor, KeyboardEventCtor, EventExceptionCtor, HashChangeEventCtor,
0203            ElementCtor, DocumentCtor, DocumentFragmentCtor, HTMLDocumentCtor,
0204            HTMLElementCtor, HTMLHtmlElementCtor, HTMLHeadElementCtor, HTMLLinkElementCtor,
0205            HTMLTitleElementCtor, HTMLMetaElementCtor, HTMLBaseElementCtor, HTMLIsIndexElementCtor,
0206            HTMLStyleElementCtor, HTMLBodyElementCtor, HTMLFormElementCtor, HTMLSelectElementCtor,
0207            HTMLOptGroupElementCtor, HTMLOptionElementCtor, HTMLInputElementCtor, HTMLTextAreaElementCtor,
0208            HTMLButtonElementCtor, HTMLLabelElementCtor, HTMLFieldSetElementCtor, HTMLLegendElementCtor,
0209            HTMLUListElementCtor, HTMLOListElementCtor, HTMLDListElementCtor, HTMLDirectoryElementCtor,
0210            HTMLMenuElementCtor, HTMLLIElementCtor, HTMLDivElementCtor, HTMLParagraphElementCtor,
0211            HTMLHeadingElementCtor, HTMLBlockQuoteElementCtor, HTMLQuoteElementCtor, HTMLPreElementCtor,
0212            HTMLBRElementCtor, HTMLBaseFontElementCtor, HTMLFontElementCtor, HTMLHRElementCtor, HTMLModElementCtor,
0213            HTMLAnchorElementCtor, HTMLImageElementCtor, HTMLObjectElementCtor, HTMLParamElementCtor,
0214            HTMLAppletElementCtor, HTMLMapElementCtor, HTMLAreaElementCtor, HTMLScriptElementCtor,
0215            HTMLTableElementCtor, HTMLTableCaptionElementCtor, HTMLTableColElementCtor,
0216            HTMLTableSectionElementCtor, HTMLTableRowElementCtor, HTMLTableCellElementCtor,
0217            HTMLFrameSetElementCtor, HTMLLayerElementCtor, HTMLFrameElementCtor, HTMLIFrameElementCtor,
0218            HTMLCollectionCtor, StyleSheetCtor,
0219            CSSStyleDeclarationCtor, HTMLCanvasElementCtor, Context2DCtor, SVGAngleCtor,
0220            XPathResultCtor, XPathExpressionCtor, XPathNSResolverCtor
0221          };
0222     WindowQObject *winq;
0223 
0224     void forgetSuppressedWindows();
0225     void showSuppressedWindows();
0226 
0227     JSValue *indexGetter(ExecState *exec, unsigned index);
0228 
0229     // updates window listeners.
0230     JSValue *getListener(ExecState *exec, int eventId) const;
0231     void setListener(ExecState *exec, int eventId, JSValue *func);
0232 
0233     struct DelayedAction {
0234         virtual void mark() {}; // mark any JS objects we use
0235         virtual bool execute(Window *) = 0; // returns whether to continue or not
0236         virtual ~DelayedAction() {};
0237     };
0238 
0239 private:
0240     // Returns true if the particular method or property should be permitted
0241     // to be accessed even across frames.
0242     bool isCrossFrameAccessible(int token) const;
0243 
0244     KParts::ReadOnlyPart *frameByIndex(unsigned index);
0245     static JSValue *framePartGetter(ExecState *exec, JSObject *, const Identifier &, const PropertySlot &slot);
0246     static JSValue *namedItemGetter(ExecState *exec, JSObject *, const Identifier &, const PropertySlot &slot);
0247 
0248     bool checkIsSafeScript(KParts::ReadOnlyPart *activePart) const;
0249 
0250     QPointer<khtml::ChildFrame> m_frame;
0251     Screen *screen;
0252     Console *console;
0253     History *history;
0254     External *external;
0255     Location *loc;
0256     DOM::EventImpl *m_evt;
0257 
0258     QList<DelayedAction *> m_delayed;
0259 
0260     struct SuppressedWindowInfo {
0261         SuppressedWindowInfo() {}  // for QValueList
0262         SuppressedWindowInfo(QUrl u, QString fr, QString fe) : url(u), frameName(fr), features(fe) {}
0263         QUrl url;
0264         QString frameName;
0265         QString features;
0266     };
0267     QList<SuppressedWindowInfo> m_suppressedWindowInfo;
0268 };
0269 
0270 /**
0271  * like QDateTime, but properly handles milliseconds
0272  */
0273 class DateTimeMS
0274 {
0275     QDate mDate;
0276     QTime mTime;
0277 public:
0278     DateTimeMS addMSecs(int s) const;
0279     bool operator >(const DateTimeMS &other) const;
0280     bool operator >=(const DateTimeMS &other) const;
0281 
0282     int msecsTo(const DateTimeMS &other) const;
0283 
0284     static DateTimeMS now();
0285 };
0286 
0287 /**
0288  * An action (either function or string) to be executed after a specified
0289  * time interval, either once or repeatedly. Used for window.setTimeout()
0290  * and window.setInterval()
0291  */
0292 class ScheduledAction
0293 {
0294 public:
0295     ScheduledAction(JSObject *_func, const List &_args, const DateTimeMS &_nextTime, int _interval, bool _singleShot, int _timerId);
0296     ScheduledAction(const QString &_code, const DateTimeMS &_nextTime, int _interval, bool _singleShot, int _timerId);
0297     ~ScheduledAction();
0298     bool execute(Window *window);
0299     void mark();
0300 
0301     JSObject *func;
0302     List args;
0303     QString code;
0304     bool isFunction;
0305     bool singleShot;
0306 
0307     DateTimeMS nextTime;
0308     int interval;
0309     bool executing;
0310     int timerId;
0311 };
0312 
0313 class WindowQObject : public QObject
0314 {
0315     Q_OBJECT
0316 public:
0317     WindowQObject(Window *w);
0318     ~WindowQObject();
0319     int installTimeout(const Identifier &handler, int t, bool singleShot);
0320     int installTimeout(JSValue *func, List args, int t, bool singleShot);
0321     void clearTimeout(int timerId);
0322     void mark();
0323     bool hasTimers() const;
0324 
0325     void pauseTimers();
0326     void resumeTimers();
0327 public Q_SLOTS:
0328     void timeoutClose();
0329 protected Q_SLOTS:
0330     void parentDestroyed();
0331 protected:
0332     void timerEvent(QTimerEvent *e) override;
0333     void setNextTimer();
0334     void killTimers();
0335 private:
0336     Window *parent;
0337     QList<ScheduledAction *> scheduledActions;
0338 
0339     /**
0340      We need to pause timers when alerts are up; so we keep track
0341      of recursion of that and the delay at topmost level.
0342      */
0343     int pauseLevel;
0344     DateTimeMS pauseStart;
0345 
0346     int lastTimerId;
0347     QList<int> timerIds;
0348     bool currentlyDispatching;
0349 };
0350 
0351 /**
0352  * Helper for pausing/resuming timers
0353  */
0354 class TimerPauser
0355 {
0356 public:
0357     TimerPauser(ExecState *exec)
0358     {
0359         win = Window::retrieveActive(exec);
0360         win->winq->pauseTimers();
0361     }
0362 
0363     ~TimerPauser()
0364     {
0365         win->winq->resumeTimers();
0366     }
0367 private:
0368     Window *win;
0369 };
0370 
0371 class Location : public JSObject
0372 {
0373 public:
0374     ~Location();
0375 
0376     JSValue *getValueProperty(ExecState *exec, int token) const;
0377     using KJS::JSObject::getOwnPropertySlot;
0378     bool getOwnPropertySlot(ExecState *exec, const Identifier &propertyName, PropertySlot &slot) override;
0379     using KJS::JSObject::put;
0380     void put(ExecState *exec, const Identifier &propertyName, JSValue *value, int attr = None) override;
0381     JSValue *toPrimitive(ExecState *exec, JSType preferred) const override;
0382     UString toString(ExecState *exec) const override;
0383     enum { Hash, Href, Hostname, Host, Pathname, Port, Protocol, Search, EqualEqual,
0384            Assign, Replace, Reload, ToString
0385          };
0386     KParts::ReadOnlyPart *part() const;
0387     const ClassInfo *classInfo() const override
0388     {
0389         return &info;
0390     }
0391     static const ClassInfo info;
0392 private:
0393     friend class Window;
0394     Location(khtml::ChildFrame *f);
0395     QPointer<khtml::ChildFrame> m_frame;
0396 };
0397 
0398 } // namespace
0399 
0400 #endif