KHtml

html_elementimpl.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) 2003 Dirk Mueller ([email protected])
7  * Copyright (C) 2002 Apple Computer, Inc.
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 //#define DEBUG
27 //#define DEBUG_LAYOUT
28 //#define PAR_DEBUG
29 //#define EVENT_DEBUG
30 //#define UNSUPPORTED_ATTR
31 
32 #include "html_elementimpl.h"
33 #include "dtd.h"
34 #include "html_documentimpl.h"
35 #include "htmltokenizer.h"
36 
37 #include <khtmlview.h>
38 #include <khtml_part.h>
39 
40 #include <rendering/render_object.h>
41 #include <rendering/render_replaced.h>
42 #include <css/css_valueimpl.h>
43 #include <css/css_stylesheetimpl.h>
44 #include <css/cssproperties.h>
45 #include <css/cssvalues.h>
46 #include <xml/dom_textimpl.h>
47 #include <xml/dom2_eventsimpl.h>
48 #include <dom/dom_doc.h>
49 
50 #include "khtml_debug.h"
51 
52 #undef FOCUS_EVENT // for win32, MinGW
53 
54 using namespace DOM;
55 using namespace khtml;
56 
57 HTMLElementImpl::HTMLElementImpl(DocumentImpl *doc)
58  : ElementImpl(doc)
59 {
60  m_htmlCompat = doc && doc->htmlMode() != DocumentImpl::XHtml;
61 }
62 
63 HTMLElementImpl::~HTMLElementImpl()
64 {
65 }
66 
67 bool HTMLElementImpl::isInline() const
68 {
69  if (renderer()) {
70  return ElementImpl::isInline();
71  }
72 
73  switch (id()) {
74  case ID_A:
75  case ID_FONT:
76  case ID_TT:
77  case ID_U:
78  case ID_B:
79  case ID_I:
80  case ID_S:
81  case ID_STRIKE:
82  case ID_BIG:
83  case ID_SMALL:
84 
85  // %phrase
86  case ID_EM:
87  case ID_STRONG:
88  case ID_DFN:
89  case ID_CODE:
90  case ID_SAMP:
91  case ID_KBD:
92  case ID_VAR:
93  case ID_CITE:
94  case ID_ABBR:
95  case ID_ACRONYM:
96 
97  // %special
98  case ID_SUB:
99  case ID_SUP:
100  case ID_SPAN:
101  case ID_NOBR:
102  case ID_WBR:
103  return true;
104 
105  default:
106  return ElementImpl::isInline();
107  }
108 }
109 
110 DOMString HTMLElementImpl::namespaceURI() const
111 {
112  return DOMString(XHTML_NAMESPACE);
113 }
114 
115 void HTMLElementImpl::parseAttribute(AttributeImpl *attr)
116 {
117  DOMString indexstring;
118  switch (attr->id()) {
119  case ATTR_ALIGN:
120  if (attr->val()) {
121  if (strcasecmp(attr->value(), "middle") == 0) {
122  addCSSProperty(CSS_PROP_TEXT_ALIGN, CSS_VAL_CENTER);
123  } else {
124  addCSSProperty(CSS_PROP_TEXT_ALIGN, attr->value().lower());
125  }
126  } else {
127  removeCSSProperty(CSS_PROP_TEXT_ALIGN);
128  }
129  break;
130 // the core attributes...
131  case ATTR_ID:
132  // unique id
133  setHasID();
134  document()->incDOMTreeVersion(DocumentImpl::TV_IDNameHref);
135  break;
136  case ATTR_CLASS:
137  if (attr->val()) {
138  DOMString v = attr->value();
139  const QChar *characters = v.unicode();
140  unsigned length = v.length();
141  unsigned i;
142  for (i = 0; i < length && characters[i].isSpace(); ++i) { }
143  setHasClass(i < length);
144  attributes()->setClass(v);
145  } else {
146  setHasClass(false);
147  }
148  document()->incDOMTreeVersion(DocumentImpl::TV_Class);
149  break;
150  case ATTR_NAME:
151  document()->incDOMTreeVersion(DocumentImpl::TV_IDNameHref);
152  break;
153  case ATTR_CONTENTEDITABLE:
154  setContentEditable(attr);
155  break;
156  case ATTR_STYLE:
157  getInlineStyleDecls()->updateFromAttribute(attr->value());
158  setChanged();
159  break;
160  case ATTR_TABINDEX:
161  indexstring = getAttribute(ATTR_TABINDEX);
162  if (attr->val()) {
163  setTabIndex(attr->value().toInt());
164  } else {
165  setNoTabIndex();
166  }
167  break;
168 // i18n attributes
169  case ATTR_LANG:
170  break;
171  case ATTR_DIR:
172  addCSSProperty(CSS_PROP_DIRECTION, attr->value().lower());
173  break;
174 // standard events
175  case ATTR_ONCLICK:
176  setHTMLEventListener(EventImpl::KHTML_ECMA_CLICK_EVENT,
177  document()->createHTMLEventListener(attr->value().string(), "onclick", this));
178  break;
179  case ATTR_ONDBLCLICK:
180  setHTMLEventListener(EventImpl::KHTML_ECMA_DBLCLICK_EVENT,
181  document()->createHTMLEventListener(attr->value().string(), "ondblclick", this));
182  break;
183  case ATTR_ONMOUSEDOWN:
184  setHTMLEventListener(EventImpl::MOUSEDOWN_EVENT,
185  document()->createHTMLEventListener(attr->value().string(), "onmousedown", this));
186  break;
187  case ATTR_ONMOUSEMOVE:
188  setHTMLEventListener(EventImpl::MOUSEMOVE_EVENT,
189  document()->createHTMLEventListener(attr->value().string(), "onmousemove", this));
190  break;
191  case ATTR_ONMOUSEOUT:
192  setHTMLEventListener(EventImpl::MOUSEOUT_EVENT,
193  document()->createHTMLEventListener(attr->value().string(), "onmouseout", this));
194  break;
195  case ATTR_ONMOUSEOVER:
196  setHTMLEventListener(EventImpl::MOUSEOVER_EVENT,
197  document()->createHTMLEventListener(attr->value().string(), "onmouseover", this));
198  break;
199  case ATTR_ONMOUSEUP:
200  setHTMLEventListener(EventImpl::MOUSEUP_EVENT,
201  document()->createHTMLEventListener(attr->value().string(), "onmouseup", this));
202  break;
203  case ATTR_ONKEYDOWN:
204  setHTMLEventListener(EventImpl::KEYDOWN_EVENT,
205  document()->createHTMLEventListener(attr->value().string(), "onkeydown", this));
206  break;
207  case ATTR_ONKEYPRESS:
208  setHTMLEventListener(EventImpl::KEYPRESS_EVENT,
209  document()->createHTMLEventListener(attr->value().string(), "onkeypress", this));
210  break;
211  case ATTR_ONKEYUP:
212  setHTMLEventListener(EventImpl::KEYUP_EVENT,
213  document()->createHTMLEventListener(attr->value().string(), "onkeyup", this));
214  break;
215  case ATTR_ONFOCUS:
216  setHTMLEventListener(EventImpl::FOCUS_EVENT,
217  document()->createHTMLEventListener(attr->value().string(), "onfocus", this));
218  break;
219  case ATTR_ONBLUR:
220  setHTMLEventListener(EventImpl::BLUR_EVENT,
221  document()->createHTMLEventListener(attr->value().string(), "onblur", this));
222  break;
223  case ATTR_ONSCROLL:
224  setHTMLEventListener(EventImpl::SCROLL_EVENT,
225  document()->createHTMLEventListener(attr->value().string(), "onscroll", this));
226  break;
227 // other misc attributes
228  default:
229 #ifdef UNSUPPORTED_ATTR
230  qCDebug(KHTML_LOG) << "UATTR: <" << this->nodeName().string() << "> ["
231  << attr->name().string() << "]=[" << attr->value().string() << "]";
232 #endif
233  break;
234  }
235 }
236 
237 void HTMLElementImpl::recalcStyle(StyleChange ch)
238 {
239  ElementImpl::recalcStyle(ch);
240 
241  if (m_render /*&& changed*/) {
242  m_render->updateFromElement();
243  }
244 }
245 
246 void HTMLElementImpl::addCSSProperty(int id, const DOMString &value)
247 {
248  if (!m_hasCombinedStyle) {
249  createNonCSSDecl();
250  }
251  nonCSSStyleDecls()->setProperty(id, value, false);
252  setChanged();
253 }
254 
255 void HTMLElementImpl::addCSSProperty(int id, int value)
256 {
257  if (!m_hasCombinedStyle) {
258  createNonCSSDecl();
259  }
260  nonCSSStyleDecls()->setProperty(id, value, false);
261  setChanged();
262 }
263 
264 void HTMLElementImpl::addCSSLength(int id, const DOMString &value, bool numOnly, bool multiLength)
265 {
266  if (!m_hasCombinedStyle) {
267  createNonCSSDecl();
268  }
269 
270  // strip attribute garbage to avoid CSS parsing errors
271  // ### create specialized hook that avoids parsing every
272  // value twice!
273  if (value.implementation()) {
274  // match \s*[+-]?\d*(\.\d*)?[%\*]?
275  unsigned i = 0, j = 0;
276  QChar *s = value.implementation()->s;
277  unsigned l = value.implementation()->l;
278 
279  while (i < l && s[i].isSpace()) {
280  ++i;
281  }
282  if (i < l && (s[i] == '+' || s[i] == '-')) {
283  ++i;
284  }
285  while (i < l && s[i].isDigit()) {
286  ++i, ++j;
287  }
288 
289  // no digits!
290  if (j == 0) {
291  return;
292  }
293 
294  int v = qBound(-8192, QString::fromRawData(s, i).toInt(), 8191);
295  const char *suffix = "px";
296  if (!numOnly || multiLength) {
297  // look if we find a % or *
298  while (i < l) {
299  if (multiLength && s[i] == '*') {
300  suffix = "";
301  break;
302  }
303  if (s[i] == '%') {
304  suffix = "%";
305  break;
306  }
307  ++i;
308  }
309  }
310  if (numOnly) {
311  suffix = "";
312  }
313 
314  QString ns = QString::number(v) + suffix;
315  nonCSSStyleDecls()->setLengthProperty(id, DOMString(ns), false, multiLength);
316  setChanged();
317  return;
318  }
319 
320  nonCSSStyleDecls()->setLengthProperty(id, value, false, multiLength);
321  setChanged();
322 }
323 
324 static inline bool isHexDigit(const QChar &c)
325 {
326  return (c >= '0' && c <= '9') ||
327  (c >= 'a' && c <= 'f') ||
328  (c >= 'A' && c <= 'F');
329 }
330 
331 static inline int toHex(const QChar &c)
332 {
333  return ((c >= '0' && c <= '9')
334  ? (c.unicode() - '0')
335  : ((c >= 'a' && c <= 'f')
336  ? (c.unicode() - 'a' + 10)
337  : ((c >= 'A' && c <= 'F')
338  ? (c.unicode() - 'A' + 10)
339  : -1)));
340 }
341 
342 /* color parsing that tries to match as close as possible IE 6. */
343 void HTMLElementImpl::addHTMLColor(int id, const DOMString &c)
344 {
345  if (!m_hasCombinedStyle) {
346  createNonCSSDecl();
347  }
348 
349  // this is the only case no color gets applied in IE.
350  if (!c.length()) {
351  removeCSSProperty(id);
352  return;
353  }
354 
355  if (nonCSSStyleDecls()->setProperty(id, c, false)) {
356  return;
357  }
358 
359  QString color = c.string();
360  // not something that fits the specs.
361 
362  // we're emulating IEs color parser here. It maps transparent to black, otherwise it tries to build a rgb value
363  // out of everyhting you put in. The algorithm is experimentally determined, but seems to work for all test cases I have.
364 
365  // the length of the color value is rounded up to the next
366  // multiple of 3. each part of the rgb triple then gets one third
367  // of the length.
368  //
369  // Each triplet is parsed byte by byte, mapping
370  // each number to a hex value (0-9a-fA-F to their values
371  // everything else to 0).
372  //
373  // The highest non zero digit in all triplets is remembered, and
374  // used as a normalization point to normalize to values between 0
375  // and 255.
376 
377  if (color.toLower() != "transparent") {
378  if (color[0] == '#') {
379  color.remove(0, 1);
380  }
381  int basicLength = (color.length() + 2) / 3;
382  if (basicLength > 1) {
383  // IE ignores colors with three digits or less
384 // qDebug("trying to fix up color '%s'. basicLength=%d, length=%d",
385 // color.toLatin1().constData(), basicLength, color.length() );
386  int colors[3] = { 0, 0, 0 };
387  int component = 0;
388  int pos = 0;
389  int maxDigit = basicLength - 1;
390  while (component < 3) {
391  // search forward for digits in the string
392  int numDigits = 0;
393  while (pos < (int)color.length() && numDigits < basicLength) {
394  int hex = toHex(color[pos]);
395  colors[component] = (colors[component] << 4);
396  if (hex > 0) {
397  colors[component] += hex;
398  maxDigit = qMin(maxDigit, numDigits);
399  }
400  numDigits++;
401  pos++;
402  }
403  while (numDigits++ < basicLength) {
404  colors[component] <<= 4;
405  }
406  component++;
407  }
408  maxDigit = basicLength - maxDigit;
409 // qDebug("color is %x %x %x, maxDigit=%d", colors[0], colors[1], colors[2], maxDigit );
410 
411  // normalize to 00-ff. The highest filled digit counts, minimum is 2 digits
412  maxDigit -= 2;
413  colors[0] >>= 4 * maxDigit;
414  colors[1] >>= 4 * maxDigit;
415  colors[2] >>= 4 * maxDigit;
416 // qDebug("normalized color is %x %x %x", colors[0], colors[1], colors[2] );
417  // assert( colors[0] < 0x100 && colors[1] < 0x100 && colors[2] < 0x100 );
418 
419  color.sprintf("#%02x%02x%02x", colors[0], colors[1], colors[2]);
420 // qDebug( "trying to add fixed color string '%s'", color.toLatin1().constData() );
421  if (nonCSSStyleDecls()->setProperty(id, DOMString(color), false)) {
422  return;
423  }
424  }
425  }
426  nonCSSStyleDecls()->setProperty(id, CSS_VAL_BLACK, false);
427 }
428 
429 void HTMLElementImpl::removeCSSProperty(int id)
430 {
431  if (!m_hasCombinedStyle) {
432  return;
433  }
434  nonCSSStyleDecls()->setParent(document()->elementSheet());
435  nonCSSStyleDecls()->removeProperty(id);
436  setChanged();
437 }
438 
439 DOMString HTMLElementImpl::innerHTML() const
440 {
441  QString result = ""; //Use QString to accumulate since DOMString is poor for appends
442  for (NodeImpl *child = firstChild(); child != nullptr; child = child->nextSibling()) {
443  DOMString kid = child->toString();
444  result += QString::fromRawData(kid.unicode(), kid.length());
445  }
446  return result;
447 }
448 
449 DOMString HTMLElementImpl::innerText() const
450 {
451  QString text = "";
452  if (!firstChild()) {
453  return text;
454  }
455 
456  const NodeImpl *n = this;
457  // find the next text/image after the anchor, to get a position
458  while (n) {
459  if (n->firstChild()) {
460  n = n->firstChild();
461  } else if (n->nextSibling()) {
462  n = n->nextSibling();
463  } else {
464  NodeImpl *next = nullptr;
465  while (!next) {
466  n = n->parentNode();
467  if (!n || n == (NodeImpl *)this) {
468  goto end;
469  }
470  next = n->nextSibling();
471  }
472  n = next;
473  }
474  if (n->isTextNode()) {
475  DOMStringImpl *data = static_cast<const TextImpl *>(n)->string();
476  text += QString::fromRawData(data->s, data->l);
477  }
478  }
479 end:
480  return text;
481 }
482 
483 DocumentFragment HTMLElementImpl::createContextualFragment(const DOMString &html)
484 {
485  // IE originally restricted innerHTML to a small subset of elements;
486  // and we largely matched that. Mozilla's embrace of innerHTML, however, extended
487  // it to pretty much everything, and so the web (and HTML5) requires it now.
488  // For now, we accept everything, but do not do context-based recovery in the parser.
489  if (!document()->isHTMLDocument()) {
490  return DocumentFragment();
491  }
492 
493  DocumentFragmentImpl *fragment = new DocumentFragmentImpl(docPtr());
494  DocumentFragment f(fragment);
495  {
496  HTMLTokenizer tok(docPtr(), fragment);
497  tok.begin();
498  tok.write(html.string(), true);
499  tok.end();
500  }
501 
502  // Exceptions are ignored because none ought to happen here.
503  int ignoredExceptionCode;
504 
505  // we need to pop <html> and <body> elements and remove <head> to
506  // accomadate folks passing complete HTML documents to make the
507  // child of an element.
508  for (NodeImpl *node = fragment->firstChild(); node;) {
509  if (node->id() == ID_HTML || node->id() == ID_BODY) {
510  NodeImpl *firstChild = node->firstChild();
511  NodeImpl *child = firstChild;
512  while (child) {
513  NodeImpl *nextChild = child->nextSibling();
514  fragment->insertBefore(child, node, ignoredExceptionCode);
515  child = nextChild;
516  }
517  if (!firstChild) {
518  NodeImpl *nextNode = node->nextSibling();
519  fragment->removeChild(node, ignoredExceptionCode);
520  node = nextNode;
521  } else {
522  fragment->removeChild(node, ignoredExceptionCode);
523  node = firstChild;
524  }
525  } else if (node->id() == ID_HEAD) {
526  NodeImpl *nextNode = node->nextSibling();
527  fragment->removeChild(node, ignoredExceptionCode);
528  node = nextNode;
529  } else {
530  node = node->nextSibling();
531  }
532  }
533 
534  return f;
535 }
536 
537 void HTMLElementImpl::setInnerHTML(const DOMString &html, int &exceptioncode)
538 {
539  if (id() == ID_SCRIPT || id() == ID_STYLE) {
540  // Script and CSS source shouldn't be parsed as HTML.
541  removeChildren();
542  appendChild(document()->createTextNode(html), exceptioncode);
543  return;
544  }
545 
546  DocumentFragment fragment = createContextualFragment(html);
547  if (fragment.isNull()) {
548  exceptioncode = DOMException::NO_MODIFICATION_ALLOWED_ERR;
549  return;
550  }
551 
552  // Make sure adding the new child is ok, before removing all children (#96187)
553  checkAddChild(fragment.handle(), exceptioncode);
554  if (exceptioncode) {
555  return;
556  }
557 
558  removeChildren();
559  appendChild(fragment.handle(), exceptioncode);
560 }
561 
562 void HTMLElementImpl::setInnerText(const DOMString &text, int &exceptioncode)
563 {
564  // following the IE specs.
565  if (endTagRequirement(id()) == FORBIDDEN) {
566  exceptioncode = DOMException::NO_MODIFICATION_ALLOWED_ERR;
567  return;
568  }
569  // IE disallows innerHTML on inline elements. I don't see why we should have this restriction, as our
570  // dhtml engine can cope with it. Lars
571  //if ( isInline() ) return false;
572  switch (id()) {
573  case ID_COL:
574  case ID_COLGROUP:
575  case ID_FRAMESET:
576  case ID_HEAD:
577  case ID_HTML:
578  case ID_TABLE:
579  case ID_TBODY:
580  case ID_TFOOT:
581  case ID_THEAD:
582  case ID_TR:
583  exceptioncode = DOMException::NO_MODIFICATION_ALLOWED_ERR;
584  return;
585  default:
586  break;
587  }
588 
589  removeChildren();
590 
591  TextImpl *t = new TextImpl(docPtr(), text.implementation());
592  appendChild(t, exceptioncode);
593 }
594 
595 void HTMLElementImpl::addHTMLAlignment(DOMString alignment)
596 {
597  //qDebug("alignment is %s", alignment.string().toLatin1().constData() );
598  // vertical alignment with respect to the current baseline of the text
599  // right or left means floating images
600  int propfloat = -1;
601  int propvalign = -1;
602  if (strcasecmp(alignment, "absmiddle") == 0) {
603  propvalign = CSS_VAL_MIDDLE;
604  } else if (strcasecmp(alignment, "absbottom") == 0) {
605  propvalign = CSS_VAL_BOTTOM;
606  } else if (strcasecmp(alignment, "left") == 0) {
607  propfloat = CSS_VAL_LEFT;
608  propvalign = CSS_VAL_TOP;
609  } else if (strcasecmp(alignment, "right") == 0) {
610  propfloat = CSS_VAL_RIGHT;
611  propvalign = CSS_VAL_TOP;
612  } else if (strcasecmp(alignment, "top") == 0) {
613  propvalign = CSS_VAL_TOP;
614  } else if (strcasecmp(alignment, "middle") == 0) {
615  propvalign = CSS_VAL__KHTML_BASELINE_MIDDLE;
616  } else if (strcasecmp(alignment, "center") == 0) {
617  propvalign = CSS_VAL_MIDDLE;
618  } else if (strcasecmp(alignment, "bottom") == 0) {
619  propvalign = CSS_VAL_BASELINE;
620  } else if (strcasecmp(alignment, "texttop") == 0) {
621  propvalign = CSS_VAL_TEXT_TOP;
622  }
623 
624  if (propfloat != -1) {
625  addCSSProperty(CSS_PROP_FLOAT, propfloat);
626  }
627  if (propvalign != -1) {
628  addCSSProperty(CSS_PROP_VERTICAL_ALIGN, propvalign);
629  }
630 }
631 
632 DOMString HTMLElementImpl::contentEditable() const
633 {
634  document()->updateRendering();
635 
636  if (!renderer()) {
637  return "false";
638  }
639 
640  switch (renderer()->style()->userInput()) {
641  case UI_ENABLED:
642  return "true";
643  case UI_DISABLED:
644  case UI_NONE:
645  return "false";
646  default:;
647  }
648  return "inherit";
649 }
650 
651 void HTMLElementImpl::setContentEditable(AttributeImpl *attr)
652 {
653  const DOMString &enabled = attr->value();
654  if (enabled.isEmpty() || strcasecmp(enabled, "true") == 0) {
655  addCSSProperty(CSS_PROP__KHTML_USER_INPUT, CSS_VAL_ENABLED);
656  } else if (strcasecmp(enabled, "false") == 0) {
657  addCSSProperty(CSS_PROP__KHTML_USER_INPUT, CSS_VAL_NONE);
658  } else if (strcasecmp(enabled, "inherit") == 0) {
659  addCSSProperty(CSS_PROP__KHTML_USER_INPUT, CSS_VAL_INHERIT);
660  }
661 }
662 
663 void HTMLElementImpl::setContentEditable(const DOMString &enabled)
664 {
665  if (enabled == "inherit") {
666  int exceptionCode;
667  removeAttribute(ATTR_CONTENTEDITABLE, exceptionCode);
668  } else {
669  setAttribute(ATTR_CONTENTEDITABLE, enabled.isEmpty() ? "true" : enabled);
670  }
671 }
672 
673 DOMString HTMLElementImpl::toString() const
674 {
675  if (!hasChildNodes()) {
676  DOMString result = openTagStartToString();
677  result += ">";
678 
679  if (endTagRequirement(id()) == REQUIRED) {
680  result += "</";
681  result += nonCaseFoldedTagName();
682  result += ">";
683  }
684 
685  return result;
686  }
687 
688  return ElementImpl::toString();
689 }
690 
691 // -------------------------------------------------------------------------
692 HTMLGenericElementImpl::HTMLGenericElementImpl(DocumentImpl *doc, ushort i)
693  : HTMLElementImpl(doc)
694 {
695  m_localName = LocalName::fromId(i);
696 }
697 
698 HTMLGenericElementImpl::HTMLGenericElementImpl(DocumentImpl *doc, LocalName l)
699  : HTMLElementImpl(doc),
700  m_localName(l)
701 {}
702 
703 HTMLGenericElementImpl::~HTMLGenericElementImpl()
704 {
705 }
void setContentEditable(const DOMString &enabled)
Sets the editability of this element.
Node insertBefore(const Node &newChild, const Node &refChild)
Inserts the node newChild before the existing child node refChild .
Definition: dom_node.cpp:314
DOMString nodeName() const
The name of this node, depending on its type; see the table above.
Definition: dom_node.cpp:210
CSSStyleDeclaration style()
Introduced in DOM Level 2 This method is from the CSSStyleDeclaration interface.
Node appendChild(const Node &newChild)
Adds the node newChild to the end of the list of children of this node.
Definition: dom_node.cpp:354
This file is part of the HTML rendering engine for KDE.
MESSAGECORE_EXPORT KMime::Content * next(KMime::Content *node, bool allowChildren=true)
DocumentFragment is a "lightweight" or "minimal" Document object.
Definition: dom_doc.h:1042
NamedNodeMap attributes() const
A NamedNodeMap containing the attributes of this node (if it is an Element ) or null otherwise...
Definition: dom_node.cpp:298
QString & remove(int position, int n)
bool hasChildNodes()
This is a convenience method to allow easy determination of whether a node has any children...
Definition: dom_node.cpp:375
QString & sprintf(const char *cformat,...)
void removeAttribute(const DOMString &name)
Removes an attribute by name.
void setAttribute(const DOMString &name, const DOMString &value)
Adds a new attribute.
QString fromRawData(const QChar *unicode, int size)
QString number(int n, int base)
bool isSpace() const const
bool isNull() const
tests if this Node is 0.
Definition: dom_node.h:928
This class implements the basic string we use in the DOM.
Definition: dom_string.h:44
Node removeChild(const Node &oldChild)
Removes the child node indicated by oldChild from the list of children, and returns it...
Definition: dom_node.cpp:340
ushort unicode() const const
QString toLower() const const
Node firstChild() const
The first child of this node.
Definition: dom_node.cpp:266
This library provides a full-featured HTML parser and widget.
const QList< QKeySequence > & end()
DOMString getAttribute(const DOMString &name)
Retrieves an attribute value by name.
int length() const const
DOMStringImpl * implementation() const
Definition: dom_string.h:145
QTextStream & hex(QTextStream &stream)
NodeImpl * handle() const
Definition: dom_node.h:936
QCA_EXPORT void setProperty(const QString &name, const QVariant &value)
Node nextSibling() const
The node immediately following this node.
Definition: dom_node.cpp:290
This file is part of the KDE documentation.
Documentation copyright © 1996-2021 The KDE developers.
Generated on Sat Oct 16 2021 22:47:53 by doxygen 1.8.11 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.