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