khtml Library API Documentation

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