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