📄 kjs_window.cpp
字号:
// -*- c-basic-offset: 2 -*-/* * This file is part of the KDE libraries * Copyright (C) 2000 Harri Porten (porten@kde.org) * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */#include <qtimer.h>#include <qinputdialog.h>#include <qstringlist.h>#include <qpaintdevicemetrics.h>#include <qapplication.h>#include <dom_string.h>#include <kdebug.h>#include <kurl.h>#include <kmessagebox.h>#include <klocale.h>#include <kparts/browserextension.h>#include <kparts/browserinterface.h>#include <kwin.h>#include <kwinmodule.h>#include <kconfig.h>#include <kjs/kjs.h>#include <kjs/operations.h>#include <kjs/lookup.h>#include "kjs_proxy.h"#include "kjs_window.h"#include "kjs_navigator.h"#include "kjs_html.h"#include "kjs_dom.h"#include "kjs_range.h"#include "kjs_traversal.h"#include "kjs_events.h"#include <qevent.h>#include "khtmlview.h"#include <html_element.h>#include <html_documentimpl.h>#include "khtml_part.h"#include "xml/dom_docimpl.h"#include "xml/dom2_eventsimpl.h"using namespace KJS;namespace KJS {////////////////////// History Object ////////////////////////class History : public HostImp { friend class HistoryFunc;public: History(KHTMLPart *p) : part(p) { } virtual KJSO get(const UString &p) const; virtual bool hasProperty(const UString &p, bool recursive) const;private: QGuardedPtr<KHTMLPart> part;};class HistoryFunc : public DOMFunction {public: HistoryFunc(const History *h, int i) : history(h), id(i) { } Completion tryExecute(const List &args); enum { Back, Forward, Go };private: const History *history; int id;};class FrameArray : public HostImp {public: FrameArray(KHTMLPart *p) : part(p) { } KJSO get(const UString &p) const;private: QGuardedPtr<KHTMLPart> part;};}; // namespace KJS////////////////////// Screen Object ////////////////////////// table for screen object/*@begin ecmaScreenTable Screen 8height DontEnum|ReadOnlywidth DontEnum|ReadOnlycolorDepth DontEnum|ReadOnlypixelDepth DontEnum|ReadOnlyavailLeft DontEnum|ReadOnlyavailTop DontEnum|ReadOnlyavailHeight DontEnum|ReadOnlyavailWidth DontEnum|ReadOnly@end*/static const struct HashEntry2 ecmaScreenTableEntries[] = { { "availLeft", Screen::availLeft, DontEnum|ReadOnly, 0 }, { 0, 0, 0, 0 }, { "availTop", Screen::availTop, DontEnum|ReadOnly, 0 }, { "height", Screen::height, DontEnum|ReadOnly, 0 }, { "width", Screen::width, DontEnum|ReadOnly, &ecmaScreenTableEntries[8] }, { 0, 0, 0, 0 }, { "availHeight", Screen::availHeight, DontEnum|ReadOnly, 0 }, { "pixelDepth", Screen::pixelDepth, DontEnum|ReadOnly, &ecmaScreenTableEntries[9] }, { "colorDepth", Screen::colorDepth, DontEnum|ReadOnly, 0 }, { "availWidth", Screen::availWidth, DontEnum|ReadOnly, 0 }};static const struct HashTable2 ecmaScreenTable = { 2, 10, ecmaScreenTableEntries, 10 };KJSO Screen::get(const UString &p) const{ int token = Lookup::find(&ecmaScreenTable, p); if (token < 0) return ObjectImp::get(p); KWinModule info; QPaintDeviceMetrics m(QApplication::desktop()); switch( token ) { case height: return Number(QApplication::desktop()->height()); case width: return Number(QApplication::desktop()->width()); case colorDepth: case pixelDepth: return Number(m.depth()); case availLeft: return Number(info.workArea().left()); case availTop: return Number(info.workArea().top()); case availHeight: return Number(info.workArea().height()); case availWidth: return Number(info.workArea().width()); default: assert(!"Screen::get: unhandled switch case"); return Undefined(); }}////////////////////// Window Object ////////////////////////const TypeInfo Window::info = { "Window", HostType, 0, 0, 0 };Window::Window(KHTMLPart *p) : m_part(p), screen(0), history(0), frames(0), loc(0){ winq = new WindowQObject(this); //kdDebug() << "Window::Window this=" << this << " part=" << m_part << endl;}Window::~Window(){ kdDebug(6070) << "Window::~Window this=" << this << " part=" << m_part << endl; delete winq;}Window *Window::retrieveWindow(KHTMLPart *p){ // prototype set in kjs_create() return (Window*)retrieve(p)->prototype();}Window *Window::retrieveActive(){ return static_cast<KJS::Window*>(KJS::Global::current().prototype().imp());}Imp *Window::retrieve(KHTMLPart *p){ assert(p); KJSProxy *proxy = p->jScript(); if (proxy) return proxy->jScript()->globalObject(); // the Global object is the "window" else return Null().imp();}Location *Window::location() const{ if (!loc) const_cast<Window*>(this)->loc = new Location(m_part); return loc;}// reference our special objects during garbage collectionvoid Window::mark(Imp *){ HostImp::mark(); if (screen && !screen->marked()) screen->mark(); if (history && !history->marked()) history->mark(); if (frames && !frames->marked()) frames->mark(); if (loc && !loc->marked()) loc->mark();#if 0 // Mark all Window objects from the map. Necessary to keep // existing window properties, such as 'opener'. if (window_map) { WindowMap::Iterator it = window_map->begin(); for ( ; it != window_map->end() ; ++it ) { if (it.data() != this && !it.data()->refcount) { //kdDebug() << "Window::mark marking window from dict " << it.data() << endl; it.data()->mark(); } } }#endif}bool Window::hasProperty(const UString &/*p*/, bool /*recursive*/) const{ // emulate IE behaviour: it doesn't throw exceptions when undeclared // variables are used. Returning true here will lead to get() returning // 'undefined' in those cases. return true;#if 0 if (p == "closed") return true; // we don't want any operations on a closed window if (m_part.isNull()) return false; // Properties if (p == "crypto" || p == "defaultStatus" || p == "document" || p == "Node" || p == "Range" || p == "NodeFilter" || p == "DOMException" || p == "frames" || p == "history" || // p == "event" || p == "innerHeight" || p == "innerWidth" || p == "length" || p == "location" || p == "name" || p == "navigator" || p == "offscreenBuffering" || p == "opener" || p == "outerHeight" || p == "outerWidth" || p == "pageXOffset" || p == "pageYOffset" || p == "parent" || p == "personalbar" || p == "screen" || p == "screenX" || p == "screenY" || p == "scrollbars" || p == "self" || p == "status" || p == "top" || p == "window" || p == "Image" || p == "Option" || // Methods p == "alert" || p == "confirm" || p == "blur" || p == "clearInterval" || p == "clearTimeout" || p == "close" || p == "focus" || p == "moveBy" || p == "moveTo" || p == "open" || p == "prompt" || p == "resizeBy" || p == "resizeTo" || p == "scroll" || p == "scrollBy" || p == "scrollTo" || p == "setInterval" || p == "setTimeout" || p == "onabort" || p == "onblur" || p == "onchange" || p == "onclick" || p == "ondblclick" || p == "ondragdrop" || p == "onerror" || p == "onfocus" || p == "onkeydown" || p == "onkeypress" || p == "onkeyup" || p == "onload" || p == "onmousedown" || p == "onmousemove" || p == "onmouseout" || p == "onmouseover" || p == "onmouseup" || p == "onmove" || p == "onreset" || p == "onresize" || p == "onselect" || p == "onsubmit" || p == "onunload" || HostImp::hasProperty(p,recursive) || m_part->findFrame( p.qstring() )) return true; // allow shortcuts like 'Image1' instead of document.images.Image1 if (m_part->document().isHTMLDocument()) { // might be XML DOM::HTMLCollection coll = m_part->htmlDocument().all(); DOM::HTMLElement element = coll.namedItem(p.string()); if (!element.isNull()) { return true; } } return false;#endif}String Window::toString() const{ return UString( "[object Window]" );}KJSO Window::get(const UString &p) const{ //kdDebug() << "Window::get " << p.qstring() << endl; if (p == "closed") return Boolean(m_part.isNull()); // we don't want any operations on a closed window if (m_part.isNull()) return Undefined(); // Reimplement toString ourselves to avoid getting [object Object] from our prototype if (p == "toString") return Function(new WindowFunc(this, WindowFunc::ToString)); if (Imp::hasProperty(p,true)) { if (isSafeScript()) return Imp::get(p); } if (p == "crypto") return Undefined(); // ### else if (p == "defaultStatus" || p == "defaultstatus") return String(UString(m_part->jsDefaultStatusBarText())); else if (p == "status") return String(UString(m_part->jsStatusBarText())); else if (p == "document") { if (isSafeScript()) return getDOMNode(m_part->document()); else return Undefined(); } else if (p == "Node") return getNodePrototype(); else if (p == "Range") return getRangePrototype(); else if (p == "NodeFilter") return getNodeFilterPrototype(); else if (p == "DOMException") return getDOMExceptionPrototype(); else if (p == "frames") return KJSO(frames ? frames : (const_cast<Window*>(this)->frames = new FrameArray(m_part))); else if (p == "history") return KJSO(history ? history : (const_cast<Window*>(this)->history = new History(m_part))); // else if (p == "event")// return getDOMEvent(static_cast<DOM::Event>(m_part->view()->lastDOMMouseEvent())); else if (p == "innerHeight") return Number(m_part->view()->visibleHeight()); else if (p == "innerWidth") return Number(m_part->view()->visibleWidth()); else if (p == "length") return Number(m_part->frames().count()); else if (p == "location") { if (isSafeScript()) return KJSO(location()); else return Undefined(); } else if (p == "name") return String(m_part->name()); else if (p == "navigator") return KJSO(new Navigator(m_part)); else if (p == "offscreenBuffering") return Boolean(true); else if (p == "opener") if (!m_part->opener()) return Null(); // ### a null Window might be better, but == null else // doesn't work yet return retrieve(m_part->opener()); else if (p == "outerHeight" || p == "outerWidth") { if (!m_part->widget()) return Number(0); KWin::Info inf = KWin::info(m_part->widget()->topLevelWidget()->winId()); return Number(p == "outerHeight" ? inf.geometry.height() : inf.geometry.width()); } else if (p == "pageXOffset") return Number(m_part->view()->contentsX()); else if (p == "pageYOffset") return Number(m_part->view()->contentsY()); else if (p == "parent") return KJSO(retrieve(m_part->parentPart() ? m_part->parentPart() : (KHTMLPart*)m_part)); else if (p == "personalbar") return Undefined(); // ### else if (p == "screenX") return Number(m_part->view() ? m_part->view()->mapToGlobal(QPoint(0,0)).x() : 0); else if (p == "screenY") return Number(m_part->view() ? m_part->view()->mapToGlobal(QPoint(0,0)).y() : 0); else if (p == "scrollbars") return Undefined(); // ### else if (p == "scroll") return Function(new WindowFunc(this, WindowFunc::ScrollTo)); // compatibility else if (p == "scrollBy") return Function(new WindowFunc(this, WindowFunc::ScrollBy)); else if (p == "scrollTo") return Function(new WindowFunc(this, WindowFunc::ScrollTo)); else if (p == "moveBy") return Function(new WindowFunc(this, WindowFunc::MoveBy)); else if (p == "moveTo") return Function(new WindowFunc(this, WindowFunc::MoveTo)); else if (p == "resizeBy") return Function(new WindowFunc(this, WindowFunc::ResizeBy)); else if (p == "resizeTo") return Function(new WindowFunc(this, WindowFunc::ResizeTo)); else if (p == "self" || p == "window") return KJSO(retrieve(m_part)); else if (p == "top") { KHTMLPart *p = m_part; while (p->parentPart()) p = p->parentPart(); return KJSO(retrieve(p)); } else if (p == "screen") return KJSO(screen ? screen : (const_cast<Window*>(this)->screen = new Screen())); else if (p == "Image") return KJSO(new ImageConstructor(Global::current(), m_part->document())); else if (p == "Option") return KJSO(new OptionConstructor(Global::current(), m_part->document())); else if (p == "alert") return Function(new WindowFunc(this, WindowFunc::Alert)); else if (p == "confirm") return Function(new WindowFunc(this, WindowFunc::Confirm));
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -