539d7c780a2e34572f8265791c0c3ae94d3a4c42
[pdfium.git] / fpdfsdk / src / javascript / PublicMethods.cpp
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
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
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
152 FX_BOOL CJS_PublicMethods::IsDigit(wchar_t ch)
153 {
154         return (ch >= L'0' && ch <= L'9');
155 }
156
157 FX_BOOL CJS_PublicMethods::IsDigit(char ch)
158 {
159         return (ch >= '0' && ch <= '9');
160 }
161
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
167 FX_BOOL CJS_PublicMethods::IsAlphaNumeric(wchar_t ch)
168 {
169         return (IsDigit(ch) || IsAlphabetic(ch));
170 }
171
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
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
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
216 CFX_WideString CJS_PublicMethods::StrLTrim(FX_LPCWSTR pStr)
217 {
218         while (*pStr && *pStr == L' ') pStr++;
219
220         return pStr;
221 }
222
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
232 CFX_WideString CJS_PublicMethods::StrTrim(FX_LPCWSTR pStr)
233 {
234         return StrRTrim(StrLTrim(pStr).c_str());
235 }
236
237 CFX_ByteString CJS_PublicMethods::StrLTrim(FX_LPCSTR pStr)
238 {
239         while (*pStr && *pStr == ' ') pStr++;
240
241         return pStr;
242 }
243
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
253 CFX_ByteString CJS_PublicMethods::StrTrim(FX_LPCSTR pStr)
254 {
255         return StrRTrim(StrLTrim(pStr));
256 }
257
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
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
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
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
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
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
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
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
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)
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 bNagative = FALSE;
1099
1100         strValue = fcvt(dValue,iDec,&iDec2,&bNagative);
1101         if (strValue.IsEmpty())
1102         {
1103                 dValue = 0;
1104                 strValue = fcvt(dValue,iDec,&iDec2,&bNagative);
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,iDecNagative;
1158                 iDecPositive = iDec2;
1159                 iDecNagative = iDec2;           
1160                 
1161                 for (iDecPositive = iDec2 -3; iDecPositive > 0;iDecPositive -= 3)
1162                 {
1163                         strValue.Insert(iDecPositive, cSeperator);
1164                         iMax++;
1165                 }
1166         }
1167         
1168         //////////////////////////////////////////////////////////////////////
1169     //for processing currency string
1170
1171         Value = CFX_WideString::FromLocal(strValue);
1172         std::wstring strValue2 = Value.c_str();
1173
1174         if (bCurrencyPrepend)
1175                 strValue2 = wstrCurrency + strValue2;
1176         else
1177                 strValue2 = strValue2 + wstrCurrency;
1178         
1179         
1180         
1181         /////////////////////////////////////////////////////////////////////////
1182         //for processing negative style
1183         if (bNagative)
1184         {
1185                 if (iNegStyle == 0)
1186                 {
1187                         strValue2.insert(0,L"-");
1188                 }
1189                 if (iNegStyle == 2 || iNegStyle == 3)
1190                 {
1191                         strValue2.insert(0,L"(");
1192                         strValue2.insert(strValue2.length(),L")");
1193                 }
1194                 if (iNegStyle == 1 || iNegStyle == 3)
1195                 {
1196                         if (Field * fTarget = pEvent->Target_Field())
1197                         {
1198                                 CJS_Array arColor(isolate);
1199                                 CJS_Value vColElm(isolate);
1200                                 vColElm = L"RGB";
1201                                 arColor.SetElement(0,vColElm);
1202                                 vColElm = 1;
1203                                 arColor.SetElement(1,vColElm);
1204                                 vColElm = 0;
1205                                 arColor.SetElement(2,vColElm);
1206                                 
1207                                 arColor.SetElement(3,vColElm);
1208                                 
1209                                 CJS_PropValue vProp(isolate);
1210                                 vProp.StartGetting();
1211                                 vProp<<arColor;
1212                                 vProp.StartSetting();
1213                                 fTarget->textColor(cc,vProp,sError);// red
1214                         }
1215                 }
1216         }
1217         else
1218         {
1219                 if (iNegStyle == 1 || iNegStyle == 3)
1220                 {
1221                         if (Field *fTarget = pEvent->Target_Field())
1222                         {
1223                                 CJS_Array arColor(isolate);
1224                                 CJS_Value vColElm(isolate);
1225                                 vColElm = L"RGB";
1226                                 arColor.SetElement(0,vColElm);
1227                                 vColElm = 0;
1228                                 arColor.SetElement(1,vColElm);
1229                                 arColor.SetElement(2,vColElm);
1230                                 arColor.SetElement(3,vColElm);
1231                                 
1232                                 CJS_PropValue vProp(isolate);
1233                                 vProp.StartGetting();
1234                                 fTarget->textColor(cc,vProp,sError);
1235                                 
1236                                 CJS_Array aProp(isolate);
1237                                 vProp.ConvertToArray(aProp);
1238
1239                                 CPWL_Color crProp;
1240                                 CPWL_Color crColor;
1241                                 color::ConvertArrayToPWLColor(aProp, crProp);
1242                                 color::ConvertArrayToPWLColor(arColor, crColor);
1243
1244                                 if (crColor != crProp)
1245                                 {
1246                                         CJS_PropValue vProp2(isolate);
1247                                         vProp2.StartGetting();
1248                                         vProp2<<arColor;
1249                                         vProp2.StartSetting();
1250                                 fTarget->textColor(cc,vProp2,sError);
1251                                 }
1252                         }
1253                 }
1254         }
1255         Value = strValue2.c_str();
1256 #endif
1257         return TRUE;
1258 }
1259
1260 //function AFNumber_Keystroke(nDec, sepStyle, negStyle, currStyle, strCurrency, bCurrencyPrepend)
1261 FX_BOOL CJS_PublicMethods::AFNumber_Keystroke(IFXJS_Context* cc, const CJS_Parameters& params, CJS_Value& vRet, CFX_WideString& sError)
1262 {
1263         CJS_Context* pContext = (CJS_Context *)cc;
1264         ASSERT(pContext != NULL);
1265         CJS_EventHandler* pEvent = pContext->GetEventHandler();
1266         ASSERT(pEvent != NULL);
1267         
1268         if(params.size() < 2)
1269                 return FALSE;
1270         int iSepStyle = params[1].ToInt();
1271         
1272         if (iSepStyle < 0 || iSepStyle > 3)
1273                 iSepStyle = 0;
1274         if(!pEvent->m_pValue)
1275                 return FALSE;
1276         CFX_WideString & val = pEvent->Value(); 
1277         CFX_WideString & w_strChange = pEvent->Change();
1278     CFX_WideString w_strValue = val;
1279
1280         if (pEvent->WillCommit())
1281         {
1282                 CFX_WideString wstrChange = w_strChange;
1283                 CFX_WideString wstrValue = StrLTrim(w_strValue.c_str());
1284                 if (wstrValue.IsEmpty())
1285                         return TRUE;
1286                 
1287                 CFX_WideString swTemp = wstrValue;
1288                 swTemp.Replace(L",", L".");
1289                 if (!IsNumber(swTemp.c_str()))
1290                 {
1291                         pEvent->Rc() = FALSE;
1292                         sError = JSGetStringFromID(pContext, IDS_STRING_JSAFNUMBER_KEYSTROKE);
1293                         Alert(pContext, sError.c_str());
1294                         return TRUE;
1295                 }
1296                 return TRUE; // it happens after the last keystroke and before validating,
1297         }
1298
1299         std::wstring w_strValue2 = w_strValue.c_str();
1300         std::wstring w_strChange2 = w_strChange.c_str();
1301         std::wstring w_strSelected;
1302         if(-1 != pEvent->SelStart())
1303                 w_strSelected = w_strValue2.substr(pEvent->SelStart(),(pEvent->SelEnd() - pEvent->SelStart()));
1304         FX_BOOL bHasSign = (w_strValue2.find('-') != -1) && (w_strSelected.find('-') == -1);
1305         if (bHasSign)
1306         {
1307                 //can't insert "change" in front to sign postion.
1308                 if (pEvent->SelStart() == 0)
1309                 {
1310             FX_BOOL &bRc = pEvent->Rc();
1311                         bRc = FALSE;
1312                         return TRUE;
1313                 }
1314         }
1315
1316         char cSep = L'.';
1317
1318         switch (iSepStyle)
1319         {
1320         case 0:
1321         case 1:
1322                 cSep = L'.';
1323                 break;
1324         case 2:
1325         case 3:
1326                 cSep = L',';
1327                 break;
1328         }
1329         
1330         FX_BOOL bHasSep = (w_strValue2.find(cSep) != -1);
1331         for (std::wstring::iterator it = w_strChange2.begin(); it != w_strChange2.end(); it++)
1332         {
1333                 if (*it == cSep)
1334                 {
1335                         if (bHasSep)
1336                         {
1337                                 FX_BOOL &bRc = pEvent->Rc();
1338                                 bRc = FALSE;
1339                                 return TRUE;
1340                         }
1341                         else
1342                         {
1343                                 bHasSep = TRUE;
1344                                 continue;
1345                         }
1346                 }
1347                 if (*it == L'-')
1348                 {
1349                         if (bHasSign)
1350                         {
1351                                 FX_BOOL &bRc = pEvent->Rc();
1352                                 bRc = FALSE;
1353                                 return TRUE;
1354                         }
1355                         else if (it != w_strChange2.begin()) //sign's position is not correct
1356                         {
1357                                 FX_BOOL &bRc = pEvent->Rc();
1358                                 bRc = FALSE;
1359                                 return TRUE;
1360                         }
1361                         else if (pEvent->SelStart() != 0)
1362                         {
1363                                 FX_BOOL &bRc = pEvent->Rc();
1364                                 bRc = FALSE;
1365                                 return TRUE;
1366                         }
1367                         bHasSign = TRUE;
1368                         continue;
1369                 }
1370                 
1371                 if (!IsDigit(*it))
1372                 {                       
1373                         FX_BOOL &bRc = pEvent->Rc();
1374                         bRc = FALSE;
1375                         return TRUE;
1376                 }
1377         }
1378         
1379         
1380         std::wstring w_prefix = w_strValue2.substr(0,pEvent->SelStart());
1381         std::wstring w_postfix;
1382         if (pEvent->SelEnd()<(int)w_strValue2.length())
1383                 w_postfix  = w_strValue2.substr(pEvent->SelEnd());
1384         w_strValue2 = w_prefix + w_strChange2 + w_postfix;
1385         w_strValue = w_strValue2.c_str();
1386         val = w_strValue;
1387         return TRUE;            
1388         
1389 }
1390
1391 //function AFPercent_Format(nDec, sepStyle)
1392 FX_BOOL CJS_PublicMethods::AFPercent_Format(IFXJS_Context* cc, const CJS_Parameters& params, CJS_Value& vRet, CFX_WideString& sError)
1393 {
1394 #if _FX_OS_ != _FX_ANDROID_
1395         CJS_Context* pContext = (CJS_Context *)cc;
1396         ASSERT(pContext != NULL);
1397         CJS_EventHandler* pEvent = pContext->GetEventHandler();
1398         ASSERT(pEvent != NULL);
1399
1400     if (params.size() != 2)
1401         {
1402                 sError = JSGetStringFromID(pContext, IDS_STRING_JSPARAMERROR);
1403                 return FALSE;
1404         }
1405         if(!pEvent->m_pValue)
1406                 return FALSE;
1407
1408         CFX_WideString& Value = pEvent->Value();
1409         CFX_ByteString strValue = StrTrim(CFX_ByteString::FromUnicode(Value));
1410         if (strValue.IsEmpty())
1411                 return TRUE;
1412
1413         int iDec = params[0].ToInt();
1414         if (iDec < 0)
1415                 iDec = -iDec;
1416
1417         int iSepStyle = params[1].ToInt();
1418         if (iSepStyle < 0 || iSepStyle > 3)
1419                 iSepStyle = 0;
1420
1421         //////////////////////////////////////////////////////
1422         //for processing decimal places
1423         double dValue = atof(strValue);
1424         dValue *= 100;
1425         if (iDec > 0)
1426                 dValue += DOUBLE_CORRECT;//УÕý
1427
1428         int iDec2;
1429         FX_BOOL bNagative = FALSE;
1430         strValue = fcvt(dValue,iDec,&iDec2,&bNagative);
1431     if (strValue.IsEmpty())
1432         {
1433                 dValue = 0;
1434                 strValue = fcvt(dValue,iDec,&iDec2,&bNagative);
1435         }
1436
1437         if (iDec2 < 0)
1438         {
1439                 for (int iNum = 0; iNum < abs(iDec2); iNum++)
1440                 {
1441                         strValue = "0" + strValue;
1442                 }
1443                 iDec2 = 0;
1444                 
1445         }
1446         int iMax = strValue.GetLength();
1447         if (iDec2 > iMax)
1448         {
1449                 for (int iNum = 0; iNum <= iDec2 - iMax; iNum++)
1450                 {
1451                         strValue += "0";
1452                 }
1453                 iMax = iDec2+1;                 
1454         }
1455         ///////////////////////////////////////////////////////
1456     //for processing seperator style
1457         if (iDec2 < iMax)
1458         {
1459                 if (iSepStyle == 0 || iSepStyle == 1)
1460                 {
1461                         strValue.Insert(iDec2, '.');
1462                         iMax++;
1463                 }
1464                 else if (iSepStyle == 2 || iSepStyle == 3)
1465                 {
1466                         strValue.Insert(iDec2, ',');
1467                         iMax++;
1468                 }
1469                 
1470                 if (iDec2 == 0)
1471                         strValue.Insert(iDec2, '0');
1472         }
1473         if (iSepStyle == 0 || iSepStyle == 2)
1474         {
1475                 char cSeperator;
1476                 if (iSepStyle == 0)
1477                         cSeperator = ',';
1478                 else
1479                         cSeperator = '.';
1480                 
1481                 int iDecPositive,iDecNagative;
1482                 iDecPositive = iDec2;
1483                 iDecNagative = iDec2;
1484                         
1485                 for (iDecPositive = iDec2 -3; iDecPositive > 0; iDecPositive -= 3)
1486                 {
1487                         strValue.Insert(iDecPositive,cSeperator);
1488                         iMax++;
1489                 }
1490         }
1491         ////////////////////////////////////////////////////////////////////
1492         //nagative mark
1493         if(bNagative)
1494                 strValue = "-" + strValue;
1495         strValue += "%";
1496         Value = CFX_WideString::FromLocal(strValue);
1497 #endif
1498         return TRUE;
1499 }
1500 //AFPercent_Keystroke(nDec, sepStyle)
1501 FX_BOOL CJS_PublicMethods::AFPercent_Keystroke(IFXJS_Context* cc, const CJS_Parameters& params, CJS_Value& vRet, CFX_WideString& sError)
1502 {
1503         return AFNumber_Keystroke(cc,params,vRet,sError);
1504 }
1505
1506 //function AFDate_FormatEx(cFormat)
1507 FX_BOOL CJS_PublicMethods::AFDate_FormatEx(IFXJS_Context* cc, const CJS_Parameters& params, CJS_Value& vRet, CFX_WideString& sError)
1508 {
1509         CJS_Context* pContext = (CJS_Context *)cc;
1510         ASSERT(pContext != NULL);
1511         CJS_EventHandler* pEvent = pContext->GetEventHandler();
1512         ASSERT(pEvent != NULL);
1513
1514         if (params.size() != 1)
1515         {
1516                 sError = JSGetStringFromID(pContext, IDS_STRING_JSPARAMERROR);
1517                 return FALSE;
1518         }
1519         if(!pEvent->m_pValue)
1520                 return FALSE;
1521
1522         CFX_WideString& val = pEvent->Value();
1523         CFX_WideString strValue = val;
1524         if (strValue.IsEmpty())
1525                 return TRUE;
1526
1527         CFX_WideString sFormat = params[0].ToCFXWideString();
1528         FX_BOOL bWrongFormat = FALSE;
1529         double dDate = 0.0f;
1530
1531         if(strValue.Find(L"GMT") != -1)
1532         {
1533                 //for GMT format time
1534                 //such as "Tue Aug 11 14:24:16 GMT+08002009"
1535                 dDate = MakeInterDate(strValue);
1536         }
1537         else
1538         {
1539                 dDate = MakeRegularDate(strValue,sFormat,bWrongFormat);
1540         }
1541
1542         if (JS_PortIsNan(dDate))
1543         {
1544                 CFX_WideString swMsg;
1545                 swMsg.Format(JSGetStringFromID(pContext, IDS_STRING_JSPARSEDATE).c_str(), sFormat.c_str());
1546                 Alert(pContext, swMsg.c_str());
1547                 return FALSE;
1548         }
1549
1550         val =  MakeFormatDate(dDate,sFormat);
1551         return TRUE;
1552 }
1553
1554 double CJS_PublicMethods::MakeInterDate(CFX_WideString strValue)
1555 {
1556         int nHour;
1557         int nMin;
1558         int nSec;
1559         int nYear;
1560         int nMonth;
1561         int nDay;
1562
1563         CFX_WideStringArray wsArray;
1564         CFX_WideString sMonth = L"";
1565         CFX_WideString sTemp = L"";
1566         int nSize = strValue.GetLength();
1567
1568         for(int i = 0; i < nSize; i++)
1569         {
1570                 FX_WCHAR c = strValue.GetAt(i);
1571                 if(c == L' ' || c == L':')
1572                 {       
1573                         wsArray.Add(sTemp);
1574                         sTemp = L"";
1575                         continue;
1576                 }
1577
1578                 sTemp += c;
1579         }
1580         
1581         wsArray.Add(sTemp);
1582         if(wsArray.GetSize() != 8)return 0;
1583
1584         sTemp = wsArray[1];
1585         if(sTemp.Compare(L"Jan") == 0) nMonth = 1;
1586         if(sTemp.Compare(L"Feb") == 0) nMonth = 2;
1587         if(sTemp.Compare(L"Mar") == 0) nMonth = 3;
1588         if(sTemp.Compare(L"Apr") == 0) nMonth = 4;
1589         if(sTemp.Compare(L"May") == 0) nMonth = 5;
1590         if(sTemp.Compare(L"Jun") == 0) nMonth = 6;
1591         if(sTemp.Compare(L"Jul") == 0) nMonth = 7;
1592         if(sTemp.Compare(L"Aug") == 0) nMonth = 8;
1593         if(sTemp.Compare(L"Sep") == 0) nMonth = 9;
1594         if(sTemp.Compare(L"Oct") == 0) nMonth = 10;
1595         if(sTemp.Compare(L"Nov") == 0) nMonth = 11;
1596         if(sTemp.Compare(L"Dec") == 0) nMonth = 12;
1597
1598         nDay = (int)ParseStringToNumber(wsArray[2].c_str());
1599         nHour = (int)ParseStringToNumber(wsArray[3].c_str());
1600         nMin = (int)ParseStringToNumber(wsArray[4].c_str());
1601         nSec = (int)ParseStringToNumber(wsArray[5].c_str());
1602         nYear = (int)ParseStringToNumber(wsArray[7].c_str());
1603
1604         double dRet = JS_MakeDate(JS_MakeDay(nYear,nMonth - 1,nDay),JS_MakeTime(nHour, nMin, nSec, 0));
1605
1606         if (JS_PortIsNan(dRet))
1607         {
1608                 dRet = JS_DateParse(strValue.c_str());
1609         }
1610         
1611         return dRet;
1612 }
1613
1614 //AFDate_KeystrokeEx(cFormat)
1615 FX_BOOL CJS_PublicMethods::AFDate_KeystrokeEx(IFXJS_Context* cc, const CJS_Parameters& params, CJS_Value& vRet, CFX_WideString& sError)
1616 {
1617         CJS_Context* pContext = (CJS_Context *)cc;
1618         ASSERT(pContext != NULL);
1619         CJS_EventHandler* pEvent = pContext->GetEventHandler();
1620         ASSERT(pEvent != NULL);
1621
1622         if (params.size() != 1)
1623         {
1624                 sError = L"AFDate_KeystrokeEx's parameters' size r not correct";
1625                 return FALSE;
1626         }
1627
1628         if (pEvent->WillCommit())
1629         {
1630                 if(!pEvent->m_pValue)
1631                         return FALSE;
1632                 CFX_WideString strValue = pEvent->Value();
1633                 if (strValue.IsEmpty())
1634                         return TRUE;
1635
1636                 CFX_WideString sFormat = params[0].ToCFXWideString();
1637                 FX_BOOL bWrongFormat = FALSE;
1638                 double dRet = MakeRegularDate(strValue,sFormat,bWrongFormat);
1639                 if (bWrongFormat || JS_PortIsNan(dRet))
1640                 {
1641                         CFX_WideString swMsg;
1642                         swMsg.Format(JSGetStringFromID(pContext, IDS_STRING_JSPARSEDATE).c_str(), sFormat.c_str());
1643                         Alert(pContext, swMsg.c_str());
1644                         pEvent->Rc() = FALSE;
1645                         return TRUE;
1646                 }
1647         }
1648         return TRUE;
1649 }
1650
1651 FX_BOOL CJS_PublicMethods::AFDate_Format(IFXJS_Context* cc, const CJS_Parameters& params, CJS_Value& vRet, CFX_WideString& sError)
1652 {
1653         v8::Isolate* isolate = ::GetIsolate(cc);
1654
1655         if (params.size() != 1)
1656         {
1657                 CJS_Context* pContext = (CJS_Context*)cc;
1658                 ASSERT(pContext != NULL);
1659
1660                 sError = JSGetStringFromID(pContext, IDS_STRING_JSPARAMERROR);
1661                 return FALSE;
1662         }
1663
1664         int iIndex = params[0].ToInt();
1665         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",
1666                 L"yy-mm-dd", L"mmm-yy", L"mmmm-yy", L"mmm d, yyyy", L"mmmm d, yyyy",
1667                 L"m/d/yy h:MM tt", L"m/d/yy HH:MM" };
1668
1669         ASSERT(iIndex < FX_ArraySize(cFormats));
1670
1671         if (iIndex < 0)
1672                 iIndex = 0;
1673         if (iIndex >= FX_ArraySize(cFormats))
1674                 iIndex = 0;
1675         CJS_Parameters newParams;
1676         CJS_Value val(isolate,cFormats[iIndex]);
1677         newParams.push_back(val);
1678         return AFDate_FormatEx(cc,newParams,vRet,sError);
1679 }
1680
1681 //AFDate_KeystrokeEx(cFormat)
1682 FX_BOOL CJS_PublicMethods::AFDate_Keystroke(IFXJS_Context* cc, const CJS_Parameters& params, CJS_Value& vRet, CFX_WideString& sError)
1683 {
1684         v8::Isolate* isolate = ::GetIsolate(cc);
1685
1686         if (params.size() != 1)
1687         {
1688                 CJS_Context* pContext = (CJS_Context*)cc;
1689                 ASSERT(pContext != NULL);
1690
1691                 sError = JSGetStringFromID(pContext, IDS_STRING_JSPARAMERROR);
1692                 return FALSE;
1693         }
1694
1695         int iIndex = params[0].ToInt();
1696         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",
1697                 L"yy-mm-dd", L"mmm-yy", L"mmmm-yy", L"mmm d, yyyy", L"mmmm d, yyyy",
1698                 L"m/d/yy h:MM tt", L"m/d/yy HH:MM" };
1699
1700         ASSERT(iIndex<FX_ArraySize(cFormats));
1701
1702         if (iIndex < 0)
1703                 iIndex = 0;
1704         if (iIndex >= FX_ArraySize(cFormats))
1705                 iIndex = 0;
1706         CJS_Parameters newParams;
1707         CJS_Value val(isolate,cFormats[iIndex]);
1708         newParams.push_back(val);
1709         return AFDate_KeystrokeEx(cc,newParams,vRet,sError);
1710 }
1711
1712 //function AFTime_Format(ptf)
1713 FX_BOOL CJS_PublicMethods::AFTime_Format(IFXJS_Context* cc, const CJS_Parameters& params, CJS_Value& vRet, CFX_WideString& sError)
1714 {
1715         v8::Isolate* isolate = ::GetIsolate(cc);
1716
1717         if (params.size() != 1)
1718         {
1719                 CJS_Context* pContext = (CJS_Context*)cc;
1720                 ASSERT(pContext != NULL);
1721                 sError = JSGetStringFromID(pContext, IDS_STRING_JSPARAMERROR);
1722                 return FALSE;
1723         }
1724
1725         int iIndex = params[0].ToInt();
1726         FX_LPCWSTR cFormats[] = {L"HH:MM", L"h:MM tt", L"HH:MM:ss", L"h:MM:ss tt"};
1727
1728         ASSERT(iIndex<FX_ArraySize(cFormats));
1729
1730         if (iIndex < 0)
1731                 iIndex = 0;
1732         if (iIndex >= FX_ArraySize(cFormats))
1733                 iIndex = 0;
1734         CJS_Parameters newParams;
1735         CJS_Value val(isolate,cFormats[iIndex]);
1736         newParams.push_back(val);
1737         return AFDate_FormatEx(cc,newParams,vRet,sError);
1738 }
1739
1740 FX_BOOL CJS_PublicMethods::AFTime_Keystroke(IFXJS_Context* cc, const CJS_Parameters& params, CJS_Value& vRet, CFX_WideString& sError)
1741 {
1742         v8::Isolate* isolate = ::GetIsolate(cc);
1743         if (params.size() != 1)
1744         {
1745                 CJS_Context* pContext = (CJS_Context*)cc;
1746                 ASSERT(pContext != NULL);
1747                 sError = JSGetStringFromID(pContext, IDS_STRING_JSPARAMERROR);
1748                 return FALSE;
1749         }
1750
1751         int iIndex = params[0].ToInt();
1752         FX_LPCWSTR cFormats[] = {L"HH:MM", L"h:MM tt", L"HH:MM:ss", L"h:MM:ss tt"};
1753
1754         ASSERT(iIndex<FX_ArraySize(cFormats));
1755
1756         if (iIndex < 0)
1757                 iIndex = 0;
1758         if (iIndex >= FX_ArraySize(cFormats))
1759                 iIndex = 0;
1760         CJS_Parameters newParams;
1761         CJS_Value val(isolate,cFormats[iIndex]);
1762         newParams.push_back(val);
1763         return AFDate_KeystrokeEx(cc,newParams,vRet,sError);
1764 }
1765
1766 FX_BOOL CJS_PublicMethods::AFTime_FormatEx(IFXJS_Context* cc, const CJS_Parameters& params, CJS_Value& vRet, CFX_WideString& sError)
1767 {
1768         return AFDate_FormatEx(cc,params,vRet,sError);
1769 }
1770
1771 FX_BOOL CJS_PublicMethods::AFTime_KeystrokeEx(IFXJS_Context* cc, const CJS_Parameters& params, CJS_Value& vRet, CFX_WideString& sError)
1772 {
1773         return AFDate_KeystrokeEx(cc,params,vRet,sError);
1774 }
1775
1776 //function AFSpecial_Format(psf)
1777 FX_BOOL CJS_PublicMethods::AFSpecial_Format(IFXJS_Context* cc, const CJS_Parameters& params, CJS_Value& vRet, CFX_WideString& sError)
1778 {
1779         CJS_Context* pContext = (CJS_Context *)cc;
1780         ASSERT(pContext != NULL);
1781
1782         if (params.size() != 1)
1783         {
1784                 sError = JSGetStringFromID(pContext, IDS_STRING_JSPARAMERROR);
1785                 return FALSE;
1786         }
1787
1788         std::string cFormat;
1789         int iIndex = params[0].ToInt();
1790
1791         CJS_EventHandler* pEvent = pContext->GetEventHandler();
1792         ASSERT(pEvent != NULL);
1793
1794         if(!pEvent->m_pValue)
1795                 return FALSE;
1796         CFX_WideString& Value = pEvent->Value();        
1797         std::string strSrc = CFX_ByteString::FromUnicode(Value).c_str();
1798         
1799         switch (iIndex) 
1800         {
1801         case 0:                         
1802                 cFormat = "99999";
1803                 break;
1804         case 1:                         
1805                 cFormat = "99999-9999";
1806                 break;
1807         case 2:                         
1808                 {
1809                         std::string NumberStr;
1810                         util::printx("9999999999", strSrc,NumberStr); 
1811                         if (NumberStr.length() >= 10 )
1812                                 cFormat = "(999) 999-9999";
1813                         else 
1814                                 cFormat = "999-9999";
1815                         break;
1816                 }
1817         case 3:
1818                 cFormat = "999-99-9999";
1819                 break;
1820         }
1821         
1822         std::string strDes;
1823         util::printx(cFormat,strSrc,strDes);
1824         Value = CFX_WideString::FromLocal(strDes.c_str());
1825         return TRUE;
1826 }
1827
1828
1829 //function AFSpecial_KeystrokeEx(mask)
1830 FX_BOOL CJS_PublicMethods::AFSpecial_KeystrokeEx(IFXJS_Context* cc, const CJS_Parameters& params, CJS_Value& vRet, CFX_WideString& sError)
1831 {
1832         CJS_Context* pContext = (CJS_Context *)cc;
1833         ASSERT(pContext != NULL);
1834         CJS_EventHandler* pEvent = pContext->GetEventHandler();
1835
1836         ASSERT(pEvent != NULL);
1837
1838         if (params.size() < 1)
1839         {
1840                 sError = JSGetStringFromID(pContext, IDS_STRING_JSPARAMERROR);
1841                 return FALSE;
1842         }
1843
1844         if(!pEvent->m_pValue)
1845                 return FALSE;
1846         CFX_WideString& valEvent = pEvent->Value();
1847
1848         CFX_WideString wstrMask = params[0].ToCFXWideString();
1849         if (wstrMask.IsEmpty())
1850                 return TRUE;
1851
1852         std::wstring wstrValue = valEvent.c_str();
1853
1854         if (pEvent->WillCommit())
1855         {
1856                 if (wstrValue.empty())
1857                         return TRUE;
1858                 int iIndexMask = 0;
1859                 for (std::wstring::iterator it = wstrValue.begin(); it != wstrValue.end(); it++)
1860                 {
1861                         wchar_t w_Value = *it;
1862                         if (!maskSatisfied(w_Value,wstrMask[iIndexMask]))
1863                                 break;
1864                         iIndexMask++;
1865                 }
1866
1867                 if (iIndexMask != wstrMask.GetLength() || (iIndexMask != wstrValue.size() && wstrMask.GetLength() != 0))
1868                 {
1869                         Alert(pContext, JSGetStringFromID(pContext, IDS_STRING_JSAFNUMBER_KEYSTROKE).c_str());
1870                         pEvent->Rc() = FALSE;
1871                 }
1872                 return TRUE;
1873         }
1874
1875         CFX_WideString &wideChange = pEvent->Change();
1876         std::wstring wChange = wideChange.c_str();
1877         if (wChange.empty())
1878                 return TRUE;
1879
1880         int iIndexMask = pEvent->SelStart();
1881
1882         if (wstrValue.length() - (pEvent->SelEnd()-pEvent->SelStart()) + wChange.length() > (FX_DWORD)wstrMask.GetLength())
1883         {
1884                 Alert(pContext, JSGetStringFromID(pContext, IDS_STRING_JSPARAM_TOOLONG).c_str());
1885                 pEvent->Rc() = FALSE;
1886                 return TRUE;
1887         }
1888
1889         if (iIndexMask >= wstrMask.GetLength() && (!wChange.empty()))
1890         {
1891                 Alert(pContext, JSGetStringFromID(pContext, IDS_STRING_JSPARAM_TOOLONG).c_str());
1892                 pEvent->Rc() = FALSE;
1893                 return TRUE;
1894         }
1895
1896         for (std::wstring::iterator it = wChange.begin(); it != wChange.end(); it++)
1897         {
1898                 if (iIndexMask >= wstrMask.GetLength())
1899                 {
1900                         Alert(pContext, JSGetStringFromID(pContext, IDS_STRING_JSPARAM_TOOLONG).c_str());
1901                         pEvent->Rc() = FALSE;
1902                         return TRUE;
1903                 }
1904                 wchar_t w_Mask = wstrMask[iIndexMask];
1905                 if (!isReservedMaskChar(w_Mask))
1906                 {
1907                         *it = w_Mask;
1908                 }
1909                 wchar_t w_Change = *it;
1910                 if (!maskSatisfied(w_Change,w_Mask))
1911                 {
1912                         pEvent->Rc() = FALSE;
1913                         return TRUE;
1914                 }
1915                 iIndexMask++;
1916         }
1917
1918         wideChange = wChange.c_str();
1919         return TRUE;
1920 }
1921
1922
1923 //function AFSpecial_Keystroke(psf)
1924 FX_BOOL CJS_PublicMethods::AFSpecial_Keystroke(IFXJS_Context* cc, const CJS_Parameters& params, CJS_Value& vRet, CFX_WideString& sError)
1925 {
1926         v8::Isolate* isolate = ::GetIsolate(cc);
1927
1928         CJS_Context* pContext = (CJS_Context *)cc;
1929         ASSERT(pContext != NULL);
1930         CJS_EventHandler* pEvent = pContext->GetEventHandler();
1931         ASSERT(pEvent != NULL);
1932
1933         if (params.size() != 1)
1934         {
1935                 sError = JSGetStringFromID(pContext, IDS_STRING_JSPARAMERROR);
1936                 return FALSE;
1937         }
1938
1939         std::string cFormat;
1940         int iIndex = params[0].ToInt();
1941
1942         if(!pEvent->m_pValue)
1943                 return FALSE;
1944         //CJS_Value val = pEvent->Value();
1945         CFX_WideString& val = pEvent->Value();
1946         std::string strSrc = CFX_ByteString::FromUnicode(val).c_str();
1947         std::wstring wstrChange = pEvent->Change().c_str();
1948
1949         switch (iIndex) 
1950         {
1951         case 0:                         
1952                 cFormat = "99999";
1953                 break;
1954         case 1:                         
1955                 //cFormat = "99999-9999";
1956                 cFormat = "999999999";
1957                 break;
1958         case 2:                         
1959                 {
1960                         std::string NumberStr;
1961                         util::printx("9999999999", strSrc,NumberStr); 
1962                         if (strSrc.length() + wstrChange.length() > 7 )
1963                                 //cFormat = "(999) 999-9999";
1964                                 cFormat = "9999999999";
1965                         else 
1966                                 //cFormat = "999-9999";
1967                                 cFormat = "9999999";
1968                         break;
1969                 }
1970         case 3:
1971                 //cFormat = "999-99-9999";
1972                 cFormat = "999999999";
1973                 break;
1974         }
1975     
1976         CJS_Parameters params2;
1977         CJS_Value vMask(isolate, cFormat.c_str());
1978         params2.push_back(vMask);
1979         
1980     return AFSpecial_KeystrokeEx(cc,params2,vRet,sError);
1981 }
1982
1983 FX_BOOL CJS_PublicMethods::AFMergeChange(IFXJS_Context* cc, const CJS_Parameters& params, CJS_Value& vRet, CFX_WideString& sError)
1984 {
1985         CJS_Context* pContext = (CJS_Context *)cc;
1986         ASSERT(pContext != NULL);
1987         CJS_EventHandler* pEventHandler = pContext->GetEventHandler();
1988         ASSERT(pEventHandler != NULL);
1989
1990         if (params.size() != 1)
1991         {
1992                 sError = JSGetStringFromID(pContext, IDS_STRING_JSPARAMERROR);
1993                 return FALSE;
1994         }
1995
1996         CFX_WideString swValue;
1997         if (pEventHandler->m_pValue != NULL)
1998                 swValue = pEventHandler->Value();
1999
2000         if (pEventHandler->WillCommit())
2001         {
2002                 vRet = swValue.c_str();
2003                 return TRUE;
2004         }
2005
2006         CFX_WideString prefix,postfix;
2007
2008         if (pEventHandler->SelStart() >= 0)
2009                 prefix = swValue.Mid(0,pEventHandler->SelStart());
2010         else
2011                 prefix = L"";
2012
2013
2014         if (pEventHandler->SelEnd() >= 0 && pEventHandler->SelEnd() <= swValue.GetLength())
2015                 postfix = swValue.Mid(pEventHandler->SelEnd(), swValue.GetLength() - pEventHandler->SelEnd());
2016         else postfix = L"";
2017
2018         vRet = (prefix + pEventHandler->Change() + postfix).c_str();
2019
2020         return TRUE;
2021 }
2022
2023 FX_BOOL CJS_PublicMethods::AFParseDateEx(IFXJS_Context* cc, const CJS_Parameters& params, CJS_Value& vRet, CFX_WideString& sError)
2024 {
2025         CJS_Context* pContext = (CJS_Context *)cc;
2026         ASSERT(pContext != NULL);
2027
2028         if (params.size() != 2)
2029         {
2030                 sError = JSGetStringFromID(pContext, IDS_STRING_JSPARAMERROR);
2031                 return FALSE;
2032         }
2033
2034         CFX_WideString sValue = params[0].ToCFXWideString();
2035         CFX_WideString sFormat = params[1].ToCFXWideString();
2036
2037         FX_BOOL bWrongFormat = FALSE;
2038         double dDate = MakeRegularDate(sValue,sFormat,bWrongFormat);
2039
2040         if (JS_PortIsNan(dDate))
2041         {
2042                 CFX_WideString swMsg;
2043                 swMsg.Format(JSGetStringFromID(pContext, IDS_STRING_JSPARSEDATE).c_str(), sFormat.c_str());
2044                 Alert((CJS_Context *)cc, swMsg.c_str());
2045                 return FALSE;
2046         }
2047
2048         vRet = dDate;
2049         return TRUE;
2050 }
2051
2052 FX_BOOL CJS_PublicMethods::AFSimple(IFXJS_Context* cc, const CJS_Parameters& params, CJS_Value& vRet, CFX_WideString& sError)
2053 {
2054         if (params.size() != 3)
2055         {
2056                 CJS_Context* pContext = (CJS_Context *)cc;
2057                 ASSERT(pContext != NULL);
2058
2059                 sError = JSGetStringFromID(pContext, IDS_STRING_JSPARAMERROR);
2060                 return FALSE;
2061         }
2062
2063         vRet = (double)AF_Simple(params[0].ToCFXWideString().c_str(), params[1].ToDouble(), params[2].ToDouble());
2064         return TRUE;
2065 }
2066
2067 FX_BOOL CJS_PublicMethods::AFMakeNumber(IFXJS_Context* cc, const CJS_Parameters& params, CJS_Value& vRet, CFX_WideString& sError)
2068 {
2069         if (params.size() != 1)
2070         {
2071                 CJS_Context* pContext = (CJS_Context *)cc;
2072                 ASSERT(pContext != NULL);
2073
2074                 sError = JSGetStringFromID(pContext, IDS_STRING_JSPARAMERROR);
2075                 return FALSE;
2076         }
2077         vRet = ParseStringToNumber(params[0].ToCFXWideString().c_str());
2078         return TRUE;
2079 }
2080
2081 FX_BOOL CJS_PublicMethods::AFSimple_Calculate(IFXJS_Context* cc, const CJS_Parameters& params, CJS_Value& vRet, CFX_WideString& sError)
2082 {
2083         v8::Isolate* isolate = ::GetIsolate(cc);
2084
2085         CJS_Context* pContext = (CJS_Context *)cc;
2086         ASSERT(pContext != NULL);
2087
2088         if (params.size() != 2)
2089         {
2090                 sError = JSGetStringFromID(pContext, IDS_STRING_JSPARAMERROR);
2091                 return FALSE;
2092         }
2093
2094         CJS_Value params1 = params[1];
2095
2096         if (!params1.IsArrayObject() && params1.GetType() != VT_string)
2097         {
2098                 sError = JSGetStringFromID(pContext, IDS_STRING_JSPARAMERROR);
2099                 return FALSE;
2100         }
2101
2102         CPDFSDK_Document* pReaderDoc = pContext->GetReaderDocument();
2103     ASSERT(pReaderDoc != NULL);
2104
2105         CPDFSDK_InterForm* pReaderInterForm = pReaderDoc->GetInterForm();
2106         ASSERT(pReaderInterForm != NULL);
2107
2108         CPDF_InterForm* pInterForm = pReaderInterForm->GetInterForm();
2109         ASSERT(pInterForm != NULL);
2110
2111         double dValue;
2112         CFX_WideString sFunction = params[0].ToCFXWideString();
2113         if (wcscmp(sFunction.c_str(), L"PRD") == 0)
2114         dValue = 1.0;
2115         else
2116                 dValue = 0.0;
2117
2118         CJS_Array FieldNameArray = AF_MakeArrayFromList(isolate,params1);
2119
2120         int nFieldsCount = 0;
2121
2122         for (int i=0,isz=FieldNameArray.GetLength(); i<isz; i++)
2123         {
2124                 CJS_Value jsValue(isolate);
2125                 FieldNameArray.GetElement(i,jsValue);
2126                 CFX_WideString wsFieldName = jsValue.ToCFXWideString();
2127
2128         for (int j=0,jsz=pInterForm->CountFields(wsFieldName); j<jsz; j++)
2129                 {
2130                         if (CPDF_FormField* pFormField = pInterForm->GetField(j, wsFieldName))
2131                         {
2132                                 double dTemp = 0.0;
2133
2134                                 switch (pFormField->GetFieldType())
2135                                 {
2136                                 case FIELDTYPE_TEXTFIELD:
2137                                 case FIELDTYPE_COMBOBOX:
2138                                         {
2139                                                 dTemp = ParseStringToNumber(pFormField->GetValue().c_str());
2140                                                 break;
2141                                         }
2142                                 case FIELDTYPE_PUSHBUTTON:
2143                                         {
2144                                                 dTemp = 0.0;
2145                                                 break;
2146                                         }
2147                                 case FIELDTYPE_CHECKBOX:
2148                                 case FIELDTYPE_RADIOBUTTON:
2149                                         {
2150                                                 dTemp = 0.0;
2151                                                 for (int c=0,csz=pFormField->CountControls(); c<csz; c++)
2152                                                 {
2153                                                         if (CPDF_FormControl* pFormCtrl = pFormField->GetControl(c))
2154                                                         {
2155                                                                 if (pFormCtrl->IsChecked())
2156                                                                 {
2157                                                                         dTemp += ParseStringToNumber(pFormCtrl->GetExportValue().c_str());
2158                                                                         break;
2159                                                                 }
2160                                                                 else
2161                                                                         continue;
2162                                                         }
2163                                                 }
2164                                                 break;
2165                                         }
2166                                 case FIELDTYPE_LISTBOX:
2167                                         {
2168                                                 dTemp = 0.0;
2169                                                 if (pFormField->CountSelectedItems() > 1)
2170                                                         break;
2171                                                 else
2172                                                 {
2173                                                         dTemp = ParseStringToNumber(pFormField->GetValue().c_str());
2174                                                         break;
2175                                                 }
2176                                         }
2177                                 default:
2178                                         break;
2179                                 }
2180
2181                                 if (i == 0 && j == 0 && (wcscmp(sFunction.c_str(), L"MIN") == 0 || wcscmp(sFunction.c_str(), L"MAX") == 0))
2182                                         dValue = dTemp;
2183
2184                                 dValue = AF_Simple(sFunction.c_str(), dValue, dTemp);
2185
2186                                 nFieldsCount++;
2187                         }
2188                 }
2189         }
2190
2191         if (wcscmp(sFunction.c_str(), L"AVG") == 0 && nFieldsCount > 0)
2192                 dValue /= nFieldsCount;
2193
2194         dValue = (double)floor(dValue * FXSYS_pow((double)10,(double)6) + 0.49) / FXSYS_pow((double)10,(double)6);
2195         CJS_Value jsValue(isolate,dValue);
2196         if((CJS_EventHandler*)pContext->GetEventHandler()->m_pValue)
2197                 ((CJS_EventHandler*)pContext->GetEventHandler())->Value() = jsValue.ToCFXWideString();
2198
2199         return TRUE;
2200 }
2201
2202 /* This function validates the current event to ensure that its value is 
2203 ** within the specified range. */
2204
2205 FX_BOOL CJS_PublicMethods::AFRange_Validate(IFXJS_Context* cc, const CJS_Parameters& params, CJS_Value& vRet, CFX_WideString& sError)
2206 {
2207         CJS_Context* pContext = (CJS_Context *)cc;
2208         ASSERT(pContext != NULL);
2209         CJS_EventHandler* pEvent = pContext->GetEventHandler();
2210         ASSERT(pEvent != NULL);
2211
2212         if (params.size() != 4) 
2213         {
2214                 sError = JSGetStringFromID(pContext, IDS_STRING_JSPARAMERROR);
2215                 return FALSE;
2216         }
2217
2218         if(!pEvent->m_pValue)
2219                 return FALSE;
2220         if (pEvent->Value().IsEmpty() )
2221                 return TRUE;
2222         double dEentValue = atof(CFX_ByteString::FromUnicode(pEvent->Value()));
2223         FX_BOOL bGreaterThan = params[0].ToBool();
2224         double dGreaterThan = params[1].ToDouble();
2225         FX_BOOL bLessThan = params[2].ToBool();
2226         double dLessThan = params[3].ToDouble();
2227         CFX_WideString swMsg;
2228
2229         if (bGreaterThan && bLessThan)
2230         {
2231                 if (dEentValue < dGreaterThan || dEentValue > dLessThan)
2232                         swMsg.Format(JSGetStringFromID(pContext, IDS_STRING_JSRANGE1).c_str(),
2233                                                  params[1].ToCFXWideString().c_str(),
2234                                                  params[3].ToCFXWideString().c_str());
2235         }
2236         else if (bGreaterThan)
2237         {
2238                 if (dEentValue < dGreaterThan)
2239                         swMsg.Format(JSGetStringFromID(pContext, IDS_STRING_JSRANGE2).c_str(),
2240                                                  params[1].ToCFXWideString().c_str());
2241         }
2242         else if (bLessThan)
2243         {
2244                 if (dEentValue > dLessThan)
2245                         swMsg.Format(JSGetStringFromID(pContext, IDS_STRING_JSRANGE3).c_str(),
2246                                                  params[3].ToCFXWideString().c_str());
2247         }
2248
2249         if (!swMsg.IsEmpty())
2250         {
2251                 Alert(pContext, swMsg.c_str());
2252                 pEvent->Rc() = FALSE;
2253         }
2254         return TRUE;
2255 }
2256
2257 FX_BOOL CJS_PublicMethods::AFExtractNums(IFXJS_Context* cc, const CJS_Parameters& params, CJS_Value& vRet, CFX_WideString& sError)
2258 {
2259         v8::Isolate* isolate = ::GetIsolate(cc);
2260         CJS_Context* pContext = (CJS_Context*)cc;
2261         ASSERT(pContext != NULL);
2262
2263         if (params.size() != 1) 
2264         {
2265                 sError = JSGetStringFromID(pContext, IDS_STRING_JSPARAMERROR);
2266                 return FALSE;
2267         }
2268
2269         CJS_Array nums(isolate);
2270
2271         CFX_WideString str = params[0].ToCFXWideString();
2272         CFX_WideString sPart;
2273
2274         if (str.GetAt(0) == L'.' || str.GetAt(0) == L',')
2275                 str = L"0" + str;
2276
2277         int nIndex = 0;
2278         for (int i=0, sz=str.GetLength(); i<sz; i++)
2279         {
2280                 FX_WCHAR wc = str.GetAt(i);
2281                 if (IsDigit((wchar_t)wc))
2282                 {
2283                         sPart += wc;
2284                 }
2285                 else
2286                 {
2287                         if (sPart.GetLength() > 0)
2288                         {
2289                                 nums.SetElement(nIndex,CJS_Value(isolate,sPart.c_str()));
2290                                 sPart = L"";
2291                                 nIndex ++;
2292                         }
2293                 }
2294         }
2295
2296         if (sPart.GetLength() > 0)
2297         {
2298                 nums.SetElement(nIndex,CJS_Value(isolate,sPart.c_str()));       
2299         }
2300
2301         if (nums.GetLength() > 0)
2302                 vRet = nums;
2303         else
2304                 vRet.SetNull();
2305
2306         return TRUE;
2307 }