diff options
author | Dan Sinclair <dsinclair@chromium.org> | 2018-05-29 19:42:39 +0000 |
---|---|---|
committer | Chromium commit bot <commit-bot@chromium.org> | 2018-05-29 19:42:39 +0000 |
commit | 6af5369477ec05554ef9e73ae6762860095f09e9 (patch) | |
tree | 0a9d28f4e3f89ca5b141954913169fdff63bf59c /xfa/fde/cfde_texteditengine.cpp | |
parent | 162a31a6af1538acf7ac9835111626161287d742 (diff) | |
download | pdfium-6af5369477ec05554ef9e73ae6762860095f09e9.tar.xz |
[xfa] Propagate the xfa change data for text to JS and back.
This CL adds the necessary plumbing to propagate the change information
for a text widget from FWL out to JS and handle the returned value as
necessary.
Bug: pdfium:1066
Change-Id: I78fd81761b90294f1836e9f09dba12ed238963cc
Reviewed-on: https://pdfium-review.googlesource.com/33070
Reviewed-by: Ryan Harrison <rharrison@chromium.org>
Commit-Queue: dsinclair <dsinclair@chromium.org>
Diffstat (limited to 'xfa/fde/cfde_texteditengine.cpp')
-rw-r--r-- | xfa/fde/cfde_texteditengine.cpp | 85 |
1 files changed, 71 insertions, 14 deletions
diff --git a/xfa/fde/cfde_texteditengine.cpp b/xfa/fde/cfde_texteditengine.cpp index 3363baa0cd..cfe844e656 100644 --- a/xfa/fde/cfde_texteditengine.cpp +++ b/xfa/fde/cfde_texteditengine.cpp @@ -262,11 +262,35 @@ size_t CFDE_TextEditEngine::CountCharsExceedingSize(const WideString& text, } void CFDE_TextEditEngine::Insert(size_t idx, - const WideString& text, + const WideString& request_text, RecordOperation add_operation) { + WideString text = request_text; + if (text.GetLength() == 0) + return; if (idx > text_length_) idx = text_length_; + TextChange change; + change.selection_start = idx; + change.selection_end = idx; + change.text = text; + change.previous_text = GetText(); + change.cancelled = false; + + if (delegate_ && (add_operation != RecordOperation::kSkipRecord && + add_operation != RecordOperation::kSkipNotify)) { + delegate_->OnTextWillChange(&change); + if (change.cancelled) + return; + + text = change.text; + idx = change.selection_start; + + // JS extended the selection, so delete it before we insert. + if (change.selection_end != change.selection_start) + DeleteSelectedText(RecordOperation::kSkipRecord); + } + size_t length = text.GetLength(); if (length == 0) return; @@ -276,11 +300,11 @@ void CFDE_TextEditEngine::Insert(size_t idx, bool exceeded_limit = false; // Currently we allow inserting a number of characters over the text limit if - // the text edit is already empty. This allows supporting text fields which - // do formatting. Otherwise, if you enter 123456789 for an SSN into a field + // we're skipping notify. This means we're setting the formatted text into the + // engine. Otherwise, if you enter 123456789 for an SSN into a field // with a 9 character limit and we reformat to 123-45-6789 we'll truncate // the 89 when inserting into the text edit. See https://crbug.com/pdfium/1089 - if (has_character_limit_ && text_length_ > 0 && + if (has_character_limit_ && add_operation != RecordOperation::kSkipNotify && text_length_ + length > character_limit_) { exceeded_limit = true; length = character_limit_ - text_length_; @@ -348,7 +372,7 @@ void CFDE_TextEditEngine::Insert(size_t idx, if (exceeded_limit) delegate_->NotifyTextFull(); - delegate_->OnTextChanged(previous_text); + delegate_->OnTextChanged(); } } @@ -811,6 +835,23 @@ WideString CFDE_TextEditEngine::Delete(size_t start_idx, if (start_idx >= text_length_) return L""; + TextChange change; + change.text = L""; + change.cancelled = false; + if (delegate_ && (add_operation != RecordOperation::kSkipRecord && + add_operation != RecordOperation::kSkipNotify)) { + change.previous_text = GetText(); + change.selection_start = start_idx; + change.selection_end = start_idx + length; + + delegate_->OnTextWillChange(&change); + if (change.cancelled) + return L""; + + start_idx = change.selection_start; + length = change.selection_end - change.selection_start; + } + length = std::min(length, text_length_ - start_idx); AdjustGap(start_idx + length, 0); @@ -831,15 +872,37 @@ WideString CFDE_TextEditEngine::Delete(size_t start_idx, is_dirty_ = true; ClearSelection(); + // The JS requested the insertion of text instead of just a deletion. + if (change.text != L"") + Insert(start_idx, change.text, RecordOperation::kSkipRecord); + if (delegate_) - delegate_->OnTextChanged(previous_text); + delegate_->OnTextChanged(); return ret; } -void CFDE_TextEditEngine::ReplaceSelectedText(const WideString& rep) { - size_t start_idx = selection_.start_idx; +void CFDE_TextEditEngine::ReplaceSelectedText(const WideString& requested_rep) { + WideString rep = requested_rep; + + if (delegate_) { + TextChange change; + change.selection_start = selection_.start_idx; + change.selection_end = selection_.start_idx + selection_.count; + change.text = rep; + change.previous_text = GetText(); + change.cancelled = false; + + delegate_->OnTextWillChange(&change); + if (change.cancelled) + return; + + rep = change.text; + selection_.start_idx = change.selection_start; + selection_.count = change.selection_end - change.selection_start; + } + size_t start_idx = selection_.start_idx; WideString txt = DeleteSelectedText(RecordOperation::kSkipRecord); Insert(gap_position_, rep, RecordOperation::kSkipRecord); @@ -1079,13 +1142,7 @@ void CFDE_TextEditEngine::RebuildPieces() { if (IsAlignedRight() && bounds_smaller) { delta = available_width_ - contents_bounding_box_.width; } else if (IsAlignedCenter() && bounds_smaller) { - // TODO(dsinclair): Old code used CombText here and set the space to - // something unrelated to the available width .... Figure out if this is - // needed and what it should do. - // if (is_comb_text_) { - // } else { delta = (available_width_ - contents_bounding_box_.width) / 2.0f; - // } } if (delta != 0.0) { |