00001
00024 #include "dom/dom_exception.h"
00025
00026 #include "xml/dom_textimpl.h"
00027 #include "xml/dom_xmlimpl.h"
00028 #include "xml/dom2_rangeimpl.h"
00029 #include "xml/dom2_eventsimpl.h"
00030 #include "xml/xml_tokenizer.h"
00031
00032 #include "css/csshelper.h"
00033 #include "css/cssstyleselector.h"
00034 #include "css/css_stylesheetimpl.h"
00035 #include "misc/htmlhashes.h"
00036 #include "misc/helper.h"
00037 #include "ecma/kjs_proxy.h"
00038
00039 #include <qptrstack.h>
00040 #include <qpaintdevicemetrics.h>
00041 #include <kdebug.h>
00042 #include <kstaticdeleter.h>
00043
00044 #include "rendering/render_root.h"
00045 #include "rendering/render_replaced.h"
00046
00047 #include "khtmlview.h"
00048 #include "khtml_part.h"
00049
00050 #include <kglobalsettings.h>
00051 #include <kstringhandler.h>
00052 #include <krfcdate.h>
00053 #include "khtml_settings.h"
00054 #include "khtmlpart_p.h"
00055
00056 #include "html/html_baseimpl.h"
00057 #include "html/html_blockimpl.h"
00058 #include "html/html_documentimpl.h"
00059 #include "html/html_formimpl.h"
00060 #include "html/html_headimpl.h"
00061 #include "html/html_imageimpl.h"
00062 #include "html/html_listimpl.h"
00063 #include "html/html_miscimpl.h"
00064 #include "html/html_tableimpl.h"
00065 #include "html/html_objectimpl.h"
00066
00067 #include <kio/job.h>
00068 #include <kapplication.h>
00069
00070 using namespace DOM;
00071 using namespace khtml;
00072
00073 DOMImplementationImpl *DOMImplementationImpl::m_instance = 0;
00074
00075 DOMImplementationImpl::DOMImplementationImpl()
00076 {
00077 }
00078
00079 DOMImplementationImpl::~DOMImplementationImpl()
00080 {
00081 }
00082
00083 bool DOMImplementationImpl::hasFeature ( const DOMString &feature, const DOMString &version )
00084 {
00085
00086 QString lower = feature.string().lower();
00087 if ((lower == "html" || lower == "xml") &&
00088 (version == "1.0" || version == "null" || version == "" || version.isNull()))
00089 return true;
00090 else
00091 return false;
00092 }
00093
00094 DocumentTypeImpl *DOMImplementationImpl::createDocumentType( const DOMString &qualifiedName, const DOMString &publicId,
00095 const DOMString &systemId, int &exceptioncode )
00096 {
00097
00098 if (qualifiedName.isNull()) {
00099 exceptioncode = DOMException::NAMESPACE_ERR;
00100 return 0;
00101 }
00102
00103
00104 if (!Element::khtmlValidQualifiedName(qualifiedName)) {
00105 exceptioncode = DOMException::INVALID_CHARACTER_ERR;
00106 return 0;
00107 }
00108
00109
00110 if (Element::khtmlMalformedQualifiedName(qualifiedName)) {
00111 exceptioncode = DOMException::NAMESPACE_ERR;
00112 return 0;
00113 }
00114
00115 return new DocumentTypeImpl(this,0,qualifiedName,publicId,systemId);
00116 }
00117
00118 DOMImplementationImpl* DOMImplementationImpl::getInterface(const DOMString& ) const
00119 {
00120
00121 return 0;
00122 }
00123
00124 DocumentImpl *DOMImplementationImpl::createDocument( const DOMString &namespaceURI, const DOMString &qualifiedName,
00125 const DocumentType &doctype, int &exceptioncode )
00126 {
00127 exceptioncode = 0;
00128
00129
00130 if (qualifiedName.isNull()) {
00131 exceptioncode = DOMException::NAMESPACE_ERR;
00132 return 0;
00133 }
00134
00135
00136 if (!Element::khtmlValidQualifiedName(qualifiedName)) {
00137 exceptioncode = DOMException::INVALID_CHARACTER_ERR;
00138 return 0;
00139 }
00140
00141
00142
00143
00144
00145
00146 int colonpos = -1;
00147 uint i;
00148 DOMStringImpl *qname = qualifiedName.implementation();
00149 for (i = 0; i < qname->l && colonpos < 0; i++) {
00150 if ((*qname)[i] == ':')
00151 colonpos = i;
00152 }
00153
00154 if (Element::khtmlMalformedQualifiedName(qualifiedName) ||
00155 (colonpos >= 0 && namespaceURI.isNull()) ||
00156 (colonpos == 3 && qualifiedName[0] == 'x' && qualifiedName[1] == 'm' && qualifiedName[2] == 'l' &&
00157 namespaceURI != "http://www.w3.org/XML/1998/namespace")) {
00158
00159 exceptioncode = DOMException::NAMESPACE_ERR;
00160 return 0;
00161 }
00162
00163 DocumentTypeImpl *dtype = static_cast<DocumentTypeImpl*>(doctype.handle());
00164
00165
00166 if (dtype && (dtype->getDocument() || dtype->implementation() != this)) {
00167 exceptioncode = DOMException::WRONG_DOCUMENT_ERR;
00168 return 0;
00169 }
00170
00171
00172 DocumentImpl *doc = new DocumentImpl(this, 0);
00173
00174
00175
00176 if (doc->doctype() && dtype)
00177 doc->doctype()->copyFrom(*dtype);
00178
00179 ElementImpl *element = doc->createElementNS(namespaceURI,qualifiedName);
00180 doc->appendChild(element,exceptioncode);
00181 if (exceptioncode) {
00182 delete element;
00183 delete doc;
00184 return 0;
00185 }
00186
00187 return doc;
00188 }
00189
00190 CSSStyleSheetImpl *DOMImplementationImpl::createCSSStyleSheet(DOMStringImpl *, DOMStringImpl *media,
00191 int &)
00192 {
00193
00194
00195 CSSStyleSheetImpl *parent = 0L;
00196 CSSStyleSheetImpl *sheet = new CSSStyleSheetImpl(parent, DOMString());
00197 sheet->setMedia(new MediaListImpl(sheet, media));
00198 return sheet;
00199 }
00200
00201 DocumentImpl *DOMImplementationImpl::createDocument( KHTMLView *v )
00202 {
00203 return new DocumentImpl(this, v);
00204 }
00205
00206 HTMLDocumentImpl *DOMImplementationImpl::createHTMLDocument( KHTMLView *v )
00207 {
00208 return new HTMLDocumentImpl(this, v);
00209 }
00210
00211 DOMImplementationImpl *DOMImplementationImpl::instance()
00212 {
00213 if (!m_instance) {
00214 m_instance = new DOMImplementationImpl();
00215 m_instance->ref();
00216 }
00217
00218 return m_instance;
00219 }
00220
00221
00222
00223 static KStaticDeleter< QPtrList<DocumentImpl> > s_changedDocumentsDeleter;
00224 QPtrList<DocumentImpl> * DocumentImpl::changedDocuments;
00225
00226
00227 DocumentImpl::DocumentImpl(DOMImplementationImpl *_implementation, KHTMLView *v)
00228 : NodeBaseImpl( new DocumentPtr() )
00229 {
00230 document->doc = this;
00231 m_paintDeviceMetrics = 0;
00232 m_decoderMibEnum = 0;
00233 m_textColor = Qt::black;
00234
00235 m_view = v;
00236
00237 if ( v ) {
00238 m_docLoader = new DocLoader(v->part(), this );
00239 setPaintDevice( m_view );
00240 }
00241 else
00242 m_docLoader = new DocLoader( 0, this );
00243
00244 visuallyOrdered = false;
00245 m_loadingSheet = false;
00246 m_bParsing = false;
00247 m_docChanged = false;
00248 m_sheet = 0;
00249 m_elemSheet = 0;
00250 m_tokenizer = 0;
00251
00252
00253
00254 m_doctype = new DocumentTypeImpl(_implementation, document,
00255 DOMString() ,
00256 DOMString() ,
00257 DOMString() );
00258 m_doctype->ref();
00259
00260 m_implementation = _implementation;
00261 m_implementation->ref();
00262 pMode = Strict;
00263 hMode = XHtml;
00264 m_textColor = "#000000";
00265 m_elementNames = 0;
00266 m_elementNameAlloc = 0;
00267 m_elementNameCount = 0;
00268 m_attrNames = 0;
00269 m_attrNameAlloc = 0;
00270 m_attrNameCount = 0;
00271 m_namespaceURIAlloc = 4;
00272 m_namespaceURICount = 1;
00273 QString xhtml(XHTML_NAMESPACE);
00274 m_namespaceURIs = new DOMStringImpl* [m_namespaceURIAlloc];
00275 m_namespaceURIs[0] = new DOMStringImpl(xhtml.unicode(), xhtml.length());
00276 m_namespaceURIs[0]->ref();
00277 m_focusNode = 0;
00278 m_defaultView = new AbstractViewImpl(this);
00279 m_defaultView->ref();
00280 m_listenerTypes = 0;
00281 m_styleSheets = new StyleSheetListImpl;
00282 m_styleSheets->ref();
00283 m_inDocument = true;
00284 m_styleSelectorDirty = false;
00285 m_styleSelector = 0;
00286 m_windowEventListeners.setAutoDelete(true);
00287
00288 m_inStyleRecalc = false;
00289 }
00290
00291 DocumentImpl::~DocumentImpl()
00292 {
00293 assert( !m_render );
00294
00295 if (changedDocuments && m_docChanged)
00296 changedDocuments->remove(this);
00297 delete m_tokenizer;
00298 document->doc = 0;
00299 delete m_sheet;
00300 delete m_styleSelector;
00301 delete m_docLoader;
00302 if (m_elemSheet ) m_elemSheet->deref();
00303 if (m_doctype)
00304 m_doctype->deref();
00305 m_implementation->deref();
00306 delete m_paintDeviceMetrics;
00307
00308 if (m_elementNames) {
00309 for (unsigned short id = 0; id < m_elementNameCount; id++)
00310 m_elementNames[id]->deref();
00311 delete [] m_elementNames;
00312 }
00313 if (m_attrNames) {
00314 for (unsigned short id = 0; id < m_attrNameCount; id++)
00315 m_attrNames[id]->deref();
00316 delete [] m_attrNames;
00317 }
00318 for (unsigned short id = 0; id < m_namespaceURICount; ++id)
00319 m_namespaceURIs[id]->deref();
00320 delete [] m_namespaceURIs;
00321 m_defaultView->deref();
00322 m_styleSheets->deref();
00323 if (m_focusNode)
00324 m_focusNode->deref();
00325 }
00326
00327
00328 DocumentTypeImpl *DocumentImpl::doctype() const
00329 {
00330 return m_doctype;
00331 }
00332
00333 DOMImplementationImpl *DocumentImpl::implementation() const
00334 {
00335 return m_implementation;
00336 }
00337
00338 ElementImpl *DocumentImpl::documentElement() const
00339 {
00340 NodeImpl *n = firstChild();
00341 while (n && n->nodeType() != Node::ELEMENT_NODE)
00342 n = n->nextSibling();
00343 return static_cast<ElementImpl*>(n);
00344 }
00345
00346 ElementImpl *DocumentImpl::createElement( const DOMString &name )
00347 {
00348 return new XMLElementImpl( document, name.implementation() );
00349 }
00350
00351 DocumentFragmentImpl *DocumentImpl::createDocumentFragment( )
00352 {
00353 return new DocumentFragmentImpl( docPtr() );
00354 }
00355
00356 CommentImpl *DocumentImpl::createComment ( DOMStringImpl* data )
00357 {
00358 return new CommentImpl( docPtr(), data );
00359 }
00360
00361 CDATASectionImpl *DocumentImpl::createCDATASection ( DOMStringImpl* data )
00362 {
00363 return new CDATASectionImpl( docPtr(), data );
00364 }
00365
00366 ProcessingInstructionImpl *DocumentImpl::createProcessingInstruction ( const DOMString &target, DOMStringImpl* data )
00367 {
00368 return new ProcessingInstructionImpl( docPtr(),target,data);
00369 }
00370
00371 Attr DocumentImpl::createAttribute( NodeImpl::Id id )
00372 {
00373 return new AttrImpl(0, docPtr(), new AttributeImpl(id, DOMString("").implementation()));
00374 }
00375
00376 EntityReferenceImpl *DocumentImpl::createEntityReference ( const DOMString &name )
00377 {
00378 return new EntityReferenceImpl(docPtr(), name.implementation());
00379 }
00380
00381 NodeImpl *DocumentImpl::importNode(NodeImpl *importedNode, bool deep, int &exceptioncode)
00382 {
00383 NodeImpl *result = 0;
00384
00385 if(importedNode->nodeType() == Node::ELEMENT_NODE)
00386 {
00387 ElementImpl *tempElementImpl = createElementNS(getDocument()->namespaceURI(id()), importedNode->nodeName());
00388 result = tempElementImpl;
00389
00390 if(static_cast<ElementImpl *>(importedNode)->attributes(true) && static_cast<ElementImpl *>(importedNode)->attributes(true)->length())
00391 {
00392 NamedNodeMapImpl *attr = static_cast<ElementImpl *>(importedNode)->attributes();
00393
00394 for(unsigned int i = 0; i < attr->length(); i++)
00395 {
00396 DOM::DOMString qualifiedName = attr->item(i)->nodeName();
00397 DOM::DOMString value = attr->item(i)->nodeValue();
00398
00399 int colonpos = qualifiedName.find(':');
00400 DOMString localName = qualifiedName;
00401 if(colonpos >= 0)
00402 {
00403 localName.remove(0, colonpos + 1);
00404
00405 }
00406
00407 NodeImpl::Id nodeId = getDocument()->attrId(getDocument()->namespaceURI(id()), localName.implementation(), false );
00408 tempElementImpl->setAttribute(nodeId, value.implementation(), exceptioncode);
00409
00410 if(exceptioncode != 0)
00411 break;
00412 }
00413 }
00414 }
00415 else if(importedNode->nodeType() == Node::TEXT_NODE)
00416 {
00417 result = createTextNode(static_cast<TextImpl*>(importedNode)->string());
00418 deep = false;
00419 }
00420 else if(importedNode->nodeType() == Node::CDATA_SECTION_NODE)
00421 {
00422 result = createCDATASection(static_cast<CDATASectionImpl*>(importedNode)->string());
00423 deep = false;
00424 }
00425 else if(importedNode->nodeType() == Node::ENTITY_REFERENCE_NODE)
00426 result = createEntityReference(importedNode->nodeName());
00427 else if(importedNode->nodeType() == Node::PROCESSING_INSTRUCTION_NODE)
00428 {
00429 result = createProcessingInstruction(importedNode->nodeName(), importedNode->nodeValue().implementation());
00430 deep = false;
00431 }
00432 else if(importedNode->nodeType() == Node::COMMENT_NODE)
00433 {
00434 result = createComment(static_cast<CommentImpl*>(importedNode)->string());
00435 deep = false;
00436 }
00437 else
00438 exceptioncode = DOMException::NOT_SUPPORTED_ERR;
00439
00440 if(deep)
00441 {
00442 for(Node n = importedNode->firstChild(); !n.isNull(); n = n.nextSibling())
00443 result->appendChild(importNode(n.handle(), true, exceptioncode), exceptioncode);
00444 }
00445
00446 return result;
00447 }
00448
00449 ElementImpl *DocumentImpl::createElementNS( const DOMString &_namespaceURI, const DOMString &_qualifiedName )
00450 {
00451 ElementImpl *e = 0;
00452 QString qName = _qualifiedName.string();
00453 int colonPos = qName.find(':',0);
00454
00455 if ((_namespaceURI.isNull() && colonPos < 0) ||
00456 _namespaceURI == XHTML_NAMESPACE) {
00457
00458
00459 e = createHTMLElement(qName.mid(colonPos+1));
00460 int exceptioncode = 0;
00461 if (colonPos >= 0)
00462 e->setPrefix(qName.left(colonPos), exceptioncode);
00463 }
00464 if (!e)
00465 e = new XMLElementImpl( document, _qualifiedName.implementation(), _namespaceURI.implementation() );
00466
00467 return e;
00468 }
00469
00470 ElementImpl *DocumentImpl::getElementById( const DOMString &elementId ) const
00471 {
00472 QPtrStack<NodeImpl> nodeStack;
00473 NodeImpl *current = _first;
00474
00475 while(1)
00476 {
00477 if(!current)
00478 {
00479 if(nodeStack.isEmpty()) break;
00480 current = nodeStack.pop();
00481 current = current->nextSibling();
00482 }
00483 else
00484 {
00485 if(current->isElementNode())
00486 {
00487 ElementImpl *e = static_cast<ElementImpl *>(current);
00488 if(e->getAttribute(ATTR_ID) == elementId)
00489 return e;
00490 }
00491
00492 NodeImpl *child = current->firstChild();
00493 if(child)
00494 {
00495 nodeStack.push(current);
00496 current = child;
00497 }
00498 else
00499 {
00500 current = current->nextSibling();
00501 }
00502 }
00503 }
00504
00505
00506 return 0;
00507 }
00508
00509 void DocumentImpl::setTitle(DOMString _title)
00510 {
00511 m_title = _title;
00512
00513 QString titleStr = m_title.string();
00514 for (unsigned int i = 0; i < titleStr.length(); ++i)
00515 if (titleStr[i] < ' ')
00516 titleStr[i] = ' ';
00517 titleStr = titleStr.stripWhiteSpace();
00518 titleStr.compose();
00519 if ( !view()->part()->parentPart() ) {
00520 if (titleStr.isNull() || titleStr.isEmpty()) {
00521
00522 KURL url = m_url;
00523 url.setRef(QString::null);
00524 url.setQuery(QString::null);
00525 titleStr = url.url();
00526 }
00527
00528 emit view()->part()->setWindowCaption( KStringHandler::csqueeze( titleStr, 128 ) );
00529 }
00530 }
00531
00532 DOMString DocumentImpl::nodeName() const
00533 {
00534 return "#document";
00535 }
00536
00537 unsigned short DocumentImpl::nodeType() const
00538 {
00539 return Node::DOCUMENT_NODE;
00540 }
00541
00542 ElementImpl *DocumentImpl::createHTMLElement( const DOMString &name )
00543 {
00544 uint id = khtml::getTagID( name.string().lower().latin1(), name.string().length() );
00545
00546 ElementImpl *n = 0;
00547 switch(id)
00548 {
00549 case ID_HTML:
00550 n = new HTMLHtmlElementImpl(docPtr());
00551 break;
00552 case ID_HEAD:
00553 n = new HTMLHeadElementImpl(docPtr());
00554 break;
00555 case ID_BODY:
00556 n = new HTMLBodyElementImpl(docPtr());
00557 break;
00558
00559
00560 case ID_BASE:
00561 n = new HTMLBaseElementImpl(docPtr());
00562 break;
00563 case ID_LINK:
00564 n = new HTMLLinkElementImpl(docPtr());
00565 break;
00566 case ID_META:
00567 n = new HTMLMetaElementImpl(docPtr());
00568 break;
00569 case ID_STYLE:
00570 n = new HTMLStyleElementImpl(docPtr());
00571 break;
00572 case ID_TITLE:
00573 n = new HTMLTitleElementImpl(docPtr());
00574 break;
00575
00576
00577 case ID_FRAME:
00578 n = new HTMLFrameElementImpl(docPtr());
00579 break;
00580 case ID_FRAMESET:
00581 n = new HTMLFrameSetElementImpl(docPtr());
00582 break;
00583 case ID_IFRAME:
00584 n = new HTMLIFrameElementImpl(docPtr());
00585 break;
00586
00587
00588
00589 case ID_FORM:
00590 n = new HTMLFormElementImpl(docPtr(), false);
00591 break;
00592 case ID_BUTTON:
00593 n = new HTMLButtonElementImpl(docPtr());
00594 break;
00595 case ID_FIELDSET:
00596 n = new HTMLFieldSetElementImpl(docPtr());
00597 break;
00598 case ID_INPUT:
00599 n = new HTMLInputElementImpl(docPtr());
00600 break;
00601 case ID_ISINDEX:
00602 n = new HTMLIsIndexElementImpl(docPtr());
00603 break;
00604 case ID_LABEL:
00605 n = new HTMLLabelElementImpl(docPtr());
00606 break;
00607 case ID_LEGEND:
00608 n = new HTMLLegendElementImpl(docPtr());
00609 break;
00610 case ID_OPTGROUP:
00611 n = new HTMLOptGroupElementImpl(docPtr());
00612 break;
00613 case ID_OPTION:
00614 n = new HTMLOptionElementImpl(docPtr());
00615 break;
00616 case ID_SELECT:
00617 n = new HTMLSelectElementImpl(docPtr());
00618 break;
00619 case ID_TEXTAREA:
00620 n = new HTMLTextAreaElementImpl(docPtr());
00621 break;
00622
00623
00624 case ID_DL:
00625 n = new HTMLDListElementImpl(docPtr());
00626 break;
00627 case ID_DD:
00628 n = new HTMLGenericElementImpl(docPtr(), id);
00629 break;
00630 case ID_DT:
00631 n = new HTMLGenericElementImpl(docPtr(), id);
00632 break;
00633 case ID_UL:
00634 n = new HTMLUListElementImpl(docPtr());
00635 break;
00636 case ID_OL:
00637 n = new HTMLOListElementImpl(docPtr());
00638 break;
00639 case ID_DIR:
00640 n = new HTMLDirectoryElementImpl(docPtr());
00641 break;
00642 case ID_MENU:
00643 n = new HTMLMenuElementImpl(docPtr());
00644 break;
00645 case ID_LI:
00646 n = new HTMLLIElementImpl(docPtr());
00647 break;
00648
00649
00650 case ID_DIV:
00651 case ID_P:
00652 n = new HTMLDivElementImpl(docPtr(), id);
00653 break;
00654 case ID_BLOCKQUOTE:
00655 case ID_H1:
00656 case ID_H2:
00657 case ID_H3:
00658 case ID_H4:
00659 case ID_H5:
00660 case ID_H6:
00661 n = new HTMLGenericElementImpl(docPtr(), id);
00662 break;
00663 case ID_HR:
00664 n = new HTMLHRElementImpl(docPtr());
00665 break;
00666 case ID_PRE:
00667 n = new HTMLPreElementImpl(docPtr(), id);
00668 break;
00669
00670
00671 case ID_BASEFONT:
00672 n = new HTMLBaseFontElementImpl(docPtr());
00673 break;
00674 case ID_FONT:
00675 n = new HTMLFontElementImpl(docPtr());
00676 break;
00677
00678
00679 case ID_DEL:
00680 case ID_INS:
00681 n = new HTMLGenericElementImpl(docPtr(), id);
00682 break;
00683
00684
00685 case ID_A:
00686 n = new HTMLAnchorElementImpl(docPtr());
00687 break;
00688
00689
00690 case ID_IMG:
00691 n = new HTMLImageElementImpl(docPtr());
00692 break;
00693 case ID_MAP:
00694 n = new HTMLMapElementImpl(docPtr());
00695
00696 break;
00697 case ID_AREA:
00698 n = new HTMLAreaElementImpl(docPtr());
00699 break;
00700
00701
00702 case ID_APPLET:
00703 n = new HTMLAppletElementImpl(docPtr());
00704 break;
00705 case ID_OBJECT:
00706 n = new HTMLObjectElementImpl(docPtr());
00707 break;
00708 case ID_PARAM:
00709 n = new HTMLParamElementImpl(docPtr());
00710 break;
00711 case ID_SCRIPT:
00712 n = new HTMLScriptElementImpl(docPtr());
00713 break;
00714
00715
00716 case ID_TABLE:
00717 n = new HTMLTableElementImpl(docPtr());
00718 break;
00719 case ID_CAPTION:
00720 n = new HTMLTableCaptionElementImpl(docPtr());
00721 break;
00722 case ID_COLGROUP:
00723 case ID_COL:
00724 n = new HTMLTableColElementImpl(docPtr(), id);
00725 break;
00726 case ID_TR:
00727 n = new HTMLTableRowElementImpl(docPtr());
00728 break;
00729 case ID_TD:
00730 case ID_TH:
00731 n = new HTMLTableCellElementImpl(docPtr(), id);
00732 break;
00733 case ID_THEAD:
00734 case ID_TBODY:
00735 case ID_TFOOT:
00736 n = new HTMLTableSectionElementImpl(docPtr(), id, false);
00737 break;
00738
00739
00740 case ID_BR:
00741 n = new HTMLBRElementImpl(docPtr());
00742 break;
00743 case ID_Q:
00744 n = new HTMLGenericElementImpl(docPtr(), id);
00745 break;
00746
00747
00748
00749
00750 case ID_ADDRESS:
00751 case ID_CENTER:
00752 n = new HTMLGenericElementImpl(docPtr(), id);
00753 break;
00754
00755
00756 case ID_TT:
00757 case ID_U:
00758 case ID_B:
00759 case ID_I:
00760 case ID_S:
00761 case ID_STRIKE:
00762 case ID_BIG:
00763 case ID_SMALL:
00764
00765
00766 case ID_EM:
00767 case ID_STRONG:
00768 case ID_DFN:
00769 case ID_CODE:
00770 case ID_SAMP:
00771 case ID_KBD:
00772 case ID_VAR:
00773 case ID_CITE:
00774 case ID_ABBR:
00775 case ID_ACRONYM:
00776
00777
00778 case ID_SUB:
00779 case ID_SUP:
00780 case ID_SPAN:
00781 case ID_NOBR:
00782 case ID_WBR:
00783 n = new HTMLGenericElementImpl(docPtr(), id);
00784 break;
00785
00786 case ID_BDO:
00787 break;
00788
00789
00790 case ID_TEXT:
00791 kdDebug( 6020 ) << "Use document->createTextNode()" << endl;
00792 break;
00793
00794 default:
00795 break;
00796 }
00797 return n;
00798 }
00799
00800 QString DocumentImpl::nextState()
00801 {
00802 QString state;
00803 if (!m_state.isEmpty())
00804 {
00805 state = m_state.first();
00806 m_state.remove(m_state.begin());
00807 }
00808 return state;
00809 }
00810
00811 QStringList DocumentImpl::docState()
00812 {
00813 QStringList s;
00814 for (QPtrListIterator<NodeImpl> it(m_maintainsState); it.current(); ++it)
00815 s.append(it.current()->state());
00816
00817 return s;
00818 }
00819
00820 RangeImpl *DocumentImpl::createRange()
00821 {
00822 return new RangeImpl( docPtr() );
00823 }
00824
00825 NodeIteratorImpl *DocumentImpl::createNodeIterator(NodeImpl *root, unsigned long whatToShow,
00826 NodeFilter &filter, bool entityReferenceExpansion,
00827 int &exceptioncode)
00828 {
00829 if (!root) {
00830 exceptioncode = DOMException::NOT_SUPPORTED_ERR;
00831 return 0;
00832 }
00833
00834 return new NodeIteratorImpl(root,whatToShow,filter,entityReferenceExpansion);
00835 }
00836
00837 TreeWalkerImpl *DocumentImpl::createTreeWalker(Node , unsigned long , NodeFilter &,
00838 bool )
00839 {
00840
00841 return new TreeWalkerImpl;
00842 }
00843
00844 void DocumentImpl::setDocumentChanged(bool b)
00845 {
00846 if (!changedDocuments)
00847 changedDocuments = s_changedDocumentsDeleter.setObject( new QPtrList<DocumentImpl>() );
00848
00849 if (b && !m_docChanged)
00850 changedDocuments->append(this);
00851 else if (!b && m_docChanged)
00852 changedDocuments->remove(this);
00853 m_docChanged = b;
00854 }
00855
00856 void DocumentImpl::recalcStyle( StyleChange change )
00857 {
00858
00859
00860
00861 if (m_inStyleRecalc)
00862 return;
00863
00864 m_inStyleRecalc = true;
00865
00866 if( !m_render ) goto bail_out;
00867
00868 if ( change == Force ) {
00869 RenderStyle* oldStyle = m_render->style();
00870 if ( oldStyle ) oldStyle->ref();
00871 RenderStyle* _style = new RenderStyle();
00872 _style->setDisplay(BLOCK);
00873 _style->setVisuallyOrdered( visuallyOrdered );
00874
00875
00876 khtml::FontDef fontDef;
00877 QFont f = KGlobalSettings::generalFont();
00878 fontDef.family = f.family();
00879 fontDef.italic = f.italic();
00880 fontDef.weight = f.weight();
00881 if (m_view) {
00882 const KHTMLSettings *settings = m_view->part()->settings();
00883 QString stdfont = settings->stdFontName();
00884 if ( !stdfont.isEmpty() )
00885 fontDef.family = stdfont;
00886
00887 fontDef.size = m_styleSelector->fontSizes()[3];
00888 }
00889
00890
00891 _style->setFontDef(fontDef);
00892 _style->htmlFont().update( paintDeviceMetrics() );
00893 if ( parseMode() != Strict )
00894 _style->setHtmlHacks(true);
00895
00896 StyleChange ch = diff( _style, oldStyle );
00897 if(m_render && ch != NoChange)
00898 m_render->setStyle(_style);
00899 else
00900 delete _style;
00901 if ( change != Force )
00902 change = ch;
00903
00904 if (oldStyle)
00905 oldStyle->deref();
00906 }
00907
00908 NodeImpl *n;
00909 for (n = _first; n; n = n->nextSibling())
00910 if ( change>= Inherit || n->hasChangedChild() || n->changed() )
00911 n->recalcStyle( change );
00912
00913
00914
00915
00916 if ( changed() ) {
00917 renderer()->setLayouted( false );
00918 renderer()->setMinMaxKnown( false );
00919 }
00920
00921 bail_out:
00922 setChanged( false );
00923 setHasChangedChild( false );
00924 setDocumentChanged( false );
00925
00926 m_inStyleRecalc = false;
00927 }
00928
00929 void DocumentImpl::updateRendering()
00930 {
00931 if (!hasChangedChild()) return;
00932
00933
00934
00935
00936
00937 StyleChange change = NoChange;
00938 #if 0
00939 if ( m_styleSelectorDirty ) {
00940 recalcStyleSelector();
00941 change = Force;
00942 }
00943 #endif
00944 recalcStyle( change );
00945
00946
00947 }
00948
00949 void DocumentImpl::updateDocumentsRendering()
00950 {
00951 if (!changedDocuments)
00952 return;
00953
00954 while ( !changedDocuments->isEmpty() ) {
00955 changedDocuments->first();
00956 DocumentImpl* it = changedDocuments->take();
00957 if (it->isDocumentChanged())
00958 it->updateRendering();
00959 }
00960 }
00961
00962 void DocumentImpl::attach()
00963 {
00964 assert(!attached());
00965
00966 if ( m_view )
00967 setPaintDevice( m_view );
00968
00969
00970 assert(!m_styleSelector);
00971 m_styleSelector = new CSSStyleSelector( this, m_usersheet, m_styleSheets, m_url,
00972 pMode == Strict );
00973 m_render = new RenderRoot(this, m_view);
00974 m_styleSelector->computeFontSizes(paintDeviceMetrics(), m_view ? m_view->part()->zoomFactor() : 100);
00975 recalcStyle( Force );
00976
00977 RenderObject* render = m_render;
00978 m_render = 0;
00979
00980 NodeBaseImpl::attach();
00981 m_render = render;
00982 }
00983
00984 void DocumentImpl::detach()
00985 {
00986 RenderObject* render = m_render;
00987
00988
00989 m_render = 0;
00990
00991 delete m_tokenizer;
00992 m_tokenizer = 0;
00993
00994 NodeBaseImpl::detach();
00995
00996 if ( render )
00997 render->detach();
00998
00999 m_view = 0;
01000 }
01001
01002 void DocumentImpl::setVisuallyOrdered()
01003 {
01004 visuallyOrdered = true;
01005 if (m_render)
01006 m_render->style()->setVisuallyOrdered(true);
01007 }
01008
01009 void DocumentImpl::setSelection(NodeImpl* s, int sp, NodeImpl* e, int ep)
01010 {
01011 if ( m_render )
01012 static_cast<RenderRoot*>(m_render)->setSelection(s->renderer(),sp,e->renderer(),ep);
01013 }
01014
01015 void DocumentImpl::clearSelection()
01016 {
01017 if ( m_render )
01018 static_cast<RenderRoot*>(m_render)->clearSelection();
01019 }
01020
01021 Tokenizer *DocumentImpl::createTokenizer()
01022 {
01023 return new XMLTokenizer(docPtr(),m_view);
01024 }
01025
01026 void DocumentImpl::setPaintDevice( QPaintDevice *dev )
01027 {
01028 m_paintDevice = dev;
01029 delete m_paintDeviceMetrics;
01030 m_paintDeviceMetrics = new QPaintDeviceMetrics( dev );
01031 }
01032
01033 void DocumentImpl::open( )
01034 {
01035 if (parsing()) return;
01036
01037 if (m_tokenizer)
01038 close();
01039
01040 delete m_tokenizer;
01041 m_tokenizer = 0;
01042
01043 removeChildren();
01044 QPtrListIterator<RegisteredEventListener> it(m_windowEventListeners);
01045 for (; it.current();)
01046 m_windowEventListeners.removeRef(it.current());
01047
01048 m_tokenizer = createTokenizer();
01049 m_decoderMibEnum = 0;
01050 connect(m_tokenizer,SIGNAL(finishedParsing()),this,SIGNAL(finishedParsing()));
01051 m_tokenizer->begin();
01052
01053 if (m_view && m_view->part()->jScript())
01054 m_view->part()->jScript()->setSourceFile(m_url,"");
01055 }
01056
01057 void DocumentImpl::close( )
01058 {
01059 if (parsing() || !m_tokenizer) return;
01060
01061 if ( m_render )
01062 m_render->close();
01063
01064 delete m_tokenizer;
01065 m_tokenizer = 0;
01066
01067 if (m_view)
01068 m_view->part()->checkEmitLoadEvent();
01069 }
01070
01071 void DocumentImpl::write( const DOMString &text )
01072 {
01073 write(text.string());
01074 }
01075
01076 void DocumentImpl::write( const QString &text )
01077 {
01078 if (!m_tokenizer) {
01079 open();
01080 write(QString::fromLatin1("<html><title></title><body>"));
01081 }
01082 m_tokenizer->write(text, false);
01083
01084 if (m_view && m_view->part()->jScript())
01085 m_view->part()->jScript()->appendSourceFile(m_url,text);
01086 }
01087
01088 void DocumentImpl::writeln( const DOMString &text )
01089 {
01090 write(text);
01091 write(DOMString("\n"));
01092 }
01093
01094 void DocumentImpl::finishParsing ( )
01095 {
01096 if(m_tokenizer)
01097 m_tokenizer->finish();
01098 }
01099
01100 void DocumentImpl::setStyleSheet(const DOM::DOMString &url, const DOM::DOMString &sheet)
01101 {
01102
01103 m_sheet = new CSSStyleSheetImpl(this, url);
01104 m_sheet->ref();
01105 m_sheet->parseString(sheet);
01106 m_loadingSheet = false;
01107
01108 updateStyleSelector();
01109 }
01110
01111 void DocumentImpl::setUserStyleSheet( const QString& sheet )
01112 {
01113 if ( m_usersheet != sheet ) {
01114 m_usersheet = sheet;
01115 updateStyleSelector();
01116 }
01117 }
01118
01119 CSSStyleSheetImpl* DocumentImpl::elementSheet()
01120 {
01121 if (!m_elemSheet) {
01122 m_elemSheet = new CSSStyleSheetImpl(this, baseURL() );
01123 m_elemSheet->ref();
01124 }
01125 return m_elemSheet;
01126 }
01127
01128 void DocumentImpl::determineParseMode( const QString & )
01129 {
01130
01131 pMode = Strict;
01132 kdDebug(6020) << " using strict parseMode" << endl;
01133 }
01134
01135
01136
01137 NodeImpl *DocumentImpl::findElement( Id id )
01138 {
01139 QPtrStack<NodeImpl> nodeStack;
01140 NodeImpl *current = _first;
01141
01142 while(1)
01143 {
01144 if(!current)
01145 {
01146 if(nodeStack.isEmpty()) break;
01147 current = nodeStack.pop();
01148 current = current->nextSibling();
01149 }
01150 else
01151 {
01152 if(current->id() == id)
01153 return current;
01154
01155 NodeImpl *child = current->firstChild();
01156 if(child)
01157 {
01158 nodeStack.push(current);
01159 current = child;
01160 }
01161 else
01162 {
01163 current = current->nextSibling();
01164 }
01165 }
01166 }
01167
01168 return 0;
01169 }
01170
01171 NodeImpl *DocumentImpl::nextFocusNode(NodeImpl *fromNode)
01172 {
01173 unsigned short fromTabIndex;
01174
01175 if (!fromNode) {
01176
01177 NodeImpl *n;
01178
01179 int lowestTabIndex = 65535;
01180 for (n = this; n != 0; n = n->traverseNextNode()) {
01181 if (n->isSelectable()) {
01182 if ((n->tabIndex() > 0) && (n->tabIndex() < lowestTabIndex))
01183 lowestTabIndex = n->tabIndex();
01184 }
01185 }
01186
01187 if (lowestTabIndex == 65535)
01188 lowestTabIndex = 0;
01189
01190
01191 for (n = this; n != 0; n = n->traverseNextNode()) {
01192 if (n->isSelectable() && (n->tabIndex() == lowestTabIndex))
01193 return n;
01194 }
01195
01196 return 0;
01197 }
01198 else {
01199 fromTabIndex = fromNode->tabIndex();
01200 }
01201
01202 if (fromTabIndex == 0) {
01203
01204 NodeImpl *n = fromNode->traverseNextNode();
01205 while (n && !(n->isSelectable() && n->tabIndex() == 0))
01206 n = n->traverseNextNode();
01207 return n;
01208 }
01209 else {
01210
01211
01212
01213
01214 unsigned short lowestSuitableTabIndex = 65535;
01215 NodeImpl *n;
01216
01217 bool reachedFromNode = false;
01218 for (n = this; n != 0; n = n->traverseNextNode()) {
01219 if (n->isSelectable() &&
01220 ((reachedFromNode && (n->tabIndex() >= fromTabIndex)) ||
01221 (!reachedFromNode && (n->tabIndex() > fromTabIndex))) &&
01222 (n->tabIndex() < lowestSuitableTabIndex) &&
01223 (n != fromNode)) {
01224
01225
01226
01227 lowestSuitableTabIndex = n->tabIndex();
01228 }
01229
01230 if (n == fromNode)
01231 reachedFromNode = true;
01232 }
01233
01234 if (lowestSuitableTabIndex == 65535) {
01235
01236 NodeImpl *n = this;
01237 while (n && !(n->isSelectable() && n->tabIndex() == 0))
01238 n = n->traverseNextNode();
01239 return n;
01240 }
01241
01242
01243 for (n = fromNode->traverseNextNode(); n != 0; n = n->traverseNextNode()) {
01244 if (n->isSelectable() && (n->tabIndex() == lowestSuitableTabIndex))
01245 return n;
01246 }
01247
01248
01249 for (n = this; n != fromNode; n = n->traverseNextNode()) {
01250 if (n->isSelectable() && (n->tabIndex() == lowestSuitableTabIndex))
01251 return n;
01252 }
01253
01254 assert(false);
01255 return 0;
01256 }
01257 }
01258
01259 NodeImpl *DocumentImpl::previousFocusNode(NodeImpl *fromNode)
01260 {
01261 NodeImpl *lastNode = this;
01262 while (lastNode->lastChild())
01263 lastNode = lastNode->lastChild();
01264
01265 if (!fromNode) {
01266
01267 NodeImpl *n;
01268
01269 int highestTabIndex = 0;
01270 for (n = lastNode; n != 0; n = n->traversePreviousNode()) {
01271 if (n->isSelectable()) {
01272 if (n->tabIndex() == 0)
01273 return n;
01274 else if (n->tabIndex() > highestTabIndex)
01275 highestTabIndex = n->tabIndex();
01276 }
01277 }
01278
01279
01280 for (n = lastNode; n != 0; n = n->traversePreviousNode()) {
01281 if (n->isSelectable() && (n->tabIndex() == highestTabIndex))
01282 return n;
01283 }
01284
01285 return 0;
01286 }
01287 else {
01288 unsigned short fromTabIndex = fromNode->tabIndex();
01289
01290 if (fromTabIndex == 0) {
01291
01292 NodeImpl *n = fromNode->traversePreviousNode();
01293 while (n && !(n->isSelectable() && n->tabIndex() == 0))
01294 n = n->traversePreviousNode();
01295 if (n)
01296 return n;
01297
01298
01299 int highestTabIndex = 0;
01300 for (n = this; n != 0; n = n->traverseNextNode()) {
01301 if (n->isSelectable() && (n->tabIndex() > highestTabIndex))
01302 highestTabIndex = n->tabIndex();
01303 }
01304
01305 if (highestTabIndex == 0)
01306 return 0;
01307
01308 for (n = lastNode; n != 0; n = n->traversePreviousNode()) {
01309 if (n->isSelectable() && (n->tabIndex() == highestTabIndex))
01310 return n;
01311 }
01312
01313 assert(false);
01314 return 0;
01315 }
01316 else {
01317
01318
01319
01320
01321 unsigned short highestSuitableTabIndex = 0;
01322 NodeImpl *n;
01323
01324 bool reachedFromNode = false;
01325 for (n = this; n != 0; n = n->traverseNextNode()) {
01326 if (n->isSelectable() &&
01327 ((!reachedFromNode && (n->tabIndex() <= fromTabIndex)) ||
01328 (reachedFromNode && (n->tabIndex() < fromTabIndex))) &&
01329 (n->tabIndex() > highestSuitableTabIndex) &&
01330 (n != fromNode)) {
01331
01332
01333
01334 highestSuitableTabIndex = n->tabIndex();
01335 }
01336
01337 if (n == fromNode)
01338 reachedFromNode = true;
01339 }
01340
01341 if (highestSuitableTabIndex == 0) {
01342
01343
01344 return 0;
01345 }
01346
01347
01348 for (n = fromNode->traversePreviousNode(); n != 0; n = n->traversePreviousNode()) {
01349 if (n->isSelectable() && (n->tabIndex() == highestSuitableTabIndex))
01350 return n;
01351 }
01352
01353 for (n = lastNode; n != fromNode; n = n->traversePreviousNode()) {
01354 if (n->isSelectable() && (n->tabIndex() == highestSuitableTabIndex))
01355 return n;
01356 }
01357
01358 assert(false);
01359 return 0;
01360 }
01361 }
01362 }
01363
01364 int DocumentImpl::nodeAbsIndex(NodeImpl *node)
01365 {
01366 assert(node->getDocument() == this);
01367
01368 int absIndex = 0;
01369 for (NodeImpl *n = node; n && n != this; n = n->traversePreviousNode())
01370 absIndex++;
01371 return absIndex;
01372 }
01373
01374 NodeImpl *DocumentImpl::nodeWithAbsIndex(int absIndex)
01375 {
01376 NodeImpl *n = this;
01377 for (int i = 0; n && (i < absIndex); i++) {
01378 n = n->traverseNextNode();
01379 }
01380 return n;
01381 }
01382
01383 void DocumentImpl::processHttpEquiv(const DOMString &equiv, const DOMString &content)
01384 {
01385 assert(!equiv.isNull() && !content.isNull());
01386
01387 KHTMLView *v = getDocument()->view();
01388
01389 if(strcasecmp(equiv, "refresh") == 0 && v->part()->metaRefreshEnabled())
01390 {
01391
01392 QString str = content.string().stripWhiteSpace();
01393 int pos = str.find(QRegExp("[;,]"));
01394 if ( pos == -1 )
01395 pos = str.find(QRegExp("[ \t]"));
01396
01397 if (pos == -1)
01398 {
01399 bool ok = false;
01400 int delay = 0;
01401 delay = content.implementation()->toInt(&ok);
01402 if(ok) v->part()->scheduleRedirection(delay, v->part()->url().url() );
01403 } else {
01404 int delay = 0;
01405 int fract = pos;
01406 bool ok = false;
01407 if ( (fract = str.find('.') ) < 0 || fract > pos)
01408 fract = pos;
01409 DOMStringImpl* s = content.implementation()->substring(0, fract);
01410 delay = s->toInt(&ok);
01411 delete s;
01412
01413 pos++;
01414 while(pos < (int)str.length() && str[pos].isSpace()) pos++;
01415 str = str.mid(pos);
01416 if(str.find("url", 0, false ) == 0) str = str.mid(3);
01417 str = str.stripWhiteSpace();
01418 if ( str.length() && str[0] == '=' ) str = str.mid( 1 ).stripWhiteSpace();
01419 while(str.length() &&
01420 (str[str.length()-1] == ';' || str[str.length()-1] == ','))
01421 str.setLength(str.length()-1);
01422 str = parseURL( DOMString(str) ).string();
01423 if ( ok || !fract)
01424 v->part()->scheduleRedirection(delay, getDocument()->completeURL( str ));
01425 }
01426 }
01427 else if(strcasecmp(equiv, "expires") == 0)
01428 {
01429 bool relative = false;
01430 QString str = content.string().stripWhiteSpace();
01431 time_t expire_date = KRFCDate::parseDate(str);
01432 if (!expire_date)
01433 {
01434 expire_date = str.toULong();
01435 relative = true;
01436 }
01437 if (!expire_date)
01438 expire_date = 1;
01439 if (m_docLoader)
01440 m_docLoader->setExpireDate(expire_date, relative);
01441 }
01442 else if(strcasecmp(equiv, "pragma") == 0 || strcasecmp(equiv, "cache-control") == 0)
01443 {
01444 QString str = content.string().lower().stripWhiteSpace();
01445 KURL url = v->part()->url();
01446 if ((str == "no-cache") && url.protocol().startsWith("http"))
01447 {
01448 KIO::http_update_cache(url, true, 0);
01449 }
01450 }
01451 else if( (strcasecmp(equiv, "set-cookie") == 0))
01452 {
01453
01454 HTMLDocumentImpl *d = static_cast<HTMLDocumentImpl *>(this);
01455 d->setCookie(content);
01456 }
01457 }
01458
01459 bool DocumentImpl::prepareMouseEvent( bool readonly, int _x, int _y, MouseEvent *ev )
01460 {
01461 if ( m_render ) {
01462 assert(m_render->isRoot());
01463 RenderObject::NodeInfo renderInfo(readonly, ev->type == MousePress);
01464 bool isInside = m_render->nodeAtPoint(renderInfo, _x, _y, 0, 0);
01465 ev->innerNode = renderInfo.innerNode();
01466
01467 if (renderInfo.URLElement()) {
01468 assert(renderInfo.URLElement()->isElementNode());
01469 ElementImpl* e = static_cast<ElementImpl*>(renderInfo.URLElement());
01470 DOMString href = khtml::parseURL(e->getAttribute(ATTR_HREF));
01471 DOMString target = e->getAttribute(ATTR_TARGET);
01472
01473 if (!target.isNull() && !href.isNull()) {
01474 ev->target = target;
01475 ev->url = href;
01476 }
01477 else
01478 ev->url = href;
01479
01480 }
01481
01482 if (!readonly)
01483 updateRendering();
01484
01485 return isInside;
01486 }
01487
01488
01489 return false;
01490 }
01491
01492
01493 bool DocumentImpl::childAllowed( NodeImpl *newChild )
01494 {
01495
01496 if (newChild->nodeType() == Node::ELEMENT_NODE) {
01497 NodeImpl *c;
01498 for (c = firstChild(); c; c = c->nextSibling()) {
01499 if (c->nodeType() == Node::ELEMENT_NODE)
01500 return false;
01501 }
01502 }
01503
01504
01505 if (newChild->nodeType() == Node::DOCUMENT_TYPE_NODE) {
01506 NodeImpl *c;
01507 for (c = firstChild(); c; c = c->nextSibling()) {
01508 if (c->nodeType() == Node::DOCUMENT_TYPE_NODE)
01509 return false;
01510 }
01511 }
01512
01513 return childTypeAllowed(newChild->nodeType());
01514 }
01515
01516 bool DocumentImpl::childTypeAllowed( unsigned short type )
01517 {
01518 switch (type) {
01519 case Node::ELEMENT_NODE:
01520 case Node::PROCESSING_INSTRUCTION_NODE:
01521 case Node::COMMENT_NODE:
01522 case Node::DOCUMENT_TYPE_NODE:
01523 return true;
01524 break;
01525 default:
01526 return false;
01527 }
01528 }
01529
01530 NodeImpl *DocumentImpl::cloneNode ( bool )
01531 {
01532
01533
01534 return 0;
01535 }
01536
01537 NodeImpl::Id DocumentImpl::attrId(DOMStringImpl* _namespaceURI, DOMStringImpl *_name, bool readonly)
01538 {
01539
01540
01541
01542
01543 NodeImpl::Id id = 0;
01544
01545
01546 QConstString n(_name->s, _name->l);
01547 if (!_namespaceURI || !strcasecmp(_namespaceURI, XHTML_NAMESPACE)) {
01548
01549
01550 if ( htmlMode() == XHtml && (id = khtml::getAttrID(n.string().ascii(), _name->l)) )
01551 return id;
01552
01553 if ( htmlMode() != XHtml && (id = khtml::getAttrID(n.string().lower().ascii(), _name->l )) )
01554 return id;
01555
01556
01557 }
01558
01559
01560 if (_namespaceURI) {
01561 DOMString nsU(_namespaceURI);
01562 bool found = false;
01563
01564 for (unsigned short ns = 0; ns < m_namespaceURICount; ++ns)
01565 if (nsU == DOMString(m_namespaceURIs[ns])) {
01566 id |= ns << 16;
01567 found = true;
01568 break;
01569 }
01570
01571 if (!found && !readonly) {
01572
01573 if (m_namespaceURICount >= m_namespaceURIAlloc) {
01574 m_namespaceURIAlloc += 32;
01575 DOMStringImpl **newURIs = new DOMStringImpl* [m_namespaceURIAlloc];
01576 for (unsigned short i = 0; i < m_namespaceURICount; i++)
01577 newURIs[i] = m_namespaceURIs[i];
01578 delete [] m_namespaceURIs;
01579 m_namespaceURIs = newURIs;
01580 }
01581 m_namespaceURIs[m_namespaceURICount++] = _namespaceURI;
01582 _namespaceURI->ref();
01583 id |= m_namespaceURICount << 16;
01584 }
01585 }
01586
01587
01588
01589 DOMString nme(n.string());
01590
01591 if (htmlMode() != XHtml) nme = nme.upper();
01592 for (id = 0; id < m_attrNameCount; id++)
01593 if (DOMString(m_attrNames[id]) == nme)
01594 return ATTR_LAST_ATTR+id;
01595
01596
01597 if (readonly) return 0;
01598
01599
01600
01601 if (m_attrNameCount+1 > m_attrNameAlloc) {
01602 m_attrNameAlloc += 100;
01603 DOMStringImpl **newNames = new DOMStringImpl* [m_attrNameAlloc];
01604 if (m_attrNames) {
01605 unsigned short i;
01606 for (i = 0; i < m_attrNameCount; i++)
01607 newNames[i] = m_attrNames[i];
01608 delete [] m_attrNames;
01609 }
01610 m_attrNames = newNames;
01611 }
01612
01613 id = m_attrNameCount++;
01614 m_attrNames[id] = nme.implementation();
01615 m_attrNames[id]->ref();
01616
01617 return ATTR_LAST_ATTR+id;
01618 }
01619
01620 DOMString DocumentImpl::attrName(NodeImpl::Id _id) const
01621 {
01622 if (_id >= ATTR_LAST_ATTR)
01623 return m_attrNames[_id-ATTR_LAST_ATTR];
01624 else {
01625
01626 if (getDocument()->htmlMode() == DocumentImpl::XHtml)
01627 return getAttrName(_id).lower();
01628 else
01629 return getAttrName(_id);
01630 }
01631 }
01632
01633 NodeImpl::Id DocumentImpl::tagId(DOMStringImpl* _namespaceURI, DOMStringImpl *_name, bool readonly)
01634 {
01635 if (!_name || !_name->l) return 0;
01636
01637
01638 NodeImpl::Id id = 0;
01639
01640
01641 QConstString n(_name->s, _name->l);
01642 if (!_namespaceURI || !strcasecmp(_namespaceURI, XHTML_NAMESPACE)) {
01643
01644
01645 if ( htmlMode() == XHtml && (id = khtml::getTagID(n.string().ascii(), _name->l)) )
01646 return id;
01647
01648 if ( htmlMode() != XHtml && (id = khtml::getTagID(n.string().lower().ascii(), _name->l )) )
01649 return id;
01650
01651
01652 }
01653
01654
01655 if (_namespaceURI) {
01656 DOMString nsU(_namespaceURI);
01657 bool found = false;
01658
01659 for (unsigned short ns = 0; ns < m_namespaceURICount; ++ns)
01660 if (nsU == DOMString(m_namespaceURIs[ns])) {
01661 id |= ns << 16;
01662 found = true;
01663 break;
01664 }
01665
01666 if (!found && !readonly) {
01667
01668 if (m_namespaceURICount >= m_namespaceURIAlloc) {
01669 m_namespaceURIAlloc += 32;
01670 DOMStringImpl **newURIs = new DOMStringImpl* [m_namespaceURIAlloc];
01671 for (unsigned short i = 0; i < m_namespaceURICount; i++)
01672 newURIs[i] = m_namespaceURIs[i];
01673 delete [] m_namespaceURIs;
01674 m_namespaceURIs = newURIs;
01675 }
01676 m_namespaceURIs[m_namespaceURICount++] = _namespaceURI;
01677 _namespaceURI->ref();
01678 id |= m_namespaceURICount << 16;
01679 }
01680 }
01681
01682
01683
01684 DOMString nme(n.string());
01685
01686 if (htmlMode() != XHtml) nme = nme.upper();
01687 for (id = 0; id < m_elementNameCount; id++)
01688 if (DOMString(m_elementNames[id]) == nme)
01689 return ID_LAST_TAG+id;
01690
01691
01692 if (readonly) return 0;
01693
01694
01695 if (m_elementNameCount+1 > m_elementNameAlloc) {
01696 m_elementNameAlloc += 100;
01697 DOMStringImpl **newNames = new DOMStringImpl* [m_elementNameAlloc];
01698
01699 if (m_elementNames) {
01700 unsigned short i;
01701 for (i = 0; i < m_elementNameCount; i++)
01702 newNames[i] = m_elementNames[i];
01703 delete [] m_elementNames;
01704 }
01705 m_elementNames = newNames;
01706 }
01707
01708 id = m_elementNameCount++;
01709 m_elementNames[id] = nme.implementation();
01710 m_elementNames[id]->ref();
01711
01712 return ID_LAST_TAG+id;
01713 }
01714
01715 DOMString DocumentImpl::tagName(NodeImpl::Id _id) const
01716 {
01717 if (_id >= ID_LAST_TAG)
01718 return m_elementNames[_id-ID_LAST_TAG];
01719 else {
01720
01721 if (getDocument()->htmlMode() == DocumentImpl::XHtml)
01722 return getTagName(_id).lower();
01723 else
01724 return getTagName(_id);
01725 }
01726 }
01727
01728
01729 DOMStringImpl* DocumentImpl::namespaceURI(NodeImpl::Id _id) const
01730 {
01731 if (_id < ID_LAST_TAG)
01732 return htmlMode() == XHtml ? m_namespaceURIs[0] : 0;
01733
01734 unsigned short ns = _id >> 16;
01735
01736 if (!ns) return 0;
01737
01738 return m_namespaceURIs[ns-1];
01739 }
01740
01741 StyleSheetListImpl* DocumentImpl::styleSheets()
01742 {
01743 return m_styleSheets;
01744 }
01745
01746 void DocumentImpl::updateStyleSelector()
01747 {
01748 recalcStyleSelector();
01749 recalcStyle(Force);
01750 #if 0
01751
01752 m_styleSelectorDirty = true;
01753 #endif
01754 if ( renderer() ) {
01755 renderer()->setLayouted( false );
01756 renderer()->setMinMaxKnown( false );
01757 }
01758 }
01759
01760
01761 QStringList DocumentImpl::availableStyleSheets() const
01762 {
01763 return m_availableSheets;
01764 }
01765
01766 void DocumentImpl::recalcStyleSelector()
01767 {
01768 if ( !m_render || !attached() ) return;
01769
01770 QPtrList<StyleSheetImpl> oldStyleSheets = m_styleSheets->styleSheets;
01771 m_styleSheets->styleSheets.clear();
01772 m_availableSheets.clear();
01773 NodeImpl *n;
01774 for (n = this; n; n = n->traverseNextNode()) {
01775 StyleSheetImpl *sheet = 0;
01776
01777 if (n->nodeType() == Node::PROCESSING_INSTRUCTION_NODE)
01778 {
01779
01780 ProcessingInstructionImpl* pi = static_cast<ProcessingInstructionImpl*>(n);
01781 sheet = pi->sheet();
01782 if (!sheet && !pi->localHref().isEmpty())
01783 {
01784
01785
01786
01787
01788 ElementImpl* elem = getElementById(pi->localHref());
01789 if (elem) {
01790 DOMString sheetText("");
01791 NodeImpl *c;
01792 for (c = elem->firstChild(); c; c = c->nextSibling()) {
01793 if (c->nodeType() == Node::TEXT_NODE || c->nodeType() == Node::CDATA_SECTION_NODE)
01794 sheetText += c->nodeValue();
01795 }
01796
01797 CSSStyleSheetImpl *cssSheet = new CSSStyleSheetImpl(this);
01798 cssSheet->parseString(sheetText);
01799 pi->setStyleSheet(cssSheet);
01800 sheet = cssSheet;
01801 }
01802 }
01803
01804 }
01805 else if (n->id() == ID_LINK || n->id() == ID_STYLE) {
01806 ElementImpl *e = static_cast<ElementImpl *>(n);
01807 QString title = e->getAttribute( ATTR_TITLE ).string();
01808 if (n->id() == ID_LINK) {
01809
01810 HTMLLinkElementImpl* l = static_cast<HTMLLinkElementImpl*>(n);
01811
01812
01813 if (!(l->sheet() || l->isLoading()))
01814 title = QString::null;
01815 }
01816 else {
01817 HTMLStyleElementImpl* s = static_cast<HTMLStyleElementImpl*>(n);
01818
01819
01820 if (!(s->sheet() || s->isLoading()))
01821 title = QString::null;
01822 }
01823
01824 QString sheetUsed = view()->part()->d->m_sheetUsed;
01825 if ( n->id() == ID_LINK )
01826 sheet = static_cast<HTMLLinkElementImpl*>(n)->sheet();
01827 else
01828
01829 sheet = static_cast<HTMLStyleElementImpl*>(n)->sheet();
01830
01831 if ( !title.isEmpty() ) {
01832 if ( sheetUsed.isEmpty() )
01833 sheetUsed = view()->part()->d->m_sheetUsed = title;
01834 if ( !m_availableSheets.contains( title ) )
01835 m_availableSheets.append( title );
01836
01837 if ( title != sheetUsed )
01838 sheet = 0;
01839 }
01840 }
01841 else if (n->id() == ID_BODY) {
01842
01843
01844 sheet = static_cast<HTMLBodyElementImpl*>(n)->sheet();
01845 }
01846 if (sheet) {
01847 sheet->ref();
01848 m_styleSheets->styleSheets.append(sheet);
01849 }
01850
01851
01852
01853 if (isHTMLDocument() && n->id() == ID_BODY)
01854 break;
01855 }
01856
01857
01858 QPtrListIterator<StyleSheetImpl> it(oldStyleSheets);
01859 for (; it.current(); ++it)
01860 it.current()->deref();
01861
01862
01863 delete m_styleSelector;
01864 QString usersheet = m_usersheet;
01865 if ( m_view && m_view->mediaType() == "print" )
01866 usersheet += m_printSheet;
01867 m_styleSelector = new CSSStyleSelector( this, usersheet, m_styleSheets, m_url,
01868 pMode == Strict );
01869
01870 m_styleSelectorDirty = false;
01871 }
01872
01873 void DocumentImpl::setFocusNode(NodeImpl *newFocusNode)
01874 {
01875
01876 if( !m_render ) return;
01877
01878 if (newFocusNode && (newFocusNode->getDocument() != this))
01879 return;
01880
01881 if (m_focusNode != newFocusNode) {
01882 NodeImpl *oldFocusNode = m_focusNode;
01883
01884 m_focusNode = newFocusNode;
01885
01886 if (oldFocusNode) {
01887 if (oldFocusNode->active())
01888 oldFocusNode->setActive(false);
01889
01890 oldFocusNode->setFocus(false);
01891 oldFocusNode->dispatchHTMLEvent(EventImpl::BLUR_EVENT,false,false);
01892 oldFocusNode->dispatchUIEvent(EventImpl::DOMFOCUSOUT_EVENT);
01893 if ((oldFocusNode == this) && oldFocusNode->hasOneRef()) {
01894 oldFocusNode->deref();
01895 return;
01896 }
01897 else {
01898 oldFocusNode->deref();
01899 }
01900 }
01901
01902 if (m_focusNode) {
01903 m_focusNode->ref();
01904 m_focusNode->dispatchHTMLEvent(EventImpl::FOCUS_EVENT,false,false);
01905 if (m_focusNode != newFocusNode) return;
01906 m_focusNode->dispatchUIEvent(EventImpl::DOMFOCUSIN_EVENT);
01907 if (m_focusNode != newFocusNode) return;
01908 m_focusNode->setFocus();
01909 if (m_focusNode != newFocusNode) return;
01910
01911
01912
01913 if (view()) {
01914 if (!m_focusNode->renderer() || !m_focusNode->renderer()->isWidget())
01915 view()->setFocus();
01916 else if (static_cast<RenderWidget*>(m_focusNode->renderer())->widget())
01917 static_cast<RenderWidget*>(m_focusNode->renderer())->widget()->setFocus();
01918 }
01919 }
01920
01921 updateRendering();
01922 }
01923 }
01924
01925 void DocumentImpl::attachNodeIterator(NodeIteratorImpl *ni)
01926 {
01927 m_nodeIterators.append(ni);
01928 }
01929
01930 void DocumentImpl::detachNodeIterator(NodeIteratorImpl *ni)
01931 {
01932 m_nodeIterators.remove(ni);
01933 }
01934
01935 void DocumentImpl::notifyBeforeNodeRemoval(NodeImpl *n)
01936 {
01937 QPtrListIterator<NodeIteratorImpl> it(m_nodeIterators);
01938 for (; it.current(); ++it)
01939 it.current()->notifyBeforeNodeRemoval(n);
01940 }
01941
01942 bool DocumentImpl::isURLAllowed(const QString& url) const
01943 {
01944 KHTMLView *w = view();
01945
01946 KURL newURL(completeURL(url));
01947 newURL.setRef(QString::null);
01948
01949
01950 if (!w || w->part()->onlyLocalReferences() && newURL.protocol() != "file")
01951 return false;
01952
01953
01954 if ( !kapp || !kapp->authorizeURLAction("redirect", w->part()->url(), newURL) )
01955 return false;
01956
01957
01958
01959 bool foundSelfReference = false;
01960 for (KHTMLPart *part = w->part(); part; part = part->parentPart()) {
01961 KURL partURL = part->url();
01962 partURL.setRef(QString::null);
01963 if (partURL == newURL) {
01964 if (foundSelfReference)
01965 return false;
01966 foundSelfReference = true;
01967 }
01968 }
01969
01970 return true;
01971 }
01972
01973 AbstractViewImpl *DocumentImpl::defaultView() const
01974 {
01975 return m_defaultView;
01976 }
01977
01978 EventImpl *DocumentImpl::createEvent(const DOMString &eventType, int &exceptioncode)
01979 {
01980 if (eventType == "UIEvents")
01981 return new UIEventImpl();
01982 else if (eventType == "MouseEvents")
01983 return new MouseEventImpl();
01984 else if (eventType == "MutationEvents")
01985 return new MutationEventImpl();
01986 else if (eventType == "HTMLEvents")
01987 return new EventImpl();
01988 else {
01989 exceptioncode = DOMException::NOT_SUPPORTED_ERR;
01990 return 0;
01991 }
01992 }
01993
01994 CSSStyleDeclarationImpl *DocumentImpl::getOverrideStyle(ElementImpl *, DOMStringImpl *)
01995 {
01996 return 0;
01997 }
01998
01999 void DocumentImpl::defaultEventHandler(EventImpl *evt)
02000 {
02001
02002 QPtrListIterator<RegisteredEventListener> it(m_windowEventListeners);
02003 Event ev(evt);
02004 for (; it.current(); ++it) {
02005 if (it.current()->id == evt->id()) {
02006 evt->setCurrentTarget(this);
02007 it.current()->listener->handleEvent(ev);
02008 return;
02009 }
02010 }
02011 }
02012
02013 void DocumentImpl::setWindowEventListener(int id, EventListener *listener)
02014 {
02015
02016 if (listener)
02017 listener->ref();
02018 removeWindowEventListener(id);
02019 if (listener) {
02020 RegisteredEventListener *rl = new RegisteredEventListener(static_cast<EventImpl::EventId>(id),listener,false);
02021 m_windowEventListeners.append(rl);
02022 listener->deref();
02023 }
02024 }
02025
02026 EventListener *DocumentImpl::getWindowEventListener(int id)
02027 {
02028 QPtrListIterator<RegisteredEventListener> it(m_windowEventListeners);
02029 for (; it.current(); ++it) {
02030 if (it.current()->id == id) {
02031 return it.current()->listener;
02032 }
02033 }
02034
02035 return 0;
02036 }
02037
02038 void DocumentImpl::removeWindowEventListener(int id)
02039 {
02040 QPtrListIterator<RegisteredEventListener> it(m_windowEventListeners);
02041 for (; it.current(); ++it) {
02042 if (it.current()->id == id) {
02043 m_windowEventListeners.removeRef(it.current());
02044 return;
02045 }
02046 }
02047 }
02048
02049 EventListener *DocumentImpl::createHTMLEventListener(QString code)
02050 {
02051 return view()->part()->createHTMLEventListener(code);
02052 }
02053
02054 void DocumentImpl::setDecoderCodec(const QTextCodec *codec)
02055 {
02056 m_decoderMibEnum = codec->mibEnum();
02057 }
02058
02059
02060
02061 DocumentFragmentImpl::DocumentFragmentImpl(DocumentPtr *doc) : NodeBaseImpl(doc)
02062 {
02063 }
02064
02065 DocumentFragmentImpl::DocumentFragmentImpl(const DocumentFragmentImpl &other)
02066 : NodeBaseImpl(other)
02067 {
02068 }
02069
02070 DOMString DocumentFragmentImpl::nodeName() const
02071 {
02072 return "#document-fragment";
02073 }
02074
02075 unsigned short DocumentFragmentImpl::nodeType() const
02076 {
02077 return Node::DOCUMENT_FRAGMENT_NODE;
02078 }
02079
02080
02081 bool DocumentFragmentImpl::childTypeAllowed( unsigned short type )
02082 {
02083 switch (type) {
02084 case Node::ELEMENT_NODE:
02085 case Node::PROCESSING_INSTRUCTION_NODE:
02086 case Node::COMMENT_NODE:
02087 case Node::TEXT_NODE:
02088 case Node::CDATA_SECTION_NODE:
02089 case Node::ENTITY_REFERENCE_NODE:
02090 return true;
02091 break;
02092 default:
02093 return false;
02094 }
02095 }
02096
02097 NodeImpl *DocumentFragmentImpl::cloneNode ( bool deep )
02098 {
02099 DocumentFragmentImpl *clone = new DocumentFragmentImpl( docPtr() );
02100 if (deep)
02101 cloneChildNodes(clone);
02102 return clone;
02103 }
02104
02105
02106
02107
02108 DocumentTypeImpl::DocumentTypeImpl(DOMImplementationImpl *implementation, DocumentPtr *doc,
02109 const DOMString &qualifiedName, const DOMString &publicId,
02110 const DOMString &systemId)
02111 : NodeImpl(doc), m_implementation(implementation),
02112 m_qualifiedName(qualifiedName), m_publicId(publicId), m_systemId(systemId)
02113 {
02114 m_implementation->ref();
02115
02116 m_entities = 0;
02117 m_notations = 0;
02118
02119
02120
02121 }
02122
02123 DocumentTypeImpl::~DocumentTypeImpl()
02124 {
02125 m_implementation->deref();
02126 if (m_entities)
02127 m_entities->deref();
02128 if (m_notations)
02129 m_notations->deref();
02130 }
02131
02132 void DocumentTypeImpl::copyFrom(const DocumentTypeImpl& other)
02133 {
02134 m_qualifiedName = other.m_qualifiedName;
02135 m_publicId = other.m_publicId;
02136 m_systemId = other.m_systemId;
02137 m_subset = other.m_subset;
02138 }
02139
02140 DOMString DocumentTypeImpl::nodeName() const
02141 {
02142 return name();
02143 }
02144
02145 unsigned short DocumentTypeImpl::nodeType() const
02146 {
02147 return Node::DOCUMENT_TYPE_NODE;
02148 }
02149
02150
02151 bool DocumentTypeImpl::childTypeAllowed( unsigned short )
02152 {
02153 return false;
02154 }
02155
02156 NodeImpl *DocumentTypeImpl::cloneNode ( bool )
02157 {
02158
02159
02160 return 0;
02161 }
02162
02163 #include "dom_docimpl.moc"