00001
00024 #include "html/html_documentimpl.h"
00025 #include "html/html_imageimpl.h"
00026 #include "html/html_headimpl.h"
00027 #include "html/html_baseimpl.h"
00028 #include "html/htmltokenizer.h"
00029 #include "html/html_miscimpl.h"
00030
00031 #include "khtmlview.h"
00032 #include "khtml_part.h"
00033 #include "khtml_settings.h"
00034 #include "misc/htmlattrs.h"
00035 #include "misc/htmlhashes.h"
00036
00037 #include "xml/xml_tokenizer.h"
00038 #include "xml/dom2_eventsimpl.h"
00039
00040 #include "khtml_factory.h"
00041 #include "rendering/render_object.h"
00042
00043 #include <dcopclient.h>
00044 #include <kapplication.h>
00045 #include <kdebug.h>
00046 #include <kurl.h>
00047 #include <kglobal.h>
00048 #include <kcharsets.h>
00049 #include <kglobalsettings.h>
00050
00051 #include "css/cssproperties.h"
00052 #include "css/cssstyleselector.h"
00053 #include "css/css_stylesheetimpl.h"
00054 #include <stdlib.h>
00055 #include <qptrstack.h>
00056
00057 template class QPtrStack<DOM::NodeImpl>;
00058
00059 using namespace DOM;
00060 using namespace khtml;
00061
00062
00063 HTMLDocumentImpl::HTMLDocumentImpl(DOMImplementationImpl *_implementation, KHTMLView *v)
00064 : DocumentImpl(_implementation, v)
00065 {
00066
00067 bodyElement = 0;
00068 htmlElement = 0;
00069
00070
00071
00072
00073
00074
00075
00076 connect( KHTMLFactory::vLinks(), SIGNAL( cleared()),
00077 SLOT( slotHistoryChanged() ));
00078 }
00079
00080 HTMLDocumentImpl::~HTMLDocumentImpl()
00081 {
00082 }
00083
00084 DOMString HTMLDocumentImpl::referrer() const
00085 {
00086 if ( view() )
00087 return view()->part()->pageReferrer();
00088 return DOMString();
00089 }
00090
00091 DOMString HTMLDocumentImpl::domain() const
00092 {
00093 if ( m_domain.isEmpty() )
00094 m_domain = KURL(URL()).host();
00095 return m_domain;
00096 }
00097
00098 void HTMLDocumentImpl::setDomain(const DOMString &newDomain)
00099 {
00100 if ( m_domain.isEmpty() )
00101 m_domain = KURL(URL()).host().lower();
00102
00103 if ( m_domain.isEmpty() )
00104 m_domain = newDomain.lower();
00105
00106
00107
00108 int oldLength = m_domain.length();
00109 int newLength = newDomain.length();
00110 if ( newLength < oldLength )
00111 {
00112 DOMString test = m_domain.copy();
00113 DOMString reference = newDomain.lower();
00114 if ( test[oldLength - newLength - 1] == '.' )
00115 {
00116 test.remove( 0, oldLength - newLength );
00117 if ( test == reference )
00118 m_domain = reference;
00119 }
00120 }
00121 }
00122
00123 DOMString HTMLDocumentImpl::lastModified() const
00124 {
00125 if ( view() )
00126 return view()->part()->lastModified();
00127 return DOMString();
00128 }
00129
00130 DOMString HTMLDocumentImpl::cookie() const
00131 {
00132 long windowId = 0;
00133 KHTMLView *v = view ();
00134
00135 if ( v && v->topLevelWidget() )
00136 windowId = v->topLevelWidget()->winId();
00137
00138 QCString replyType;
00139 QByteArray params, reply;
00140 QDataStream stream(params, IO_WriteOnly);
00141 stream << URL() << windowId;
00142 if (!kapp->dcopClient()->call("kcookiejar", "kcookiejar",
00143 "findDOMCookies(QString, int)", params,
00144 replyType, reply)) {
00145
00146 KApplication::startServiceByDesktopName( "kcookiejar");
00147 if (!kapp->dcopClient()->call("kcookiejar", "kcookiejar",
00148 "findDOMCookies(QString)", params, replyType, reply)) {
00149 kdWarning(6010) << "Can't communicate with cookiejar!" << endl;
00150 return DOMString();
00151 }
00152 }
00153
00154 QDataStream stream2(reply, IO_ReadOnly);
00155 if(replyType != "QString") {
00156 kdError(6010) << "DCOP function findDOMCookies(...) returns "
00157 << replyType << ", expected QString" << endl;
00158 return DOMString();
00159 }
00160
00161 QString result;
00162 stream2 >> result;
00163 return DOMString(result);
00164 }
00165
00166 void HTMLDocumentImpl::setCookie( const DOMString & value )
00167 {
00168 long windowId = 0;
00169 KHTMLView *v = view ();
00170
00171 if ( v && v->topLevelWidget() )
00172 windowId = v->topLevelWidget()->winId();
00173
00174 QByteArray params;
00175 QDataStream stream(params, IO_WriteOnly);
00176 QString fake_header("Set-Cookie: ");
00177 fake_header.append(value.string());
00178 fake_header.append("\n");
00179 stream << URL() << fake_header.utf8() << windowId;
00180 if (!kapp->dcopClient()->send("kcookiejar", "kcookiejar",
00181 "addCookies(QString,QCString,long int)", params))
00182 {
00183
00184 KApplication::startServiceByDesktopName( "kcookiejar");
00185 if (!kapp->dcopClient()->send("kcookiejar", "kcookiejar",
00186 "addCookies(QString,QCString,long int)", params))
00187 kdWarning(6010) << "Can't communicate with cookiejar!" << endl;
00188 }
00189 }
00190
00191
00192
00193 HTMLElementImpl *HTMLDocumentImpl::body()
00194 {
00195 NodeImpl *de = documentElement();
00196 if (!de)
00197 return 0;
00198
00199
00200 NodeImpl* body = 0;
00201 for (NodeImpl* i = de->firstChild(); i; i = i->nextSibling()) {
00202 if (i->id() == ID_FRAMESET)
00203 return static_cast<HTMLElementImpl*>(i);
00204
00205 if (i->id() == ID_BODY)
00206 body = i;
00207 }
00208 return static_cast<HTMLElementImpl *>(body);
00209 }
00210
00211 void HTMLDocumentImpl::setBody(HTMLElementImpl *_body)
00212 {
00213 int exceptioncode = 0;
00214 HTMLElementImpl *b = body();
00215 if ( !_body && !b ) return;
00216 if ( !_body )
00217 documentElement()->removeChild( b, exceptioncode );
00218 else if ( !b )
00219 documentElement()->appendChild( _body, exceptioncode );
00220 else
00221 documentElement()->replaceChild( _body, b, exceptioncode );
00222 }
00223
00224 Tokenizer *HTMLDocumentImpl::createTokenizer()
00225 {
00226 return new HTMLTokenizer(docPtr(),m_view);
00227 }
00228
00229
00230
00231
00232
00233 bool HTMLDocumentImpl::childAllowed( NodeImpl *newChild )
00234 {
00235
00236 return (newChild->id() == ID_HTML || newChild->id() == ID_COMMENT);
00237 }
00238
00239 ElementImpl *HTMLDocumentImpl::createElement( const DOMString &name )
00240 {
00241 return createHTMLElement(name);
00242 }
00243
00244 void HTMLDocumentImpl::slotHistoryChanged()
00245 {
00246 if ( true || !m_render )
00247 return;
00248
00249 recalcStyle( Force );
00250 m_render->repaint();
00251 }
00252
00253 HTMLMapElementImpl* HTMLDocumentImpl::getMap(const DOMString& _url)
00254 {
00255 QString url = _url.string();
00256 QString s;
00257 int pos = url.find('#');
00258
00259 s = QString(_url.unicode() + pos + 1, _url.length() - pos - 1);
00260
00261 QMapConstIterator<QString,HTMLMapElementImpl*> it = mapMap.find(s);
00262
00263 if (it != mapMap.end())
00264 return *it;
00265 else
00266 return 0;
00267 }
00268
00269 static bool isTransitional(const QString &spec, int start)
00270 {
00271 if((spec.find("TRANSITIONAL", start, false ) != -1 ) ||
00272 (spec.find("LOOSE", start, false ) != -1 ) ||
00273 (spec.find("FRAMESET", start, false ) != -1 ) ||
00274 (spec.find("LATIN1", start, false ) != -1 ) ||
00275 (spec.find("SYMBOLS", start, false ) != -1 ) ||
00276 (spec.find("SPECIAL", start, false ) != -1 ) ) {
00277
00278 return true;
00279 }
00280 return false;
00281 }
00282
00283 void HTMLDocumentImpl::close()
00284 {
00285 bool doload = !parsing() && m_tokenizer;
00286
00287 DocumentImpl::close();
00288
00289 HTMLElementImpl* b = body();
00290 if (b && doload) {
00291
00292
00293
00294
00295
00296
00297 b->dispatchWindowEvent(EventImpl::LOAD_EVENT, false, false);
00298
00299 b = body();
00300
00301
00302 if (b && b->id() == ID_FRAMESET)
00303 getDocument()->dispatchWindowEvent(EventImpl::LOAD_EVENT, false, false);
00304
00305 updateRendering();
00306 }
00307 }
00308
00309
00310 void HTMLDocumentImpl::determineParseMode( const QString &str )
00311 {
00312
00313
00314
00315 int oldPMode = pMode;
00316
00317
00318 pMode = Compat;
00319 hMode = Html3;
00320
00321 ParseMode systemId = Unknown;
00322 ParseMode publicId = Unknown;
00323
00324 int pos = 0;
00325 int doctype = str.find("!doctype", 0, false);
00326 if( doctype > 2 ) {
00327 pos = doctype - 2;
00328
00329 int start = doctype + 9;
00330 while ( start < (int)str.length() && str[start].isSpace() )
00331 start++;
00332 int espace = str.find(' ',start);
00333 QString name = str.mid(start,espace-start);
00334
00335 m_doctype->setName( name );
00336 }
00337
00338
00339 int start = str.find('<', pos);
00340 int stop = str.find('>', pos);
00341 if( start > -1 && stop > start ) {
00342 QString spec = str.mid( start + 1, stop - start - 1 );
00343
00344 start = 0;
00345 int quote = -1;
00346 if( doctype != -1 ) {
00347 while( (quote = spec.find( "\"", start )) != -1 ) {
00348 int quote2 = spec.find( "\"", quote+1 );
00349 if(quote2 < 0) quote2 = spec.length();
00350 QString val = spec.mid( quote+1, quote2 - quote-1 );
00351
00352
00353 pos = val.find("http://www.w3.org/tr/", 0, false);
00354 if ( pos != -1 ) {
00355
00356 if ( val.find("strict.dtd", pos, false) != -1 )
00357 systemId = Strict;
00358 else if (isTransitional(val, pos))
00359 systemId = Transitional;
00360 }
00361
00362
00363 pos = val.find("//dtd", 0, false );
00364 if ( pos != -1 ) {
00365 if( val.find( "xhtml", pos+6, false ) != -1 ) {
00366 hMode = XHtml;
00367 publicId = isTransitional(val, pos) ? Transitional : Strict;
00368 } else if ( val.find( "15445:1999", pos+6 ) != -1 ) {
00369 hMode = Html4;
00370 publicId = Strict;
00371 } else {
00372 int tagPos = val.find( "html", pos+6, false );
00373 if( tagPos == -1 )
00374 tagPos = val.find( "hypertext markup", pos+6, false );
00375 if ( tagPos != -1 ) {
00376 tagPos = val.find(QRegExp("[0-9]"), tagPos );
00377 int version = val.mid( tagPos, 1 ).toInt();
00378
00379 if( version > 3 ) {
00380 hMode = Html4;
00381 publicId = isTransitional( val, tagPos ) ? Transitional : Strict;
00382 }
00383 }
00384 }
00385 }
00386 start = quote2 + 1;
00387 }
00388 }
00389
00390 if( systemId == publicId )
00391 pMode = publicId;
00392 else if ( systemId == Unknown )
00393 pMode = hMode == Html4 ? Compat : publicId;
00394 else if ( publicId == Transitional && systemId == Strict ) {
00395 pMode = hMode == Html3 ? Compat : Strict;
00396 } else
00397 pMode = Compat;
00398
00399 if ( hMode == XHtml )
00400 pMode = Strict;
00401 }
00402
00403
00404
00405
00406
00407
00408
00409
00410
00411 if ( pMode != oldPMode && styleSelector() )
00412 recalcStyleSelector();
00413 }
00414
00415 #include "html_documentimpl.moc"