html_baseimpl.cpp Source File (khtml Library)

| # khtml Library API Documentation
Overview | Class Hierarchy | Classes | Classes (annotated) | Members | Source Files

# html_baseimpl.cpp

    00001
    00024 // -------------------------------------------------------------------------
    00025
    00026 #include "html/html_baseimpl.h"
    00027 #include "html/html_documentimpl.h"
    00028
    00029 #include "khtmlview.h"
    00030 #include "khtml_part.h"
    00031
    00032 #include "rendering/render_frames.h"
    00033 #include "rendering/render_html.h"
    00034 #include "rendering/render_body.h"
    00035 #include "css/cssstyleselector.h"
    00036 #include "css/css_stylesheetimpl.h"
    00037 #include "css/cssproperties.h"
    00038 #include "css/cssvalues.h"
    00039 #include "css/csshelper.h"
    00040 #include "misc/loader.h"
    00041 #include "misc/htmlhashes.h"
    00042 #include "dom/dom_string.h"
    00043 #include "dom/dom_doc.h"
    00044 #include "xml/dom2_eventsimpl.h"
    00045
    00046 #include <kurl.h>
    00047 #include <kdebug.h>
    00048
    00049 using namespace DOM;
    00050 using namespace khtml;
    00051
    00052 HTMLBodyElementImpl::HTMLBodyElementImpl(DocumentPtr *doc)
    00053     : HTMLElementImpl(doc),
    00054     m_bgSet( false ), m_fgSet( false )
    00055 {
    00056     m_styleSheet = 0;
    00057 }
    00058
    00059 HTMLBodyElementImpl::~HTMLBodyElementImpl()
    00060 {
    00061     if(m_styleSheet) m_styleSheet->deref();
    00062 }
    00063
    00064 NodeImpl::Id HTMLBodyElementImpl::id() const
    00065 {
    00066     return ID_BODY;
    00067 }
    00068
    00069 void HTMLBodyElementImpl::parseAttribute(AttributeImpl *attr)
    00070 {
    00071     switch(attr->id())
    00072     {
    00073
    00074     case ATTR_BACKGROUND:
    00075     {
    00076         QString url = khtml::parseURL( attr->value() ).string();
    00077         if (!url.isEmpty()) {
    00078             url = getDocument()->completeURL( url );
    00079             addCSSProperty(CSS_PROP_BACKGROUND_IMAGE, "url('"+url+"')" );
    00080             m_bgSet = true;
    00081         }
    00082         else
    00083             m_bgSet = false;
    00084         break;
    00085     }
    00086     case ATTR_MARGINWIDTH: {
    00087         KHTMLView* w = getDocument()->view();
    00088         w->setMarginWidth( -1 ); // unset this, so it doesn't override the setting here
    00089         addCSSLength(CSS_PROP_MARGIN_RIGHT, attr->value() );
    00090     }
    00091         /* nobreak; */
    00092     case ATTR_LEFTMARGIN:
    00093         addCSSLength(CSS_PROP_MARGIN_LEFT, attr->value() );
    00094         break;
    00095     case ATTR_MARGINHEIGHT: {
    00096         KHTMLView* w = getDocument()->view();
    00097         w->setMarginHeight( -1 ); // unset this, so it doesn't override the setting here
    00098         addCSSLength(CSS_PROP_MARGIN_BOTTOM, attr->value());
    00099     }
    00100         /* nobreak */
    00101     case ATTR_TOPMARGIN:
    00102         addCSSLength(CSS_PROP_MARGIN_TOP, attr->value());
    00103         break;
    00104     case ATTR_BGCOLOR:
    00105         addCSSProperty(CSS_PROP_BACKGROUND_COLOR, attr->value());
    00106         m_bgSet = !attr->value().isNull();
    00107         break;
    00108     case ATTR_TEXT:
    00109         addCSSProperty(CSS_PROP_COLOR, attr->value());
    00110         m_fgSet = !attr->value().isNull();
    00111         break;
    00112     case ATTR_BGPROPERTIES:
    00113         if ( strcasecmp( attr->value(), "fixed" ) == 0)
    00114             addCSSProperty(CSS_PROP_BACKGROUND_ATTACHMENT, CSS_VAL_FIXED);
    00115         break;
    00116     case ATTR_VLINK:
    00117     case ATTR_ALINK:
    00118     case ATTR_LINK:
    00119     {
    00120         if(!m_styleSheet) {
    00121             m_styleSheet = new CSSStyleSheetImpl(this,DOMString(),true);
    00122             m_styleSheet->ref();
    00123         }
    00124         QString aStr;
    00125         if ( attr->id() == ATTR_LINK )
    00126             aStr = "a:link";
    00127         else if ( attr->id() == ATTR_VLINK )
    00128             aStr = "a:visited";
    00129         else if ( attr->id() == ATTR_ALINK )
    00130             aStr = "a:active";
    00131         aStr += " { color: " + attr->value().string() + "; }";
    00132         m_styleSheet->parseString(aStr);
    00133         m_styleSheet->setNonCSSHints();
    00134         break;
    00135     }
    00136     case ATTR_ONLOAD:
    00137         getDocument()->setWindowEventListener(EventImpl::LOAD_EVENT,
    00138             getDocument()->createHTMLEventListener(attr->value().string()));
    00139         break;
    00140     case ATTR_ONUNLOAD:
    00141         getDocument()->setWindowEventListener(EventImpl::UNLOAD_EVENT,
    00142             getDocument()->createHTMLEventListener(attr->value().string()));
    00143         break;
    00144     case ATTR_ONBLUR:
    00145         getDocument()->setWindowEventListener(EventImpl::BLUR_EVENT,
    00146             getDocument()->createHTMLEventListener(attr->value().string()));
    00147         break;
    00148     case ATTR_ONFOCUS:
    00149         getDocument()->setWindowEventListener(EventImpl::FOCUS_EVENT,
    00150             getDocument()->createHTMLEventListener(attr->value().string()));
    00151         break;
    00152     case ATTR_ONRESIZE:
    00153         getDocument()->setWindowEventListener(EventImpl::RESIZE_EVENT,
    00154             getDocument()->createHTMLEventListener(attr->value().string()));
    00155         break;
    00156     case ATTR_NOSAVE:
    00157         break;
    00158     default:
    00159         HTMLElementImpl::parseAttribute(attr);
    00160     }
    00161 }
    00162
    00163 void HTMLBodyElementImpl::insertedIntoDocument()
    00164 {
    00165     HTMLElementImpl::insertedIntoDocument();
    00166
    00167     KHTMLView* w = getDocument()->view();
    00168     if(w->marginWidth() != -1) {
    00169         QString s;
    00170         s.sprintf( "%d", w->marginWidth() );
    00171         addCSSLength(CSS_PROP_MARGIN_LEFT, s);
    00172         addCSSLength(CSS_PROP_MARGIN_RIGHT, s);
    00173     }
    00174     if(w->marginHeight() != -1) {
    00175         QString s;
    00176         s.sprintf( "%d", w->marginHeight() );
    00177         addCSSLength(CSS_PROP_MARGIN_TOP, s);
    00178         addCSSLength(CSS_PROP_MARGIN_BOTTOM, s);
    00179     }
    00180
    00181     if ( m_bgSet && !m_fgSet )
    00182         addCSSProperty(CSS_PROP_COLOR, "#000000");
    00183
    00184     if (m_styleSheet)
    00185         getDocument()->updateStyleSelector();
    00186 }
    00187
    00188 void HTMLBodyElementImpl::removedFromDocument()
    00189 {
    00190     HTMLElementImpl::removedFromDocument();
    00191
    00192     if (m_styleSheet)
    00193         getDocument()->updateStyleSelector();
    00194 }
    00195
    00196 void HTMLBodyElementImpl::attach()
    00197 {
    00198     assert(!m_render);
    00199     assert(parentNode());
    00200     assert(parentNode()->renderer());
    00201
    00202     RenderStyle* style = getDocument()->styleSelector()->styleForElement(this);
    00203     style->ref();
    00204     if (style->display() != NONE) {
    00205         m_render = new RenderBody(this);
    00206         m_render->setStyle(style);
    00207         parentNode()->renderer()->addChild(m_render, nextRenderer());
    00208     }
    00209     style->deref();
    00210
    00211     NodeBaseImpl::attach();
    00212 }
    00213
    00214 // -------------------------------------------------------------------------
    00215
    00216 HTMLFrameElementImpl::HTMLFrameElementImpl(DocumentPtr *doc)
    00217     : HTMLElementImpl(doc)
    00218 {
    00219     frameBorder = true;
    00220     frameBorderSet = false;
    00221     marginWidth = -1;
    00222     marginHeight = -1;
    00223     scrolling = QScrollView::Auto;
    00224     noresize = false;
    00225     url = "about:blank";
    00226 }
    00227
    00228 HTMLFrameElementImpl::~HTMLFrameElementImpl()
    00229 {
    00230 }
    00231
    00232 NodeImpl::Id HTMLFrameElementImpl::id() const
    00233 {
    00234     return ID_FRAME;
    00235 }
    00236
    00237 void HTMLFrameElementImpl::parseAttribute(AttributeImpl *attr)
    00238 {
    00239     switch(attr->id())
    00240     {
    00241     case ATTR_SRC:
    00242         url = khtml::parseURL(attr->val());
    00243         // FIXME_APPLE: load new url in the iframe
    00244         setChanged();
    00245         break;
    00246     case ATTR_ID:
    00247     case ATTR_NAME:
    00248         // FIXME: if already attached, doesn't change the frame name
    00249         // FIXME: frame name conflicts, no unique frame name anymore
    00250         name = attr->value();
    00251         break;
    00252     case ATTR_FRAMEBORDER:
    00253     {
    00254         frameBorder = attr->value().toInt();
    00255         frameBorderSet = ( attr->val() != 0 );
    00256         // FIXME: when attached, has no effect
    00257     }
    00258     break;
    00259     case ATTR_MARGINWIDTH:
    00260         marginWidth = attr->val()->toInt();
    00261         // FIXME: when attached, has no effect
    00262         break;
    00263     case ATTR_MARGINHEIGHT:
    00264         marginHeight = attr->val()->toInt();
    00265         // FIXME: when attached, has no effect
    00266         break;
    00267     case ATTR_NORESIZE:
    00268         noresize = true;
    00269         // FIXME: when attached, has no effect
    00270         break;
    00271     case ATTR_SCROLLING:
    00272         if( strcasecmp( attr->value(), "auto" ) == 0 )
    00273             scrolling = QScrollView::Auto;
    00274         else if( strcasecmp( attr->value(), "yes" ) == 0 )
    00275             scrolling = QScrollView::AlwaysOn;
    00276         else if( strcasecmp( attr->value(), "no" ) == 0 )
    00277             scrolling = QScrollView::AlwaysOff;
    00278         // when attached, has no effect
    00279         break;
    00280     case ATTR_ONLOAD:
    00281         static_cast<HTMLDocumentImpl*>( getDocument() )->body()
    00282               ->setHTMLEventListener(EventImpl::LOAD_EVENT,
    00283             getDocument()->createHTMLEventListener(attr->value().string()));
    00284         break;
    00285     case ATTR_ONUNLOAD:
    00286         static_cast<HTMLDocumentImpl*>( getDocument() )->body()
    00287               ->setHTMLEventListener(EventImpl::UNLOAD_EVENT,
    00288             getDocument()->createHTMLEventListener(attr->value().string()));
    00289         break;
    00290
    00291     default:
    00292         HTMLElementImpl::parseAttribute(attr);
    00293     }
    00294 }
    00295
    00296 void HTMLFrameElementImpl::attach()
    00297 {
    00298     assert(!attached());
    00299     assert(parentNode());
    00300     assert(parentNode()->renderer());
    00301
    00302     // we should first look up via id, then via name.
    00303     // this shortterm hack fixes the ugly case. ### rewrite needed for next release
    00304     name = getAttribute(ATTR_NAME);
    00305     if (name.isNull())
    00306         name = getAttribute(ATTR_ID);
    00307
    00308     // inherit default settings from parent frameset
    00309     HTMLElementImpl* node = static_cast<HTMLElementImpl*>(parentNode());
    00310     while(node)
    00311     {
    00312         if(node->id() == ID_FRAMESET)
    00313         {
    00314             HTMLFrameSetElementImpl* frameset = static_cast<HTMLFrameSetElementImpl*>(node);
    00315             if(!frameBorderSet)  frameBorder = frameset->frameBorder();
    00316             if(!noresize)  noresize = frameset->noResize();
    00317             break;
    00318         }
    00319         node = static_cast<HTMLElementImpl*>(node->parentNode());
    00320     }
    00321
    00322     // ignore display: none for this element!
    00323     KHTMLView* w = getDocument()->view();
    00324
    00325     if (isURLAllowed(url.string()))  {
    00326         m_render = new RenderFrame(this);
    00327         m_render->setStyle(getDocument()->styleSelector()->styleForElement(this));
    00328         parentNode()->renderer()->addChild(m_render, nextRenderer());
    00329     }
    00330
    00331     NodeBaseImpl::attach();
    00332
    00333     if (!m_render)
    00334         return;
    00335
    00336     // we need a unique name for every frame in the frameset. Hope that's unique enough.
    00337     if(name.isEmpty() || w->part()->frameExists( name.string() ) )
    00338       name = DOMString(w->part()->requestFrameName());
    00339
    00340     // load the frame contents
    00341     w->part()->requestFrame( static_cast<RenderFrame*>(m_render), url.string(), name.string() );
    00342 }
    00343
    00344 void HTMLFrameElementImpl::setLocation( const DOMString& str )
    00345 {
    00346     url = str;
    00347     KHTMLView* w = getDocument()->view();
    00348     if ( m_render && w && w->part() )
    00349         // don't call this for an iframe
    00350         w->part()->requestFrame( static_cast<khtml::RenderFrame *>(m_render), url.string(), name.string() );
    00351 }
    00352
    00353 bool HTMLFrameElementImpl::isSelectable() const
    00354 {
    00355     return m_render!=0;
    00356 }
    00357
    00358 void HTMLFrameElementImpl::setFocus(bool received)
    00359 {
    00360     HTMLElementImpl::setFocus(received);
    00361     khtml::RenderFrame *renderFrame = static_cast<khtml::RenderFrame *>(m_render);
    00362     if (!renderFrame || !renderFrame->widget())
    00363         return;
    00364     if (received)
    00365         renderFrame->widget()->setFocus();
    00366     else
    00367         renderFrame->widget()->clearFocus();
    00368 }
    00369
    00370 DocumentImpl* HTMLFrameElementImpl::contentDocument() const
    00371 {
    00372     if ( !m_render ) return 0;
    00373
    00374     RenderPart* render = static_cast<RenderPart*>( m_render );
    00375
    00376     if(render->widget() && render->widget()->inherits("KHTMLView"))
    00377         return static_cast<KHTMLView*>( render->widget() )->part()->xmlDocImpl();
    00378
    00379     return 0;
    00380 }
    00381
    00382 // -------------------------------------------------------------------------
    00383
    00384 HTMLFrameSetElementImpl::HTMLFrameSetElementImpl(DocumentPtr *doc)
    00385     : HTMLElementImpl(doc)
    00386 {
    00387     // default value for rows and cols...
    00388     m_totalRows = 1;
    00389     m_totalCols = 1;
    00390
    00391     m_rows = m_cols = 0;
    00392
    00393     frameborder = true;
    00394     frameBorderSet = false;
    00395     m_border = 4;
    00396     noresize = false;
    00397
    00398     m_resizing = false;
    00399 }
    00400
    00401 HTMLFrameSetElementImpl::~HTMLFrameSetElementImpl()
    00402 {
    00403     if (m_rows)
    00404         delete [] m_rows;
    00405     if (m_cols)
    00406         delete [] m_cols;
    00407 }
    00408
    00409 NodeImpl::Id HTMLFrameSetElementImpl::id() const
    00410 {
    00411     return ID_FRAMESET;
    00412 }
    00413
    00414 void HTMLFrameSetElementImpl::parseAttribute(AttributeImpl *attr)
    00415 {
    00416     switch(attr->id())
    00417     {
    00418     case ATTR_ROWS:
    00419         if (!attr->val()) break;
    00420         if (m_rows) delete [] m_rows;
    00421         m_rows = attr->val()->toLengthArray(m_totalRows);
    00422         setChanged();
    00423     break;
    00424     case ATTR_COLS:
    00425         if (!attr->val()) break;
    00426         delete [] m_cols;
    00427         m_cols = attr->val()->toLengthArray(m_totalCols);
    00428         setChanged();
    00429     break;
    00430     case ATTR_FRAMEBORDER:
    00431         // false or "no" or "0"..
    00432         if ( attr->value().toInt() == 0 ) {
    00433             frameborder = false;
    00434             m_border = 0;
    00435         }
    00436         frameBorderSet = true;
    00437         break;
    00438     case ATTR_NORESIZE:
    00439         noresize = true;
    00440         break;
    00441     case ATTR_BORDER:
    00442         m_border = attr->val()->toInt();
    00443         if(!m_border)
    00444             frameborder = false;
    00445         break;
    00446     case ATTR_ONLOAD:
    00447         getDocument()->setHTMLEventListener(EventImpl::LOAD_EVENT,
    00448             getDocument()->createHTMLEventListener(attr->value().string()));
    00449         break;
    00450     case ATTR_ONUNLOAD:
    00451         getDocument()->setHTMLEventListener(EventImpl::UNLOAD_EVENT,
    00452             getDocument()->createHTMLEventListener(attr->value().string()));
    00453         break;
    00454     default:
    00455         HTMLElementImpl::parseAttribute(attr);
    00456     }
    00457 }
    00458
    00459 void HTMLFrameSetElementImpl::attach()
    00460 {
    00461     assert(!m_render);
    00462     assert(parentNode());
    00463     assert(parentNode()->renderer());
    00464
    00465     // inherit default settings from parent frameset
    00466     HTMLElementImpl* node = static_cast<HTMLElementImpl*>(parentNode());
    00467     while(node)
    00468     {
    00469         if(node->id() == ID_FRAMESET)
    00470         {
    00471             HTMLFrameSetElementImpl* frameset = static_cast<HTMLFrameSetElementImpl*>(node);
    00472             if(!frameBorderSet)  frameborder = frameset->frameBorder();
    00473             if(!noresize)  noresize = frameset->noResize();
    00474             break;
    00475         }
    00476         node = static_cast<HTMLElementImpl*>(node->parentNode());
    00477     }
    00478
    00479     // ignore display: none
    00480     m_render = new RenderFrameSet(this);
    00481     m_render->setStyle(getDocument()->styleSelector()->styleForElement(this));
    00482     parentNode()->renderer()->addChild(m_render, nextRenderer());
    00483
    00484     NodeBaseImpl::attach();
    00485 }
    00486
    00487 void HTMLFrameSetElementImpl::defaultEventHandler(EventImpl *evt)
    00488 {
    00489     if (evt->isMouseEvent() && !noresize && m_render)
    00490         static_cast<khtml::RenderFrameSet *>(m_render)->userResize(static_cast<MouseEventImpl*>(evt));
    00491
    00492     evt->setDefaultHandled();
    00493     HTMLElementImpl::defaultEventHandler(evt);
    00494 }
    00495
    00496 void HTMLFrameSetElementImpl::detach()
    00497 {
    00498     if(attached())
    00499         // ### send the event when we actually get removed from the doc instead of here
    00500         getDocument()->dispatchHTMLEvent(EventImpl::UNLOAD_EVENT,false,false);
    00501
    00502     HTMLElementImpl::detach();
    00503 }
    00504
    00505 void HTMLFrameSetElementImpl::recalcStyle( StyleChange ch )
    00506 {
    00507     if (changed() && m_render) {
    00508         m_render->setLayouted(false);
    00509 //         m_render->layout();
    00510         setChanged(false);
    00511     }
    00512     HTMLElementImpl::recalcStyle( ch );
    00513 }
    00514
    00515
    00516 // -------------------------------------------------------------------------
    00517
    00518 NodeImpl::Id HTMLHeadElementImpl::id() const
    00519 {
    00520     return ID_HEAD;
    00521 }
    00522
    00523 void HTMLHtmlElementImpl::attach()
    00524 {
    00525     assert(!m_render);
    00526     assert(parentNode());
    00527     assert(parentNode()->renderer());
    00528
    00529     m_render = new RenderHtml(this);
    00530     m_render->setStyle(getDocument()->styleSelector()->styleForElement(this));
    00531     parentNode()->renderer()->addChild(m_render, nextRenderer());
    00532
    00533     NodeBaseImpl::attach();
    00534 }
    00535
    00536 // -------------------------------------------------------------------------
    00537
    00538 NodeImpl::Id HTMLHtmlElementImpl::id() const
    00539 {
    00540     return ID_HTML;
    00541 }
    00542
    00543
    00544 // -------------------------------------------------------------------------
    00545
    00546 HTMLIFrameElementImpl::HTMLIFrameElementImpl(DocumentPtr *doc) : HTMLFrameElementImpl(doc)
    00547 {
    00548     frameBorder = false;
    00549     marginWidth = 0;
    00550     marginHeight = 0;
    00551     needWidgetUpdate = false;
    00552 }
    00553
    00554 HTMLIFrameElementImpl::~HTMLIFrameElementImpl()
    00555 {
    00556 }
    00557
    00558 NodeImpl::Id HTMLIFrameElementImpl::id() const
    00559 {
    00560     return ID_IFRAME;
    00561 }
    00562
    00563 void HTMLIFrameElementImpl::parseAttribute(AttributeImpl *attr )
    00564 {
    00565   switch (  attr->id() )
    00566   {
    00567     case ATTR_WIDTH:
    00568       addCSSLength( CSS_PROP_WIDTH, attr->value());
    00569       break;
    00570     case ATTR_HEIGHT:
    00571       addCSSLength( CSS_PROP_HEIGHT, attr->value() );
    00572       break;
    00573     case ATTR_SRC:
    00574       needWidgetUpdate = true; // ### do this for scrolling, margins etc?
    00575       HTMLFrameElementImpl::parseAttribute( attr );
    00576       break;
    00577     default:
    00578       HTMLFrameElementImpl::parseAttribute( attr );
    00579   }
    00580 }
    00581
    00582 void HTMLIFrameElementImpl::attach()
    00583 {
    00584     assert(!attached());
    00585     assert(!m_render);
    00586     assert(parentNode());
    00587
    00588     RenderStyle* _style = getDocument()->styleSelector()->styleForElement(this);
    00589     _style->ref();
    00590     if (isURLAllowed(url.string()) &&
    00591         parentNode()->renderer() && _style->display() != NONE) {
    00592         m_render = new RenderPartObject(this);
    00593         m_render->setStyle(_style);
    00594         parentNode()->renderer()->addChild(m_render, nextRenderer());
    00595     }
    00596     _style->deref();
    00597
    00598     NodeBaseImpl::attach();
    00599
    00600     if (m_render) {
    00601         // we need a unique name for every frame in the frameset. Hope that's unique enough.
    00602         KHTMLView* w = getDocument()->view();
    00603         if(name.isEmpty() || w->part()->frameExists( name.string() ))
    00604             name = DOMString(w->part()->requestFrameName());
    00605
    00606         static_cast<RenderPartObject*>(m_render)->updateWidget();
    00607         needWidgetUpdate = false;
    00608     }
    00609 }
    00610
    00611 void HTMLIFrameElementImpl::recalcStyle( StyleChange ch )
    00612 {
    00613     if (needWidgetUpdate) {
    00614         if(m_render)  static_cast<RenderPartObject*>(m_render)->updateWidget();
    00615         needWidgetUpdate = false;
    00616     }
    00617     HTMLElementImpl::recalcStyle( ch );
    00618 }
    00619

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