PageRenderTime 161ms CodeModel.GetById 3ms app.highlight 138ms RepoModel.GetById 1ms app.codeStats 1ms

/fpdfsdk/src/javascript/PublicMethods.cpp

https://github.com/hunslater/pdfium
C++ | 2335 lines | 1952 code | 322 blank | 61 comment | 568 complexity | 14f9b37cb3cae786554e62184941a011 MD5 | raw file

Large files files are truncated, but you can click here to view the full file

   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
  22static 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
  38BEGIN_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)
  61END_JS_STATIC_GLOBAL_FUN()
  62
  63IMPLEMENT_JS_STATIC_GLOBAL_FUN(CJS_PublicMethods)
  64
  65struct stru_TbConvert
  66{
  67	FX_LPCSTR lpszJSMark;
  68	FX_LPCSTR lpszCppMark;
  69};
  70
  71static 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
  93static 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
  98static 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
 103FX_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
 151FX_BOOL CJS_PublicMethods::IsDigit(wchar_t ch)
 152{
 153	return (ch >= L'0' && ch <= L'9');
 154}
 155
 156FX_BOOL CJS_PublicMethods::IsDigit(char ch)
 157{
 158	return (ch >= '0' && ch <= '9');
 159}
 160
 161FX_BOOL CJS_PublicMethods::IsAlphabetic(wchar_t ch)
 162{
 163	return ((ch >= L'a' && ch <= L'z') || (ch >= L'A' && ch <= L'Z'));
 164}
 165
 166FX_BOOL CJS_PublicMethods::IsAlphaNumeric(wchar_t ch)
 167{
 168	return (IsDigit(ch) || IsAlphabetic(ch));
 169}
 170
 171FX_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
 188FX_BOOL CJS_PublicMethods::isReservedMaskChar(wchar_t ch)
 189{
 190	return ch == L'9' || ch == L'A' || ch == L'O' || ch == L'X';
 191}
 192
 193double 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
 215CFX_WideString CJS_PublicMethods::StrLTrim(FX_LPCWSTR pStr)
 216{
 217	while (*pStr && *pStr == L' ') pStr++;
 218
 219	return pStr;
 220}
 221
 222CFX_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
 237CFX_WideString CJS_PublicMethods::StrTrim(FX_LPCWSTR pStr)
 238{
 239	return StrRTrim(StrLTrim(pStr));
 240}
 241
 242CFX_ByteString CJS_PublicMethods::StrLTrim(FX_LPCSTR pStr)
 243{
 244	while (*pStr && *pStr == ' ') pStr++;
 245
 246    return pStr;
 247}
 248
 249CFX_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
 264CFX_ByteString CJS_PublicMethods::StrTrim(FX_LPCSTR pStr)
 265{
 266	return StrRTrim(StrLTrim(pStr));
 267}
 268
 269double 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
 415double 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
 425FX_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
 436CJS_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
 477int 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
 501CFX_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
 520double 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
 608double 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
 914CFX_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)
1063FX_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)
1272FX_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)
1404FX_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)
1523FX_BOOL CJS_PublicMethods::AFPercent_Keystroke(OBJ_METHOD_PARAMS)
1524{
1525	return AFNumber_Keystroke(cc,params,vRet,sError);
1526}
1527
1528//function AFDate_FormatEx(cFormat)
1529FX_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
1577double 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)
1638FX_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
1674FX_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)
1705FX_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)
1736FX_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
1763FX_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
1789FX_BOOL CJS_PublicMethods::AFTime_FormatEx(OBJ_METHOD_PARAMS)
1790{
1791	return AFDate_FormatEx(cc,params,vRet,sError);
1792}
1793
1794FX_BOOL CJS_PublicMethods::AFTime_KeystrokeEx(OBJ_METHOD_PARAMS)
1795{
1796	return AFDate_KeystrokeEx(cc,params,vRet,sError);
1797}
1798
1799//function AFSpecial_Format(psf)
1800FX_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)
1853FX_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)
1953FX_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
2012FX_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
2052FX_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
2082FX_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
2097FX_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
2111FX_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
2235FX_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_B

Large files files are truncated, but you can click here to view the full file