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