Home | History | Annotate | Download | only in javascript
      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 }
   2336