1// Copyright 2014 PDFium Authors. All rights reserved. 2// Use of this source code is governed by a BSD-style license that can be 3// found in the LICENSE file. 4 5// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com 6 7#include "../../include/javascript/JavaScript.h" 8#include "../../include/javascript/JS_Define.h" 9#include "../../include/javascript/JS_Object.h" 10#include "../../include/javascript/JS_Value.h" 11#include "../../include/javascript/Document.h" 12 13/* ---------------------------- CJS_Value ---------------------------- */ 14 15CJS_Value::CJS_Value(v8::Isolate* isolate) : m_eType(VT_unknown),m_isolate(isolate) 16{ 17} 18CJS_Value::CJS_Value(v8::Isolate* isolate, v8::Local<v8::Value> pValue,FXJSVALUETYPE t) : 19 m_pValue(pValue), m_eType(t), m_isolate(isolate) 20{ 21} 22 23CJS_Value::CJS_Value(v8::Isolate* isolate, const int &iValue):m_isolate(isolate) 24{ 25 operator =(iValue); 26} 27 28CJS_Value::CJS_Value(v8::Isolate* isolate, const bool &bValue):m_isolate(isolate) 29{ 30 operator =(bValue); 31} 32 33CJS_Value::CJS_Value(v8::Isolate* isolate, const float &fValue):m_isolate(isolate) 34{ 35 operator =(fValue); 36} 37 38CJS_Value::CJS_Value(v8::Isolate* isolate, const double &dValue):m_isolate(isolate) 39{ 40 operator =(dValue); 41} 42 43CJS_Value::CJS_Value(v8::Isolate* isolate, JSFXObject pJsObj):m_isolate(isolate) 44{ 45 operator =(pJsObj); 46} 47 48CJS_Value::CJS_Value(v8::Isolate* isolate, CJS_Object* pJsObj):m_isolate(isolate) 49{ 50 operator =(pJsObj); 51} 52 53CJS_Value::CJS_Value(v8::Isolate* isolate, CJS_Document* pJsDoc):m_isolate(isolate) 54{ 55 m_eType = VT_object; 56 if (pJsDoc) 57 m_pValue = (JSFXObject)*pJsDoc; 58} 59 60CJS_Value::CJS_Value(v8::Isolate* isolate, FX_LPCWSTR pWstr):m_isolate(isolate) 61{ 62 operator =(pWstr); 63} 64 65CJS_Value::CJS_Value(v8::Isolate* isolate, FX_LPCSTR pStr):m_isolate(isolate) 66{ 67 operator = (pStr); 68} 69 70CJS_Value::CJS_Value(v8::Isolate* isolate, CJS_Array& array):m_isolate(isolate) 71{ 72 operator = (array); 73} 74 75CJS_Value::~CJS_Value() 76{ 77} 78 79void CJS_Value::Attach(v8::Local<v8::Value> pValue,FXJSVALUETYPE t) 80{ 81 m_pValue = pValue; 82 m_eType = t; 83} 84 85void CJS_Value::Attach(CJS_Value *pValue) 86{ 87 if (pValue) 88 Attach(pValue->ToV8Value(), pValue->GetType()); 89} 90 91void CJS_Value::Detach() 92{ 93 m_pValue = v8::Local<v8::Value>(); 94 m_eType = VT_unknown; 95} 96 97/* ---------------------------------------------------------------------------------------- */ 98 99int CJS_Value::ToInt() const 100{ 101 return JS_ToInt32(m_isolate, m_pValue); 102} 103 104bool CJS_Value::ToBool() const 105{ 106 return JS_ToBoolean(m_isolate, m_pValue); 107} 108 109double CJS_Value::ToDouble() const 110{ 111 return JS_ToNumber(m_isolate, m_pValue); 112} 113 114float CJS_Value::ToFloat() const 115{ 116 return (float)ToDouble(); 117} 118 119CJS_Object* CJS_Value::ToCJSObject() const 120{ 121 v8::Local<v8::Object> pObj = JS_ToObject(m_isolate, m_pValue); 122 return (CJS_Object*)JS_GetPrivate(m_isolate, pObj); 123} 124 125v8::Local<v8::Object> CJS_Value::ToV8Object() const 126{ 127 return JS_ToObject(m_isolate, m_pValue); 128} 129 130CFX_WideString CJS_Value::ToCFXWideString() const 131{ 132 return JS_ToString(m_isolate, m_pValue); 133} 134 135CFX_ByteString CJS_Value::ToCFXByteString() const 136{ 137 return CFX_ByteString::FromUnicode(ToCFXWideString()); 138} 139 140v8::Local<v8::Value> CJS_Value::ToV8Value() const 141{ 142 return m_pValue; 143} 144 145v8::Local<v8::Array>CJS_Value::ToV8Array() const 146{ 147 if (IsArrayObject()) 148 return v8::Local<v8::Array>::Cast(JS_ToObject(m_isolate, m_pValue)); 149 return v8::Local<v8::Array>(); 150} 151 152/* ---------------------------------------------------------------------------------------- */ 153 154void CJS_Value::operator =(int iValue) 155{ 156 m_pValue = JS_NewNumber(m_isolate, iValue); 157 158 m_eType = VT_number; 159} 160 161void CJS_Value::operator =(bool bValue) 162{ 163 m_pValue = JS_NewBoolean(m_isolate, bValue); 164 165 m_eType = VT_boolean; 166} 167 168void CJS_Value::operator =(double dValue) 169{ 170 m_pValue = JS_NewNumber(m_isolate,dValue); 171 172 m_eType = VT_number; 173} 174 175void CJS_Value::operator = (float fValue) 176{ 177 m_pValue = JS_NewNumber(m_isolate,fValue); 178 m_eType = VT_number; 179} 180 181void CJS_Value::operator =(v8::Local<v8::Object> pObj) 182{ 183 184 m_pValue = JS_NewObject(m_isolate,pObj); 185 186 m_eType = VT_fxobject; 187} 188 189void CJS_Value::operator =(CJS_Object * pObj) 190{ 191 if (pObj) 192 operator = ((JSFXObject)*pObj); 193} 194 195void CJS_Value::operator = (CJS_Document* pJsDoc) 196{ 197 m_eType = VT_object; 198 if (pJsDoc) { 199 m_pValue = static_cast<JSFXObject>(*pJsDoc); 200 } 201} 202 203void CJS_Value::operator =(FX_LPCWSTR pWstr) 204{ 205 m_pValue = JS_NewString(m_isolate,(wchar_t *)pWstr); 206 207 m_eType = VT_string; 208} 209 210void CJS_Value::SetNull() 211{ 212 m_pValue = JS_NewNull(); 213 214 m_eType = VT_null; 215} 216 217void CJS_Value::operator = (FX_LPCSTR pStr) 218{ 219 operator = (CFX_WideString::FromLocal(pStr).c_str()); 220} 221 222void CJS_Value::operator = (CJS_Array & array) 223{ 224 m_pValue = JS_NewObject2(m_isolate,(v8::Local<v8::Array>)array); 225 226 m_eType = VT_object; 227} 228 229void CJS_Value::operator = (CJS_Date & date) 230{ 231 m_pValue = JS_NewDate(m_isolate, (double)date); 232 233 m_eType = VT_date; 234} 235 236void CJS_Value::operator = (CJS_Value value) 237{ 238 m_pValue = value.ToV8Value(); 239 240 m_eType = value.m_eType; 241 m_isolate = value.m_isolate; 242} 243 244/* ---------------------------------------------------------------------------------------- */ 245 246FXJSVALUETYPE CJS_Value::GetType() const 247{ 248 if(m_pValue.IsEmpty()) return VT_unknown; 249 if(m_pValue->IsString()) return VT_string; 250 if(m_pValue->IsNumber()) return VT_number; 251 if(m_pValue->IsBoolean()) return VT_boolean; 252 if(m_pValue->IsDate()) return VT_date; 253 if(m_pValue->IsObject()) return VT_object; 254 if(m_pValue->IsNull()) return VT_null; 255 if(m_pValue->IsUndefined()) return VT_undefined; 256 return VT_unknown; 257} 258 259FX_BOOL CJS_Value::IsArrayObject() const 260{ 261 if(m_pValue.IsEmpty()) return FALSE; 262 return m_pValue->IsArray(); 263} 264 265FX_BOOL CJS_Value::IsDateObject() const 266{ 267 if(m_pValue.IsEmpty()) return FALSE; 268 return m_pValue->IsDate(); 269} 270 271//CJS_Value::operator CJS_Array() 272FX_BOOL CJS_Value::ConvertToArray(CJS_Array &array) const 273{ 274 if (IsArrayObject()) 275 { 276 array.Attach(JS_ToArray(m_isolate, m_pValue)); 277 return TRUE; 278 } 279 280 return FALSE; 281} 282 283FX_BOOL CJS_Value::ConvertToDate(CJS_Date &date) const 284{ 285// if (GetType() == VT_date) 286// { 287// date = (double)(*this); 288// return TRUE; 289// } 290 291 if (IsDateObject()) 292 { 293 date.Attach(m_pValue); 294 return TRUE; 295 } 296 297 return FALSE; 298} 299 300/* ---------------------------- CJS_PropValue ---------------------------- */ 301 302CJS_PropValue::CJS_PropValue(const CJS_Value &value) : 303 CJS_Value(value), 304 m_bIsSetting(0) 305{ 306} 307 308CJS_PropValue::CJS_PropValue(v8::Isolate* isolate) : CJS_Value(isolate), 309 m_bIsSetting(0) 310{ 311} 312 313CJS_PropValue::~CJS_PropValue() 314{ 315} 316 317FX_BOOL CJS_PropValue::IsSetting() 318{ 319 return m_bIsSetting; 320} 321 322FX_BOOL CJS_PropValue::IsGetting() 323{ 324 return !m_bIsSetting; 325} 326 327void CJS_PropValue::operator <<(int iValue) 328{ 329 ASSERT(!m_bIsSetting); 330 CJS_Value::operator =(iValue); 331} 332 333void CJS_PropValue::operator >>(int & iValue) const 334{ 335 ASSERT(m_bIsSetting); 336 iValue = CJS_Value::ToInt(); 337} 338 339 340void CJS_PropValue::operator <<(bool bValue) 341{ 342 ASSERT(!m_bIsSetting); 343 CJS_Value::operator =(bValue); 344} 345 346void CJS_PropValue::operator >>(bool& bValue) const 347{ 348 ASSERT(m_bIsSetting); 349 bValue = CJS_Value::ToBool(); 350} 351 352void CJS_PropValue::operator <<(double dValue) 353{ 354 ASSERT(!m_bIsSetting); 355 CJS_Value::operator =(dValue); 356} 357 358void CJS_PropValue::operator >>(double& dValue) const 359{ 360 ASSERT(m_bIsSetting); 361 dValue = CJS_Value::ToDouble(); 362} 363 364void CJS_PropValue::operator <<(CJS_Object* pObj) 365{ 366 ASSERT(!m_bIsSetting); 367 CJS_Value::operator = (pObj); 368} 369 370void CJS_PropValue::operator >>(CJS_Object*& ppObj) const 371{ 372 ASSERT(m_bIsSetting); 373 ppObj = CJS_Value::ToCJSObject(); 374} 375 376void CJS_PropValue::operator <<(CJS_Document* pJsDoc) 377{ 378 ASSERT(!m_bIsSetting); 379 CJS_Value::operator = (pJsDoc); 380} 381 382void CJS_PropValue::operator >>(CJS_Document*& ppJsDoc) const 383{ 384 ASSERT(m_bIsSetting); 385 ppJsDoc = static_cast<CJS_Document*>(CJS_Value::ToCJSObject()); 386} 387 388void CJS_PropValue::operator<<(JSFXObject pObj) 389{ 390 ASSERT(!m_bIsSetting); 391 CJS_Value::operator = (pObj); 392} 393 394void CJS_PropValue::operator>>(JSFXObject &ppObj) const 395{ 396 ASSERT(m_bIsSetting); 397 ppObj = CJS_Value::ToV8Object(); 398} 399 400 401void CJS_PropValue::StartSetting() 402{ 403 m_bIsSetting = 1; 404} 405 406void CJS_PropValue::StartGetting() 407{ 408 m_bIsSetting = 0; 409} 410void CJS_PropValue::operator <<(CFX_ByteString string) 411{ 412 ASSERT(!m_bIsSetting); 413 CJS_Value::operator = (string.c_str()); 414} 415 416void CJS_PropValue::operator >>(CFX_ByteString &string) const 417{ 418 ASSERT(m_bIsSetting); 419 string = CJS_Value::ToCFXByteString(); 420} 421 422void CJS_PropValue::operator <<(FX_LPCWSTR c_string) 423{ 424 ASSERT(!m_bIsSetting); 425 CJS_Value::operator =(c_string); 426} 427 428void CJS_PropValue::operator >>(CFX_WideString &wide_string) const 429{ 430 ASSERT(m_bIsSetting); 431 wide_string = CJS_Value::ToCFXWideString(); 432} 433 434void CJS_PropValue::operator <<(CFX_WideString wide_string) 435{ 436 ASSERT(!m_bIsSetting); 437 CJS_Value::operator = (wide_string.c_str()); 438} 439 440void CJS_PropValue::operator >>(CJS_Array &array) const 441{ 442 ASSERT(m_bIsSetting); 443 ConvertToArray(array); 444} 445 446void CJS_PropValue::operator <<(CJS_Array &array) 447{ 448 ASSERT(!m_bIsSetting); 449 CJS_Value::operator=(array); 450} 451 452void CJS_PropValue::operator>>(CJS_Date &date) const 453{ 454 ASSERT(m_bIsSetting); 455 ConvertToDate(date); 456} 457 458void CJS_PropValue::operator<<(CJS_Date &date) 459{ 460 ASSERT(!m_bIsSetting); 461 CJS_Value::operator=(date); 462} 463 464CJS_PropValue::operator v8::Local<v8::Value>() const 465{ 466 return m_pValue; 467} 468 469/* ======================================== CJS_Array ========================================= */ 470CJS_Array::CJS_Array(v8::Isolate* isolate):m_isolate(isolate) 471{ 472} 473 474CJS_Array::~CJS_Array() 475{ 476} 477 478void CJS_Array::Attach(v8::Local<v8::Array> pArray) 479{ 480 m_pArray = pArray; 481} 482 483FX_BOOL CJS_Array::IsAttached() 484{ 485 return FALSE; 486} 487 488void CJS_Array::GetElement(unsigned index,CJS_Value &value) 489{ 490 if (m_pArray.IsEmpty()) 491 return; 492 v8::Local<v8::Value> p = JS_GetArrayElement(m_isolate, m_pArray,index); 493 value.Attach(p,VT_object); 494} 495 496void CJS_Array::SetElement(unsigned index,CJS_Value value) 497{ 498 if (m_pArray.IsEmpty()) 499 m_pArray = JS_NewArray(m_isolate); 500 501 JS_PutArrayElement(m_isolate, m_pArray, index, value.ToV8Value(), value.GetType()); 502} 503 504int CJS_Array::GetLength() 505{ 506 if (m_pArray.IsEmpty()) 507 return 0; 508 return JS_GetArrayLength(m_pArray); 509} 510 511CJS_Array:: operator v8::Local<v8::Array>() 512{ 513 if (m_pArray.IsEmpty()) 514 m_pArray = JS_NewArray(m_isolate); 515 516 return m_pArray; 517} 518 519/* ======================================== CJS_Date ========================================= */ 520 521CJS_Date::CJS_Date(v8::Isolate* isolate) :m_isolate(isolate) 522{ 523} 524 525CJS_Date::CJS_Date(v8::Isolate* isolate,double dMsec_time) 526{ 527 m_isolate = isolate; 528 m_pDate = JS_NewDate(isolate,dMsec_time); 529} 530 531CJS_Date::CJS_Date(v8::Isolate* isolate,int year, int mon, int day,int hour, int min, int sec) 532{ 533 m_isolate = isolate; 534 m_pDate = JS_NewDate(isolate,MakeDate(year,mon,day,hour,min,sec,0)); 535} 536 537double CJS_Date::MakeDate(int year, int mon, int day,int hour, int min, int sec,int ms) 538{ 539 return JS_MakeDate(JS_MakeDay(year,mon,day), JS_MakeTime(hour,min,sec,ms)); 540} 541 542CJS_Date::~CJS_Date() 543{ 544} 545 546FX_BOOL CJS_Date::IsValidDate() 547{ 548 if(m_pDate.IsEmpty()) return FALSE; 549 return !JS_PortIsNan(JS_ToNumber(m_isolate, m_pDate)); 550} 551 552void CJS_Date::Attach(v8::Local<v8::Value> pDate) 553{ 554 m_pDate = pDate; 555} 556 557int CJS_Date::GetYear() 558{ 559 if (IsValidDate()) 560 return JS_GetYearFromTime(JS_LocalTime(JS_ToNumber(m_isolate, m_pDate))); 561 562 return 0; 563} 564 565void CJS_Date::SetYear(int iYear) 566{ 567 double date = MakeDate(iYear,GetMonth(),GetDay(),GetHours(),GetMinutes(),GetSeconds(),0); 568 JS_ValueCopy(m_pDate, JS_NewDate(m_isolate,date)); 569} 570 571int CJS_Date::GetMonth() 572{ 573 if (IsValidDate()) 574 return JS_GetMonthFromTime(JS_LocalTime(JS_ToNumber(m_isolate, m_pDate))); 575 576 return 0; 577} 578 579void CJS_Date::SetMonth(int iMonth) 580{ 581 582 double date = MakeDate(GetYear(),iMonth,GetDay(),GetHours(),GetMinutes(),GetSeconds(),0); 583 JS_ValueCopy(m_pDate, JS_NewDate(m_isolate,date)); 584 585} 586 587int CJS_Date::GetDay() 588{ 589 if (IsValidDate()) 590 return JS_GetDayFromTime(JS_LocalTime(JS_ToNumber(m_isolate, m_pDate))); 591 592 return 0; 593} 594 595void CJS_Date::SetDay(int iDay) 596{ 597 598 double date = MakeDate(GetYear(),GetMonth(),iDay,GetHours(),GetMinutes(),GetSeconds(),0); 599 JS_ValueCopy(m_pDate,JS_NewDate(m_isolate,date)); 600 601} 602 603int CJS_Date::GetHours() 604{ 605 if (IsValidDate()) 606 return JS_GetHourFromTime(JS_LocalTime(JS_ToNumber(m_isolate, m_pDate))); 607 608 return 0; 609} 610 611void CJS_Date::SetHours(int iHours) 612{ 613 double date = MakeDate(GetYear(),GetMonth(),GetDay(),iHours,GetMinutes(),GetSeconds(),0); 614 JS_ValueCopy(m_pDate,JS_NewDate(m_isolate,date)); 615} 616 617int CJS_Date::GetMinutes() 618{ 619 if (IsValidDate()) 620 return JS_GetMinFromTime(JS_LocalTime(JS_ToNumber(m_isolate, m_pDate))); 621 622 return 0; 623} 624 625void CJS_Date::SetMinutes(int minutes) 626{ 627 double date = MakeDate(GetYear(),GetMonth(),GetDay(),GetHours(),minutes,GetSeconds(),0); 628 JS_ValueCopy(m_pDate,JS_NewDate(m_isolate,date)); 629} 630 631int CJS_Date::GetSeconds() 632{ 633 if (IsValidDate()) 634 return JS_GetSecFromTime(JS_LocalTime(JS_ToNumber(m_isolate, m_pDate))); 635 636 return 0; 637} 638 639void CJS_Date::SetSeconds(int seconds) 640{ 641 double date = MakeDate(GetYear(),GetMonth(),GetDay(),GetHours(),GetMinutes(),seconds,0); 642 JS_ValueCopy(m_pDate,JS_NewDate(m_isolate,date)); 643} 644 645CJS_Date::operator v8::Local<v8::Value>() 646{ 647 return m_pDate; 648} 649 650CJS_Date::operator double() const 651{ 652 if(m_pDate.IsEmpty()) 653 return 0.0; 654 return JS_ToNumber(m_isolate, m_pDate); 655} 656 657CFX_WideString CJS_Date::ToString() const 658{ 659 if(m_pDate.IsEmpty()) 660 return L""; 661 return JS_ToString(m_isolate, m_pDate); 662} 663