File indexing completed on 2024-05-05 16:10:08

0001 /**
0002  * This file is part of the DOM implementation for KDE.
0003  *
0004  * Copyright (C) 1999 Lars Knoll (knoll@kde.org)
0005  *           (C) 1999 Antti Koivisto (koivisto@kde.org)
0006  *           (C) 2000 Simon Hausmann (hausmann@kde.org)
0007  *           (C) 2001-2003 Dirk Mueller (mueller@kde.org)
0008  *
0009  * This library is free software; you can redistribute it and/or
0010  * modify it under the terms of the GNU Library General Public
0011  * License as published by the Free Software Foundation; either
0012  * version 2 of the License, or (at your option) any later version.
0013  *
0014  * This library is distributed in the hope that it will be useful,
0015  * but WITHOUT ANY WARRANTY; without even the implied warranty of
0016  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
0017  * Library General Public License for more details.
0018  *
0019  * You should have received a copy of the GNU Library General Public License
0020  * along with this library; see the file COPYING.LIB.  If not, write to
0021  * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
0022  * Boston, MA 02110-1301, USA.
0023  */
0024 // -------------------------------------------------------------------------
0025 
0026 #include "html/html_baseimpl.h"
0027 #include "html/html_documentimpl.h"
0028 
0029 #include "khtmlview.h"
0030 #include "khtml_part.h"
0031 #include "khtmlpart_p.h"
0032 
0033 #include "rendering/render_frames.h"
0034 #include "rendering/render_body.h"
0035 #include "css/cssstyleselector.h"
0036 #include "css/css_stylesheetimpl.h"
0037 #include "css/cssproperties.h"
0038 #include "css/cssvalues.h"
0039 #include "misc/loader.h"
0040 #include "dom/dom_string.h"
0041 #include "dom/dom_doc.h"
0042 #include "xml/dom2_eventsimpl.h"
0043 
0044 #include <QUrl>
0045 #include "khtml_debug.h"
0046 
0047 #undef FOCUS_EVENT  // for win32, MinGW
0048 
0049 using namespace DOM;
0050 using namespace khtml;
0051 
0052 HTMLBodyElementImpl::HTMLBodyElementImpl(DocumentImpl *doc)
0053     : HTMLElementImpl(doc),
0054       m_bgSet(false), m_fgSet(false)
0055 {
0056     m_styleSheet = nullptr;
0057 }
0058 
0059 HTMLBodyElementImpl::~HTMLBodyElementImpl()
0060 {
0061     if (m_styleSheet) {
0062         m_styleSheet->deref();
0063     }
0064 }
0065 
0066 NodeImpl::Id HTMLBodyElementImpl::id() const
0067 {
0068     return ID_BODY;
0069 }
0070 
0071 void HTMLBodyElementImpl::parseAttribute(AttributeImpl *attr)
0072 {
0073     switch (attr->id()) {
0074 
0075     case ATTR_BACKGROUND: {
0076         QString url = attr->value().trimSpaces().string();
0077         if (!url.isEmpty()) {
0078             url = document()->completeURL(url);
0079             addCSSProperty(CSS_PROP_BACKGROUND_IMAGE, DOMString("url('" + url + "')"));
0080             m_bgSet = true;
0081         } else {
0082             removeCSSProperty(CSS_PROP_BACKGROUND_IMAGE);
0083             m_bgSet = false;
0084         }
0085         break;
0086     }
0087     case ATTR_MARGINWIDTH: {
0088         KHTMLView *w = document()->view();
0089         if (w) {
0090             w->setMarginWidth(-1);    // unset this, so it doesn't override the setting here
0091         }
0092         addCSSLength(CSS_PROP_MARGIN_RIGHT, attr->value());
0093     }
0094     /* nobreak; */
0095     case ATTR_LEFTMARGIN:
0096         addCSSLength(CSS_PROP_MARGIN_LEFT, attr->value());
0097         break;
0098     case ATTR_MARGINHEIGHT: {
0099         KHTMLView *w = document()->view();
0100         if (w) {
0101             w->setMarginHeight(-1);    // unset this, so it doesn't override the setting here
0102         }
0103         addCSSLength(CSS_PROP_MARGIN_BOTTOM, attr->value());
0104     }
0105     /* nobreak */
0106     case ATTR_TOPMARGIN:
0107         addCSSLength(CSS_PROP_MARGIN_TOP, attr->value());
0108         break;
0109     case ATTR_BGCOLOR:
0110         addHTMLColor(CSS_PROP_BACKGROUND_COLOR, attr->value());
0111         m_bgSet = !attr->value().isNull();
0112         break;
0113     case ATTR_TEXT:
0114         addHTMLColor(CSS_PROP_COLOR, attr->value());
0115         m_fgSet = !attr->value().isNull();
0116         break;
0117     case ATTR_BGPROPERTIES:
0118         if (strcasecmp(attr->value(), "fixed") == 0) {
0119             addCSSProperty(CSS_PROP_BACKGROUND_ATTACHMENT, CSS_VAL_FIXED);
0120         }
0121         break;
0122     case ATTR_VLINK:
0123     case ATTR_ALINK:
0124     case ATTR_LINK: {
0125         if (!m_styleSheet) {
0126             m_styleSheet = new CSSStyleSheetImpl(this, DOMString(), true /*implicit*/);
0127             m_styleSheet->ref();
0128         }
0129         QString aStr;
0130         if (attr->id() == ATTR_LINK) {
0131             aStr = "a:link";
0132         } else if (attr->id() == ATTR_VLINK) {
0133             aStr = "a:visited";
0134         } else if (attr->id() == ATTR_ALINK) {
0135             aStr = "a:active";
0136         }
0137         aStr += " { color: " + attr->value().string() + "; }";
0138         m_styleSheet->parseString(aStr, false);
0139         if (attached()) {
0140             document()->updateStyleSelector();
0141         }
0142         break;
0143     }
0144     case ATTR_ONLOAD:
0145         document()->setHTMLWindowEventListener(EventImpl::LOAD_EVENT,
0146                                                document()->createHTMLEventListener(attr->value().string(), "onload", nullptr));
0147         break;
0148     case ATTR_ONUNLOAD:
0149         document()->setHTMLWindowEventListener(EventImpl::UNLOAD_EVENT,
0150                                                document()->createHTMLEventListener(attr->value().string(), "onunload", nullptr));
0151         break;
0152     case ATTR_ONBLUR:
0153         document()->setHTMLWindowEventListener(EventImpl::BLUR_EVENT,
0154                                                document()->createHTMLEventListener(attr->value().string(), "onblur", nullptr));
0155         break;
0156     case ATTR_ONFOCUS:
0157         document()->setHTMLWindowEventListener(EventImpl::FOCUS_EVENT,
0158                                                document()->createHTMLEventListener(attr->value().string(), "onfocus", nullptr));
0159         break;
0160     case ATTR_ONRESIZE:
0161         document()->setHTMLWindowEventListener(EventImpl::RESIZE_EVENT,
0162                                                document()->createHTMLEventListener(attr->value().string(), "onresize", nullptr));
0163         break;
0164     case ATTR_ONKEYUP:
0165         document()->setHTMLWindowEventListener(EventImpl::KEYUP_EVENT,
0166                                                document()->createHTMLEventListener(attr->value().string(), "onkeyup", nullptr));
0167         break;
0168     case ATTR_ONKEYDOWN:
0169         document()->setHTMLWindowEventListener(EventImpl::KEYDOWN_EVENT,
0170                                                document()->createHTMLEventListener(attr->value().string(), "onkeydown", nullptr));
0171         break;
0172     case ATTR_ONKEYPRESS:
0173         document()->setHTMLWindowEventListener(EventImpl::KEYPRESS_EVENT,
0174                                                document()->createHTMLEventListener(attr->value().string(), "onkeypress", nullptr));
0175         break;
0176     case ATTR_ONSCROLL:
0177         document()->setHTMLWindowEventListener(EventImpl::SCROLL_EVENT,
0178                                                document()->createHTMLEventListener(attr->value().string(), "onscroll", nullptr));
0179         break;
0180     case ATTR_ONMESSAGE:
0181         document()->setHTMLWindowEventListener(EventImpl::MESSAGE_EVENT,
0182                                                document()->createHTMLEventListener(attr->value().string(), "onmessage", nullptr));
0183         break;
0184     case ATTR_ONHASHCHANGE:
0185         document()->setHTMLWindowEventListener(EventImpl::HASHCHANGE_EVENT,
0186                                                document()->createHTMLEventListener(attr->value().string(), "onhashchange", nullptr));
0187         break;
0188     case ATTR_NOSAVE:
0189         break;
0190     default:
0191         HTMLElementImpl::parseAttribute(attr);
0192     }
0193 }
0194 
0195 void HTMLBodyElementImpl::insertedIntoDocument()
0196 {
0197     HTMLElementImpl::insertedIntoDocument();
0198 
0199     KHTMLView *w = document()->view();
0200     if (w && w->marginWidth() != -1) {
0201         QString s = QStringLiteral("%1").arg(w->marginWidth());
0202         addCSSLength(CSS_PROP_MARGIN_LEFT, s);
0203         addCSSLength(CSS_PROP_MARGIN_RIGHT, s);
0204     }
0205     if (w && w->marginHeight() != -1) {
0206         QString s = QStringLiteral("%1").arg(w->marginHeight());
0207         addCSSLength(CSS_PROP_MARGIN_TOP, s);
0208         addCSSLength(CSS_PROP_MARGIN_BOTTOM, s);
0209     }
0210 
0211     if (m_bgSet && !m_fgSet) {
0212         addCSSProperty(CSS_PROP_COLOR, CSS_VAL_BLACK);
0213     }
0214 
0215     if (m_styleSheet) {
0216         document()->updateStyleSelector();
0217     }
0218 }
0219 
0220 void HTMLBodyElementImpl::removedFromDocument()
0221 {
0222     HTMLElementImpl::removedFromDocument();
0223 
0224     if (m_styleSheet) {
0225         document()->updateStyleSelector();
0226     }
0227 }
0228 
0229 void HTMLBodyElementImpl::attach()
0230 {
0231     assert(!m_render);
0232     assert(parentNode());
0233 
0234     RenderStyle *style = document()->styleSelector()->styleForElement(this);
0235     style->ref();
0236     if (parentNode()->renderer() && parentNode()->renderer()->childAllowed()
0237             && style->display() != NONE) {
0238         if (style->display() == BLOCK)
0239             // only use the quirky class for block display
0240         {
0241             m_render = new(document()->renderArena()) RenderBody(this);
0242         } else {
0243             m_render = RenderObject::createObject(this, style);
0244         }
0245         m_render->setStyle(style);
0246         parentNode()->renderer()->addChild(m_render, nextRenderer());
0247     }
0248     style->deref();
0249 
0250     NodeBaseImpl::attach();
0251 }
0252 
0253 // -------------------------------------------------------------------------
0254 
0255 HTMLFrameElementImpl::HTMLFrameElementImpl(DocumentImpl *doc)
0256     : HTMLPartContainerElementImpl(doc)
0257 {
0258     frameBorder = true;
0259     frameBorderSet = false;
0260     marginWidth = -1;
0261     marginHeight = -1;
0262     scrolling = Qt::ScrollBarAsNeeded;
0263     noresize = false;
0264     url = QLatin1String("about:blank");
0265 }
0266 
0267 HTMLFrameElementImpl::~HTMLFrameElementImpl()
0268 {
0269 }
0270 
0271 NodeImpl::Id HTMLFrameElementImpl::id() const
0272 {
0273     return ID_FRAME;
0274 }
0275 
0276 void HTMLFrameElementImpl::ensureUniqueName()
0277 {
0278     // If we already have a name, don't do anything.
0279     if (!name.isEmpty()) {
0280         return;
0281     }
0282 
0283     // Use the specified name first..
0284     name = getAttribute(ATTR_NAME);
0285     if (name.isNull()) {
0286         name = getAttribute(ATTR_ID);
0287     }
0288 
0289     // Generate synthetic name if there isn't a natural one or
0290     // if the natural one conflicts
0291     KHTMLPart *parentPart = document()->part();
0292 
0293     // If there is no part, we will not load anything, so no
0294     // worry about names being unique or not.
0295     if (!parentPart) {
0296         return;
0297     }
0298 
0299     KHTMLPart *otherFrame = parentPart->findFrame(name.string());
0300     if (name.isEmpty() || (otherFrame && otherFrame != contentPart())) {
0301         name = DOMString(parentPart->requestFrameName());
0302     }
0303 
0304     // Make sure we're registered properly.
0305     parentPart->d->renameFrameForContainer(this, name.string());
0306 }
0307 
0308 void HTMLFrameElementImpl::defaultEventHandler(EventImpl *e)
0309 {
0310     // ### duplicated in HTMLObjectBaseElementImpl
0311     if (e->target() == this && m_render && m_render->isWidget()
0312             && static_cast<RenderWidget *>(m_render)->isRedirectedWidget()
0313             && qobject_cast<KHTMLView *>(static_cast<RenderWidget *>(m_render)->widget())) {
0314         switch (e->id())  {
0315         case EventImpl::MOUSEDOWN_EVENT:
0316         case EventImpl::MOUSEUP_EVENT:
0317         case EventImpl::MOUSEMOVE_EVENT:
0318         case EventImpl::MOUSEOUT_EVENT:
0319         case EventImpl::MOUSEOVER_EVENT:
0320         case EventImpl::KHTML_MOUSEWHEEL_EVENT:
0321         case EventImpl::KEYDOWN_EVENT:
0322         case EventImpl::KEYUP_EVENT:
0323         case EventImpl::KEYPRESS_EVENT:
0324         case EventImpl::DOMFOCUSIN_EVENT:
0325         case EventImpl::DOMFOCUSOUT_EVENT:
0326             if (static_cast<RenderWidget *>(m_render)->handleEvent(*e)) {
0327                 e->setDefaultHandled();
0328             }
0329         default:
0330             break;
0331         }
0332     }
0333     HTMLPartContainerElementImpl::defaultEventHandler(e);
0334 }
0335 
0336 void HTMLFrameElementImpl::parseAttribute(AttributeImpl *attr)
0337 {
0338     switch (attr->id()) {
0339     case ATTR_SRC:
0340         setLocation(attr->value().trimSpaces().string());
0341         break;
0342     case ATTR_FRAMEBORDER: {
0343         frameBorder = attr->value().toInt();
0344         frameBorderSet = (attr->val() != nullptr);
0345         // FIXME: when attached, has no effect
0346     }
0347     break;
0348     case ATTR_MARGINWIDTH:
0349         marginWidth = attr->val()->toInt();
0350         // FIXME: when attached, has no effect
0351         break;
0352     case ATTR_MARGINHEIGHT:
0353         marginHeight = attr->val()->toInt();
0354         // FIXME: when attached, has no effect
0355         break;
0356     case ATTR_NORESIZE:
0357         noresize = true;
0358         // FIXME: when attached, has no effect
0359         break;
0360     case ATTR_SCROLLING:
0361         if (strcasecmp(attr->value(), "auto") == 0) {
0362             scrolling = Qt::ScrollBarAsNeeded;
0363         } else if (strcasecmp(attr->value(), "yes") == 0) {
0364             scrolling = Qt::ScrollBarAlwaysOn;
0365         } else if (strcasecmp(attr->value(), "no") == 0) {
0366             scrolling = Qt::ScrollBarAlwaysOff;
0367         }
0368         // when attached, has no effect
0369         break;
0370     case ATTR_ONLOAD:
0371         setHTMLEventListener(EventImpl::LOAD_EVENT,
0372                              document()->createHTMLEventListener(attr->value().string(), "onload", this));
0373         break;
0374     case ATTR_ONUNLOAD:
0375         setHTMLEventListener(EventImpl::UNLOAD_EVENT,
0376                              document()->createHTMLEventListener(attr->value().string(), "onunload", this));
0377         break;
0378     default:
0379         HTMLElementImpl::parseAttribute(attr);
0380     }
0381 }
0382 
0383 void HTMLFrameElementImpl::attach()
0384 {
0385     assert(!attached());
0386     assert(parentNode());
0387 
0388     computeContentIfNeeded();
0389 
0390     // inherit default settings from parent frameset
0391     HTMLElementImpl *node = static_cast<HTMLElementImpl *>(parentNode());
0392     while (node) {
0393         if (node->id() == ID_FRAMESET) {
0394             HTMLFrameSetElementImpl *frameset = static_cast<HTMLFrameSetElementImpl *>(node);
0395             if (!frameBorderSet) {
0396                 frameBorder = frameset->frameBorder();
0397             }
0398             if (!noresize) {
0399                 noresize = frameset->noResize();
0400             }
0401             break;
0402         }
0403         node = static_cast<HTMLElementImpl *>(node->parentNode());
0404     }
0405 
0406     if (parentNode()->renderer() && parentNode()->renderer()->childAllowed()
0407             && document()->isURLAllowed(url))  {
0408         RenderStyle *_style = document()->styleSelector()->styleForElement(this);
0409         _style->ref();
0410         if (_style->display() != NONE) {
0411             m_render = new(document()->renderArena()) RenderFrame(this);
0412             m_render->setStyle(_style);
0413             parentNode()->renderer()->addChild(m_render, nextRenderer());
0414         }
0415         _style->deref();
0416     }
0417 
0418     // If we already have a widget, set it.
0419     if (m_render && childWidget()) {
0420         static_cast<RenderFrame *>(m_render)->setWidget(childWidget());
0421     }
0422 
0423     NodeBaseImpl::attach();
0424 }
0425 
0426 void HTMLFrameElementImpl::setWidgetNotify(QWidget *widget)
0427 {
0428     if (m_render) {
0429         static_cast<RenderFrame *>(m_render)->setWidget(widget);
0430     }
0431 }
0432 
0433 void HTMLFrameElementImpl::computeContent()
0434 {
0435     KHTMLPart *parentPart = document()->part();
0436 
0437     if (!parentPart) {
0438         return;
0439     }
0440 
0441     // Bail out on any disallowed URLs
0442     if (!document()->isURLAllowed(url)) {
0443         return;
0444     }
0445 
0446     // If we have a part already, make sure it's in the right spot...
0447     // (can happen if someone asks to change location while we're in process
0448     // of loading the original one)
0449     if (contentPart()) {
0450         setLocation(url);
0451         return;
0452     }
0453 
0454     ensureUniqueName();
0455 
0456     // Go ahead and load a part... We don't need to clear the widget here,
0457     // since the -frames- have their lifetime managed, using the name uniqueness.
0458     parentPart->loadFrameElement(this, url, name.string());
0459 }
0460 
0461 void HTMLFrameElementImpl::setLocation(const QString &str)
0462 {
0463     url = str;
0464 
0465     if (!document()->isURLAllowed(url)) {
0466         return;
0467     }
0468 
0469     // if we already have a child part, ask it to go there..
0470     KHTMLPart *childPart = contentPart();
0471     if (childPart) {
0472         childPart->openUrl(QUrl(document()->completeURL(url)));
0473     } else {
0474         setNeedComputeContent();    // otherwise, request it..
0475     }
0476 }
0477 
0478 bool HTMLFrameElementImpl::isFocusableImpl(FocusType ft) const
0479 {
0480     if (m_render != nullptr) {
0481         return true;
0482     }
0483     return HTMLPartContainerElementImpl::isFocusableImpl(ft);
0484 }
0485 
0486 void HTMLFrameElementImpl::setFocus(bool received)
0487 {
0488     HTMLElementImpl::setFocus(received);
0489     khtml::RenderFrame *renderFrame = static_cast<khtml::RenderFrame *>(m_render);
0490     if (!renderFrame || !renderFrame->widget()) {
0491         return;
0492     }
0493     if (received) {
0494         renderFrame->widget()->setFocus();
0495     } else {
0496         renderFrame->widget()->clearFocus();
0497     }
0498 }
0499 
0500 DocumentImpl *HTMLFrameElementImpl::contentDocument() const
0501 {
0502     if (!childWidget()) {
0503         return nullptr;
0504     }
0505 
0506     if (::qobject_cast<KHTMLView *>(childWidget())) {
0507         return static_cast<KHTMLView *>(childWidget())->part()->xmlDocImpl();
0508     }
0509 
0510     return nullptr;
0511 }
0512 
0513 KHTMLPart   *HTMLFrameElementImpl::contentPart() const
0514 {
0515     if (!childWidget()) {
0516         return nullptr;
0517     }
0518 
0519     if (::qobject_cast<KHTMLView *>(childWidget())) {
0520         return static_cast<KHTMLView *>(childWidget())->part();
0521     }
0522 
0523     return nullptr;
0524 }
0525 
0526 // -------------------------------------------------------------------------
0527 
0528 DOMString HTMLBodyElementImpl::aLink() const
0529 {
0530     return getAttribute(ATTR_ALINK);
0531 }
0532 
0533 void HTMLBodyElementImpl::setALink(const DOMString &value)
0534 {
0535     setAttribute(ATTR_ALINK, value);
0536 }
0537 
0538 DOMString HTMLBodyElementImpl::bgColor() const
0539 {
0540     return getAttribute(ATTR_BGCOLOR);
0541 }
0542 
0543 void HTMLBodyElementImpl::setBgColor(const DOMString &value)
0544 {
0545     setAttribute(ATTR_BGCOLOR, value);
0546 }
0547 
0548 DOMString HTMLBodyElementImpl::link() const
0549 {
0550     return getAttribute(ATTR_LINK);
0551 }
0552 
0553 void HTMLBodyElementImpl::setLink(const DOMString &value)
0554 {
0555     setAttribute(ATTR_LINK, value);
0556 }
0557 
0558 DOMString HTMLBodyElementImpl::text() const
0559 {
0560     return getAttribute(ATTR_TEXT);
0561 }
0562 
0563 void HTMLBodyElementImpl::setText(const DOMString &value)
0564 {
0565     setAttribute(ATTR_TEXT, value);
0566 }
0567 
0568 DOMString HTMLBodyElementImpl::vLink() const
0569 {
0570     return getAttribute(ATTR_VLINK);
0571 }
0572 
0573 void HTMLBodyElementImpl::setVLink(const DOMString &value)
0574 {
0575     setAttribute(ATTR_VLINK, value);
0576 }
0577 
0578 // -------------------------------------------------------------------------
0579 
0580 HTMLFrameSetElementImpl::HTMLFrameSetElementImpl(DocumentImpl *doc)
0581     : HTMLElementImpl(doc)
0582 {
0583     // default value for rows and cols...
0584     m_totalRows = 1;
0585     m_totalCols = 1;
0586 
0587     m_rows = m_cols = nullptr;
0588 
0589     frameborder = true;
0590     frameBorderSet = false;
0591     m_border = 4;
0592     noresize = false;
0593 
0594     m_resizing = false;
0595 }
0596 
0597 HTMLFrameSetElementImpl::~HTMLFrameSetElementImpl()
0598 {
0599     delete [] m_rows;
0600     delete [] m_cols;
0601 }
0602 
0603 NodeImpl::Id HTMLFrameSetElementImpl::id() const
0604 {
0605     return ID_FRAMESET;
0606 }
0607 
0608 void HTMLFrameSetElementImpl::parseAttribute(AttributeImpl *attr)
0609 {
0610     switch (attr->id()) {
0611     case ATTR_ROWS:
0612         if (!attr->val()) {
0613             break;
0614         }
0615         delete [] m_rows;
0616         m_rows = attr->val()->toLengthArray(m_totalRows);
0617         setChanged();
0618         break;
0619     case ATTR_COLS:
0620         if (!attr->val()) {
0621             break;
0622         }
0623         delete [] m_cols;
0624         m_cols = attr->val()->toLengthArray(m_totalCols);
0625         setChanged();
0626         break;
0627     case ATTR_FRAMEBORDER:
0628         // false or "no" or "0"..
0629         if (attr->value().toInt() == 0) {
0630             frameborder = false;
0631             m_border = 0;
0632         }
0633         frameBorderSet = true;
0634         break;
0635     case ATTR_NORESIZE:
0636         noresize = true;
0637         break;
0638     case ATTR_BORDER:
0639         m_border = attr->val()->toInt();
0640         if (!m_border) {
0641             frameborder = false;
0642         }
0643         break;
0644     case ATTR_ONLOAD:
0645         document()->setHTMLWindowEventListener(EventImpl::LOAD_EVENT,
0646                                                document()->createHTMLEventListener(attr->value().string(), "onload", nullptr));
0647         break;
0648     case ATTR_ONUNLOAD:
0649         document()->setHTMLWindowEventListener(EventImpl::UNLOAD_EVENT,
0650                                                document()->createHTMLEventListener(attr->value().string(), "onunload", nullptr));
0651         break;
0652     case ATTR_ONMESSAGE:
0653         document()->setHTMLWindowEventListener(EventImpl::MESSAGE_EVENT,
0654                                                document()->createHTMLEventListener(attr->value().string(), "onmessage", nullptr));
0655         break;
0656     default:
0657         HTMLElementImpl::parseAttribute(attr);
0658     }
0659 }
0660 
0661 void HTMLFrameSetElementImpl::attach()
0662 {
0663     assert(!attached());
0664     assert(parentNode());
0665 
0666     // inherit default settings from parent frameset
0667     HTMLElementImpl *node = static_cast<HTMLElementImpl *>(parentNode());
0668     while (node) {
0669         if (node->id() == ID_FRAMESET) {
0670             HTMLFrameSetElementImpl *frameset = static_cast<HTMLFrameSetElementImpl *>(node);
0671             if (!frameBorderSet) {
0672                 frameborder = frameset->frameBorder();
0673             }
0674             if (!noresize) {
0675                 noresize = frameset->noResize();
0676             }
0677             break;
0678         }
0679         node = static_cast<HTMLElementImpl *>(node->parentNode());
0680     }
0681 
0682     RenderStyle *_style = document()->styleSelector()->styleForElement(this);
0683     _style->ref();
0684     // ignore display: none
0685     if (parentNode()->renderer() && parentNode()->renderer()->childAllowed()) {
0686         m_render = new(document()->renderArena()) RenderFrameSet(this);
0687         m_render->setStyle(_style);
0688         parentNode()->renderer()->addChild(m_render, nextRenderer());
0689     }
0690     _style->deref();
0691 
0692     NodeBaseImpl::attach();
0693 }
0694 
0695 void HTMLFrameSetElementImpl::defaultEventHandler(EventImpl *evt)
0696 {
0697     if (evt->isMouseEvent() && !noresize && m_render) {
0698         static_cast<khtml::RenderFrameSet *>(m_render)->userResize(static_cast<MouseEventImpl *>(evt));
0699     }
0700 
0701     evt->setDefaultHandled();
0702     HTMLElementImpl::defaultEventHandler(evt);
0703 }
0704 
0705 void HTMLFrameSetElementImpl::detach()
0706 {
0707     if (attached())
0708         // ### send the event when we actually get removed from the doc instead of here
0709     {
0710         document()->dispatchHTMLEvent(EventImpl::UNLOAD_EVENT, false, false);
0711     }
0712 
0713     HTMLElementImpl::detach();
0714 }
0715 
0716 void HTMLFrameSetElementImpl::recalcStyle(StyleChange ch)
0717 {
0718     if (changed() && m_render) {
0719         m_render->setNeedsLayout(true);
0720 //         m_render->layout();
0721         setChanged(false);
0722     }
0723     HTMLElementImpl::recalcStyle(ch);
0724 }
0725 
0726 // -------------------------------------------------------------------------
0727 
0728 NodeImpl::Id HTMLHeadElementImpl::id() const
0729 {
0730     return ID_HEAD;
0731 }
0732 
0733 // -------------------------------------------------------------------------
0734 
0735 NodeImpl::Id HTMLHtmlElementImpl::id() const
0736 {
0737     return ID_HTML;
0738 }
0739 
0740 // -------------------------------------------------------------------------
0741 
0742 HTMLIFrameElementImpl::HTMLIFrameElementImpl(DocumentImpl *doc) : HTMLFrameElementImpl(doc)
0743 {
0744     frameBorder = false;
0745     marginWidth = 0;
0746     marginHeight = 0;
0747     m_frame = true;
0748 }
0749 
0750 void HTMLIFrameElementImpl::insertedIntoDocument()
0751 {
0752     HTMLFrameElementImpl::insertedIntoDocument();
0753 
0754     assert(!contentPart());
0755     setNeedComputeContent();
0756     computeContentIfNeeded(); // also clears
0757 }
0758 
0759 void HTMLIFrameElementImpl::removedFromDocument()
0760 {
0761     HTMLFrameElementImpl::removedFromDocument();
0762     clearChildWidget();
0763 }
0764 
0765 HTMLIFrameElementImpl::~HTMLIFrameElementImpl()
0766 {
0767 }
0768 
0769 NodeImpl::Id HTMLIFrameElementImpl::id() const
0770 {
0771     return ID_IFRAME;
0772 }
0773 
0774 void HTMLIFrameElementImpl::parseAttribute(AttributeImpl *attr)
0775 {
0776     switch (attr->id()) {
0777     case ATTR_WIDTH:
0778         if (!attr->value().isEmpty()) {
0779             addCSSLength(CSS_PROP_WIDTH, attr->value());
0780         } else {
0781             removeCSSProperty(CSS_PROP_WIDTH);
0782         }
0783         break;
0784     case ATTR_HEIGHT:
0785         if (!attr->value().isEmpty()) {
0786             addCSSLength(CSS_PROP_HEIGHT, attr->value());
0787         } else {
0788             removeCSSProperty(CSS_PROP_HEIGHT);
0789         }
0790         break;
0791     case ATTR_ALIGN:
0792         addHTMLAlignment(attr->value());
0793         break;
0794     case ATTR_SRC:
0795         url = attr->value().trimSpaces().string();
0796         setNeedComputeContent();
0797         // ### synchronously start the process?
0798         break;
0799     case ATTR_NAME:
0800         ensureUniqueName();
0801         break;
0802     case ATTR_ID:
0803         HTMLFrameElementImpl::parseAttribute(attr);   // want default ID handling
0804         ensureUniqueName();
0805         break;
0806     case ATTR_FRAMEBORDER: {
0807         m_frame = (!attr->val() || attr->value().toInt() > 0);
0808         if (attached()) {
0809             updateFrame();
0810         }
0811         break;
0812     }
0813     default:
0814         HTMLFrameElementImpl::parseAttribute(attr);
0815     }
0816 }
0817 
0818 void HTMLIFrameElementImpl::updateFrame()
0819 {
0820     if (m_frame) {
0821         addCSSProperty(CSS_PROP_BORDER_TOP_STYLE, CSS_VAL_OUTSET);
0822         addCSSProperty(CSS_PROP_BORDER_BOTTOM_STYLE, CSS_VAL_OUTSET);
0823         addCSSProperty(CSS_PROP_BORDER_LEFT_STYLE, CSS_VAL_OUTSET);
0824         addCSSProperty(CSS_PROP_BORDER_RIGHT_STYLE, CSS_VAL_OUTSET);
0825         addCSSLength(CSS_PROP_BORDER_WIDTH, "2");
0826     } else {
0827         addCSSProperty(CSS_PROP_BORDER_TOP_STYLE, CSS_VAL_NONE);
0828         addCSSProperty(CSS_PROP_BORDER_BOTTOM_STYLE, CSS_VAL_NONE);
0829         addCSSProperty(CSS_PROP_BORDER_LEFT_STYLE, CSS_VAL_NONE);
0830         addCSSProperty(CSS_PROP_BORDER_RIGHT_STYLE, CSS_VAL_NONE);
0831         removeCSSProperty(CSS_PROP_BORDER_WIDTH);
0832     }
0833 
0834 }
0835 
0836 void HTMLIFrameElementImpl::attach()
0837 {
0838     assert(!attached());
0839     assert(!m_render);
0840     assert(parentNode());
0841 
0842     updateFrame();
0843 
0844     RenderStyle *style = document()->styleSelector()->styleForElement(this);
0845     style->ref();
0846     if (document()->isURLAllowed(url) && parentNode()->renderer()
0847             && parentNode()->renderer()->childAllowed() && style->display() != NONE) {
0848         m_render = new(document()->renderArena()) RenderPartObject(this);
0849         m_render->setStyle(style);
0850         parentNode()->renderer()->addChild(m_render, nextRenderer());
0851     }
0852     style->deref();
0853 
0854     NodeBaseImpl::attach();
0855 
0856     if (m_render && childWidget()) {
0857         static_cast<RenderPartObject *>(m_render)->setWidget(childWidget());
0858     }
0859 }
0860 
0861 void HTMLIFrameElementImpl::computeContent()
0862 {
0863     KHTMLPart *parentPart = document()->part();
0864 
0865     if (!parentPart) {
0866         return;
0867     }
0868 
0869     if (!document()->isURLAllowed(url)) {
0870         return;
0871     }
0872 
0873     if (!inDocument()) {
0874         clearChildWidget();
0875         return;
0876     }
0877 
0878     // get our name in order..
0879     ensureUniqueName();
0880 
0881     // make sure "" is handled as about: blank
0882     const QString aboutBlank = QLatin1String("about:blank");
0883     QString effectiveURL = url;
0884     if (effectiveURL.isEmpty()) {
0885         effectiveURL = aboutBlank;
0886     }
0887 
0888     // qCDebug(KHTML_LOG) << "-> requesting:" << name.string() << effectiveURL << contentPart();
0889 
0890     parentPart->loadFrameElement(this, effectiveURL, name.string(), QStringList(), true);
0891 }
0892 
0893 void HTMLIFrameElementImpl::setWidgetNotify(QWidget *widget)
0894 {
0895     if (m_render) {
0896         static_cast<RenderPartObject *>(m_render)->setWidget(widget);
0897     }
0898 }
0899