📄 kjs_html.cpp
字号:
// -*- c-basic-offset: 2 -*-
/*
* This file is part of the KDE libraries
* Copyright (C) 1999-2000 Harri Porten (porten@kde.org)
* Copyright (C) 2004 Apple Computer, Inc.
*
* 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 "misc/loader.h"
#include "dom/html_block.h"
#include "dom/html_head.h"
#include "dom/html_image.h"
#include "dom/html_inline.h"
#include "dom/html_list.h"
#include "dom/html_table.h"
#include "dom/html_object.h"
#include "dom/dom_exception.h"
#include "xml/dom2_eventsimpl.h"
// ### HACK
#include "html/html_baseimpl.h"
#include "html/html_canvasimpl.h"
#include "html/html_documentimpl.h"
#include "html/html_imageimpl.h"
#include "html/html_objectimpl.h"
#include "khtml_part.h"
#include "khtmlview.h"
#include "ecma/kjs_css.h"
#include "ecma/kjs_html.h"
#include "ecma/kjs_window.h"
#include "ecma/kjs_html.lut.h"
#include "kjs_events.h"
#include "kjs_proxy.h"
#include "misc/htmltags.h"
#if !NOKIA_CHANGES
#include "rendering/render_canvasimage.h"
#endif
#include "rendering/render_object.h"
#include "rendering/render_layer.h"
#include <kdebug.h>
#include "cssparser.h"
#include "css_stylesheetimpl.h"
#include "qcolor.h"
#include "qpixmap.h"
#include "qpainter.h"
#if !NOKIA_CHANGES
#include <ApplicationServices/ApplicationServices.h>
#endif
using namespace KJS;
using DOM::DocumentImpl;
using DOM::DOMString;
using DOM::HTMLFrameElementImpl;
using DOM::HTMLIFrameElementImpl;
IMPLEMENT_PROTOFUNC(HTMLDocFunction)
Value KJS::HTMLDocFunction::tryCall(ExecState *exec, Object &thisObj, const List &args)
{
if (!thisObj.inherits(&HTMLDocument::info)) {
Object err = Error::create(exec,TypeError);
exec->setException(err);
return err;
}
DOM::HTMLDocument doc = static_cast<KJS::HTMLDocument *>(thisObj.imp())->toDocument();
switch (id) {
case HTMLDocument::Clear: // even IE doesn't support that one...
//doc.clear(); // TODO
return Undefined();
case HTMLDocument::Open:
// For compatibility with other browsers, pass open calls with more than 2 parameters to the window.
if (args.size() > 2) {
KHTMLPart *part = static_cast<DOM::DocumentImpl *>(doc.handle())->part();
if (part) {
Window *window = Window::retrieveWindow(part);
if (window) {
Object functionObject = Object::dynamicCast(window->get(exec, "open"));
if (functionObject.isNull() || !functionObject.implementsCall()) {
Object exception = Error::create(exec, TypeError);
exec->setException(exception);
return exception;
}
Object windowObject(window);
return functionObject.call(exec, windowObject, args);
}
}
return Undefined();
}
// In the case of two parameters or fewer, do a normal document open.
doc.open();
return Undefined();
case HTMLDocument::Close:
// see khtmltests/ecma/tokenizer-script-recursion.html
doc.close();
return Undefined();
case HTMLDocument::Write:
case HTMLDocument::WriteLn: {
// DOM only specifies single string argument, but NS & IE allow multiple
// or no arguments
UString str = "";
for (int i = 0; i < args.size(); i++)
str += args[i].toString(exec);
if (id == HTMLDocument::WriteLn)
str += "\n";
//kdDebug() << "document.write: " << str.ascii() << endl;
doc.write(str.string());
return Undefined();
}
case HTMLDocument::GetElementsByName:
return getDOMNodeList(exec,doc.getElementsByName(args[0].toString(exec).string()));
case HTMLDocument::CaptureEvents:
case HTMLDocument::ReleaseEvents:
// Do nothing for now. These are NS-specific legacy calls.
break;
}
return Undefined();
}
const ClassInfo KJS::HTMLDocument::info =
{ "HTMLDocument", &DOMDocument::info, &HTMLDocumentTable, 0 };
/* Source for HTMLDocumentTable. Use "make hashtables" to regenerate.
@begin HTMLDocumentTable 30
title HTMLDocument::Title DontDelete
referrer HTMLDocument::Referrer DontDelete|ReadOnly
domain HTMLDocument::Domain DontDelete
URL HTMLDocument::URL DontDelete|ReadOnly
body HTMLDocument::Body DontDelete
location HTMLDocument::Location DontDelete
cookie HTMLDocument::Cookie DontDelete
images HTMLDocument::Images DontDelete|ReadOnly
embeds HTMLDocument::Embeds DontDelete|ReadOnly
applets HTMLDocument::Applets DontDelete|ReadOnly
links HTMLDocument::Links DontDelete|ReadOnly
forms HTMLDocument::Forms DontDelete|ReadOnly
anchors HTMLDocument::Anchors DontDelete|ReadOnly
scripts HTMLDocument::Scripts DontDelete|ReadOnly
# We want no document.all at all, not just a function that returns undefined.
# That means we lose the "document.all when spoofing as IE" feature, but we don't spoof in Safari.
# And this makes sites that set document.all explicitly work when they otherwise wouldn't,
# e.g. https://corporateexchange.airborne.com
# (Not in APPLE_CHANGES since we can't do #if in KJS identifier lists.)
# all HTMLDocument::All DontDelete|ReadOnly
clear HTMLDocument::Clear DontDelete|Function 0
open HTMLDocument::Open DontDelete|Function 0
close HTMLDocument::Close DontDelete|Function 0
write HTMLDocument::Write DontDelete|Function 1
writeln HTMLDocument::WriteLn DontDelete|Function 1
getElementsByName HTMLDocument::GetElementsByName DontDelete|Function 1
captureEvents HTMLDocument::CaptureEvents DontDelete|Function 0
releaseEvents HTMLDocument::ReleaseEvents DontDelete|Function 0
bgColor HTMLDocument::BgColor DontDelete
fgColor HTMLDocument::FgColor DontDelete
alinkColor HTMLDocument::AlinkColor DontDelete
linkColor HTMLDocument::LinkColor DontDelete
vlinkColor HTMLDocument::VlinkColor DontDelete
lastModified HTMLDocument::LastModified DontDelete|ReadOnly
height HTMLDocument::Height DontDelete|ReadOnly
width HTMLDocument::Width DontDelete|ReadOnly
dir HTMLDocument::Dir DontDelete
designMode HTMLDocument::DesignMode DontDelete
#potentially obsolete array properties
# layers
# plugins
# tags
#potentially obsolete properties
# embeds
# ids
@end
*/
bool KJS::HTMLDocument::hasProperty(ExecState *exec, const Identifier &p) const
{
#ifdef KJS_VERBOSE
//kdDebug(6070) << "KJS::HTMLDocument::hasProperty " << p.qstring() << endl;
#endif
DOM::HTMLDocumentImpl *docImpl = static_cast<DOM::HTMLDocumentImpl *>(node.handle());
return (DOMDocument::hasProperty(exec, p) ||
docImpl->haveNamedImageOrForm(p.qstring()));
}
Value KJS::HTMLDocument::tryGet(ExecState *exec, const Identifier &propertyName) const
{
#ifdef KJS_VERBOSE
kdDebug(6070) << "KJS::HTMLDocument::tryGet " << propertyName.qstring() << endl;
#endif
DOM::HTMLDocument doc = static_cast<DOM::HTMLDocument>(node);
DOM::HTMLBodyElement body = doc.body();
KHTMLView *view = static_cast<DOM::DocumentImpl*>(doc.handle())->view();
const HashEntry* entry = Lookup::findEntry(&HTMLDocumentTable, propertyName);
if (entry) {
switch (entry->value) {
case Title:
return String(doc.title());
case Referrer:
return String(doc.referrer());
case Domain:
return String(doc.domain());
case URL:
return String(doc.URL());
case Body:
return getDOMNode(exec,doc.body());
case Location:
if ( view && view->part() )
{
Window* win = Window::retrieveWindow(view->part());
if (win)
return Value(win->location());
else
return Undefined();
}
else
return Undefined();
case Cookie:
return String(doc.cookie());
case Images:
return getHTMLCollection(exec,doc.images());
case Embeds:
return getHTMLCollection(exec,doc.embeds());
case Applets:
return getHTMLCollection(exec,doc.applets());
case Links:
return getHTMLCollection(exec,doc.links());
case Forms:
return getHTMLCollection(exec,doc.forms());
case Anchors:
return getHTMLCollection(exec,doc.anchors());
case Scripts: // TODO (IE-specific)
{
// To be implemented. Meanwhile, return an object with a length property set to 0
kdWarning() << "KJS::HTMLDocument document.scripts called - not implemented" << endl;
Object obj( new ObjectImp() );
obj.put( exec, lengthPropertyName, Number(0) );
return obj;
}
case All:
// Disable document.all when we try to be Netscape-compatible
if ( exec->dynamicInterpreter()->compatMode() == Interpreter::NetscapeCompat )
return Undefined();
return getHTMLCollection(exec,doc.all());
case Clear:
case Open:
case Close:
case Write:
case WriteLn:
case GetElementsByName:
case CaptureEvents:
case ReleaseEvents:
return lookupOrCreateFunction<HTMLDocFunction>( exec, propertyName, this, entry->value, entry->params, entry->attr );
}
}
// Look for overrides
ValueImp * val = ObjectImp::getDirect(propertyName);
if (val)
return Value(val);
if (entry) {
switch (entry->value) {
case BgColor:
return String(body.bgColor());
case FgColor:
return String(body.text());
case AlinkColor:
return String(body.aLink());
case LinkColor:
return String(body.link());
case VlinkColor:
return String(body.vLink());
case LastModified:
return String(doc.lastModified());
case Height:
return Number(view ? view->contentsHeight() : 0);
case Width:
return Number(view ? view->contentsWidth() : 0);
case Dir:
return String(body.dir());
case DesignMode:
{
DocumentImpl *docimpl = static_cast<DocumentImpl *>(doc.handle());
if (!docimpl)
return Undefined();
return String(docimpl->inDesignMode() ? "on" : "off");
}
}
}
if (DOMDocument::hasProperty(exec, propertyName))
return DOMDocument::tryGet(exec, propertyName);
//kdDebug(6070) << "KJS::HTMLDocument::tryGet " << propertyName.qstring() << " not found, returning element" << endl;
// image and form elements with the name p will be looked up last
#if APPLE_CHANGES
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -