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 |