blob: faa1eeb6fccc7d624119dfea86758c171ca8ae2b [file] [log] [blame]
// Copyright 2014 PDFium Authors. All rights reserved.
// 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 "../../include/javascript/JavaScript.h"
#include "../../include/javascript/JS_Define.h"
#include "../../include/javascript/JS_Object.h"
#include "../../include/javascript/JS_Value.h"
#include "../../include/javascript/Document.h"
/* ---------------------------- CJS_Value ---------------------------- */
CJS_Value::CJS_Value(v8::Isolate* isolate)
: m_eType(VT_unknown), m_isolate(isolate) {}
CJS_Value::CJS_Value(v8::Isolate* isolate,
v8::Local<v8::Value> pValue,
FXJSVALUETYPE t)
: m_pValue(pValue), m_eType(t), m_isolate(isolate) {}
CJS_Value::CJS_Value(v8::Isolate* isolate, const int& iValue)
: m_isolate(isolate) {
operator=(iValue);
}
CJS_Value::CJS_Value(v8::Isolate* isolate, const bool& bValue)
: m_isolate(isolate) {
operator=(bValue);
}
CJS_Value::CJS_Value(v8::Isolate* isolate, const float& fValue)
: m_isolate(isolate) {
operator=(fValue);
}
CJS_Value::CJS_Value(v8::Isolate* isolate, const double& dValue)
: m_isolate(isolate) {
operator=(dValue);
}
CJS_Value::CJS_Value(v8::Isolate* isolate, JSFXObject pJsObj)
: m_isolate(isolate) {
operator=(pJsObj);
}
CJS_Value::CJS_Value(v8::Isolate* isolate, CJS_Object* pJsObj)
: m_isolate(isolate) {
operator=(pJsObj);
}
CJS_Value::CJS_Value(v8::Isolate* isolate, CJS_Document* pJsDoc)
: m_isolate(isolate) {
m_eType = VT_object;
if (pJsDoc)
m_pValue = (JSFXObject)*pJsDoc;
}
CJS_Value::CJS_Value(v8::Isolate* isolate, const FX_WCHAR* pWstr)
: m_isolate(isolate) {
operator=(pWstr);
}
CJS_Value::CJS_Value(v8::Isolate* isolate, const FX_CHAR* pStr)
: m_isolate(isolate) {
operator=(pStr);
}
CJS_Value::CJS_Value(v8::Isolate* isolate, CJS_Array& array)
: m_isolate(isolate) {
operator=(array);
}
CJS_Value::~CJS_Value() {}
void CJS_Value::Attach(v8::Local<v8::Value> pValue, FXJSVALUETYPE t) {
m_pValue = pValue;
m_eType = t;
}
void CJS_Value::Attach(CJS_Value* pValue) {
if (pValue)
Attach(pValue->ToV8Value(), pValue->GetType());
}
void CJS_Value::Detach() {
m_pValue = v8::Local<v8::Value>();
m_eType = VT_unknown;
}
/* ----------------------------------------------------------------------------------------
*/
int CJS_Value::ToInt() const {
return JS_ToInt32(m_isolate, m_pValue);
}
bool CJS_Value::ToBool() const {
return JS_ToBoolean(m_isolate, m_pValue);
}
double CJS_Value::ToDouble() const {
return JS_ToNumber(m_isolate, m_pValue);
}
float CJS_Value::ToFloat() const {
return (float)ToDouble();
}
CJS_Object* CJS_Value::ToCJSObject() const {
v8::Local<v8::Object> pObj = JS_ToObject(m_isolate, m_pValue);
return (CJS_Object*)JS_GetPrivate(m_isolate, pObj);
}
v8::Local<v8::Object> CJS_Value::ToV8Object() const {
return JS_ToObject(m_isolate, m_pValue);
}
CFX_WideString CJS_Value::ToCFXWideString() const {
return JS_ToString(m_isolate, m_pValue);
}
CFX_ByteString CJS_Value::ToCFXByteString() const {
return CFX_ByteString::FromUnicode(ToCFXWideString());
}
v8::Local<v8::Value> CJS_Value::ToV8Value() const {
return m_pValue;
}
v8::Local<v8::Array> CJS_Value::ToV8Array() const {
if (IsArrayObject())
return v8::Local<v8::Array>::Cast(JS_ToObject(m_isolate, m_pValue));
return v8::Local<v8::Array>();
}
/* ----------------------------------------------------------------------------------------
*/
void CJS_Value::operator=(int iValue) {
m_pValue = JS_NewNumber(m_isolate, iValue);
m_eType = VT_number;
}
void CJS_Value::operator=(bool bValue) {
m_pValue = JS_NewBoolean(m_isolate, bValue);
m_eType = VT_boolean;
}
void CJS_Value::operator=(double dValue) {
m_pValue = JS_NewNumber(m_isolate, dValue);
m_eType = VT_number;
}
void CJS_Value::operator=(float fValue) {
m_pValue = JS_NewNumber(m_isolate, fValue);
m_eType = VT_number;
}
void CJS_Value::operator=(v8::Local<v8::Object> pObj) {
m_pValue = JS_NewObject(m_isolate, pObj);
m_eType = VT_fxobject;
}
void CJS_Value::operator=(CJS_Object* pObj) {
if (pObj)
operator=((JSFXObject)*pObj);
}
void CJS_Value::operator=(CJS_Document* pJsDoc) {
m_eType = VT_object;
if (pJsDoc) {
m_pValue = static_cast<JSFXObject>(*pJsDoc);
}
}
void CJS_Value::operator=(const FX_WCHAR* pWstr) {
m_pValue = JS_NewString(m_isolate, (wchar_t*)pWstr);
m_eType = VT_string;
}
void CJS_Value::SetNull() {
m_pValue = JS_NewNull();
m_eType = VT_null;
}
void CJS_Value::operator=(const FX_CHAR* pStr) {
operator=(CFX_WideString::FromLocal(pStr).c_str());
}
void CJS_Value::operator=(CJS_Array& array) {
m_pValue = JS_NewObject2(m_isolate, (v8::Local<v8::Array>)array);
m_eType = VT_object;
}
void CJS_Value::operator=(CJS_Date& date) {
m_pValue = JS_NewDate(m_isolate, (double)date);
m_eType = VT_date;
}
void CJS_Value::operator=(CJS_Value value) {
m_pValue = value.ToV8Value();
m_eType = value.m_eType;
m_isolate = value.m_isolate;
}
/* ----------------------------------------------------------------------------------------
*/
FXJSVALUETYPE CJS_Value::GetType() const {
if (m_pValue.IsEmpty())
return VT_unknown;
if (m_pValue->IsString())
return VT_string;
if (m_pValue->IsNumber())
return VT_number;
if (m_pValue->IsBoolean())
return VT_boolean;
if (m_pValue->IsDate())
return VT_date;
if (m_pValue->IsObject())
return VT_object;
if (m_pValue->IsNull())
return VT_null;
if (m_pValue->IsUndefined())
return VT_undefined;
return VT_unknown;
}
FX_BOOL CJS_Value::IsArrayObject() const {
if (m_pValue.IsEmpty())
return FALSE;
return m_pValue->IsArray();
}
FX_BOOL CJS_Value::IsDateObject() const {
if (m_pValue.IsEmpty())
return FALSE;
return m_pValue->IsDate();
}
// CJS_Value::operator CJS_Array()
FX_BOOL CJS_Value::ConvertToArray(CJS_Array& array) const {
if (IsArrayObject()) {
array.Attach(JS_ToArray(m_isolate, m_pValue));
return TRUE;
}
return FALSE;
}
FX_BOOL CJS_Value::ConvertToDate(CJS_Date& date) const {
// if (GetType() == VT_date)
// {
// date = (double)(*this);
// return TRUE;
// }
if (IsDateObject()) {
date.Attach(m_pValue);
return TRUE;
}
return FALSE;
}
/* ---------------------------- CJS_PropValue ---------------------------- */
CJS_PropValue::CJS_PropValue(const CJS_Value& value)
: CJS_Value(value), m_bIsSetting(0) {}
CJS_PropValue::CJS_PropValue(v8::Isolate* isolate)
: CJS_Value(isolate), m_bIsSetting(0) {}
CJS_PropValue::~CJS_PropValue() {}
FX_BOOL CJS_PropValue::IsSetting() {
return m_bIsSetting;
}
FX_BOOL CJS_PropValue::IsGetting() {
return !m_bIsSetting;
}
void CJS_PropValue::operator<<(int iValue) {
ASSERT(!m_bIsSetting);
CJS_Value::operator=(iValue);
}
void CJS_PropValue::operator>>(int& iValue) const {
ASSERT(m_bIsSetting);
iValue = CJS_Value::ToInt();
}
void CJS_PropValue::operator<<(bool bValue) {
ASSERT(!m_bIsSetting);
CJS_Value::operator=(bValue);
}
void CJS_PropValue::operator>>(bool& bValue) const {
ASSERT(m_bIsSetting);
bValue = CJS_Value::ToBool();
}
void CJS_PropValue::operator<<(double dValue) {
ASSERT(!m_bIsSetting);
CJS_Value::operator=(dValue);
}
void CJS_PropValue::operator>>(double& dValue) const {
ASSERT(m_bIsSetting);
dValue = CJS_Value::ToDouble();
}
void CJS_PropValue::operator<<(CJS_Object* pObj) {
ASSERT(!m_bIsSetting);
CJS_Value::operator=(pObj);
}
void CJS_PropValue::operator>>(CJS_Object*& ppObj) const {
ASSERT(m_bIsSetting);
ppObj = CJS_Value::ToCJSObject();
}
void CJS_PropValue::operator<<(CJS_Document* pJsDoc) {
ASSERT(!m_bIsSetting);
CJS_Value::operator=(pJsDoc);
}
void CJS_PropValue::operator>>(CJS_Document*& ppJsDoc) const {
ASSERT(m_bIsSetting);
ppJsDoc = static_cast<CJS_Document*>(CJS_Value::ToCJSObject());
}
void CJS_PropValue::operator<<(JSFXObject pObj) {
ASSERT(!m_bIsSetting);
CJS_Value::operator=(pObj);
}
void CJS_PropValue::operator>>(JSFXObject& ppObj) const {
ASSERT(m_bIsSetting);
ppObj = CJS_Value::ToV8Object();
}
void CJS_PropValue::StartSetting() {
m_bIsSetting = 1;
}
void CJS_PropValue::StartGetting() {
m_bIsSetting = 0;
}
void CJS_PropValue::operator<<(CFX_ByteString string) {
ASSERT(!m_bIsSetting);
CJS_Value::operator=(string.c_str());
}
void CJS_PropValue::operator>>(CFX_ByteString& string) const {
ASSERT(m_bIsSetting);
string = CJS_Value::ToCFXByteString();
}
void CJS_PropValue::operator<<(const FX_WCHAR* c_string) {
ASSERT(!m_bIsSetting);
CJS_Value::operator=(c_string);
}
void CJS_PropValue::operator>>(CFX_WideString& wide_string) const {
ASSERT(m_bIsSetting);
wide_string = CJS_Value::ToCFXWideString();
}
void CJS_PropValue::operator<<(CFX_WideString wide_string) {
ASSERT(!m_bIsSetting);
CJS_Value::operator=(wide_string.c_str());
}
void CJS_PropValue::operator>>(CJS_Array& array) const {
ASSERT(m_bIsSetting);
ConvertToArray(array);
}
void CJS_PropValue::operator<<(CJS_Array& array) {
ASSERT(!m_bIsSetting);
CJS_Value::operator=(array);
}
void CJS_PropValue::operator>>(CJS_Date& date) const {
ASSERT(m_bIsSetting);
ConvertToDate(date);
}
void CJS_PropValue::operator<<(CJS_Date& date) {
ASSERT(!m_bIsSetting);
CJS_Value::operator=(date);
}
CJS_PropValue::operator v8::Local<v8::Value>() const {
return m_pValue;
}
/* ======================================== CJS_Array
* ========================================= */
CJS_Array::CJS_Array(v8::Isolate* isolate) : m_isolate(isolate) {}
CJS_Array::~CJS_Array() {}
void CJS_Array::Attach(v8::Local<v8::Array> pArray) {
m_pArray = pArray;
}
FX_BOOL CJS_Array::IsAttached() {
return FALSE;
}
void CJS_Array::GetElement(unsigned index, CJS_Value& value) {
if (m_pArray.IsEmpty())
return;
v8::Local<v8::Value> p = JS_GetArrayElement(m_isolate, m_pArray, index);
value.Attach(p, VT_object);
}
void CJS_Array::SetElement(unsigned index, CJS_Value value) {
if (m_pArray.IsEmpty())
m_pArray = JS_NewArray(m_isolate);
JS_PutArrayElement(m_isolate, m_pArray, index, value.ToV8Value(),
value.GetType());
}
int CJS_Array::GetLength() {
if (m_pArray.IsEmpty())
return 0;
return JS_GetArrayLength(m_pArray);
}
CJS_Array::operator v8::Local<v8::Array>() {
if (m_pArray.IsEmpty())
m_pArray = JS_NewArray(m_isolate);
return m_pArray;
}
/* ======================================== CJS_Date
* ========================================= */
CJS_Date::CJS_Date(v8::Isolate* isolate) : m_isolate(isolate) {}
CJS_Date::CJS_Date(v8::Isolate* isolate, double dMsec_time) {
m_isolate = isolate;
m_pDate = JS_NewDate(isolate, dMsec_time);
}
CJS_Date::CJS_Date(v8::Isolate* isolate,
int year,
int mon,
int day,
int hour,
int min,
int sec) {
m_isolate = isolate;
m_pDate = JS_NewDate(isolate, MakeDate(year, mon, day, hour, min, sec, 0));
}
double CJS_Date::MakeDate(int year,
int mon,
int day,
int hour,
int min,
int sec,
int ms) {
return JS_MakeDate(JS_MakeDay(year, mon, day),
JS_MakeTime(hour, min, sec, ms));
}
CJS_Date::~CJS_Date() {}
FX_BOOL CJS_Date::IsValidDate() {
if (m_pDate.IsEmpty())
return FALSE;
return !JS_PortIsNan(JS_ToNumber(m_isolate, m_pDate));
}
void CJS_Date::Attach(v8::Local<v8::Value> pDate) {
m_pDate = pDate;
}
int CJS_Date::GetYear() {
if (IsValidDate())
return JS_GetYearFromTime(JS_LocalTime(JS_ToNumber(m_isolate, m_pDate)));
return 0;
}
void CJS_Date::SetYear(int iYear) {
double date = MakeDate(iYear, GetMonth(), GetDay(), GetHours(), GetMinutes(),
GetSeconds(), 0);
JS_ValueCopy(m_pDate, JS_NewDate(m_isolate, date));
}
int CJS_Date::GetMonth() {
if (IsValidDate())
return JS_GetMonthFromTime(JS_LocalTime(JS_ToNumber(m_isolate, m_pDate)));
return 0;
}
void CJS_Date::SetMonth(int iMonth) {
double date = MakeDate(GetYear(), iMonth, GetDay(), GetHours(), GetMinutes(),
GetSeconds(), 0);
JS_ValueCopy(m_pDate, JS_NewDate(m_isolate, date));
}
int CJS_Date::GetDay() {
if (IsValidDate())
return JS_GetDayFromTime(JS_LocalTime(JS_ToNumber(m_isolate, m_pDate)));
return 0;
}
void CJS_Date::SetDay(int iDay) {
double date = MakeDate(GetYear(), GetMonth(), iDay, GetHours(), GetMinutes(),
GetSeconds(), 0);
JS_ValueCopy(m_pDate, JS_NewDate(m_isolate, date));
}
int CJS_Date::GetHours() {
if (IsValidDate())
return JS_GetHourFromTime(JS_LocalTime(JS_ToNumber(m_isolate, m_pDate)));
return 0;
}
void CJS_Date::SetHours(int iHours) {
double date = MakeDate(GetYear(), GetMonth(), GetDay(), iHours, GetMinutes(),
GetSeconds(), 0);
JS_ValueCopy(m_pDate, JS_NewDate(m_isolate, date));
}
int CJS_Date::GetMinutes() {
if (IsValidDate())
return JS_GetMinFromTime(JS_LocalTime(JS_ToNumber(m_isolate, m_pDate)));
return 0;
}
void CJS_Date::SetMinutes(int minutes) {
double date = MakeDate(GetYear(), GetMonth(), GetDay(), GetHours(), minutes,
GetSeconds(), 0);
JS_ValueCopy(m_pDate, JS_NewDate(m_isolate, date));
}
int CJS_Date::GetSeconds() {
if (IsValidDate())
return JS_GetSecFromTime(JS_LocalTime(JS_ToNumber(m_isolate, m_pDate)));
return 0;
}
void CJS_Date::SetSeconds(int seconds) {
double date = MakeDate(GetYear(), GetMonth(), GetDay(), GetHours(),
GetMinutes(), seconds, 0);
JS_ValueCopy(m_pDate, JS_NewDate(m_isolate, date));
}
CJS_Date::operator v8::Local<v8::Value>() {
return m_pDate;
}
CJS_Date::operator double() const {
if (m_pDate.IsEmpty())
return 0.0;
return JS_ToNumber(m_isolate, m_pDate);
}
CFX_WideString CJS_Date::ToString() const {
if (m_pDate.IsEmpty())
return L"";
return JS_ToString(m_isolate, m_pDate);
}