• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
GetIsolate(IFXJS_Context * cc)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 
IsNumber(FX_LPCWSTR string)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 
IsDigit(wchar_t ch)152 FX_BOOL CJS_PublicMethods::IsDigit(wchar_t ch)
153 {
154 	return (ch >= L'0' && ch <= L'9');
155 }
156 
IsDigit(char ch)157 FX_BOOL CJS_PublicMethods::IsDigit(char ch)
158 {
159 	return (ch >= '0' && ch <= '9');
160 }
161 
IsAlphabetic(wchar_t ch)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 
IsAlphaNumeric(wchar_t ch)167 FX_BOOL CJS_PublicMethods::IsAlphaNumeric(wchar_t ch)
168 {
169 	return (IsDigit(ch) || IsAlphabetic(ch));
170 }
171 
maskSatisfied(wchar_t c_Change,wchar_t c_Mask)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 
isReservedMaskChar(wchar_t ch)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 
AF_Simple(FX_LPCWSTR sFuction,double dValue1,double dValue2)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 
StrLTrim(FX_LPCWSTR pStr)216 CFX_WideString CJS_PublicMethods::StrLTrim(FX_LPCWSTR pStr)
217 {
218 	while (*pStr && *pStr == L' ') pStr++;
219 
220 	return pStr;
221 }
222 
StrRTrim(FX_LPCWSTR pStr)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 
StrTrim(FX_LPCWSTR pStr)232 CFX_WideString CJS_PublicMethods::StrTrim(FX_LPCWSTR pStr)
233 {
234 	return StrRTrim(StrLTrim(pStr).c_str());
235 }
236 
StrLTrim(FX_LPCSTR pStr)237 CFX_ByteString CJS_PublicMethods::StrLTrim(FX_LPCSTR pStr)
238 {
239 	while (*pStr && *pStr == ' ') pStr++;
240 
241         return pStr;
242 }
243 
StrRTrim(FX_LPCSTR pStr)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 
StrTrim(FX_LPCSTR pStr)253 CFX_ByteString CJS_PublicMethods::StrTrim(FX_LPCSTR pStr)
254 {
255 	return StrRTrim(StrLTrim(pStr));
256 }
257 
ParseNumber(FX_LPCWSTR swSource,FX_BOOL & bAllDigits,FX_BOOL & bDot,FX_BOOL & bSign,FX_BOOL & bKXJS)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 
ParseStringToNumber(FX_LPCWSTR swSource)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 
ConvertStringToNumber(FX_LPCWSTR swSource,double & dRet,FX_BOOL & bDot)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 
AF_MakeArrayFromList(v8::Isolate * isolate,CJS_Value val)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 
ParseStringInteger(const CFX_WideString & string,int nStart,int & nSkip,int nMaxStep)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 
ParseStringString(const CFX_WideString & string,int nStart,int & nSkip)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 
ParseNormalDate(const CFX_WideString & value,FX_BOOL & bWrongFormat)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 
MakeRegularDate(const CFX_WideString & value,const CFX_WideString & format,FX_BOOL & bWrongFormat)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 
MakeFormatDate(double dDate,const CFX_WideString & format)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)
AFNumber_Format(IFXJS_Context * cc,const CJS_Parameters & params,CJS_Value & vRet,CFX_WideString & sError)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)
AFNumber_Keystroke(IFXJS_Context * cc,const CJS_Parameters & params,CJS_Value & vRet,CFX_WideString & sError)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)
AFPercent_Format(IFXJS_Context * cc,const CJS_Parameters & params,CJS_Value & vRet,CFX_WideString & sError)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)
AFPercent_Keystroke(IFXJS_Context * cc,const CJS_Parameters & params,CJS_Value & vRet,CFX_WideString & sError)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)
AFDate_FormatEx(IFXJS_Context * cc,const CJS_Parameters & params,CJS_Value & vRet,CFX_WideString & sError)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 
MakeInterDate(CFX_WideString strValue)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)
AFDate_KeystrokeEx(IFXJS_Context * cc,const CJS_Parameters & params,CJS_Value & vRet,CFX_WideString & sError)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 
AFDate_Format(IFXJS_Context * cc,const CJS_Parameters & params,CJS_Value & vRet,CFX_WideString & sError)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)
AFDate_Keystroke(IFXJS_Context * cc,const CJS_Parameters & params,CJS_Value & vRet,CFX_WideString & sError)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)
AFTime_Format(IFXJS_Context * cc,const CJS_Parameters & params,CJS_Value & vRet,CFX_WideString & sError)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 
AFTime_Keystroke(IFXJS_Context * cc,const CJS_Parameters & params,CJS_Value & vRet,CFX_WideString & sError)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 
AFTime_FormatEx(IFXJS_Context * cc,const CJS_Parameters & params,CJS_Value & vRet,CFX_WideString & sError)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 
AFTime_KeystrokeEx(IFXJS_Context * cc,const CJS_Parameters & params,CJS_Value & vRet,CFX_WideString & sError)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)
AFSpecial_Format(IFXJS_Context * cc,const CJS_Parameters & params,CJS_Value & vRet,CFX_WideString & sError)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)
AFSpecial_KeystrokeEx(IFXJS_Context * cc,const CJS_Parameters & params,CJS_Value & vRet,CFX_WideString & sError)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)
AFSpecial_Keystroke(IFXJS_Context * cc,const CJS_Parameters & params,CJS_Value & vRet,CFX_WideString & sError)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 
AFMergeChange(IFXJS_Context * cc,const CJS_Parameters & params,CJS_Value & vRet,CFX_WideString & sError)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 
AFParseDateEx(IFXJS_Context * cc,const CJS_Parameters & params,CJS_Value & vRet,CFX_WideString & sError)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 
AFSimple(IFXJS_Context * cc,const CJS_Parameters & params,CJS_Value & vRet,CFX_WideString & sError)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 
AFMakeNumber(IFXJS_Context * cc,const CJS_Parameters & params,CJS_Value & vRet,CFX_WideString & sError)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 
AFSimple_Calculate(IFXJS_Context * cc,const CJS_Parameters & params,CJS_Value & vRet,CFX_WideString & sError)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 
AFRange_Validate(IFXJS_Context * cc,const CJS_Parameters & params,CJS_Value & vRet,CFX_WideString & sError)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 
AFExtractNums(IFXJS_Context * cc,const CJS_Parameters & params,CJS_Value & vRet,CFX_WideString & sError)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