KHtml

dom_elementimpl.h
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) 2001 Peter Kelly ([email protected])
7  * (C) 2001 Dirk Mueller ([email protected])
8  * (C) 2003, 2004, 2005, 2006, 2007 Apple Inc. All rights reserved.
9  *
10  * This library is free software; you can redistribute it and/or
11  * modify it under the terms of the GNU Library General Public
12  * License as published by the Free Software Foundation; either
13  * version 2 of the License, or (at your option) any later version.
14  *
15  * This library is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
18  * Library General Public License for more details.
19  *
20  * You should have received a copy of the GNU Library General Public License
21  * along with this library; see the file COPYING.LIB. If not, write to
22  * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
23  * Boston, MA 02110-1301, USA.
24  *
25  */
26 #ifndef _DOM_ELEMENTImpl_h_
27 #define _DOM_ELEMENTImpl_h_
28 
29 #include "dom_nodeimpl.h"
30 #include "dom/dom_exception.h"
31 #include "dom/dom_element.h"
32 #include "xml/dom_stringimpl.h"
33 #include "misc/shared.h"
34 #include "wtf/Vector.h"
35 #include "xml/ClassNames.h"
36 
37 // WebCore SVG
38 #include "dom/QualifiedName.h"
39 // End WebCore SVG
40 
41 namespace khtml
42 {
43 class CSSStyleSelector;
44 }
45 
46 namespace DOM
47 {
48 
49 class ElementImpl;
50 class DocumentImpl;
51 class NamedAttrMapImpl;
52 class ElementRareDataImpl;
53 class CSSInlineStyleDeclarationImpl;
54 
55 // Attr can have Text and EntityReference children
56 // therefore it has to be a fullblown Node. The plan
57 // is to dynamically allocate a textchild and store the
58 // resulting nodevalue in the AttributeImpl upon
59 // destruction. however, this is not yet implemented.
60 class AttrImpl : public NodeBaseImpl
61 {
62  friend class ElementImpl;
63  friend class NamedAttrMapImpl;
64 
65 public:
66  AttrImpl(ElementImpl *element, DocumentImpl *docPtr, NamespaceName namespaceName, LocalName localName, PrefixName prefix, DOMStringImpl *value);
67  ~AttrImpl();
68 
69 private:
70  AttrImpl(const AttrImpl &other);
71  AttrImpl &operator = (const AttrImpl &other);
72  void createTextChild();
73 public:
74 
75  // DOM methods & attributes for Attr
76  bool specified() const
77  {
78  return true; /* we don't yet support default attributes*/
79  }
80  ElementImpl *ownerElement() const
81  {
82  return m_element;
83  }
84  void setOwnerElement(ElementImpl *impl)
85  {
86  m_element = impl;
87  }
88  DOMString name() const;
89 
90  //DOMString value() const;
91  void setValue(const DOMString &v, int &exceptioncode);
92 
93  // DOM methods overridden from parent classes
94  DOMString nodeName() const override;
95  unsigned short nodeType() const override;
96  DOMString prefix() const override;
97  void setPrefix(const DOMString &refix, int &exceptioncode) override;
98  DOMString namespaceURI() const override;
99  DOMString localName() const override;
100 
101  inline const PrefixName &prefixName() const
102  {
103  return m_prefix;
104  }
105 
106  DOMString nodeValue() const override;
107  void setNodeValue(const DOMString &, int &exceptioncode) override;
108  WTF::PassRefPtr<NodeImpl> cloneNode(bool deep) override;
109 
110  // Other methods (not part of DOM)
111  bool isAttributeNode() const override
112  {
113  return true;
114  }
115  bool childAllowed(NodeImpl *newChild) override;
116  bool childTypeAllowed(unsigned short type) override;
117  NodeImpl::Id id() const override
118  {
119  return makeId(m_namespace.id(), m_localName.id());
120  }
121  void childrenChanged() override;
122 
123  // non-virtual id, for faster attribute look-ups
124  inline NodeImpl::Id fastId() const
125  {
126  return makeId(m_namespace.id(), m_localName.id());
127  }
128 
129  // This is used for when the value is normalized on setting by
130  // parseAttribute; it silently updates it w/o issuing any events, etc.
131  // Doesn't work for ATTR_ID!
132  void rewriteValue(const DOMString &newValue);
133 
134  DOMString toString() const override;
135 
136  void setElement(ElementImpl *element);
137  DOMStringImpl *val() const
138  {
139  return m_value;
140  }
141 
142 protected:
143  ElementImpl *m_element;
144  LocalName m_localName;
145  NamespaceName m_namespace;
146  PrefixName m_prefix;
147  DOMStringImpl *m_value;
148 };
149 
150 // Mini version of AttrImpl internal to NamedAttrMapImpl.
151 // Stores either the id (LocalName and NamespaceName) and value of an attribute
152 // (in the case of m_localName.id() != 0), or a pointer to an AttrImpl (if m_localName.id() == 0)
153 // The latter case only happens when the Attr node is requested by some DOM
154 // code or is an XML attribute.
155 // In most cases the id and value is all we need to store, which is more
156 // memory efficient.
157 // FIXME: update comment - no longer create mini version for only html attributes
158 struct AttributeImpl {
159  inline NodeImpl::Id id() const
160  {
161  return m_localName.id() ? makeId(m_namespace.id(), m_localName.id()) : m_data.attr->fastId();
162  }
163  DOMStringImpl *val() const
164  {
165  if (m_localName.id()) {
166  return m_data.value;
167  } else {
168  return m_data.attr->val();
169  }
170  }
171  DOMString value() const
172  {
173  return val();
174  }
175  AttrImpl *attr() const
176  {
177  return m_localName.id() ? nullptr : m_data.attr;
178  }
179  DOMString namespaceURI() const
180  {
181  return m_localName.id() ? m_namespace.toString() : m_data.attr->namespaceURI();
182  }
183  DOMString prefix() const
184  {
185  return m_localName.id() ? m_prefix.toString() : m_data.attr->prefix();
186  }
187  DOMString localName() const
188  {
189  return m_localName.id() ? m_localName.toString() : m_data.attr->localName();
190  }
191  const PrefixName &prefixName() const
192  {
193  return m_localName.id() ? m_prefix : m_data.attr->prefixName();
194  }
195 
196  // for WebCore api compat
197  QualifiedName name() const
198  {
199  return m_localName.id() ? QualifiedName(m_prefix, m_localName, m_namespace) : QualifiedName(id(), PrefixName::fromString(prefix()));
200  }
201 
202  void setValue(DOMStringImpl *value, ElementImpl *element);
203  AttrImpl *createAttr(ElementImpl *element, DocumentImpl *docPtr);
204  void free();
205 
206  // See the description for AttrImpl.
207  void rewriteValue(const DOMString &newValue);
208 
209  LocalName m_localName;
210  NamespaceName m_namespace;
211  PrefixName m_prefix;
212  union {
213  DOMStringImpl *value;
214  AttrImpl *attr;
215  } m_data;
216 };
217 
218 struct CombinedStyleDecl {
219  DOM::CSSInlineStyleDeclarationImpl *inlineDecls;
220  DOM::CSSStyleDeclarationImpl *nonCSSDecls;
221 };
222 
223 class ElementImpl : public NodeBaseImpl
224 {
225  friend class DocumentImpl;
226  friend class NamedAttrMapImpl;
227  friend class AttrImpl;
228  friend class NodeImpl;
229  friend class khtml::CSSStyleSelector;
230 public:
231  ElementImpl(DocumentImpl *doc);
232  ~ElementImpl();
233 
234  // stuff for WebCore DOM & SVG api compatibility
235  bool hasTagName(const QualifiedName &name) const override
236  {
237  return qualifiedName() == name;/*should be matches here*/
238  }
239  QualifiedName qualifiedName() const
240  {
241  return QualifiedName(id(), m_prefix);
242  }
243  CSSInlineStyleDeclarationImpl *style()
244  {
245  return getInlineStyleDecls();
246  }
247  void setAttribute(const QualifiedName &name, const DOMString &value)
248  {
249  setAttribute(name.id(), value); /* is it enough for SVG or should the full setAttribute() be called? */
250  }
251  bool hasAttribute(const QualifiedName &name) const
252  {
253  return hasAttribute(name.tagName());
254  }
255  DOMString getAttribute(const QualifiedName &name) const
256  {
257  int ec;
258  return const_cast<ElementImpl *>(this)->getAttributeNS(name.namespaceURI(), name.localName(), ec);
259  }
260  DOMString getAttributeNS(const DOMString &namespaceURI, const DOMString &localName, int &exceptionCode) const
261  {
262  return const_cast<ElementImpl *>(this)->getAttributeNS(namespaceURI, localName, exceptionCode);
263  }
264  // FIXME: get rid of const_cast hacks (the const qualifiers of getAttribute should be reviewed
265  // as for external API it should look like const,hower we can replace AttributeImpl (small version)
266  // with normal AttrImpl (NodeImpl)
267  // END OF FIXME
268  // enf of WC api compatibility stuff
269 
270  //Higher-level DOM stuff
271  bool hasAttributes() const override;
272  bool hasAttribute(const DOMString &name) const;
273  bool hasAttributeNS(const DOMString &namespaceURI, const DOMString &localName) const;
274  DOMString getAttribute(const DOMString &name);
275  void setAttribute(const DOMString &name, const DOMString &value, int &exceptioncode);
276  void removeAttribute(const DOMString &name, int &exceptioncode);
277  void removeAttribute(NodeImpl::Id id, int &exceptioncode);
278  AttrImpl *getAttributeNode(const DOMString &name);
279  Attr setAttributeNode(AttrImpl *newAttr, int &exceptioncode);
280  Attr removeAttributeNode(AttrImpl *oldAttr, int &exceptioncode);
281 
282  DOMString getAttributeNS(const DOMString &namespaceURI, const DOMString &localName, int &exceptioncode);
283  void removeAttributeNS(const DOMString &namespaceURI, const DOMString &localName, int &exceptioncode);
284  AttrImpl *getAttributeNodeNS(const DOMString &namespaceURI, const DOMString &localName, int &exceptioncode);
285  Attr setAttributeNodeNS(AttrImpl *newAttr, int &exceptioncode);
286 
287  // At this level per WAI-ARIA
288  void blur();
289  void focus();
290 
291  //Lower-level implementation primitives
292  inline DOMString getAttribute(NodeImpl::Id id, const PrefixName &prefix = emptyPrefixName, bool nsAware = false) const
293  {
294  return DOMString(getAttributeImpl(id, prefix, nsAware));
295  }
296  inline DOMStringImpl *getAttributeImpl(NodeImpl::Id id, const PrefixName &prefix = emptyPrefixName, bool nsAware = false) const;
297  void setAttribute(NodeImpl::Id id, const PrefixName &prefix, bool nsAware, const DOMString &value, int &exceptioncode);
298  void setAttributeNS(const DOMString &namespaceURI, const DOMString &localName, const DOMString &value, int &exceptioncode);
299 
300  inline DOMStringImpl *getAttributeImplById(NodeImpl::Id id) const;
301 
302  // WebCore API
303  DOMString getIDAttribute() const
304  {
305  return getAttribute(ATTR_ID);
306  }
307  // End
308 
309  bool hasAttribute(NodeImpl::Id id, const PrefixName &prefix = emptyPrefixName, bool nsAware = false) const
310  {
311  return getAttributeImpl(id, prefix, nsAware) != nullptr;
312  }
313  DOMString prefix() const override
314  {
315  return m_prefix.toString();
316  }
317  void setPrefix(const DOMString &_prefix, int &exceptioncode) override;
318  DOMString namespaceURI() const override;
319  inline const PrefixName &prefixName() const
320  {
321  return m_prefix;
322  }
323 
324  short tabIndex() const override;
325  void setTabIndex(short _tabIndex);
326  void setNoTabIndex();
327  bool hasTabIndex() const;
328 
329  // DOM methods overridden from parent classes
330  virtual DOMString tagName() const;
331  DOMString localName() const override;
332 
333  // Internal version of tagName for elements that doesn't
334  // do case normalization
335  DOMString nonCaseFoldedTagName() const;
336 
337  unsigned short nodeType() const override;
338  WTF::PassRefPtr<NodeImpl> cloneNode(bool deep) override;
339  DOMString nodeName() const override;
340  NodeImpl::Id id() const override = 0;
341  bool isElementNode() const override
342  {
343  return true;
344  }
345  void insertedIntoDocument() override;
346  void removedFromDocument() override;
347 
348  // ElementTraversal API
349  ElementImpl *firstElementChild() const;
350  ElementImpl *lastElementChild() const;
351  ElementImpl *previousElementSibling() const;
352  ElementImpl *nextElementSibling() const;
353  unsigned childElementCount() const;
354 
355  // convenience methods which ignore exceptions
356  void setAttribute(NodeImpl::Id id, const DOMString &value);
357  void setBooleanAttribute(NodeImpl::Id id, bool b);
358 
359  NamedAttrMapImpl *attributes(bool readonly = false) const
360  {
361  if (m_needsStyleAttributeUpdate) {
362  synchronizeStyleAttribute();
363  }
364  if (!readonly && !namedAttrMap) {
365  createAttributeMap();
366  }
367  return namedAttrMap;
368  }
369 
370  //This is always called, whenever an attribute changed
371  virtual void parseAttribute(AttributeImpl *) {}
372  void parseNullAttribute(NodeImpl::Id id, PrefixName prefix)
373  {
374  AttributeImpl aimpl;
375  aimpl.m_localName = LocalName::fromId(localNamePart(id));
376  aimpl.m_namespace = NamespaceName::fromId(namespacePart(id));
377  aimpl.m_prefix = prefix;
378  aimpl.m_data.value = nullptr;
379  parseAttribute(&aimpl);
380  }
381 
382  void parseAttribute(AttrImpl *fullAttr)
383  {
384  AttributeImpl aimpl;
385  aimpl.m_localName = emptyLocalName;
386  aimpl.m_data.attr = fullAttr;
387  parseAttribute(&aimpl);
388  }
389 
390  inline const ClassNames &classNames() const;
391 
392  // not part of the DOM
393  void setAttributeMap(NamedAttrMapImpl *list);
394 
395  // State of the element.
396  QString state() override
397  {
398  return QString();
399  }
400 
401  virtual void copyNonAttributeProperties(const ElementImpl * /*source*/) {}
402 
403  void attach() override;
404  void close() override;
405  void detach() override;
406  void structureChanged() override;
407  void backwardsStructureChanged() override;
408  virtual void attributeChanged(NodeImpl::Id attrId);
409  // for WebCore API compatibility
410  virtual void attributeChanged(AttributeImpl *attribute, bool /*preserveDecls*/)
411  {
412  attributeChanged(attribute->id());
413  }
414 
415  void defaultEventHandler(EventImpl *evt) override;
416 
417  khtml::RenderStyle *styleForRenderer(khtml::RenderObject *parent) override;
418  khtml::RenderObject *createRenderer(khtml::RenderArena *, khtml::RenderStyle *) override;
419  void recalcStyle(StyleChange = NoChange) override;
420  khtml::RenderStyle *computedStyle() override;
421 
422  virtual void mouseEventHandler(MouseEvent * /*ev*/, bool /*inside*/) {}
423 
424  bool childAllowed(NodeImpl *newChild) override;
425  bool childTypeAllowed(unsigned short type) override;
426  DOM::CSSInlineStyleDeclarationImpl *inlineStyleDecls() const
427  {
428  return m_hasCombinedStyle ? m_style.combinedDecls->inlineDecls : m_style.inlineDecls;
429  }
430  DOM::CSSStyleDeclarationImpl *nonCSSStyleDecls() const
431  {
432  return m_hasCombinedStyle ? m_style.combinedDecls->nonCSSDecls : nullptr;
433  }
434  DOM::CSSInlineStyleDeclarationImpl *getInlineStyleDecls();
435 
436  void dispatchAttrRemovalEvent(NodeImpl::Id id, DOMStringImpl *value);
437  void dispatchAttrAdditionEvent(NodeImpl::Id id, DOMStringImpl *value);
438 
439  DOMString toString() const override;
440  DOMString selectionToString(NodeImpl *selectionStart, NodeImpl *selectionEnd, int startOffset, int endOffset, bool &found) const override;
441 
442  bool isFocusableImpl(FocusType ft) const override;
443  bool isContentEditable() const override;
444  void setContentEditable(bool enabled);
445 
446  void scrollIntoView(bool alignToTop);
447 
448  /** Returns the opening tag and properties.
449  * Examples: '<b', '<img alt="hello" src="image.png"
450  *
451  * For security reasons, passwords are stripped out of all src= and
452  * href= tags if expandurls is turned on.
453  *
454  * @param expandurls If this is set then in the above example, it would give
455  * src="http://website.com/image.png". Note that the password
456  * is stripped out of the url.
457  *
458  * DOM::RangeImpl uses this which is why it is public.
459  */
460  DOMString openTagStartToString(bool expandurls = false) const;
461 
462  void updateId(DOMStringImpl *oldId, DOMStringImpl *newId);
463  //Called when mapping from id to this node in document should be removed
464  virtual void removeId(const DOMString &id);
465  //Called when mapping from id to this node in document should be added
466  virtual void addId(const DOMString &id);
467 
468  // Synchronize style attribute after it was changed via CSSOM
469  void synchronizeStyleAttribute() const;
470 
471 protected:
472  void createAttributeMap() const;
473  void createInlineDecl(); // for inline styles
474  void createNonCSSDecl(); // for presentational styles
475  void finishCloneNode(ElementImpl *clone, bool deep);
476 
477 private:
478  // There is some information such as computed style for display:none
479  // elements that is needed only for a few elements. We store it
480  // in one of these.
481  ElementRareDataImpl *rareData();
482  const ElementRareDataImpl *rareData() const;
483  ElementRareDataImpl *createRareData();
484 
485 protected: // member variables
486  mutable NamedAttrMapImpl *namedAttrMap;
487 
488  union {
489  DOM::CSSInlineStyleDeclarationImpl *inlineDecls;
490  CombinedStyleDecl *combinedDecls;
491  } m_style;
492  PrefixName m_prefix;
493 };
494 
495 class XMLElementImpl : public ElementImpl
496 {
497 
498 public:
499  XMLElementImpl(DocumentImpl *doc, NamespaceName namespacename, LocalName localName, PrefixName prefix);
500  ~XMLElementImpl();
501 
502  void parseAttribute(AttributeImpl *attr) override;
503 
504  WTF::PassRefPtr<NodeImpl> cloneNode(bool deep) override;
505 
506  // Other methods (not part of DOM)
507  bool isXMLElementNode() const override
508  {
509  return true;
510  }
511  Id id() const override
512  {
513  return makeId(m_namespace.id(), m_localName.id());
514  }
515 
516 protected:
517  LocalName m_localName;
518  NamespaceName m_namespace;
519 };
520 
521 // the map of attributes of an element
522 class NamedAttrMapImpl : public NamedNodeMapImpl
523 {
524  friend class ElementImpl;
525 public:
526  NamedAttrMapImpl(ElementImpl *element);
527  virtual ~NamedAttrMapImpl();
528 
529  // DOM methods & attributes for NamedNodeMap
530  NodeImpl *getNamedItem(NodeImpl::Id id, const PrefixName &prefix = emptyPrefixName, bool nsAware = false) override;
531  Node removeNamedItem(NodeImpl::Id id, const PrefixName &prefix, bool nsAware, int &exceptioncode) override;
532  Node setNamedItem(NodeImpl *arg, const PrefixName &prefix, bool nsAware, int &exceptioncode) override;
533 
534  // for WebCore api compat
535  virtual NodeImpl *getNamedItem(const QualifiedName &name)
536  {
537  return getNamedItem(name.id(), name.prefixId(), true);
538  }
539 
540  NodeImpl *item(unsigned index) override;
541  unsigned length() const override
542  {
543  return m_attrs.size();
544  }
545 
546  // Other methods (not part of DOM)
547  bool isReadOnly() override
548  {
549  return false;
550  }
551  bool htmlCompat() override
552  {
553  return m_element ? m_element->m_htmlCompat : false;
554  }
555 
556  AttributeImpl &attributeAt(unsigned index)
557  {
558  return m_attrs[index];
559  }
560  const AttributeImpl &attributeAt(unsigned index) const
561  {
562  return m_attrs[index];
563  }
564  AttrImpl *attrAt(unsigned index) const
565  {
566  return m_attrs[index].attr();
567  }
568  // ### replace idAt and getValueAt with attrAt
569  NodeImpl::Id idAt(unsigned index) const;
570  DOMStringImpl *valueAt(unsigned index) const;
571  DOMStringImpl *getValue(NodeImpl::Id id, const PrefixName &prefix = emptyPrefixName, bool nsAware = false) const;
572  void setValue(NodeImpl::Id id, DOMStringImpl *value, const PrefixName &prefix = emptyPrefixName, bool nsAware = false);
573  Attr removeAttr(AttrImpl *attr);
574  void copyAttributes(NamedAttrMapImpl *other);
575  void setElement(ElementImpl *element);
576  void detachFromElement();
577 
578  int find(NodeImpl::Id id, const PrefixName &prefix, bool nsAware) const;
579  inline DOMStringImpl *fastFind(NodeImpl::Id id) const;
580 
581  inline void clearClass()
582  {
583  m_classNames.clear();
584  }
585  void setClass(const DOMString &string);
586  inline const ClassNames &classNames() const
587  {
588  return m_classNames;
589  }
590 
591  // Rewrites value if attribute already exists or adds a new attribute otherwise
592  // @important: any changes won't be propagated to parent Element
593  void setValueWithoutElementUpdate(NodeImpl::Id id, DOMStringImpl *value);
594 
595 protected:
596  ElementImpl *m_element;
597  WTF::Vector<AttributeImpl> m_attrs;
598  ClassNames m_classNames;
599 };
600 
601 // ------------ inline DOM helper functions ---------------
602 
603 inline bool checkQualifiedName(const DOMString &qualifiedName, const DOMString &namespaceURI, int *colonPos,
604  bool nameCanBeNull, bool nameCanBeEmpty, int *pExceptioncode)
605 {
606 
607  // Not mentioned in spec: throw NAMESPACE_ERR if no qualifiedName supplied
608  if (!nameCanBeNull && qualifiedName.isNull()) {
609  if (pExceptioncode) {
610  *pExceptioncode = DOMException::NAMESPACE_ERR;
611  }
612  return false;
613  }
614 
615  // INVALID_CHARACTER_ERR: Raised if the specified qualified name contains an illegal character.
616  if (!qualifiedName.isNull() && !Element::khtmlValidQualifiedName(qualifiedName)
617  && (!qualifiedName.isEmpty() || !nameCanBeEmpty)) {
618  if (pExceptioncode) {
619  *pExceptioncode = DOMException::INVALID_CHARACTER_ERR;
620  }
621  return false;
622  }
623 
624  // NAMESPACE_ERR:
625  // - Raised if the qualifiedName is malformed,
626  // - if the qualifiedName has a prefix and the namespaceURI is null, or
627  // - if the qualifiedName is null and the namespaceURI is different from null
628  // - if the qualifiedName has a prefix that is "xml" and the namespaceURI is different
629  // from "http://www.w3.org/XML/1998/namespace" [Namespaces].
630  int colonpos = -1;
631  uint i;
632  DOMStringImpl *qname = qualifiedName.implementation();
633  for (i = 0; i < (qname ? qname->l : 0); i++) {
634  if ((*qname)[i] == QLatin1Char(':')) {
635  colonpos = i;
636  break;
637  }
638  }
639 
640  bool hasXMLPrefix = colonpos == 3 && (*qname)[0] == QLatin1Char('x') &&
641  (*qname)[1] == QLatin1Char('m') && (*qname)[2] == QLatin1Char('l');
642  bool hasXMLNSPrefix = colonpos == 5 && (*qname)[0] == QLatin1Char('x') &&
643  (*qname)[1] == QLatin1Char('m') && (*qname)[2] == QLatin1Char('l') &&
644  (*qname)[3] == QLatin1Char('n') && (*qname)[4] == QLatin1Char('s');
645 
646  if ((!qualifiedName.isNull() && Element::khtmlMalformedQualifiedName(qualifiedName)) ||
647  (colonpos >= 0 && namespaceURI.isNull()) ||
648  colonpos == 0 || // prefix has to consist of at least a letter
649  (qualifiedName.isNull() && !namespaceURI.isNull()) ||
650  (hasXMLPrefix && namespaceURI != XML_NAMESPACE) ||
651  (hasXMLNSPrefix && namespaceURI != XMLNS_NAMESPACE) ||
652  (namespaceURI == XMLNS_NAMESPACE && !hasXMLNSPrefix && qualifiedName != "xmlns")) {
653  if (pExceptioncode) {
654  *pExceptioncode = DOMException::NAMESPACE_ERR;
655  }
656  return false;
657  }
658  if (colonPos) {
659  *colonPos = colonpos;
660  }
661  return true;
662 }
663 
664 inline void splitPrefixLocalName(DOMStringImpl *qualifiedName, DOMString &prefix, DOMString &localName, int colonPos = -2)
665 {
666  if (colonPos == -2)
667  for (uint i = 0; i < qualifiedName->l; ++i)
668  if (qualifiedName->s[i] == QLatin1Char(':')) {
669  colonPos = i;
670  break;
671  }
672  if (colonPos >= 0) {
673  prefix = qualifiedName->copy();
674  localName = prefix.split(colonPos + 1);
675  prefix.implementation()->truncate(colonPos);
676  } else {
677  localName = qualifiedName;
678  }
679 }
680 
681 inline void splitPrefixLocalName(const DOMString &qualifiedName, PrefixName &prefix, LocalName &localName, bool htmlCompat = false, int colonPos = -2)
682 {
683  DOMString localname, prefixname;
684  splitPrefixLocalName(qualifiedName.implementation(), prefixname, localname, colonPos);
685  if (htmlCompat) {
686  prefix = PrefixName::fromString(prefixname, khtml::IDS_NormalizeLower);
687  localName = LocalName::fromString(localname, khtml::IDS_NormalizeLower);
688  } else {
689  prefix = PrefixName::fromString(prefixname);
690  localName = LocalName::fromString(localname);
691  }
692 }
693 
694 // methods that could be very hot and therefore need to be inlined
695 inline DOMStringImpl *ElementImpl::getAttributeImpl(NodeImpl::Id id, const PrefixName &prefix, bool nsAware) const
696 {
697  if (m_needsStyleAttributeUpdate && (id == ATTR_STYLE)) {
698  synchronizeStyleAttribute();
699  }
700  return namedAttrMap ? namedAttrMap->getValue(id, prefix, nsAware) : nullptr;
701 }
702 
703 inline const ClassNames &ElementImpl::classNames() const
704 {
705  // hasClass() should be called on element first as in CSSStyleSelector::checkSimpleSelector
706  return namedAttrMap->classNames();
707 }
708 
709 inline DOMStringImpl *ElementImpl::getAttributeImplById(NodeImpl::Id id) const
710 {
711  return namedAttrMap ? namedAttrMap->fastFind(id) : nullptr;
712 }
713 
714 inline DOMStringImpl *NamedAttrMapImpl::fastFind(NodeImpl::Id id) const
715 {
716  unsigned mask = anyQName;
717  if (namespacePart(id) == anyNamespace) {
718  mask = anyLocalName;
719  id = localNamePart(id);
720  }
721  unsigned len = m_attrs.size();
722  for (unsigned i = 0; i < len; ++i)
723  if (id == (m_attrs[i].id() & mask)) {
724  return m_attrs[i].val();
725  }
726  return nullptr;
727 }
728 
729 } //namespace
730 
731 #endif
DOMString split(unsigned int pos)
Splits the string into two.
Definition: dom_string.cpp:224
QString name(const QVariant &location)
This file is part of the HTML rendering engine for KDE.
StandardShortcut find(const QKeySequence &keySeq)
const QList< QKeySequence > & close()
This class implements the basic string we use in the DOM.
Definition: dom_string.h:44
the StyleSelector implementation for CSS.
int64_t Id
This library provides a full-featured HTML parser and widget.
char * toString(const T &value)
Base Class for all rendering tree objects.
DOMStringImpl * implementation() const
Definition: dom_string.h:145
This file is part of the KDE documentation.
Documentation copyright © 1996-2021 The KDE developers.
Generated on Tue Oct 26 2021 22:48:00 by doxygen 1.8.11 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.