| 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 * (C) 2001 Dirk Mueller (mueller@kde.org) | 4 * (C) 2001 Dirk Mueller (mueller@kde.org) |
| 5 * Copyright (C) 2004, 2005, 2006, 2007 Apple Inc. All rights reserved. | 5 * Copyright (C) 2004, 2005, 2006, 2007 Apple Inc. All rights reserved. |
| 6 * (C) 2006 Alexey Proskuryakov (ap@nypop.com) | 6 * (C) 2006 Alexey Proskuryakov (ap@nypop.com) |
| 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 85 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 96 return; | 96 return; |
| 97 } | 97 } |
| 98 | 98 |
| 99 HTMLFormControlElementWithState::defaultEventHandler(event); | 99 HTMLFormControlElementWithState::defaultEventHandler(event); |
| 100 } | 100 } |
| 101 | 101 |
| 102 void HTMLTextFormControlElement::forwardEvent(Event* event) | 102 void HTMLTextFormControlElement::forwardEvent(Event* event) |
| 103 { | 103 { |
| 104 if (event->type() == EventTypeNames::blur || event->type() == EventTypeNames
::focus) | 104 if (event->type() == EventTypeNames::blur || event->type() == EventTypeNames
::focus) |
| 105 return; | 105 return; |
| 106 innerTextElement()->defaultEventHandler(event); | 106 innerEditorElement()->defaultEventHandler(event); |
| 107 } | 107 } |
| 108 | 108 |
| 109 String HTMLTextFormControlElement::strippedPlaceholder() const | 109 String HTMLTextFormControlElement::strippedPlaceholder() const |
| 110 { | 110 { |
| 111 // According to the HTML5 specification, we need to remove CR and LF from | 111 // According to the HTML5 specification, we need to remove CR and LF from |
| 112 // the attribute value. | 112 // the attribute value. |
| 113 const AtomicString& attributeValue = fastGetAttribute(placeholderAttr); | 113 const AtomicString& attributeValue = fastGetAttribute(placeholderAttr); |
| 114 if (!attributeValue.contains(newlineCharacter) && !attributeValue.contains(c
arriageReturn)) | 114 if (!attributeValue.contains(newlineCharacter) && !attributeValue.contains(c
arriageReturn)) |
| 115 return attributeValue; | 115 return attributeValue; |
| 116 | 116 |
| (...skipping 93 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 210 | 210 |
| 211 void HTMLTextFormControlElement::setRangeText(const String& replacement, unsigne
d start, unsigned end, const String& selectionMode, ExceptionState& exceptionSta
te) | 211 void HTMLTextFormControlElement::setRangeText(const String& replacement, unsigne
d start, unsigned end, const String& selectionMode, ExceptionState& exceptionSta
te) |
| 212 { | 212 { |
| 213 if (start > end) { | 213 if (start > end) { |
| 214 exceptionState.throwDOMException(IndexSizeError, "The provided start val
ue (" + String::number(start) + ") is larger than the provided end value (" + St
ring::number(end) + ")."); | 214 exceptionState.throwDOMException(IndexSizeError, "The provided start val
ue (" + String::number(start) + ") is larger than the provided end value (" + St
ring::number(end) + ")."); |
| 215 return; | 215 return; |
| 216 } | 216 } |
| 217 if (hasAuthorShadowRoot()) | 217 if (hasAuthorShadowRoot()) |
| 218 return; | 218 return; |
| 219 | 219 |
| 220 String text = innerTextValue(); | 220 String text = innerEditorValue(); |
| 221 unsigned textLength = text.length(); | 221 unsigned textLength = text.length(); |
| 222 unsigned replacementLength = replacement.length(); | 222 unsigned replacementLength = replacement.length(); |
| 223 unsigned newSelectionStart = selectionStart(); | 223 unsigned newSelectionStart = selectionStart(); |
| 224 unsigned newSelectionEnd = selectionEnd(); | 224 unsigned newSelectionEnd = selectionEnd(); |
| 225 | 225 |
| 226 start = std::min(start, textLength); | 226 start = std::min(start, textLength); |
| 227 end = std::min(end, textLength); | 227 end = std::min(end, textLength); |
| 228 | 228 |
| 229 if (start < end) | 229 if (start < end) |
| 230 text.replace(start, end - start, replacement); | 230 text.replace(start, end - start, replacement); |
| 231 else | 231 else |
| 232 text.insert(replacement, start); | 232 text.insert(replacement, start); |
| 233 | 233 |
| 234 setInnerTextValue(text); | 234 setInnerEditorValue(text); |
| 235 | 235 |
| 236 // FIXME: What should happen to the value (as in value()) if there's no rend
erer? | 236 // FIXME: What should happen to the value (as in value()) if there's no rend
erer? |
| 237 if (!renderer()) | 237 if (!renderer()) |
| 238 return; | 238 return; |
| 239 | 239 |
| 240 subtreeHasChanged(); | 240 subtreeHasChanged(); |
| 241 | 241 |
| 242 if (equalIgnoringCase(selectionMode, "select")) { | 242 if (equalIgnoringCase(selectionMode, "select")) { |
| 243 newSelectionStart = start; | 243 newSelectionStart = start; |
| 244 newSelectionEnd = start + replacementLength; | 244 newSelectionEnd = start + replacementLength; |
| (...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 278 void HTMLTextFormControlElement::setSelectionRange(int start, int end, TextField
SelectionDirection direction) | 278 void HTMLTextFormControlElement::setSelectionRange(int start, int end, TextField
SelectionDirection direction) |
| 279 { | 279 { |
| 280 document().updateLayoutIgnorePendingStylesheets(); | 280 document().updateLayoutIgnorePendingStylesheets(); |
| 281 | 281 |
| 282 if (!renderer() || !renderer()->isTextControl()) | 282 if (!renderer() || !renderer()->isTextControl()) |
| 283 return; | 283 return; |
| 284 | 284 |
| 285 end = std::max(end, 0); | 285 end = std::max(end, 0); |
| 286 start = std::min(std::max(start, 0), end); | 286 start = std::min(std::max(start, 0), end); |
| 287 | 287 |
| 288 if (!hasVisibleTextArea(renderer(), innerTextElement())) { | 288 if (!hasVisibleTextArea(renderer(), innerEditorElement())) { |
| 289 cacheSelection(start, end, direction); | 289 cacheSelection(start, end, direction); |
| 290 return; | 290 return; |
| 291 } | 291 } |
| 292 VisiblePosition startPosition = visiblePositionForIndex(start); | 292 VisiblePosition startPosition = visiblePositionForIndex(start); |
| 293 VisiblePosition endPosition; | 293 VisiblePosition endPosition; |
| 294 if (start == end) | 294 if (start == end) |
| 295 endPosition = startPosition; | 295 endPosition = startPosition; |
| 296 else | 296 else |
| 297 endPosition = visiblePositionForIndex(end); | 297 endPosition = visiblePositionForIndex(end); |
| 298 | 298 |
| (...skipping 10 matching lines...) Expand all Loading... |
| 309 newSelection = VisibleSelection(startPosition, endPosition); | 309 newSelection = VisibleSelection(startPosition, endPosition); |
| 310 newSelection.setIsDirectional(direction != SelectionHasNoDirection); | 310 newSelection.setIsDirectional(direction != SelectionHasNoDirection); |
| 311 | 311 |
| 312 if (LocalFrame* frame = document().frame()) | 312 if (LocalFrame* frame = document().frame()) |
| 313 frame->selection().setSelection(newSelection); | 313 frame->selection().setSelection(newSelection); |
| 314 } | 314 } |
| 315 | 315 |
| 316 VisiblePosition HTMLTextFormControlElement::visiblePositionForIndex(int index) c
onst | 316 VisiblePosition HTMLTextFormControlElement::visiblePositionForIndex(int index) c
onst |
| 317 { | 317 { |
| 318 if (index <= 0) | 318 if (index <= 0) |
| 319 return VisiblePosition(firstPositionInNode(innerTextElement()), DOWNSTRE
AM); | 319 return VisiblePosition(firstPositionInNode(innerEditorElement()), DOWNST
REAM); |
| 320 RefPtrWillBeRawPtr<Range> range = Range::create(document()); | 320 RefPtrWillBeRawPtr<Range> range = Range::create(document()); |
| 321 range->selectNodeContents(innerTextElement(), ASSERT_NO_EXCEPTION); | 321 range->selectNodeContents(innerEditorElement(), ASSERT_NO_EXCEPTION); |
| 322 CharacterIterator it(range.get()); | 322 CharacterIterator it(range.get()); |
| 323 it.advance(index - 1); | 323 it.advance(index - 1); |
| 324 return VisiblePosition(it.range()->endPosition(), UPSTREAM); | 324 return VisiblePosition(it.range()->endPosition(), UPSTREAM); |
| 325 } | 325 } |
| 326 | 326 |
| 327 int HTMLTextFormControlElement::indexForVisiblePosition(const VisiblePosition& p
os) const | 327 int HTMLTextFormControlElement::indexForVisiblePosition(const VisiblePosition& p
os) const |
| 328 { | 328 { |
| 329 Position indexPosition = pos.deepEquivalent().parentAnchoredEquivalent(); | 329 Position indexPosition = pos.deepEquivalent().parentAnchoredEquivalent(); |
| 330 if (enclosingTextFormControl(indexPosition) != this) | 330 if (enclosingTextFormControl(indexPosition) != this) |
| 331 return 0; | 331 return 0; |
| 332 ASSERT(indexPosition.document()); | 332 ASSERT(indexPosition.document()); |
| 333 RefPtrWillBeRawPtr<Range> range = Range::create(*indexPosition.document()); | 333 RefPtrWillBeRawPtr<Range> range = Range::create(*indexPosition.document()); |
| 334 range->setStart(innerTextElement(), 0, ASSERT_NO_EXCEPTION); | 334 range->setStart(innerEditorElement(), 0, ASSERT_NO_EXCEPTION); |
| 335 range->setEnd(indexPosition.containerNode(), indexPosition.offsetInContainer
Node(), ASSERT_NO_EXCEPTION); | 335 range->setEnd(indexPosition.containerNode(), indexPosition.offsetInContainer
Node(), ASSERT_NO_EXCEPTION); |
| 336 return TextIterator::rangeLength(range.get()); | 336 return TextIterator::rangeLength(range.get()); |
| 337 } | 337 } |
| 338 | 338 |
| 339 int HTMLTextFormControlElement::selectionStart() const | 339 int HTMLTextFormControlElement::selectionStart() const |
| 340 { | 340 { |
| 341 if (!isTextFormControl()) | 341 if (!isTextFormControl()) |
| 342 return 0; | 342 return 0; |
| 343 if (document().focusedElement() != this) | 343 if (document().focusedElement() != this) |
| 344 return m_cachedSelectionStart; | 344 return m_cachedSelectionStart; |
| (...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 428 | 428 |
| 429 PassRefPtrWillBeRawPtr<Range> HTMLTextFormControlElement::selection() const | 429 PassRefPtrWillBeRawPtr<Range> HTMLTextFormControlElement::selection() const |
| 430 { | 430 { |
| 431 if (!renderer() || !isTextFormControl()) | 431 if (!renderer() || !isTextFormControl()) |
| 432 return nullptr; | 432 return nullptr; |
| 433 | 433 |
| 434 int start = m_cachedSelectionStart; | 434 int start = m_cachedSelectionStart; |
| 435 int end = m_cachedSelectionEnd; | 435 int end = m_cachedSelectionEnd; |
| 436 | 436 |
| 437 ASSERT(start <= end); | 437 ASSERT(start <= end); |
| 438 HTMLElement* innerText = innerTextElement(); | 438 HTMLElement* innerText = innerEditorElement(); |
| 439 if (!innerText) | 439 if (!innerText) |
| 440 return nullptr; | 440 return nullptr; |
| 441 | 441 |
| 442 if (!innerText->firstChild()) | 442 if (!innerText->firstChild()) |
| 443 return Range::create(document(), innerText, 0, innerText, 0); | 443 return Range::create(document(), innerText, 0, innerText, 0); |
| 444 | 444 |
| 445 int offset = 0; | 445 int offset = 0; |
| 446 Node* startNode = 0; | 446 Node* startNode = 0; |
| 447 Node* endNode = 0; | 447 Node* endNode = 0; |
| 448 for (Node* node = innerText->firstChild(); node; node = NodeTraversal::next(
*node, innerText)) { | 448 for (Node* node = innerText->firstChild(); node; node = NodeTraversal::next(
*node, innerText)) { |
| (...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 495 HTMLFormControlElementWithState::parseAttribute(name, value); | 495 HTMLFormControlElementWithState::parseAttribute(name, value); |
| 496 } | 496 } |
| 497 | 497 |
| 498 bool HTMLTextFormControlElement::lastChangeWasUserEdit() const | 498 bool HTMLTextFormControlElement::lastChangeWasUserEdit() const |
| 499 { | 499 { |
| 500 if (!isTextFormControl()) | 500 if (!isTextFormControl()) |
| 501 return false; | 501 return false; |
| 502 return m_lastChangeWasUserEdit; | 502 return m_lastChangeWasUserEdit; |
| 503 } | 503 } |
| 504 | 504 |
| 505 void HTMLTextFormControlElement::setInnerTextValue(const String& value) | 505 void HTMLTextFormControlElement::setInnerEditorValue(const String& value) |
| 506 { | 506 { |
| 507 ASSERT(!hasAuthorShadowRoot()); | 507 ASSERT(!hasAuthorShadowRoot()); |
| 508 if (!isTextFormControl() || hasAuthorShadowRoot()) | 508 if (!isTextFormControl() || hasAuthorShadowRoot()) |
| 509 return; | 509 return; |
| 510 | 510 |
| 511 bool textIsChanged = value != innerTextValue(); | 511 bool textIsChanged = value != innerEditorValue(); |
| 512 if (textIsChanged || !innerTextElement()->hasChildren()) { | 512 if (textIsChanged || !innerEditorElement()->hasChildren()) { |
| 513 if (textIsChanged && renderer()) { | 513 if (textIsChanged && renderer()) { |
| 514 if (AXObjectCache* cache = document().existingAXObjectCache()) | 514 if (AXObjectCache* cache = document().existingAXObjectCache()) |
| 515 cache->postNotification(this, AXObjectCache::AXValueChanged, fal
se); | 515 cache->postNotification(this, AXObjectCache::AXValueChanged, fal
se); |
| 516 } | 516 } |
| 517 innerTextElement()->setInnerText(value, ASSERT_NO_EXCEPTION); | 517 innerEditorElement()->setInnerText(value, ASSERT_NO_EXCEPTION); |
| 518 | 518 |
| 519 if (value.endsWith('\n') || value.endsWith('\r')) | 519 if (value.endsWith('\n') || value.endsWith('\r')) |
| 520 innerTextElement()->appendChild(HTMLBRElement::create(document())); | 520 innerEditorElement()->appendChild(HTMLBRElement::create(document()))
; |
| 521 } | 521 } |
| 522 } | 522 } |
| 523 | 523 |
| 524 static String finishText(StringBuilder& result) | 524 static String finishText(StringBuilder& result) |
| 525 { | 525 { |
| 526 // Remove one trailing newline; there's always one that's collapsed out by r
endering. | 526 // Remove one trailing newline; there's always one that's collapsed out by r
endering. |
| 527 size_t size = result.length(); | 527 size_t size = result.length(); |
| 528 if (size && result[size - 1] == '\n') | 528 if (size && result[size - 1] == '\n') |
| 529 result.resize(--size); | 529 result.resize(--size); |
| 530 return result.toString(); | 530 return result.toString(); |
| 531 } | 531 } |
| 532 | 532 |
| 533 String HTMLTextFormControlElement::innerTextValue() const | 533 String HTMLTextFormControlElement::innerEditorValue() const |
| 534 { | 534 { |
| 535 ASSERT(!hasAuthorShadowRoot()); | 535 ASSERT(!hasAuthorShadowRoot()); |
| 536 HTMLElement* innerText = innerTextElement(); | 536 HTMLElement* innerEditor = innerEditorElement(); |
| 537 if (!innerText || !isTextFormControl()) | 537 if (!innerEditor || !isTextFormControl()) |
| 538 return emptyString(); | 538 return emptyString(); |
| 539 | 539 |
| 540 StringBuilder result; | 540 StringBuilder result; |
| 541 for (Node* node = innerText; node; node = NodeTraversal::next(*node, innerTe
xt)) { | 541 for (Node* node = innerEditor; node; node = NodeTraversal::next(*node, inner
Editor)) { |
| 542 if (isHTMLBRElement(*node)) | 542 if (isHTMLBRElement(*node)) |
| 543 result.append(newlineCharacter); | 543 result.append(newlineCharacter); |
| 544 else if (node->isTextNode()) | 544 else if (node->isTextNode()) |
| 545 result.append(toText(node)->data()); | 545 result.append(toText(node)->data()); |
| 546 } | 546 } |
| 547 return finishText(result); | 547 return finishText(result); |
| 548 } | 548 } |
| 549 | 549 |
| 550 static void getNextSoftBreak(RootInlineBox*& line, Node*& breakNode, unsigned& b
reakOffset) | 550 static void getNextSoftBreak(RootInlineBox*& line, Node*& breakNode, unsigned& b
reakOffset) |
| 551 { | 551 { |
| 552 RootInlineBox* next; | 552 RootInlineBox* next; |
| 553 for (; line; line = next) { | 553 for (; line; line = next) { |
| 554 next = line->nextRootBox(); | 554 next = line->nextRootBox(); |
| 555 if (next && !line->endsWithBreak()) { | 555 if (next && !line->endsWithBreak()) { |
| 556 ASSERT(line->lineBreakObj()); | 556 ASSERT(line->lineBreakObj()); |
| 557 breakNode = line->lineBreakObj()->node(); | 557 breakNode = line->lineBreakObj()->node(); |
| 558 breakOffset = line->lineBreakPos(); | 558 breakOffset = line->lineBreakPos(); |
| 559 line = next; | 559 line = next; |
| 560 return; | 560 return; |
| 561 } | 561 } |
| 562 } | 562 } |
| 563 breakNode = 0; | 563 breakNode = 0; |
| 564 breakOffset = 0; | 564 breakOffset = 0; |
| 565 } | 565 } |
| 566 | 566 |
| 567 String HTMLTextFormControlElement::valueWithHardLineBreaks() const | 567 String HTMLTextFormControlElement::valueWithHardLineBreaks() const |
| 568 { | 568 { |
| 569 // FIXME: It's not acceptable to ignore the HardWrap setting when there is n
o renderer. | 569 // FIXME: It's not acceptable to ignore the HardWrap setting when there is n
o renderer. |
| 570 // While we have no evidence this has ever been a practical problem, it woul
d be best to fix it some day. | 570 // While we have no evidence this has ever been a practical problem, it woul
d be best to fix it some day. |
| 571 HTMLElement* innerText = innerTextElement(); | 571 HTMLElement* innerText = innerEditorElement(); |
| 572 if (!innerText || !isTextFormControl()) | 572 if (!innerText || !isTextFormControl()) |
| 573 return value(); | 573 return value(); |
| 574 | 574 |
| 575 RenderBlock* renderer = toRenderBlock(innerText->renderer()); | 575 RenderBlock* renderer = toRenderBlock(innerText->renderer()); |
| 576 if (!renderer) | 576 if (!renderer) |
| 577 return value(); | 577 return value(); |
| 578 | 578 |
| 579 Node* breakNode; | 579 Node* breakNode; |
| 580 unsigned breakOffset; | 580 unsigned breakOffset; |
| 581 RootInlineBox* line = renderer->firstRootBox(); | 581 RootInlineBox* line = renderer->firstRootBox(); |
| (...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 647 if (equalIgnoringCase(dirAttributeValue, "auto")) { | 647 if (equalIgnoringCase(dirAttributeValue, "auto")) { |
| 648 bool isAuto; | 648 bool isAuto; |
| 649 TextDirection textDirection = element->directionalityIfhasDirAutoAtt
ribute(isAuto); | 649 TextDirection textDirection = element->directionalityIfhasDirAutoAtt
ribute(isAuto); |
| 650 return textDirection == RTL ? "rtl" : "ltr"; | 650 return textDirection == RTL ? "rtl" : "ltr"; |
| 651 } | 651 } |
| 652 } | 652 } |
| 653 | 653 |
| 654 return "ltr"; | 654 return "ltr"; |
| 655 } | 655 } |
| 656 | 656 |
| 657 HTMLElement* HTMLTextFormControlElement::innerTextElement() const | 657 HTMLElement* HTMLTextFormControlElement::innerEditorElement() const |
| 658 { | 658 { |
| 659 return toHTMLElement(userAgentShadowRoot()->getElementById(ShadowElementName
s::innerEditor())); | 659 return toHTMLElement(userAgentShadowRoot()->getElementById(ShadowElementName
s::innerEditor())); |
| 660 } | 660 } |
| 661 | 661 |
| 662 } // namespace Webcore | 662 } // namespace Webcore |
| OLD | NEW |