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 11 matching lines...) Expand all Loading... |
22 * | 22 * |
23 */ | 23 */ |
24 | 24 |
25 #include "config.h" | 25 #include "config.h" |
26 #include "core/html/HTMLElement.h" | 26 #include "core/html/HTMLElement.h" |
27 | 27 |
28 #include "CSSPropertyNames.h" | 28 #include "CSSPropertyNames.h" |
29 #include "CSSValueKeywords.h" | 29 #include "CSSValueKeywords.h" |
30 #include "HTMLNames.h" | 30 #include "HTMLNames.h" |
31 #include "XMLNames.h" | 31 #include "XMLNames.h" |
32 #include "bindings/v8/ExceptionMessages.h" | |
33 #include "bindings/v8/ExceptionState.h" | 32 #include "bindings/v8/ExceptionState.h" |
34 #include "bindings/v8/ScriptController.h" | 33 #include "bindings/v8/ScriptController.h" |
35 #include "bindings/v8/ScriptEventListener.h" | 34 #include "bindings/v8/ScriptEventListener.h" |
36 #include "core/css/CSSParser.h" | 35 #include "core/css/CSSParser.h" |
37 #include "core/css/CSSValuePool.h" | 36 #include "core/css/CSSValuePool.h" |
38 #include "core/css/StylePropertySet.h" | 37 #include "core/css/StylePropertySet.h" |
39 #include "core/dom/DocumentFragment.h" | 38 #include "core/dom/DocumentFragment.h" |
40 #include "core/dom/ExceptionCode.h" | 39 #include "core/dom/ExceptionCode.h" |
41 #include "core/dom/NodeTraversal.h" | 40 #include "core/dom/NodeTraversal.h" |
42 #include "core/dom/Text.h" | 41 #include "core/dom/Text.h" |
(...skipping 312 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
355 | 354 |
356 start = i + 1; // Character after line break. | 355 start = i + 1; // Character after line break. |
357 } | 356 } |
358 | 357 |
359 return fragment; | 358 return fragment; |
360 } | 359 } |
361 | 360 |
362 void HTMLElement::setInnerText(const String& text, ExceptionState& exceptionStat
e) | 361 void HTMLElement::setInnerText(const String& text, ExceptionState& exceptionStat
e) |
363 { | 362 { |
364 if (ieForbidsInsertHTML()) { | 363 if (ieForbidsInsertHTML()) { |
365 exceptionState.throwDOMException(NoModificationAllowedError, ExceptionMe
ssages::failedToSet("innerText", "HTMLElement", "The '" + localName() + "' eleme
nt does not support text insertion.")); | 364 exceptionState.throwDOMException(NoModificationAllowedError, "The '" + l
ocalName() + "' element does not support text insertion."); |
366 return; | 365 return; |
367 } | 366 } |
368 if (hasLocalName(colTag) || hasLocalName(colgroupTag) || hasLocalName(frames
etTag) || | 367 if (hasLocalName(colTag) || hasLocalName(colgroupTag) || hasLocalName(frames
etTag) || |
369 hasLocalName(headTag) || hasLocalName(htmlTag) || hasLocalName(tableTag)
|| | 368 hasLocalName(headTag) || hasLocalName(htmlTag) || hasLocalName(tableTag)
|| |
370 hasLocalName(tbodyTag) || hasLocalName(tfootTag) || hasLocalName(theadTa
g) || | 369 hasLocalName(tbodyTag) || hasLocalName(tfootTag) || hasLocalName(theadTa
g) || |
371 hasLocalName(trTag)) { | 370 hasLocalName(trTag)) { |
372 exceptionState.throwDOMException(NoModificationAllowedError, ExceptionMe
ssages::failedToSet("innerText", "HTMLElement", "The '" + localName() + "' eleme
nt does not support text insertion.")); | 371 exceptionState.throwDOMException(NoModificationAllowedError, "The '" + l
ocalName() + "' element does not support text insertion."); |
373 return; | 372 return; |
374 } | 373 } |
375 | 374 |
376 // FIXME: This doesn't take whitespace collapsing into account at all. | 375 // FIXME: This doesn't take whitespace collapsing into account at all. |
377 | 376 |
378 if (!text.contains('\n') && !text.contains('\r')) { | 377 if (!text.contains('\n') && !text.contains('\r')) { |
379 if (text.isEmpty()) { | 378 if (text.isEmpty()) { |
380 removeChildren(); | 379 removeChildren(); |
381 return; | 380 return; |
382 } | 381 } |
(...skipping 19 matching lines...) Expand all Loading... |
402 | 401 |
403 // Add text nodes and <br> elements. | 402 // Add text nodes and <br> elements. |
404 RefPtr<DocumentFragment> fragment = textToFragment(text, exceptionState); | 403 RefPtr<DocumentFragment> fragment = textToFragment(text, exceptionState); |
405 if (!exceptionState.hadException()) | 404 if (!exceptionState.hadException()) |
406 replaceChildrenWithFragment(this, fragment.release(), exceptionState); | 405 replaceChildrenWithFragment(this, fragment.release(), exceptionState); |
407 } | 406 } |
408 | 407 |
409 void HTMLElement::setOuterText(const String &text, ExceptionState& exceptionStat
e) | 408 void HTMLElement::setOuterText(const String &text, ExceptionState& exceptionStat
e) |
410 { | 409 { |
411 if (ieForbidsInsertHTML()) { | 410 if (ieForbidsInsertHTML()) { |
412 exceptionState.throwDOMException(NoModificationAllowedError, ExceptionMe
ssages::failedToSet("outerText", "HTMLElement", "The '" + localName() + "' eleme
nt does not support text insertion.")); | 411 exceptionState.throwDOMException(NoModificationAllowedError, "The '" + l
ocalName() + "' element does not support text insertion."); |
413 return; | 412 return; |
414 } | 413 } |
415 if (hasLocalName(colTag) || hasLocalName(colgroupTag) || hasLocalName(frames
etTag) || | 414 if (hasLocalName(colTag) || hasLocalName(colgroupTag) || hasLocalName(frames
etTag) || |
416 hasLocalName(headTag) || hasLocalName(htmlTag) || hasLocalName(tableTag)
|| | 415 hasLocalName(headTag) || hasLocalName(htmlTag) || hasLocalName(tableTag)
|| |
417 hasLocalName(tbodyTag) || hasLocalName(tfootTag) || hasLocalName(theadTa
g) || | 416 hasLocalName(tbodyTag) || hasLocalName(tfootTag) || hasLocalName(theadTa
g) || |
418 hasLocalName(trTag)) { | 417 hasLocalName(trTag)) { |
419 exceptionState.throwDOMException(NoModificationAllowedError, ExceptionMe
ssages::failedToSet("outerText", "HTMLElement", "The '" + localName() + "' eleme
nt does not support text insertion.")); | 418 exceptionState.throwDOMException(NoModificationAllowedError, "The '" + l
ocalName() + "' element does not support text insertion."); |
420 return; | 419 return; |
421 } | 420 } |
422 | 421 |
423 ContainerNode* parent = parentNode(); | 422 ContainerNode* parent = parentNode(); |
424 if (!parent) { | 423 if (!parent) { |
425 exceptionState.throwDOMException(NoModificationAllowedError, ExceptionMe
ssages::failedToSet("outerText", "HTMLElement", "The element has no parent.")); | 424 exceptionState.throwDOMException(NoModificationAllowedError, "The elemen
t has no parent."); |
426 return; | 425 return; |
427 } | 426 } |
428 | 427 |
429 RefPtr<Node> prev = previousSibling(); | 428 RefPtr<Node> prev = previousSibling(); |
430 RefPtr<Node> next = nextSibling(); | 429 RefPtr<Node> next = nextSibling(); |
431 RefPtr<Node> newChild; | 430 RefPtr<Node> newChild; |
432 | 431 |
433 // Convert text to fragment with <br> tags instead of linebreaks if needed. | 432 // Convert text to fragment with <br> tags instead of linebreaks if needed. |
434 if (text.contains('\r') || text.contains('\n')) | 433 if (text.contains('\r') || text.contains('\n')) |
435 newChild = textToFragment(text, exceptionState); | 434 newChild = textToFragment(text, exceptionState); |
436 else | 435 else |
437 newChild = Text::create(document(), text); | 436 newChild = Text::create(document(), text); |
438 | 437 |
439 // textToFragment might cause mutation events. | 438 // textToFragment might cause mutation events. |
440 if (!this || !parentNode()) | 439 if (!this || !parentNode()) |
441 exceptionState.throwDOMException(HierarchyRequestError, ExceptionMessage
s::failedToSet("outerText", "HTMLElement", "The element has no parent.")); | 440 exceptionState.throwDOMException(HierarchyRequestError, "The element has
no parent."); |
442 | 441 |
443 if (exceptionState.hadException()) | 442 if (exceptionState.hadException()) |
444 return; | 443 return; |
445 | 444 |
446 parent->replaceChild(newChild.release(), this, exceptionState); | 445 parent->replaceChild(newChild.release(), this, exceptionState); |
447 | 446 |
448 RefPtr<Node> node = next ? next->previousSibling() : 0; | 447 RefPtr<Node> node = next ? next->previousSibling() : 0; |
449 if (!exceptionState.hadException() && node && node->isTextNode()) | 448 if (!exceptionState.hadException() && node && node->isTextNode()) |
450 mergeWithNextTextNode(node.release(), exceptionState); | 449 mergeWithNextTextNode(node.release(), exceptionState); |
451 | 450 |
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
484 if (equalIgnoringCase(where, "afterEnd")) { | 483 if (equalIgnoringCase(where, "afterEnd")) { |
485 if (ContainerNode* parent = this->parentNode()) { | 484 if (ContainerNode* parent = this->parentNode()) { |
486 parent->insertBefore(newChild, nextSibling(), exceptionState); | 485 parent->insertBefore(newChild, nextSibling(), exceptionState); |
487 if (!exceptionState.hadException()) | 486 if (!exceptionState.hadException()) |
488 return newChild; | 487 return newChild; |
489 } | 488 } |
490 return 0; | 489 return 0; |
491 } | 490 } |
492 | 491 |
493 // IE throws COM Exception E_INVALIDARG; this is the best DOM exception alte
rnative. | 492 // IE throws COM Exception E_INVALIDARG; this is the best DOM exception alte
rnative. |
494 exceptionState.throwDOMException(SyntaxError, ExceptionMessages::failedToExe
cute("insertAdjacent", "HTMLElement", "The value provided ('" + where + "') is n
ot one of 'beforeBegin', 'afterBegin', 'beforeEnd', or 'afterEnd'.")); | 493 exceptionState.throwDOMException(SyntaxError, "The value provided ('" + wher
e + "') is not one of 'beforeBegin', 'afterBegin', 'beforeEnd', or 'afterEnd'.")
; |
495 return 0; | 494 return 0; |
496 } | 495 } |
497 | 496 |
498 Element* HTMLElement::insertAdjacentElement(const String& where, Element* newChi
ld, ExceptionState& exceptionState) | 497 Element* HTMLElement::insertAdjacentElement(const String& where, Element* newChi
ld, ExceptionState& exceptionState) |
499 { | 498 { |
500 if (!newChild) { | 499 if (!newChild) { |
501 // IE throws COM Exception E_INVALIDARG; this is the best DOM exception
alternative. | 500 // IE throws COM Exception E_INVALIDARG; this is the best DOM exception
alternative. |
502 exceptionState.throwTypeError(ExceptionMessages::failedToExecute("insert
AdjacentElement", "HTMLElement", "The node provided is null.")); | 501 exceptionState.throwTypeError("The node provided is null."); |
503 return 0; | 502 return 0; |
504 } | 503 } |
505 | 504 |
506 Node* returnValue = insertAdjacent(where, newChild, exceptionState); | 505 Node* returnValue = insertAdjacent(where, newChild, exceptionState); |
507 return toElement(returnValue); | 506 return toElement(returnValue); |
508 } | 507 } |
509 | 508 |
510 // Step 3 of http://www.whatwg.org/specs/web-apps/current-work/multipage/apis-in
-html-documents.html#insertadjacenthtml() | 509 // Step 3 of http://www.whatwg.org/specs/web-apps/current-work/multipage/apis-in
-html-documents.html#insertadjacenthtml() |
511 static Element* contextElementForInsertion(const String& where, Element* element
, ExceptionState& exceptionState) | 510 static Element* contextElementForInsertion(const String& where, Element* element
, ExceptionState& exceptionState) |
512 { | 511 { |
513 if (equalIgnoringCase(where, "beforeBegin") || equalIgnoringCase(where, "aft
erEnd")) { | 512 if (equalIgnoringCase(where, "beforeBegin") || equalIgnoringCase(where, "aft
erEnd")) { |
514 ContainerNode* parent = element->parentNode(); | 513 ContainerNode* parent = element->parentNode(); |
515 if (parent && !parent->isElementNode()) { | 514 if (parent && !parent->isElementNode()) { |
516 exceptionState.throwDOMException(NoModificationAllowedError, Excepti
onMessages::failedToExecute("insertAdjacentHTML", "HTMLElement", "The element ha
s no parent.")); | 515 exceptionState.throwDOMException(NoModificationAllowedError, "The el
ement has no parent."); |
517 return 0; | 516 return 0; |
518 } | 517 } |
519 return toElement(parent); | 518 return toElement(parent); |
520 } | 519 } |
521 if (equalIgnoringCase(where, "afterBegin") || equalIgnoringCase(where, "befo
reEnd")) | 520 if (equalIgnoringCase(where, "afterBegin") || equalIgnoringCase(where, "befo
reEnd")) |
522 return element; | 521 return element; |
523 exceptionState.throwDOMException(SyntaxError, ExceptionMessages::failedToExe
cute("insertAdjacentHTML", "HTMLElement", "The value provided ('" + where + "')
is not one of 'beforeBegin', 'afterBegin', 'beforeEnd', or 'afterEnd'.")); | 522 exceptionState.throwDOMException(SyntaxError, "The value provided ('" + wher
e + "') is not one of 'beforeBegin', 'afterBegin', 'beforeEnd', or 'afterEnd'.")
; |
524 return 0; | 523 return 0; |
525 } | 524 } |
526 | 525 |
527 void HTMLElement::insertAdjacentHTML(const String& where, const String& markup,
ExceptionState& exceptionState) | 526 void HTMLElement::insertAdjacentHTML(const String& where, const String& markup,
ExceptionState& exceptionState) |
528 { | 527 { |
529 RefPtr<Element> contextElement = contextElementForInsertion(where, this, exc
eptionState); | 528 RefPtr<Element> contextElement = contextElementForInsertion(where, this, exc
eptionState); |
530 if (!contextElement) | 529 if (!contextElement) |
531 return; | 530 return; |
532 | 531 |
533 RefPtr<DocumentFragment> fragment = createFragmentForInnerOuterHTML(markup,
contextElement.get(), AllowScriptingContent, "insertAdjacentHTML", exceptionStat
e); | 532 RefPtr<DocumentFragment> fragment = createFragmentForInnerOuterHTML(markup,
contextElement.get(), AllowScriptingContent, "insertAdjacentHTML", exceptionStat
e); |
(...skipping 95 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
629 { | 628 { |
630 if (equalIgnoringCase(enabled, "true")) | 629 if (equalIgnoringCase(enabled, "true")) |
631 setAttribute(contenteditableAttr, "true"); | 630 setAttribute(contenteditableAttr, "true"); |
632 else if (equalIgnoringCase(enabled, "false")) | 631 else if (equalIgnoringCase(enabled, "false")) |
633 setAttribute(contenteditableAttr, "false"); | 632 setAttribute(contenteditableAttr, "false"); |
634 else if (equalIgnoringCase(enabled, "plaintext-only")) | 633 else if (equalIgnoringCase(enabled, "plaintext-only")) |
635 setAttribute(contenteditableAttr, "plaintext-only"); | 634 setAttribute(contenteditableAttr, "plaintext-only"); |
636 else if (equalIgnoringCase(enabled, "inherit")) | 635 else if (equalIgnoringCase(enabled, "inherit")) |
637 removeAttribute(contenteditableAttr); | 636 removeAttribute(contenteditableAttr); |
638 else | 637 else |
639 exceptionState.throwDOMException(SyntaxError, ExceptionMessages::failedT
oSet("contentEditable", "HTMLElement", "The value provided ('" + enabled + "') i
s not one of 'true', 'false', 'plaintext-only', or 'inherit'.")); | 638 exceptionState.throwDOMException(SyntaxError, "The value provided ('" +
enabled + "') is not one of 'true', 'false', 'plaintext-only', or 'inherit'."); |
640 } | 639 } |
641 | 640 |
642 bool HTMLElement::draggable() const | 641 bool HTMLElement::draggable() const |
643 { | 642 { |
644 return equalIgnoringCase(getAttribute(draggableAttr), "true"); | 643 return equalIgnoringCase(getAttribute(draggableAttr), "true"); |
645 } | 644 } |
646 | 645 |
647 void HTMLElement::setDraggable(bool value) | 646 void HTMLElement::setDraggable(bool value) |
648 { | 647 { |
649 setAttribute(draggableAttr, value ? "true" : "false"); | 648 setAttribute(draggableAttr, value ? "true" : "false"); |
(...skipping 426 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1076 #ifndef NDEBUG | 1075 #ifndef NDEBUG |
1077 | 1076 |
1078 // For use in the debugger | 1077 // For use in the debugger |
1079 void dumpInnerHTML(WebCore::HTMLElement*); | 1078 void dumpInnerHTML(WebCore::HTMLElement*); |
1080 | 1079 |
1081 void dumpInnerHTML(WebCore::HTMLElement* element) | 1080 void dumpInnerHTML(WebCore::HTMLElement* element) |
1082 { | 1081 { |
1083 printf("%s\n", element->innerHTML().ascii().data()); | 1082 printf("%s\n", element->innerHTML().ascii().data()); |
1084 } | 1083 } |
1085 #endif | 1084 #endif |
OLD | NEW |