OLD | NEW |
1 /* | 1 /* |
2 * Copyright (C) 1999 Lars Knoll (knoll@kde.org) | 2 * Copyright (C) 1999 Lars Knoll (knoll@kde.org) |
3 * (C) 1999 Antti Koivisto (koivisto@kde.org) | 3 * (C) 1999 Antti Koivisto (koivisto@kde.org) |
4 * Copyright (C) 2004, 2005, 2006, 2007, 2008 Apple Inc. All rights reserved. | 4 * Copyright (C) 2004, 2005, 2006, 2007, 2008 Apple Inc. All rights reserved. |
5 * Copyright (C) 2009 Torch Mobile Inc. All rights reserved. (http://www.torchmo
bile.com/) | 5 * Copyright (C) 2009 Torch Mobile Inc. All rights reserved. (http://www.torchmo
bile.com/) |
6 * Copyright (C) 2011 Motorola Mobility. All rights reserved. | 6 * Copyright (C) 2011 Motorola Mobility. All rights reserved. |
7 * | 7 * |
8 * This library is free software; you can redistribute it and/or | 8 * This library is free software; you can redistribute it and/or |
9 * modify it under the terms of the GNU Library General Public | 9 * modify it under the terms of the GNU Library General Public |
10 * License as published by the Free Software Foundation; either | 10 * License as published by the Free Software Foundation; either |
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
67 PassRefPtr<HTMLElement> HTMLElement::create(const QualifiedName& tagName, Docume
nt* document) | 67 PassRefPtr<HTMLElement> HTMLElement::create(const QualifiedName& tagName, Docume
nt* document) |
68 { | 68 { |
69 return adoptRef(new HTMLElement(tagName, document)); | 69 return adoptRef(new HTMLElement(tagName, document)); |
70 } | 70 } |
71 | 71 |
72 String HTMLElement::nodeName() const | 72 String HTMLElement::nodeName() const |
73 { | 73 { |
74 // FIXME: Would be nice to have an atomicstring lookup based off uppercase | 74 // FIXME: Would be nice to have an atomicstring lookup based off uppercase |
75 // chars that does not have to copy the string on a hit in the hash. | 75 // chars that does not have to copy the string on a hit in the hash. |
76 // FIXME: We should have a way to detect XHTML elements and replace the hasP
refix() check with it. | 76 // FIXME: We should have a way to detect XHTML elements and replace the hasP
refix() check with it. |
77 if (document()->isHTMLDocument() && !tagQName().hasPrefix()) | 77 if (document().isHTMLDocument() && !tagQName().hasPrefix()) |
78 return tagQName().localNameUpper(); | 78 return tagQName().localNameUpper(); |
79 return Element::nodeName(); | 79 return Element::nodeName(); |
80 } | 80 } |
81 | 81 |
82 bool HTMLElement::ieForbidsInsertHTML() const | 82 bool HTMLElement::ieForbidsInsertHTML() const |
83 { | 83 { |
84 // FIXME: Supposedly IE disallows settting innerHTML, outerHTML | 84 // FIXME: Supposedly IE disallows settting innerHTML, outerHTML |
85 // and createContextualFragment on these tags. We have no tests to | 85 // and createContextualFragment on these tags. We have no tests to |
86 // verify this however, so this list could be totally wrong. | 86 // verify this however, so this list could be totally wrong. |
87 // This list was moved from the previous endTagRequirement() implementation. | 87 // This list was moved from the previous endTagRequirement() implementation. |
(...skipping 200 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
288 | 288 |
289 if (name == dirAttr) | 289 if (name == dirAttr) |
290 dirAttributeChanged(value); | 290 dirAttributeChanged(value); |
291 else if (name == tabindexAttr) { | 291 else if (name == tabindexAttr) { |
292 int tabindex = 0; | 292 int tabindex = 0; |
293 if (value.isEmpty()) { | 293 if (value.isEmpty()) { |
294 clearTabIndexExplicitlyIfNeeded(); | 294 clearTabIndexExplicitlyIfNeeded(); |
295 if (treeScope()->adjustedFocusedElement() == this) { | 295 if (treeScope()->adjustedFocusedElement() == this) { |
296 // We might want to call blur(), but it's dangerous to dispatch | 296 // We might want to call blur(), but it's dangerous to dispatch |
297 // events here. | 297 // events here. |
298 document()->setNeedsFocusedElementCheck(); | 298 document().setNeedsFocusedElementCheck(); |
299 } | 299 } |
300 } else if (parseHTMLInteger(value, tabindex)) { | 300 } else if (parseHTMLInteger(value, tabindex)) { |
301 // Clamp tabindex to the range of 'short' to match Firefox's behavio
r. | 301 // Clamp tabindex to the range of 'short' to match Firefox's behavio
r. |
302 setTabIndexExplicitly(max(static_cast<int>(std::numeric_limits<short
>::min()), min(tabindex, static_cast<int>(std::numeric_limits<short>::max())))); | 302 setTabIndexExplicitly(max(static_cast<int>(std::numeric_limits<short
>::min()), min(tabindex, static_cast<int>(std::numeric_limits<short>::max())))); |
303 } | 303 } |
304 } else { | 304 } else { |
305 AtomicString eventName = eventNameForAttributeName(name); | 305 AtomicString eventName = eventNameForAttributeName(name); |
306 if (!eventName.isNull()) | 306 if (!eventName.isNull()) |
307 setAttributeEventListener(eventName, createAttributeEventListener(th
is, name, value)); | 307 setAttributeEventListener(eventName, createAttributeEventListener(th
is, name, value)); |
308 } | 308 } |
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
361 RefPtr<Node> node = next ? next->previousSibling() : 0; | 361 RefPtr<Node> node = next ? next->previousSibling() : 0; |
362 if (!es.hadException() && node && node->isTextNode()) | 362 if (!es.hadException() && node && node->isTextNode()) |
363 mergeWithNextTextNode(node.release(), es); | 363 mergeWithNextTextNode(node.release(), es); |
364 | 364 |
365 if (!es.hadException() && prev && prev->isTextNode()) | 365 if (!es.hadException() && prev && prev->isTextNode()) |
366 mergeWithNextTextNode(prev.release(), es); | 366 mergeWithNextTextNode(prev.release(), es); |
367 } | 367 } |
368 | 368 |
369 PassRefPtr<DocumentFragment> HTMLElement::textToFragment(const String& text, Exc
eptionState& es) | 369 PassRefPtr<DocumentFragment> HTMLElement::textToFragment(const String& text, Exc
eptionState& es) |
370 { | 370 { |
371 RefPtr<DocumentFragment> fragment = DocumentFragment::create(document()); | 371 RefPtr<DocumentFragment> fragment = DocumentFragment::create(&document()); |
372 unsigned int i, length = text.length(); | 372 unsigned int i, length = text.length(); |
373 UChar c = 0; | 373 UChar c = 0; |
374 for (unsigned int start = 0; start < length; ) { | 374 for (unsigned int start = 0; start < length; ) { |
375 | 375 |
376 // Find next line break. | 376 // Find next line break. |
377 for (i = start; i < length; i++) { | 377 for (i = start; i < length; i++) { |
378 c = text[i]; | 378 c = text[i]; |
379 if (c == '\r' || c == '\n') | 379 if (c == '\r' || c == '\n') |
380 break; | 380 break; |
381 } | 381 } |
382 | 382 |
383 fragment->appendChild(Text::create(document(), text.substring(start, i -
start)), es); | 383 fragment->appendChild(Text::create(&document(), text.substring(start, i
- start)), es); |
384 if (es.hadException()) | 384 if (es.hadException()) |
385 return 0; | 385 return 0; |
386 | 386 |
387 if (c == '\r' || c == '\n') { | 387 if (c == '\r' || c == '\n') { |
388 fragment->appendChild(HTMLBRElement::create(document()), es); | 388 fragment->appendChild(HTMLBRElement::create(&document()), es); |
389 if (es.hadException()) | 389 if (es.hadException()) |
390 return 0; | 390 return 0; |
391 // Make sure \r\n doesn't result in two line breaks. | 391 // Make sure \r\n doesn't result in two line breaks. |
392 if (c == '\r' && i + 1 < length && text[i + 1] == '\n') | 392 if (c == '\r' && i + 1 < length && text[i + 1] == '\n') |
393 i++; | 393 i++; |
394 } | 394 } |
395 | 395 |
396 start = i + 1; // Character after line break. | 396 start = i + 1; // Character after line break. |
397 } | 397 } |
398 | 398 |
(...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
467 } | 467 } |
468 | 468 |
469 RefPtr<Node> prev = previousSibling(); | 469 RefPtr<Node> prev = previousSibling(); |
470 RefPtr<Node> next = nextSibling(); | 470 RefPtr<Node> next = nextSibling(); |
471 RefPtr<Node> newChild; | 471 RefPtr<Node> newChild; |
472 | 472 |
473 // Convert text to fragment with <br> tags instead of linebreaks if needed. | 473 // Convert text to fragment with <br> tags instead of linebreaks if needed. |
474 if (text.contains('\r') || text.contains('\n')) | 474 if (text.contains('\r') || text.contains('\n')) |
475 newChild = textToFragment(text, es); | 475 newChild = textToFragment(text, es); |
476 else | 476 else |
477 newChild = Text::create(document(), text); | 477 newChild = Text::create(&document(), text); |
478 | 478 |
479 if (!this || !parentNode()) | 479 if (!this || !parentNode()) |
480 es.throwDOMException(HierarchyRequestError); | 480 es.throwDOMException(HierarchyRequestError); |
481 if (es.hadException()) | 481 if (es.hadException()) |
482 return; | 482 return; |
483 parent->replaceChild(newChild.release(), this, es); | 483 parent->replaceChild(newChild.release(), this, es); |
484 | 484 |
485 RefPtr<Node> node = next ? next->previousSibling() : 0; | 485 RefPtr<Node> node = next ? next->previousSibling() : 0; |
486 if (!es.hadException() && node && node->isTextNode()) | 486 if (!es.hadException() && node && node->isTextNode()) |
487 mergeWithNextTextNode(node.release(), es); | 487 mergeWithNextTextNode(node.release(), es); |
(...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
567 if (!contextElement) | 567 if (!contextElement) |
568 return; | 568 return; |
569 RefPtr<DocumentFragment> fragment = createFragmentForInnerOuterHTML(markup,
contextElement, AllowScriptingContent, es); | 569 RefPtr<DocumentFragment> fragment = createFragmentForInnerOuterHTML(markup,
contextElement, AllowScriptingContent, es); |
570 if (!fragment) | 570 if (!fragment) |
571 return; | 571 return; |
572 insertAdjacent(where, fragment.get(), es); | 572 insertAdjacent(where, fragment.get(), es); |
573 } | 573 } |
574 | 574 |
575 void HTMLElement::insertAdjacentText(const String& where, const String& text, Ex
ceptionState& es) | 575 void HTMLElement::insertAdjacentText(const String& where, const String& text, Ex
ceptionState& es) |
576 { | 576 { |
577 RefPtr<Text> textNode = document()->createTextNode(text); | 577 RefPtr<Text> textNode = document().createTextNode(text); |
578 insertAdjacent(where, textNode.get(), es); | 578 insertAdjacent(where, textNode.get(), es); |
579 } | 579 } |
580 | 580 |
581 void HTMLElement::applyAlignmentAttributeToStyle(const AtomicString& alignment,
MutableStylePropertySet* style) | 581 void HTMLElement::applyAlignmentAttributeToStyle(const AtomicString& alignment,
MutableStylePropertySet* style) |
582 { | 582 { |
583 // Vertical alignment with respect to the current baseline of the text | 583 // Vertical alignment with respect to the current baseline of the text |
584 // right or left means floating images. | 584 // right or left means floating images. |
585 CSSValueID floatValue = CSSValueInvalid; | 585 CSSValueID floatValue = CSSValueInvalid; |
586 CSSValueID verticalAlignValue = CSSValueInvalid; | 586 CSSValueID verticalAlignValue = CSSValueInvalid; |
587 | 587 |
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
619 } | 619 } |
620 | 620 |
621 bool HTMLElement::supportsSpatialNavigationFocus() const | 621 bool HTMLElement::supportsSpatialNavigationFocus() const |
622 { | 622 { |
623 // This function checks whether the element satisfies the extended criteria | 623 // This function checks whether the element satisfies the extended criteria |
624 // for the element to be focusable, introduced by spatial navigation feature
, | 624 // for the element to be focusable, introduced by spatial navigation feature
, |
625 // i.e. checks if click or keyboard event handler is specified. | 625 // i.e. checks if click or keyboard event handler is specified. |
626 // This is the way to make it possible to navigate to (focus) elements | 626 // This is the way to make it possible to navigate to (focus) elements |
627 // which web designer meant for being active (made them respond to click eve
nts). | 627 // which web designer meant for being active (made them respond to click eve
nts). |
628 | 628 |
629 if (!document()->settings() || !document()->settings()->spatialNavigationEna
bled()) | 629 if (!document().settings() || !document().settings()->spatialNavigationEnabl
ed()) |
630 return false; | 630 return false; |
631 EventTarget* target = const_cast<HTMLElement*>(this); | 631 EventTarget* target = const_cast<HTMLElement*>(this); |
632 return target->hasEventListeners(eventNames().clickEvent) | 632 return target->hasEventListeners(eventNames().clickEvent) |
633 || target->hasEventListeners(eventNames().keydownEvent) | 633 || target->hasEventListeners(eventNames().keydownEvent) |
634 || target->hasEventListeners(eventNames().keypressEvent) | 634 || target->hasEventListeners(eventNames().keypressEvent) |
635 || target->hasEventListeners(eventNames().keyupEvent); | 635 || target->hasEventListeners(eventNames().keyupEvent); |
636 } | 636 } |
637 | 637 |
638 bool HTMLElement::supportsFocus() const | 638 bool HTMLElement::supportsFocus() const |
639 { | 639 { |
(...skipping 115 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
755 } | 755 } |
756 | 756 |
757 void HTMLElement::setTranslate(bool enable) | 757 void HTMLElement::setTranslate(bool enable) |
758 { | 758 { |
759 setAttribute(translateAttr, enable ? "yes" : "no"); | 759 setAttribute(translateAttr, enable ? "yes" : "no"); |
760 } | 760 } |
761 | 761 |
762 bool HTMLElement::rendererIsNeeded(const NodeRenderingContext& context) | 762 bool HTMLElement::rendererIsNeeded(const NodeRenderingContext& context) |
763 { | 763 { |
764 if (hasLocalName(noscriptTag)) { | 764 if (hasLocalName(noscriptTag)) { |
765 Frame* frame = document()->frame(); | 765 Frame* frame = document().frame(); |
766 if (frame && frame->script()->canExecuteScripts(NotAboutToExecuteScript)
) | 766 if (frame && frame->script()->canExecuteScripts(NotAboutToExecuteScript)
) |
767 return false; | 767 return false; |
768 } else if (hasLocalName(noembedTag)) { | 768 } else if (hasLocalName(noembedTag)) { |
769 Frame* frame = document()->frame(); | 769 Frame* frame = document().frame(); |
770 if (frame && frame->loader()->allowPlugins(NotAboutToInstantiatePlugin)) | 770 if (frame && frame->loader()->allowPlugins(NotAboutToInstantiatePlugin)) |
771 return false; | 771 return false; |
772 } | 772 } |
773 return Element::rendererIsNeeded(context); | 773 return Element::rendererIsNeeded(context); |
774 } | 774 } |
775 | 775 |
776 RenderObject* HTMLElement::createRenderer(RenderStyle* style) | 776 RenderObject* HTMLElement::createRenderer(RenderStyle* style) |
777 { | 777 { |
778 if (hasLocalName(wbrTag)) | 778 if (hasLocalName(wbrTag)) |
779 return new RenderWordBreak(this); | 779 return new RenderWordBreak(this); |
(...skipping 142 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
922 { | 922 { |
923 Node* strongDirectionalityTextNode; | 923 Node* strongDirectionalityTextNode; |
924 TextDirection textDirection = directionality(&strongDirectionalityTextNode); | 924 TextDirection textDirection = directionality(&strongDirectionalityTextNode); |
925 setHasDirAutoFlagRecursively(this, true, strongDirectionalityTextNode); | 925 setHasDirAutoFlagRecursively(this, true, strongDirectionalityTextNode); |
926 if (renderer() && renderer()->style() && renderer()->style()->direction() !=
textDirection) | 926 if (renderer() && renderer()->style() && renderer()->style()->direction() !=
textDirection) |
927 setNeedsStyleRecalc(); | 927 setNeedsStyleRecalc(); |
928 } | 928 } |
929 | 929 |
930 void HTMLElement::adjustDirectionalityIfNeededAfterChildrenChanged(Node* beforeC
hange, int childCountDelta) | 930 void HTMLElement::adjustDirectionalityIfNeededAfterChildrenChanged(Node* beforeC
hange, int childCountDelta) |
931 { | 931 { |
932 if (document()->renderer() && childCountDelta < 0) { | 932 if (document().renderer() && childCountDelta < 0) { |
933 Node* node = beforeChange ? NodeTraversal::nextSkippingChildren(beforeCh
ange) : 0; | 933 Node* node = beforeChange ? NodeTraversal::nextSkippingChildren(beforeCh
ange) : 0; |
934 for (int counter = 0; node && counter < childCountDelta; counter++, node
= NodeTraversal::nextSkippingChildren(node)) { | 934 for (int counter = 0; node && counter < childCountDelta; counter++, node
= NodeTraversal::nextSkippingChildren(node)) { |
935 if (elementAffectsDirectionality(node)) | 935 if (elementAffectsDirectionality(node)) |
936 continue; | 936 continue; |
937 | 937 |
938 setHasDirAutoFlagRecursively(node, false); | 938 setHasDirAutoFlagRecursively(node, false); |
939 } | 939 } |
940 } | 940 } |
941 | 941 |
942 if (!selfOrAncestorHasDirAutoAttribute()) | 942 if (!selfOrAncestorHasDirAutoAttribute()) |
(...skipping 130 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1073 handleKeypressEvent(toKeyboardEvent(event)); | 1073 handleKeypressEvent(toKeyboardEvent(event)); |
1074 if (event->defaultHandled()) | 1074 if (event->defaultHandled()) |
1075 return; | 1075 return; |
1076 } | 1076 } |
1077 | 1077 |
1078 Element::defaultEventHandler(event); | 1078 Element::defaultEventHandler(event); |
1079 } | 1079 } |
1080 | 1080 |
1081 void HTMLElement::handleKeypressEvent(KeyboardEvent* event) | 1081 void HTMLElement::handleKeypressEvent(KeyboardEvent* event) |
1082 { | 1082 { |
1083 if (!document()->settings() || !document()->settings()->spatialNavigationEna
bled() || !supportsFocus()) | 1083 if (!document().settings() || !document().settings()->spatialNavigationEnabl
ed() || !supportsFocus()) |
1084 return; | 1084 return; |
1085 // if the element is a text form control (like <input type=text> or <textare
a>) | 1085 // if the element is a text form control (like <input type=text> or <textare
a>) |
1086 // or has contentEditable attribute on, we should enter a space or newline | 1086 // or has contentEditable attribute on, we should enter a space or newline |
1087 // even in spatial navigation mode instead of handling it as a "click" actio
n. | 1087 // even in spatial navigation mode instead of handling it as a "click" actio
n. |
1088 if (isTextFormControl() || isContentEditable()) | 1088 if (isTextFormControl() || isContentEditable()) |
1089 return; | 1089 return; |
1090 int charCode = event->charCode(); | 1090 int charCode = event->charCode(); |
1091 if (charCode == '\r' || charCode == ' ') { | 1091 if (charCode == '\r' || charCode == ' ') { |
1092 dispatchSimulatedClick(event); | 1092 dispatchSimulatedClick(event); |
1093 event->setDefaultHandled(); | 1093 event->setDefaultHandled(); |
1094 } | 1094 } |
1095 } | 1095 } |
1096 | 1096 |
1097 } // namespace WebCore | 1097 } // namespace WebCore |
1098 | 1098 |
1099 #ifndef NDEBUG | 1099 #ifndef NDEBUG |
1100 | 1100 |
1101 // For use in the debugger | 1101 // For use in the debugger |
1102 void dumpInnerHTML(WebCore::HTMLElement*); | 1102 void dumpInnerHTML(WebCore::HTMLElement*); |
1103 | 1103 |
1104 void dumpInnerHTML(WebCore::HTMLElement* element) | 1104 void dumpInnerHTML(WebCore::HTMLElement* element) |
1105 { | 1105 { |
1106 printf("%s\n", element->innerHTML().ascii().data()); | 1106 printf("%s\n", element->innerHTML().ascii().data()); |
1107 } | 1107 } |
1108 #endif | 1108 #endif |
OLD | NEW |