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