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, 2008, 2010 Apple Inc. All rights reserv
ed. | 5 * Copyright (C) 2004, 2005, 2006, 2007, 2008, 2010 Apple Inc. All rights reserv
ed. |
6 * (C) 2006 Alexey Proskuryakov (ap@nypop.com) | 6 * (C) 2006 Alexey Proskuryakov (ap@nypop.com) |
7 * Copyright (C) 2007 Samuel Weinig (sam@webkit.org) | 7 * Copyright (C) 2007 Samuel Weinig (sam@webkit.org) |
8 * | 8 * |
9 * This library is free software; you can redistribute it and/or | 9 * This library is free software; you can redistribute it and/or |
10 * modify it under the terms of the GNU Library General Public | 10 * modify it under the terms of the GNU Library General Public |
(...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
90 | 90 |
91 PassRefPtrWillBeRawPtr<HTMLTextAreaElement> HTMLTextAreaElement::create(Document
& document, HTMLFormElement* form) | 91 PassRefPtrWillBeRawPtr<HTMLTextAreaElement> HTMLTextAreaElement::create(Document
& document, HTMLFormElement* form) |
92 { | 92 { |
93 RefPtrWillBeRawPtr<HTMLTextAreaElement> textArea = adoptRefWillBeNoop(new HT
MLTextAreaElement(document, form)); | 93 RefPtrWillBeRawPtr<HTMLTextAreaElement> textArea = adoptRefWillBeNoop(new HT
MLTextAreaElement(document, form)); |
94 textArea->ensureUserAgentShadowRoot(); | 94 textArea->ensureUserAgentShadowRoot(); |
95 return textArea.release(); | 95 return textArea.release(); |
96 } | 96 } |
97 | 97 |
98 void HTMLTextAreaElement::didAddUserAgentShadowRoot(ShadowRoot& root) | 98 void HTMLTextAreaElement::didAddUserAgentShadowRoot(ShadowRoot& root) |
99 { | 99 { |
100 root.appendChild(TextControlInnerTextElement::create(document())); | 100 root.appendChild(TextControlInnerEditorElement::create(document())); |
101 } | 101 } |
102 | 102 |
103 const AtomicString& HTMLTextAreaElement::formControlType() const | 103 const AtomicString& HTMLTextAreaElement::formControlType() const |
104 { | 104 { |
105 DEFINE_STATIC_LOCAL(const AtomicString, textarea, ("textarea", AtomicString:
:ConstructFromLiteral)); | 105 DEFINE_STATIC_LOCAL(const AtomicString, textarea, ("textarea", AtomicString:
:ConstructFromLiteral)); |
106 return textarea; | 106 return textarea; |
107 } | 107 } |
108 | 108 |
109 FormControlState HTMLTextAreaElement::saveFormControlState() const | 109 FormControlState HTMLTextAreaElement::saveFormControlState() const |
110 { | 110 { |
111 return m_isDirty ? FormControlState(value()) : FormControlState(); | 111 return m_isDirty ? FormControlState(value()) : FormControlState(); |
112 } | 112 } |
113 | 113 |
114 void HTMLTextAreaElement::restoreFormControlState(const FormControlState& state) | 114 void HTMLTextAreaElement::restoreFormControlState(const FormControlState& state) |
115 { | 115 { |
116 setValue(state[0]); | 116 setValue(state[0]); |
117 } | 117 } |
118 | 118 |
119 void HTMLTextAreaElement::childrenChanged(bool changedByParser, Node* beforeChan
ge, Node* afterChange, int childCountDelta) | 119 void HTMLTextAreaElement::childrenChanged(bool changedByParser, Node* beforeChan
ge, Node* afterChange, int childCountDelta) |
120 { | 120 { |
121 HTMLElement::childrenChanged(changedByParser, beforeChange, afterChange, chi
ldCountDelta); | 121 HTMLElement::childrenChanged(changedByParser, beforeChange, afterChange, chi
ldCountDelta); |
122 setLastChangeWasNotUserEdit(); | 122 setLastChangeWasNotUserEdit(); |
123 if (m_isDirty) | 123 if (m_isDirty) |
124 setInnerTextValue(value()); | 124 setInnerEditorValue(value()); |
125 else | 125 else |
126 setNonDirtyValue(defaultValue()); | 126 setNonDirtyValue(defaultValue()); |
127 } | 127 } |
128 | 128 |
129 bool HTMLTextAreaElement::isPresentationAttribute(const QualifiedName& name) con
st | 129 bool HTMLTextAreaElement::isPresentationAttribute(const QualifiedName& name) con
st |
130 { | 130 { |
131 if (name == alignAttr) { | 131 if (name == alignAttr) { |
132 // Don't map 'align' attribute. This matches what Firefox, Opera and IE
do. | 132 // Don't map 'align' attribute. This matches what Firefox, Opera and IE
do. |
133 // See http://bugs.webkit.org/show_bug.cgi?id=7075 | 133 // See http://bugs.webkit.org/show_bug.cgi?id=7075 |
134 return false; | 134 return false; |
(...skipping 148 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
283 | 283 |
284 void HTMLTextAreaElement::handleBeforeTextInsertedEvent(BeforeTextInsertedEvent*
event) const | 284 void HTMLTextAreaElement::handleBeforeTextInsertedEvent(BeforeTextInsertedEvent*
event) const |
285 { | 285 { |
286 ASSERT(event); | 286 ASSERT(event); |
287 ASSERT(renderer()); | 287 ASSERT(renderer()); |
288 int signedMaxLength = maxLength(); | 288 int signedMaxLength = maxLength(); |
289 if (signedMaxLength < 0) | 289 if (signedMaxLength < 0) |
290 return; | 290 return; |
291 unsigned unsignedMaxLength = static_cast<unsigned>(signedMaxLength); | 291 unsigned unsignedMaxLength = static_cast<unsigned>(signedMaxLength); |
292 | 292 |
293 const String& currentValue = innerTextValue(); | 293 const String& currentValue = innerEditorValue(); |
294 unsigned currentLength = computeLengthForSubmission(currentValue); | 294 unsigned currentLength = computeLengthForSubmission(currentValue); |
295 if (currentLength + computeLengthForSubmission(event->text()) < unsignedMaxL
ength) | 295 if (currentLength + computeLengthForSubmission(event->text()) < unsignedMaxL
ength) |
296 return; | 296 return; |
297 | 297 |
298 // selectionLength represents the selection length of this text field to be | 298 // selectionLength represents the selection length of this text field to be |
299 // removed by this insertion. | 299 // removed by this insertion. |
300 // If the text field has no focus, we don't need to take account of the | 300 // If the text field has no focus, we don't need to take account of the |
301 // selection length. The selection is the source of text drag-and-drop in | 301 // selection length. The selection is the source of text drag-and-drop in |
302 // that case, and nothing in the text field will be removed. | 302 // that case, and nothing in the text field will be removed. |
303 unsigned selectionLength = focused() ? computeLengthForSubmission(plainText(
document().frame()->selection().selection().toNormalizedRange().get())) : 0; | 303 unsigned selectionLength = focused() ? computeLengthForSubmission(plainText(
document().frame()->selection().selection().toNormalizedRange().get())) : 0; |
304 ASSERT(currentLength >= selectionLength); | 304 ASSERT(currentLength >= selectionLength); |
305 unsigned baseLength = currentLength - selectionLength; | 305 unsigned baseLength = currentLength - selectionLength; |
306 unsigned appendableLength = unsignedMaxLength > baseLength ? unsignedMaxLeng
th - baseLength : 0; | 306 unsigned appendableLength = unsignedMaxLength > baseLength ? unsignedMaxLeng
th - baseLength : 0; |
307 event->setText(sanitizeUserInputValue(event->text(), appendableLength)); | 307 event->setText(sanitizeUserInputValue(event->text(), appendableLength)); |
308 } | 308 } |
309 | 309 |
310 String HTMLTextAreaElement::sanitizeUserInputValue(const String& proposedValue,
unsigned maxLength) | 310 String HTMLTextAreaElement::sanitizeUserInputValue(const String& proposedValue,
unsigned maxLength) |
311 { | 311 { |
312 if (maxLength > 0 && U16_IS_LEAD(proposedValue[maxLength - 1])) | 312 if (maxLength > 0 && U16_IS_LEAD(proposedValue[maxLength - 1])) |
313 --maxLength; | 313 --maxLength; |
314 return proposedValue.left(maxLength); | 314 return proposedValue.left(maxLength); |
315 } | 315 } |
316 | 316 |
317 void HTMLTextAreaElement::updateValue() const | 317 void HTMLTextAreaElement::updateValue() const |
318 { | 318 { |
319 if (m_valueIsUpToDate) | 319 if (m_valueIsUpToDate) |
320 return; | 320 return; |
321 | 321 |
322 ASSERT(renderer()); | 322 ASSERT(renderer()); |
323 m_value = innerTextValue(); | 323 m_value = innerEditorValue(); |
324 const_cast<HTMLTextAreaElement*>(this)->m_valueIsUpToDate = true; | 324 const_cast<HTMLTextAreaElement*>(this)->m_valueIsUpToDate = true; |
325 const_cast<HTMLTextAreaElement*>(this)->notifyFormStateChanged(); | 325 const_cast<HTMLTextAreaElement*>(this)->notifyFormStateChanged(); |
326 m_isDirty = true; | 326 m_isDirty = true; |
327 const_cast<HTMLTextAreaElement*>(this)->updatePlaceholderVisibility(false); | 327 const_cast<HTMLTextAreaElement*>(this)->updatePlaceholderVisibility(false); |
328 } | 328 } |
329 | 329 |
330 String HTMLTextAreaElement::value() const | 330 String HTMLTextAreaElement::value() const |
331 { | 331 { |
332 updateValue(); | 332 updateValue(); |
333 return m_value; | 333 return m_value; |
(...skipping 23 matching lines...) Expand all Loading... |
357 String normalizedValue = newValue.isNull() ? "" : newValue; | 357 String normalizedValue = newValue.isNull() ? "" : newValue; |
358 normalizedValue.replace("\r\n", "\n"); | 358 normalizedValue.replace("\r\n", "\n"); |
359 normalizedValue.replace('\r', '\n'); | 359 normalizedValue.replace('\r', '\n'); |
360 | 360 |
361 // Return early because we don't want to move the caret or trigger other sid
e effects | 361 // Return early because we don't want to move the caret or trigger other sid
e effects |
362 // when the value isn't changing. This matches Firefox behavior, at least. | 362 // when the value isn't changing. This matches Firefox behavior, at least. |
363 if (normalizedValue == value()) | 363 if (normalizedValue == value()) |
364 return; | 364 return; |
365 | 365 |
366 m_value = normalizedValue; | 366 m_value = normalizedValue; |
367 setInnerTextValue(m_value); | 367 setInnerEditorValue(m_value); |
368 if (eventBehavior == DispatchNoEvent) | 368 if (eventBehavior == DispatchNoEvent) |
369 setLastChangeWasNotUserEdit(); | 369 setLastChangeWasNotUserEdit(); |
370 updatePlaceholderVisibility(false); | 370 updatePlaceholderVisibility(false); |
371 setNeedsStyleRecalc(SubtreeStyleChange); | 371 setNeedsStyleRecalc(SubtreeStyleChange); |
372 m_suggestedValue = String(); | 372 m_suggestedValue = String(); |
373 | 373 |
374 // Set the caret to the end of the text value. | 374 // Set the caret to the end of the text value. |
375 if (document().focusedElement() == this) { | 375 if (document().focusedElement() == this) { |
376 unsigned endOfString = m_value.length(); | 376 unsigned endOfString = m_value.length(); |
377 setSelectionRange(endOfString, endOfString); | 377 setSelectionRange(endOfString, endOfString); |
378 } | 378 } |
379 | 379 |
380 notifyFormStateChanged(); | 380 notifyFormStateChanged(); |
381 if (eventBehavior == DispatchNoEvent) { | 381 if (eventBehavior == DispatchNoEvent) { |
382 setTextAsOfLastFormControlChangeEvent(normalizedValue); | 382 setTextAsOfLastFormControlChangeEvent(normalizedValue); |
383 } else { | 383 } else { |
384 if (eventBehavior == DispatchInputAndChangeEvent) | 384 if (eventBehavior == DispatchInputAndChangeEvent) |
385 dispatchFormControlInputEvent(); | 385 dispatchFormControlInputEvent(); |
386 dispatchFormControlChangeEvent(); | 386 dispatchFormControlChangeEvent(); |
387 } | 387 } |
388 } | 388 } |
389 | 389 |
390 void HTMLTextAreaElement::setInnerTextValue(const String& value) | 390 void HTMLTextAreaElement::setInnerEditorValue(const String& value) |
391 { | 391 { |
392 HTMLTextFormControlElement::setInnerTextValue(value); | 392 HTMLTextFormControlElement::setInnerEditorValue(value); |
393 m_valueIsUpToDate = true; | 393 m_valueIsUpToDate = true; |
394 } | 394 } |
395 | 395 |
396 String HTMLTextAreaElement::defaultValue() const | 396 String HTMLTextAreaElement::defaultValue() const |
397 { | 397 { |
398 StringBuilder value; | 398 StringBuilder value; |
399 | 399 |
400 // Since there may be comments, ignore nodes other than text nodes. | 400 // Since there may be comments, ignore nodes other than text nodes. |
401 for (Node* n = firstChild(); n; n = n->nextSibling()) { | 401 for (Node* n = firstChild(); n; n = n->nextSibling()) { |
402 if (n->isTextNode()) | 402 if (n->isTextNode()) |
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
449 String HTMLTextAreaElement::suggestedValue() const | 449 String HTMLTextAreaElement::suggestedValue() const |
450 { | 450 { |
451 return m_suggestedValue; | 451 return m_suggestedValue; |
452 } | 452 } |
453 | 453 |
454 void HTMLTextAreaElement::setSuggestedValue(const String& value) | 454 void HTMLTextAreaElement::setSuggestedValue(const String& value) |
455 { | 455 { |
456 m_suggestedValue = value; | 456 m_suggestedValue = value; |
457 | 457 |
458 if (!value.isNull()) | 458 if (!value.isNull()) |
459 setInnerTextValue(m_suggestedValue); | 459 setInnerEditorValue(m_suggestedValue); |
460 else | 460 else |
461 setInnerTextValue(m_value); | 461 setInnerEditorValue(m_value); |
462 updatePlaceholderVisibility(false); | 462 updatePlaceholderVisibility(false); |
463 setNeedsStyleRecalc(SubtreeStyleChange); | 463 setNeedsStyleRecalc(SubtreeStyleChange); |
464 } | 464 } |
465 | 465 |
466 String HTMLTextAreaElement::validationMessage() const | 466 String HTMLTextAreaElement::validationMessage() const |
467 { | 467 { |
468 if (!willValidate()) | 468 if (!willValidate()) |
469 return String(); | 469 return String(); |
470 | 470 |
471 if (customError()) | 471 if (customError()) |
(...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
545 if (placeholderText.isEmpty()) { | 545 if (placeholderText.isEmpty()) { |
546 if (placeholder) | 546 if (placeholder) |
547 userAgentShadowRoot()->removeChild(placeholder); | 547 userAgentShadowRoot()->removeChild(placeholder); |
548 return; | 548 return; |
549 } | 549 } |
550 if (!placeholder) { | 550 if (!placeholder) { |
551 RefPtrWillBeRawPtr<HTMLDivElement> newElement = HTMLDivElement::create(d
ocument()); | 551 RefPtrWillBeRawPtr<HTMLDivElement> newElement = HTMLDivElement::create(d
ocument()); |
552 placeholder = newElement.get(); | 552 placeholder = newElement.get(); |
553 placeholder->setShadowPseudoId(AtomicString("-webkit-input-placeholder",
AtomicString::ConstructFromLiteral)); | 553 placeholder->setShadowPseudoId(AtomicString("-webkit-input-placeholder",
AtomicString::ConstructFromLiteral)); |
554 placeholder->setAttribute(idAttr, ShadowElementNames::placeholder()); | 554 placeholder->setAttribute(idAttr, ShadowElementNames::placeholder()); |
555 userAgentShadowRoot()->insertBefore(placeholder, innerTextElement()->nex
tSibling()); | 555 userAgentShadowRoot()->insertBefore(placeholder, innerEditorElement()->n
extSibling()); |
556 } | 556 } |
557 placeholder->setTextContent(placeholderText); | 557 placeholder->setTextContent(placeholderText); |
558 } | 558 } |
559 | 559 |
560 bool HTMLTextAreaElement::isInteractiveContent() const | 560 bool HTMLTextAreaElement::isInteractiveContent() const |
561 { | 561 { |
562 return true; | 562 return true; |
563 } | 563 } |
564 | 564 |
565 bool HTMLTextAreaElement::supportsAutofocus() const | 565 bool HTMLTextAreaElement::supportsAutofocus() const |
566 { | 566 { |
567 return true; | 567 return true; |
568 } | 568 } |
569 | 569 |
570 } | 570 } |
OLD | NEW |