#include <khtmlview.h>
#include "xml/dom2_eventsimpl.h"
#include "rendering/render_canvas.h"
#include "xml/dom_nodeimpl.h"
#include "xml/dom_docimpl.h"
#include <kdebug.h>
#include <khtml_part.h>
#include "kjs_dom.h"
#include "kjs_html.h"
#include "kjs_css.h"
#include "kjs_range.h"
#include "kjs_traversal.h"
#include "kjs_events.h"
#include "kjs_views.h"
#include "kjs_window.h"
#include "dom/dom_exception.h"
#include "kjs_dom.lut.h"
#include "khtmlpart_p.h"
#include "html_objectimpl.h"
#include "misc/htmltags.h"
#if APPLE_CHANGES
#include <JavaScriptCore/runtime_object.h>
#endif
using namespace KJS;
using DOM::DOMException;
using DOM::DOMString;
using DOM::NodeFilter;
DEFINE_PROTOTYPE("DOMNode",DOMNodeProto)
IMPLEMENT_PROTOFUNC(DOMNodeProtoFunc)
IMPLEMENT_PROTOTYPE(DOMNodeProto,DOMNodeProtoFunc)
const ClassInfo DOMNode::info = { "Node", 0, &DOMNodeTable, 0 };
DOMNode::DOMNode(ExecState *exec, const DOM::Node &n)
: DOMObject(DOMNodeProto::self(exec)), node(n)
{
}
DOMNode::DOMNode(const Object &proto, const DOM::Node &n)
: DOMObject(proto), node(n)
{
}
bool DOMNode::toBoolean(ExecState *) const
{
return !node.isNull();
}
Value DOMNode::tryGet(ExecState *exec, const Identifier &propertyName) const
{
#ifdef KJS_VERBOSE
kdDebug(6070) << "DOMNode::tryGet " << propertyName.qstring() << endl;
#endif
return DOMObjectLookupGetValue<DOMNode, DOMObject>(exec, propertyName, &DOMNodeTable, this);
}
Value DOMNode::getValueProperty(ExecState *exec, int token) const
{
switch (token) {
case NodeName:
return getStringOrNull(node.nodeName());
case NodeValue:
return getStringOrNull(node.nodeValue());
case NodeType:
return Number((unsigned int)node.nodeType());
case ParentNode:
return getDOMNode(exec,node.parentNode());
case ParentElement: return getDOMNode(exec,node.parentNode());
case ChildNodes:
return getDOMNodeList(exec,node.childNodes());
case FirstChild:
return getDOMNode(exec,node.firstChild());
case LastChild:
return getDOMNode(exec,node.lastChild());
case PreviousSibling:
return getDOMNode(exec,node.previousSibling());
case NextSibling:
return getDOMNode(exec,node.nextSibling());
case Attributes:
return getDOMNamedNodeMap(exec,node.attributes());
case NamespaceURI:
return getStringOrNull(node.namespaceURI());
case Prefix:
return getStringOrNull(node.prefix());
case LocalName:
return getStringOrNull(node.localName());
case OwnerDocument:
return getDOMNode(exec,node.ownerDocument());
case OnAbort:
return getListener(DOM::EventImpl::ABORT_EVENT);
case OnBlur:
return getListener(DOM::EventImpl::BLUR_EVENT);
case OnChange:
return getListener(DOM::EventImpl::CHANGE_EVENT);
case OnClick:
return getListener(DOM::EventImpl::KHTML_CLICK_EVENT);
case OnContextMenu:
return getListener(DOM::EventImpl::CONTEXTMENU_EVENT);
case OnDblClick:
return getListener(DOM::EventImpl::KHTML_DBLCLICK_EVENT);
case OnDragDrop:
return getListener(DOM::EventImpl::KHTML_DRAGDROP_EVENT);
case OnError:
return getListener(DOM::EventImpl::KHTML_ERROR_EVENT);
case OnFocus:
return getListener(DOM::EventImpl::FOCUS_EVENT);
case OnInput:
return getListener(DOM::EventImpl::INPUT_EVENT);
case OnKeyDown:
return getListener(DOM::EventImpl::KEYDOWN_EVENT);
case OnKeyPress:
return getListener(DOM::EventImpl::KEYPRESS_EVENT);
case OnKeyUp:
return getListener(DOM::EventImpl::KEYUP_EVENT);
case OnLoad:
return getListener(DOM::EventImpl::LOAD_EVENT);
case OnMouseDown:
return getListener(DOM::EventImpl::MOUSEDOWN_EVENT);
case OnMouseMove:
return getListener(DOM::EventImpl::MOUSEMOVE_EVENT);
case OnMouseOut:
return getListener(DOM::EventImpl::MOUSEOUT_EVENT);
case OnMouseOver:
return getListener(DOM::EventImpl::MOUSEOVER_EVENT);
case OnMouseUp:
return getListener(DOM::EventImpl::MOUSEUP_EVENT);
case OnBeforeCut:
return getListener(DOM::EventImpl::BEFORECUT_EVENT);
case OnCut:
return getListener(DOM::EventImpl::CUT_EVENT);
case OnBeforeCopy:
return getListener(DOM::EventImpl::BEFORECOPY_EVENT);
case OnCopy:
return getListener(DOM::EventImpl::COPY_EVENT);
case OnBeforePaste:
return getListener(DOM::EventImpl::BEFOREPASTE_EVENT);
case OnPaste:
return getListener(DOM::EventImpl::PASTE_EVENT);
case OnDragEnter:
return getListener(DOM::EventImpl::DRAGENTER_EVENT);
case OnDragOver:
return getListener(DOM::EventImpl::DRAGOVER_EVENT);
case OnDragLeave:
return getListener(DOM::EventImpl::DRAGLEAVE_EVENT);
case OnDrop:
return getListener(DOM::EventImpl::DROP_EVENT);
case OnDragStart:
return getListener(DOM::EventImpl::DRAGSTART_EVENT);
case OnDrag:
return getListener(DOM::EventImpl::DRAG_EVENT);
case OnDragEnd:
return getListener(DOM::EventImpl::DRAGEND_EVENT);
case OnMove:
return getListener(DOM::EventImpl::KHTML_MOVE_EVENT);
case OnReset:
return getListener(DOM::EventImpl::RESET_EVENT);
case OnResize:
return getListener(DOM::EventImpl::RESIZE_EVENT);
case OnScroll:
return getListener(DOM::EventImpl::SCROLL_EVENT);
#if APPLE_CHANGES
case OnSearch:
return getListener(DOM::EventImpl::SEARCH_EVENT);
#endif
case OnSelect:
return getListener(DOM::EventImpl::SELECT_EVENT);
case OnSelectStart:
return getListener(DOM::EventImpl::SELECTSTART_EVENT);
case OnSubmit:
return getListener(DOM::EventImpl::SUBMIT_EVENT);
case OnUnload:
return getListener(DOM::EventImpl::UNLOAD_EVENT);
default:
DOM::DocumentImpl* docimpl = node.handle()->getDocument();
if (docimpl) {
docimpl->updateLayoutIgnorePendingStylesheets();
}
khtml::RenderObject *rend = node.handle()->renderer();
switch (token) {
case OffsetLeft:
return rend ? static_cast<Value>(Number(rend->offsetLeft())) : Value(Undefined());
case OffsetTop:
return rend ? static_cast<Value>(Number(rend->offsetTop())) : Value(Undefined());
case OffsetWidth:
return rend ? static_cast<Value>(Number(rend->offsetWidth()) ) : Value(Undefined());
case OffsetHeight:
return rend ? static_cast<Value>(Number(rend->offsetHeight() ) ) : Value(Undefined());
case OffsetParent: {
khtml::RenderObject* par = rend ? rend->offsetParent() : 0;
return getDOMNode(exec, par ? par->element() : 0);
}
case ClientWidth:
return rend ? static_cast<Value>(Number(rend->clientWidth()) ) : Value(Undefined());
case ClientHeight:
return rend ? static_cast<Value>(Number(rend->clientHeight()) ) : Value(Undefined());
case ScrollWidth:
return rend ? static_cast<Value>(Number(rend->scrollWidth()) ) : Value(Undefined());
case ScrollHeight:
return rend ? static_cast<Value>(Number(rend->scrollHeight()) ) : Value(Undefined());
case ScrollLeft:
return Number(rend && rend->layer() ? rend->layer()->scrollXOffset() : 0);
case ScrollTop:
return Number(rend && rend->layer() ? rend->layer()->scrollYOffset() : 0);
default:
kdWarning() << "Unhandled token in DOMNode::getValueProperty : " << token << endl;
break;
}
}
return Value();
}
void DOMNode::tryPut(ExecState *exec, const Identifier& propertyName, const Value& value, int attr)
{
#ifdef KJS_VERBOSE
kdDebug(6070) << "DOMNode::tryPut " << propertyName.qstring() << endl;
#endif
DOMObjectLookupPut<DOMNode,DOMObject>(exec, propertyName, value, attr,
&DOMNodeTable, this );
}
void DOMNode::putValue(ExecState *exec, int token, const Value& value, int )
{
switch (token) {
case NodeValue:
node.setNodeValue(value.toString(exec).string());
break;
case Prefix:
node.setPrefix(value.toString(exec).string());
break;
case OnAbort:
setListener(exec,DOM::EventImpl::ABORT_EVENT,value);
break;
case OnBlur:
setListener(exec,DOM::EventImpl::BLUR_EVENT,value);
break;
case OnChange:
setListener(exec,DOM::EventImpl::CHANGE_EVENT,value);
break;
case OnClick:
setListener(exec,DOM::EventImpl::KHTML_CLICK_EVENT,value);
break;
case OnContextMenu:
setListener(exec,DOM::EventImpl::CONTEXTMENU_EVENT,value);
break;
case OnDblClick:
setListener(exec,DOM::EventImpl::KHTML_DBLCLICK_EVENT,value);
break;
case OnDragDrop:
setListener(exec,DOM::EventImpl::KHTML_DRAGDROP_EVENT,value);
break;
case OnError:
setListener(exec,DOM::EventImpl::KHTML_ERROR_EVENT,value);
break;
case OnFocus:
setListener(exec,DOM::EventImpl::FOCUS_EVENT,value);
break;
case OnInput:
setListener(exec,DOM::EventImpl::INPUT_EVENT,value);
break;
case OnKeyDown:
setListener(exec,DOM::EventImpl::KEYDOWN_EVENT,value);
break;
case OnKeyPress:
setListener(exec,DOM::EventImpl::KEYPRESS_EVENT,value);
break;
case OnKeyUp:
setListener(exec,DOM::EventImpl::KEYUP_EVENT,value);
break;
case OnLoad:
setListener(exec,DOM::EventImpl::LOAD_EVENT,value);
break;
case OnMouseDown:
setListener(exec,DOM::EventImpl::MOUSEDOWN_EVENT,value);
break;
case OnMouseMove:
setListener(exec,DOM::EventImpl::MOUSEMOVE_EVENT,value);
break;
case OnMouseOut:
setListener(exec,DOM::EventImpl::MOUSEOUT_EVENT,value);
break;
case OnMouseOver:
setListener(exec,DOM::EventImpl::MOUSEOVER_EVENT,value);
break;
case OnMouseUp:
setListener(exec,DOM::EventImpl::MOUSEUP_EVENT,value);
break;
case OnBeforeCut:
setListener(exec,DOM::EventImpl::BEFORECUT_EVENT,value);
break;
case OnCut:
setListener(exec,DOM::EventImpl::CUT_EVENT,value);
break;
case OnBeforeCopy:
setListener(exec,DOM::EventImpl::BEFORECOPY_EVENT,value);
break;
case OnCopy:
setListener(exec,DOM::EventImpl::COPY_EVENT,value);
break;
case OnBeforePaste:
setListener(exec,DOM::EventImpl::BEFOREPASTE_EVENT,value);
break;
case OnPaste:
setListener(exec,DOM::EventImpl::PASTE_EVENT,value);
break;
case OnDragEnter:
setListener(exec,DOM::EventImpl::DRAGENTER_EVENT,value);
break;
case OnDragOver:
setListener(exec,DOM::EventImpl::DRAGOVER_EVENT,value);
break;
case OnDragLeave:
setListener(exec,DOM::EventImpl::DRAGLEAVE_EVENT,value);
break;
case OnDrop:
setListener(exec,DOM::EventImpl::DROP_EVENT,value);
break;
case OnDragStart:
setListener(exec,DOM::EventImpl::DRAGSTART_EVENT,value);
break;
case OnDrag:
setListener(exec,DOM::EventImpl::DRAG_EVENT,value);
break;
case OnDragEnd:
setListener(exec,DOM::EventImpl::DRAGEND_EVENT,value);
break;
case OnMove:
setListener(exec,DOM::EventImpl::KHTML_MOVE_EVENT,value);
break;
case OnReset:
setListener(exec,DOM::EventImpl::RESET_EVENT,value);
break;
case OnResize:
setListener(exec,DOM::EventImpl::RESIZE_EVENT,value);
break;
case OnScroll:
setListener(exec,DOM::EventImpl::SCROLL_EVENT,value);
#if APPLE_CHANGES
case OnSearch:
setListener(exec,DOM::EventImpl::SEARCH_EVENT,value);
break;
#endif
case OnSelect:
setListener(exec,DOM::EventImpl::SELECT_EVENT,value);
break;
case OnSelectStart:
setListener(exec,DOM::EventImpl::SELECTSTART_EVENT,value);
break;
case OnSubmit:
setListener(exec,DOM::EventImpl::SUBMIT_EVENT,value);
break;
case OnUnload:
setListener(exec,DOM::EventImpl::UNLOAD_EVENT,value);
break;
case ScrollTop: {
khtml::RenderObject *rend = node.handle() ? node.handle()->renderer() : 0L;
if (rend && rend->hasOverflowClip())
rend->layer()->scrollToYOffset(value.toInt32(exec));
break;
}
case ScrollLeft: {
khtml::RenderObject *rend = node.handle() ? node.handle()->renderer() : 0L;
if (rend && rend->hasOverflowClip())
rend->layer()->scrollToXOffset(value.toInt32(exec));
break;
}
default:
kdWarning() << "DOMNode::putValue unhandled token " << token << endl;
}
}
Value DOMNode::toPrimitive(ExecState *exec, Type ) const
{
if (node.isNull())
return Null();
return String(toString(exec));
}
UString DOMNode::toString(ExecState *) const
{
if (node.isNull())
return "null";
UString s;
DOM::Element e = node;
if ( !e.isNull() ) {
s = UString(e.nodeName().string());
} else
s = className();
return "[object " + s + "]";
}
void DOMNode::setListener(ExecState *exec, int eventId, Value func) const
{
node.handle()->setHTMLEventListener(eventId,Window::retrieveActive(exec)->getJSEventListener(func,true));
}
Value DOMNode::getListener(int eventId) const
{
DOM::EventListener *listener = node.handle()->getHTMLEventListener(eventId);
JSEventListener *jsListener = static_cast<JSEventListener*>(listener);
if ( jsListener && jsListener->listenerObjImp() )
return jsListener->listenerObj();
else
return Null();
}
void DOMNode::pushEventHandlerScope(ExecState *, ScopeChain &) const
{
}
Value DOMNodeProtoFunc::tryCall(ExecState *exec, Object &thisObj, const List &args)
{
if (!thisObj.inherits(&DOMNode::info)) {
Object err = Error::create(exec,TypeError);
exec->setException(err);
return err;
}
DOM::Node node = static_cast<DOMNode *>( thisObj.imp() )->toNode();
switch (id) {
case DOMNode::HasAttributes:
return Boolean(node.hasAttributes());
case DOMNode::HasChildNodes:
return Boolean(node.hasChildNodes());
case DOMNode::CloneNode:
return getDOMNode(exec,node.cloneNode(args[0].toBoolean(exec)));
case DOMNode::Normalize:
node.normalize();
return Undefined();
case DOMNode::IsSupported:
return Boolean(node.isSupported(args[0].toString(exec).string(),
(args[1].type() != UndefinedType && args[1].type() != NullType) ? args[1].toString(exec).string() : DOMString()));
case DOMNode::AddEventListener: {
JSEventListener *listener = Window::retrieveActive(exec)->getJSEventListener(args[1]);
if (listener)
node.addEventListener(args[0].toString(exec).string(),listener,args[2].toBoolean(exec));
return Undefined();
}
case DOMNode::RemoveEventListener: {
JSEventListener *listener = Window::retrieveActive(exec)->getJSEventListener(args[1]);
if (listener)
node.removeEventListener(args[0].toString(exec).string(),listener,args[2].toBoolean(exec));
return Undefined();
}
case DOMNode::DispatchEvent:
return Boolean(node.dispatchEvent(toEvent(args[0])));
case DOMNode::AppendChild:
return getDOMNode(exec,node.appendChild(toNode(args[0])));
case DOMNode::RemoveChild:
return getDOMNode(exec,node.removeChild(toNode(args[0])));
case DOMNode::InsertBefore:
return getDOMNode(exec,node.insertBefore(toNode(args[0]), toNode(args[1])));
case DOMNode::ReplaceChild:
return getDOMNode(exec,node.replaceChild(toNode(args[0]), toNode(args[1])));
case DOMNode::Contains:
{
int exceptioncode=0;
DOM::Node other = toNode(args[0]);
if (!other.isNull() && node.nodeType()==DOM::Node::ELEMENT_NODE)
{
DOM::NodeBaseImpl *impl = static_cast<DOM::NodeBaseImpl *>(node.handle());
bool retval = !impl->checkNoOwner(other.handle(),exceptioncode);
return Boolean(retval && exceptioncode == 0);
}
return Undefined();
}
case DOMNode::Item:
return getDOMNode(exec, node.childNodes().item(static_cast<unsigned long>(args[0].toNumber(exec))));
}
return Undefined();
}
const ClassInfo DOMNodeList::info = { "NodeList", 0, 0, 0 };
DOMNodeList::~DOMNodeList()
{
ScriptInterpreter::forgetDOMObject(list.handle());
}
Value DOMNodeList::toPrimitive(ExecState *exec, Type ) const
{
if (list.isNull())
return Null();
return String(toString(exec));
}
bool DOMNodeList::hasProperty(ExecState *exec, const Identifier &p) const
{
if (p == lengthPropertyName || p == "item")
return true;
return ObjectImp::hasProperty(exec, p);
}
Value DOMNodeList::tryGet(ExecState *exec, const Identifier &p) const
{
#ifdef KJS_VERBOSE
kdDebug(6070) << "DOMNodeList::tryGet " << p.ascii() << endl;
#endif
Value result;
if (p == lengthPropertyName)
result = Number(list.length());
else if (p == "item") {
result = lookupOrCreateFunction<DOMNodeListFunc>(exec, p, this, DOMNodeListFunc::Item, 1, DontDelete|Function);
}
else {
bool ok;
long unsigned int idx = p.toULong(&ok);
if (ok) {
result = getDOMNode(exec,list.item(idx));
} else {
DOM::Node node = list.itemById(p.string());
if (!node.isNull()) {
result = getDOMNode(exec, node);
} else {
result = ObjectImp::get(exec, p);
}
}
}
return result;
}
Value DOMNodeList::call(ExecState *exec, Object &thisObj, const List &args)
{
Value val;
try {
val = tryCall(exec, thisObj, args);
}
catch (...) {
Object err = Error::create(exec, GeneralError, "Exception from DOMNodeList");
exec->setException(err);
}
return val;
}
Value DOMNodeList::tryCall(ExecState *exec, Object &, const List &args)
{
UString s = args[0].toString(exec);
bool ok;
unsigned int u = s.toULong(&ok);
if (ok)
return getDOMNode(exec,list.item(u));
kdWarning() << "KJS::DOMNodeList::tryCall " << s.qstring() << " not implemented" << endl;
return Undefined();
}
DOMNodeListFunc::DOMNodeListFunc(ExecState *exec, int i, int len)
: DOMFunction(), id(i)
{
Value protect(this);
put(exec,lengthPropertyName,Number(len),DontDelete|ReadOnly|DontEnum);
}
Value DOMNodeListFunc::tryCall(ExecState *exec, Object &thisObj, const List &args)
{
if (!thisObj.inherits(&KJS::DOMNodeList::info)) {
Object err = Error::create(exec,TypeError);
exec->setException(err);
return err;
}
DOM::NodeList list = static_cast<DOMNodeList *>(thisObj.imp())->nodeList();
Value result;
if (id == Item)
result = getDOMNode(exec, list.item(args[0].toInt32(exec)));
return result;
}
const ClassInfo DOMAttr::info = { "Attr", &DOMNode::info, &DOMAttrTable, 0 };
Value DOMAttr::tryGet(ExecState *exec, const Identifier &propertyName) const
{
#ifdef KJS_VERBOSE
kdDebug(6070) << "DOMAttr::tryPut " << propertyName.qstring() << endl;
#endif
return DOMObjectLookupGetValue<DOMAttr,DOMNode>(exec, propertyName,
&DOMAttrTable, this );
}
Value DOMAttr::getValueProperty(ExecState *exec, int token) const
{
switch (token) {
case Name:
return getStringOrNull(static_cast<DOM::Attr>(node).name());
case Specified:
return Boolean(static_cast<DOM::Attr>(node).specified());
case ValueProperty:
return getStringOrNull(static_cast<DOM::Attr>(node).value());
case OwnerElement: return getDOMNode(exec,static_cast<DOM::Attr>(node).ownerElement());
}
return Value(); }
void DOMAttr::tryPut(ExecState *exec, const Identifier &propertyName, const Value& value, int attr)
{
#ifdef KJS_VERBOSE
kdDebug(6070) << "DOMAttr::tryPut " << propertyName.qstring() << endl;
#endif
DOMObjectLookupPut<DOMAttr,DOMNode>(exec, propertyName, value, attr,
&DOMAttrTable, this );
}
void DOMAttr::putValue(ExecState *exec, int token, const Value& value, int )
{
switch (token) {
case ValueProperty:
static_cast<DOM::Attr>(node).setValue(value.toString(exec).string());
return;
default:
kdWarning() << "DOMAttr::putValue unhandled token " << token << endl;
}
}
DEFINE_PROTOTYPE("DOMDocument", DOMDocumentProto)
IMPLEMENT_PROTOFUNC(DOMDocumentProtoFunc)
IMPLEMENT_PROTOTYPE_WITH_PARENT(DOMDocumentProto, DOMDocumentProtoFunc, DOMNodeProto)
const ClassInfo DOMDocument::info = { "Document", &DOMNode::info, &DOMDocumentTable, 0 };
DOMDocument::DOMDocument(ExecState *exec, const DOM::Document &d)
: DOMNode(DOMDocumentProto::self(exec), d) { }
DOMDocument::DOMDocument(const Object &proto, const DOM::Document &d)
: DOMNode(proto, d) { }
DOMDocument::~DOMDocument()
{
ScriptInterpreter::forgetDOMObject(node.handle());
}
Value DOMDocument::tryGet(ExecState *exec, const Identifier &propertyName) const
{
#ifdef KJS_VERBOSE
kdDebug(6070) << "DOMDocument::tryGet " << propertyName.qstring() << endl;
#endif
return DOMObjectLookupGetValue<DOMDocument, DOMNode>(
exec, propertyName, &DOMDocumentTable, this);
}
Value DOMDocument::getValueProperty(ExecState *exec, int token) const
{
DOM::Document doc = static_cast<DOM::Document>(node);
switch(token) {
case DocType:
return getDOMNode(exec,doc.doctype());
case Implementation:
return getDOMDOMImplementation(exec,doc.implementation());
case DocumentElement:
return getDOMNode(exec,doc.documentElement());
case StyleSheets:
return getDOMStyleSheetList(exec, doc.styleSheets(), doc);
case PreferredStylesheetSet:
return getStringOrNull(doc.preferredStylesheetSet());
case SelectedStylesheetSet:
return getStringOrNull(doc.selectedStylesheetSet());
case ReadyState:
{
DOM::DocumentImpl* docimpl = node.handle()->getDocument();
if ( docimpl )
{
KHTMLPart* part = docimpl->part();
if ( part ) {
if (part->d->m_bComplete) return String("complete");
if (docimpl->parsing()) return String("loading");
return String("loaded");
}
}
return Undefined();
}
case DOMDocument::DefaultView: return getDOMAbstractView(exec,doc.defaultView());
default:
kdWarning() << "DOMDocument::getValueProperty unhandled token " << token << endl;
return Value();
}
}
void DOMDocument::tryPut(ExecState *exec, const Identifier& propertyName, const Value& value, int attr)
{
#ifdef KJS_VERBOSE
kdDebug(6070) << "DOMDocument::tryPut " << propertyName.qstring() << endl;
#endif
DOMObjectLookupPut<DOMDocument,DOMNode>(exec, propertyName, value, attr, &DOMDocumentTable, this );
}
void DOMDocument::putValue(ExecState *exec, int token, const Value& value, int )
{
DOM::Document doc = static_cast<DOM::Document>(node);
switch (token) {
case SelectedStylesheetSet: {
doc.setSelectedStylesheetSet(value.toString(exec).string());
break;
}
}
}
Value DOMDocumentProtoFunc::tryCall(ExecState *exec, Object &thisObj, const List &args)
{
if (!thisObj.inherits(&KJS::DOMNode::info)) {
Object err = Error::create(exec,TypeError);
exec->setException(err);
return err;
}
DOM::Node node = static_cast<DOMNode *>( thisObj.imp() )->toNode();
DOM::Document doc = static_cast<DOM::Document>(node);
String str = args[0].toString(exec);
DOM::DOMString s = str.value().string();
switch(id) {
case DOMDocument::CreateElement:
return getDOMNode(exec,doc.createElement(s));
case DOMDocument::CreateDocumentFragment:
return getDOMNode(exec,doc.createDocumentFragment());
case DOMDocument::CreateTextNode:
return getDOMNode(exec,doc.createTextNode(s));
case DOMDocument::CreateComment:
return getDOMNode(exec,doc.createComment(s));
case DOMDocument::CreateCDATASection:
return getDOMNode(exec,doc.createCDATASection(s));
case DOMDocument::CreateProcessingInstruction:
return getDOMNode(exec,doc.createProcessingInstruction(args[0].toString(exec).string(),
args[1].toString(exec).string()));
case DOMDocument::CreateAttribute:
return getDOMNode(exec,doc.createAttribute(s));
case DOMDocument::CreateEntityReference:
return getDOMNode(exec,doc.createEntityReference(args[0].toString(exec).string()));
case DOMDocument::GetElementsByTagName:
return getDOMNodeList(exec,doc.getElementsByTagName(s));
case DOMDocument::ImportNode: return getDOMNode(exec,doc.importNode(toNode(args[0]), args[1].toBoolean(exec)));
case DOMDocument::CreateElementNS: return getDOMNode(exec,doc.createElementNS(args[0].toString(exec).string(), args[1].toString(exec).string()));
case DOMDocument::CreateAttributeNS: return getDOMNode(exec,doc.createAttributeNS(args[0].toString(exec).string(),args[1].toString(exec).string()));
case DOMDocument::GetElementsByTagNameNS: return getDOMNodeList(exec,doc.getElementsByTagNameNS(args[0].toString(exec).string(),
args[1].toString(exec).string()));
case DOMDocument::GetElementById:
return getDOMNode(exec,doc.getElementById(args[0].toString(exec).string()));
case DOMDocument::CreateRange:
return getDOMRange(exec,doc.createRange());
case DOMDocument::CreateNodeIterator: {
NodeFilter filter;
if (!args[2].isA(NullType)) {
Object obj = Object::dynamicCast(args[2]);
if (!obj.isNull())
filter = NodeFilter(new JSNodeFilterCondition(obj));
}
return getDOMNodeIterator(exec, doc.createNodeIterator(toNode(args[0]), (long unsigned int)(args[1].toNumber(exec)), filter, args[3].toBoolean(exec)));
}
case DOMDocument::CreateTreeWalker: {
NodeFilter filter;
if (!args[2].isA(NullType)) {
Object obj = Object::dynamicCast(args[2]);
if (!obj.isNull())
filter = NodeFilter(new JSNodeFilterCondition(obj));
}
return getDOMTreeWalker(exec, doc.createTreeWalker(toNode(args[0]), (long unsigned int)(args[1].toNumber(exec)), filter, args[3].toBoolean(exec)));
}
case DOMDocument::CreateEvent:
return getDOMEvent(exec,doc.createEvent(s));
case DOMDocument::GetOverrideStyle: {
DOM::Node arg0 = toNode(args[0]);
if (arg0.nodeType() != DOM::Node::ELEMENT_NODE)
return Undefined(); else
return getDOMCSSStyleDeclaration(exec,doc.getOverrideStyle(static_cast<DOM::Element>(arg0),args[1].toString(exec).string()));
}
case DOMDocument::ExecCommand: {
return Boolean(doc.execCommand(args[0].toString(exec).string(), args[1].toBoolean(exec), args[2].toString(exec).string()));
}
case DOMDocument::QueryCommandEnabled: {
return Boolean(doc.queryCommandEnabled(args[0].toString(exec).string()));
}
case DOMDocument::QueryCommandIndeterm: {
return Boolean(doc.queryCommandIndeterm(args[0].toString(exec).string()));
}
case DOMDocument::QueryCommandState: {
return Boolean(doc.queryCommandState(args[0].toString(exec).string()));
}
case DOMDocument::QueryCommandSupported: {
return Boolean(doc.queryCommandSupported(args[0].toString(exec).string()));
}
case DOMDocument::QueryCommandValue: {
DOM::DOMString commandValue(doc.queryCommandValue(args[0].toString(exec).string()));
if (commandValue.isNull())
return Boolean(false);
else
return String(commandValue);
}
default:
break;
}
return Undefined();
}
DEFINE_PROTOTYPE("DOMElement",DOMElementProto)
IMPLEMENT_PROTOFUNC(DOMElementProtoFunc)
IMPLEMENT_PROTOTYPE_WITH_PARENT(DOMElementProto,DOMElementProtoFunc,DOMNodeProto)
const ClassInfo DOMElement::info = { "Element", &DOMNode::info, &DOMElementTable, 0 };
DOMElement::DOMElement(ExecState *exec, const DOM::Element &e)
: DOMNode(DOMElementProto::self(exec), e) { }
DOMElement::DOMElement(const Object &proto, const DOM::Element &e)
: DOMNode(proto, e) { }
Value DOMElement::tryGet(ExecState *exec, const Identifier &propertyName) const
{
#ifdef KJS_VERBOSE
kdDebug(6070) << "DOMElement::tryGet " << propertyName.qstring() << endl;
#endif
DOM::Element element = static_cast<DOM::Element>(node);
const HashEntry* entry = Lookup::findEntry(&DOMElementTable, propertyName);
if (entry)
{
switch( entry->value ) {
case TagName:
return getStringOrNull(element.tagName());
case Style:
return getDOMCSSStyleDeclaration(exec,element.style());
default:
kdWarning() << "Unhandled token in DOMElement::tryGet : " << entry->value << endl;
break;
}
}
if (DOMNode::hasProperty(exec, propertyName))
return DOMNode::tryGet(exec, propertyName);
DOM::DOMString attr = element.getAttribute( propertyName.string() );
if ( !attr.isNull() )
return getStringOrNull( attr );
return Undefined();
}
Value DOMElementProtoFunc::tryCall(ExecState *exec, Object &thisObj, const List &args)
{
if (!thisObj.inherits(&KJS::DOMNode::info)) { Object err = Error::create(exec,TypeError);
exec->setException(err);
return err;
}
DOM::Node node = static_cast<DOMNode *>( thisObj.imp() )->toNode();
DOM::Element element = static_cast<DOM::Element>(node);
switch(id) {
case DOMElement::GetAttribute:
return getStringOrNull(element.getAttribute(args[0].toString(exec).string()));
case DOMElement::SetAttribute:
element.setAttribute(args[0].toString(exec).string(),args[1].toString(exec).string());
return Undefined();
case DOMElement::RemoveAttribute:
element.removeAttribute(args[0].toString(exec).string());
return Undefined();
case DOMElement::GetAttributeNode:
return getDOMNode(exec,element.getAttributeNode(args[0].toString(exec).string()));
case DOMElement::SetAttributeNode:
return getDOMNode(exec,element.setAttributeNode((new DOMNode(exec,KJS::toNode(args[0])))->toNode()));
case DOMElement::RemoveAttributeNode:
return getDOMNode(exec,element.removeAttributeNode((new DOMNode(exec,KJS::toNode(args[0])))->toNode()));
case DOMElement::GetElementsByTagName:
return getDOMNodeList(exec,element.getElementsByTagName(args[0].toString(exec).string()));
case DOMElement::HasAttribute: return Boolean(element.hasAttribute(args[0].toString(exec).string()));
case DOMElement::GetAttributeNS: return String(element.getAttributeNS(args[0].toString(exec).string(),args[1].toString(exec).string()));
case DOMElement::SetAttributeNS: element.setAttributeNS(args[0].toString(exec).string(),args[1].toString(exec).string(),args[2].toString(exec).string());
return Undefined();
case DOMElement::RemoveAttributeNS: element.removeAttributeNS(args[0].toString(exec).string(),args[1].toString(exec).string());
return Undefined();
case DOMElement::GetAttributeNodeNS: return getDOMNode(exec,element.getAttributeNodeNS(args[0].toString(exec).string(),args[1].toString(exec).string()));
case DOMElement::SetAttributeNodeNS: return getDOMNode(exec,element.setAttributeNodeNS((new DOMNode(exec,KJS::toNode(args[0])))->toNode()));
case DOMElement::GetElementsByTagNameNS: return getDOMNodeList(exec,element.getElementsByTagNameNS(args[0].toString(exec).string(),args[1].toString(exec).string()));
case DOMElement::HasAttributeNS: return Boolean(element.hasAttributeNS(args[0].toString(exec).string(),args[1].toString(exec).string()));
case DOMElement::ScrollByLines:
case DOMElement::ScrollByPages:
{
DOM::DocumentImpl* docimpl = node.handle()->getDocument();
if (docimpl) {
docimpl->updateLayoutIgnorePendingStylesheets();
}
khtml::RenderObject *rend = node.handle() ? node.handle()->renderer() : 0L;
if (rend && rend->hasOverflowClip()) {
KWQScrollDirection direction = KWQScrollDown;
int multiplier = args[0].toInt32(exec);
if (multiplier < 0) {
direction = KWQScrollUp;
multiplier = -multiplier;
}
KWQScrollGranularity granularity = id == DOMElement::ScrollByLines ? KWQScrollLine : KWQScrollPage;
rend->layer()->scroll(direction, granularity, multiplier);
}
return Undefined();
}
default:
return Undefined();
}
}
DEFINE_PROTOTYPE("DOMImplementation",DOMDOMImplementationProto)
IMPLEMENT_PROTOFUNC(DOMDOMImplementationProtoFunc)
IMPLEMENT_PROTOTYPE(DOMDOMImplementationProto,DOMDOMImplementationProtoFunc)
const ClassInfo DOMDOMImplementation::info = { "DOMImplementation", 0, 0, 0 };
DOMDOMImplementation::DOMDOMImplementation(ExecState *exec, const DOM::DOMImplementation &i)
: DOMObject(DOMDOMImplementationProto::self(exec)), implementation(i) { }
DOMDOMImplementation::~DOMDOMImplementation()
{
ScriptInterpreter::forgetDOMObject(implementation.handle());
}
Value DOMDOMImplementationProtoFunc::tryCall(ExecState *exec, Object &thisObj, const List &args)
{
if (!thisObj.inherits(&KJS::DOMDOMImplementation::info)) {
Object err = Error::create(exec,TypeError);
exec->setException(err);
return err;
}
DOM::DOMImplementation implementation = static_cast<DOMDOMImplementation *>( thisObj.imp() )->toImplementation();
switch(id) {
case DOMDOMImplementation::HasFeature:
return Boolean(implementation.hasFeature(args[0].toString(exec).string(),
(args[1].type() != UndefinedType && args[1].type() != NullType) ? args[1].toString(exec).string() : DOMString()));
case DOMDOMImplementation::CreateDocumentType: return getDOMNode(exec,implementation.createDocumentType(args[0].toString(exec).string(),args[1].toString(exec).string(),args[2].toString(exec).string()));
case DOMDOMImplementation::CreateDocument: return getDOMNode(exec,implementation.createDocument(args[0].toString(exec).string(),args[1].toString(exec).string(),toNode(args[2])));
case DOMDOMImplementation::CreateCSSStyleSheet: return getDOMStyleSheet(exec,implementation.createCSSStyleSheet(args[0].toString(exec).string(),args[1].toString(exec).string()));
case DOMDOMImplementation::CreateHTMLDocument: return getDOMNode(exec, implementation.createHTMLDocument(args[0].toString(exec).string()));
default:
break;
}
return Undefined();
}
const ClassInfo DOMDocumentType::info = { "DocumentType", &DOMNode::info, &DOMDocumentTypeTable, 0 };
DOMDocumentType::DOMDocumentType(ExecState *exec, const DOM::DocumentType &dt)
: DOMNode( exec, dt ) { }
Value DOMDocumentType::tryGet(ExecState *exec, const Identifier &propertyName) const
{
return DOMObjectLookupGetValue<DOMDocumentType, DOMNode>(exec, propertyName, &DOMDocumentTypeTable, this);
}
Value DOMDocumentType::getValueProperty(ExecState *exec, int token) const
{
DOM::DocumentType type = static_cast<DOM::DocumentType>(node);
switch (token) {
case Name:
return getStringOrNull(type.name());
case Entities:
return getDOMNamedNodeMap(exec,type.entities());
case Notations:
return getDOMNamedNodeMap(exec,type.notations());
case PublicId: return getStringOrNull(type.publicId());
case SystemId: return getStringOrNull(type.systemId());
case InternalSubset: return getStringOrNull(type.internalSubset());
default:
kdWarning() << "DOMDocumentType::getValueProperty unhandled token " << token << endl;
return Value();
}
}
DEFINE_PROTOTYPE("NamedNodeMap", DOMNamedNodeMapProto)
IMPLEMENT_PROTOFUNC(DOMNamedNodeMapProtoFunc)
IMPLEMENT_PROTOTYPE(DOMNamedNodeMapProto,DOMNamedNodeMapProtoFunc)
const ClassInfo DOMNamedNodeMap::info = { "NamedNodeMap", 0, 0, 0 };
DOMNamedNodeMap::DOMNamedNodeMap(ExecState *exec, const DOM::NamedNodeMap &m)
: DOMObject(DOMNamedNodeMapProto::self(exec)), map(m) { }
DOMNamedNodeMap::~DOMNamedNodeMap()
{
ScriptInterpreter::forgetDOMObject(map.handle());
}
bool DOMNamedNodeMap::hasProperty(ExecState *exec, const Identifier &p) const
{
if (p == lengthPropertyName)
return true;
return DOMObject::hasProperty(exec, p);
}
Value DOMNamedNodeMap::tryGet(ExecState* exec, const Identifier &p) const
{
if (p == lengthPropertyName)
return Number(map.length());
bool ok;
long unsigned int idx = p.toULong(&ok);
if (ok)
return getDOMNode(exec,map.item(idx));
return DOMObject::tryGet(exec, p);
}
Value DOMNamedNodeMapProtoFunc::tryCall(ExecState *exec, Object &thisObj, const List &args)
{
if (!thisObj.inherits(&KJS::DOMNamedNodeMap::info)) {
Object err = Error::create(exec,TypeError);
exec->setException(err);
return err;
}
DOM::NamedNodeMap map = static_cast<DOMNamedNodeMap *>(thisObj.imp())->toMap();
switch(id) {
case DOMNamedNodeMap::GetNamedItem:
return getDOMNode(exec, map.getNamedItem(args[0].toString(exec).string()));
case DOMNamedNodeMap::SetNamedItem:
return getDOMNode(exec, map.setNamedItem((new DOMNode(exec,KJS::toNode(args[0])))->toNode()));
case DOMNamedNodeMap::RemoveNamedItem:
return getDOMNode(exec, map.removeNamedItem(args[0].toString(exec).string()));
case DOMNamedNodeMap::Item:
return getDOMNode(exec, map.item(args[0].toInt32(exec)));
case DOMNamedNodeMap::GetNamedItemNS: return getDOMNode(exec, map.getNamedItemNS(args[0].toString(exec).string(),args[1].toString(exec).string()));
case DOMNamedNodeMap::SetNamedItemNS: return getDOMNode(exec, map.setNamedItemNS(toNode(args[0])));
case DOMNamedNodeMap::RemoveNamedItemNS: return getDOMNode(exec, map.removeNamedItemNS(args[0].toString(exec).string(),args[1].toString(exec).string()));
default:
break;
}
return Undefined();
}
const ClassInfo DOMProcessingInstruction::info = { "ProcessingInstruction", &DOMNode::info, &DOMProcessingInstructionTable, 0 };
Value DOMProcessingInstruction::tryGet(ExecState *exec, const Identifier &propertyName) const
{
return DOMObjectLookupGetValue<DOMProcessingInstruction, DOMNode>(exec, propertyName, &DOMProcessingInstructionTable, this);
}
Value DOMProcessingInstruction::getValueProperty(ExecState *exec, int token) const
{
switch (token) {
case Target:
return getStringOrNull(static_cast<DOM::ProcessingInstruction>(node).target());
case Data:
return getStringOrNull(static_cast<DOM::ProcessingInstruction>(node).data());
case Sheet:
return getDOMStyleSheet(exec,static_cast<DOM::ProcessingInstruction>(node).sheet());
default:
kdWarning() << "DOMProcessingInstruction::getValueProperty unhandled token " << token << endl;
return Value();
}
}
void DOMProcessingInstruction::tryPut(ExecState *exec, const Identifier &propertyName, const Value& value, int attr)
{
if (propertyName == "data")
static_cast<DOM::ProcessingInstruction>(node).setData(value.toString(exec).string());
else
DOMNode::tryPut(exec, propertyName,value,attr);
}
const ClassInfo DOMNotation::info = { "Notation", &DOMNode::info, &DOMNotationTable, 0 };
Value DOMNotation::tryGet(ExecState *exec, const Identifier &propertyName) const
{
return DOMObjectLookupGetValue<DOMNotation, DOMNode>(exec, propertyName, &DOMNotationTable, this);
}
Value DOMNotation::getValueProperty(ExecState *, int token) const
{
switch (token) {
case PublicId:
return getStringOrNull(static_cast<DOM::Notation>(node).publicId());
case SystemId:
return getStringOrNull(static_cast<DOM::Notation>(node).systemId());
default:
kdWarning() << "DOMNotation::getValueProperty unhandled token " << token << endl;
return Value();
}
}
const ClassInfo DOMEntity::info = { "Entity", &DOMNode::info, 0, 0 };
Value DOMEntity::tryGet(ExecState *exec, const Identifier &propertyName) const
{
return DOMObjectLookupGetValue<DOMEntity, DOMNode>(exec, propertyName, &DOMEntityTable, this);
}
Value DOMEntity::getValueProperty(ExecState *, int token) const
{
switch (token) {
case PublicId:
return getStringOrNull(static_cast<DOM::Entity>(node).publicId());
case SystemId:
return getStringOrNull(static_cast<DOM::Entity>(node).systemId());
case NotationName:
return getStringOrNull(static_cast<DOM::Entity>(node).notationName());
default:
kdWarning() << "DOMEntity::getValueProperty unhandled token " << token << endl;
return Value();
}
}
Value KJS::getDOMDocumentNode(ExecState *exec, const DOM::Document &n)
{
DOMDocument *ret = 0;
ScriptInterpreter* interp = static_cast<ScriptInterpreter *>(exec->dynamicInterpreter());
if ((ret = static_cast<DOMDocument *>(interp->getDOMObject(n.handle()))))
return Value(ret);
if (n.isHTMLDocument())
ret = new HTMLDocument(exec, static_cast<DOM::HTMLDocument>(n));
else
ret = new DOMDocument(exec, n);
Value val(ret);
if (n.view()) {
static Identifier documentIdentifier("document");
Window::retrieveWindow(n.view()->part())->putDirect(documentIdentifier, ret, DontDelete|ReadOnly);
}
interp->putDOMObject(n.handle(), ret);
return val;
}
bool KJS::checkNodeSecurity(ExecState *exec, const DOM::Node& n)
{
if (!n.handle())
return false;
KHTMLPart *part = n.handle()->getDocument()->part();
Window* win = part ? Window::retrieveWindow(part) : 0L;
if ( !win || !win->isSafeScript(exec) )
return false;
return true;
}
Value KJS::getDOMNode(ExecState *exec, const DOM::Node &n)
{
DOMObject *ret = 0;
if (n.isNull())
return Null();
ScriptInterpreter* interp = static_cast<ScriptInterpreter *>(exec->dynamicInterpreter());
DOM::NodeImpl *doc = n.ownerDocument().handle();
if ((ret = interp->getDOMObjectForDocument(static_cast<DOM::DocumentImpl *>(doc), n.handle())))
return Value(ret);
switch (n.nodeType()) {
case DOM::Node::ELEMENT_NODE:
if (static_cast<DOM::Element>(n).isHTMLElement())
ret = new HTMLElement(exec, static_cast<DOM::HTMLElement>(n));
else
ret = new DOMElement(exec, static_cast<DOM::Element>(n));
break;
case DOM::Node::ATTRIBUTE_NODE:
ret = new DOMAttr(exec, static_cast<DOM::Attr>(n));
break;
case DOM::Node::TEXT_NODE:
case DOM::Node::CDATA_SECTION_NODE:
ret = new DOMText(exec, static_cast<DOM::Text>(n));
break;
case DOM::Node::ENTITY_REFERENCE_NODE:
ret = new DOMNode(exec, n);
break;
case DOM::Node::ENTITY_NODE:
ret = new DOMEntity(exec, static_cast<DOM::Entity>(n));
break;
case DOM::Node::PROCESSING_INSTRUCTION_NODE:
ret = new DOMProcessingInstruction(exec, static_cast<DOM::ProcessingInstruction>(n));
break;
case DOM::Node::COMMENT_NODE:
ret = new DOMCharacterData(exec, static_cast<DOM::CharacterData>(n));
break;
case DOM::Node::DOCUMENT_NODE:
return getDOMDocumentNode(exec, static_cast<DOM::Document>(n));
case DOM::Node::DOCUMENT_TYPE_NODE:
ret = new DOMDocumentType(exec, static_cast<DOM::DocumentType>(n));
break;
case DOM::Node::DOCUMENT_FRAGMENT_NODE:
ret = new DOMNode(exec, n);
break;
case DOM::Node::NOTATION_NODE:
ret = new DOMNotation(exec, static_cast<DOM::Notation>(n));
break;
default:
ret = new DOMNode(exec, n);
}
interp->putDOMObjectForDocument(static_cast<DOM::DocumentImpl *>(doc), n.handle(), ret);
return Value(ret);
}
Value KJS::getDOMNamedNodeMap(ExecState *exec, const DOM::NamedNodeMap &m)
{
return Value(cacheDOMObject<DOM::NamedNodeMap, KJS::DOMNamedNodeMap>(exec, m));
}
Value KJS::getRuntimeObject(ExecState *exec, const DOM::Node &node)
{
DOM::HTMLElement element = static_cast<DOM::HTMLElement>(node);
if (!node.isNull()) {
if (node.handle()->id() == ID_APPLET) {
DOM::HTMLAppletElementImpl *appletElement = static_cast<DOM::HTMLAppletElementImpl *>(element.handle());
if (appletElement->getAppletInstance()) {
RuntimeObjectImp *appletImp = new RuntimeObjectImp(appletElement->getAppletInstance(), false);
return Value(appletImp);
}
}
else if (node.handle()->id() == ID_EMBED) {
DOM::HTMLEmbedElementImpl *embedElement = static_cast<DOM::HTMLEmbedElementImpl *>(element.handle());
if (embedElement->getEmbedInstance()) {
RuntimeObjectImp *runtimeImp = new RuntimeObjectImp(embedElement->getEmbedInstance(), false);
return Value(runtimeImp);
}
}
else if (node.handle()->id() == ID_OBJECT) {
DOM::HTMLObjectElementImpl *objectElement = static_cast<DOM::HTMLObjectElementImpl *>(element.handle());
if (objectElement->getObjectInstance()) {
RuntimeObjectImp *runtimeImp = new RuntimeObjectImp(objectElement->getObjectInstance(), false);
return Value(runtimeImp);
}
}
}
return Value();
}
Value KJS::getDOMNodeList(ExecState *exec, const DOM::NodeList &l)
{
return Value(cacheDOMObject<DOM::NodeList, KJS::DOMNodeList>(exec, l));
}
Value KJS::getDOMDOMImplementation(ExecState *exec, const DOM::DOMImplementation &i)
{
return Value(cacheDOMObject<DOM::DOMImplementation, KJS::DOMDOMImplementation>(exec, i));
}
const ClassInfo NodeConstructor::info = { "NodeConstructor", 0, &NodeConstructorTable, 0 };
Value NodeConstructor::tryGet(ExecState *exec, const Identifier &propertyName) const
{
return DOMObjectLookupGetValue<NodeConstructor, DOMObject>(exec, propertyName, &NodeConstructorTable, this);
}
Value NodeConstructor::getValueProperty(ExecState *, int token) const
{
return Number((unsigned int)token);
#if 0
switch (token) {
case ELEMENT_NODE:
return Number((unsigned int)DOM::Node::ELEMENT_NODE);
case ATTRIBUTE_NODE:
return Number((unsigned int)DOM::Node::ATTRIBUTE_NODE);
case TEXT_NODE:
return Number((unsigned int)DOM::Node::TEXT_NODE);
case CDATA_SECTION_NODE:
return Number((unsigned int)DOM::Node::CDATA_SECTION_NODE);
case ENTITY_REFERENCE_NODE:
return Number((unsigned int)DOM::Node::ENTITY_REFERENCE_NODE);
case ENTITY_NODE:
return Number((unsigned int)DOM::Node::ENTITY_NODE);
case PROCESSING_INSTRUCTION_NODE:
return Number((unsigned int)DOM::Node::PROCESSING_INSTRUCTION_NODE);
case COMMENT_NODE:
return Number((unsigned int)DOM::Node::COMMENT_NODE);
case DOCUMENT_NODE:
return Number((unsigned int)DOM::Node::DOCUMENT_NODE);
case DOCUMENT_TYPE_NODE:
return Number((unsigned int)DOM::Node::DOCUMENT_TYPE_NODE);
case DOCUMENT_FRAGMENT_NODE:
return Number((unsigned int)DOM::Node::DOCUMENT_FRAGMENT_NODE);
case NOTATION_NODE:
return Number((unsigned int)DOM::Node::NOTATION_NODE);
default:
kdWarning() << "NodeConstructor::getValueProperty unhandled token " << token << endl;
return Value();
}
#endif
}
Object KJS::getNodeConstructor(ExecState *exec)
{
return Object(cacheGlobalObject<NodeConstructor>(exec, "[[node.constructor]]"));
}
const ClassInfo DOMExceptionConstructor::info = { "DOMExceptionConstructor", 0, 0, 0 };
Value DOMExceptionConstructor::tryGet(ExecState *exec, const Identifier &propertyName) const
{
return DOMObjectLookupGetValue<DOMExceptionConstructor, DOMObject>(exec, propertyName, &DOMExceptionConstructorTable, this);
}
Value DOMExceptionConstructor::getValueProperty(ExecState *, int token) const
{
return Number((unsigned int)token);
#if 0
switch (token) {
case INDEX_SIZE_ERR:
return Number((unsigned int)DOM::DOMException::INDEX_SIZE_ERR);
case DOMSTRING_SIZE_ERR:
return Number((unsigned int)DOM::DOMException::DOMSTRING_SIZE_ERR);
case HIERARCHY_REQUEST_ERR:
return Number((unsigned int)DOM::DOMException::HIERARCHY_REQUEST_ERR);
case WRONG_DOCUMENT_ERR:
return Number((unsigned int)DOM::DOMException::WRONG_DOCUMENT_ERR);
case INVALID_CHARACTER_ERR:
return Number((unsigned int)DOM::DOMException::INVALID_CHARACTER_ERR);
case NO_DATA_ALLOWED_ERR:
return Number((unsigned int)DOM::DOMException::NO_DATA_ALLOWED_ERR);
case NO_MODIFICATION_ALLOWED_ERR:
return Number((unsigned int)DOM::DOMException::NO_MODIFICATION_ALLOWED_ERR);
case NOT_FOUND_ERR:
return Number((unsigned int)DOM::DOMException::NOT_FOUND_ERR);
case NOT_SUPPORTED_ERR:
return Number((unsigned int)DOM::DOMException::NOT_SUPPORTED_ERR);
case INUSE_ATTRIBUTE_ERR:
return Number((unsigned int)DOM::DOMException::INUSE_ATTRIBUTE_ERR);
case INVALID_STATE_ERR:
return Number((unsigned int)DOM::DOMException::INVALID_STATE_ERR);
case SYNTAX_ERR:
return Number((unsigned int)DOM::DOMException::SYNTAX_ERR);
case INVALID_MODIFICATION_ERR:
return Number((unsigned int)DOM::DOMException::INVALID_MODIFICATION_ERR);
case NAMESPACE_ERR:
return Number((unsigned int)DOM::DOMException::NAMESPACE_ERR);
case INVALID_ACCESS_ERR:
return Number((unsigned int)DOM::DOMException::INVALID_ACCESS_ERR);
default:
kdWarning() << "DOMExceptionConstructor::getValueProperty unhandled token " << token << endl;
return Value();
}
#endif
}
Object KJS::getDOMExceptionConstructor(ExecState *exec)
{
return cacheGlobalObject<DOMExceptionConstructor>(exec, "[[DOMException.constructor]]");
}
DOMNamedNodesCollection::DOMNamedNodesCollection(ExecState *, const QValueList<DOM::Node>& nodes )
: DOMObject(), m_nodes(nodes)
{
}
Value DOMNamedNodesCollection::tryGet(ExecState *exec, const Identifier &propertyName) const
{
if (propertyName == lengthPropertyName)
return Number(m_nodes.count());
bool ok;
unsigned int u = propertyName.toULong(&ok);
if (ok && u < m_nodes.count()) {
DOM::Node node = m_nodes[u];
return getDOMNode(exec,node);
}
if (!ok) {
for (QValueListConstIterator<DOM::Node> it = m_nodes.begin(); it != m_nodes.end(); it++) {
DOM::Node node = *it;
DOM::NamedNodeMap attributes = node.attributes();
if (attributes.isNull()) {
continue;
}
DOM::Node idAttr = attributes.getNamedItem("id");
if (idAttr.isNull()) {
continue;
}
if (idAttr.nodeValue() == propertyName.string()) {
return getDOMNode(exec,node);
}
}
}
return DOMObject::tryGet(exec,propertyName);
}
const ClassInfo DOMCharacterData::info = { "CharacterImp",
&DOMNode::info, &DOMCharacterDataTable, 0 };
DEFINE_PROTOTYPE("DOMCharacterData",DOMCharacterDataProto)
IMPLEMENT_PROTOFUNC(DOMCharacterDataProtoFunc)
IMPLEMENT_PROTOTYPE_WITH_PARENT(DOMCharacterDataProto,DOMCharacterDataProtoFunc, DOMNodeProto)
DOMCharacterData::DOMCharacterData(ExecState *exec, const DOM::CharacterData &d)
: DOMNode(DOMCharacterDataProto::self(exec), d) {}
DOMCharacterData::DOMCharacterData(const Object &proto, const DOM::CharacterData &d)
: DOMNode(proto, d) {}
Value DOMCharacterData::tryGet(ExecState *exec, const Identifier &p) const
{
#ifdef KJS_VERBOSE
kdDebug(6070)<<"DOMCharacterData::tryGet "<<p.string().string()<<endl;
#endif
return DOMObjectLookupGetValue<DOMCharacterData,DOMNode>(exec,p,&DOMCharacterDataTable,this);
}
Value DOMCharacterData::getValueProperty(ExecState *, int token) const
{
DOM::CharacterData data = static_cast<DOM::CharacterData>(node);
switch (token) {
case Data:
return String(data.data());
case Length:
return Number(data.length());
default:
kdWarning() << "Unhandled token in DOMCharacterData::getValueProperty : " << token << endl;
return Value();
}
}
void DOMCharacterData::tryPut(ExecState *exec, const Identifier &propertyName, const Value& value, int attr)
{
if (propertyName == "data")
static_cast<DOM::CharacterData>(node).setData(value.toString(exec).string());
else
DOMNode::tryPut(exec, propertyName,value,attr);
}
Value DOMCharacterDataProtoFunc::tryCall(ExecState *exec, Object &thisObj, const List &args)
{
if (!thisObj.inherits(&KJS::DOMCharacterData::info)) {
Object err = Error::create(exec,TypeError);
exec->setException(err);
return err;
}
DOM::CharacterData data = static_cast<DOMCharacterData *>(thisObj.imp())->toData();
switch(id) {
case DOMCharacterData::SubstringData: {
const int count = args[1].toInt32(exec);
if (count < 0)
throw DOMException(DOMException::INDEX_SIZE_ERR);
return getStringOrNull(data.substringData(args[0].toInt32(exec), count));
}
case DOMCharacterData::AppendData:
data.appendData(args[0].toString(exec).string());
return Undefined();
case DOMCharacterData::InsertData:
data.insertData(args[0].toInt32(exec), args[1].toString(exec).string());
return Undefined();
case DOMCharacterData::DeleteData: {
const int count = args[1].toInt32(exec);
if (count < 0)
throw DOMException(DOMException::INDEX_SIZE_ERR);
data.deleteData(args[0].toInt32(exec), count);
return Undefined();
}
case DOMCharacterData::ReplaceData: {
const int count = args[1].toInt32(exec);
if (count < 0)
throw DOMException(DOMException::INDEX_SIZE_ERR);
data.replaceData(args[0].toInt32(exec), count, args[2].toString(exec).string());
return Undefined();
}
default:
return Undefined();
}
}
const ClassInfo DOMText::info = { "Text",
&DOMCharacterData::info, 0, 0 };
DEFINE_PROTOTYPE("DOMText",DOMTextProto)
IMPLEMENT_PROTOFUNC(DOMTextProtoFunc)
IMPLEMENT_PROTOTYPE_WITH_PARENT(DOMTextProto,DOMTextProtoFunc,DOMCharacterDataProto)
DOMText::DOMText(ExecState *exec, const DOM::Text &t)
: DOMCharacterData(DOMTextProto::self(exec), t) { }
Value DOMText::tryGet(ExecState *exec, const Identifier &p) const
{
if (p == "")
return Undefined(); else
return DOMCharacterData::tryGet(exec, p);
}
Value DOMTextProtoFunc::tryCall(ExecState *exec, Object &thisObj, const List &args)
{
if (!thisObj.inherits(&KJS::DOMText::info)) {
Object err = Error::create(exec,TypeError);
exec->setException(err);
return err;
}
DOM::Text text = static_cast<DOMText *>(thisObj.imp())->toText();
switch(id) {
case DOMText::SplitText:
return getDOMNode(exec,text.splitText(args[0].toInt32(exec)));
break;
default:
return Undefined();
}
}