kjs_dom.cpp Source File (khtml Library)

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

This file is part of the documentation for kdelibs Version 3.1.5.
Documentation copyright © 1996-2002 the KDE developers.
Generated on Wed Jan 28 13:34:14 2004 by doxygen 1.3.4 written by Dimitri van Heesch, © 1997-2001