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/IJavaScript.h"
9 #include "../../include/javascript/JS_Define.h"
10 #include "../../include/javascript/JS_Object.h"
11 #include "../../include/javascript/JS_Value.h"
12 #include "../../include/javascript/PublicMethods.h"
13 #include "../../include/javascript/JS_EventHandler.h"
14 #include "../../include/javascript/resource.h"
15 #include "../../include/javascript/JS_Context.h"
16 #include "../../include/javascript/JS_Value.h"
17 #include "../../include/javascript/util.h"
18 #include "../../include/javascript/Field.h"
19 #include "../../include/javascript/color.h"
20 #include "../../include/javascript/JS_Runtime.h"
21
GetIsolate(IFXJS_Context * cc)22 static v8::Isolate* GetIsolate(IFXJS_Context* cc)
23 {
24 CJS_Context* pContext = (CJS_Context *)cc;
25 ASSERT(pContext != NULL);
26
27 CJS_Runtime* pRuntime = pContext->GetJSRuntime();
28 ASSERT(pRuntime != NULL);
29
30 return pRuntime->GetIsolate();
31 }
32
33
34 /* -------------------------------- CJS_PublicMethods -------------------------------- */
35
36 #define DOUBLE_CORRECT 0.000000000000001
37
38 BEGIN_JS_STATIC_GLOBAL_FUN(CJS_PublicMethods)
39 JS_STATIC_GLOBAL_FUN_ENTRY(AFNumber_Format)
40 JS_STATIC_GLOBAL_FUN_ENTRY(AFNumber_Keystroke)
41 JS_STATIC_GLOBAL_FUN_ENTRY(AFPercent_Format)
42 JS_STATIC_GLOBAL_FUN_ENTRY(AFPercent_Keystroke)
43 JS_STATIC_GLOBAL_FUN_ENTRY(AFDate_FormatEx)
44 JS_STATIC_GLOBAL_FUN_ENTRY(AFDate_KeystrokeEx)
45 JS_STATIC_GLOBAL_FUN_ENTRY(AFDate_Format)
46 JS_STATIC_GLOBAL_FUN_ENTRY(AFDate_Keystroke)
47 JS_STATIC_GLOBAL_FUN_ENTRY(AFTime_FormatEx)
48 JS_STATIC_GLOBAL_FUN_ENTRY(AFTime_KeystrokeEx)
49 JS_STATIC_GLOBAL_FUN_ENTRY(AFTime_Format)
50 JS_STATIC_GLOBAL_FUN_ENTRY(AFTime_Keystroke)
51 JS_STATIC_GLOBAL_FUN_ENTRY(AFSpecial_Format)
52 JS_STATIC_GLOBAL_FUN_ENTRY(AFSpecial_Keystroke)
53 JS_STATIC_GLOBAL_FUN_ENTRY(AFSpecial_KeystrokeEx)
54 JS_STATIC_GLOBAL_FUN_ENTRY(AFSimple)
55 JS_STATIC_GLOBAL_FUN_ENTRY(AFMakeNumber)
56 JS_STATIC_GLOBAL_FUN_ENTRY(AFSimple_Calculate)
57 JS_STATIC_GLOBAL_FUN_ENTRY(AFRange_Validate)
58 JS_STATIC_GLOBAL_FUN_ENTRY(AFMergeChange)
59 JS_STATIC_GLOBAL_FUN_ENTRY(AFParseDateEx)
60 JS_STATIC_GLOBAL_FUN_ENTRY(AFExtractNums)
61 END_JS_STATIC_GLOBAL_FUN()
62
63 IMPLEMENT_JS_STATIC_GLOBAL_FUN(CJS_PublicMethods)
64
65 struct stru_TbConvert
66 {
67 FX_LPCSTR lpszJSMark;
68 FX_LPCSTR lpszCppMark;
69 };
70
71 static const stru_TbConvert fcTable[] = {
72 { "mmmm","%B" },
73 { "mmm", "%b" },
74 { "mm", "%m" },
75 //"m"
76 { "dddd","%A" },
77 { "ddd", "%a" },
78 { "dd", "%d" },
79 //"d", "%w",
80 { "yyyy","%Y" },
81 { "yy", "%y" },
82 { "HH", "%H" },
83 //"H"
84 { "hh", "%I" },
85 //"h"
86 { "MM", "%M" },
87 //"M"
88 { "ss", "%S" },
89 //"s
90 { "tt", "%p" },
91 //"t"
92 };
93
94 static FX_LPCWSTR months[] =
95 {
96 L"Jan", L"Feb", L"Mar", L"Apr", L"May", L"Jun", L"Jul", L"Aug", L"Sep", L"Oct", L"Nov", L"Dec"
97 };
98
99 static FX_LPCWSTR fullmonths[] =
100 {
101 L"January", L"February", L"March", L"April", L"May", L"June", L"July", L"August", L"September", L"October", L"November", L"December"
102 };
103
IsNumber(FX_LPCWSTR string)104 FX_BOOL CJS_PublicMethods::IsNumber(FX_LPCWSTR string)
105 {
106 CFX_WideString sTrim = StrTrim(string);
107 FX_LPCWSTR pTrim = sTrim.c_str();
108 FX_LPCWSTR p = pTrim;
109
110
111 FX_BOOL bDot = FALSE;
112 FX_BOOL bKXJS = FALSE;
113
114 wchar_t c;
115 while ((c = *p))
116 {
117 if (c == '.' || c == ',')
118 {
119 if (bDot) return FALSE;
120 bDot = TRUE;
121 }
122 else if (c == '-' || c == '+')
123 {
124 if (p != pTrim)
125 return FALSE;
126 }
127 else if (c == 'e' || c == 'E')
128 {
129 if (bKXJS) return FALSE;
130
131 p++;
132 c = *p;
133 if (c == '+' || c == '-')
134 {
135 bKXJS = TRUE;
136 }
137 else
138 {
139 return FALSE;
140 }
141 }
142 else if (!IsDigit(c))
143 {
144 return FALSE;
145 }
146 p++;
147 }
148
149 return TRUE;
150 }
151
IsDigit(wchar_t ch)152 FX_BOOL CJS_PublicMethods::IsDigit(wchar_t ch)
153 {
154 return (ch >= L'0' && ch <= L'9');
155 }
156
IsDigit(char ch)157 FX_BOOL CJS_PublicMethods::IsDigit(char ch)
158 {
159 return (ch >= '0' && ch <= '9');
160 }
161
IsAlphabetic(wchar_t ch)162 FX_BOOL CJS_PublicMethods::IsAlphabetic(wchar_t ch)
163 {
164 return ((ch >= L'a' && ch <= L'z') || (ch >= L'A' && ch <= L'Z'));
165 }
166
IsAlphaNumeric(wchar_t ch)167 FX_BOOL CJS_PublicMethods::IsAlphaNumeric(wchar_t ch)
168 {
169 return (IsDigit(ch) || IsAlphabetic(ch));
170 }
171
maskSatisfied(wchar_t c_Change,wchar_t c_Mask)172 FX_BOOL CJS_PublicMethods::maskSatisfied(wchar_t c_Change,wchar_t c_Mask)
173 {
174 switch (c_Mask)
175 {
176 case L'9':
177 return IsDigit(c_Change);
178 case L'A':
179 return IsAlphabetic(c_Change);
180 case L'O':
181 return IsAlphaNumeric(c_Change);
182 case L'X':
183 return TRUE;
184 default:
185 return (c_Change == c_Mask);
186 }
187 }
188
isReservedMaskChar(wchar_t ch)189 FX_BOOL CJS_PublicMethods::isReservedMaskChar(wchar_t ch)
190 {
191 return ch == L'9' || ch == L'A' || ch == L'O' || ch == L'X';
192 }
193
AF_Simple(FX_LPCWSTR sFuction,double dValue1,double dValue2)194 double CJS_PublicMethods::AF_Simple(FX_LPCWSTR sFuction, double dValue1, double dValue2)
195 {
196 if (FXSYS_wcsicmp(sFuction,L"AVG") == 0 || FXSYS_wcsicmp(sFuction,L"SUM") == 0)
197 {
198 return dValue1 + dValue2;
199 }
200 else if (FXSYS_wcsicmp(sFuction, L"PRD") == 0)
201 {
202 return dValue1 * dValue2;
203 }
204 else if (FXSYS_wcsicmp(sFuction,L"MIN") == 0)
205 {
206 return FX_MIN(dValue1, dValue2);
207 }
208 else if (FXSYS_wcsicmp(sFuction,L"MAX") == 0)
209 {
210 return FX_MAX(dValue1, dValue2);
211 }
212
213 return dValue1;
214 }
215
StrLTrim(FX_LPCWSTR pStr)216 CFX_WideString CJS_PublicMethods::StrLTrim(FX_LPCWSTR pStr)
217 {
218 while (*pStr && *pStr == L' ') pStr++;
219
220 return pStr;
221 }
222
StrRTrim(FX_LPCWSTR pStr)223 CFX_WideString CJS_PublicMethods::StrRTrim(FX_LPCWSTR pStr)
224 {
225 FX_LPCWSTR p = pStr;
226 while (*p) p++;
227 while (p > pStr && *(p - 1) == L' ') p--;
228
229 return CFX_WideString(pStr, p - pStr);
230 }
231
StrTrim(FX_LPCWSTR pStr)232 CFX_WideString CJS_PublicMethods::StrTrim(FX_LPCWSTR pStr)
233 {
234 return StrRTrim(StrLTrim(pStr).c_str());
235 }
236
StrLTrim(FX_LPCSTR pStr)237 CFX_ByteString CJS_PublicMethods::StrLTrim(FX_LPCSTR pStr)
238 {
239 while (*pStr && *pStr == ' ') pStr++;
240
241 return pStr;
242 }
243
StrRTrim(FX_LPCSTR pStr)244 CFX_ByteString CJS_PublicMethods::StrRTrim(FX_LPCSTR pStr)
245 {
246 FX_LPCSTR p = pStr;
247 while (*p) p++;
248 while (p > pStr && *(p - 1) == L' ') p--;
249
250 return CFX_ByteString(pStr,p-pStr);
251 }
252
StrTrim(FX_LPCSTR pStr)253 CFX_ByteString CJS_PublicMethods::StrTrim(FX_LPCSTR pStr)
254 {
255 return StrRTrim(StrLTrim(pStr));
256 }
257
ParseNumber(FX_LPCWSTR swSource,FX_BOOL & bAllDigits,FX_BOOL & bDot,FX_BOOL & bSign,FX_BOOL & bKXJS)258 double CJS_PublicMethods::ParseNumber(FX_LPCWSTR swSource, FX_BOOL& bAllDigits, FX_BOOL& bDot, FX_BOOL& bSign, FX_BOOL& bKXJS)
259 {
260 bDot = FALSE;
261 bSign = FALSE;
262 bKXJS = FALSE;
263
264 FX_BOOL bDigitExist = FALSE;
265
266 FX_LPCWSTR p = swSource;
267 wchar_t c;
268
269 FX_LPCWSTR pStart = NULL;
270 FX_LPCWSTR pEnd = NULL;
271
272 while ((c = *p))
273 {
274 if (!pStart && c != L' ')
275 {
276 pStart = p;
277 }
278
279 pEnd = p;
280 p++;
281 }
282
283 if (!pStart)
284 {
285 bAllDigits = FALSE;
286 return 0;
287 }
288
289 while (pEnd != pStart)
290 {
291 if (*pEnd == L' ')
292 pEnd --;
293 else
294 break;
295 }
296
297 double dRet = 0;
298 p = pStart;
299 bAllDigits = TRUE;
300 CFX_WideString swDigits;
301
302 while (p <= pEnd)
303 {
304 c = *p;
305
306 if (IsDigit(c))
307 {
308 swDigits += c;
309 bDigitExist = TRUE;
310 }
311 else
312 {
313 switch (c)
314 {
315 case L' ':
316 bAllDigits = FALSE;
317 break;
318 case L'.':
319 case L',':
320 if (!bDot)
321 {
322 if (bDigitExist)
323 {
324 swDigits += L'.';
325 }
326 else
327 {
328 swDigits += L'0';
329 swDigits += L'.';
330 bDigitExist = TRUE;
331 }
332
333 bDot = TRUE;
334 break;
335 }
336 case 'e':
337 case 'E':
338 if (!bKXJS)
339 {
340 p++;
341 c = *p;
342 if (c == '+' || c == '-')
343 {
344 bKXJS = TRUE;
345 swDigits += 'e';
346 swDigits += c;
347 }
348 break;
349 }
350 case L'-':
351 if (!bDigitExist && !bSign)
352 {
353 swDigits += c;
354 bSign = TRUE;
355 break;
356 }
357 default:
358 bAllDigits = FALSE;
359
360 if (p != pStart && !bDot && bDigitExist)
361 {
362 swDigits += L'.';
363 bDot = TRUE;
364 }
365 else
366 {
367 bDot = FALSE;
368 bDigitExist = FALSE;
369 swDigits = L"";
370 }
371 break;
372 }
373 }
374
375 p++;
376 }
377
378 if (swDigits.GetLength() > 0 && swDigits.GetLength() < 17)
379 {
380 CFX_ByteString sDigits = swDigits.UTF8Encode();
381
382 if (bKXJS)
383 {
384 dRet = atof(sDigits);
385 }
386 else
387 {
388 if (bDot)
389 {
390 char* pStopString;
391 dRet = ::strtod(sDigits, &pStopString);
392 }
393 else
394 {
395 dRet = atol(sDigits);
396 }
397 }
398
399 }
400
401 return dRet;
402 }
403
ParseStringToNumber(FX_LPCWSTR swSource)404 double CJS_PublicMethods::ParseStringToNumber(FX_LPCWSTR swSource)
405 {
406 FX_BOOL bAllDigits = FALSE;
407 FX_BOOL bDot = FALSE;
408 FX_BOOL bSign = FALSE;
409 FX_BOOL bKXJS = FALSE;
410
411 return ParseNumber(swSource, bAllDigits, bDot, bSign, bKXJS);
412 }
413
ConvertStringToNumber(FX_LPCWSTR swSource,double & dRet,FX_BOOL & bDot)414 FX_BOOL CJS_PublicMethods::ConvertStringToNumber(FX_LPCWSTR swSource, double & dRet, FX_BOOL & bDot)
415 {
416 FX_BOOL bAllDigits = FALSE;
417 FX_BOOL bSign = FALSE;
418 FX_BOOL bKXJS = FALSE;
419
420 dRet = ParseNumber(swSource, bAllDigits, bDot, bSign, bKXJS);
421
422 return bAllDigits;
423 }
424
AF_MakeArrayFromList(v8::Isolate * isolate,CJS_Value val)425 CJS_Array CJS_PublicMethods::AF_MakeArrayFromList(v8::Isolate* isolate, CJS_Value val)
426 {
427 CJS_Array StrArray(isolate);
428 if(val.IsArrayObject())
429 {
430 val.ConvertToArray(StrArray);
431 return StrArray;
432 }
433 CFX_WideString wsStr = val.ToCFXWideString();
434 CFX_ByteString t = CFX_ByteString::FromUnicode(wsStr);
435 const char * p = (const char *)t;
436
437
438 int ch = ',' ;
439 int nIndex = 0;
440
441 while (*p)
442 {
443 const char * pTemp = strchr(p, ch);
444 if (pTemp == NULL)
445 {
446 StrArray.SetElement(nIndex, CJS_Value(isolate, StrTrim(p).c_str()));
447 break;
448 }
449 else
450 {
451 char * pSub = new char[pTemp - p + 1];
452 strncpy(pSub, p, pTemp - p);
453 *(pSub + (pTemp - p)) = '\0';
454
455 StrArray.SetElement(nIndex, CJS_Value(isolate, StrTrim(pSub).c_str()));
456 delete []pSub;
457
458 nIndex ++;
459 p = ++pTemp;
460 }
461
462 }
463 return StrArray;
464 }
465
ParseStringInteger(const CFX_WideString & string,int nStart,int & nSkip,int nMaxStep)466 int CJS_PublicMethods::ParseStringInteger(const CFX_WideString& string,int nStart,int& nSkip, int nMaxStep)
467 {
468 int nRet = 0;
469 nSkip = 0;
470 for (int i=nStart, sz=string.GetLength(); i < sz; i++)
471 {
472 if (i-nStart > 10)
473 break;
474
475 FX_WCHAR c = string.GetAt(i);
476 if (IsDigit((wchar_t)c))
477 {
478 nRet = nRet * 10 + (c - '0');
479 nSkip = i - nStart + 1;
480 if (nSkip >= nMaxStep)
481 break;
482 }
483 else
484 break;
485 }
486
487 return nRet;
488 }
489
ParseStringString(const CFX_WideString & string,int nStart,int & nSkip)490 CFX_WideString CJS_PublicMethods::ParseStringString(const CFX_WideString& string, int nStart, int& nSkip)
491 {
492 CFX_WideString swRet;
493 nSkip = 0;
494 for (int i=nStart, sz=string.GetLength(); i < sz; i++)
495 {
496 FX_WCHAR c = string.GetAt(i);
497 if ((c >= L'a' && c <= L'z') || (c >= L'A' && c <= L'Z'))
498 {
499 swRet += c;
500 nSkip = i - nStart + 1;
501 }
502 else
503 break;
504 }
505
506 return swRet;
507 }
508
ParseNormalDate(const CFX_WideString & value,FX_BOOL & bWrongFormat)509 double CJS_PublicMethods::ParseNormalDate(const CFX_WideString & value, FX_BOOL& bWrongFormat)
510 {
511 double dt = JS_GetDateTime();
512
513 int nYear = JS_GetYearFromTime(dt);
514 int nMonth = JS_GetMonthFromTime(dt) + 1;
515 int nDay = JS_GetDayFromTime(dt);
516 int nHour = JS_GetHourFromTime(dt);
517 int nMin = JS_GetMinFromTime(dt);
518 int nSec = JS_GetSecFromTime(dt);
519
520 int number[3];
521
522 int nSkip = 0;
523 int nLen = value.GetLength();
524 int nIndex = 0;
525 int i = 0;
526 while (i < nLen)
527 {
528 if (nIndex > 2) break;
529
530 FX_WCHAR c = value.GetAt(i);
531 if (IsDigit((wchar_t)c))
532 {
533 number[nIndex++] = ParseStringInteger(value, i, nSkip, 4);
534 i += nSkip;
535 }
536 else
537 {
538 i ++;
539 }
540 }
541
542 if (nIndex == 2)
543 {
544 // case2: month/day
545 // case3: day/month
546 if ((number[0] >= 1 && number[0] <= 12) && (number[1] >= 1 && number[1] <= 31))
547 {
548 nMonth = number[0];
549 nDay = number[1];
550 }
551 else if ((number[0] >= 1 && number[0] <= 31) && (number[1] >= 1 && number[1] <= 12))
552 {
553 nDay = number[0];
554 nMonth = number[1];
555 }
556
557 bWrongFormat = FALSE;
558 }
559 else if (nIndex == 3)
560 {
561 // case1: year/month/day
562 // case2: month/day/year
563 // case3: day/month/year
564
565 if (number[0] > 12 && (number[1] >= 1 && number[1] <= 12) && (number[2] >= 1 && number[2] <= 31))
566 {
567 nYear = number[0];
568 nMonth = number[1];
569 nDay = number[2];
570 }
571 else if ((number[0] >= 1 && number[0] <= 12) && (number[1] >= 1 && number[1] <= 31) && number[2] > 31)
572 {
573 nMonth = number[0];
574 nDay = number[1];
575 nYear = number[2];
576 }
577 else if ((number[0] >= 1 && number[0] <= 31) && (number[1] >= 1 && number[1] <= 12) && number[2] > 31)
578 {
579 nDay = number[0];
580 nMonth = number[1];
581 nYear = number[2];
582 }
583
584 bWrongFormat = FALSE;
585 }
586 else
587 {
588 bWrongFormat = TRUE;
589 return dt;
590 }
591
592 CFX_WideString swTemp;
593 swTemp.Format(L"%d/%d/%d %d:%d:%d",nMonth,nDay,nYear,nHour,nMin,nSec);
594 return JS_DateParse(swTemp.c_str());
595 }
596
MakeRegularDate(const CFX_WideString & value,const CFX_WideString & format,FX_BOOL & bWrongFormat)597 double CJS_PublicMethods::MakeRegularDate(const CFX_WideString & value, const CFX_WideString & format, FX_BOOL& bWrongFormat)
598 {
599 double dt = JS_GetDateTime();
600
601 if (format.IsEmpty() || value.IsEmpty())
602 return dt;
603
604 int nYear = JS_GetYearFromTime(dt);
605 int nMonth = JS_GetMonthFromTime(dt) + 1;
606 int nDay = JS_GetDayFromTime(dt);
607 int nHour = JS_GetHourFromTime(dt);
608 int nMin = JS_GetMinFromTime(dt);
609 int nSec = JS_GetSecFromTime(dt);
610
611 int nYearSub = 99; //nYear - 2000;
612
613 FX_BOOL bPm = FALSE;
614 FX_BOOL bExit = FALSE;
615 bWrongFormat = FALSE;
616
617 int i=0;
618 int j=0;
619
620 while (i < format.GetLength())
621 {
622 if (bExit) break;
623
624 FX_WCHAR c = format.GetAt(i);
625 switch (c)
626 {
627 case ':':
628 case '.':
629 case '-':
630 case '\\':
631 case '/':
632 i++;
633 j++;
634 break;
635
636 case 'y':
637 case 'm':
638 case 'd':
639 case 'H':
640 case 'h':
641 case 'M':
642 case 's':
643 case 't':
644 {
645 int oldj = j;
646 int nSkip = 0;
647 int remaining = format.GetLength() - i - 1;
648
649 if (remaining == 0 || format.GetAt(i+1) != c)
650 {
651 switch (c)
652 {
653 case 'y':
654 i++;
655 j++;
656 break;
657 case 'm':
658 nMonth = ParseStringInteger(value, j, nSkip, 2);
659 i++;
660 j += nSkip;
661 break;
662 case 'd':
663 nDay = ParseStringInteger(value, j, nSkip, 2);
664 i++;
665 j += nSkip;
666 break;
667 case 'H':
668 nHour = ParseStringInteger(value, j, nSkip, 2);
669 i++;
670 j += nSkip;
671 break;
672 case 'h':
673 nHour = ParseStringInteger(value, j, nSkip, 2);
674 i++;
675 j += nSkip;
676 break;
677 case 'M':
678 nMin = ParseStringInteger(value, j, nSkip, 2);
679 i++;
680 j += nSkip;
681 break;
682 case 's':
683 nSec = ParseStringInteger(value, j, nSkip, 2);
684 i++;
685 j += nSkip;
686 break;
687 case 't':
688 bPm = (j < value.GetLength() && value.GetAt(j) == 'p');
689 i++;
690 j++;
691 break;
692 }
693 }
694 else if (remaining == 1 || format.GetAt(i+2) != c)
695 {
696 switch (c)
697 {
698 case 'y':
699 nYear = ParseStringInteger(value, j, nSkip, 4);
700 i += 2;
701 j += nSkip;
702 break;
703 case 'm':
704 nMonth = ParseStringInteger(value, j, nSkip, 2);
705 i += 2;
706 j += nSkip;
707 break;
708 case 'd':
709 nDay = ParseStringInteger(value, j, nSkip, 2);
710 i += 2;
711 j += nSkip;
712 break;
713 case 'H':
714 nHour = ParseStringInteger(value, j, nSkip, 2);
715 i += 2;
716 j += nSkip;
717 break;
718 case 'h':
719 nHour = ParseStringInteger(value, j, nSkip, 2);
720 i += 2;
721 j += nSkip;
722 break;
723 case 'M':
724 nMin = ParseStringInteger(value, j, nSkip, 2);
725 i += 2;
726 j += nSkip;
727 break;
728 case 's':
729 nSec = ParseStringInteger(value, j, nSkip, 2);
730 i += 2;
731 j += nSkip;
732 break;
733 case 't':
734 bPm = (j + 1 < value.GetLength() && value.GetAt(j) == 'p' && value.GetAt(j+1) == 'm');
735 i += 2;
736 j += 2;
737 break;
738 }
739 }
740 else if (remaining == 2 || format.GetAt(i+3) != c)
741 {
742 switch (c)
743 {
744 case 'm':
745 {
746 CFX_WideString sMonth = ParseStringString(value, j, nSkip);
747 FX_BOOL bFind = FALSE;
748 for (int m = 0; m < 12; m++)
749 {
750 if (sMonth.CompareNoCase(months[m]) == 0)
751 {
752 nMonth = m + 1;
753 i+=3;
754 j+=nSkip;
755 bFind = TRUE;
756 break;
757 }
758 }
759
760 if (!bFind)
761 {
762 nMonth = ParseStringInteger(value, j, nSkip, 3);
763 i+=3;
764 j += nSkip;
765 }
766 }
767 break;
768 case 'y':
769 break;
770 default:
771 i+=3;
772 j+=3;
773 break;
774 }
775 }
776 else if (remaining == 3 || format.GetAt(i+4) != c)
777 {
778 switch (c)
779 {
780
781
782 case 'y':
783 nYear = ParseStringInteger(value, j, nSkip, 4);
784 j += nSkip;
785 i += 4;
786 break;
787 case 'm':
788 {
789 FX_BOOL bFind = FALSE;
790
791 CFX_WideString sMonth = ParseStringString(value, j, nSkip);
792 sMonth.MakeLower();
793
794 for (int m = 0; m < 12; m++)
795 {
796 CFX_WideString sFullMonths = fullmonths[m];
797 sFullMonths.MakeLower();
798
799 if (sFullMonths.Find(sMonth.c_str(), 0) != -1)
800 {
801 nMonth = m + 1;
802 i += 4;
803 j += nSkip;
804 bFind = TRUE;
805 break;
806 }
807 }
808
809 if (!bFind)
810 {
811 nMonth = ParseStringInteger(value, j, nSkip, 4);
812 i+=4;
813 j += nSkip;
814 }
815 }
816 break;
817 default:
818 i += 4;
819 j += 4;
820 break;
821 }
822 }
823 else
824 {
825 if (j >= value.GetLength() || format.GetAt(i) != value.GetAt(j))
826 {
827 bWrongFormat = TRUE;
828 bExit = TRUE;
829 }
830 i++;
831 j++;
832 }
833
834 if (oldj == j)
835 {
836 bWrongFormat = TRUE;
837 bExit = TRUE;
838 }
839 }
840
841 break;
842 default:
843 if (value.GetLength() <= j)
844 {
845 bExit = TRUE;
846 }
847 else if (format.GetAt(i) != value.GetAt(j))
848 {
849 bWrongFormat = TRUE;
850 bExit = TRUE;
851 }
852
853 i++;
854 j++;
855 break;
856 }
857 }
858
859 if (bPm) nHour += 12;
860
861 if (nYear >= 0 && nYear <= nYearSub)
862 nYear += 2000;
863
864 if (nMonth < 1 || nMonth > 12)
865 bWrongFormat = TRUE;
866
867 if (nDay < 1 || nDay > 31)
868 bWrongFormat = TRUE;
869
870 if (nHour < 0 || nHour > 24)
871 bWrongFormat = TRUE;
872
873 if (nMin < 0 || nMin > 60)
874 bWrongFormat = TRUE;
875
876 if (nSec < 0 || nSec > 60)
877 bWrongFormat = TRUE;
878
879 double dRet = 0;
880
881 if (bWrongFormat)
882 {
883 dRet = ParseNormalDate(value, bWrongFormat);
884 }
885 else
886 {
887 dRet = JS_MakeDate(JS_MakeDay(nYear,nMonth - 1,nDay),JS_MakeTime(nHour, nMin, nSec, 0));
888
889 if (JS_PortIsNan(dRet))
890 {
891 dRet = JS_DateParse(value.c_str());
892 }
893 }
894
895 if (JS_PortIsNan(dRet))
896 {
897 dRet = ParseNormalDate(value, bWrongFormat);
898 }
899
900 return dRet;
901
902 }
903
MakeFormatDate(double dDate,const CFX_WideString & format)904 CFX_WideString CJS_PublicMethods::MakeFormatDate(double dDate, const CFX_WideString & format)
905 {
906 CFX_WideString sRet = L"",sPart = L"";
907
908 int nYear = JS_GetYearFromTime(dDate);
909 int nMonth = JS_GetMonthFromTime(dDate) + 1;
910 int nDay = JS_GetDayFromTime(dDate);
911 int nHour = JS_GetHourFromTime(dDate);
912 int nMin = JS_GetMinFromTime(dDate);
913 int nSec = JS_GetSecFromTime(dDate);
914
915 int i = 0;
916 while (i < format.GetLength())
917 {
918 FX_WCHAR c = format.GetAt(i);
919 int remaining = format.GetLength() - i - 1;
920 sPart = L"";
921 switch (c)
922 {
923 case 'y':
924 case 'm':
925 case 'd':
926 case 'H':
927 case 'h':
928 case 'M':
929 case 's':
930 case 't':
931 if (remaining == 0 || format.GetAt(i+1) != c)
932 {
933 switch (c)
934 {
935 case 'y':
936 sPart += c;
937 break;
938 case 'm':
939 sPart.Format(L"%d",nMonth);
940 break;
941 case 'd':
942 sPart.Format(L"%d",nDay);
943 break;
944 case 'H':
945 sPart.Format(L"%d",nHour);
946 break;
947 case 'h':
948 sPart.Format(L"%d",nHour>12?nHour - 12:nHour);
949 break;
950 case 'M':
951 sPart.Format(L"%d",nMin);
952 break;
953 case 's':
954 sPart.Format(L"%d",nSec);
955 break;
956 case 't':
957 sPart += nHour>12?'p':'a';
958 break;
959 }
960 i++;
961 }
962 else if (remaining == 1 || format.GetAt(i+2) != c)
963 {
964 switch (c)
965 {
966 case 'y':
967 sPart.Format(L"%02d",nYear - (nYear / 100) * 100);
968 break;
969 case 'm':
970 sPart.Format(L"%02d",nMonth);
971 break;
972 case 'd':
973 sPart.Format(L"%02d",nDay);
974 break;
975 case 'H':
976 sPart.Format(L"%02d",nHour);
977 break;
978 case 'h':
979 sPart.Format(L"%02d",nHour>12?nHour - 12:nHour);
980 break;
981 case 'M':
982 sPart.Format(L"%02d",nMin);
983 break;
984 case 's':
985 sPart.Format(L"%02d",nSec);
986 break;
987 case 't':
988 sPart = nHour>12? L"pm": L"am";
989 break;
990 }
991 i+=2;
992 }
993 else if (remaining == 2 || format.GetAt(i+3) != c)
994 {
995 switch (c)
996 {
997 case 'm':
998 i+=3;
999 if (nMonth > 0&&nMonth <= 12)
1000 sPart += months[nMonth - 1];
1001 break;
1002 default:
1003 i+=3;
1004 sPart += c;
1005 sPart += c;
1006 sPart += c;
1007 break;
1008 }
1009 }
1010 else if (remaining == 3 || format.GetAt(i+4) != c)
1011 {
1012 switch (c)
1013 {
1014 case 'y':
1015 sPart.Format(L"%04d",nYear);
1016 i += 4;
1017 break;
1018 case 'm':
1019 i+=4;
1020 if (nMonth > 0&&nMonth <= 12)
1021 sPart += fullmonths[nMonth - 1];
1022 break;
1023 default:
1024 i += 4;
1025 sPart += c;
1026 sPart += c;
1027 sPart += c;
1028 sPart += c;
1029 break;
1030 }
1031 }
1032 else
1033 {
1034 i++;
1035 sPart += c;
1036 }
1037 break;
1038 default:
1039 i++;
1040 sPart += c;
1041 break;
1042 }
1043
1044 sRet += sPart;
1045 }
1046
1047 return sRet;
1048 }
1049
1050 /* -------------------------------------------------------------------------- */
1051
1052 //function AFNumber_Format(nDec, sepStyle, negStyle, currStyle, strCurrency, bCurrencyPrepend)
AFNumber_Format(IFXJS_Context * cc,const CJS_Parameters & params,CJS_Value & vRet,CFX_WideString & sError)1053 FX_BOOL CJS_PublicMethods::AFNumber_Format(IFXJS_Context* cc, const CJS_Parameters& params, CJS_Value& vRet, CFX_WideString& sError)
1054 {
1055 #if _FX_OS_ != _FX_ANDROID_
1056 v8::Isolate* isolate = ::GetIsolate(cc);
1057 CJS_Context* pContext = (CJS_Context *)cc;
1058 ASSERT(pContext != NULL);
1059 CJS_EventHandler* pEvent = pContext->GetEventHandler();
1060 ASSERT(pEvent != NULL);
1061
1062 if (params.size() != 6)
1063 {
1064 sError = JSGetStringFromID(pContext, IDS_STRING_JSPARAMERROR);
1065 return FALSE;
1066 }
1067 if(!pEvent->m_pValue)
1068 return FALSE;
1069 CFX_WideString& Value = pEvent->Value();
1070 CFX_ByteString strValue = StrTrim(CFX_ByteString::FromUnicode(Value));
1071
1072 if (strValue.IsEmpty()) return TRUE;
1073
1074 int iDec = params[0].ToInt();
1075 int iSepStyle = params[1].ToInt();
1076 int iNegStyle = params[2].ToInt();
1077 // params[3] is iCurrStyle, it's not used.
1078 std::wstring wstrCurrency(params[4].ToCFXWideString().c_str());
1079 FX_BOOL bCurrencyPrepend = params[5].ToBool();
1080
1081 if (iDec < 0) iDec = -iDec;
1082
1083 if (iSepStyle < 0 || iSepStyle > 3)
1084 iSepStyle = 0;
1085
1086 if (iNegStyle < 0 || iNegStyle > 3)
1087 iNegStyle = 0;
1088
1089
1090 //////////////////////////////////////////////////////
1091 //for processing decimal places
1092 strValue.Replace(",", ".");
1093 double dValue = atof(strValue);
1094 if (iDec > 0)
1095 dValue += DOUBLE_CORRECT;
1096
1097 int iDec2;
1098 FX_BOOL bNegative = FALSE;
1099
1100 strValue = fcvt(dValue,iDec,&iDec2,&bNegative);
1101 if (strValue.IsEmpty())
1102 {
1103 dValue = 0;
1104 strValue = fcvt(dValue,iDec,&iDec2,&bNegative);
1105 if (strValue.IsEmpty())
1106 {
1107 strValue = "0";
1108 iDec2 = 1;
1109 }
1110
1111 }
1112
1113 if (iDec2 < 0)
1114 {
1115 for (int iNum = 0;iNum < abs(iDec2);iNum++)
1116 {
1117 strValue = "0" + strValue;
1118 }
1119 iDec2 = 0;
1120
1121 }
1122 int iMax = strValue.GetLength();
1123 if (iDec2 > iMax)
1124 {
1125 for (int iNum = 0;iNum <= iDec2 - iMax ;iNum++)
1126 {
1127 strValue += "0";
1128 }
1129 iMax = iDec2+1;
1130 }
1131 ///////////////////////////////////////////////////////
1132 //for processing seperator style
1133 if (iDec2 < iMax)
1134 {
1135 if (iSepStyle == 0 || iSepStyle == 1)
1136 {
1137 strValue.Insert(iDec2, '.');
1138 iMax++;
1139 }
1140 else if (iSepStyle == 2 || iSepStyle == 3)
1141 {
1142 strValue.Insert(iDec2, ',');
1143 iMax++;
1144 }
1145
1146 if (iDec2 == 0)
1147 strValue.Insert(iDec2, '0');
1148 }
1149 if (iSepStyle == 0 || iSepStyle == 2)
1150 {
1151 char cSeperator;
1152 if (iSepStyle == 0)
1153 cSeperator = ',';
1154 else
1155 cSeperator = '.';
1156
1157 int iDecPositive;
1158 iDecPositive = iDec2;
1159
1160 for (iDecPositive = iDec2 -3; iDecPositive > 0;iDecPositive -= 3)
1161 {
1162 strValue.Insert(iDecPositive, cSeperator);
1163 iMax++;
1164 }
1165 }
1166
1167 //////////////////////////////////////////////////////////////////////
1168 //for processing currency string
1169
1170 Value = CFX_WideString::FromLocal(strValue);
1171 std::wstring strValue2 = Value.c_str();
1172
1173 if (bCurrencyPrepend)
1174 strValue2 = wstrCurrency + strValue2;
1175 else
1176 strValue2 = strValue2 + wstrCurrency;
1177
1178
1179
1180 /////////////////////////////////////////////////////////////////////////
1181 //for processing negative style
1182 if (bNegative)
1183 {
1184 if (iNegStyle == 0)
1185 {
1186 strValue2.insert(0,L"-");
1187 }
1188 if (iNegStyle == 2 || iNegStyle == 3)
1189 {
1190 strValue2.insert(0,L"(");
1191 strValue2.insert(strValue2.length(),L")");
1192 }
1193 if (iNegStyle == 1 || iNegStyle == 3)
1194 {
1195 if (Field * fTarget = pEvent->Target_Field())
1196 {
1197 CJS_Array arColor(isolate);
1198 CJS_Value vColElm(isolate);
1199 vColElm = L"RGB";
1200 arColor.SetElement(0,vColElm);
1201 vColElm = 1;
1202 arColor.SetElement(1,vColElm);
1203 vColElm = 0;
1204 arColor.SetElement(2,vColElm);
1205
1206 arColor.SetElement(3,vColElm);
1207
1208 CJS_PropValue vProp(isolate);
1209 vProp.StartGetting();
1210 vProp<<arColor;
1211 vProp.StartSetting();
1212 fTarget->textColor(cc,vProp,sError);// red
1213 }
1214 }
1215 }
1216 else
1217 {
1218 if (iNegStyle == 1 || iNegStyle == 3)
1219 {
1220 if (Field *fTarget = pEvent->Target_Field())
1221 {
1222 CJS_Array arColor(isolate);
1223 CJS_Value vColElm(isolate);
1224 vColElm = L"RGB";
1225 arColor.SetElement(0,vColElm);
1226 vColElm = 0;
1227 arColor.SetElement(1,vColElm);
1228 arColor.SetElement(2,vColElm);
1229 arColor.SetElement(3,vColElm);
1230
1231 CJS_PropValue vProp(isolate);
1232 vProp.StartGetting();
1233 fTarget->textColor(cc,vProp,sError);
1234
1235 CJS_Array aProp(isolate);
1236 vProp.ConvertToArray(aProp);
1237
1238 CPWL_Color crProp;
1239 CPWL_Color crColor;
1240 color::ConvertArrayToPWLColor(aProp, crProp);
1241 color::ConvertArrayToPWLColor(arColor, crColor);
1242
1243 if (crColor != crProp)
1244 {
1245 CJS_PropValue vProp2(isolate);
1246 vProp2.StartGetting();
1247 vProp2<<arColor;
1248 vProp2.StartSetting();
1249 fTarget->textColor(cc,vProp2,sError);
1250 }
1251 }
1252 }
1253 }
1254 Value = strValue2.c_str();
1255 #endif
1256 return TRUE;
1257 }
1258
1259 //function AFNumber_Keystroke(nDec, sepStyle, negStyle, currStyle, strCurrency, bCurrencyPrepend)
AFNumber_Keystroke(IFXJS_Context * cc,const CJS_Parameters & params,CJS_Value & vRet,CFX_WideString & sError)1260 FX_BOOL CJS_PublicMethods::AFNumber_Keystroke(IFXJS_Context* cc, const CJS_Parameters& params, CJS_Value& vRet, CFX_WideString& sError)
1261 {
1262 CJS_Context* pContext = (CJS_Context *)cc;
1263 ASSERT(pContext != NULL);
1264 CJS_EventHandler* pEvent = pContext->GetEventHandler();
1265 ASSERT(pEvent != NULL);
1266
1267 if(params.size() < 2)
1268 return FALSE;
1269 int iSepStyle = params[1].ToInt();
1270
1271 if (iSepStyle < 0 || iSepStyle > 3)
1272 iSepStyle = 0;
1273 if(!pEvent->m_pValue)
1274 return FALSE;
1275 CFX_WideString & val = pEvent->Value();
1276 CFX_WideString & w_strChange = pEvent->Change();
1277 CFX_WideString w_strValue = val;
1278
1279 if (pEvent->WillCommit())
1280 {
1281 CFX_WideString wstrChange = w_strChange;
1282 CFX_WideString wstrValue = StrLTrim(w_strValue.c_str());
1283 if (wstrValue.IsEmpty())
1284 return TRUE;
1285
1286 CFX_WideString swTemp = wstrValue;
1287 swTemp.Replace(L",", L".");
1288 if (!IsNumber(swTemp.c_str()))
1289 {
1290 pEvent->Rc() = FALSE;
1291 sError = JSGetStringFromID(pContext, IDS_STRING_JSAFNUMBER_KEYSTROKE);
1292 Alert(pContext, sError.c_str());
1293 return TRUE;
1294 }
1295 return TRUE; // it happens after the last keystroke and before validating,
1296 }
1297
1298 std::wstring w_strValue2 = w_strValue.c_str();
1299 std::wstring w_strChange2 = w_strChange.c_str();
1300 std::wstring w_strSelected;
1301 if(-1 != pEvent->SelStart())
1302 w_strSelected = w_strValue2.substr(pEvent->SelStart(),(pEvent->SelEnd() - pEvent->SelStart()));
1303 FX_BOOL bHasSign = (w_strValue2.find('-') != -1) && (w_strSelected.find('-') == -1);
1304 if (bHasSign)
1305 {
1306 //can't insert "change" in front to sign postion.
1307 if (pEvent->SelStart() == 0)
1308 {
1309 FX_BOOL &bRc = pEvent->Rc();
1310 bRc = FALSE;
1311 return TRUE;
1312 }
1313 }
1314
1315 char cSep = L'.';
1316
1317 switch (iSepStyle)
1318 {
1319 case 0:
1320 case 1:
1321 cSep = L'.';
1322 break;
1323 case 2:
1324 case 3:
1325 cSep = L',';
1326 break;
1327 }
1328
1329 FX_BOOL bHasSep = (w_strValue2.find(cSep) != -1);
1330 for (std::wstring::iterator it = w_strChange2.begin(); it != w_strChange2.end(); it++)
1331 {
1332 if (*it == cSep)
1333 {
1334 if (bHasSep)
1335 {
1336 FX_BOOL &bRc = pEvent->Rc();
1337 bRc = FALSE;
1338 return TRUE;
1339 }
1340 else
1341 {
1342 bHasSep = TRUE;
1343 continue;
1344 }
1345 }
1346 if (*it == L'-')
1347 {
1348 if (bHasSign)
1349 {
1350 FX_BOOL &bRc = pEvent->Rc();
1351 bRc = FALSE;
1352 return TRUE;
1353 }
1354 else if (it != w_strChange2.begin()) //sign's position is not correct
1355 {
1356 FX_BOOL &bRc = pEvent->Rc();
1357 bRc = FALSE;
1358 return TRUE;
1359 }
1360 else if (pEvent->SelStart() != 0)
1361 {
1362 FX_BOOL &bRc = pEvent->Rc();
1363 bRc = FALSE;
1364 return TRUE;
1365 }
1366 bHasSign = TRUE;
1367 continue;
1368 }
1369
1370 if (!IsDigit(*it))
1371 {
1372 FX_BOOL &bRc = pEvent->Rc();
1373 bRc = FALSE;
1374 return TRUE;
1375 }
1376 }
1377
1378
1379 std::wstring w_prefix = w_strValue2.substr(0,pEvent->SelStart());
1380 std::wstring w_postfix;
1381 if (pEvent->SelEnd()<(int)w_strValue2.length())
1382 w_postfix = w_strValue2.substr(pEvent->SelEnd());
1383 w_strValue2 = w_prefix + w_strChange2 + w_postfix;
1384 w_strValue = w_strValue2.c_str();
1385 val = w_strValue;
1386 return TRUE;
1387
1388 }
1389
1390 //function AFPercent_Format(nDec, sepStyle)
AFPercent_Format(IFXJS_Context * cc,const CJS_Parameters & params,CJS_Value & vRet,CFX_WideString & sError)1391 FX_BOOL CJS_PublicMethods::AFPercent_Format(IFXJS_Context* cc, const CJS_Parameters& params, CJS_Value& vRet, CFX_WideString& sError)
1392 {
1393 #if _FX_OS_ != _FX_ANDROID_
1394 CJS_Context* pContext = (CJS_Context *)cc;
1395 ASSERT(pContext != NULL);
1396 CJS_EventHandler* pEvent = pContext->GetEventHandler();
1397 ASSERT(pEvent != NULL);
1398
1399 if (params.size() != 2)
1400 {
1401 sError = JSGetStringFromID(pContext, IDS_STRING_JSPARAMERROR);
1402 return FALSE;
1403 }
1404 if(!pEvent->m_pValue)
1405 return FALSE;
1406
1407 CFX_WideString& Value = pEvent->Value();
1408 CFX_ByteString strValue = StrTrim(CFX_ByteString::FromUnicode(Value));
1409 if (strValue.IsEmpty())
1410 return TRUE;
1411
1412 int iDec = params[0].ToInt();
1413 if (iDec < 0)
1414 iDec = -iDec;
1415
1416 int iSepStyle = params[1].ToInt();
1417 if (iSepStyle < 0 || iSepStyle > 3)
1418 iSepStyle = 0;
1419
1420 //////////////////////////////////////////////////////
1421 //for processing decimal places
1422 double dValue = atof(strValue);
1423 dValue *= 100;
1424 if (iDec > 0)
1425 dValue += DOUBLE_CORRECT;//��
1426
1427 int iDec2;
1428 FX_BOOL bNegative = FALSE;
1429 strValue = fcvt(dValue,iDec,&iDec2,&bNegative);
1430 if (strValue.IsEmpty())
1431 {
1432 dValue = 0;
1433 strValue = fcvt(dValue,iDec,&iDec2,&bNegative);
1434 }
1435
1436 if (iDec2 < 0)
1437 {
1438 for (int iNum = 0; iNum < abs(iDec2); iNum++)
1439 {
1440 strValue = "0" + strValue;
1441 }
1442 iDec2 = 0;
1443
1444 }
1445 int iMax = strValue.GetLength();
1446 if (iDec2 > iMax)
1447 {
1448 for (int iNum = 0; iNum <= iDec2 - iMax; iNum++)
1449 {
1450 strValue += "0";
1451 }
1452 iMax = iDec2+1;
1453 }
1454 ///////////////////////////////////////////////////////
1455 //for processing seperator style
1456 if (iDec2 < iMax)
1457 {
1458 if (iSepStyle == 0 || iSepStyle == 1)
1459 {
1460 strValue.Insert(iDec2, '.');
1461 iMax++;
1462 }
1463 else if (iSepStyle == 2 || iSepStyle == 3)
1464 {
1465 strValue.Insert(iDec2, ',');
1466 iMax++;
1467 }
1468
1469 if (iDec2 == 0)
1470 strValue.Insert(iDec2, '0');
1471 }
1472 if (iSepStyle == 0 || iSepStyle == 2)
1473 {
1474 char cSeperator;
1475 if (iSepStyle == 0)
1476 cSeperator = ',';
1477 else
1478 cSeperator = '.';
1479
1480 int iDecPositive;
1481 iDecPositive = iDec2;
1482
1483 for (iDecPositive = iDec2 -3; iDecPositive > 0; iDecPositive -= 3)
1484 {
1485 strValue.Insert(iDecPositive,cSeperator);
1486 iMax++;
1487 }
1488 }
1489 ////////////////////////////////////////////////////////////////////
1490 //negative mark
1491 if(bNegative)
1492 strValue = "-" + strValue;
1493 strValue += "%";
1494 Value = CFX_WideString::FromLocal(strValue);
1495 #endif
1496 return TRUE;
1497 }
1498 //AFPercent_Keystroke(nDec, sepStyle)
AFPercent_Keystroke(IFXJS_Context * cc,const CJS_Parameters & params,CJS_Value & vRet,CFX_WideString & sError)1499 FX_BOOL CJS_PublicMethods::AFPercent_Keystroke(IFXJS_Context* cc, const CJS_Parameters& params, CJS_Value& vRet, CFX_WideString& sError)
1500 {
1501 return AFNumber_Keystroke(cc,params,vRet,sError);
1502 }
1503
1504 //function AFDate_FormatEx(cFormat)
AFDate_FormatEx(IFXJS_Context * cc,const CJS_Parameters & params,CJS_Value & vRet,CFX_WideString & sError)1505 FX_BOOL CJS_PublicMethods::AFDate_FormatEx(IFXJS_Context* cc, const CJS_Parameters& params, CJS_Value& vRet, CFX_WideString& sError)
1506 {
1507 CJS_Context* pContext = (CJS_Context *)cc;
1508 ASSERT(pContext != NULL);
1509 CJS_EventHandler* pEvent = pContext->GetEventHandler();
1510 ASSERT(pEvent != NULL);
1511
1512 if (params.size() != 1)
1513 {
1514 sError = JSGetStringFromID(pContext, IDS_STRING_JSPARAMERROR);
1515 return FALSE;
1516 }
1517 if(!pEvent->m_pValue)
1518 return FALSE;
1519
1520 CFX_WideString& val = pEvent->Value();
1521 CFX_WideString strValue = val;
1522 if (strValue.IsEmpty())
1523 return TRUE;
1524
1525 CFX_WideString sFormat = params[0].ToCFXWideString();
1526 FX_BOOL bWrongFormat = FALSE;
1527 double dDate = 0.0f;
1528
1529 if(strValue.Find(L"GMT") != -1)
1530 {
1531 //for GMT format time
1532 //such as "Tue Aug 11 14:24:16 GMT+08002009"
1533 dDate = MakeInterDate(strValue);
1534 }
1535 else
1536 {
1537 dDate = MakeRegularDate(strValue,sFormat,bWrongFormat);
1538 }
1539
1540 if (JS_PortIsNan(dDate))
1541 {
1542 CFX_WideString swMsg;
1543 swMsg.Format(JSGetStringFromID(pContext, IDS_STRING_JSPARSEDATE).c_str(), sFormat.c_str());
1544 Alert(pContext, swMsg.c_str());
1545 return FALSE;
1546 }
1547
1548 val = MakeFormatDate(dDate,sFormat);
1549 return TRUE;
1550 }
1551
MakeInterDate(CFX_WideString strValue)1552 double CJS_PublicMethods::MakeInterDate(CFX_WideString strValue)
1553 {
1554 int nHour;
1555 int nMin;
1556 int nSec;
1557 int nYear;
1558 int nMonth;
1559 int nDay;
1560
1561 CFX_WideStringArray wsArray;
1562 CFX_WideString sMonth = L"";
1563 CFX_WideString sTemp = L"";
1564 int nSize = strValue.GetLength();
1565
1566 for(int i = 0; i < nSize; i++)
1567 {
1568 FX_WCHAR c = strValue.GetAt(i);
1569 if(c == L' ' || c == L':')
1570 {
1571 wsArray.Add(sTemp);
1572 sTemp = L"";
1573 continue;
1574 }
1575
1576 sTemp += c;
1577 }
1578
1579 wsArray.Add(sTemp);
1580 if(wsArray.GetSize() != 8)return 0;
1581
1582 sTemp = wsArray[1];
1583 if(sTemp.Compare(L"Jan") == 0) nMonth = 1;
1584 if(sTemp.Compare(L"Feb") == 0) nMonth = 2;
1585 if(sTemp.Compare(L"Mar") == 0) nMonth = 3;
1586 if(sTemp.Compare(L"Apr") == 0) nMonth = 4;
1587 if(sTemp.Compare(L"May") == 0) nMonth = 5;
1588 if(sTemp.Compare(L"Jun") == 0) nMonth = 6;
1589 if(sTemp.Compare(L"Jul") == 0) nMonth = 7;
1590 if(sTemp.Compare(L"Aug") == 0) nMonth = 8;
1591 if(sTemp.Compare(L"Sep") == 0) nMonth = 9;
1592 if(sTemp.Compare(L"Oct") == 0) nMonth = 10;
1593 if(sTemp.Compare(L"Nov") == 0) nMonth = 11;
1594 if(sTemp.Compare(L"Dec") == 0) nMonth = 12;
1595
1596 nDay = (int)ParseStringToNumber(wsArray[2].c_str());
1597 nHour = (int)ParseStringToNumber(wsArray[3].c_str());
1598 nMin = (int)ParseStringToNumber(wsArray[4].c_str());
1599 nSec = (int)ParseStringToNumber(wsArray[5].c_str());
1600 nYear = (int)ParseStringToNumber(wsArray[7].c_str());
1601
1602 double dRet = JS_MakeDate(JS_MakeDay(nYear,nMonth - 1,nDay),JS_MakeTime(nHour, nMin, nSec, 0));
1603
1604 if (JS_PortIsNan(dRet))
1605 {
1606 dRet = JS_DateParse(strValue.c_str());
1607 }
1608
1609 return dRet;
1610 }
1611
1612 //AFDate_KeystrokeEx(cFormat)
AFDate_KeystrokeEx(IFXJS_Context * cc,const CJS_Parameters & params,CJS_Value & vRet,CFX_WideString & sError)1613 FX_BOOL CJS_PublicMethods::AFDate_KeystrokeEx(IFXJS_Context* cc, const CJS_Parameters& params, CJS_Value& vRet, CFX_WideString& sError)
1614 {
1615 CJS_Context* pContext = (CJS_Context *)cc;
1616 ASSERT(pContext != NULL);
1617 CJS_EventHandler* pEvent = pContext->GetEventHandler();
1618 ASSERT(pEvent != NULL);
1619
1620 if (params.size() != 1)
1621 {
1622 sError = L"AFDate_KeystrokeEx's parameters' size r not correct";
1623 return FALSE;
1624 }
1625
1626 if (pEvent->WillCommit())
1627 {
1628 if(!pEvent->m_pValue)
1629 return FALSE;
1630 CFX_WideString strValue = pEvent->Value();
1631 if (strValue.IsEmpty())
1632 return TRUE;
1633
1634 CFX_WideString sFormat = params[0].ToCFXWideString();
1635 FX_BOOL bWrongFormat = FALSE;
1636 double dRet = MakeRegularDate(strValue,sFormat,bWrongFormat);
1637 if (bWrongFormat || JS_PortIsNan(dRet))
1638 {
1639 CFX_WideString swMsg;
1640 swMsg.Format(JSGetStringFromID(pContext, IDS_STRING_JSPARSEDATE).c_str(), sFormat.c_str());
1641 Alert(pContext, swMsg.c_str());
1642 pEvent->Rc() = FALSE;
1643 return TRUE;
1644 }
1645 }
1646 return TRUE;
1647 }
1648
AFDate_Format(IFXJS_Context * cc,const CJS_Parameters & params,CJS_Value & vRet,CFX_WideString & sError)1649 FX_BOOL CJS_PublicMethods::AFDate_Format(IFXJS_Context* cc, const CJS_Parameters& params, CJS_Value& vRet, CFX_WideString& sError)
1650 {
1651 v8::Isolate* isolate = ::GetIsolate(cc);
1652
1653 if (params.size() != 1)
1654 {
1655 CJS_Context* pContext = (CJS_Context*)cc;
1656 ASSERT(pContext != NULL);
1657
1658 sError = JSGetStringFromID(pContext, IDS_STRING_JSPARAMERROR);
1659 return FALSE;
1660 }
1661
1662 int iIndex = params[0].ToInt();
1663 FX_LPCWSTR cFormats[] = {L"m/d", L"m/d/yy", L"mm/dd/yy", L"mm/yy", L"d-mmm", L"d-mmm-yy", L"dd-mmm-yy",
1664 L"yy-mm-dd", L"mmm-yy", L"mmmm-yy", L"mmm d, yyyy", L"mmmm d, yyyy",
1665 L"m/d/yy h:MM tt", L"m/d/yy HH:MM" };
1666
1667 ASSERT(iIndex < FX_ArraySize(cFormats));
1668
1669 if (iIndex < 0)
1670 iIndex = 0;
1671 if (iIndex >= FX_ArraySize(cFormats))
1672 iIndex = 0;
1673 CJS_Parameters newParams;
1674 CJS_Value val(isolate,cFormats[iIndex]);
1675 newParams.push_back(val);
1676 return AFDate_FormatEx(cc,newParams,vRet,sError);
1677 }
1678
1679 //AFDate_KeystrokeEx(cFormat)
AFDate_Keystroke(IFXJS_Context * cc,const CJS_Parameters & params,CJS_Value & vRet,CFX_WideString & sError)1680 FX_BOOL CJS_PublicMethods::AFDate_Keystroke(IFXJS_Context* cc, const CJS_Parameters& params, CJS_Value& vRet, CFX_WideString& sError)
1681 {
1682 v8::Isolate* isolate = ::GetIsolate(cc);
1683
1684 if (params.size() != 1)
1685 {
1686 CJS_Context* pContext = (CJS_Context*)cc;
1687 ASSERT(pContext != NULL);
1688
1689 sError = JSGetStringFromID(pContext, IDS_STRING_JSPARAMERROR);
1690 return FALSE;
1691 }
1692
1693 int iIndex = params[0].ToInt();
1694 FX_LPCWSTR cFormats[] = {L"m/d", L"m/d/yy", L"mm/dd/yy", L"mm/yy", L"d-mmm", L"d-mmm-yy", L"dd-mmm-yy",
1695 L"yy-mm-dd", L"mmm-yy", L"mmmm-yy", L"mmm d, yyyy", L"mmmm d, yyyy",
1696 L"m/d/yy h:MM tt", L"m/d/yy HH:MM" };
1697
1698 ASSERT(iIndex<FX_ArraySize(cFormats));
1699
1700 if (iIndex < 0)
1701 iIndex = 0;
1702 if (iIndex >= FX_ArraySize(cFormats))
1703 iIndex = 0;
1704 CJS_Parameters newParams;
1705 CJS_Value val(isolate,cFormats[iIndex]);
1706 newParams.push_back(val);
1707 return AFDate_KeystrokeEx(cc,newParams,vRet,sError);
1708 }
1709
1710 //function AFTime_Format(ptf)
AFTime_Format(IFXJS_Context * cc,const CJS_Parameters & params,CJS_Value & vRet,CFX_WideString & sError)1711 FX_BOOL CJS_PublicMethods::AFTime_Format(IFXJS_Context* cc, const CJS_Parameters& params, CJS_Value& vRet, CFX_WideString& sError)
1712 {
1713 v8::Isolate* isolate = ::GetIsolate(cc);
1714
1715 if (params.size() != 1)
1716 {
1717 CJS_Context* pContext = (CJS_Context*)cc;
1718 ASSERT(pContext != NULL);
1719 sError = JSGetStringFromID(pContext, IDS_STRING_JSPARAMERROR);
1720 return FALSE;
1721 }
1722
1723 int iIndex = params[0].ToInt();
1724 FX_LPCWSTR cFormats[] = {L"HH:MM", L"h:MM tt", L"HH:MM:ss", L"h:MM:ss tt"};
1725
1726 ASSERT(iIndex<FX_ArraySize(cFormats));
1727
1728 if (iIndex < 0)
1729 iIndex = 0;
1730 if (iIndex >= FX_ArraySize(cFormats))
1731 iIndex = 0;
1732 CJS_Parameters newParams;
1733 CJS_Value val(isolate,cFormats[iIndex]);
1734 newParams.push_back(val);
1735 return AFDate_FormatEx(cc,newParams,vRet,sError);
1736 }
1737
AFTime_Keystroke(IFXJS_Context * cc,const CJS_Parameters & params,CJS_Value & vRet,CFX_WideString & sError)1738 FX_BOOL CJS_PublicMethods::AFTime_Keystroke(IFXJS_Context* cc, const CJS_Parameters& params, CJS_Value& vRet, CFX_WideString& sError)
1739 {
1740 v8::Isolate* isolate = ::GetIsolate(cc);
1741 if (params.size() != 1)
1742 {
1743 CJS_Context* pContext = (CJS_Context*)cc;
1744 ASSERT(pContext != NULL);
1745 sError = JSGetStringFromID(pContext, IDS_STRING_JSPARAMERROR);
1746 return FALSE;
1747 }
1748
1749 int iIndex = params[0].ToInt();
1750 FX_LPCWSTR cFormats[] = {L"HH:MM", L"h:MM tt", L"HH:MM:ss", L"h:MM:ss tt"};
1751
1752 ASSERT(iIndex<FX_ArraySize(cFormats));
1753
1754 if (iIndex < 0)
1755 iIndex = 0;
1756 if (iIndex >= FX_ArraySize(cFormats))
1757 iIndex = 0;
1758 CJS_Parameters newParams;
1759 CJS_Value val(isolate,cFormats[iIndex]);
1760 newParams.push_back(val);
1761 return AFDate_KeystrokeEx(cc,newParams,vRet,sError);
1762 }
1763
AFTime_FormatEx(IFXJS_Context * cc,const CJS_Parameters & params,CJS_Value & vRet,CFX_WideString & sError)1764 FX_BOOL CJS_PublicMethods::AFTime_FormatEx(IFXJS_Context* cc, const CJS_Parameters& params, CJS_Value& vRet, CFX_WideString& sError)
1765 {
1766 return AFDate_FormatEx(cc,params,vRet,sError);
1767 }
1768
AFTime_KeystrokeEx(IFXJS_Context * cc,const CJS_Parameters & params,CJS_Value & vRet,CFX_WideString & sError)1769 FX_BOOL CJS_PublicMethods::AFTime_KeystrokeEx(IFXJS_Context* cc, const CJS_Parameters& params, CJS_Value& vRet, CFX_WideString& sError)
1770 {
1771 return AFDate_KeystrokeEx(cc,params,vRet,sError);
1772 }
1773
1774 //function AFSpecial_Format(psf)
AFSpecial_Format(IFXJS_Context * cc,const CJS_Parameters & params,CJS_Value & vRet,CFX_WideString & sError)1775 FX_BOOL CJS_PublicMethods::AFSpecial_Format(IFXJS_Context* cc, const CJS_Parameters& params, CJS_Value& vRet, CFX_WideString& sError)
1776 {
1777 CJS_Context* pContext = (CJS_Context *)cc;
1778 ASSERT(pContext != NULL);
1779
1780 if (params.size() != 1)
1781 {
1782 sError = JSGetStringFromID(pContext, IDS_STRING_JSPARAMERROR);
1783 return FALSE;
1784 }
1785
1786 std::string cFormat;
1787 int iIndex = params[0].ToInt();
1788
1789 CJS_EventHandler* pEvent = pContext->GetEventHandler();
1790 ASSERT(pEvent != NULL);
1791
1792 if(!pEvent->m_pValue)
1793 return FALSE;
1794 CFX_WideString& Value = pEvent->Value();
1795 std::string strSrc = CFX_ByteString::FromUnicode(Value).c_str();
1796
1797 switch (iIndex)
1798 {
1799 case 0:
1800 cFormat = "99999";
1801 break;
1802 case 1:
1803 cFormat = "99999-9999";
1804 break;
1805 case 2:
1806 {
1807 std::string NumberStr;
1808 util::printx("9999999999", strSrc,NumberStr);
1809 if (NumberStr.length() >= 10 )
1810 cFormat = "(999) 999-9999";
1811 else
1812 cFormat = "999-9999";
1813 break;
1814 }
1815 case 3:
1816 cFormat = "999-99-9999";
1817 break;
1818 }
1819
1820 std::string strDes;
1821 util::printx(cFormat,strSrc,strDes);
1822 Value = CFX_WideString::FromLocal(strDes.c_str());
1823 return TRUE;
1824 }
1825
1826
1827 //function AFSpecial_KeystrokeEx(mask)
AFSpecial_KeystrokeEx(IFXJS_Context * cc,const CJS_Parameters & params,CJS_Value & vRet,CFX_WideString & sError)1828 FX_BOOL CJS_PublicMethods::AFSpecial_KeystrokeEx(IFXJS_Context* cc, const CJS_Parameters& params, CJS_Value& vRet, CFX_WideString& sError)
1829 {
1830 CJS_Context* pContext = (CJS_Context *)cc;
1831 ASSERT(pContext != NULL);
1832 CJS_EventHandler* pEvent = pContext->GetEventHandler();
1833
1834 ASSERT(pEvent != NULL);
1835
1836 if (params.size() < 1)
1837 {
1838 sError = JSGetStringFromID(pContext, IDS_STRING_JSPARAMERROR);
1839 return FALSE;
1840 }
1841
1842 if(!pEvent->m_pValue)
1843 return FALSE;
1844 CFX_WideString& valEvent = pEvent->Value();
1845
1846 CFX_WideString wstrMask = params[0].ToCFXWideString();
1847 if (wstrMask.IsEmpty())
1848 return TRUE;
1849
1850 std::wstring wstrValue = valEvent.c_str();
1851
1852 if (pEvent->WillCommit())
1853 {
1854 if (wstrValue.empty())
1855 return TRUE;
1856 int iIndexMask = 0;
1857 for (std::wstring::iterator it = wstrValue.begin(); it != wstrValue.end(); it++)
1858 {
1859 wchar_t w_Value = *it;
1860 if (!maskSatisfied(w_Value,wstrMask[iIndexMask]))
1861 break;
1862 iIndexMask++;
1863 }
1864
1865 if (iIndexMask != wstrMask.GetLength() || (iIndexMask != wstrValue.size() && wstrMask.GetLength() != 0))
1866 {
1867 Alert(pContext, JSGetStringFromID(pContext, IDS_STRING_JSAFNUMBER_KEYSTROKE).c_str());
1868 pEvent->Rc() = FALSE;
1869 }
1870 return TRUE;
1871 }
1872
1873 CFX_WideString &wideChange = pEvent->Change();
1874 std::wstring wChange = wideChange.c_str();
1875 if (wChange.empty())
1876 return TRUE;
1877
1878 int iIndexMask = pEvent->SelStart();
1879
1880 if (wstrValue.length() - (pEvent->SelEnd()-pEvent->SelStart()) + wChange.length() > (FX_DWORD)wstrMask.GetLength())
1881 {
1882 Alert(pContext, JSGetStringFromID(pContext, IDS_STRING_JSPARAM_TOOLONG).c_str());
1883 pEvent->Rc() = FALSE;
1884 return TRUE;
1885 }
1886
1887 if (iIndexMask >= wstrMask.GetLength() && (!wChange.empty()))
1888 {
1889 Alert(pContext, JSGetStringFromID(pContext, IDS_STRING_JSPARAM_TOOLONG).c_str());
1890 pEvent->Rc() = FALSE;
1891 return TRUE;
1892 }
1893
1894 for (std::wstring::iterator it = wChange.begin(); it != wChange.end(); it++)
1895 {
1896 if (iIndexMask >= wstrMask.GetLength())
1897 {
1898 Alert(pContext, JSGetStringFromID(pContext, IDS_STRING_JSPARAM_TOOLONG).c_str());
1899 pEvent->Rc() = FALSE;
1900 return TRUE;
1901 }
1902 wchar_t w_Mask = wstrMask[iIndexMask];
1903 if (!isReservedMaskChar(w_Mask))
1904 {
1905 *it = w_Mask;
1906 }
1907 wchar_t w_Change = *it;
1908 if (!maskSatisfied(w_Change,w_Mask))
1909 {
1910 pEvent->Rc() = FALSE;
1911 return TRUE;
1912 }
1913 iIndexMask++;
1914 }
1915
1916 wideChange = wChange.c_str();
1917 return TRUE;
1918 }
1919
1920
1921 //function AFSpecial_Keystroke(psf)
AFSpecial_Keystroke(IFXJS_Context * cc,const CJS_Parameters & params,CJS_Value & vRet,CFX_WideString & sError)1922 FX_BOOL CJS_PublicMethods::AFSpecial_Keystroke(IFXJS_Context* cc, const CJS_Parameters& params, CJS_Value& vRet, CFX_WideString& sError)
1923 {
1924 v8::Isolate* isolate = ::GetIsolate(cc);
1925
1926 CJS_Context* pContext = (CJS_Context *)cc;
1927 ASSERT(pContext != NULL);
1928 CJS_EventHandler* pEvent = pContext->GetEventHandler();
1929 ASSERT(pEvent != NULL);
1930
1931 if (params.size() != 1)
1932 {
1933 sError = JSGetStringFromID(pContext, IDS_STRING_JSPARAMERROR);
1934 return FALSE;
1935 }
1936
1937 std::string cFormat;
1938 int iIndex = params[0].ToInt();
1939
1940 if(!pEvent->m_pValue)
1941 return FALSE;
1942 //CJS_Value val = pEvent->Value();
1943 CFX_WideString& val = pEvent->Value();
1944 std::string strSrc = CFX_ByteString::FromUnicode(val).c_str();
1945 std::wstring wstrChange = pEvent->Change().c_str();
1946
1947 switch (iIndex)
1948 {
1949 case 0:
1950 cFormat = "99999";
1951 break;
1952 case 1:
1953 //cFormat = "99999-9999";
1954 cFormat = "999999999";
1955 break;
1956 case 2:
1957 {
1958 std::string NumberStr;
1959 util::printx("9999999999", strSrc,NumberStr);
1960 if (strSrc.length() + wstrChange.length() > 7 )
1961 //cFormat = "(999) 999-9999";
1962 cFormat = "9999999999";
1963 else
1964 //cFormat = "999-9999";
1965 cFormat = "9999999";
1966 break;
1967 }
1968 case 3:
1969 //cFormat = "999-99-9999";
1970 cFormat = "999999999";
1971 break;
1972 }
1973
1974 CJS_Parameters params2;
1975 CJS_Value vMask(isolate, cFormat.c_str());
1976 params2.push_back(vMask);
1977
1978 return AFSpecial_KeystrokeEx(cc,params2,vRet,sError);
1979 }
1980
AFMergeChange(IFXJS_Context * cc,const CJS_Parameters & params,CJS_Value & vRet,CFX_WideString & sError)1981 FX_BOOL CJS_PublicMethods::AFMergeChange(IFXJS_Context* cc, const CJS_Parameters& params, CJS_Value& vRet, CFX_WideString& sError)
1982 {
1983 CJS_Context* pContext = (CJS_Context *)cc;
1984 ASSERT(pContext != NULL);
1985 CJS_EventHandler* pEventHandler = pContext->GetEventHandler();
1986 ASSERT(pEventHandler != NULL);
1987
1988 if (params.size() != 1)
1989 {
1990 sError = JSGetStringFromID(pContext, IDS_STRING_JSPARAMERROR);
1991 return FALSE;
1992 }
1993
1994 CFX_WideString swValue;
1995 if (pEventHandler->m_pValue != NULL)
1996 swValue = pEventHandler->Value();
1997
1998 if (pEventHandler->WillCommit())
1999 {
2000 vRet = swValue.c_str();
2001 return TRUE;
2002 }
2003
2004 CFX_WideString prefix,postfix;
2005
2006 if (pEventHandler->SelStart() >= 0)
2007 prefix = swValue.Mid(0,pEventHandler->SelStart());
2008 else
2009 prefix = L"";
2010
2011
2012 if (pEventHandler->SelEnd() >= 0 && pEventHandler->SelEnd() <= swValue.GetLength())
2013 postfix = swValue.Mid(pEventHandler->SelEnd(), swValue.GetLength() - pEventHandler->SelEnd());
2014 else postfix = L"";
2015
2016 vRet = (prefix + pEventHandler->Change() + postfix).c_str();
2017
2018 return TRUE;
2019 }
2020
AFParseDateEx(IFXJS_Context * cc,const CJS_Parameters & params,CJS_Value & vRet,CFX_WideString & sError)2021 FX_BOOL CJS_PublicMethods::AFParseDateEx(IFXJS_Context* cc, const CJS_Parameters& params, CJS_Value& vRet, CFX_WideString& sError)
2022 {
2023 CJS_Context* pContext = (CJS_Context *)cc;
2024 ASSERT(pContext != NULL);
2025
2026 if (params.size() != 2)
2027 {
2028 sError = JSGetStringFromID(pContext, IDS_STRING_JSPARAMERROR);
2029 return FALSE;
2030 }
2031
2032 CFX_WideString sValue = params[0].ToCFXWideString();
2033 CFX_WideString sFormat = params[1].ToCFXWideString();
2034
2035 FX_BOOL bWrongFormat = FALSE;
2036 double dDate = MakeRegularDate(sValue,sFormat,bWrongFormat);
2037
2038 if (JS_PortIsNan(dDate))
2039 {
2040 CFX_WideString swMsg;
2041 swMsg.Format(JSGetStringFromID(pContext, IDS_STRING_JSPARSEDATE).c_str(), sFormat.c_str());
2042 Alert((CJS_Context *)cc, swMsg.c_str());
2043 return FALSE;
2044 }
2045
2046 vRet = dDate;
2047 return TRUE;
2048 }
2049
AFSimple(IFXJS_Context * cc,const CJS_Parameters & params,CJS_Value & vRet,CFX_WideString & sError)2050 FX_BOOL CJS_PublicMethods::AFSimple(IFXJS_Context* cc, const CJS_Parameters& params, CJS_Value& vRet, CFX_WideString& sError)
2051 {
2052 if (params.size() != 3)
2053 {
2054 CJS_Context* pContext = (CJS_Context *)cc;
2055 ASSERT(pContext != NULL);
2056
2057 sError = JSGetStringFromID(pContext, IDS_STRING_JSPARAMERROR);
2058 return FALSE;
2059 }
2060
2061 vRet = (double)AF_Simple(params[0].ToCFXWideString().c_str(), params[1].ToDouble(), params[2].ToDouble());
2062 return TRUE;
2063 }
2064
AFMakeNumber(IFXJS_Context * cc,const CJS_Parameters & params,CJS_Value & vRet,CFX_WideString & sError)2065 FX_BOOL CJS_PublicMethods::AFMakeNumber(IFXJS_Context* cc, const CJS_Parameters& params, CJS_Value& vRet, CFX_WideString& sError)
2066 {
2067 if (params.size() != 1)
2068 {
2069 CJS_Context* pContext = (CJS_Context *)cc;
2070 ASSERT(pContext != NULL);
2071
2072 sError = JSGetStringFromID(pContext, IDS_STRING_JSPARAMERROR);
2073 return FALSE;
2074 }
2075 vRet = ParseStringToNumber(params[0].ToCFXWideString().c_str());
2076 return TRUE;
2077 }
2078
AFSimple_Calculate(IFXJS_Context * cc,const CJS_Parameters & params,CJS_Value & vRet,CFX_WideString & sError)2079 FX_BOOL CJS_PublicMethods::AFSimple_Calculate(IFXJS_Context* cc, const CJS_Parameters& params, CJS_Value& vRet, CFX_WideString& sError)
2080 {
2081 v8::Isolate* isolate = ::GetIsolate(cc);
2082
2083 CJS_Context* pContext = (CJS_Context *)cc;
2084 ASSERT(pContext != NULL);
2085
2086 if (params.size() != 2)
2087 {
2088 sError = JSGetStringFromID(pContext, IDS_STRING_JSPARAMERROR);
2089 return FALSE;
2090 }
2091
2092 CJS_Value params1 = params[1];
2093
2094 if (!params1.IsArrayObject() && params1.GetType() != VT_string)
2095 {
2096 sError = JSGetStringFromID(pContext, IDS_STRING_JSPARAMERROR);
2097 return FALSE;
2098 }
2099
2100 CPDFSDK_Document* pReaderDoc = pContext->GetReaderDocument();
2101 ASSERT(pReaderDoc != NULL);
2102
2103 CPDFSDK_InterForm* pReaderInterForm = pReaderDoc->GetInterForm();
2104 ASSERT(pReaderInterForm != NULL);
2105
2106 CPDF_InterForm* pInterForm = pReaderInterForm->GetInterForm();
2107 ASSERT(pInterForm != NULL);
2108
2109 double dValue;
2110 CFX_WideString sFunction = params[0].ToCFXWideString();
2111 if (wcscmp(sFunction.c_str(), L"PRD") == 0)
2112 dValue = 1.0;
2113 else
2114 dValue = 0.0;
2115
2116 CJS_Array FieldNameArray = AF_MakeArrayFromList(isolate,params1);
2117
2118 int nFieldsCount = 0;
2119
2120 for (int i=0,isz=FieldNameArray.GetLength(); i<isz; i++)
2121 {
2122 CJS_Value jsValue(isolate);
2123 FieldNameArray.GetElement(i,jsValue);
2124 CFX_WideString wsFieldName = jsValue.ToCFXWideString();
2125
2126 for (int j=0,jsz=pInterForm->CountFields(wsFieldName); j<jsz; j++)
2127 {
2128 if (CPDF_FormField* pFormField = pInterForm->GetField(j, wsFieldName))
2129 {
2130 double dTemp = 0.0;
2131
2132 switch (pFormField->GetFieldType())
2133 {
2134 case FIELDTYPE_TEXTFIELD:
2135 case FIELDTYPE_COMBOBOX:
2136 {
2137 dTemp = ParseStringToNumber(pFormField->GetValue().c_str());
2138 break;
2139 }
2140 case FIELDTYPE_PUSHBUTTON:
2141 {
2142 dTemp = 0.0;
2143 break;
2144 }
2145 case FIELDTYPE_CHECKBOX:
2146 case FIELDTYPE_RADIOBUTTON:
2147 {
2148 dTemp = 0.0;
2149 for (int c=0,csz=pFormField->CountControls(); c<csz; c++)
2150 {
2151 if (CPDF_FormControl* pFormCtrl = pFormField->GetControl(c))
2152 {
2153 if (pFormCtrl->IsChecked())
2154 {
2155 dTemp += ParseStringToNumber(pFormCtrl->GetExportValue().c_str());
2156 break;
2157 }
2158 else
2159 continue;
2160 }
2161 }
2162 break;
2163 }
2164 case FIELDTYPE_LISTBOX:
2165 {
2166 dTemp = 0.0;
2167 if (pFormField->CountSelectedItems() > 1)
2168 break;
2169 else
2170 {
2171 dTemp = ParseStringToNumber(pFormField->GetValue().c_str());
2172 break;
2173 }
2174 }
2175 default:
2176 break;
2177 }
2178
2179 if (i == 0 && j == 0 && (wcscmp(sFunction.c_str(), L"MIN") == 0 || wcscmp(sFunction.c_str(), L"MAX") == 0))
2180 dValue = dTemp;
2181
2182 dValue = AF_Simple(sFunction.c_str(), dValue, dTemp);
2183
2184 nFieldsCount++;
2185 }
2186 }
2187 }
2188
2189 if (wcscmp(sFunction.c_str(), L"AVG") == 0 && nFieldsCount > 0)
2190 dValue /= nFieldsCount;
2191
2192 dValue = (double)floor(dValue * FXSYS_pow((double)10,(double)6) + 0.49) / FXSYS_pow((double)10,(double)6);
2193 CJS_Value jsValue(isolate,dValue);
2194 if((CJS_EventHandler*)pContext->GetEventHandler()->m_pValue)
2195 ((CJS_EventHandler*)pContext->GetEventHandler())->Value() = jsValue.ToCFXWideString();
2196
2197 return TRUE;
2198 }
2199
2200 /* This function validates the current event to ensure that its value is
2201 ** within the specified range. */
2202
AFRange_Validate(IFXJS_Context * cc,const CJS_Parameters & params,CJS_Value & vRet,CFX_WideString & sError)2203 FX_BOOL CJS_PublicMethods::AFRange_Validate(IFXJS_Context* cc, const CJS_Parameters& params, CJS_Value& vRet, CFX_WideString& sError)
2204 {
2205 CJS_Context* pContext = (CJS_Context *)cc;
2206 ASSERT(pContext != NULL);
2207 CJS_EventHandler* pEvent = pContext->GetEventHandler();
2208 ASSERT(pEvent != NULL);
2209
2210 if (params.size() != 4)
2211 {
2212 sError = JSGetStringFromID(pContext, IDS_STRING_JSPARAMERROR);
2213 return FALSE;
2214 }
2215
2216 if(!pEvent->m_pValue)
2217 return FALSE;
2218 if (pEvent->Value().IsEmpty() )
2219 return TRUE;
2220 double dEentValue = atof(CFX_ByteString::FromUnicode(pEvent->Value()));
2221 FX_BOOL bGreaterThan = params[0].ToBool();
2222 double dGreaterThan = params[1].ToDouble();
2223 FX_BOOL bLessThan = params[2].ToBool();
2224 double dLessThan = params[3].ToDouble();
2225 CFX_WideString swMsg;
2226
2227 if (bGreaterThan && bLessThan)
2228 {
2229 if (dEentValue < dGreaterThan || dEentValue > dLessThan)
2230 swMsg.Format(JSGetStringFromID(pContext, IDS_STRING_JSRANGE1).c_str(),
2231 params[1].ToCFXWideString().c_str(),
2232 params[3].ToCFXWideString().c_str());
2233 }
2234 else if (bGreaterThan)
2235 {
2236 if (dEentValue < dGreaterThan)
2237 swMsg.Format(JSGetStringFromID(pContext, IDS_STRING_JSRANGE2).c_str(),
2238 params[1].ToCFXWideString().c_str());
2239 }
2240 else if (bLessThan)
2241 {
2242 if (dEentValue > dLessThan)
2243 swMsg.Format(JSGetStringFromID(pContext, IDS_STRING_JSRANGE3).c_str(),
2244 params[3].ToCFXWideString().c_str());
2245 }
2246
2247 if (!swMsg.IsEmpty())
2248 {
2249 Alert(pContext, swMsg.c_str());
2250 pEvent->Rc() = FALSE;
2251 }
2252 return TRUE;
2253 }
2254
AFExtractNums(IFXJS_Context * cc,const CJS_Parameters & params,CJS_Value & vRet,CFX_WideString & sError)2255 FX_BOOL CJS_PublicMethods::AFExtractNums(IFXJS_Context* cc, const CJS_Parameters& params, CJS_Value& vRet, CFX_WideString& sError)
2256 {
2257 v8::Isolate* isolate = ::GetIsolate(cc);
2258 CJS_Context* pContext = (CJS_Context*)cc;
2259 ASSERT(pContext != NULL);
2260
2261 if (params.size() != 1)
2262 {
2263 sError = JSGetStringFromID(pContext, IDS_STRING_JSPARAMERROR);
2264 return FALSE;
2265 }
2266
2267 CJS_Array nums(isolate);
2268
2269 CFX_WideString str = params[0].ToCFXWideString();
2270 CFX_WideString sPart;
2271
2272 if (str.GetAt(0) == L'.' || str.GetAt(0) == L',')
2273 str = L"0" + str;
2274
2275 int nIndex = 0;
2276 for (int i=0, sz=str.GetLength(); i<sz; i++)
2277 {
2278 FX_WCHAR wc = str.GetAt(i);
2279 if (IsDigit((wchar_t)wc))
2280 {
2281 sPart += wc;
2282 }
2283 else
2284 {
2285 if (sPart.GetLength() > 0)
2286 {
2287 nums.SetElement(nIndex,CJS_Value(isolate,sPart.c_str()));
2288 sPart = L"";
2289 nIndex ++;
2290 }
2291 }
2292 }
2293
2294 if (sPart.GetLength() > 0)
2295 {
2296 nums.SetElement(nIndex,CJS_Value(isolate,sPart.c_str()));
2297 }
2298
2299 if (nums.GetLength() > 0)
2300 vRet = nums;
2301 else
2302 vRet.SetNull();
2303
2304 return TRUE;
2305 }
2306