| # khtml Library API Documentation
Overview | Class Hierarchy | Classes | Classes (annotated) | Members | Namespaces | Source Files

# kjs_dom.cpp

    00001 // -*- c-basic-offset: 2 -*-
    00002 /*
    00003  *  This file is part of the KDE libraries
    00004  *  Copyright (C) 2000 Harri Porten (porten@kde.org)
    00005  *  Copyright (C) 2003 Apple Computer, Inc.
    00006  *
    00007  *  This library is free software; you can redistribute it and/or
    00008  *  modify it under the terms of the GNU Library General Public
    00009  *  License as published by the Free Software Foundation; either
    00010  *  version 2 of the License, or (at your option) any later version.
    00011  *
    00012  *  This library is distributed in the hope that it will be useful,
    00013  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
    00014  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
    00015  *  Library General Public License for more details.
    00016  *
    00017  *  You should have received a copy of the GNU Library General Public
    00018  *  License along with this library; if not, write to the Free Software
    00019  *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
    00020  */
    00021
    00022 #include <khtmlview.h>
    00023 #include "xml/dom2_eventsimpl.h"
    00024 #include "rendering/render_canvas.h"
    00025 #include "rendering/render_layer.h"
    00026 #include "xml/dom_nodeimpl.h"
    00027 #include "xml/dom_docimpl.h"
    00028 #include "misc/htmltags.h" // ID_*
    00029 #include "misc/htmlattrs.h" // ATTR_*
    00030 #include "html/html_baseimpl.h"
    00031 #include <kdebug.h>
    00032 #include <khtml_part.h>
    00033
    00034 #include "kjs_dom.h"
    00035 #include "kjs_html.h"
    00036 #include "kjs_css.h"
    00037 #include "kjs_range.h"
    00038 #include "kjs_traversal.h"
    00039 #include "kjs_events.h"
    00040 #include "kjs_views.h"
    00041 #include "kjs_window.h"
    00042 #include "dom/dom_exception.h"
    00043 #include "kjs_dom.lut.h"
    00044 #include "khtmlpart_p.h"
    00045
    00046 using namespace KJS;
    00047
    00048 // -------------------------------------------------------------------------
    00049 /* Source for DOMNodeProtoTable.
    00050 @begin DOMNodeProtoTable 13
    00051   insertBefore  DOMNode::InsertBefore   DontDelete|Function 2
    00052   replaceChild  DOMNode::ReplaceChild   DontDelete|Function 2
    00053   removeChild   DOMNode::RemoveChild    DontDelete|Function 1
    00054   appendChild   DOMNode::AppendChild    DontDelete|Function 1
    00055   hasAttributes DOMNode::HasAttributes  DontDelete|Function 0
    00056   hasChildNodes DOMNode::HasChildNodes  DontDelete|Function 0
    00057   cloneNode DOMNode::CloneNode  DontDelete|Function 1
    00058 # DOM2
    00059   normalize DOMNode::Normalize  DontDelete|Function 0
    00060   isSupported   DOMNode::IsSupported    DontDelete|Function 2
    00061 # from the EventTarget interface
    00062   addEventListener  DOMNode::AddEventListener   DontDelete|Function 3
    00063   removeEventListener   DOMNode::RemoveEventListener    DontDelete|Function 3
    00064   dispatchEvent     DOMNode::DispatchEvent  DontDelete|Function 1
    00065 # IE extensions
    00066   contains  DOMNode::Contains       DontDelete|Function 1
    00067   insertAdjacentHTML    DOMNode::InsertAdjacentHTML DontDelete|Function 2
    00068 # "DOM level 0" (from Gecko DOM reference; also in WinIE)
    00069   item          DOMNode::Item           DontDelete|Function 1
    00070 @end
    00071 */
    00072 DEFINE_PROTOTYPE("DOMNode",DOMNodeProto)
    00073 IMPLEMENT_PROTOFUNC_DOM(DOMNodeProtoFunc)
    00074 IMPLEMENT_PROTOTYPE(DOMNodeProto,DOMNodeProtoFunc)
    00075
    00076 const ClassInfo DOMNode::info = { "Node", 0, &DOMNodeTable, 0 };
    00077
    00078 DOMNode::DOMNode(ExecState *exec, const DOM::Node& n)
    00079   : DOMObject(DOMNodeProto::self(exec)), node(n)
    00080 {
    00081 }
    00082
    00083 DOMNode::DOMNode(const Object& proto, const DOM::Node& n)
    00084   : DOMObject(proto), node(n)
    00085 {
    00086 }
    00087
    00088 DOMNode::~DOMNode()
    00089 {
    00090   ScriptInterpreter::forgetDOMObject(node.handle());
    00091 }
    00092
    00093 bool DOMNode::toBoolean(ExecState *) const
    00094 {
    00095     return !node.isNull();
    00096 }
    00097
    00098 /* Source for DOMNodeTable.
    00099 @begin DOMNodeTable 53
    00100   nodeName  DOMNode::NodeName   DontDelete|ReadOnly
    00101   nodeValue DOMNode::NodeValue  DontDelete
    00102   nodeType  DOMNode::NodeType   DontDelete|ReadOnly
    00103   parentNode    DOMNode::ParentNode DontDelete|ReadOnly
    00104   parentElement DOMNode::ParentElement  DontDelete|ReadOnly
    00105   childNodes    DOMNode::ChildNodes DontDelete|ReadOnly
    00106   firstChild    DOMNode::FirstChild DontDelete|ReadOnly
    00107   lastChild DOMNode::LastChild  DontDelete|ReadOnly
    00108   previousSibling  DOMNode::PreviousSibling DontDelete|ReadOnly
    00109   nextSibling   DOMNode::NextSibling    DontDelete|ReadOnly
    00110   attributes    DOMNode::Attributes DontDelete|ReadOnly
    00111   namespaceURI  DOMNode::NamespaceURI   DontDelete|ReadOnly
    00112 # DOM2
    00113   prefix    DOMNode::Prefix     DontDelete
    00114   localName DOMNode::LocalName  DontDelete|ReadOnly
    00115   ownerDocument DOMNode::OwnerDocument  DontDelete|ReadOnly
    00116 # Event handlers
    00117 # IE also has: onactivate, onbefore*, oncontextmenu, oncontrolselect, oncut,
    00118 # ondeactivate, ondrag*, ondrop, onfocusin, onfocusout, onhelp, onmousewheel,
    00119 # onmove*, onpaste, onpropertychange, onreadystatechange, onresizeend/start,
    00120 # onselectionchange, onstop
    00121   onabort   DOMNode::OnAbort        DontDelete
    00122   onblur    DOMNode::OnBlur         DontDelete
    00123   onchange  DOMNode::OnChange       DontDelete
    00124   onclick   DOMNode::OnClick        DontDelete
    00125   ondblclick    DOMNode::OnDblClick     DontDelete
    00126   ondragdrop    DOMNode::OnDragDrop     DontDelete
    00127   onerror   DOMNode::OnError        DontDelete
    00128   onfocus   DOMNode::OnFocus            DontDelete
    00129   onkeydown DOMNode::OnKeyDown      DontDelete
    00130   onkeypress    DOMNode::OnKeyPress     DontDelete
    00131   onkeyup   DOMNode::OnKeyUp        DontDelete
    00132   onload    DOMNode::OnLoad         DontDelete
    00133   onmousedown   DOMNode::OnMouseDown        DontDelete
    00134   onmousemove   DOMNode::OnMouseMove        DontDelete
    00135   onmouseout    DOMNode::OnMouseOut     DontDelete
    00136   onmouseover   DOMNode::OnMouseOver        DontDelete
    00137   onmouseup DOMNode::OnMouseUp      DontDelete
    00138   onmove    DOMNode::OnMove         DontDelete
    00139   onreset   DOMNode::OnReset        DontDelete
    00140   onresize  DOMNode::OnResize       DontDelete
    00141   onselect  DOMNode::OnSelect       DontDelete
    00142   onsubmit  DOMNode::OnSubmit       DontDelete
    00143   onunload  DOMNode::OnUnload       DontDelete
    00144 # IE extensions
    00145   offsetLeft    DOMNode::OffsetLeft     DontDelete|ReadOnly
    00146   offsetTop DOMNode::OffsetTop      DontDelete|ReadOnly
    00147   offsetWidth   DOMNode::OffsetWidth        DontDelete|ReadOnly
    00148   offsetHeight  DOMNode::OffsetHeight       DontDelete|ReadOnly
    00149   offsetParent  DOMNode::OffsetParent       DontDelete|ReadOnly
    00150   clientWidth   DOMNode::ClientWidth        DontDelete|ReadOnly
    00151   clientHeight  DOMNode::ClientHeight       DontDelete|ReadOnly
    00152   scrollLeft    DOMNode::ScrollLeft     DontDelete
    00153   scrollTop DOMNode::ScrollTop      DontDelete
    00154   scrollWidth   DOMNode::ScrollWidth            DontDelete|ReadOnly
    00155   scrollHeight  DOMNode::ScrollHeight           DontDelete|ReadOnly
    00156   sourceIndex   DOMNode::SourceIndex        DontDelete|ReadOnly
    00157 @end
    00158 */
    00159 Value DOMNode::tryGet(ExecState *exec, const Identifier &propertyName) const
    00160 {
    00161 #ifdef KJS_VERBOSE
    00162   kdDebug(6070) << "DOMNode::tryGet " << propertyName.qstring() << endl;
    00163 #endif
    00164   return DOMObjectLookupGetValue<DOMNode, DOMObject>(exec, propertyName, &DOMNodeTable, this);
    00165 }
    00166
    00167 Value DOMNode::getValueProperty(ExecState *exec, int token) const
    00168 {
    00169   switch (token) {
    00170   case NodeName:
    00171     return String(node.nodeName());
    00172   case NodeValue:
    00173     return getString(node.nodeValue()); // initially null, per domts/level1/core/hc_documentcreateelement.html
    00174   case NodeType:
    00175     return Number((unsigned int)node.nodeType());
    00176   case ParentNode:
    00177     return getDOMNode(exec,node.parentNode());
    00178   case ParentElement: // IE only apparently
    00179     return getDOMNode(exec,node.parentNode());
    00180   case ChildNodes:
    00181     return getDOMNodeList(exec,node.childNodes());
    00182   case FirstChild:
    00183     return getDOMNode(exec,node.firstChild());
    00184   case LastChild:
    00185     return getDOMNode(exec,node.lastChild());
    00186   case PreviousSibling:
    00187     return getDOMNode(exec,node.previousSibling());
    00188   case NextSibling:
    00189     return getDOMNode(exec,node.nextSibling());
    00190   case Attributes:
    00191     return getDOMNamedNodeMap(exec,node.attributes());
    00192   case NamespaceURI:
    00193     return getString(node.namespaceURI()); // Moz returns null if not set (dom/namespaces.html)
    00194   case Prefix:
    00195     return getString(node.prefix());  // Moz returns null if not set (dom/namespaces.html)
    00196   case LocalName:
    00197     return getString(node.localName());  // Moz returns null if not set (dom/namespaces.html)
    00198   case OwnerDocument:
    00199     return getDOMNode(exec,node.ownerDocument());
    00200   case OnAbort:
    00201     return getListener(DOM::EventImpl::ABORT_EVENT);
    00202   case OnBlur:
    00203     return getListener(DOM::EventImpl::BLUR_EVENT);
    00204   case OnChange:
    00205     return getListener(DOM::EventImpl::CHANGE_EVENT);
    00206   case OnClick:
    00207     return getListener(DOM::EventImpl::KHTML_ECMA_CLICK_EVENT);
    00208   case OnDblClick:
    00209     return getListener(DOM::EventImpl::KHTML_ECMA_DBLCLICK_EVENT);
    00210   case OnDragDrop:
    00211     return getListener(DOM::EventImpl::KHTML_DRAGDROP_EVENT);
    00212   case OnError:
    00213     return getListener(DOM::EventImpl::KHTML_ERROR_EVENT);
    00214   case OnFocus:
    00215     return getListener(DOM::EventImpl::FOCUS_EVENT);
    00216   case OnKeyDown:
    00217     return getListener(DOM::EventImpl::KEYDOWN_EVENT);
    00218   case OnKeyPress:
    00219     return getListener(DOM::EventImpl::KHTML_KEYPRESS_EVENT);
    00220   case OnKeyUp:
    00221     return getListener(DOM::EventImpl::KEYUP_EVENT);
    00222   case OnLoad:
    00223     return getListener(DOM::EventImpl::LOAD_EVENT);
    00224   case OnMouseDown:
    00225     return getListener(DOM::EventImpl::MOUSEDOWN_EVENT);
    00226   case OnMouseMove:
    00227     return getListener(DOM::EventImpl::MOUSEMOVE_EVENT);
    00228   case OnMouseOut:
    00229     return getListener(DOM::EventImpl::MOUSEOUT_EVENT);
    00230   case OnMouseOver:
    00231     return getListener(DOM::EventImpl::MOUSEOVER_EVENT);
    00232   case OnMouseUp:
    00233     return getListener(DOM::EventImpl::MOUSEUP_EVENT);
    00234   case OnMove:
    00235     return getListener(DOM::EventImpl::KHTML_MOVE_EVENT);
    00236   case OnReset:
    00237     return getListener(DOM::EventImpl::RESET_EVENT);
    00238   case OnResize:
    00239     return getListener(DOM::EventImpl::RESIZE_EVENT);
    00240   case OnSelect:
    00241     return getListener(DOM::EventImpl::SELECT_EVENT);
    00242   case OnSubmit:
    00243     return getListener(DOM::EventImpl::SUBMIT_EVENT);
    00244   case OnUnload:
    00245     return getListener(DOM::EventImpl::UNLOAD_EVENT);
    00246   case SourceIndex: {
    00247     // Retrieves the ordinal position of the object, in source order, as the object
    00248     // appears in the document's all collection
    00249     // i.e. document.all[n.sourceIndex] == n
    00250     DOM::Document doc = node.ownerDocument();
    00251     if (doc.isHTMLDocument()) {
    00252       DOM::HTMLCollection all = static_cast<DOM::HTMLDocument>(doc).all();
    00253       unsigned long i = 0;
    00254       DOM::Node n = all.firstItem();
    00255       for ( ; !n.isNull() && n != node; n = all.nextItem() )
    00256         ++i;
    00257       Q_ASSERT( !n.isNull() ); // node not in document.all !?
    00258       return Number(i);
    00259     }
    00260   }
    00261   default:
    00262     // no DOM standard, found in IE only
    00263
    00264     // Make sure our layout is up to date before we allow a query on these attributes.
    00265     DOM::DocumentImpl* docimpl = node.handle()->getDocument();
    00266     if (docimpl) {
    00267       docimpl->updateLayout();
    00268     }
    00269
    00270     khtml::RenderObject *rend = node.handle()->renderer();
    00271
    00272     switch (token) {
    00273     case OffsetLeft:
    00274       return rend ? static_cast<Value>( Number( rend->offsetLeft() ) ) : Undefined();
    00275     case OffsetTop:
    00276       return rend ? static_cast<Value>(  Number( rend->offsetTop() ) ) : Undefined();
    00277     case OffsetWidth:
    00278       return rend ? static_cast<Value>(  Number( rend->offsetWidth() ) ) : Undefined();
    00279     case OffsetHeight:
    00280       return rend ? static_cast<Value>(  Number( rend->offsetHeight() ) ) : Undefined();
    00281     case OffsetParent:
    00282     {
    00283       khtml::RenderObject* par = rend ? rend->offsetParent() : 0;
    00284       return getDOMNode( exec, par ? par->element() : 0 );
    00285     }
    00286     case ClientWidth:
    00287       return rend ? static_cast<Value>( Number( rend->clientWidth() ) ) : Undefined();
    00288     case ClientHeight:
    00289       return rend ? static_cast<Value>( Number( rend->clientHeight() ) ) : Undefined();
    00290     case ScrollWidth:
    00291       return rend ? static_cast<Value>( Number(rend->scrollWidth()) ) : Undefined();
    00292     case ScrollHeight:
    00293       return rend ? static_cast<Value>( Number(rend->scrollHeight()) ) : Undefined();
    00294     case ScrollLeft:
    00295       if (rend && rend->layer()) {
    00296           if (rend->isRoot() && !rend->style()->hidesOverflow())
    00297               return Number( node.ownerDocument().view() ? node.ownerDocument().view()->contentsX() : 0);
    00298           return Number( rend->layer()->scrollXOffset() );
    00299       }
    00300       return Number( 0 );
    00301     case ScrollTop:
    00302       if (rend && rend->layer()) {
    00303           if (rend->isRoot() && !rend->style()->hidesOverflow())
    00304               return Number( node.ownerDocument().view() ? node.ownerDocument().view()->contentsY() : 0);
    00305           return Number( rend->layer()->scrollYOffset() );
    00306       }
    00307       return Number( 0 );
    00308     default:
    00309       kdDebug(6070) << "WARNING: Unhandled token in DOMNode::getValueProperty : " << token << endl;
    00310       break;
    00311     }
    00312   }
    00313   return Undefined();
    00314 }
    00315
    00316
    00317 void DOMNode::tryPut(ExecState *exec, const Identifier& propertyName, const Value& value, int attr)
    00318 {
    00319 #ifdef KJS_VERBOSE
    00320   kdDebug(6070) << "DOMNode::tryPut " << propertyName.qstring() << endl;
    00321 #endif
    00322   DOMObjectLookupPut<DOMNode,DOMObject>(exec, propertyName, value, attr,
    00323                                         &DOMNodeTable, this );
    00324 }
    00325
    00326 void DOMNode::putValueProperty(ExecState *exec, int token, const Value& value, int /*attr*/)
    00327 {
    00328   switch (token) {
    00329   case NodeValue:
    00330     node.setNodeValue(value.toString(exec).string());
    00331     break;
    00332   case Prefix:
    00333     node.setPrefix(value.toString(exec).string());
    00334     break;
    00335   case OnAbort:
    00336     setListener(exec,DOM::EventImpl::ABORT_EVENT,value);
    00337     break;
    00338   case OnBlur:
    00339     setListener(exec,DOM::EventImpl::BLUR_EVENT,value);
    00340     break;
    00341   case OnChange:
    00342     setListener(exec,DOM::EventImpl::CHANGE_EVENT,value);
    00343     break;
    00344   case OnClick:
    00345     setListener(exec,DOM::EventImpl::KHTML_ECMA_CLICK_EVENT,value);
    00346     break;
    00347   case OnDblClick:
    00348     setListener(exec,DOM::EventImpl::KHTML_ECMA_DBLCLICK_EVENT,value);
    00349     break;
    00350   case OnDragDrop:
    00351     setListener(exec,DOM::EventImpl::KHTML_DRAGDROP_EVENT,value);
    00352     break;
    00353   case OnError:
    00354     setListener(exec,DOM::EventImpl::KHTML_ERROR_EVENT,value);
    00355     break;
    00356   case OnFocus:
    00357     setListener(exec,DOM::EventImpl::FOCUS_EVENT,value);
    00358     break;
    00359   case OnKeyDown:
    00360     setListener(exec,DOM::EventImpl::KEYDOWN_EVENT,value);
    00361     break;
    00362   case OnKeyPress:
    00363     setListener(exec,DOM::EventImpl::KHTML_KEYPRESS_EVENT,value);
    00364     break;
    00365   case OnKeyUp:
    00366     setListener(exec,DOM::EventImpl::KEYUP_EVENT,value);
    00367     break;
    00368   case OnLoad:
    00369     setListener(exec,DOM::EventImpl::LOAD_EVENT,value);
    00370     break;
    00371   case OnMouseDown:
    00372     setListener(exec,DOM::EventImpl::MOUSEDOWN_EVENT,value);
    00373     break;
    00374   case OnMouseMove:
    00375     setListener(exec,DOM::EventImpl::MOUSEMOVE_EVENT,value);
    00376     break;
    00377   case OnMouseOut:
    00378     setListener(exec,DOM::EventImpl::MOUSEOUT_EVENT,value);
    00379     break;
    00380   case OnMouseOver:
    00381     setListener(exec,DOM::EventImpl::MOUSEOVER_EVENT,value);
    00382     break;
    00383   case OnMouseUp:
    00384     setListener(exec,DOM::EventImpl::MOUSEUP_EVENT,value);
    00385     break;
    00386   case OnMove:
    00387     setListener(exec,DOM::EventImpl::KHTML_MOVE_EVENT,value);
    00388     break;
    00389   case OnReset:
    00390     setListener(exec,DOM::EventImpl::RESET_EVENT,value);
    00391     break;
    00392   case OnResize:
    00393     setListener(exec,DOM::EventImpl::RESIZE_EVENT,value);
    00394     break;
    00395   case OnSelect:
    00396     setListener(exec,DOM::EventImpl::SELECT_EVENT,value);
    00397     break;
    00398   case OnSubmit:
    00399     setListener(exec,DOM::EventImpl::SUBMIT_EVENT,value);
    00400     break;
    00401   case OnUnload:
    00402     setListener(exec,DOM::EventImpl::UNLOAD_EVENT,value);
    00403     break;
    00404   case ScrollTop: {
    00405     khtml::RenderObject *rend = node.handle() ? node.handle()->renderer() : 0L;
    00406     if (rend && rend->layer()) {
    00407         node.handle()->getDocument()->updateLayout();
    00408         if (rend->style()->hidesOverflow())
    00409             rend->layer()->scrollToYOffset(value.toInt32(exec));
    00410         else if (rend->isRoot()) {
    00411             QScrollView* sview = node.ownerDocument().view();
    00412             if (sview)
    00413                 sview->setContentsPos(sview->contentsX(), value.toInt32(exec));
    00414         }
    00415     }
    00416     break;
    00417   }
    00418   case ScrollLeft: {
    00419     khtml::RenderObject *rend = node.handle() ? node.handle()->renderer() : 0L;
    00420     if (rend && rend->layer()) {
    00421         node.handle()->getDocument()->updateLayout();
    00422         if (rend->style()->hidesOverflow())
    00423             rend->layer()->scrollToXOffset(value.toInt32(exec));
    00424         else if (rend->isRoot()) {
    00425             QScrollView* sview = node.ownerDocument().view();
    00426             if (sview)
    00427                 sview->setContentsPos(value.toInt32(exec), sview->contentsY());
    00428         }
    00429     }
    00430     break;
    00431   }
    00432   default:
    00433     kdDebug(6070) << "WARNING: DOMNode::putValueProperty unhandled token " << token << endl;
    00434   }
    00435 }
    00436
    00437 Value DOMNode::toPrimitive(ExecState *exec, Type /*preferred*/) const
    00438 {
    00439   if (node.isNull())
    00440     return Null();
    00441
    00442   return String(toString(exec));
    00443 }
    00444
    00445 UString DOMNode::toString(ExecState *) const
    00446 {
    00447   if (node.isNull())
    00448     return "null";
    00449   UString s;
    00450
    00451   DOM::Element e = node;
    00452   if ( !e.isNull() ) {
    00453     s = e.nodeName().string();
    00454   } else
    00455     s = className(); // fallback
    00456
    00457   return "[object " + s + "]";
    00458 }
    00459
    00460 void DOMNode::setListener(ExecState *exec, int eventId, const Value& func) const
    00461 {
    00462   node.handle()->setHTMLEventListener(eventId,Window::retrieveActive(exec)->getJSEventListener(func,true));
    00463 }
    00464
    00465 Value DOMNode::getListener(int eventId) const
    00466 {
    00467   DOM::EventListener *listener = node.handle()->getHTMLEventListener(eventId);
    00468   JSEventListener *jsListener = static_cast<JSEventListener*>(listener);
    00469   if ( jsListener && jsListener->listenerObjImp() )
    00470     return jsListener->listenerObj();
    00471   else
    00472     return Null();
    00473 }
    00474
    00475 void DOMNode::pushEventHandlerScope(ExecState *, ScopeChain &) const
    00476 {
    00477 }
    00478
    00479 Value DOMNodeProtoFunc::tryCall(ExecState *exec, Object &thisObj, const List &args)
    00480 {
    00481   KJS_CHECK_THIS( DOMNode, thisObj );
    00482   DOM::Node node = static_cast<DOMNode *>( thisObj.imp() )->toNode();
    00483   switch (id) {
    00484     case DOMNode::HasAttributes:
    00485       return Boolean(node.hasAttributes());
    00486     case DOMNode::HasChildNodes:
    00487       return Boolean(node.hasChildNodes());
    00488     case DOMNode::CloneNode:
    00489       return getDOMNode(exec,node.cloneNode(args[0].toBoolean(exec)));
    00490     case DOMNode::Normalize:
    00491       node.normalize();
    00492       return Undefined();
    00493     case DOMNode::IsSupported:
    00494       return Boolean(node.isSupported(args[0].toString(exec).string(),args[1].toString(exec).string()));
    00495     case DOMNode::AddEventListener: {
    00496         JSEventListener *listener = Window::retrieveActive(exec)->getJSEventListener(args[1]);
    00497         node.addEventListener(args[0].toString(exec).string(),listener,args[2].toBoolean(exec));
    00498         return Undefined();
    00499     }
    00500     case DOMNode::RemoveEventListener: {
    00501         JSEventListener *listener = Window::retrieveActive(exec)->getJSEventListener(args[1]);
    00502         node.removeEventListener(args[0].toString(exec).string(),listener,args[2].toBoolean(exec));
    00503         return Undefined();
    00504     }
    00505     case DOMNode::DispatchEvent:
    00506       return Boolean(node.dispatchEvent(toEvent(args[0])));
    00507     case DOMNode::AppendChild:
    00508       return getDOMNode(exec,node.appendChild(toNode(args[0])));
    00509     case DOMNode::RemoveChild:
    00510       return getDOMNode(exec,node.removeChild(toNode(args[0])));
    00511     case DOMNode::InsertBefore:
    00512       return getDOMNode(exec,node.insertBefore(toNode(args[0]), toNode(args[1])));
    00513     case DOMNode::ReplaceChild:
    00514       return getDOMNode(exec,node.replaceChild(toNode(args[0]), toNode(args[1])));
    00515     case DOMNode::Contains:
    00516     {
    00517     DOM::Node other = toNode(args[0]);
    00518     if (!other.isNull() && node.nodeType()==DOM::Node::ELEMENT_NODE)
    00519     {
    00520         DOM::NodeBaseImpl *impl = static_cast<DOM::NodeBaseImpl *>(node.handle());
    00521         bool retval = other.handle()->isAncestor(impl);
    00522         return Boolean(retval);
    00523     }
    00524         return Undefined();
    00525     }
    00526     case DOMNode::InsertAdjacentHTML:
    00527     {
    00528       // see http://www.faqts.com/knowledge_base/view.phtml/aid/5756
    00529       // and http://msdn.microsoft.com/workshop/author/dhtml/reference/methods/insertAdjacentHTML.asp
    00530       Range range = node.ownerDocument().createRange();
    00531
    00532       range.setStartBefore(node);
    00533
    00534       DocumentFragment docFrag = range.createContextualFragment(args[1].toString(exec).string());
    00535
    00536       DOMString where = args[0].toString(exec).string();
    00537
    00538       if (where == "beforeBegin" || where == "BeforeBegin")
    00539         node.parentNode().insertBefore(docFrag, node);
    00540       else if (where == "afterBegin" || where == "AfterBegin")
    00541         node.insertBefore(docFrag, node.firstChild());
    00542       else if (where == "beforeEnd" || where == "BeforeEnd")
    00543         return getDOMNode(exec, node.appendChild(docFrag));
    00544       else if (where == "afterEnd" || where == "AfterEnd")
    00545         if (!node.nextSibling().isNull())
    00546       node.parentNode().insertBefore(docFrag, node.nextSibling());
    00547     else
    00548       node.parentNode().appendChild(docFrag);
    00549
    00550       return Undefined();
    00551     }
    00552     case DOMNode::Item:
    00553       return getDOMNode(exec, node.childNodes().item(static_cast<unsigned long>(args[0].toNumber(exec))));
    00554   }
    00555
    00556   return Undefined();
    00557 }
    00558
    00559 // -------------------------------------------------------------------------
    00560
    00561 /*
    00562 @begin DOMNodeListProtoTable 2
    00563   item      DOMNodeList::Item       DontDelete|Function 1
    00564 # IE extension (IE treats DOMNodeList like an HTMLCollection)
    00565   namedItem DOMNodeList::NamedItem      DontDelete|Function 1
    00566 @end
    00567 */
    00568 DEFINE_PROTOTYPE("DOMNodeList", DOMNodeListProto)
    00569 IMPLEMENT_PROTOFUNC_DOM(DOMNodeListProtoFunc)
    00570 IMPLEMENT_PROTOTYPE(DOMNodeListProto,DOMNodeListProtoFunc)
    00571
    00572 const ClassInfo DOMNodeList::info = { "NodeList", 0, 0, 0 };
    00573
    00574 DOMNodeList::DOMNodeList(ExecState *exec, const DOM::NodeList& l)
    00575  : DOMObject(DOMNodeListProto::self(exec)), list(l) { }
    00576
    00577 DOMNodeList::~DOMNodeList()
    00578 {
    00579   ScriptInterpreter::forgetDOMObject(list.handle());
    00580 }
    00581
    00582 // We have to implement hasProperty since we don't use a hashtable for 'length'
    00583 // ## this breaks "for (..in..)" though.
    00584 bool DOMNodeList::hasProperty(ExecState *exec, const Identifier &p) const
    00585 {
    00586   if (p == lengthPropertyName)
    00587     return true;
    00588   // ## missing: accept p if array index or item id...
    00589   return ObjectImp::hasProperty(exec, p);
    00590 }
    00591
    00592 Value DOMNodeList::tryGet(ExecState *exec, const Identifier &p) const
    00593 {
    00594 #ifdef KJS_VERBOSE
    00595   kdDebug(6070) << "DOMNodeList::tryGet " << p.ascii() << endl;
    00596 #endif
    00597   if (p == lengthPropertyName)
    00598     return Number(list.length());
    00599
    00600   // Look in the prototype (for functions) before assuming it's an item's name
    00601   Object proto = Object::dynamicCast(prototype());
    00602   if (!proto.isNull() && proto.hasProperty(exec,p))
    00603     return proto.get(exec,p);
    00604
    00605   Value result;
    00606
    00607   // array index ?
    00608   bool ok;
    00609   long unsigned int idx = p.toULong(&ok);
    00610   if (ok)
    00611     result = getDOMNode(exec,list.item(idx));
    00612   else {
    00613     // Find by ID
    00614     DOM::HTMLElement e;
    00615     unsigned long l = list.length();
    00616     bool found = false;
    00617
    00618     for ( unsigned long i = 0; i < l; i++ )
    00619       if ( ( e = list.item( i ) ).id() == p.string() ) {
    00620         result = getDOMNode(exec, list.item( i ) );
    00621         found = true;
    00622         break;
    00623       }
    00624
    00625     if ( !found )
    00626       result = ObjectImp::get(exec, p);
    00627   }
    00628
    00629   return result;
    00630 }
    00631
    00632 // Need to support both get and call, so that list[0] and list(0) work.
    00633 Value DOMNodeList::call(ExecState *exec, Object &thisObj, const List &args)
    00634 {
    00635   // This code duplication is necessary, DOMNodeList isn't a DOMFunction
    00636   Value val;
    00637   try {
    00638     val = tryCall(exec, thisObj, args);
    00639   }
    00640   // pity there's no way to distinguish between these in JS code
    00641   catch (...) {
    00642     Object err = Error::create(exec, GeneralError, "Exception from DOMNodeList");
    00643     exec->setException(err);
    00644   }
    00645   return val;
    00646 }
    00647
    00648 Value DOMNodeList::tryCall(ExecState *exec, Object &, const List &args)
    00649 {
    00650   // Do not use thisObj here. See HTMLCollection.
    00651   UString s = args[0].toString(exec);
    00652
    00653   // index-based lookup?
    00654   bool ok;
    00655   unsigned int u = s.toULong(&ok);
    00656   if (ok)
    00657     return getDOMNode(exec,list.item(u));
    00658
    00659   // try lookup by name
    00660   // ### NodeList::namedItem() would be cool to have
    00661   // ### do we need to support the same two arg overload as in HTMLCollection?
    00662   Value result = tryGet(exec, Identifier(s));
    00663
    00664   if (result.isValid())
    00665     return result;
    00666
    00667   return Undefined();
    00668 }
    00669
    00670 // Not a prototype class currently, but should probably be converted to one
    00671 Value DOMNodeListProtoFunc::tryCall(ExecState *exec, Object &thisObj, const List &args)
    00672 {
    00673   KJS_CHECK_THIS( KJS::DOMNodeList, thisObj );
    00674   DOM::NodeList list = static_cast<DOMNodeList *>(thisObj.imp())->nodeList();
    00675   switch (id) {
    00676   case KJS::DOMNodeList::Item:
    00677     return getDOMNode(exec, list.item(args[0].toInt32(exec)));
    00678   case KJS::DOMNodeList::NamedItem:
    00679   {
    00680     // Not a real namedItem implementation like the one HTMLCollection has.
    00681     // This is only an IE extension...
    00682     DOM::HTMLElement e;
    00683     unsigned long len = list.length();
    00684     DOM::DOMString s = args[0].toString(exec).string();
    00685
    00686     for ( unsigned long i = 0; i < len; i++ )
    00687     {
    00688       e = list.item( i );
    00689       if ( !e.isNull() && (
    00690              e.id() == s || static_cast<ElementImpl *>(e.handle())->getAttribute(ATTR_NAME) == s )
    00691       )
    00692       {
    00693         return getDOMNode(exec, e );
    00694       }
    00695     }
    00696     return Null(); // see HTMLCollection::NamedItem implementation
    00697   }
    00698   default:
    00699     return Undefined();
    00700   }
    00701 }
    00702
    00703 // -------------------------------------------------------------------------
    00704
    00705 const ClassInfo DOMAttr::info = { "Attr", &DOMNode::info, &DOMAttrTable, 0 };
    00706
    00707 /* Source for DOMAttrTable.
    00708 @begin DOMAttrTable 5
    00709   name      DOMAttr::Name       DontDelete|ReadOnly
    00710   specified DOMAttr::Specified  DontDelete|ReadOnly
    00711   value     DOMAttr::ValueProperty  DontDelete
    00712   ownerElement  DOMAttr::OwnerElement   DontDelete|ReadOnly
    00713 @end
    00714 */
    00715 Value DOMAttr::tryGet(ExecState *exec, const Identifier &propertyName) const
    00716 {
    00717 #ifdef KJS_VERBOSE
    00718   kdDebug(6070) << "DOMAttr::tryGet " << propertyName.qstring() << endl;
    00719 #endif
    00720   return DOMObjectLookupGetValue<DOMAttr,DOMNode>(exec, propertyName,
    00721                                                   &DOMAttrTable, this );
    00722 }
    00723
    00724 Value DOMAttr::getValueProperty(ExecState *exec, int token) const
    00725 {
    00726   switch (token) {
    00727   case Name:
    00728     return String(static_cast<DOM::Attr>(node).name());
    00729   case Specified:
    00730     return Boolean(static_cast<DOM::Attr>(node).specified());
    00731   case ValueProperty:
    00732     return String(static_cast<DOM::Attr>(node).value());
    00733   case OwnerElement: // DOM2
    00734     return getDOMNode(exec,static_cast<DOM::Attr>(node).ownerElement());
    00735   }
    00736   return Value(); // not reached
    00737 }
    00738
    00739 void DOMAttr::tryPut(ExecState *exec, const Identifier &propertyName, const Value& value, int attr)
    00740 {
    00741 #ifdef KJS_VERBOSE
    00742   kdDebug(6070) << "DOMAttr::tryPut " << propertyName.qstring() << endl;
    00743 #endif
    00744   DOMObjectLookupPut<DOMAttr,DOMNode>(exec, propertyName, value, attr,
    00745                                       &DOMAttrTable, this );
    00746 }
    00747
    00748 void DOMAttr::putValueProperty(ExecState *exec, int token, const Value& value, int /*attr*/)
    00749 {
    00750   switch (token) {
    00751   case ValueProperty:
    00752     static_cast<DOM::Attr>(node).setValue(value.toString(exec).string());
    00753     return;
    00754   default:
    00755     kdDebug(6070) << "WARNING: DOMAttr::putValueProperty unhandled token " << token << endl;
    00756   }
    00757 }
    00758
    00759 // -------------------------------------------------------------------------
    00760
    00761 /* Source for DOMDocumentProtoTable.
    00762 @begin DOMDocumentProtoTable 23
    00763   createElement   DOMDocument::CreateElement                   DontDelete|Function 1
    00764   createDocumentFragment DOMDocument::CreateDocumentFragment   DontDelete|Function 1
    00765   createTextNode  DOMDocument::CreateTextNode                  DontDelete|Function 1
    00766   createComment   DOMDocument::CreateComment                   DontDelete|Function 1
    00767   createCDATASection DOMDocument::CreateCDATASection           DontDelete|Function 1
    00768   createProcessingInstruction DOMDocument::CreateProcessingInstruction DontDelete|Function 1
    00769   createAttribute DOMDocument::CreateAttribute                 DontDelete|Function 1
    00770   createEntityReference DOMDocument::CreateEntityReference     DontDelete|Function 1
    00771   getElementsByTagName  DOMDocument::GetElementsByTagName      DontDelete|Function 1
    00772   importNode           DOMDocument::ImportNode                 DontDelete|Function 2
    00773   createElementNS      DOMDocument::CreateElementNS            DontDelete|Function 2
    00774   createAttributeNS    DOMDocument::CreateAttributeNS          DontDelete|Function 2
    00775   getElementsByTagNameNS  DOMDocument::GetElementsByTagNameNS  DontDelete|Function 2
    00776   getElementById     DOMDocument::GetElementById               DontDelete|Function 1
    00777   createRange        DOMDocument::CreateRange                  DontDelete|Function 0
    00778   createNodeIterator DOMDocument::CreateNodeIterator           DontDelete|Function 3
    00779   createTreeWalker   DOMDocument::CreateTreeWalker             DontDelete|Function 4
    00780   createEvent        DOMDocument::CreateEvent                  DontDelete|Function 1
    00781   getOverrideStyle   DOMDocument::GetOverrideStyle             DontDelete|Function 2
    00782   abort              DOMDocument::Abort                        DontDelete|Function 0
    00783   load               DOMDocument::Load                         DontDelete|Function 1
    00784   loadXML            DOMDocument::LoadXML                      DontDelete|Function 2
    00785 @end
    00786 */
    00787 DEFINE_PROTOTYPE("DOMDocument", DOMDocumentProto)
    00788 IMPLEMENT_PROTOFUNC_DOM(DOMDocumentProtoFunc)
    00789 IMPLEMENT_PROTOTYPE_WITH_PARENT(DOMDocumentProto, DOMDocumentProtoFunc, DOMNodeProto)
    00790
    00791 const ClassInfo DOMDocument::info = { "Document", &DOMNode::info, &DOMDocumentTable, 0 };
    00792
    00793 /* Source for DOMDocumentTable.
    00794 @begin DOMDocumentTable 4
    00795   doctype         DOMDocument::DocType                         DontDelete|ReadOnly
    00796   implementation  DOMDocument::Implementation                  DontDelete|ReadOnly
    00797   documentElement DOMDocument::DocumentElement                 DontDelete|ReadOnly
    00798   styleSheets     DOMDocument::StyleSheets                     DontDelete|ReadOnly
    00799   preferredStylesheetSet  DOMDocument::PreferredStylesheetSet  DontDelete|ReadOnly
    00800   selectedStylesheetSet  DOMDocument::SelectedStylesheetSet    DontDelete
    00801   readyState      DOMDocument::ReadyState                      DontDelete|ReadOnly
    00802   defaultView     DOMDocument::DefaultView                     DontDelete|ReadOnly
    00803   async           DOMDocument::Async                           DontDelete
    00804 @end
    00805 */
    00806
    00807 DOMDocument::DOMDocument(ExecState *exec, const DOM::Document& d)
    00808   : DOMNode(DOMDocumentProto::self(exec), d) { }
    00809
    00810 DOMDocument::DOMDocument(const Object& proto, const DOM::Document& d)
    00811   : DOMNode(proto, d) { }
    00812
    00813 DOMDocument::~DOMDocument()
    00814 {
    00815   ScriptInterpreter::forgetDOMObject(node.handle());
    00816 }
    00817
    00818 Value DOMDocument::tryGet(ExecState *exec, const Identifier &propertyName) const
    00819 {
    00820 #ifdef KJS_VERBOSE
    00821   kdDebug(6070) << "DOMDocument::tryGet " << propertyName.qstring() << endl;
    00822 #endif
    00823   return DOMObjectLookupGetValue<DOMDocument, DOMNode>(
    00824     exec, propertyName, &DOMDocumentTable, this);
    00825 }
    00826
    00827 Value DOMDocument::getValueProperty(ExecState *exec, int token) const
    00828 {
    00829   DOM::Document doc = static_cast<DOM::Document>(node);
    00830
    00831   switch(token) {
    00832   case DocType:
    00833     return getDOMNode(exec,doc.doctype());
    00834   case Implementation:
    00835     return getDOMDOMImplementation(exec,doc.implementation());
    00836   case DocumentElement:
    00837     return getDOMNode(exec,doc.documentElement());
    00838   case StyleSheets:
    00839     //kdDebug() << "DOMDocument::StyleSheets, returning " << doc.styleSheets().length() << " stylesheets" << endl;
    00840     return getDOMStyleSheetList(exec, doc.styleSheets(), doc);
    00841   case DOMDocument::DefaultView: // DOM2
    00842     return getDOMAbstractView(exec, doc.defaultView());
    00843   case PreferredStylesheetSet:
    00844     return String(doc.preferredStylesheetSet());
    00845   case SelectedStylesheetSet:
    00846     return String(doc.selectedStylesheetSet());
    00847   case ReadyState:
    00848     {
    00849     DOM::DocumentImpl* docimpl = node.handle()->getDocument();
    00850     if ( docimpl && docimpl->view() )
    00851     {
    00852       KHTMLPart* part = docimpl->view()->part();
    00853       if ( part ) {
    00854         if (part->d->m_bComplete) return String("complete");
    00855         if (docimpl->parsing()) return String("loading");
    00856         return String("loaded");
    00857         // What does the interactive value mean ?
    00858         // Missing support for "uninitialized"
    00859       }
    00860     }
    00861     return Undefined();
    00862     }
    00863   case Async:
    00864     return Boolean(doc.async());
    00865   default:
    00866     kdDebug(6070) << "WARNING: DOMDocument::getValueProperty unhandled token " << token << endl;
    00867     return Value();
    00868   }
    00869 }
    00870
    00871 void DOMDocument::tryPut(ExecState *exec, const Identifier& propertyName, const Value& value, int attr)
    00872 {
    00873 #ifdef KJS_VERBOSE
    00874   kdDebug(6070) << "DOMDocument::tryPut " << propertyName.qstring() << endl;
    00875 #endif
    00876   DOMObjectLookupPut<DOMDocument,DOMNode>(exec, propertyName, value, attr, &DOMDocumentTable, this );
    00877 }
    00878
    00879 void DOMDocument::putValueProperty(ExecState *exec, int token, const Value& value, int /*attr*/)
    00880 {
    00881   DOM::Document doc = static_cast<DOM::Document>(node);
    00882   switch (token) {
    00883     case SelectedStylesheetSet: {
    00884       doc.setSelectedStylesheetSet(value.toString(exec).string());
    00885       break;
    00886     }
    00887     case Async: {
    00888       doc.setAsync(value.toBoolean(exec));
    00889       break;
    00890     }
    00891   }
    00892 }
    00893
    00894 Value DOMDocumentProtoFunc::tryCall(ExecState *exec, Object &thisObj, const List &args)
    00895 {
    00896   KJS_CHECK_THIS( KJS::DOMDocument, thisObj );
    00897   DOM::Node node = static_cast<DOMNode *>( thisObj.imp() )->toNode();
    00898   DOM::Document doc = static_cast<DOM::Document>(node);
    00899   String str = args[0].toString(exec);
    00900   DOM::DOMString s = str.value().string();
    00901
    00902   switch(id) {
    00903   case DOMDocument::CreateElement:
    00904     return getDOMNode(exec,doc.createElement(s));
    00905   case DOMDocument::CreateDocumentFragment:
    00906     return getDOMNode(exec,doc.createDocumentFragment());
    00907   case DOMDocument::CreateTextNode:
    00908     return getDOMNode(exec,doc.createTextNode(s));
    00909   case DOMDocument::CreateComment:
    00910     return getDOMNode(exec,doc.createComment(s));
    00911   case DOMDocument::CreateCDATASection:
    00912     return getDOMNode(exec,doc.createCDATASection(s));  /* TODO: okay ? */
    00913   case DOMDocument::CreateProcessingInstruction:
    00914     return getDOMNode(exec,doc.createProcessingInstruction(args[0].toString(exec).string(),
    00915                                                                  args[1].toString(exec).string()));
    00916   case DOMDocument::CreateAttribute:
    00917     return getDOMNode(exec,doc.createAttribute(s));
    00918   case DOMDocument::CreateEntityReference:
    00919     return getDOMNode(exec,doc.createEntityReference(args[0].toString(exec).string()));
    00920   case DOMDocument::GetElementsByTagName:
    00921     return getDOMNodeList(exec,doc.getElementsByTagName(s));
    00922   case DOMDocument::ImportNode: // DOM2
    00923     return getDOMNode(exec,doc.importNode(toNode(args[0]), args[1].toBoolean(exec)));
    00924   case DOMDocument::CreateElementNS: // DOM2
    00925     return getDOMNode(exec,doc.createElementNS(args[0].toString(exec).string(), args[1].toString(exec).string()));
    00926   case DOMDocument::CreateAttributeNS: // DOM2
    00927     return getDOMNode(exec,doc.createAttributeNS(args[0].toString(exec).string(),args[1].toString(exec).string()));
    00928   case DOMDocument::GetElementsByTagNameNS: // DOM2
    00929     return getDOMNodeList(exec,doc.getElementsByTagNameNS(args[0].toString(exec).string(),
    00930                                                           args[1].toString(exec).string()));
    00931   case DOMDocument::GetElementById:
    00932 #ifdef KJS_VERBOSE
    00933   kdDebug(6070) << "DOMDocument::GetElementById looking for " << args[0].toString(exec).string() << endl;
    00934 #endif
    00935     return getDOMNode(exec,doc.getElementById(args[0].toString(exec).string()));
    00936   case DOMDocument::CreateRange:
    00937     return getDOMRange(exec,doc.createRange());
    00938   case DOMDocument::CreateNodeIterator:
    00939     if (args[2].isA(NullType)) {
    00940         DOM::NodeFilter filter;
    00941         return getDOMNodeIterator(exec,
    00942                                   doc.createNodeIterator(toNode(args[0]),
    00943                                                          (long unsigned int)(args[1].toNumber(exec)),
    00944                                                          filter,args[3].toBoolean(exec)));
    00945     }
    00946     else {
    00947       Object obj = Object::dynamicCast(args[2]);
    00948       if (!obj.isNull())
    00949       {
    00950         DOM::CustomNodeFilter *customFilter = new JSNodeFilter(obj);
    00951         DOM::NodeFilter filter = DOM::NodeFilter::createCustom(customFilter);
    00952         return getDOMNodeIterator(exec,
    00953           doc.createNodeIterator(
    00954             toNode(args[0]),(long unsigned int)(args[1].toNumber(exec)),
    00955             filter,args[3].toBoolean(exec)));
    00956       }// else?
    00957     }
    00958   case DOMDocument::CreateTreeWalker:
    00959     return getDOMTreeWalker(exec,doc.createTreeWalker(toNode(args[0]),(long unsigned int)(args[1].toNumber(exec)),
    00960              toNodeFilter(args[2]),args[3].toBoolean(exec)));
    00961   case DOMDocument::CreateEvent:
    00962     return getDOMEvent(exec,doc.createEvent(s));
    00963   case DOMDocument::GetOverrideStyle: {
    00964     DOM::Node arg0 = toNode(args[0]);
    00965     if (arg0.nodeType() != DOM::Node::ELEMENT_NODE)
    00966       return Undefined(); // throw exception?
    00967     else
    00968       return getDOMCSSStyleDeclaration(exec,doc.getOverrideStyle(static_cast<DOM::Element>(arg0),args[1].toString(exec).string()));
    00969   }
    00970   case DOMDocument::Abort:
    00971     doc.abort();
    00972     break;
    00973   case DOMDocument::Load: {
    00974     Window* active = Window::retrieveActive(exec);
    00975     // Complete the URL using the "active part" (running interpreter). We do this for the security
    00976     // check and to make sure we load exactly the same url as we have verified to be safe
    00977     KHTMLPart *khtmlpart = ::qt_cast<KHTMLPart *>(active->part());
    00978     if (khtmlpart) {
    00979       // Security: only allow documents to be loaded from the same host
    00980       QString dstUrl = khtmlpart->htmlDocument().completeURL(s).string();
    00981       KParts::ReadOnlyPart *part = static_cast<KJS::ScriptInterpreter*>(exec->interpreter())->part();
    00982       if (part->url().host() == KURL(dstUrl).host()) {
    00983     kdDebug(6070) << "JavaScript: access granted for document.load() of " << dstUrl << endl;
    00984     doc.load(dstUrl);
    00985       }
    00986       else {
    00987     kdDebug(6070) << "JavaScript: access denied for document.load() of " << dstUrl << endl;
    00988       }
    00989     }
    00990     break;
    00991   }
    00992   case DOMDocument::LoadXML:
    00993     doc.loadXML(s);
    00994     break;
    00995   default:
    00996     break;
    00997   }
    00998
    00999   return Undefined();
    01000 }
    01001
    01002 // -------------------------------------------------------------------------
    01003
    01004 /* Source for DOMElementProtoTable.
    01005 @begin DOMElementProtoTable 17
    01006   getAttribute      DOMElement::GetAttribute    DontDelete|Function 1
    01007   setAttribute      DOMElement::SetAttribute    DontDelete|Function 2
    01008   removeAttribute   DOMElement::RemoveAttribute DontDelete|Function 1
    01009   getAttributeNode  DOMElement::GetAttributeNode    DontDelete|Function 1
    01010   setAttributeNode  DOMElement::SetAttributeNode    DontDelete|Function 2
    01011   removeAttributeNode   DOMElement::RemoveAttributeNode DontDelete|Function 1
    01012   getElementsByTagName  DOMElement::GetElementsByTagName    DontDelete|Function 1
    01013   hasAttribute      DOMElement::HasAttribute    DontDelete|Function 1
    01014   getAttributeNS    DOMElement::GetAttributeNS  DontDelete|Function 2
    01015   setAttributeNS    DOMElement::SetAttributeNS  DontDelete|Function 3
    01016   removeAttributeNS DOMElement::RemoveAttributeNS   DontDelete|Function 2
    01017   getAttributeNodeNS    DOMElement::GetAttributeNodeNS  DontDelete|Function 2
    01018   setAttributeNodeNS    DOMElement::SetAttributeNodeNS  DontDelete|Function 1
    01019   getElementsByTagNameNS DOMElement::GetElementsByTagNameNS DontDelete|Function 2
    01020   hasAttributeNS    DOMElement::HasAttributeNS  DontDelete|Function 2
    01021 @end
    01022 */
    01023 DEFINE_PROTOTYPE("DOMElement",DOMElementProto)
    01024 IMPLEMENT_PROTOFUNC_DOM(DOMElementProtoFunc)
    01025 IMPLEMENT_PROTOTYPE_WITH_PARENT(DOMElementProto,DOMElementProtoFunc,DOMNodeProto)
    01026
    01027 const ClassInfo DOMElement::info = { "Element", &DOMNode::info, &DOMElementTable, 0 };
    01028 /* Source for DOMElementTable.
    01029 @begin DOMElementTable 3
    01030   tagName   DOMElement::TagName                         DontDelete|ReadOnly
    01031   style     DOMElement::Style                           DontDelete|ReadOnly
    01032 @end
    01033 */
    01034 DOMElement::DOMElement(ExecState *exec, const DOM::Element& e)
    01035   : DOMNode(DOMElementProto::self(exec), e) { }
    01036
    01037 DOMElement::DOMElement(const Object& proto, const DOM::Element& e)
    01038   : DOMNode(proto, e) { }
    01039
    01040 Value DOMElement::tryGet(ExecState *exec, const Identifier &propertyName) const
    01041 {
    01042 #ifdef KJS_VERBOSE
    01043   kdDebug(6070) << "DOMElement::tryGet " << propertyName.qstring() << endl;
    01044 #endif
    01045   DOM::Element element = static_cast<DOM::Element>(node);
    01046
    01047   const HashEntry* entry = Lookup::findEntry(&DOMElementTable, propertyName);
    01048   if (entry)
    01049   {
    01050     switch( entry->value ) {
    01051     case TagName:
    01052       return String(element.tagName());
    01053     case Style:
    01054       return getDOMCSSStyleDeclaration(exec,element.style());
    01055     default:
    01056       kdDebug(6070) << "WARNING: Unhandled token in DOMElement::tryGet : " << entry->value << endl;
    01057       break;
    01058     }
    01059   }
    01060   // We have to check in DOMNode before giving access to attributes, otherwise
    01061   // onload="..." would make onload return the string (attribute value) instead of
    01062   // the listener object (function).
    01063   if (DOMNode::hasProperty(exec, propertyName))
    01064     return DOMNode::tryGet(exec, propertyName);
    01065
    01066   DOM::DOMString attr = element.getAttribute( propertyName.string() );
    01067   // Give access to attributes
    01068   if ( !attr.isNull() )
    01069     return String( attr );
    01070
    01071   return Undefined();
    01072 }
    01073
    01074 Value DOMElementProtoFunc::tryCall(ExecState *exec, Object &thisObj, const List &args)
    01075 {
    01076   KJS_CHECK_THIS( KJS::DOMNode, thisObj ); // node should be enough here, given the cast
    01077   DOM::Node node = static_cast<DOMNode *>( thisObj.imp() )->toNode();
    01078   DOM::Element element = static_cast<DOM::Element>(node);
    01079
    01080   switch(id) {
    01081     case DOMElement::GetAttribute:
    01082       return String(element.getAttribute(args[0].toString(exec).string()));
    01083     case DOMElement::SetAttribute:
    01084       element.setAttribute(args[0].toString(exec).string(),args[1].toString(exec).string());
    01085       return Undefined();
    01086     case DOMElement::RemoveAttribute:
    01087       element.removeAttribute(args[0].toString(exec).string());
    01088       return Undefined();
    01089     case DOMElement::GetAttributeNode:
    01090       return getDOMNode(exec,element.getAttributeNode(args[0].toString(exec).string()));
    01091     case DOMElement::SetAttributeNode:
    01092       return getDOMNode(exec,element.setAttributeNode((new DOMNode(exec,KJS::toNode(args[0])))->toNode()));
    01093     case DOMElement::RemoveAttributeNode:
    01094       return getDOMNode(exec,element.removeAttributeNode((new DOMNode(exec,KJS::toNode(args[0])))->toNode()));
    01095     case DOMElement::GetElementsByTagName:
    01096       return getDOMNodeList(exec,element.getElementsByTagName(args[0].toString(exec).string()));
    01097     case DOMElement::HasAttribute: // DOM2
    01098       return Boolean(element.hasAttribute(args[0].toString(exec).string()));
    01099     case DOMElement::GetAttributeNS: // DOM2
    01100       return String(element.getAttributeNS(args[0].toString(exec).string(),args[1].toString(exec).string()));
    01101     case DOMElement::SetAttributeNS: // DOM2
    01102       element.setAttributeNS(args[0].toString(exec).string(),args[1].toString(exec).string(),args[2].toString(exec).string());
    01103       return Undefined();
    01104     case DOMElement::RemoveAttributeNS: // DOM2
    01105       element.removeAttributeNS(args[0].toString(exec).string(),args[1].toString(exec).string());
    01106       return Undefined();
    01107     case DOMElement::GetAttributeNodeNS: // DOM2
    01108       return getDOMNode(exec,element.getAttributeNodeNS(args[0].toString(exec).string(),args[1].toString(exec).string()));
    01109     case DOMElement::SetAttributeNodeNS: // DOM2
    01110       return getDOMNode(exec,element.setAttributeNodeNS((new DOMNode(exec,KJS::toNode(args[0])))->toNode()));
    01111     case DOMElement::GetElementsByTagNameNS: // DOM2
    01112       return getDOMNodeList(exec,element.getElementsByTagNameNS(args[0].toString(exec).string(),args[1].toString(exec).string()));
    01113     case DOMElement::HasAttributeNS: // DOM2
    01114       return Boolean(element.hasAttributeNS(args[0].toString(exec).string(),args[1].toString(exec).string()));
    01115   default:
    01116     return Undefined();
    01117   }
    01118 }
    01119
    01120 // -------------------------------------------------------------------------
    01121
    01122 /* Source for DOMDOMImplementationProtoTable.
    01123 @begin DOMDOMImplementationProtoTable 5
    01124   hasFeature        DOMDOMImplementation::HasFeature        DontDelete|Function 2
    01125   createCSSStyleSheet   DOMDOMImplementation::CreateCSSStyleSheet   DontDelete|Function 2
    01126 # DOM2
    01127   createDocumentType    DOMDOMImplementation::CreateDocumentType    DontDelete|Function 3
    01128   createDocument    DOMDOMImplementation::CreateDocument        DontDelete|Function 3
    01129   createHTMLDocument    DOMDOMImplementation::CreateHTMLDocument        DontDelete|Function 1
    01130 @end
    01131 */
    01132 DEFINE_PROTOTYPE("DOMImplementation",DOMDOMImplementationProto)
    01133 IMPLEMENT_PROTOFUNC_DOM(DOMDOMImplementationProtoFunc)
    01134 IMPLEMENT_PROTOTYPE(DOMDOMImplementationProto,DOMDOMImplementationProtoFunc)
    01135
    01136 const ClassInfo DOMDOMImplementation::info = { "DOMImplementation", 0, 0, 0 };
    01137
    01138 DOMDOMImplementation::DOMDOMImplementation(ExecState *exec, const DOM::DOMImplementation& i)
    01139   : DOMObject(DOMDOMImplementationProto::self(exec)), implementation(i) { }
    01140
    01141 DOMDOMImplementation::~DOMDOMImplementation()
    01142 {
    01143   ScriptInterpreter::forgetDOMObject(implementation.handle());
    01144 }
    01145
    01146 Value DOMDOMImplementationProtoFunc::tryCall(ExecState *exec, Object &thisObj, const List &args)
    01147 {
    01148   KJS_CHECK_THIS( KJS::DOMDOMImplementation, thisObj );
    01149   DOM::DOMImplementation implementation = static_cast<DOMDOMImplementation *>( thisObj.imp() )->toImplementation();
    01150
    01151   switch(id) {
    01152   case DOMDOMImplementation::HasFeature:
    01153     return Boolean(implementation.hasFeature(args[0].toString(exec).string(),args[1].toString(exec).string()));
    01154   case DOMDOMImplementation::CreateDocumentType: // DOM2
    01155     return getDOMNode(exec,implementation.createDocumentType(args[0].toString(exec).string(),args[1].toString(exec).string(),args[2].toString(exec).string()));
    01156   case DOMDOMImplementation::CreateDocument: { // DOM2
    01157     // Initially set the URL to document of the creator... this is so that it resides in the same
    01158     // host/domain for security checks. The URL will be updated if Document.load() is called.
    01159     KHTMLPart *part = ::qt_cast<KHTMLPart*>(static_cast<KJS::ScriptInterpreter*>(exec->interpreter())->part());
    01160     if (part) {
    01161       Document doc = implementation.createDocument(args[0].toString(exec).string(),args[1].toString(exec).string(),toNode(args[2]));
    01162       KURL url = static_cast<DocumentImpl*>(part->document().handle())->URL();
    01163       static_cast<DocumentImpl*>(doc.handle())->setURL(url.url());
    01164       return getDOMNode(exec,doc);
    01165     }
    01166     break;
    01167   }
    01168   case DOMDOMImplementation::CreateCSSStyleSheet: // DOM2
    01169     return getDOMStyleSheet(exec,implementation.createCSSStyleSheet(args[0].toString(exec).string(),args[1].toString(exec).string()));
    01170   case DOMDOMImplementation::CreateHTMLDocument: // DOM2-HTML
    01171     return getDOMNode(exec, implementation.createHTMLDocument(args[0].toString(exec).string()));
    01172   default:
    01173     break;
    01174   }
    01175   return Undefined();
    01176 }
    01177
    01178 // -------------------------------------------------------------------------
    01179
    01180 const ClassInfo DOMDocumentType::info = { "DocumentType", &DOMNode::info, &DOMDocumentTypeTable, 0 };
    01181
    01182 /* Source for DOMDocumentTypeTable.
    01183 @begin DOMDocumentTypeTable 6
    01184   name          DOMDocumentType::Name       DontDelete|ReadOnly
    01185   entities      DOMDocumentType::Entities   DontDelete|ReadOnly
    01186   notations     DOMDocumentType::Notations  DontDelete|ReadOnly
    01187 # DOM2
    01188   publicId      DOMDocumentType::PublicId   DontDelete|ReadOnly
    01189   systemId      DOMDocumentType::SystemId   DontDelete|ReadOnly
    01190   internalSubset    DOMDocumentType::InternalSubset DontDelete|ReadOnly
    01191 @end
    01192 */
    01193 DOMDocumentType::DOMDocumentType(ExecState *exec, const DOM::DocumentType& dt)
    01194   : DOMNode( /*### no proto yet*/exec, dt ) { }
    01195
    01196 Value DOMDocumentType::tryGet(ExecState *exec, const Identifier &propertyName) const
    01197 {
    01198 #ifdef KJS_VERBOSE
    01199   kdDebug(6070) << "DOMDocumentType::tryGet " << propertyName.qstring() << endl;
    01200 #endif
    01201   return DOMObjectLookupGetValue<DOMDocumentType, DOMNode>(exec, propertyName, &DOMDocumentTypeTable, this);
    01202 }
    01203
    01204 Value DOMDocumentType::getValueProperty(ExecState *exec, int token) const
    01205 {
    01206   DOM::DocumentType type = static_cast<DOM::DocumentType>(node);
    01207   switch (token) {
    01208   case Name:
    01209     return String(type.name());
    01210   case Entities:
    01211     return getDOMNamedNodeMap(exec,type.entities());
    01212   case Notations:
    01213     return getDOMNamedNodeMap(exec,type.notations());
    01214   case PublicId: // DOM2
    01215     return String(type.publicId());
    01216   case SystemId: // DOM2
    01217     return String(type.systemId());
    01218   case InternalSubset: // DOM2
    01219     return getString(type.internalSubset()); // can be null, see domts/level2/core/internalSubset01.html
    01220   default:
    01221     kdDebug(6070) << "WARNING: DOMDocumentType::getValueProperty unhandled token " << token << endl;
    01222     return Value();
    01223   }
    01224 }
    01225
    01226 // -------------------------------------------------------------------------
    01227
    01228 /* Source for DOMNamedNodeMapProtoTable.
    01229 @begin DOMNamedNodeMapProtoTable 7
    01230   getNamedItem      DOMNamedNodeMap::GetNamedItem       DontDelete|Function 1
    01231   setNamedItem      DOMNamedNodeMap::SetNamedItem       DontDelete|Function 1
    01232   removeNamedItem   DOMNamedNodeMap::RemoveNamedItem    DontDelete|Function 1
    01233   item          DOMNamedNodeMap::Item           DontDelete|Function 1
    01234 # DOM2
    01235   getNamedItemNS    DOMNamedNodeMap::GetNamedItemNS     DontDelete|Function 2
    01236   setNamedItemNS    DOMNamedNodeMap::SetNamedItemNS     DontDelete|Function 1
    01237   removeNamedItemNS DOMNamedNodeMap::RemoveNamedItemNS  DontDelete|Function 2
    01238 @end
    01239 @begin DOMNamedNodeMapTable 7
    01240   length        DOMNamedNodeMap::Length         DontDelete|Function 1
    01241 @end
    01242 */
    01243 DEFINE_PROTOTYPE("NamedNodeMap", DOMNamedNodeMapProto)
    01244 IMPLEMENT_PROTOFUNC_DOM(DOMNamedNodeMapProtoFunc)
    01245 IMPLEMENT_PROTOTYPE(DOMNamedNodeMapProto,DOMNamedNodeMapProtoFunc)
    01246
    01247 const ClassInfo DOMNamedNodeMap::info = { "NamedNodeMap", 0, &DOMNamedNodeMapTable, 0 };
    01248
    01249 DOMNamedNodeMap::DOMNamedNodeMap(ExecState *exec, const DOM::NamedNodeMap& m)
    01250   : DOMObject(DOMNamedNodeMapProto::self(exec)), map(m) { }
    01251
    01252 DOMNamedNodeMap::~DOMNamedNodeMap()
    01253 {
    01254   ScriptInterpreter::forgetDOMObject(map.handle());
    01255 }
    01256
    01257 bool DOMNamedNodeMap::hasProperty(ExecState *exec, const Identifier &p) const
    01258 {
    01259   // ## missing? array index
    01260   return DOMObject::hasProperty(exec, p);
    01261 }
    01262
    01263 Value DOMNamedNodeMap::tryGet(ExecState* exec, const Identifier &p) const
    01264 {
    01265   if (p == lengthPropertyName)
    01266     return Number(map.length());
    01267
    01268   // array index ?
    01269   bool ok;
    01270   long unsigned int idx = p.toULong(&ok);
    01271   if (ok)
    01272     return getDOMNode(exec,map.item(idx));
    01273
    01274   // Anything else (including functions, defined in the prototype)
    01275   return DOMObject::tryGet(exec, p);
    01276 }
    01277
    01278 Value DOMNamedNodeMapProtoFunc::tryCall(ExecState *exec, Object &thisObj, const List &args)
    01279 {
    01280   KJS_CHECK_THIS( KJS::DOMNamedNodeMap, thisObj );
    01281   DOM::NamedNodeMap map = static_cast<DOMNamedNodeMap *>(thisObj.imp())->toMap();
    01282
    01283   switch(id) {
    01284     case DOMNamedNodeMap::GetNamedItem:
    01285       return getDOMNode(exec, map.getNamedItem(args[0].toString(exec).string()));
    01286     case DOMNamedNodeMap::SetNamedItem:
    01287       return getDOMNode(exec, map.setNamedItem((new DOMNode(exec,KJS::toNode(args[0])))->toNode()));
    01288     case DOMNamedNodeMap::RemoveNamedItem:
    01289       return getDOMNode(exec, map.removeNamedItem(args[0].toString(exec).string()));
    01290     case DOMNamedNodeMap::Item:
    01291       return getDOMNode(exec, map.item(args[0].toInt32(exec)));
    01292     case DOMNamedNodeMap::GetNamedItemNS: // DOM2
    01293       return getDOMNode(exec, map.getNamedItemNS(args[0].toString(exec).string(),args[1].toString(exec).string()));
    01294     case DOMNamedNodeMap::SetNamedItemNS: // DOM2
    01295       return getDOMNode(exec, map.setNamedItemNS(toNode(args[0])));
    01296     case DOMNamedNodeMap::RemoveNamedItemNS: // DOM2
    01297       return getDOMNode(exec, map.removeNamedItemNS(args[0].toString(exec).string(),args[1].toString(exec).string()));
    01298     default:
    01299       break;
    01300   }
    01301
    01302   return Undefined();
    01303 }
    01304
    01305 // -------------------------------------------------------------------------
    01306
    01307 const ClassInfo DOMProcessingInstruction::info = { "ProcessingInstruction", &DOMNode::info, &DOMProcessingInstructionTable, 0 };
    01308
    01309 /* Source for DOMProcessingInstructionTable.
    01310 @begin DOMProcessingInstructionTable 3
    01311   target    DOMProcessingInstruction::Target    DontDelete|ReadOnly
    01312   data      DOMProcessingInstruction::Data      DontDelete
    01313   sheet     DOMProcessingInstruction::Sheet     DontDelete|ReadOnly
    01314 @end
    01315 */
    01316 Value DOMProcessingInstruction::tryGet(ExecState *exec, const Identifier &propertyName) const
    01317 {
    01318   return DOMObjectLookupGetValue<DOMProcessingInstruction, DOMNode>(exec, propertyName, &DOMProcessingInstructionTable, this);
    01319 }
    01320
    01321 Value DOMProcessingInstruction::getValueProperty(ExecState *exec, int token) const
    01322 {
    01323   switch (token) {
    01324   case Target:
    01325     return String(static_cast<DOM::ProcessingInstruction>(node).target());
    01326   case Data:
    01327     return String(static_cast<DOM::ProcessingInstruction>(node).data());
    01328   case Sheet:
    01329     return getDOMStyleSheet(exec,static_cast<DOM::ProcessingInstruction>(node).sheet());
    01330   default:
    01331     kdDebug(6070) << "WARNING: DOMProcessingInstruction::getValueProperty unhandled token " << token << endl;
    01332     return Value();
    01333   }
    01334 }
    01335
    01336 void DOMProcessingInstruction::tryPut(ExecState *exec, const Identifier &propertyName, const Value& value, int attr)
    01337 {
    01338   // Not worth using the hashtable for this one ;)
    01339   if (propertyName == "data")
    01340     static_cast<DOM::ProcessingInstruction>(node).setData(value.toString(exec).string());
    01341   else
    01342     DOMNode::tryPut(exec, propertyName,value,attr);
    01343 }
    01344
    01345 // -------------------------------------------------------------------------
    01346
    01347 const ClassInfo DOMNotation::info = { "Notation", &DOMNode::info, &DOMNotationTable, 0 };
    01348
    01349 /* Source for DOMNotationTable.
    01350 @begin DOMNotationTable 2
    01351   publicId      DOMNotation::PublicId   DontDelete|ReadOnly
    01352   systemId      DOMNotation::SystemId   DontDelete|ReadOnly
    01353 @end
    01354 */
    01355 Value DOMNotation::tryGet(ExecState *exec, const Identifier &propertyName) const
    01356 {
    01357   return DOMObjectLookupGetValue<DOMNotation, DOMNode>(exec, propertyName, &DOMNotationTable, this);
    01358 }
    01359
    01360 Value DOMNotation::getValueProperty(ExecState *, int token) const
    01361 {
    01362   switch (token) {
    01363   case PublicId:
    01364     return String(static_cast<DOM::Notation>(node).publicId());
    01365   case SystemId:
    01366     return String(static_cast<DOM::Notation>(node).systemId());
    01367   default:
    01368     kdDebug(6070) << "WARNING: DOMNotation::getValueProperty unhandled token " << token << endl;
    01369     return Value();
    01370   }
    01371 }
    01372
    01373 // -------------------------------------------------------------------------
    01374
    01375 const ClassInfo DOMEntity::info = { "Entity", &DOMNode::info, 0, 0 };
    01376
    01377 /* Source for DOMEntityTable.
    01378 @begin DOMEntityTable 2
    01379   publicId      DOMEntity::PublicId     DontDelete|ReadOnly
    01380   systemId      DOMEntity::SystemId     DontDelete|ReadOnly
    01381   notationName      DOMEntity::NotationName DontDelete|ReadOnly
    01382 @end
    01383 */
    01384 Value DOMEntity::tryGet(ExecState *exec, const Identifier &propertyName) const
    01385 {
    01386   return DOMObjectLookupGetValue<DOMEntity, DOMNode>(exec, propertyName, &DOMEntityTable, this);
    01387 }
    01388
    01389 Value DOMEntity::getValueProperty(ExecState *, int token) const
    01390 {
    01391   switch (token) {
    01392   case PublicId:
    01393     return String(static_cast<DOM::Entity>(node).publicId());
    01394   case SystemId:
    01395     return String(static_cast<DOM::Entity>(node).systemId());
    01396   case NotationName:
    01397     return String(static_cast<DOM::Entity>(node).notationName());
    01398   default:
    01399     kdDebug(6070) << "WARNING: DOMEntity::getValueProperty unhandled token " << token << endl;
    01400     return Value();
    01401   }
    01402 }
    01403
    01404 // -------------------------------------------------------------------------
    01405
    01406 bool KJS::checkNodeSecurity(ExecState *exec, const DOM::Node& n)
    01407 {
    01408   // Check to see if the currently executing interpreter is allowed to access the specified node
    01409   if (n.isNull())
    01410     return true;
    01411   KHTMLView *view = n.handle()->getDocument()->view();
    01412   Window* win = view && view->part() ? Window::retrieveWindow(view->part()) : 0L;
    01413   if ( !win || !win->isSafeScript(exec) )
    01414     return false;
    01415   return true;
    01416 }
    01417
    01418 Value KJS::getDOMNode(ExecState *exec, const DOM::Node& n)
    01419 {
    01420   DOMObject *ret = 0;
    01421   if (n.isNull())
    01422     return Null();
    01423   ScriptInterpreter* interp = static_cast<ScriptInterpreter *>(exec->interpreter());
    01424   if ((ret = interp->getDOMObject(n.handle())))
    01425     return Value(ret);
    01426
    01427   switch (n.nodeType()) {
    01428     case DOM::Node::ELEMENT_NODE:
    01429       if (static_cast<DOM::Element>(n).isHTMLElement())
    01430         ret = new HTMLElement(exec, static_cast<DOM::HTMLElement>(n));
    01431       else
    01432         ret = new DOMElement(exec, static_cast<DOM::Element>(n));
    01433       break;
    01434     case DOM::Node::ATTRIBUTE_NODE:
    01435       ret = new DOMAttr(exec, static_cast<DOM::Attr>(n));
    01436       break;
    01437     case DOM::Node::TEXT_NODE:
    01438     case DOM::Node::CDATA_SECTION_NODE:
    01439       ret = new DOMText(exec, static_cast<DOM::Text>(n));
    01440       break;
    01441     case DOM::Node::ENTITY_REFERENCE_NODE:
    01442       ret = new DOMNode(exec, n);
    01443       break;
    01444     case DOM::Node::ENTITY_NODE:
    01445       ret = new DOMEntity(exec, static_cast<DOM::Entity>(n));
    01446       break;
    01447     case DOM::Node::PROCESSING_INSTRUCTION_NODE:
    01448       ret = new DOMProcessingInstruction(exec, static_cast<DOM::ProcessingInstruction>(n));
    01449       break;
    01450     case DOM::Node::COMMENT_NODE:
    01451       ret = new DOMCharacterData(exec, static_cast<DOM::CharacterData>(n));
    01452       break;
    01453     case DOM::Node::DOCUMENT_NODE:
    01454       if (static_cast<DOM::Document>(n).isHTMLDocument())
    01455         ret = new HTMLDocument(exec, static_cast<DOM::HTMLDocument>(n));
    01456       else
    01457         ret = new DOMDocument(exec, static_cast<DOM::Document>(n));
    01458       break;
    01459     case DOM::Node::DOCUMENT_TYPE_NODE:
    01460       ret = new DOMDocumentType(exec, static_cast<DOM::DocumentType>(n));
    01461       break;
    01462     case DOM::Node::DOCUMENT_FRAGMENT_NODE:
    01463       ret = new DOMNode(exec, n);
    01464       break;
    01465     case DOM::Node::NOTATION_NODE:
    01466       ret = new DOMNotation(exec, static_cast<DOM::Notation>(n));
    01467       break;
    01468     default:
    01469       ret = new DOMNode(exec, n);
    01470   }
    01471   interp->putDOMObject(n.handle(),ret);
    01472
    01473   return Value(ret);
    01474 }
    01475
    01476 Value KJS::getDOMNamedNodeMap(ExecState *exec, const DOM::NamedNodeMap& m)
    01477 {
    01478   return Value(cacheDOMObject<DOM::NamedNodeMap, KJS::DOMNamedNodeMap>(exec, m));
    01479 }
    01480
    01481 Value KJS::getDOMNodeList(ExecState *exec, const DOM::NodeList& l)
    01482 {
    01483   return Value(cacheDOMObject<DOM::NodeList, KJS::DOMNodeList>(exec, l));
    01484 }
    01485
    01486 Value KJS::getDOMDOMImplementation(ExecState *exec, const DOM::DOMImplementation& i)
    01487 {
    01488   return Value(cacheDOMObject<DOM::DOMImplementation, KJS::DOMDOMImplementation>(exec, i));
    01489 }
    01490
    01491 // -------------------------------------------------------------------------
    01492
    01493 const ClassInfo NodeConstructor::info = { "NodeConstructor", 0, &NodeConstructorTable, 0 };
    01494 /* Source for NodeConstructorTable.
    01495 @begin NodeConstructorTable 11
    01496   ELEMENT_NODE      DOM::Node::ELEMENT_NODE     DontDelete|ReadOnly
    01497   ATTRIBUTE_NODE    DOM::Node::ATTRIBUTE_NODE       DontDelete|ReadOnly
    01498   TEXT_NODE     DOM::Node::TEXT_NODE        DontDelete|ReadOnly
    01499   CDATA_SECTION_NODE    DOM::Node::CDATA_SECTION_NODE   DontDelete|ReadOnly
    01500   ENTITY_REFERENCE_NODE DOM::Node::ENTITY_REFERENCE_NODE    DontDelete|ReadOnly
    01501   ENTITY_NODE       DOM::Node::ENTITY_NODE      DontDelete|ReadOnly
    01502   PROCESSING_INSTRUCTION_NODE DOM::Node::PROCESSING_INSTRUCTION_NODE DontDelete|ReadOnly
    01503   COMMENT_NODE      DOM::Node::COMMENT_NODE     DontDelete|ReadOnly
    01504   DOCUMENT_NODE     DOM::Node::DOCUMENT_NODE        DontDelete|ReadOnly
    01505   DOCUMENT_TYPE_NODE    DOM::Node::DOCUMENT_TYPE_NODE   DontDelete|ReadOnly
    01506   DOCUMENT_FRAGMENT_NODE DOM::Node::DOCUMENT_FRAGMENT_NODE  DontDelete|ReadOnly
    01507   NOTATION_NODE     DOM::Node::NOTATION_NODE        DontDelete|ReadOnly
    01508 @end
    01509 */
    01510
    01511 NodeConstructor::NodeConstructor(ExecState *exec)
    01512   : DOMObject(exec->interpreter()->builtinObjectPrototype())
    01513 {
    01514 }
    01515
    01516 Value NodeConstructor::tryGet(ExecState *exec, const Identifier &propertyName) const
    01517 {
    01518   return DOMObjectLookupGetValue<NodeConstructor, DOMObject>(exec, propertyName, &NodeConstructorTable, this);
    01519 }
    01520
    01521 Value NodeConstructor::getValueProperty(ExecState *, int token) const
    01522 {
    01523   // We use the token as the value to return directly
    01524   return Number((unsigned int)token);
    01525 #if 0
    01526   switch (token) {
    01527   case ELEMENT_NODE:
    01528     return Number((unsigned int)DOM::Node::ELEMENT_NODE);
    01529   case ATTRIBUTE_NODE:
    01530     return Number((unsigned int)DOM::Node::ATTRIBUTE_NODE);
    01531   case TEXT_NODE:
    01532     return Number((unsigned int)DOM::Node::TEXT_NODE);
    01533   case CDATA_SECTION_NODE:
    01534     return Number((unsigned int)DOM::Node::CDATA_SECTION_NODE);
    01535   case ENTITY_REFERENCE_NODE:
    01536     return Number((unsigned int)DOM::Node::ENTITY_REFERENCE_NODE);
    01537   case ENTITY_NODE:
    01538     return Number((unsigned int)DOM::Node::ENTITY_NODE);
    01539   case PROCESSING_INSTRUCTION_NODE:
    01540     return Number((unsigned int)DOM::Node::PROCESSING_INSTRUCTION_NODE);
    01541   case COMMENT_NODE:
    01542     return Number((unsigned int)DOM::Node::COMMENT_NODE);
    01543   case DOCUMENT_NODE:
    01544     return Number((unsigned int)DOM::Node::DOCUMENT_NODE);
    01545   case DOCUMENT_TYPE_NODE:
    01546     return Number((unsigned int)DOM::Node::DOCUMENT_TYPE_NODE);
    01547   case DOCUMENT_FRAGMENT_NODE:
    01548     return Number((unsigned int)DOM::Node::DOCUMENT_FRAGMENT_NODE);
    01549   case NOTATION_NODE:
    01550     return Number((unsigned int)DOM::Node::NOTATION_NODE);
    01551   default:
    01552     kdDebug(6070) << "WARNING: NodeConstructor::getValueProperty unhandled token " << token << endl;
    01553     return Value();
    01554   }
    01555 #endif
    01556 }
    01557
    01558 Object KJS::getNodeConstructor(ExecState *exec)
    01559 {
    01560   return Object(cacheGlobalObject<NodeConstructor>(exec, "[[node.constructor]]"));
    01561 }
    01562
    01563 // -------------------------------------------------------------------------
    01564
    01565 const ClassInfo DOMExceptionConstructor::info = { "DOMExceptionConstructor", 0, 0, 0 };
    01566
    01567 /* Source for DOMExceptionConstructorTable.
    01568 @begin DOMExceptionConstructorTable 15
    01569   INDEX_SIZE_ERR        DOM::DOMException::INDEX_SIZE_ERR       DontDelete|ReadOnly
    01570   DOMSTRING_SIZE_ERR        DOM::DOMException::DOMSTRING_SIZE_ERR   DontDelete|ReadOnly
    01571   HIERARCHY_REQUEST_ERR     DOM::DOMException::HIERARCHY_REQUEST_ERR    DontDelete|ReadOnly
    01572   WRONG_DOCUMENT_ERR        DOM::DOMException::WRONG_DOCUMENT_ERR   DontDelete|ReadOnly
    01573   INVALID_CHARACTER_ERR     DOM::DOMException::INVALID_CHARACTER_ERR    DontDelete|ReadOnly
    01574   NO_DATA_ALLOWED_ERR       DOM::DOMException::NO_DATA_ALLOWED_ERR  DontDelete|ReadOnly
    01575   NO_MODIFICATION_ALLOWED_ERR   DOM::DOMException::NO_MODIFICATION_ALLOWED_ERR  DontDelete|ReadOnly
    01576   NOT_FOUND_ERR         DOM::DOMException::NOT_FOUND_ERR        DontDelete|ReadOnly
    01577   NOT_SUPPORTED_ERR     DOM::DOMException::NOT_SUPPORTED_ERR    DontDelete|ReadOnly
    01578   INUSE_ATTRIBUTE_ERR       DOM::DOMException::INUSE_ATTRIBUTE_ERR  DontDelete|ReadOnly
    01579   INVALID_STATE_ERR     DOM::DOMException::INVALID_STATE_ERR    DontDelete|ReadOnly
    01580   SYNTAX_ERR            DOM::DOMException::SYNTAX_ERR       DontDelete|ReadOnly
    01581   INVALID_MODIFICATION_ERR  DOM::DOMException::INVALID_MODIFICATION_ERR DontDelete|ReadOnly
    01582   NAMESPACE_ERR         DOM::DOMException::NAMESPACE_ERR        DontDelete|ReadOnly
    01583   INVALID_ACCESS_ERR        DOM::DOMException::INVALID_ACCESS_ERR   DontDelete|ReadOnly
    01584 @end
    01585 */
    01586
    01587 DOMExceptionConstructor::DOMExceptionConstructor(ExecState* exec)
    01588   : DOMObject(exec->interpreter()->builtinObjectPrototype())
    01589 {
    01590 }
    01591
    01592 Value DOMExceptionConstructor::tryGet(ExecState *exec, const Identifier &propertyName) const
    01593 {
    01594   return DOMObjectLookupGetValue<DOMExceptionConstructor, DOMObject>(exec, propertyName, &DOMExceptionConstructorTable, this);
    01595 }
    01596
    01597 Value DOMExceptionConstructor::getValueProperty(ExecState *, int token) const
    01598 {
    01599   // We use the token as the value to return directly
    01600   return Number((unsigned int)token);
    01601 #if 0
    01602   switch (token) {
    01603   case INDEX_SIZE_ERR:
    01604     return Number((unsigned int)DOM::DOMException::INDEX_SIZE_ERR);
    01605   case DOMSTRING_SIZE_ERR:
    01606     return Number((unsigned int)DOM::DOMException::DOMSTRING_SIZE_ERR);
    01607   case HIERARCHY_REQUEST_ERR:
    01608     return Number((unsigned int)DOM::DOMException::HIERARCHY_REQUEST_ERR);
    01609   case WRONG_DOCUMENT_ERR:
    01610     return Number((unsigned int)DOM::DOMException::WRONG_DOCUMENT_ERR);
    01611   case INVALID_CHARACTER_ERR:
    01612     return Number((unsigned int)DOM::DOMException::INVALID_CHARACTER_ERR);
    01613   case NO_DATA_ALLOWED_ERR:
    01614     return Number((unsigned int)DOM::DOMException::NO_DATA_ALLOWED_ERR);
    01615   case NO_MODIFICATION_ALLOWED_ERR:
    01616     return Number((unsigned int)DOM::DOMException::NO_MODIFICATION_ALLOWED_ERR);
    01617   case NOT_FOUND_ERR:
    01618     return Number((unsigned int)DOM::DOMException::NOT_FOUND_ERR);
    01619   case NOT_SUPPORTED_ERR:
    01620     return Number((unsigned int)DOM::DOMException::NOT_SUPPORTED_ERR);
    01621   case INUSE_ATTRIBUTE_ERR:
    01622     return Number((unsigned int)DOM::DOMException::INUSE_ATTRIBUTE_ERR);
    01623   case INVALID_STATE_ERR:
    01624     return Number((unsigned int)DOM::DOMException::INVALID_STATE_ERR);
    01625   case SYNTAX_ERR:
    01626     return Number((unsigned int)DOM::DOMException::SYNTAX_ERR);
    01627   case INVALID_MODIFICATION_ERR:
    01628     return Number((unsigned int)DOM::DOMException::INVALID_MODIFICATION_ERR);
    01629   case NAMESPACE_ERR:
    01630     return Number((unsigned int)DOM::DOMException::NAMESPACE_ERR);
    01631   case INVALID_ACCESS_ERR:
    01632     return Number((unsigned int)DOM::DOMException::INVALID_ACCESS_ERR);
    01633   default:
    01634     kdDebug(6070) << "WARNING: DOMExceptionConstructor::getValueProperty unhandled token " << token << endl;
    01635     return Value();
    01636   }
    01637 #endif
    01638 }
    01639
    01640 Object KJS::getDOMExceptionConstructor(ExecState *exec)
    01641 {
    01642   return cacheGlobalObject<DOMExceptionConstructor>(exec, "[[DOMException.constructor]]");
    01643 }
    01644
    01645 // -------------------------------------------------------------------------
    01646
    01647 /* Source for DOMNamedNodesCollection.
    01648 @begin DOMNamedNodesCollectionTable 1
    01649   length        KJS::DOMNamedNodesCollection::Length        DontDelete|ReadOnly
    01650 @end
    01651 */
    01652 const ClassInfo KJS::DOMNamedNodesCollection::info = { "DOMNamedNodesCollection", 0, &DOMNamedNodesCollectionTable, 0 };
    01653
    01654 // Such a collection is usually very short-lived, it only exists
    01655 // for constructs like document.forms.<name>[1],
    01656 // so it shouldn't be a problem that it's storing all the nodes (with the same name). (David)
    01657 DOMNamedNodesCollection::DOMNamedNodesCollection(ExecState *exec, const QValueList<DOM::Node>& nodes )
    01658   : DOMObject(exec->interpreter()->builtinObjectPrototype()),
    01659   m_nodes(nodes)
    01660 {
    01661   // Maybe we should ref (and deref in the dtor) the nodes, though ?
    01662 }
    01663
    01664 Value DOMNamedNodesCollection::tryGet(ExecState *exec, const Identifier &propertyName) const
    01665 {
    01666   kdDebug(6070) << k_funcinfo << propertyName.ascii() << endl;
    01667   if (propertyName == lengthPropertyName)
    01668     return Number(m_nodes.count());
    01669   // index?
    01670   bool ok;
    01671   unsigned int u = propertyName.toULong(&ok);
    01672   if (ok && u < m_nodes.count()) {
    01673     DOM::Node node = m_nodes[u];
    01674     return getDOMNode(exec,node);
    01675   }
    01676   return DOMObject::tryGet(exec,propertyName);
    01677 }
    01678
    01679 // -------------------------------------------------------------------------
    01680
    01681 const ClassInfo DOMCharacterData::info = { "CharacterImp",
    01682                       &DOMNode::info, &DOMCharacterDataTable, 0 };
    01683 /*
    01684 @begin DOMCharacterDataTable 2
    01685   data      DOMCharacterData::Data      DontDelete
    01686   length    DOMCharacterData::Length    DontDelete|ReadOnly
    01687 @end
    01688 @begin DOMCharacterDataProtoTable 7
    01689   substringData DOMCharacterData::SubstringData DontDelete|Function 2
    01690   appendData    DOMCharacterData::AppendData    DontDelete|Function 1
    01691   insertData    DOMCharacterData::InsertData    DontDelete|Function 2
    01692   deleteData    DOMCharacterData::DeleteData    DontDelete|Function 2
    01693   replaceData   DOMCharacterData::ReplaceData   DontDelete|Function 2
    01694 @end
    01695 */
    01696 DEFINE_PROTOTYPE("DOMCharacterData",DOMCharacterDataProto)
    01697 IMPLEMENT_PROTOFUNC_DOM(DOMCharacterDataProtoFunc)
    01698 IMPLEMENT_PROTOTYPE_WITH_PARENT(DOMCharacterDataProto,DOMCharacterDataProtoFunc, DOMNodeProto)
    01699
    01700 DOMCharacterData::DOMCharacterData(ExecState *exec, const DOM::CharacterData& d)
    01701  : DOMNode(DOMCharacterDataProto::self(exec), d) {}
    01702
    01703 DOMCharacterData::DOMCharacterData(const Object& proto, const DOM::CharacterData& d)
    01704  : DOMNode(proto, d) {}
    01705
    01706 Value DOMCharacterData::tryGet(ExecState *exec, const Identifier &p) const
    01707 {
    01708 #ifdef KJS_VERBOSE
    01709   kdDebug(6070)<<"DOMCharacterData::tryGet "<<p.string().string()<<endl;
    01710 #endif
    01711   return DOMObjectLookupGetValue<DOMCharacterData,DOMNode>(exec,p,&DOMCharacterDataTable,this);
    01712 }
    01713
    01714 Value DOMCharacterData::getValueProperty(ExecState *, int token) const
    01715 {
    01716   DOM::CharacterData data = static_cast<DOM::CharacterData>(node);
    01717   switch (token) {
    01718   case Data:
    01719     return String(data.data());
    01720   case Length:
    01721     return Number(data.length());
    01722  default:
    01723    kdDebug(6070) << "WARNING: Unhandled token in DOMCharacterData::getValueProperty : " << token << endl;
    01724    return Value();
    01725   }
    01726 }
    01727
    01728 void DOMCharacterData::tryPut(ExecState *exec, const Identifier &propertyName, const Value& value, int attr)
    01729 {
    01730   if (propertyName == "data")
    01731     static_cast<DOM::CharacterData>(node).setData(value.toString(exec).string());
    01732   else
    01733     DOMNode::tryPut(exec, propertyName,value,attr);
    01734 }
    01735
    01736 Value DOMCharacterDataProtoFunc::tryCall(ExecState *exec, Object &thisObj, const List &args)
    01737 {
    01738   KJS_CHECK_THIS( KJS::DOMCharacterData, thisObj );
    01739   DOM::CharacterData data = static_cast<DOMCharacterData *>(thisObj.imp())->toData();
    01740   switch(id) {
    01741     case DOMCharacterData::SubstringData:
    01742       return String(data.substringData(args[0].toInteger(exec),args[1].toInteger(exec)));
    01743     case DOMCharacterData::AppendData:
    01744       data.appendData(args[0].toString(exec).string());
    01745       return Undefined();
    01746       break;
    01747     case DOMCharacterData::InsertData:
    01748       data.insertData(args[0].toInteger(exec),args[1].toString(exec).string());
    01749       return  Undefined();
    01750       break;
    01751     case DOMCharacterData::DeleteData:
    01752       data.deleteData(args[0].toInteger(exec),args[1].toInteger(exec));
    01753       return  Undefined();
    01754       break;
    01755     case DOMCharacterData::ReplaceData:
    01756       data.replaceData(args[0].toInteger(exec),args[1].toInteger(exec),args[2].toString(exec).string());
    01757       return Undefined();
    01758       break;
    01759     default:
    01760       return Undefined();
    01761   }
    01762 }
    01763
    01764 // -------------------------------------------------------------------------
    01765
    01766 const ClassInfo DOMText::info = { "Text",
    01767                  &DOMCharacterData::info, 0, 0 };
    01768 /*
    01769 @begin DOMTextProtoTable 1
    01770   splitText DOMText::SplitText  DontDelete|Function 1
    01771 @end
    01772 */
    01773 DEFINE_PROTOTYPE("DOMText",DOMTextProto)
    01774 IMPLEMENT_PROTOFUNC_DOM(DOMTextProtoFunc)
    01775 IMPLEMENT_PROTOTYPE_WITH_PARENT(DOMTextProto,DOMTextProtoFunc,DOMCharacterDataProto)
    01776
    01777 DOMText::DOMText(ExecState *exec, const DOM::Text& t)
    01778   : DOMCharacterData(DOMTextProto::self(exec), t) { }
    01779
    01780 Value DOMText::tryGet(ExecState *exec, const Identifier &p) const
    01781 {
    01782   if (p.isEmpty())
    01783     return Undefined(); // ### TODO
    01784   else
    01785     return DOMCharacterData::tryGet(exec, p);
    01786 }
    01787
    01788 Value DOMTextProtoFunc::tryCall(ExecState *exec, Object &thisObj, const List &args)
    01789 {
    01790   KJS_CHECK_THIS( KJS::DOMText, thisObj );
    01791   DOM::Text text = static_cast<DOMText *>(thisObj.imp())->toText();
    01792   switch(id) {
    01793     case DOMText::SplitText:
    01794       return getDOMNode(exec,text.splitText(args[0].toInteger(exec)));
    01795       break;
    01796     default:
    01797       return Undefined();
    01798   }
    01799 }

This file is part of the documentation for khtml Library Version 3.4.1.
Documentation copyright © 1996-2004 the KDE developers.
Generated on Sat Jun 11 20:33:18 2005 by doxygen 1.4.1 written by Dimitri van Heesch, © 1997-2003