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