void HTMLTextFormControlElement::setInnerEditorValue(const String& value) { ASSERT(!openShadowRoot()); if (!isTextFormControl() || openShadowRoot()) return; bool textIsChanged = value != innerEditorValue(); HTMLElement* innerEditor = innerEditorElement(); if (!textIsChanged && innerEditor->hasChildren()) return; // If the last child is a trailing <br> that's appended below, remove it // first so as to enable setInnerText() fast path of updating a text node. if (isHTMLBRElement(innerEditor->lastChild())) innerEditor->removeChild(innerEditor->lastChild(), ASSERT_NO_EXCEPTION); // We don't use setTextContent. It triggers unnecessary paint. if (value.isEmpty()) innerEditor->removeChildren(); else replaceChildrenWithText(innerEditor, value, ASSERT_NO_EXCEPTION); // Add <br> so that we can put the caret at the next line of the last // newline. addPlaceholderBreakElementIfNecessary(); if (textIsChanged && layoutObject()) { if (AXObjectCache* cache = document().existingAXObjectCache()) cache->handleTextFormControlChanged(this); } }
void HTMLElement::setInnerText(const String& text, ExceptionCode& ec) { if (ieForbidsInsertHTML()) { ec = NO_MODIFICATION_ALLOWED_ERR; return; } if (hasLocalName(colTag) || hasLocalName(colgroupTag) || hasLocalName(framesetTag) || hasLocalName(headTag) || hasLocalName(htmlTag) || hasLocalName(tableTag) || hasLocalName(tbodyTag) || hasLocalName(tfootTag) || hasLocalName(theadTag) || hasLocalName(trTag)) { ec = NO_MODIFICATION_ALLOWED_ERR; return; } // FIXME: This doesn't take whitespace collapsing into account at all. if (!text.contains('\n') && !text.contains('\r')) { if (text.isEmpty()) { removeChildren(); return; } replaceChildrenWithText(this, text, ec); return; } // FIXME: Do we need to be able to detect preserveNewline style even when there's no renderer? // FIXME: Can the renderer be out of date here? Do we need to call updateStyleIfNeeded? // For example, for the contents of textarea elements that are display:none? RenderObject* r = renderer(); if (r && r->style()->preserveNewline()) { if (!text.contains('\r')) { replaceChildrenWithText(this, text, ec); return; } String textWithConsistentLineBreaks = text; textWithConsistentLineBreaks.replace("\r\n", "\n"); textWithConsistentLineBreaks.replace('\r', '\n'); replaceChildrenWithText(this, textWithConsistentLineBreaks, ec); return; } // Add text nodes and <br> elements. ec = 0; RefPtr<DocumentFragment> fragment = textToFragment(text, ec); if (!ec) replaceChildrenWithFragment(this, fragment.release(), ec); }
void HTMLElement::setInnerText(const String& text, ExceptionState& exceptionState) { if (ieForbidsInsertHTML()) { exceptionState.throwDOMException(NoModificationAllowedError, "The '" + localName() + "' element does not support text insertion."); return; } if (shouldProhibitSetInnerOuterText(*this)) { exceptionState.throwDOMException(NoModificationAllowedError, "The '" + localName() + "' element does not support text insertion."); return; } // FIXME: This doesn't take whitespace collapsing into account at all. if (!text.contains('\n') && !text.contains('\r')) { if (text.isEmpty()) { removeChildren(); return; } replaceChildrenWithText(this, text, exceptionState); return; } // FIXME: Do we need to be able to detect preserveNewline style even when there's no renderer? // FIXME: Can the renderer be out of date here? Do we need to call updateStyleIfNeeded? // For example, for the contents of textarea elements that are display:none? LayoutObject* r = layoutObject(); if (r && r->style()->preserveNewline()) { if (!text.contains('\r')) { replaceChildrenWithText(this, text, exceptionState); return; } String textWithConsistentLineBreaks = text; textWithConsistentLineBreaks.replace("\r\n", "\n"); textWithConsistentLineBreaks.replace('\r', '\n'); replaceChildrenWithText(this, textWithConsistentLineBreaks, exceptionState); return; } // Add text nodes and <br> elements. RefPtrWillBeRawPtr<DocumentFragment> fragment = textToFragment(text, exceptionState); if (!exceptionState.hadException()) replaceChildrenWithFragment(this, fragment.release(), exceptionState); }
void HTMLElement::setInnerText(const String& text, ExceptionCode& ec) { // follow the IE specs about when this is allowed if (endTagRequirement() == TagStatusForbidden) { ec = NO_MODIFICATION_ALLOWED_ERR; return; } if (hasLocalName(colTag) || hasLocalName(colgroupTag) || hasLocalName(framesetTag) || hasLocalName(headTag) || hasLocalName(htmlTag) || hasLocalName(tableTag) || hasLocalName(tbodyTag) || hasLocalName(tfootTag) || hasLocalName(theadTag) || hasLocalName(trTag)) { ec = NO_MODIFICATION_ALLOWED_ERR; return; } // FIXME: This doesn't take whitespace collapsing into account at all. if (!text.contains('\n') && !text.contains('\r')) { if (text.isEmpty()) { removeChildren(); return; } replaceChildrenWithText(this, text, ec); return; } // FIXME: Do we need to be able to detect preserveNewline style even when there's no renderer? // FIXME: Can the renderer be out of date here? Do we need to call updateRendering? // For example, for the contents of textarea elements that are display:none? RenderObject* r = renderer(); if (r && r->style()->preserveNewline()) { if (!text.contains('\r')) { replaceChildrenWithText(this, text, ec); return; } String textWithConsistentLineBreaks = text; textWithConsistentLineBreaks.replace("\r\n", "\n"); textWithConsistentLineBreaks.replace('\r', '\n'); replaceChildrenWithText(this, textWithConsistentLineBreaks, ec); return; } // Add text nodes and <br> elements. ec = 0; RefPtr<DocumentFragment> fragment = new DocumentFragment(document()); int lineStart = 0; UChar prev = 0; int length = text.length(); for (int i = 0; i < length; ++i) { UChar c = text[i]; if (c == '\n' || c == '\r') { if (i > lineStart) { fragment->appendChild(new Text(document(), text.substring(lineStart, i - lineStart)), ec); if (ec) return; } if (!(c == '\n' && i != 0 && prev == '\r')) { fragment->appendChild(new HTMLBRElement(brTag, document()), ec); if (ec) return; } lineStart = i + 1; } prev = c; } if (length > lineStart) fragment->appendChild(new Text(document(), text.substring(lineStart, length - lineStart)), ec); replaceChildrenWithFragment(this, fragment.release(), ec); }