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 15 CJS_Value::CJS_Value(v8::Isolate* isolate) : m_eType(VT_unknown),m_isolate(isolate) 16 { 17 } 18 CJS_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 23 CJS_Value::CJS_Value(v8::Isolate* isolate, const int &iValue):m_isolate(isolate) 24 { 25 operator =(iValue); 26 } 27 28 CJS_Value::CJS_Value(v8::Isolate* isolate, const bool &bValue):m_isolate(isolate) 29 { 30 operator =(bValue); 31 } 32 33 CJS_Value::CJS_Value(v8::Isolate* isolate, const float &fValue):m_isolate(isolate) 34 { 35 operator =(fValue); 36 } 37 38 CJS_Value::CJS_Value(v8::Isolate* isolate, const double &dValue):m_isolate(isolate) 39 { 40 operator =(dValue); 41 } 42 43 CJS_Value::CJS_Value(v8::Isolate* isolate, JSFXObject pJsObj):m_isolate(isolate) 44 { 45 operator =(pJsObj); 46 } 47 48 CJS_Value::CJS_Value(v8::Isolate* isolate, CJS_Object* pJsObj):m_isolate(isolate) 49 { 50 operator =(pJsObj); 51 } 52 53 CJS_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 60 CJS_Value::CJS_Value(v8::Isolate* isolate, FX_LPCWSTR pWstr):m_isolate(isolate) 61 { 62 operator =(pWstr); 63 } 64 65 CJS_Value::CJS_Value(v8::Isolate* isolate, FX_LPCSTR pStr):m_isolate(isolate) 66 { 67 operator = (pStr); 68 } 69 70 CJS_Value::CJS_Value(v8::Isolate* isolate, CJS_Array& array):m_isolate(isolate) 71 { 72 operator = (array); 73 } 74 75 CJS_Value::~CJS_Value() 76 { 77 } 78 79 void CJS_Value::Attach(v8::Local<v8::Value> pValue,FXJSVALUETYPE t) 80 { 81 m_pValue = pValue; 82 m_eType = t; 83 } 84 85 void CJS_Value::Attach(CJS_Value *pValue) 86 { 87 if (pValue) 88 Attach(pValue->ToV8Value(), pValue->GetType()); 89 } 90 91 void CJS_Value::Detach() 92 { 93 m_pValue = v8::Local<v8::Value>(); 94 m_eType = VT_unknown; 95 } 96 97 /* ---------------------------------------------------------------------------------------- */ 98 99 int CJS_Value::ToInt() const 100 { 101 return JS_ToInt32(m_isolate, m_pValue); 102 } 103 104 bool CJS_Value::ToBool() const 105 { 106 return JS_ToBoolean(m_isolate, m_pValue); 107 } 108 109 double CJS_Value::ToDouble() const 110 { 111 return JS_ToNumber(m_isolate, m_pValue); 112 } 113 114 float CJS_Value::ToFloat() const 115 { 116 return (float)ToDouble(); 117 } 118 119 CJS_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 125 v8::Local<v8::Object> CJS_Value::ToV8Object() const 126 { 127 return JS_ToObject(m_isolate, m_pValue); 128 } 129 130 CFX_WideString CJS_Value::ToCFXWideString() const 131 { 132 return JS_ToString(m_isolate, m_pValue); 133 } 134 135 CFX_ByteString CJS_Value::ToCFXByteString() const 136 { 137 return CFX_ByteString::FromUnicode(ToCFXWideString()); 138 } 139 140 v8::Local<v8::Value> CJS_Value::ToV8Value() const 141 { 142 return m_pValue; 143 } 144 145 v8::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 154 void CJS_Value::operator =(int iValue) 155 { 156 m_pValue = JS_NewNumber(m_isolate, iValue); 157 158 m_eType = VT_number; 159 } 160 161 void CJS_Value::operator =(bool bValue) 162 { 163 m_pValue = JS_NewBoolean(m_isolate, bValue); 164 165 m_eType = VT_boolean; 166 } 167 168 void CJS_Value::operator =(double dValue) 169 { 170 m_pValue = JS_NewNumber(m_isolate,dValue); 171 172 m_eType = VT_number; 173 } 174 175 void CJS_Value::operator = (float fValue) 176 { 177 m_pValue = JS_NewNumber(m_isolate,fValue); 178 m_eType = VT_number; 179 } 180 181 void 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 189 void CJS_Value::operator =(CJS_Object * pObj) 190 { 191 if (pObj) 192 operator = ((JSFXObject)*pObj); 193 } 194 195 void 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 203 void 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 210 void CJS_Value::SetNull() 211 { 212 m_pValue = JS_NewNull(); 213 214 m_eType = VT_null; 215 } 216 217 void CJS_Value::operator = (FX_LPCSTR pStr) 218 { 219 operator = (CFX_WideString::FromLocal(pStr).c_str()); 220 } 221 222 void 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 229 void CJS_Value::operator = (CJS_Date & date) 230 { 231 m_pValue = JS_NewDate(m_isolate, (double)date); 232 233 m_eType = VT_date; 234 } 235 236 void 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 246 FXJSVALUETYPE 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 259 FX_BOOL CJS_Value::IsArrayObject() const 260 { 261 if(m_pValue.IsEmpty()) return FALSE; 262 return m_pValue->IsArray(); 263 } 264 265 FX_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() 272 FX_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 283 FX_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 302 CJS_PropValue::CJS_PropValue(const CJS_Value &value) : 303 CJS_Value(value), 304 m_bIsSetting(0) 305 { 306 } 307 308 CJS_PropValue::CJS_PropValue(v8::Isolate* isolate) : CJS_Value(isolate), 309 m_bIsSetting(0) 310 { 311 } 312 313 CJS_PropValue::~CJS_PropValue() 314 { 315 } 316 317 FX_BOOL CJS_PropValue::IsSetting() 318 { 319 return m_bIsSetting; 320 } 321 322 FX_BOOL CJS_PropValue::IsGetting() 323 { 324 return !m_bIsSetting; 325 } 326 327 void CJS_PropValue::operator <<(int iValue) 328 { 329 ASSERT(!m_bIsSetting); 330 CJS_Value::operator =(iValue); 331 } 332 333 void CJS_PropValue::operator >>(int & iValue) const 334 { 335 ASSERT(m_bIsSetting); 336 iValue = CJS_Value::ToInt(); 337 } 338 339 340 void CJS_PropValue::operator <<(bool bValue) 341 { 342 ASSERT(!m_bIsSetting); 343 CJS_Value::operator =(bValue); 344 } 345 346 void CJS_PropValue::operator >>(bool& bValue) const 347 { 348 ASSERT(m_bIsSetting); 349 bValue = CJS_Value::ToBool(); 350 } 351 352 void CJS_PropValue::operator <<(double dValue) 353 { 354 ASSERT(!m_bIsSetting); 355 CJS_Value::operator =(dValue); 356 } 357 358 void CJS_PropValue::operator >>(double& dValue) const 359 { 360 ASSERT(m_bIsSetting); 361 dValue = CJS_Value::ToDouble(); 362 } 363 364 void CJS_PropValue::operator <<(CJS_Object* pObj) 365 { 366 ASSERT(!m_bIsSetting); 367 CJS_Value::operator = (pObj); 368 } 369 370 void CJS_PropValue::operator >>(CJS_Object*& ppObj) const 371 { 372 ASSERT(m_bIsSetting); 373 ppObj = CJS_Value::ToCJSObject(); 374 } 375 376 void CJS_PropValue::operator <<(CJS_Document* pJsDoc) 377 { 378 ASSERT(!m_bIsSetting); 379 CJS_Value::operator = (pJsDoc); 380 } 381 382 void CJS_PropValue::operator >>(CJS_Document*& ppJsDoc) const 383 { 384 ASSERT(m_bIsSetting); 385 ppJsDoc = static_cast<CJS_Document*>(CJS_Value::ToCJSObject()); 386 } 387 388 void CJS_PropValue::operator<<(JSFXObject pObj) 389 { 390 ASSERT(!m_bIsSetting); 391 CJS_Value::operator = (pObj); 392 } 393 394 void CJS_PropValue::operator>>(JSFXObject &ppObj) const 395 { 396 ASSERT(m_bIsSetting); 397 ppObj = CJS_Value::ToV8Object(); 398 } 399 400 401 void CJS_PropValue::StartSetting() 402 { 403 m_bIsSetting = 1; 404 } 405 406 void CJS_PropValue::StartGetting() 407 { 408 m_bIsSetting = 0; 409 } 410 void CJS_PropValue::operator <<(CFX_ByteString string) 411 { 412 ASSERT(!m_bIsSetting); 413 CJS_Value::operator = (string.c_str()); 414 } 415 416 void CJS_PropValue::operator >>(CFX_ByteString &string) const 417 { 418 ASSERT(m_bIsSetting); 419 string = CJS_Value::ToCFXByteString(); 420 } 421 422 void CJS_PropValue::operator <<(FX_LPCWSTR c_string) 423 { 424 ASSERT(!m_bIsSetting); 425 CJS_Value::operator =(c_string); 426 } 427 428 void CJS_PropValue::operator >>(CFX_WideString &wide_string) const 429 { 430 ASSERT(m_bIsSetting); 431 wide_string = CJS_Value::ToCFXWideString(); 432 } 433 434 void CJS_PropValue::operator <<(CFX_WideString wide_string) 435 { 436 ASSERT(!m_bIsSetting); 437 CJS_Value::operator = (wide_string.c_str()); 438 } 439 440 void CJS_PropValue::operator >>(CJS_Array &array) const 441 { 442 ASSERT(m_bIsSetting); 443 ConvertToArray(array); 444 } 445 446 void CJS_PropValue::operator <<(CJS_Array &array) 447 { 448 ASSERT(!m_bIsSetting); 449 CJS_Value::operator=(array); 450 } 451 452 void CJS_PropValue::operator>>(CJS_Date &date) const 453 { 454 ASSERT(m_bIsSetting); 455 ConvertToDate(date); 456 } 457 458 void CJS_PropValue::operator<<(CJS_Date &date) 459 { 460 ASSERT(!m_bIsSetting); 461 CJS_Value::operator=(date); 462 } 463 464 CJS_PropValue::operator v8::Local<v8::Value>() const 465 { 466 return m_pValue; 467 } 468 469 /* ======================================== CJS_Array ========================================= */ 470 CJS_Array::CJS_Array(v8::Isolate* isolate):m_isolate(isolate) 471 { 472 } 473 474 CJS_Array::~CJS_Array() 475 { 476 } 477 478 void CJS_Array::Attach(v8::Local<v8::Array> pArray) 479 { 480 m_pArray = pArray; 481 } 482 483 FX_BOOL CJS_Array::IsAttached() 484 { 485 return FALSE; 486 } 487 488 void 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 496 void 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 504 int CJS_Array::GetLength() 505 { 506 if (m_pArray.IsEmpty()) 507 return 0; 508 return JS_GetArrayLength(m_pArray); 509 } 510 511 CJS_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 521 CJS_Date::CJS_Date(v8::Isolate* isolate) :m_isolate(isolate) 522 { 523 } 524 525 CJS_Date::CJS_Date(v8::Isolate* isolate,double dMsec_time) 526 { 527 m_isolate = isolate; 528 m_pDate = JS_NewDate(isolate,dMsec_time); 529 } 530 531 CJS_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 537 double 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 542 CJS_Date::~CJS_Date() 543 { 544 } 545 546 FX_BOOL CJS_Date::IsValidDate() 547 { 548 if(m_pDate.IsEmpty()) return FALSE; 549 return !JS_PortIsNan(JS_ToNumber(m_isolate, m_pDate)); 550 } 551 552 void CJS_Date::Attach(v8::Local<v8::Value> pDate) 553 { 554 m_pDate = pDate; 555 } 556 557 int 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 565 void 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 571 int 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 579 void 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 587 int 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 595 void 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 603 int 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 611 void 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 617 int 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 625 void 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 631 int 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 639 void 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 645 CJS_Date::operator v8::Local<v8::Value>() 646 { 647 return m_pDate; 648 } 649 650 CJS_Date::operator double() const 651 { 652 if(m_pDate.IsEmpty()) 653 return 0.0; 654 return JS_ToNumber(m_isolate, m_pDate); 655 } 656 657 CFX_WideString CJS_Date::ToString() const 658 { 659 if(m_pDate.IsEmpty()) 660 return L""; 661 return JS_ToString(m_isolate, m_pDate); 662 } 663