316 lines
12 KiB
C++
316 lines
12 KiB
C++
// Copyright 2017 The PDFium Authors
|
|
// Use of this source code is governed by a BSD-style license that can be
|
|
// found in the LICENSE file.
|
|
|
|
// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
|
|
|
|
#include "fxjs/xfa/cjx_eventpseudomodel.h"
|
|
|
|
#include <algorithm>
|
|
#include <vector>
|
|
|
|
#include "fxjs/fxv8.h"
|
|
#include "fxjs/xfa/cfxjse_engine.h"
|
|
#include "third_party/base/notreached.h"
|
|
#include "third_party/base/numerics/safe_conversions.h"
|
|
#include "v8/include/v8-primitive.h"
|
|
#include "xfa/fxfa/cxfa_eventparam.h"
|
|
#include "xfa/fxfa/cxfa_ffnotify.h"
|
|
#include "xfa/fxfa/parser/cscript_eventpseudomodel.h"
|
|
|
|
namespace {
|
|
|
|
void StringProperty(v8::Isolate* pIsolate,
|
|
v8::Local<v8::Value>* pReturn,
|
|
WideString* wsValue,
|
|
bool bSetting) {
|
|
if (bSetting) {
|
|
*wsValue = fxv8::ReentrantToWideStringHelper(pIsolate, *pReturn);
|
|
return;
|
|
}
|
|
*pReturn = fxv8::NewStringHelper(pIsolate, wsValue->ToUTF8().AsStringView());
|
|
}
|
|
|
|
void IntegerProperty(v8::Isolate* pIsolate,
|
|
v8::Local<v8::Value>* pReturn,
|
|
int32_t* iValue,
|
|
bool bSetting) {
|
|
if (bSetting) {
|
|
*iValue = fxv8::ReentrantToInt32Helper(pIsolate, *pReturn);
|
|
return;
|
|
}
|
|
*pReturn = fxv8::NewNumberHelper(pIsolate, *iValue);
|
|
}
|
|
|
|
void BooleanProperty(v8::Isolate* pIsolate,
|
|
v8::Local<v8::Value>* pReturn,
|
|
bool* bValue,
|
|
bool bSetting) {
|
|
if (bSetting) {
|
|
*bValue = fxv8::ReentrantToBooleanHelper(pIsolate, *pReturn);
|
|
return;
|
|
}
|
|
*pReturn = fxv8::NewBooleanHelper(pIsolate, *bValue);
|
|
}
|
|
|
|
} // namespace
|
|
|
|
const CJX_MethodSpec CJX_EventPseudoModel::MethodSpecs[] = {
|
|
{"emit", emit_static},
|
|
{"reset", reset_static}};
|
|
|
|
CJX_EventPseudoModel::CJX_EventPseudoModel(CScript_EventPseudoModel* model)
|
|
: CJX_Object(model) {
|
|
DefineMethods(MethodSpecs);
|
|
}
|
|
|
|
CJX_EventPseudoModel::~CJX_EventPseudoModel() = default;
|
|
|
|
bool CJX_EventPseudoModel::DynamicTypeIs(TypeTag eType) const {
|
|
return eType == static_type__ || ParentType__::DynamicTypeIs(eType);
|
|
}
|
|
|
|
void CJX_EventPseudoModel::cancelAction(v8::Isolate* pIsolate,
|
|
v8::Local<v8::Value>* pValue,
|
|
bool bSetting,
|
|
XFA_Attribute eAttribute) {
|
|
Property(pIsolate, pValue, XFA_Event::CancelAction, bSetting);
|
|
}
|
|
|
|
void CJX_EventPseudoModel::change(v8::Isolate* pIsolate,
|
|
v8::Local<v8::Value>* pValue,
|
|
bool bSetting,
|
|
XFA_Attribute eAttribute) {
|
|
Property(pIsolate, pValue, XFA_Event::Change, bSetting);
|
|
}
|
|
|
|
void CJX_EventPseudoModel::commitKey(v8::Isolate* pIsolate,
|
|
v8::Local<v8::Value>* pValue,
|
|
bool bSetting,
|
|
XFA_Attribute eAttribute) {
|
|
Property(pIsolate, pValue, XFA_Event::CommitKey, bSetting);
|
|
}
|
|
|
|
void CJX_EventPseudoModel::fullText(v8::Isolate* pIsolate,
|
|
v8::Local<v8::Value>* pValue,
|
|
bool bSetting,
|
|
XFA_Attribute eAttribute) {
|
|
Property(pIsolate, pValue, XFA_Event::FullText, bSetting);
|
|
}
|
|
|
|
void CJX_EventPseudoModel::keyDown(v8::Isolate* pIsolate,
|
|
v8::Local<v8::Value>* pValue,
|
|
bool bSetting,
|
|
XFA_Attribute eAttribute) {
|
|
Property(pIsolate, pValue, XFA_Event::Keydown, bSetting);
|
|
}
|
|
|
|
void CJX_EventPseudoModel::modifier(v8::Isolate* pIsolate,
|
|
v8::Local<v8::Value>* pValue,
|
|
bool bSetting,
|
|
XFA_Attribute eAttribute) {
|
|
Property(pIsolate, pValue, XFA_Event::Modifier, bSetting);
|
|
}
|
|
|
|
void CJX_EventPseudoModel::newContentType(v8::Isolate* pIsolate,
|
|
v8::Local<v8::Value>* pValue,
|
|
bool bSetting,
|
|
XFA_Attribute eAttribute) {
|
|
Property(pIsolate, pValue, XFA_Event::NewContentType, bSetting);
|
|
}
|
|
|
|
void CJX_EventPseudoModel::newText(v8::Isolate* pIsolate,
|
|
v8::Local<v8::Value>* pValue,
|
|
bool bSetting,
|
|
XFA_Attribute eAttribute) {
|
|
if (bSetting)
|
|
return;
|
|
|
|
CFXJSE_Engine* pScriptContext = GetDocument()->GetScriptContext();
|
|
CXFA_EventParam* pEventParam = pScriptContext->GetEventParam();
|
|
if (!pEventParam)
|
|
return;
|
|
|
|
*pValue = fxv8::NewStringHelper(
|
|
pIsolate, pEventParam->GetNewText().ToUTF8().AsStringView());
|
|
}
|
|
|
|
void CJX_EventPseudoModel::prevContentType(v8::Isolate* pIsolate,
|
|
v8::Local<v8::Value>* pValue,
|
|
bool bSetting,
|
|
XFA_Attribute eAttribute) {
|
|
Property(pIsolate, pValue, XFA_Event::PreviousContentType, bSetting);
|
|
}
|
|
|
|
void CJX_EventPseudoModel::prevText(v8::Isolate* pIsolate,
|
|
v8::Local<v8::Value>* pValue,
|
|
bool bSetting,
|
|
XFA_Attribute eAttribute) {
|
|
Property(pIsolate, pValue, XFA_Event::PreviousText, bSetting);
|
|
}
|
|
|
|
void CJX_EventPseudoModel::reenter(v8::Isolate* pIsolate,
|
|
v8::Local<v8::Value>* pValue,
|
|
bool bSetting,
|
|
XFA_Attribute eAttribute) {
|
|
Property(pIsolate, pValue, XFA_Event::Reenter, bSetting);
|
|
}
|
|
|
|
void CJX_EventPseudoModel::selEnd(v8::Isolate* pIsolate,
|
|
v8::Local<v8::Value>* pValue,
|
|
bool bSetting,
|
|
XFA_Attribute eAttribute) {
|
|
Property(pIsolate, pValue, XFA_Event::SelectionEnd, bSetting);
|
|
}
|
|
|
|
void CJX_EventPseudoModel::selStart(v8::Isolate* pIsolate,
|
|
v8::Local<v8::Value>* pValue,
|
|
bool bSetting,
|
|
XFA_Attribute eAttribute) {
|
|
Property(pIsolate, pValue, XFA_Event::SelectionStart, bSetting);
|
|
}
|
|
|
|
void CJX_EventPseudoModel::shift(v8::Isolate* pIsolate,
|
|
v8::Local<v8::Value>* pValue,
|
|
bool bSetting,
|
|
XFA_Attribute eAttribute) {
|
|
Property(pIsolate, pValue, XFA_Event::Shift, bSetting);
|
|
}
|
|
|
|
void CJX_EventPseudoModel::soapFaultCode(v8::Isolate* pIsolate,
|
|
v8::Local<v8::Value>* pValue,
|
|
bool bSetting,
|
|
XFA_Attribute eAttribute) {
|
|
Property(pIsolate, pValue, XFA_Event::SoapFaultCode, bSetting);
|
|
}
|
|
|
|
void CJX_EventPseudoModel::soapFaultString(v8::Isolate* pIsolate,
|
|
v8::Local<v8::Value>* pValue,
|
|
bool bSetting,
|
|
XFA_Attribute eAttribute) {
|
|
Property(pIsolate, pValue, XFA_Event::SoapFaultString, bSetting);
|
|
}
|
|
|
|
void CJX_EventPseudoModel::target(v8::Isolate* pIsolate,
|
|
v8::Local<v8::Value>* pValue,
|
|
bool bSetting,
|
|
XFA_Attribute eAttribute) {
|
|
Property(pIsolate, pValue, XFA_Event::Target, bSetting);
|
|
}
|
|
|
|
CJS_Result CJX_EventPseudoModel::emit(
|
|
CFXJSE_Engine* runtime,
|
|
const std::vector<v8::Local<v8::Value>>& params) {
|
|
CFXJSE_Engine* pScriptContext = GetDocument()->GetScriptContext();
|
|
CXFA_EventParam* pEventParam = pScriptContext->GetEventParam();
|
|
if (!pEventParam)
|
|
return CJS_Result::Success();
|
|
|
|
CXFA_FFNotify* pNotify = GetDocument()->GetNotify();
|
|
if (!pNotify)
|
|
return CJS_Result::Success();
|
|
|
|
pNotify->HandleWidgetEvent(pScriptContext->GetEventTarget(), pEventParam);
|
|
return CJS_Result::Success();
|
|
}
|
|
|
|
CJS_Result CJX_EventPseudoModel::reset(
|
|
CFXJSE_Engine* runtime,
|
|
const std::vector<v8::Local<v8::Value>>& params) {
|
|
CFXJSE_Engine* pScriptContext = GetDocument()->GetScriptContext();
|
|
CXFA_EventParam* pEventParam = pScriptContext->GetEventParam();
|
|
if (pEventParam)
|
|
*pEventParam = CXFA_EventParam();
|
|
|
|
return CJS_Result::Success();
|
|
}
|
|
|
|
void CJX_EventPseudoModel::Property(v8::Isolate* pIsolate,
|
|
v8::Local<v8::Value>* pValue,
|
|
XFA_Event dwFlag,
|
|
bool bSetting) {
|
|
// Only the cancelAction, selStart, selEnd and change properties are writable.
|
|
if (bSetting && dwFlag != XFA_Event::CancelAction &&
|
|
dwFlag != XFA_Event::SelectionStart &&
|
|
dwFlag != XFA_Event::SelectionEnd && dwFlag != XFA_Event::Change) {
|
|
return;
|
|
}
|
|
|
|
CFXJSE_Engine* pScriptContext = GetDocument()->GetScriptContext();
|
|
CXFA_EventParam* pEventParam = pScriptContext->GetEventParam();
|
|
if (!pEventParam)
|
|
return;
|
|
|
|
switch (dwFlag) {
|
|
case XFA_Event::CancelAction:
|
|
BooleanProperty(pIsolate, pValue, &pEventParam->m_bCancelAction,
|
|
bSetting);
|
|
break;
|
|
case XFA_Event::Change:
|
|
StringProperty(pIsolate, pValue, &pEventParam->m_wsChange, bSetting);
|
|
break;
|
|
case XFA_Event::CommitKey:
|
|
IntegerProperty(pIsolate, pValue, &pEventParam->m_iCommitKey, bSetting);
|
|
break;
|
|
case XFA_Event::FullText:
|
|
StringProperty(pIsolate, pValue, &pEventParam->m_wsFullText, bSetting);
|
|
break;
|
|
case XFA_Event::Keydown:
|
|
BooleanProperty(pIsolate, pValue, &pEventParam->m_bKeyDown, bSetting);
|
|
break;
|
|
case XFA_Event::Modifier:
|
|
BooleanProperty(pIsolate, pValue, &pEventParam->m_bModifier, bSetting);
|
|
break;
|
|
case XFA_Event::NewContentType:
|
|
StringProperty(pIsolate, pValue, &pEventParam->m_wsNewContentType,
|
|
bSetting);
|
|
break;
|
|
case XFA_Event::NewText:
|
|
NOTREACHED();
|
|
break;
|
|
case XFA_Event::PreviousContentType:
|
|
StringProperty(pIsolate, pValue, &pEventParam->m_wsPrevContentType,
|
|
bSetting);
|
|
break;
|
|
case XFA_Event::PreviousText:
|
|
StringProperty(pIsolate, pValue, &pEventParam->m_wsPrevText, bSetting);
|
|
break;
|
|
case XFA_Event::Reenter:
|
|
BooleanProperty(pIsolate, pValue, &pEventParam->m_bReenter, bSetting);
|
|
break;
|
|
case XFA_Event::SelectionEnd:
|
|
IntegerProperty(pIsolate, pValue, &pEventParam->m_iSelEnd, bSetting);
|
|
|
|
pEventParam->m_iSelEnd = std::max(0, pEventParam->m_iSelEnd);
|
|
pEventParam->m_iSelEnd = std::min(
|
|
pEventParam->m_iSelEnd, pdfium::base::checked_cast<int32_t>(
|
|
pEventParam->m_wsPrevText.GetLength()));
|
|
pEventParam->m_iSelStart =
|
|
std::min(pEventParam->m_iSelStart, pEventParam->m_iSelEnd);
|
|
break;
|
|
case XFA_Event::SelectionStart:
|
|
IntegerProperty(pIsolate, pValue, &pEventParam->m_iSelStart, bSetting);
|
|
pEventParam->m_iSelStart = std::max(0, pEventParam->m_iSelStart);
|
|
pEventParam->m_iSelStart = std::min(
|
|
pEventParam->m_iSelStart, pdfium::base::checked_cast<int32_t>(
|
|
pEventParam->m_wsPrevText.GetLength()));
|
|
pEventParam->m_iSelEnd =
|
|
std::max(pEventParam->m_iSelStart, pEventParam->m_iSelEnd);
|
|
break;
|
|
case XFA_Event::Shift:
|
|
BooleanProperty(pIsolate, pValue, &pEventParam->m_bShift, bSetting);
|
|
break;
|
|
case XFA_Event::SoapFaultCode:
|
|
StringProperty(pIsolate, pValue, &pEventParam->m_wsSoapFaultCode,
|
|
bSetting);
|
|
break;
|
|
case XFA_Event::SoapFaultString:
|
|
StringProperty(pIsolate, pValue, &pEventParam->m_wsSoapFaultString,
|
|
bSetting);
|
|
break;
|
|
case XFA_Event::Target:
|
|
default:
|
|
break;
|
|
}
|
|
}
|