From cbf1550e48e300142a53f635daba3c1d8910add9 Mon Sep 17 00:00:00 2001 From: Dan Sinclair Date: Fri, 25 May 2018 16:18:40 +0000 Subject: [xfa] Generate CXFA_EventParam.newText dynamically When an xfa.event is sent it is possible to change the selStart, selEnd and change values of the event. This should cause the value of newText to be changed as needed. This CL removes m_wsNewText from CXFA_EventParam and instead generates the new text based on the previous text, the selection and the change. Bug: 1066 Change-Id: I35d126fad9771c8980654a8af64d2b98989bff3f Reviewed-on: https://pdfium-review.googlesource.com/32970 Commit-Queue: Ryan Harrison Reviewed-by: Ryan Harrison --- fpdfsdk/cpdfsdk_widget.cpp | 13 ---------- fxjs/cfxjse_formcalc_context_embeddertest.cpp | 37 +++++++++++++++++++++++++++ fxjs/xfa/cjx_eventpseudomodel.cpp | 15 +++++++++-- xfa/fxfa/cxfa_eventparam.cpp | 6 ++++- xfa/fxfa/cxfa_eventparam.h | 3 ++- xfa/fxfa/cxfa_ffcheckbutton.cpp | 2 +- xfa/fxfa/cxfa_ffcombobox.cpp | 2 +- xfa/fxfa/cxfa_ffdatetimeedit.cpp | 2 +- xfa/fxfa/cxfa_fflistbox.cpp | 7 ----- xfa/fxfa/cxfa_fftextedit.cpp | 2 -- 10 files changed, 60 insertions(+), 29 deletions(-) diff --git a/fpdfsdk/cpdfsdk_widget.cpp b/fpdfsdk/cpdfsdk_widget.cpp index 840c75a3b0..40e04e8772 100644 --- a/fpdfsdk/cpdfsdk_widget.cpp +++ b/fpdfsdk/cpdfsdk_widget.cpp @@ -236,13 +236,6 @@ bool CPDFSDK_Widget::OnXFAAAction(PDFSDK_XFAAActionType eXFAAAT, param.m_wsFullText = data->sValue; param.m_bKeyDown = data->bKeyDown; param.m_bModifier = data->bModifier; - param.m_wsNewText = data->sValue; - if (data->nSelEnd > data->nSelStart) - param.m_wsNewText.Delete(data->nSelStart, data->nSelEnd - data->nSelStart); - - for (const auto& c : data->sChange) - param.m_wsNewText.Insert(data->nSelStart, c); - param.m_wsPrevText = data->sValue; if ((eEventType == XFA_EVENT_Click || eEventType == XFA_EVENT_Change) && GetFieldType() == FormFieldType::kRadioButton) { @@ -834,12 +827,6 @@ bool CPDFSDK_Widget::OnAAction(CPDF_AAction::AActionType type, param.m_wsFullText = data->sValue; param.m_bKeyDown = data->bKeyDown; param.m_bModifier = data->bModifier; - param.m_wsNewText = data->sValue; - if (data->nSelEnd > data->nSelStart) - param.m_wsNewText.Delete(data->nSelStart, - data->nSelEnd - data->nSelStart); - for (int i = data->sChange.GetLength() - 1; i >= 0; i--) - param.m_wsNewText.Insert(data->nSelStart, data->sChange[i]); param.m_wsPrevText = data->sValue; int32_t nRet = XFA_EVENTERROR_NotExist; diff --git a/fxjs/cfxjse_formcalc_context_embeddertest.cpp b/fxjs/cfxjse_formcalc_context_embeddertest.cpp index 4b9d93a660..ed0c5bccc7 100644 --- a/fxjs/cfxjse_formcalc_context_embeddertest.cpp +++ b/fxjs/cfxjse_formcalc_context_embeddertest.cpp @@ -1573,3 +1573,40 @@ TEST_F(CFXJSE_FormCalcContextEmbedderTest, XFAEventCancelAction) { EXPECT_TRUE(Execute("xfa.event.cancelAction = \"true\"")); EXPECT_TRUE(context->GetEventParam()->m_bCancelAction); } + +TEST_F(CFXJSE_FormCalcContextEmbedderTest, ComplexTextChangeEvent) { + ASSERT_TRUE(OpenDocument("simple_xfa.pdf")); + + CXFA_EventParam params; + params.m_wsChange = L"g"; + params.m_wsPrevText = L"abcd"; + params.m_iSelStart = 1; + params.m_iSelEnd = 3; + + CFXJSE_Engine* context = GetScriptContext(); + context->SetEventParam(params); + + EXPECT_EQ(L"abcd", context->GetEventParam()->m_wsPrevText); + EXPECT_EQ(L"agd", context->GetEventParam()->GetNewText()); + EXPECT_EQ(L"g", context->GetEventParam()->m_wsChange); + EXPECT_EQ(1, context->GetEventParam()->m_iSelStart); + EXPECT_EQ(3, context->GetEventParam()->m_iSelEnd); + + const char change_event[] = {"xfa.event.change = \"xyz\""}; + EXPECT_TRUE(Execute(change_event)); + + EXPECT_EQ(L"abcd", context->GetEventParam()->m_wsPrevText); + EXPECT_EQ(L"xyz", context->GetEventParam()->m_wsChange); + EXPECT_EQ(L"axyzd", context->GetEventParam()->GetNewText()); + EXPECT_EQ(1, context->GetEventParam()->m_iSelStart); + EXPECT_EQ(3, context->GetEventParam()->m_iSelEnd); + + const char sel_event[] = {"xfa.event.selEnd = \"1\""}; + EXPECT_TRUE(Execute(sel_event)); + + EXPECT_EQ(L"abcd", context->GetEventParam()->m_wsPrevText); + EXPECT_EQ(L"xyz", context->GetEventParam()->m_wsChange); + EXPECT_EQ(L"axyzbcd", context->GetEventParam()->GetNewText()); + EXPECT_EQ(1, context->GetEventParam()->m_iSelStart); + EXPECT_EQ(1, context->GetEventParam()->m_iSelEnd); +} diff --git a/fxjs/xfa/cjx_eventpseudomodel.cpp b/fxjs/xfa/cjx_eventpseudomodel.cpp index 82b76fce12..d2364c8f32 100644 --- a/fxjs/xfa/cjx_eventpseudomodel.cpp +++ b/fxjs/xfa/cjx_eventpseudomodel.cpp @@ -101,7 +101,18 @@ void CJX_EventPseudoModel::newContentType(CFXJSE_Value* pValue, void CJX_EventPseudoModel::newText(CFXJSE_Value* pValue, bool bSetting, XFA_Attribute eAttribute) { - Property(pValue, XFA_Event::NewText, bSetting); + if (bSetting) + return; + + CFXJSE_Engine* pScriptContext = GetDocument()->GetScriptContext(); + if (!pScriptContext) + return; + + CXFA_EventParam* pEventParam = pScriptContext->GetEventParam(); + if (!pEventParam) + return; + + pValue->SetString(pEventParam->GetNewText().UTF8Encode().AsStringView()); } void CJX_EventPseudoModel::prevContentType(CFXJSE_Value* pValue, @@ -237,7 +248,7 @@ void CJX_EventPseudoModel::Property(CFXJSE_Value* pValue, StringProperty(pValue, &pEventParam->m_wsNewContentType, bSetting); break; case XFA_Event::NewText: - StringProperty(pValue, &pEventParam->m_wsNewText, bSetting); + NOTREACHED(); break; case XFA_Event::PreviousContentType: StringProperty(pValue, &pEventParam->m_wsPrevContentType, bSetting); diff --git a/xfa/fxfa/cxfa_eventparam.cpp b/xfa/fxfa/cxfa_eventparam.cpp index bd6742f4dd..4e3cae9d1d 100644 --- a/xfa/fxfa/cxfa_eventparam.cpp +++ b/xfa/fxfa/cxfa_eventparam.cpp @@ -33,7 +33,6 @@ void CXFA_EventParam::Reset() { m_bKeyDown = false; m_bModifier = false; m_wsNewContentType.clear(); - m_wsNewText.clear(); m_wsPrevContentType.clear(); m_wsPrevText.clear(); m_bReenter = false; @@ -44,3 +43,8 @@ void CXFA_EventParam::Reset() { m_wsSoapFaultString.clear(); m_bIsFormReady = false; } + +WideString CXFA_EventParam::GetNewText() const { + return m_wsPrevText.Left(m_iSelStart) + m_wsChange + + m_wsPrevText.Right(m_wsPrevText.GetLength() - m_iSelEnd); +} diff --git a/xfa/fxfa/cxfa_eventparam.h b/xfa/fxfa/cxfa_eventparam.h index 210eeb515a..3fc5780008 100644 --- a/xfa/fxfa/cxfa_eventparam.h +++ b/xfa/fxfa/cxfa_eventparam.h @@ -67,12 +67,13 @@ class CXFA_EventParam { WideString m_wsChange; WideString m_wsFullText; WideString m_wsNewContentType; - WideString m_wsNewText; WideString m_wsPrevContentType; WideString m_wsPrevText; WideString m_wsSoapFaultCode; WideString m_wsSoapFaultString; bool m_bIsFormReady; + + WideString GetNewText() const; }; #endif // XFA_FXFA_CXFA_EVENTPARAM_H_ diff --git a/xfa/fxfa/cxfa_ffcheckbutton.cpp b/xfa/fxfa/cxfa_ffcheckbutton.cpp index c78fa1336d..289821f304 100644 --- a/xfa/fxfa/cxfa_ffcheckbutton.cpp +++ b/xfa/fxfa/cxfa_ffcheckbutton.cpp @@ -306,7 +306,7 @@ void CXFA_FFCheckButton::OnProcessEvent(CFWL_Event* pEvent) { case CFWL_Event::Type::CheckStateChanged: { CXFA_EventParam eParam; eParam.m_eType = XFA_EVENT_Change; - eParam.m_wsNewText = m_pNode->GetValue(XFA_VALUEPICTURE_Raw); + eParam.m_wsPrevText = m_pNode->GetValue(XFA_VALUEPICTURE_Raw); CXFA_Node* exclNode = m_pNode->GetExclGroupIfExists(); if (ProcessCommittedData()) { diff --git a/xfa/fxfa/cxfa_ffcombobox.cpp b/xfa/fxfa/cxfa_ffcombobox.cpp index e4de85c517..a150101efb 100644 --- a/xfa/fxfa/cxfa_ffcombobox.cpp +++ b/xfa/fxfa/cxfa_ffcombobox.cpp @@ -127,7 +127,7 @@ bool CXFA_FFComboBox::IsDataChanged() { void CXFA_FFComboBox::FWLEventSelChange(CXFA_EventParam* pParam) { pParam->m_eType = XFA_EVENT_Change; pParam->m_pTarget = m_pNode.Get(); - pParam->m_wsNewText = ToComboBox(m_pNormalWidget.get())->GetEditText(); + pParam->m_wsPrevText = ToComboBox(m_pNormalWidget.get())->GetEditText(); m_pNode->ProcessEvent(GetDocView(), XFA_AttributeEnum::Change, pParam); } diff --git a/xfa/fxfa/cxfa_ffdatetimeedit.cpp b/xfa/fxfa/cxfa_ffdatetimeedit.cpp index 632924f1ab..f5531ffd66 100644 --- a/xfa/fxfa/cxfa_ffdatetimeedit.cpp +++ b/xfa/fxfa/cxfa_ffdatetimeedit.cpp @@ -197,7 +197,7 @@ void CXFA_FFDateTimeEdit::OnSelectChanged(CFWL_Widget* pWidget, CXFA_EventParam eParam; eParam.m_eType = XFA_EVENT_Change; eParam.m_pTarget = m_pNode.Get(); - eParam.m_wsNewText = m_pNode->GetValue(XFA_VALUEPICTURE_Raw); + eParam.m_wsPrevText = m_pNode->GetValue(XFA_VALUEPICTURE_Raw); m_pNode->ProcessEvent(GetDocView(), XFA_AttributeEnum::Change, &eParam); } diff --git a/xfa/fxfa/cxfa_fflistbox.cpp b/xfa/fxfa/cxfa_fflistbox.cpp index 50f9d4a772..583efacdea 100644 --- a/xfa/fxfa/cxfa_fflistbox.cpp +++ b/xfa/fxfa/cxfa_fflistbox.cpp @@ -153,13 +153,6 @@ void CXFA_FFListBox::OnSelectChanged(CFWL_Widget* pWidget) { eParam.m_eType = XFA_EVENT_Change; eParam.m_pTarget = m_pNode.Get(); eParam.m_wsPrevText = m_pNode->GetValue(XFA_VALUEPICTURE_Raw); - - auto* pListBox = ToListBox(m_pNormalWidget.get()); - int32_t iSels = pListBox->CountSelItems(); - if (iSels > 0) { - CFWL_ListItem* item = pListBox->GetSelItem(0); - eParam.m_wsNewText = item ? item->GetText() : L""; - } m_pNode->ProcessEvent(GetDocView(), XFA_AttributeEnum::Change, &eParam); } diff --git a/xfa/fxfa/cxfa_fftextedit.cpp b/xfa/fxfa/cxfa_fftextedit.cpp index 520ed31ec5..02787d579b 100644 --- a/xfa/fxfa/cxfa_fftextedit.cpp +++ b/xfa/fxfa/cxfa_fftextedit.cpp @@ -307,7 +307,6 @@ void CXFA_FFTextEdit::OnTextChanged(CFWL_Widget* pWidget, eParam.m_wsPrevText = wsPrevText; if (m_pNode->GetFFWidgetType() == XFA_FFWidgetType::kDateTimeEdit) { auto* pDateTime = static_cast(m_pNormalWidget.get()); - eParam.m_wsNewText = pDateTime->GetEditText(); if (pDateTime->HasSelection()) { size_t count; std::tie(eParam.m_iSelStart, count) = pDateTime->GetSelection(); @@ -315,7 +314,6 @@ void CXFA_FFTextEdit::OnTextChanged(CFWL_Widget* pWidget, } } else { CFWL_Edit* pEdit = ToEdit(m_pNormalWidget.get()); - eParam.m_wsNewText = pEdit->GetText(); if (pEdit->HasSelection()) std::tie(eParam.m_iSelStart, eParam.m_iSelEnd) = pEdit->GetSelection(); } -- cgit v1.2.3