KHtml

html_baseimpl.cpp
1 /**
2  * This file is part of the DOM implementation for KDE.
3  *
4  * Copyright (C) 1999 Lars Knoll ([email protected])
5  * (C) 1999 Antti Koivisto ([email protected])
6  * (C) 2000 Simon Hausmann ([email protected])
7  * (C) 2001-2003 Dirk Mueller ([email protected])
8  *
9  * This library is free software; you can redistribute it and/or
10  * modify it under the terms of the GNU Library General Public
11  * License as published by the Free Software Foundation; either
12  * version 2 of the License, or (at your option) any later version.
13  *
14  * This library is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17  * Library General Public License for more details.
18  *
19  * You should have received a copy of the GNU Library General Public License
20  * along with this library; see the file COPYING.LIB. If not, write to
21  * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
22  * Boston, MA 02110-1301, USA.
23  */
24 // -------------------------------------------------------------------------
25 
26 #include "html/html_baseimpl.h"
27 #include "html/html_documentimpl.h"
28 
29 #include "khtmlview.h"
30 #include "khtml_part.h"
31 #include "khtmlpart_p.h"
32 
33 #include "rendering/render_frames.h"
34 #include "rendering/render_body.h"
35 #include "css/cssstyleselector.h"
36 #include "css/css_stylesheetimpl.h"
37 #include "css/cssproperties.h"
38 #include "css/cssvalues.h"
39 #include "misc/loader.h"
40 #include "dom/dom_string.h"
41 #include "dom/dom_doc.h"
42 #include "xml/dom2_eventsimpl.h"
43 
44 #include <QUrl>
45 #include "khtml_debug.h"
46 
47 #undef FOCUS_EVENT // for win32, MinGW
48 
49 using namespace DOM;
50 using namespace khtml;
51 
52 HTMLBodyElementImpl::HTMLBodyElementImpl(DocumentImpl *doc)
53  : HTMLElementImpl(doc),
54  m_bgSet(false), m_fgSet(false)
55 {
56  m_styleSheet = nullptr;
57 }
58 
59 HTMLBodyElementImpl::~HTMLBodyElementImpl()
60 {
61  if (m_styleSheet) {
62  m_styleSheet->deref();
63  }
64 }
65 
66 NodeImpl::Id HTMLBodyElementImpl::id() const
67 {
68  return ID_BODY;
69 }
70 
71 void HTMLBodyElementImpl::parseAttribute(AttributeImpl *attr)
72 {
73  switch (attr->id()) {
74 
75  case ATTR_BACKGROUND: {
76  QString url = attr->value().trimSpaces().string();
77  if (!url.isEmpty()) {
78  url = document()->completeURL(url);
79  addCSSProperty(CSS_PROP_BACKGROUND_IMAGE, DOMString("url('" + url + "')"));
80  m_bgSet = true;
81  } else {
82  removeCSSProperty(CSS_PROP_BACKGROUND_IMAGE);
83  m_bgSet = false;
84  }
85  break;
86  }
87  case ATTR_MARGINWIDTH: {
88  KHTMLView *w = document()->view();
89  if (w) {
90  w->setMarginWidth(-1); // unset this, so it doesn't override the setting here
91  }
92  addCSSLength(CSS_PROP_MARGIN_RIGHT, attr->value());
93  }
94  /* nobreak; */
95  case ATTR_LEFTMARGIN:
96  addCSSLength(CSS_PROP_MARGIN_LEFT, attr->value());
97  break;
98  case ATTR_MARGINHEIGHT: {
99  KHTMLView *w = document()->view();
100  if (w) {
101  w->setMarginHeight(-1); // unset this, so it doesn't override the setting here
102  }
103  addCSSLength(CSS_PROP_MARGIN_BOTTOM, attr->value());
104  }
105  /* nobreak */
106  case ATTR_TOPMARGIN:
107  addCSSLength(CSS_PROP_MARGIN_TOP, attr->value());
108  break;
109  case ATTR_BGCOLOR:
110  addHTMLColor(CSS_PROP_BACKGROUND_COLOR, attr->value());
111  m_bgSet = !attr->value().isNull();
112  break;
113  case ATTR_TEXT:
114  addHTMLColor(CSS_PROP_COLOR, attr->value());
115  m_fgSet = !attr->value().isNull();
116  break;
117  case ATTR_BGPROPERTIES:
118  if (strcasecmp(attr->value(), "fixed") == 0) {
119  addCSSProperty(CSS_PROP_BACKGROUND_ATTACHMENT, CSS_VAL_FIXED);
120  }
121  break;
122  case ATTR_VLINK:
123  case ATTR_ALINK:
124  case ATTR_LINK: {
125  if (!m_styleSheet) {
126  m_styleSheet = new CSSStyleSheetImpl(this, DOMString(), true /*implicit*/);
127  m_styleSheet->ref();
128  }
129  QString aStr;
130  if (attr->id() == ATTR_LINK) {
131  aStr = "a:link";
132  } else if (attr->id() == ATTR_VLINK) {
133  aStr = "a:visited";
134  } else if (attr->id() == ATTR_ALINK) {
135  aStr = "a:active";
136  }
137  aStr += " { color: " + attr->value().string() + "; }";
138  m_styleSheet->parseString(aStr, false);
139  if (attached()) {
140  document()->updateStyleSelector();
141  }
142  break;
143  }
144  case ATTR_ONLOAD:
145  document()->setHTMLWindowEventListener(EventImpl::LOAD_EVENT,
146  document()->createHTMLEventListener(attr->value().string(), "onload", nullptr));
147  break;
148  case ATTR_ONUNLOAD:
149  document()->setHTMLWindowEventListener(EventImpl::UNLOAD_EVENT,
150  document()->createHTMLEventListener(attr->value().string(), "onunload", nullptr));
151  break;
152  case ATTR_ONBLUR:
153  document()->setHTMLWindowEventListener(EventImpl::BLUR_EVENT,
154  document()->createHTMLEventListener(attr->value().string(), "onblur", nullptr));
155  break;
156  case ATTR_ONFOCUS:
157  document()->setHTMLWindowEventListener(EventImpl::FOCUS_EVENT,
158  document()->createHTMLEventListener(attr->value().string(), "onfocus", nullptr));
159  break;
160  case ATTR_ONRESIZE:
161  document()->setHTMLWindowEventListener(EventImpl::RESIZE_EVENT,
162  document()->createHTMLEventListener(attr->value().string(), "onresize", nullptr));
163  break;
164  case ATTR_ONKEYUP:
165  document()->setHTMLWindowEventListener(EventImpl::KEYUP_EVENT,
166  document()->createHTMLEventListener(attr->value().string(), "onkeyup", nullptr));
167  break;
168  case ATTR_ONKEYDOWN:
169  document()->setHTMLWindowEventListener(EventImpl::KEYDOWN_EVENT,
170  document()->createHTMLEventListener(attr->value().string(), "onkeydown", nullptr));
171  break;
172  case ATTR_ONKEYPRESS:
173  document()->setHTMLWindowEventListener(EventImpl::KEYPRESS_EVENT,
174  document()->createHTMLEventListener(attr->value().string(), "onkeypress", nullptr));
175  break;
176  case ATTR_ONSCROLL:
177  document()->setHTMLWindowEventListener(EventImpl::SCROLL_EVENT,
178  document()->createHTMLEventListener(attr->value().string(), "onscroll", nullptr));
179  break;
180  case ATTR_ONMESSAGE:
181  document()->setHTMLWindowEventListener(EventImpl::MESSAGE_EVENT,
182  document()->createHTMLEventListener(attr->value().string(), "onmessage", nullptr));
183  break;
184  case ATTR_ONHASHCHANGE:
185  document()->setHTMLWindowEventListener(EventImpl::HASHCHANGE_EVENT,
186  document()->createHTMLEventListener(attr->value().string(), "onhashchange", nullptr));
187  break;
188  case ATTR_NOSAVE:
189  break;
190  default:
191  HTMLElementImpl::parseAttribute(attr);
192  }
193 }
194 
195 void HTMLBodyElementImpl::insertedIntoDocument()
196 {
197  HTMLElementImpl::insertedIntoDocument();
198 
199  KHTMLView *w = document()->view();
200  if (w && w->marginWidth() != -1) {
201  QString s = QStringLiteral("%1").arg(w->marginWidth());
202  addCSSLength(CSS_PROP_MARGIN_LEFT, s);
203  addCSSLength(CSS_PROP_MARGIN_RIGHT, s);
204  }
205  if (w && w->marginHeight() != -1) {
206  QString s = QStringLiteral("%1").arg(w->marginHeight());
207  addCSSLength(CSS_PROP_MARGIN_TOP, s);
208  addCSSLength(CSS_PROP_MARGIN_BOTTOM, s);
209  }
210 
211  if (m_bgSet && !m_fgSet) {
212  addCSSProperty(CSS_PROP_COLOR, CSS_VAL_BLACK);
213  }
214 
215  if (m_styleSheet) {
216  document()->updateStyleSelector();
217  }
218 }
219 
220 void HTMLBodyElementImpl::removedFromDocument()
221 {
222  HTMLElementImpl::removedFromDocument();
223 
224  if (m_styleSheet) {
225  document()->updateStyleSelector();
226  }
227 }
228 
229 void HTMLBodyElementImpl::attach()
230 {
231  assert(!m_render);
232  assert(parentNode());
233 
234  RenderStyle *style = document()->styleSelector()->styleForElement(this);
235  style->ref();
236  if (parentNode()->renderer() && parentNode()->renderer()->childAllowed()
237  && style->display() != NONE) {
238  if (style->display() == BLOCK)
239  // only use the quirky class for block display
240  {
241  m_render = new(document()->renderArena()) RenderBody(this);
242  } else {
243  m_render = RenderObject::createObject(this, style);
244  }
245  m_render->setStyle(style);
246  parentNode()->renderer()->addChild(m_render, nextRenderer());
247  }
248  style->deref();
249 
250  NodeBaseImpl::attach();
251 }
252 
253 // -------------------------------------------------------------------------
254 
255 HTMLFrameElementImpl::HTMLFrameElementImpl(DocumentImpl *doc)
256  : HTMLPartContainerElementImpl(doc)
257 {
258  frameBorder = true;
259  frameBorderSet = false;
260  marginWidth = -1;
261  marginHeight = -1;
262  scrolling = Qt::ScrollBarAsNeeded;
263  noresize = false;
264  url = QLatin1String("about:blank");
265 }
266 
267 HTMLFrameElementImpl::~HTMLFrameElementImpl()
268 {
269 }
270 
271 NodeImpl::Id HTMLFrameElementImpl::id() const
272 {
273  return ID_FRAME;
274 }
275 
276 void HTMLFrameElementImpl::ensureUniqueName()
277 {
278  // If we already have a name, don't do anything.
279  if (!name.isEmpty()) {
280  return;
281  }
282 
283  // Use the specified name first..
284  name = getAttribute(ATTR_NAME);
285  if (name.isNull()) {
286  name = getAttribute(ATTR_ID);
287  }
288 
289  // Generate synthetic name if there isn't a natural one or
290  // if the natural one conflicts
291  KHTMLPart *parentPart = document()->part();
292 
293  // If there is no part, we will not load anything, so no
294  // worry about names being unique or not.
295  if (!parentPart) {
296  return;
297  }
298 
299  KHTMLPart *otherFrame = parentPart->findFrame(name.string());
300  if (name.isEmpty() || (otherFrame && otherFrame != contentPart())) {
301  name = DOMString(parentPart->requestFrameName());
302  }
303 
304  // Make sure we're registered properly.
305  parentPart->d->renameFrameForContainer(this, name.string());
306 }
307 
308 void HTMLFrameElementImpl::defaultEventHandler(EventImpl *e)
309 {
310  // ### duplicated in HTMLObjectBaseElementImpl
311  if (e->target() == this && m_render && m_render->isWidget()
312  && static_cast<RenderWidget *>(m_render)->isRedirectedWidget()
313  && qobject_cast<KHTMLView *>(static_cast<RenderWidget *>(m_render)->widget())) {
314  switch (e->id()) {
315  case EventImpl::MOUSEDOWN_EVENT:
316  case EventImpl::MOUSEUP_EVENT:
317  case EventImpl::MOUSEMOVE_EVENT:
318  case EventImpl::MOUSEOUT_EVENT:
319  case EventImpl::MOUSEOVER_EVENT:
320  case EventImpl::KHTML_MOUSEWHEEL_EVENT:
321  case EventImpl::KEYDOWN_EVENT:
322  case EventImpl::KEYUP_EVENT:
323  case EventImpl::KEYPRESS_EVENT:
324  case EventImpl::DOMFOCUSIN_EVENT:
325  case EventImpl::DOMFOCUSOUT_EVENT:
326  if (static_cast<RenderWidget *>(m_render)->handleEvent(*e)) {
327  e->setDefaultHandled();
328  }
329  default:
330  break;
331  }
332  }
333  HTMLPartContainerElementImpl::defaultEventHandler(e);
334 }
335 
336 void HTMLFrameElementImpl::parseAttribute(AttributeImpl *attr)
337 {
338  switch (attr->id()) {
339  case ATTR_SRC:
340  setLocation(attr->value().trimSpaces().string());
341  break;
342  case ATTR_FRAMEBORDER: {
343  frameBorder = attr->value().toInt();
344  frameBorderSet = (attr->val() != nullptr);
345  // FIXME: when attached, has no effect
346  }
347  break;
348  case ATTR_MARGINWIDTH:
349  marginWidth = attr->val()->toInt();
350  // FIXME: when attached, has no effect
351  break;
352  case ATTR_MARGINHEIGHT:
353  marginHeight = attr->val()->toInt();
354  // FIXME: when attached, has no effect
355  break;
356  case ATTR_NORESIZE:
357  noresize = true;
358  // FIXME: when attached, has no effect
359  break;
360  case ATTR_SCROLLING:
361  if (strcasecmp(attr->value(), "auto") == 0) {
362  scrolling = Qt::ScrollBarAsNeeded;
363  } else if (strcasecmp(attr->value(), "yes") == 0) {
364  scrolling = Qt::ScrollBarAlwaysOn;
365  } else if (strcasecmp(attr->value(), "no") == 0) {
366  scrolling = Qt::ScrollBarAlwaysOff;
367  }
368  // when attached, has no effect
369  break;
370  case ATTR_ONLOAD:
371  setHTMLEventListener(EventImpl::LOAD_EVENT,
372  document()->createHTMLEventListener(attr->value().string(), "onload", this));
373  break;
374  case ATTR_ONUNLOAD:
375  setHTMLEventListener(EventImpl::UNLOAD_EVENT,
376  document()->createHTMLEventListener(attr->value().string(), "onunload", this));
377  break;
378  default:
379  HTMLElementImpl::parseAttribute(attr);
380  }
381 }
382 
383 void HTMLFrameElementImpl::attach()
384 {
385  assert(!attached());
386  assert(parentNode());
387 
388  computeContentIfNeeded();
389 
390  // inherit default settings from parent frameset
391  HTMLElementImpl *node = static_cast<HTMLElementImpl *>(parentNode());
392  while (node) {
393  if (node->id() == ID_FRAMESET) {
394  HTMLFrameSetElementImpl *frameset = static_cast<HTMLFrameSetElementImpl *>(node);
395  if (!frameBorderSet) {
396  frameBorder = frameset->frameBorder();
397  }
398  if (!noresize) {
399  noresize = frameset->noResize();
400  }
401  break;
402  }
403  node = static_cast<HTMLElementImpl *>(node->parentNode());
404  }
405 
406  if (parentNode()->renderer() && parentNode()->renderer()->childAllowed()
407  && document()->isURLAllowed(url)) {
408  RenderStyle *_style = document()->styleSelector()->styleForElement(this);
409  _style->ref();
410  if (_style->display() != NONE) {
411  m_render = new(document()->renderArena()) RenderFrame(this);
412  m_render->setStyle(_style);
413  parentNode()->renderer()->addChild(m_render, nextRenderer());
414  }
415  _style->deref();
416  }
417 
418  // If we already have a widget, set it.
419  if (m_render && childWidget()) {
420  static_cast<RenderFrame *>(m_render)->setWidget(childWidget());
421  }
422 
423  NodeBaseImpl::attach();
424 }
425 
426 void HTMLFrameElementImpl::setWidgetNotify(QWidget *widget)
427 {
428  if (m_render) {
429  static_cast<RenderFrame *>(m_render)->setWidget(widget);
430  }
431 }
432 
433 void HTMLFrameElementImpl::computeContent()
434 {
435  KHTMLPart *parentPart = document()->part();
436 
437  if (!parentPart) {
438  return;
439  }
440 
441  // Bail out on any disallowed URLs
442  if (!document()->isURLAllowed(url)) {
443  return;
444  }
445 
446  // If we have a part already, make sure it's in the right spot...
447  // (can happen if someone asks to change location while we're in process
448  // of loading the original one)
449  if (contentPart()) {
450  setLocation(url);
451  return;
452  }
453 
454  ensureUniqueName();
455 
456  // Go ahead and load a part... We don't need to clear the widget here,
457  // since the -frames- have their lifetime managed, using the name uniqueness.
458  parentPart->loadFrameElement(this, url, name.string());
459 }
460 
461 void HTMLFrameElementImpl::setLocation(const QString &str)
462 {
463  url = str;
464 
465  if (!document()->isURLAllowed(url)) {
466  return;
467  }
468 
469  // if we already have a child part, ask it to go there..
470  KHTMLPart *childPart = contentPart();
471  if (childPart) {
472  childPart->openUrl(QUrl(document()->completeURL(url)));
473  } else {
474  setNeedComputeContent(); // otherwise, request it..
475  }
476 }
477 
478 bool HTMLFrameElementImpl::isFocusableImpl(FocusType ft) const
479 {
480  if (m_render != nullptr) {
481  return true;
482  }
483  return HTMLPartContainerElementImpl::isFocusableImpl(ft);
484 }
485 
486 void HTMLFrameElementImpl::setFocus(bool received)
487 {
488  HTMLElementImpl::setFocus(received);
489  khtml::RenderFrame *renderFrame = static_cast<khtml::RenderFrame *>(m_render);
490  if (!renderFrame || !renderFrame->widget()) {
491  return;
492  }
493  if (received) {
494  renderFrame->widget()->setFocus();
495  } else {
496  renderFrame->widget()->clearFocus();
497  }
498 }
499 
500 DocumentImpl *HTMLFrameElementImpl::contentDocument() const
501 {
502  if (!childWidget()) {
503  return nullptr;
504  }
505 
506  if (::qobject_cast<KHTMLView *>(childWidget())) {
507  return static_cast<KHTMLView *>(childWidget())->part()->xmlDocImpl();
508  }
509 
510  return nullptr;
511 }
512 
513 KHTMLPart *HTMLFrameElementImpl::contentPart() const
514 {
515  if (!childWidget()) {
516  return nullptr;
517  }
518 
519  if (::qobject_cast<KHTMLView *>(childWidget())) {
520  return static_cast<KHTMLView *>(childWidget())->part();
521  }
522 
523  return nullptr;
524 }
525 
526 // -------------------------------------------------------------------------
527 
528 DOMString HTMLBodyElementImpl::aLink() const
529 {
530  return getAttribute(ATTR_ALINK);
531 }
532 
533 void HTMLBodyElementImpl::setALink(const DOMString &value)
534 {
535  setAttribute(ATTR_ALINK, value);
536 }
537 
538 DOMString HTMLBodyElementImpl::bgColor() const
539 {
540  return getAttribute(ATTR_BGCOLOR);
541 }
542 
543 void HTMLBodyElementImpl::setBgColor(const DOMString &value)
544 {
545  setAttribute(ATTR_BGCOLOR, value);
546 }
547 
548 DOMString HTMLBodyElementImpl::link() const
549 {
550  return getAttribute(ATTR_LINK);
551 }
552 
553 void HTMLBodyElementImpl::setLink(const DOMString &value)
554 {
555  setAttribute(ATTR_LINK, value);
556 }
557 
558 DOMString HTMLBodyElementImpl::text() const
559 {
560  return getAttribute(ATTR_TEXT);
561 }
562 
563 void HTMLBodyElementImpl::setText(const DOMString &value)
564 {
565  setAttribute(ATTR_TEXT, value);
566 }
567 
568 DOMString HTMLBodyElementImpl::vLink() const
569 {
570  return getAttribute(ATTR_VLINK);
571 }
572 
573 void HTMLBodyElementImpl::setVLink(const DOMString &value)
574 {
575  setAttribute(ATTR_VLINK, value);
576 }
577 
578 // -------------------------------------------------------------------------
579 
580 HTMLFrameSetElementImpl::HTMLFrameSetElementImpl(DocumentImpl *doc)
581  : HTMLElementImpl(doc)
582 {
583  // default value for rows and cols...
584  m_totalRows = 1;
585  m_totalCols = 1;
586 
587  m_rows = m_cols = nullptr;
588 
589  frameborder = true;
590  frameBorderSet = false;
591  m_border = 4;
592  noresize = false;
593 
594  m_resizing = false;
595 }
596 
597 HTMLFrameSetElementImpl::~HTMLFrameSetElementImpl()
598 {
599  delete [] m_rows;
600  delete [] m_cols;
601 }
602 
603 NodeImpl::Id HTMLFrameSetElementImpl::id() const
604 {
605  return ID_FRAMESET;
606 }
607 
608 void HTMLFrameSetElementImpl::parseAttribute(AttributeImpl *attr)
609 {
610  switch (attr->id()) {
611  case ATTR_ROWS:
612  if (!attr->val()) {
613  break;
614  }
615  delete [] m_rows;
616  m_rows = attr->val()->toLengthArray(m_totalRows);
617  setChanged();
618  break;
619  case ATTR_COLS:
620  if (!attr->val()) {
621  break;
622  }
623  delete [] m_cols;
624  m_cols = attr->val()->toLengthArray(m_totalCols);
625  setChanged();
626  break;
627  case ATTR_FRAMEBORDER:
628  // false or "no" or "0"..
629  if (attr->value().toInt() == 0) {
630  frameborder = false;
631  m_border = 0;
632  }
633  frameBorderSet = true;
634  break;
635  case ATTR_NORESIZE:
636  noresize = true;
637  break;
638  case ATTR_BORDER:
639  m_border = attr->val()->toInt();
640  if (!m_border) {
641  frameborder = false;
642  }
643  break;
644  case ATTR_ONLOAD:
645  document()->setHTMLWindowEventListener(EventImpl::LOAD_EVENT,
646  document()->createHTMLEventListener(attr->value().string(), "onload", nullptr));
647  break;
648  case ATTR_ONUNLOAD:
649  document()->setHTMLWindowEventListener(EventImpl::UNLOAD_EVENT,
650  document()->createHTMLEventListener(attr->value().string(), "onunload", nullptr));
651  break;
652  case ATTR_ONMESSAGE:
653  document()->setHTMLWindowEventListener(EventImpl::MESSAGE_EVENT,
654  document()->createHTMLEventListener(attr->value().string(), "onmessage", nullptr));
655  break;
656  default:
657  HTMLElementImpl::parseAttribute(attr);
658  }
659 }
660 
661 void HTMLFrameSetElementImpl::attach()
662 {
663  assert(!attached());
664  assert(parentNode());
665 
666  // inherit default settings from parent frameset
667  HTMLElementImpl *node = static_cast<HTMLElementImpl *>(parentNode());
668  while (node) {
669  if (node->id() == ID_FRAMESET) {
670  HTMLFrameSetElementImpl *frameset = static_cast<HTMLFrameSetElementImpl *>(node);
671  if (!frameBorderSet) {
672  frameborder = frameset->frameBorder();
673  }
674  if (!noresize) {
675  noresize = frameset->noResize();
676  }
677  break;
678  }
679  node = static_cast<HTMLElementImpl *>(node->parentNode());
680  }
681 
682  RenderStyle *_style = document()->styleSelector()->styleForElement(this);
683  _style->ref();
684  // ignore display: none
685  if (parentNode()->renderer() && parentNode()->renderer()->childAllowed()) {
686  m_render = new(document()->renderArena()) RenderFrameSet(this);
687  m_render->setStyle(_style);
688  parentNode()->renderer()->addChild(m_render, nextRenderer());
689  }
690  _style->deref();
691 
692  NodeBaseImpl::attach();
693 }
694 
695 void HTMLFrameSetElementImpl::defaultEventHandler(EventImpl *evt)
696 {
697  if (evt->isMouseEvent() && !noresize && m_render) {
698  static_cast<khtml::RenderFrameSet *>(m_render)->userResize(static_cast<MouseEventImpl *>(evt));
699  }
700 
701  evt->setDefaultHandled();
702  HTMLElementImpl::defaultEventHandler(evt);
703 }
704 
705 void HTMLFrameSetElementImpl::detach()
706 {
707  if (attached())
708  // ### send the event when we actually get removed from the doc instead of here
709  {
710  document()->dispatchHTMLEvent(EventImpl::UNLOAD_EVENT, false, false);
711  }
712 
713  HTMLElementImpl::detach();
714 }
715 
716 void HTMLFrameSetElementImpl::recalcStyle(StyleChange ch)
717 {
718  if (changed() && m_render) {
719  m_render->setNeedsLayout(true);
720 // m_render->layout();
721  setChanged(false);
722  }
723  HTMLElementImpl::recalcStyle(ch);
724 }
725 
726 // -------------------------------------------------------------------------
727 
728 NodeImpl::Id HTMLHeadElementImpl::id() const
729 {
730  return ID_HEAD;
731 }
732 
733 // -------------------------------------------------------------------------
734 
735 NodeImpl::Id HTMLHtmlElementImpl::id() const
736 {
737  return ID_HTML;
738 }
739 
740 // -------------------------------------------------------------------------
741 
742 HTMLIFrameElementImpl::HTMLIFrameElementImpl(DocumentImpl *doc) : HTMLFrameElementImpl(doc)
743 {
744  frameBorder = false;
745  marginWidth = 0;
746  marginHeight = 0;
747  m_frame = true;
748 }
749 
750 void HTMLIFrameElementImpl::insertedIntoDocument()
751 {
752  HTMLFrameElementImpl::insertedIntoDocument();
753 
754  assert(!contentPart());
755  setNeedComputeContent();
756  computeContentIfNeeded(); // also clears
757 }
758 
759 void HTMLIFrameElementImpl::removedFromDocument()
760 {
761  HTMLFrameElementImpl::removedFromDocument();
762  clearChildWidget();
763 }
764 
765 HTMLIFrameElementImpl::~HTMLIFrameElementImpl()
766 {
767 }
768 
769 NodeImpl::Id HTMLIFrameElementImpl::id() const
770 {
771  return ID_IFRAME;
772 }
773 
774 void HTMLIFrameElementImpl::parseAttribute(AttributeImpl *attr)
775 {
776  switch (attr->id()) {
777  case ATTR_WIDTH:
778  if (!attr->value().isEmpty()) {
779  addCSSLength(CSS_PROP_WIDTH, attr->value());
780  } else {
781  removeCSSProperty(CSS_PROP_WIDTH);
782  }
783  break;
784  case ATTR_HEIGHT:
785  if (!attr->value().isEmpty()) {
786  addCSSLength(CSS_PROP_HEIGHT, attr->value());
787  } else {
788  removeCSSProperty(CSS_PROP_HEIGHT);
789  }
790  break;
791  case ATTR_ALIGN:
792  addHTMLAlignment(attr->value());
793  break;
794  case ATTR_SRC:
795  url = attr->value().trimSpaces().string();
796  setNeedComputeContent();
797  // ### synchronously start the process?
798  break;
799  case ATTR_NAME:
800  ensureUniqueName();
801  break;
802  case ATTR_ID:
803  HTMLFrameElementImpl::parseAttribute(attr); // want default ID handling
804  ensureUniqueName();
805  break;
806  case ATTR_FRAMEBORDER: {
807  m_frame = (!attr->val() || attr->value().toInt() > 0);
808  if (attached()) {
809  updateFrame();
810  }
811  break;
812  }
813  default:
814  HTMLFrameElementImpl::parseAttribute(attr);
815  }
816 }
817 
818 void HTMLIFrameElementImpl::updateFrame()
819 {
820  if (m_frame) {
821  addCSSProperty(CSS_PROP_BORDER_TOP_STYLE, CSS_VAL_OUTSET);
822  addCSSProperty(CSS_PROP_BORDER_BOTTOM_STYLE, CSS_VAL_OUTSET);
823  addCSSProperty(CSS_PROP_BORDER_LEFT_STYLE, CSS_VAL_OUTSET);
824  addCSSProperty(CSS_PROP_BORDER_RIGHT_STYLE, CSS_VAL_OUTSET);
825  addCSSLength(CSS_PROP_BORDER_WIDTH, "2");
826  } else {
827  addCSSProperty(CSS_PROP_BORDER_TOP_STYLE, CSS_VAL_NONE);
828  addCSSProperty(CSS_PROP_BORDER_BOTTOM_STYLE, CSS_VAL_NONE);
829  addCSSProperty(CSS_PROP_BORDER_LEFT_STYLE, CSS_VAL_NONE);
830  addCSSProperty(CSS_PROP_BORDER_RIGHT_STYLE, CSS_VAL_NONE);
831  removeCSSProperty(CSS_PROP_BORDER_WIDTH);
832  }
833 
834 }
835 
836 void HTMLIFrameElementImpl::attach()
837 {
838  assert(!attached());
839  assert(!m_render);
840  assert(parentNode());
841 
842  updateFrame();
843 
844  RenderStyle *style = document()->styleSelector()->styleForElement(this);
845  style->ref();
846  if (document()->isURLAllowed(url) && parentNode()->renderer()
847  && parentNode()->renderer()->childAllowed() && style->display() != NONE) {
848  m_render = new(document()->renderArena()) RenderPartObject(this);
849  m_render->setStyle(style);
850  parentNode()->renderer()->addChild(m_render, nextRenderer());
851  }
852  style->deref();
853 
854  NodeBaseImpl::attach();
855 
856  if (m_render && childWidget()) {
857  static_cast<RenderPartObject *>(m_render)->setWidget(childWidget());
858  }
859 }
860 
861 void HTMLIFrameElementImpl::computeContent()
862 {
863  KHTMLPart *parentPart = document()->part();
864 
865  if (!parentPart) {
866  return;
867  }
868 
869  if (!document()->isURLAllowed(url)) {
870  return;
871  }
872 
873  if (!inDocument()) {
874  clearChildWidget();
875  return;
876  }
877 
878  // get our name in order..
879  ensureUniqueName();
880 
881  // make sure "" is handled as about: blank
882  const QString aboutBlank = QLatin1String("about:blank");
883  QString effectiveURL = url;
884  if (effectiveURL.isEmpty()) {
885  effectiveURL = aboutBlank;
886  }
887 
888  // qCDebug(KHTML_LOG) << "-> requesting:" << name.string() << effectiveURL << contentPart();
889 
890  parentPart->loadFrameElement(this, effectiveURL, name.string(), QStringList(), true);
891 }
892 
893 void HTMLIFrameElementImpl::setWidgetNotify(QWidget *widget)
894 {
895  if (m_render) {
896  static_cast<RenderPartObject *>(m_render)->setWidget(widget);
897  }
898 }
899 
ScrollBarAsNeeded
int marginWidth() const
Returns the margin width.
Definition: khtmlview.h:159
QString name(const QVariant &location)
CSSStyleDeclaration style()
Introduced in DOM Level 2 This method is from the CSSStyleDeclaration interface.
This file is part of the HTML rendering engine for KDE.
This class is khtml&#39;s main class.
Definition: khtml_part.h:208
Renders and displays HTML in a QScrollArea.
Definition: khtmlview.h:97
bool isNull() const const
void setAttribute(const DOMString &name, const DOMString &value)
Adds a new attribute.
bool openUrl(const QUrl &url) override
Opens the specified URL url.
Definition: khtml_part.cpp:707
Node parentNode() const
The parent of this node.
Definition: dom_node.cpp:250
bool isEmpty() const const
This class implements the basic string we use in the DOM.
Definition: dom_string.h:44
KHTMLPart * findFrame(const QString &f)
Finds a frame by name.
void setMarginWidth(int x)
Sets a margin in x direction.
Definition: khtmlview.cpp:969
This library provides a full-featured HTML parser and widget.
DOMString getAttribute(const DOMString &name)
Retrieves an attribute value by name.
QString arg(qlonglong a, int fieldWidth, int base, QChar fillChar) const const
int marginHeight()
Returns the margin height.
Definition: khtmlview.h:174
This file is part of the KDE documentation.
Documentation copyright © 1996-2021 The KDE developers.
Generated on Tue Oct 26 2021 22:48:01 by doxygen 1.8.11 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.