summaryrefslogtreecommitdiff
path: root/xfa/fde
diff options
context:
space:
mode:
authorDan Sinclair <dsinclair@chromium.org>2018-05-29 19:42:39 +0000
committerChromium commit bot <commit-bot@chromium.org>2018-05-29 19:42:39 +0000
commit6af5369477ec05554ef9e73ae6762860095f09e9 (patch)
tree0a9d28f4e3f89ca5b141954913169fdff63bf59c /xfa/fde
parent162a31a6af1538acf7ac9835111626161287d742 (diff)
downloadpdfium-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')
-rw-r--r--xfa/fde/cfde_texteditengine.cpp85
-rw-r--r--xfa/fde/cfde_texteditengine.h16
-rw-r--r--xfa/fde/cfde_texteditengine_unittest.cpp3
3 files changed, 84 insertions, 20 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) {
diff --git a/xfa/fde/cfde_texteditengine.h b/xfa/fde/cfde_texteditengine.h
index 58f77edf31..868be8866a 100644
--- a/xfa/fde/cfde_texteditengine.h
+++ b/xfa/fde/cfde_texteditengine.h
@@ -61,21 +61,27 @@ class CFDE_TextEditEngine {
virtual void Undo() const = 0;
};
+ struct TextChange {
+ WideString text;
+ WideString previous_text;
+ size_t selection_start;
+ size_t selection_end;
+ bool cancelled;
+ };
+
class Delegate {
public:
virtual ~Delegate() = default;
virtual void NotifyTextFull() = 0;
virtual void OnCaretChanged() = 0;
- virtual void OnTextChanged(const WideString& prevText) = 0;
+ virtual void OnTextWillChange(TextChange* change) = 0;
+ virtual void OnTextChanged() = 0;
virtual void OnSelChanged() = 0;
virtual bool OnValidate(const WideString& wsText) = 0;
virtual void SetScrollOffset(float fScrollOffset) = 0;
};
- enum class RecordOperation {
- kInsertRecord,
- kSkipRecord,
- };
+ enum class RecordOperation { kInsertRecord, kSkipRecord, kSkipNotify };
CFDE_TextEditEngine();
~CFDE_TextEditEngine();
diff --git a/xfa/fde/cfde_texteditengine_unittest.cpp b/xfa/fde/cfde_texteditengine_unittest.cpp
index 123d16ce4b..c5efe529e6 100644
--- a/xfa/fde/cfde_texteditengine_unittest.cpp
+++ b/xfa/fde/cfde_texteditengine_unittest.cpp
@@ -21,7 +21,8 @@ class CFDE_TextEditEngineTest : public testing::Test {
void NotifyTextFull() override { text_is_full = true; }
void OnCaretChanged() override {}
- void OnTextChanged(const WideString& prevText) override {}
+ void OnTextWillChange(CFDE_TextEditEngine::TextChange* change) override {}
+ void OnTextChanged() override {}
void OnSelChanged() override {}
bool OnValidate(const WideString& wsText) override {
return !fail_validation;