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

# html_elementimpl.cpp

    00001
    00024 // -------------------------------------------------------------------------
    00025 //#define DEBUG
    00026 //#define DEBUG_LAYOUT
    00027 //#define PAR_DEBUG
    00028 //#define EVENT_DEBUG
    00029 //#define UNSUPPORTED_ATTR
    00030
    00031 #include "html/dtd.h"
    00032 #include "html/html_elementimpl.h"
    00033 #include "html/html_documentimpl.h"
    00034 #include "html/htmltokenizer.h"
    00035
    00036 #include "misc/htmlhashes.h"
    00037
    00038 #include "khtmlview.h"
    00039 #include "khtml_part.h"
    00040
    00041 #include "rendering/render_object.h"
    00042 #include "rendering/render_replaced.h"
    00043 #include "css/css_valueimpl.h"
    00044 #include "css/css_stylesheetimpl.h"
    00045 #include "css/cssproperties.h"
    00046 #include "css/cssvalues.h"
    00047 #include "xml/dom_textimpl.h"
    00048 #include "xml/dom2_eventsimpl.h"
    00049
    00050 #include <kapplication.h>
    00051 #include <kdebug.h>
    00052
    00053 using namespace DOM;
    00054 using namespace khtml;
    00055
    00056 HTMLElementImpl::~HTMLElementImpl()
    00057 {
    00058 }
    00059
    00060 void HTMLElementImpl::parseAttribute(AttributeImpl *attr)
    00061 {
    00062     DOMString indexstring;
    00063     switch( attr->id() )
    00064     {
    00065     case ATTR_ALIGN:
    00066         if (attr->val()) {
    00067             if ( strcasecmp(attr->value(), "middle" ) == 0 )
    00068                 addCSSProperty( CSS_PROP_TEXT_ALIGN, "center" );
    00069             else
    00070                 addCSSProperty(CSS_PROP_TEXT_ALIGN, attr->value());
    00071         }
    00072         else
    00073             removeCSSProperty(CSS_PROP_TEXT_ALIGN);
    00074         break;
    00075 // the core attributes...
    00076     case ATTR_ID:
    00077         // unique id
    00078         setHasID();
    00079         setChanged(); // in case of a CSS selector on id
    00080         break;
    00081     case ATTR_CLASS:
    00082     case ATTR_NAME:
    00083         setChanged(); // in case of a CSS selector on class/name
    00084         break;
    00085     case ATTR_STYLE:
    00086         // ### we need to remove old style info in case there was any!
    00087         // ### the inline sheet ay contain more than 1 property!
    00088         // stylesheet info
    00089         setHasStyle();
    00090         if(!m_styleDecls) createDecl();
    00091         m_styleDecls->setProperty(attr->value());
    00092         setChanged();
    00093         break;
    00094     case ATTR_TABINDEX:
    00095         indexstring=getAttribute(ATTR_TABINDEX);
    00096         if (indexstring.length())
    00097             setTabIndex(indexstring.toInt());
    00098         break;
    00099 // i18n attributes
    00100     case ATTR_LANG:
    00101         break;
    00102     case ATTR_DIR:
    00103         addCSSProperty(CSS_PROP_DIRECTION, attr->value());
    00104         addCSSProperty(CSS_PROP_UNICODE_BIDI, CSS_VAL_EMBED);
    00105         break;
    00106 // standard events
    00107     case ATTR_ONCLICK:
    00108         setHTMLEventListener(EventImpl::KHTML_ECMA_CLICK_EVENT,
    00109             getDocument()->createHTMLEventListener(attr->value().string()));
    00110         break;
    00111     case ATTR_ONDBLCLICK:
    00112         setHTMLEventListener(EventImpl::KHTML_ECMA_DBLCLICK_EVENT,
    00113             getDocument()->createHTMLEventListener(attr->value().string()));
    00114         break;
    00115     case ATTR_ONMOUSEDOWN:
    00116         setHTMLEventListener(EventImpl::MOUSEDOWN_EVENT,
    00117             getDocument()->createHTMLEventListener(attr->value().string()));
    00118         break;
    00119     case ATTR_ONMOUSEMOVE:
    00120         setHTMLEventListener(EventImpl::MOUSEMOVE_EVENT,
    00121             getDocument()->createHTMLEventListener(attr->value().string()));
    00122         break;
    00123     case ATTR_ONMOUSEOUT:
    00124         setHTMLEventListener(EventImpl::MOUSEOUT_EVENT,
    00125             getDocument()->createHTMLEventListener(attr->value().string()));
    00126         break;
    00127     case ATTR_ONMOUSEOVER:
    00128         setHTMLEventListener(EventImpl::MOUSEOVER_EVENT,
    00129             getDocument()->createHTMLEventListener(attr->value().string()));
    00130         break;
    00131     case ATTR_ONMOUSEUP:
    00132         setHTMLEventListener(EventImpl::MOUSEUP_EVENT,
    00133             getDocument()->createHTMLEventListener(attr->value().string()));
    00134         break;
    00135     case ATTR_ONFOCUS:
    00136         setHTMLEventListener(EventImpl::DOMFOCUSIN_EVENT,
    00137             getDocument()->createHTMLEventListener(attr->value().string()));
    00138         break;
    00139     case ATTR_ONKEYDOWN:
    00140         setHTMLEventListener(EventImpl::KHTML_KEYDOWN_EVENT,
    00141             getDocument()->createHTMLEventListener(attr->value().string()));
    00142         break;
    00143     case ATTR_ONKEYPRESS:
    00144         setHTMLEventListener(EventImpl::KHTML_KEYPRESS_EVENT,
    00145             getDocument()->createHTMLEventListener(attr->value().string()));
    00146         break;
    00147     case ATTR_ONKEYUP:
    00148         setHTMLEventListener(EventImpl::KHTML_KEYUP_EVENT,
    00149             getDocument()->createHTMLEventListener(attr->value().string()));
    00150         break;
    00151 // other misc attributes
    00152     default:
    00153 #ifdef UNSUPPORTED_ATTR
    00154         kdDebug(6030) << "UATTR: <" << this->nodeName().string() << "> ["
    00155                       << attr->name().string() << "]=[" << attr->value().string() << "]" << endl;
    00156 #endif
    00157         break;
    00158     }
    00159 }
    00160
    00161 void HTMLElementImpl::recalcStyle( StyleChange ch )
    00162 {
    00163     ElementImpl::recalcStyle( ch );
    00164
    00165     if (m_render /*&& changed*/)
    00166         m_render->updateFromElement();
    00167 }
    00168
    00169 void HTMLElementImpl::addCSSProperty(int id, const DOMString &value)
    00170 {
    00171     if(!m_styleDecls) createDecl();
    00172     m_styleDecls->setProperty(id, value, false, true);
    00173     setChanged();
    00174 }
    00175
    00176 void HTMLElementImpl::addCSSProperty(int id, int value)
    00177 {
    00178     if(!m_styleDecls) createDecl();
    00179     m_styleDecls->setProperty(id, value, false, true);
    00180     setChanged();
    00181 }
    00182
    00183 void HTMLElementImpl::addCSSLength(int id, const DOMString &value, bool numOnly, bool multiLength)
    00184 {
    00185     if(!m_styleDecls) createDecl();
    00186
    00187     // strip attribute garbage..
    00188     DOMStringImpl* v = value.implementation();
    00189     if ( v ) {
    00190         unsigned int l = 0;
    00191
    00192         while ( l < v->l && v->s[l].unicode() <= ' ') l++;
    00193
    00194         for ( ;l < v->l; l++ ) {
    00195             char cc = v->s[l].latin1();
    00196             if ( cc > '9' || ( cc < '0' && ( numOnly || (cc != '%' && cc != '.' &&
    00197                                                          !( multiLength && cc == '*') ) ) ) )
    00198                 break;
    00199         }
    00200         if ( l != v->l ) {
    00201             m_styleDecls->setLengthProperty( id, DOMString( v->s, l ), false, true, multiLength );
    00202             setChanged();
    00203             return;
    00204         }
    00205     }
    00206
    00207     m_styleDecls->setLengthProperty(id, value, false, true, multiLength);
    00208     setChanged();
    00209 }
    00210
    00211 void HTMLElementImpl::removeCSSProperty(int id)
    00212 {
    00213     if(!m_styleDecls)
    00214         return;
    00215     m_styleDecls->setParent(getDocument()->elementSheet());
    00216     m_styleDecls->removeProperty(id);
    00217     setChanged();
    00218 }
    00219
    00220 DOMString HTMLElementImpl::innerHTML() const
    00221 {
    00222     return toHTML();
    00223 }
    00224
    00225 DOMString HTMLElementImpl::innerText() const
    00226 {
    00227     DOMString text;
    00228
    00229     const NodeImpl *n = this;
    00230     // find the next text/image after the anchor, to get a position
    00231     while(n) {
    00232         if(n->firstChild())
    00233             n = n->firstChild();
    00234         else if(n->nextSibling())
    00235             n = n->nextSibling();
    00236         else {
    00237             NodeImpl *next = 0;
    00238             while(!next) {
    00239                 n = n->parentNode();
    00240                 if(!n || n == (NodeImpl *)this ) goto end;
    00241                 next = n->nextSibling();
    00242             }
    00243             n = next;
    00244         }
    00245         if(n->isTextNode() ) {
    00246             text += static_cast<const TextImpl *>(n)->data();
    00247         }
    00248     }
    00249  end:
    00250     return text;
    00251 }
    00252
    00253 bool HTMLElementImpl::setInnerHTML( const DOMString &html )
    00254 {
    00255     // the following is in accordance with the definition as used by IE
    00256     if( endTag[id()] == FORBIDDEN )
    00257         return false;
    00258     // IE disallows innerHTML on inline elements. I don't see why we should have this restriction, as our
    00259     // dhtml engine can cope with it. Lars
    00260     //if ( isInline() ) return false;
    00261     switch( id() ) {
    00262         case ID_COL:
    00263         case ID_COLGROUP:
    00264         case ID_FRAMESET:
    00265         case ID_HEAD:
    00266         case ID_HTML:
    00267         case ID_STYLE:
    00268         case ID_TABLE:
    00269         case ID_TBODY:
    00270         case ID_TFOOT:
    00271         case ID_THEAD:
    00272         case ID_TITLE:
    00273         case ID_TR:
    00274             return false;
    00275         default:
    00276             break;
    00277     }
    00278     if ( !getDocument()->isHTMLDocument() )
    00279         return false;
    00280
    00281     DocumentFragmentImpl *fragment = new DocumentFragmentImpl( docPtr() );
    00282     HTMLTokenizer *tok = new HTMLTokenizer( docPtr(), fragment );
    00283     tok->begin();
    00284     tok->write( html.string(), true );
    00285     tok->end();
    00286     delete tok;
    00287
    00288     removeChildren();
    00289     int ec = 0;
    00290     appendChild( fragment, ec );
    00291     delete fragment;
    00292     return !ec;
    00293 }
    00294
    00295 bool HTMLElementImpl::setInnerText( const DOMString &text )
    00296 {
    00297     // following the IE specs.
    00298     if( endTag[id()] == FORBIDDEN )
    00299         return false;
    00300     // IE disallows innerHTML on inline elements. I don't see why we should have this restriction, as our
    00301     // dhtml engine can cope with it. Lars
    00302     //if ( isInline() ) return false;
    00303     switch( id() ) {
    00304         case ID_COL:
    00305         case ID_COLGROUP:
    00306         case ID_FRAMESET:
    00307         case ID_HEAD:
    00308         case ID_HTML:
    00309         case ID_TABLE:
    00310         case ID_TBODY:
    00311         case ID_TFOOT:
    00312         case ID_THEAD:
    00313         case ID_TR:
    00314             return false;
    00315         default:
    00316             break;
    00317     }
    00318
    00319     removeChildren();
    00320
    00321     TextImpl *t = new TextImpl( docPtr(), text.implementation() );
    00322     int ec = 0;
    00323     appendChild( t, ec );
    00324     if ( !ec )
    00325         return true;
    00326     return false;
    00327 }
    00328
    00329 DOMString HTMLElementImpl::namespaceURI() const
    00330 {
    00331     // For HTML documents, we treat HTML elements as having no namespace. But for XML documents
    00332     // the elements have the namespace defined in the XHTML spec
    00333     if (getDocument()->isHTMLDocument())
    00334         return DOMString();
    00335     else
    00336         return XHTML_NAMESPACE;
    00337 }
    00338
    00339 void HTMLElementImpl::addHTMLAlignment( DOMString alignment )
    00340 {
    00341     //qDebug("alignment is %s", alignment.string().latin1() );
    00342     // vertical alignment with respect to the current baseline of the text
    00343     // right or left means floating images
    00344     int propfloat = -1;
    00345     int propvalign = -1;
    00346     if ( strcasecmp( alignment, "absmiddle" ) == 0 ) {
    00347         propvalign = CSS_VAL_MIDDLE;
    00348     } else if ( strcasecmp( alignment, "absbottom" ) == 0 ) {
    00349         propvalign = CSS_VAL_BOTTOM;
    00350     } else if ( strcasecmp( alignment, "left" ) == 0 ) {
    00351         propfloat = CSS_VAL_LEFT;
    00352         propvalign = CSS_VAL_TOP;
    00353     } else if ( strcasecmp( alignment, "right" ) == 0 ) {
    00354         propfloat = CSS_VAL_RIGHT;
    00355         propvalign = CSS_VAL_TOP;
    00356     } else if ( strcasecmp( alignment, "top" ) == 0 ) {
    00357         propvalign = CSS_VAL_TOP;
    00358     } else if ( strcasecmp( alignment, "middle" ) == 0 ) {
    00359         propvalign = CSS_VAL__KONQ_BASELINE_MIDDLE;
    00360     } else if ( strcasecmp( alignment, "center" ) == 0 ) {
    00361         propvalign = CSS_VAL_MIDDLE;
    00362     } else if ( strcasecmp( alignment, "bottom" ) == 0 ) {
    00363         propvalign = CSS_VAL_BASELINE;
    00364     } else if ( strcasecmp ( alignment, "texttop") == 0 ) {
    00365         propvalign = CSS_VAL_TEXT_TOP;
    00366     }
    00367
    00368     if ( propfloat != -1 )
    00369         addCSSProperty( CSS_PROP_FLOAT, propfloat );
    00370     if ( propvalign != -1 )
    00371         addCSSProperty( CSS_PROP_VERTICAL_ALIGN, propvalign );
    00372 }
    00373
    00374 bool HTMLElementImpl::isURLAllowed(const QString& url) const
    00375 {
    00376     KHTMLView *w = getDocument()->view();
    00377
    00378     KURL newURL(getDocument()->completeURL(url));
    00379     newURL.setRef(QString::null);
    00380
    00381     // Prohibit non-file URLs if we are asked to.
    00382     if (!w || w->part()->onlyLocalReferences() && newURL.protocol() != "file")
    00383         return false;
    00384
    00385     // do we allow this suburl ?
    00386     if ( !kapp || !kapp->kapp->authorizeURLAction("redirect", w->part()->url(), newURL) )
    00387         return false;
    00388
    00389     // We allow one level of self-reference because some sites depend on that.
    00390     // But we don't allow more than one.
    00391     bool foundSelfReference = false;
    00392     for (KHTMLPart *part = w->part(); part; part = part->parentPart()) {
    00393         KURL partURL = part->url();
    00394         partURL.setRef(QString::null);
    00395         if (partURL == newURL) {
    00396             if (foundSelfReference)
    00397                 return false;
    00398             foundSelfReference = true;
    00399         }
    00400     }
    00401
    00402     return true;
    00403 }
    00404
    00405
    00406
    00407 // -------------------------------------------------------------------------
    00408 HTMLGenericElementImpl::HTMLGenericElementImpl(DocumentPtr *doc, ushort i)
    00409     : HTMLElementImpl(doc)
    00410 {
    00411     _id = i;
    00412 }
    00413
    00414 HTMLGenericElementImpl::~HTMLGenericElementImpl()
    00415 {
    00416 }
    00417

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:51 2004 by doxygen 1.3.4 written by Dimitri van Heesch, © 1997-2001