blob: 094f3e7dd7e02dae390af11b143ab7e52881a065 [file] [log] [blame]
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07001// 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.
Lei Zhanga6d9f0e2015-06-13 00:48:38 -07004
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07005// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
6
Tom Sepez37458412015-10-06 11:33:46 -07007#include "PublicMethods.h"
8
Tom Sepez37458412015-10-06 11:33:46 -07009#include "Field.h"
10#include "JS_Context.h"
11#include "JS_Define.h"
12#include "JS_EventHandler.h"
13#include "JS_Object.h"
14#include "JS_Runtime.h"
15#include "JS_Value.h"
16#include "color.h"
Dan Sinclair10cfea12015-11-16 13:09:00 -050017#include "core/include/fxcrt/fx_ext.h"
Lei Zhangbde53d22015-11-12 22:21:30 -080018#include "fpdfsdk/include/fsdk_mgr.h" // For CPDFDoc_Environment.
19#include "fpdfsdk/include/javascript/IJavaScript.h"
Tom Sepez37458412015-10-06 11:33:46 -070020#include "resource.h"
21#include "util.h"
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -070022
Nico Weber9d8ec5a2015-08-04 13:00:21 -070023#define DOUBLE_CORRECT 0.000000000000001
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -070024
25BEGIN_JS_STATIC_GLOBAL_FUN(CJS_PublicMethods)
Nico Weber9d8ec5a2015-08-04 13:00:21 -070026JS_STATIC_GLOBAL_FUN_ENTRY(AFNumber_Format)
27JS_STATIC_GLOBAL_FUN_ENTRY(AFNumber_Keystroke)
28JS_STATIC_GLOBAL_FUN_ENTRY(AFPercent_Format)
29JS_STATIC_GLOBAL_FUN_ENTRY(AFPercent_Keystroke)
30JS_STATIC_GLOBAL_FUN_ENTRY(AFDate_FormatEx)
31JS_STATIC_GLOBAL_FUN_ENTRY(AFDate_KeystrokeEx)
32JS_STATIC_GLOBAL_FUN_ENTRY(AFDate_Format)
33JS_STATIC_GLOBAL_FUN_ENTRY(AFDate_Keystroke)
34JS_STATIC_GLOBAL_FUN_ENTRY(AFTime_FormatEx)
35JS_STATIC_GLOBAL_FUN_ENTRY(AFTime_KeystrokeEx)
36JS_STATIC_GLOBAL_FUN_ENTRY(AFTime_Format)
37JS_STATIC_GLOBAL_FUN_ENTRY(AFTime_Keystroke)
38JS_STATIC_GLOBAL_FUN_ENTRY(AFSpecial_Format)
39JS_STATIC_GLOBAL_FUN_ENTRY(AFSpecial_Keystroke)
40JS_STATIC_GLOBAL_FUN_ENTRY(AFSpecial_KeystrokeEx)
41JS_STATIC_GLOBAL_FUN_ENTRY(AFSimple)
42JS_STATIC_GLOBAL_FUN_ENTRY(AFMakeNumber)
43JS_STATIC_GLOBAL_FUN_ENTRY(AFSimple_Calculate)
44JS_STATIC_GLOBAL_FUN_ENTRY(AFRange_Validate)
45JS_STATIC_GLOBAL_FUN_ENTRY(AFMergeChange)
46JS_STATIC_GLOBAL_FUN_ENTRY(AFParseDateEx)
47JS_STATIC_GLOBAL_FUN_ENTRY(AFExtractNums)
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -070048END_JS_STATIC_GLOBAL_FUN()
49
50IMPLEMENT_JS_STATIC_GLOBAL_FUN(CJS_PublicMethods)
51
Tom Sepezdfbf8e72015-10-14 14:17:26 -070052static const FX_WCHAR* const months[] = {L"Jan",
53 L"Feb",
54 L"Mar",
55 L"Apr",
56 L"May",
57 L"Jun",
58 L"Jul",
59 L"Aug",
60 L"Sep",
61 L"Oct",
62 L"Nov",
63 L"Dec"};
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -070064
Tom Sepezc7e4c4f2015-11-20 09:45:24 -080065static const FX_WCHAR* const fullmonths[] = {L"January",
66 L"February",
67 L"March",
68 L"April",
69 L"May",
70 L"June",
71 L"July",
72 L"August",
73 L"September",
74 L"October",
75 L"November",
76 L"December"};
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -070077
Nico Weber9d8ec5a2015-08-04 13:00:21 -070078FX_BOOL CJS_PublicMethods::IsNumber(const FX_WCHAR* string) {
79 CFX_WideString sTrim = StrTrim(string);
80 const FX_WCHAR* pTrim = sTrim.c_str();
81 const FX_WCHAR* p = pTrim;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -070082
Nico Weber9d8ec5a2015-08-04 13:00:21 -070083 FX_BOOL bDot = FALSE;
84 FX_BOOL bKXJS = FALSE;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -070085
Nico Weber9d8ec5a2015-08-04 13:00:21 -070086 wchar_t c;
87 while ((c = *p)) {
88 if (c == '.' || c == ',') {
89 if (bDot)
90 return FALSE;
91 bDot = TRUE;
92 } else if (c == '-' || c == '+') {
93 if (p != pTrim)
94 return FALSE;
95 } else if (c == 'e' || c == 'E') {
96 if (bKXJS)
97 return FALSE;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -070098
Nico Weber9d8ec5a2015-08-04 13:00:21 -070099 p++;
100 c = *p;
101 if (c == '+' || c == '-') {
102 bKXJS = TRUE;
103 } else {
104 return FALSE;
105 }
106 } else if (!IsDigit(c)) {
107 return FALSE;
108 }
109 p++;
110 }
111
112 return TRUE;
113}
114
115FX_BOOL CJS_PublicMethods::IsDigit(wchar_t ch) {
116 return (ch >= L'0' && ch <= L'9');
117}
118
119FX_BOOL CJS_PublicMethods::IsDigit(char ch) {
Dan Sinclair10cfea12015-11-16 13:09:00 -0500120 return std::isdigit(ch);
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700121}
122
123FX_BOOL CJS_PublicMethods::IsAlphabetic(wchar_t ch) {
124 return ((ch >= L'a' && ch <= L'z') || (ch >= L'A' && ch <= L'Z'));
125}
126
127FX_BOOL CJS_PublicMethods::IsAlphaNumeric(wchar_t ch) {
128 return (IsDigit(ch) || IsAlphabetic(ch));
129}
130
131FX_BOOL CJS_PublicMethods::maskSatisfied(wchar_t c_Change, wchar_t c_Mask) {
132 switch (c_Mask) {
133 case L'9':
134 return IsDigit(c_Change);
135 case L'A':
136 return IsAlphabetic(c_Change);
137 case L'O':
138 return IsAlphaNumeric(c_Change);
139 case L'X':
140 return TRUE;
141 default:
142 return (c_Change == c_Mask);
143 }
144}
145
146FX_BOOL CJS_PublicMethods::isReservedMaskChar(wchar_t ch) {
147 return ch == L'9' || ch == L'A' || ch == L'O' || ch == L'X';
148}
149
150double CJS_PublicMethods::AF_Simple(const FX_WCHAR* sFuction,
151 double dValue1,
152 double dValue2) {
153 if (FXSYS_wcsicmp(sFuction, L"AVG") == 0 ||
154 FXSYS_wcsicmp(sFuction, L"SUM") == 0) {
155 return dValue1 + dValue2;
156 }
157 if (FXSYS_wcsicmp(sFuction, L"PRD") == 0) {
158 return dValue1 * dValue2;
159 }
160 if (FXSYS_wcsicmp(sFuction, L"MIN") == 0) {
161 return FX_MIN(dValue1, dValue2);
162 }
163 if (FXSYS_wcsicmp(sFuction, L"MAX") == 0) {
164 return FX_MAX(dValue1, dValue2);
165 }
166 return dValue1;
167}
168
169CFX_WideString CJS_PublicMethods::StrLTrim(const FX_WCHAR* pStr) {
170 while (*pStr && *pStr == L' ')
171 pStr++;
172
173 return pStr;
174}
175
176CFX_WideString CJS_PublicMethods::StrRTrim(const FX_WCHAR* pStr) {
177 const FX_WCHAR* p = pStr;
178 while (*p)
179 p++;
180 while (p > pStr && *(p - 1) == L' ')
181 p--;
182
183 return CFX_WideString(pStr, p - pStr);
184}
185
186CFX_WideString CJS_PublicMethods::StrTrim(const FX_WCHAR* pStr) {
187 return StrRTrim(StrLTrim(pStr).c_str());
188}
189
190CFX_ByteString CJS_PublicMethods::StrLTrim(const FX_CHAR* pStr) {
191 while (*pStr && *pStr == ' ')
192 pStr++;
193
194 return pStr;
195}
196
197CFX_ByteString CJS_PublicMethods::StrRTrim(const FX_CHAR* pStr) {
198 const FX_CHAR* p = pStr;
199 while (*p)
200 p++;
201 while (p > pStr && *(p - 1) == L' ')
202 p--;
203
204 return CFX_ByteString(pStr, p - pStr);
205}
206
207CFX_ByteString CJS_PublicMethods::StrTrim(const FX_CHAR* pStr) {
208 return StrRTrim(StrLTrim(pStr));
209}
210
211double CJS_PublicMethods::ParseNumber(const FX_WCHAR* swSource,
212 FX_BOOL& bAllDigits,
213 FX_BOOL& bDot,
214 FX_BOOL& bSign,
215 FX_BOOL& bKXJS) {
216 bDot = FALSE;
217 bSign = FALSE;
218 bKXJS = FALSE;
219
220 FX_BOOL bDigitExist = FALSE;
221
222 const FX_WCHAR* p = swSource;
223 wchar_t c;
224
225 const FX_WCHAR* pStart = NULL;
226 const FX_WCHAR* pEnd = NULL;
227
228 while ((c = *p)) {
229 if (!pStart && c != L' ') {
230 pStart = p;
231 }
232
233 pEnd = p;
234 p++;
235 }
236
237 if (!pStart) {
238 bAllDigits = FALSE;
239 return 0;
240 }
241
242 while (pEnd != pStart) {
243 if (*pEnd == L' ')
244 pEnd--;
245 else
246 break;
247 }
248
249 double dRet = 0;
250 p = pStart;
251 bAllDigits = TRUE;
252 CFX_WideString swDigits;
253
254 while (p <= pEnd) {
255 c = *p;
256
257 if (IsDigit(c)) {
258 swDigits += c;
259 bDigitExist = TRUE;
260 } else {
261 switch (c) {
262 case L' ':
263 bAllDigits = FALSE;
264 break;
265 case L'.':
266 case L',':
267 if (!bDot) {
268 if (bDigitExist) {
269 swDigits += L'.';
270 } else {
271 swDigits += L'0';
272 swDigits += L'.';
273 bDigitExist = TRUE;
274 }
275
Tom Sepez2f2ffec2015-07-23 14:42:09 -0700276 bDot = TRUE;
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700277 break;
278 }
279 case 'e':
280 case 'E':
281 if (!bKXJS) {
Tom Sepez2f2ffec2015-07-23 14:42:09 -0700282 p++;
283 c = *p;
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700284 if (c == '+' || c == '-') {
285 bKXJS = TRUE;
286 swDigits += 'e';
287 swDigits += c;
Tom Sepez2f2ffec2015-07-23 14:42:09 -0700288 }
Tom Sepez2f2ffec2015-07-23 14:42:09 -0700289 break;
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700290 }
291 case L'-':
292 if (!bDigitExist && !bSign) {
Tom Sepez2f2ffec2015-07-23 14:42:09 -0700293 swDigits += c;
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700294 bSign = TRUE;
Tom Sepez2f2ffec2015-07-23 14:42:09 -0700295 break;
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700296 }
297 default:
298 bAllDigits = FALSE;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700299
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700300 if (p != pStart && !bDot && bDigitExist) {
301 swDigits += L'.';
302 bDot = TRUE;
303 } else {
304 bDot = FALSE;
305 bDigitExist = FALSE;
306 swDigits = L"";
307 }
308 break;
309 }
Tom Sepez2f2ffec2015-07-23 14:42:09 -0700310 }
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700311
312 p++;
313 }
314
315 if (swDigits.GetLength() > 0 && swDigits.GetLength() < 17) {
316 CFX_ByteString sDigits = swDigits.UTF8Encode();
317
318 if (bKXJS) {
319 dRet = atof(sDigits);
320 } else {
321 if (bDot) {
322 char* pStopString;
323 dRet = ::strtod(sDigits, &pStopString);
324 } else {
325 dRet = atol(sDigits);
326 }
327 }
328 }
329
330 return dRet;
331}
332
333double CJS_PublicMethods::ParseStringToNumber(const FX_WCHAR* swSource) {
334 FX_BOOL bAllDigits = FALSE;
335 FX_BOOL bDot = FALSE;
336 FX_BOOL bSign = FALSE;
337 FX_BOOL bKXJS = FALSE;
338
339 return ParseNumber(swSource, bAllDigits, bDot, bSign, bKXJS);
340}
341
342FX_BOOL CJS_PublicMethods::ConvertStringToNumber(const FX_WCHAR* swSource,
343 double& dRet,
344 FX_BOOL& bDot) {
345 FX_BOOL bAllDigits = FALSE;
346 FX_BOOL bSign = FALSE;
347 FX_BOOL bKXJS = FALSE;
348
349 dRet = ParseNumber(swSource, bAllDigits, bDot, bSign, bKXJS);
350
351 return bAllDigits;
352}
353
Tom Sepez67fd5df2015-10-08 12:24:19 -0700354CJS_Array CJS_PublicMethods::AF_MakeArrayFromList(CJS_Runtime* pRuntime,
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700355 CJS_Value val) {
Tom Sepez67fd5df2015-10-08 12:24:19 -0700356 CJS_Array StrArray(pRuntime);
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700357 if (val.IsArrayObject()) {
358 val.ConvertToArray(StrArray);
Tom Sepez2f2ffec2015-07-23 14:42:09 -0700359 return StrArray;
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700360 }
361 CFX_WideString wsStr = val.ToCFXWideString();
362 CFX_ByteString t = CFX_ByteString::FromUnicode(wsStr);
363 const char* p = (const char*)t;
364
365 int ch = ',';
366 int nIndex = 0;
367
368 while (*p) {
369 const char* pTemp = strchr(p, ch);
Lei Zhang997de612015-11-04 18:17:53 -0800370 if (!pTemp) {
Tom Sepez67fd5df2015-10-08 12:24:19 -0700371 StrArray.SetElement(nIndex, CJS_Value(pRuntime, StrTrim(p).c_str()));
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700372 break;
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700373 }
Lei Zhang997de612015-11-04 18:17:53 -0800374
375 char* pSub = new char[pTemp - p + 1];
376 strncpy(pSub, p, pTemp - p);
377 *(pSub + (pTemp - p)) = '\0';
378
379 StrArray.SetElement(nIndex, CJS_Value(pRuntime, StrTrim(pSub).c_str()));
380 delete[] pSub;
381
382 nIndex++;
383 p = ++pTemp;
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700384 }
385 return StrArray;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700386}
387
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700388int CJS_PublicMethods::ParseStringInteger(const CFX_WideString& string,
389 int nStart,
390 int& nSkip,
391 int nMaxStep) {
392 int nRet = 0;
393 nSkip = 0;
394 for (int i = nStart, sz = string.GetLength(); i < sz; i++) {
395 if (i - nStart > 10)
396 break;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700397
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700398 FX_WCHAR c = string.GetAt(i);
399 if (IsDigit((wchar_t)c)) {
Dan Sinclair10cfea12015-11-16 13:09:00 -0500400 nRet = nRet * 10 + FXSYS_toDecimalDigitWide(c);
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700401 nSkip = i - nStart + 1;
402 if (nSkip >= nMaxStep)
403 break;
404 } else
405 break;
406 }
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700407
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700408 return nRet;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700409}
410
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700411CFX_WideString CJS_PublicMethods::ParseStringString(
412 const CFX_WideString& string,
413 int nStart,
414 int& nSkip) {
415 CFX_WideString swRet;
416 nSkip = 0;
417 for (int i = nStart, sz = string.GetLength(); i < sz; i++) {
418 FX_WCHAR c = string.GetAt(i);
419 if ((c >= L'a' && c <= L'z') || (c >= L'A' && c <= L'Z')) {
420 swRet += c;
421 nSkip = i - nStart + 1;
422 } else
423 break;
424 }
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700425
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700426 return swRet;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700427}
428
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700429double CJS_PublicMethods::ParseNormalDate(const CFX_WideString& value,
430 FX_BOOL& bWrongFormat) {
431 double dt = JS_GetDateTime();
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700432
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700433 int nYear = JS_GetYearFromTime(dt);
434 int nMonth = JS_GetMonthFromTime(dt) + 1;
435 int nDay = JS_GetDayFromTime(dt);
436 int nHour = JS_GetHourFromTime(dt);
437 int nMin = JS_GetMinFromTime(dt);
438 int nSec = JS_GetSecFromTime(dt);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700439
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700440 int number[3];
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700441
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700442 int nSkip = 0;
443 int nLen = value.GetLength();
444 int nIndex = 0;
445 int i = 0;
446 while (i < nLen) {
447 if (nIndex > 2)
448 break;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700449
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700450 FX_WCHAR c = value.GetAt(i);
451 if (IsDigit((wchar_t)c)) {
452 number[nIndex++] = ParseStringInteger(value, i, nSkip, 4);
453 i += nSkip;
454 } else {
455 i++;
456 }
457 }
458
459 if (nIndex == 2) {
460 // case2: month/day
461 // case3: day/month
462 if ((number[0] >= 1 && number[0] <= 12) &&
463 (number[1] >= 1 && number[1] <= 31)) {
464 nMonth = number[0];
465 nDay = number[1];
466 } else if ((number[0] >= 1 && number[0] <= 31) &&
467 (number[1] >= 1 && number[1] <= 12)) {
468 nDay = number[0];
469 nMonth = number[1];
Tom Sepez2f2ffec2015-07-23 14:42:09 -0700470 }
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700471
Tom Sepez2f2ffec2015-07-23 14:42:09 -0700472 bWrongFormat = FALSE;
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700473 } else if (nIndex == 3) {
474 // case1: year/month/day
475 // case2: month/day/year
476 // case3: day/month/year
Tom Sepez5ffacd62014-07-18 14:42:12 -0700477
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700478 if (number[0] > 12 && (number[1] >= 1 && number[1] <= 12) &&
479 (number[2] >= 1 && number[2] <= 31)) {
480 nYear = number[0];
481 nMonth = number[1];
482 nDay = number[2];
483 } else if ((number[0] >= 1 && number[0] <= 12) &&
484 (number[1] >= 1 && number[1] <= 31) && number[2] > 31) {
485 nMonth = number[0];
486 nDay = number[1];
487 nYear = number[2];
488 } else if ((number[0] >= 1 && number[0] <= 31) &&
489 (number[1] >= 1 && number[1] <= 12) && number[2] > 31) {
490 nDay = number[0];
491 nMonth = number[1];
492 nYear = number[2];
Tom Sepez2f2ffec2015-07-23 14:42:09 -0700493 }
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700494
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700495 bWrongFormat = FALSE;
496 } else {
497 bWrongFormat = TRUE;
498 return dt;
499 }
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700500
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700501 CFX_WideString swTemp;
502 swTemp.Format(L"%d/%d/%d %d:%d:%d", nMonth, nDay, nYear, nHour, nMin, nSec);
503 return JS_DateParse(swTemp.c_str());
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700504}
505
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700506double CJS_PublicMethods::MakeRegularDate(const CFX_WideString& value,
507 const CFX_WideString& format,
508 FX_BOOL& bWrongFormat) {
509 double dt = JS_GetDateTime();
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700510
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700511 if (format.IsEmpty() || value.IsEmpty())
512 return dt;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700513
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700514 int nYear = JS_GetYearFromTime(dt);
515 int nMonth = JS_GetMonthFromTime(dt) + 1;
516 int nDay = JS_GetDayFromTime(dt);
517 int nHour = JS_GetHourFromTime(dt);
518 int nMin = JS_GetMinFromTime(dt);
519 int nSec = JS_GetSecFromTime(dt);
520
521 int nYearSub = 99; // nYear - 2000;
522
523 FX_BOOL bPm = FALSE;
524 FX_BOOL bExit = FALSE;
525 bWrongFormat = FALSE;
526
527 int i = 0;
528 int j = 0;
529
530 while (i < format.GetLength()) {
531 if (bExit)
532 break;
533
534 FX_WCHAR c = format.GetAt(i);
535 switch (c) {
536 case ':':
537 case '.':
538 case '-':
539 case '\\':
540 case '/':
541 i++;
542 j++;
543 break;
544
545 case 'y':
546 case 'm':
547 case 'd':
548 case 'H':
549 case 'h':
550 case 'M':
551 case 's':
552 case 't': {
553 int oldj = j;
554 int nSkip = 0;
555 int remaining = format.GetLength() - i - 1;
556
557 if (remaining == 0 || format.GetAt(i + 1) != c) {
558 switch (c) {
Tom Sepez2f2ffec2015-07-23 14:42:09 -0700559 case 'y':
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700560 i++;
561 j++;
562 break;
Tom Sepez2f2ffec2015-07-23 14:42:09 -0700563 case 'm':
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700564 nMonth = ParseStringInteger(value, j, nSkip, 2);
565 i++;
566 j += nSkip;
567 break;
Tom Sepez2f2ffec2015-07-23 14:42:09 -0700568 case 'd':
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700569 nDay = ParseStringInteger(value, j, nSkip, 2);
570 i++;
571 j += nSkip;
572 break;
Tom Sepez2f2ffec2015-07-23 14:42:09 -0700573 case 'H':
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700574 nHour = ParseStringInteger(value, j, nSkip, 2);
575 i++;
576 j += nSkip;
577 break;
Tom Sepez2f2ffec2015-07-23 14:42:09 -0700578 case 'h':
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700579 nHour = ParseStringInteger(value, j, nSkip, 2);
580 i++;
581 j += nSkip;
582 break;
Tom Sepez2f2ffec2015-07-23 14:42:09 -0700583 case 'M':
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700584 nMin = ParseStringInteger(value, j, nSkip, 2);
585 i++;
586 j += nSkip;
587 break;
Tom Sepez2f2ffec2015-07-23 14:42:09 -0700588 case 's':
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700589 nSec = ParseStringInteger(value, j, nSkip, 2);
590 i++;
591 j += nSkip;
592 break;
Tom Sepez2f2ffec2015-07-23 14:42:09 -0700593 case 't':
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700594 bPm = (j < value.GetLength() && value.GetAt(j) == 'p');
595 i++;
596 j++;
597 break;
598 }
599 } else if (remaining == 1 || format.GetAt(i + 2) != c) {
600 switch (c) {
601 case 'y':
602 nYear = ParseStringInteger(value, j, nSkip, 4);
603 i += 2;
604 j += nSkip;
605 break;
606 case 'm':
607 nMonth = ParseStringInteger(value, j, nSkip, 2);
608 i += 2;
609 j += nSkip;
610 break;
611 case 'd':
612 nDay = ParseStringInteger(value, j, nSkip, 2);
613 i += 2;
614 j += nSkip;
615 break;
616 case 'H':
617 nHour = ParseStringInteger(value, j, nSkip, 2);
618 i += 2;
619 j += nSkip;
620 break;
621 case 'h':
622 nHour = ParseStringInteger(value, j, nSkip, 2);
623 i += 2;
624 j += nSkip;
625 break;
626 case 'M':
627 nMin = ParseStringInteger(value, j, nSkip, 2);
628 i += 2;
629 j += nSkip;
630 break;
631 case 's':
632 nSec = ParseStringInteger(value, j, nSkip, 2);
633 i += 2;
634 j += nSkip;
635 break;
636 case 't':
637 bPm = (j + 1 < value.GetLength() && value.GetAt(j) == 'p' &&
638 value.GetAt(j + 1) == 'm');
639 i += 2;
640 j += 2;
641 break;
642 }
643 } else if (remaining == 2 || format.GetAt(i + 3) != c) {
644 switch (c) {
645 case 'm': {
646 CFX_WideString sMonth = ParseStringString(value, j, nSkip);
647 FX_BOOL bFind = FALSE;
648 for (int m = 0; m < 12; m++) {
649 if (sMonth.CompareNoCase(months[m]) == 0) {
650 nMonth = m + 1;
651 i += 3;
652 j += nSkip;
653 bFind = TRUE;
654 break;
Tom Sepez2f2ffec2015-07-23 14:42:09 -0700655 }
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700656 }
657
658 if (!bFind) {
659 nMonth = ParseStringInteger(value, j, nSkip, 3);
660 i += 3;
661 j += nSkip;
662 }
663 } break;
664 case 'y':
665 break;
Tom Sepez2f2ffec2015-07-23 14:42:09 -0700666 default:
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700667 i += 3;
668 j += 3;
669 break;
670 }
671 } else if (remaining == 3 || format.GetAt(i + 4) != c) {
672 switch (c) {
673 case 'y':
674 nYear = ParseStringInteger(value, j, nSkip, 4);
675 j += nSkip;
676 i += 4;
677 break;
678 case 'm': {
679 FX_BOOL bFind = FALSE;
680
681 CFX_WideString sMonth = ParseStringString(value, j, nSkip);
682 sMonth.MakeLower();
683
684 for (int m = 0; m < 12; m++) {
685 CFX_WideString sFullMonths = fullmonths[m];
686 sFullMonths.MakeLower();
687
688 if (sFullMonths.Find(sMonth.c_str(), 0) != -1) {
689 nMonth = m + 1;
690 i += 4;
691 j += nSkip;
692 bFind = TRUE;
693 break;
694 }
695 }
696
697 if (!bFind) {
698 nMonth = ParseStringInteger(value, j, nSkip, 4);
699 i += 4;
700 j += nSkip;
701 }
702 } break;
703 default:
704 i += 4;
705 j += 4;
706 break;
707 }
708 } else {
709 if (j >= value.GetLength() || format.GetAt(i) != value.GetAt(j)) {
710 bWrongFormat = TRUE;
711 bExit = TRUE;
712 }
713 i++;
714 j++;
Tom Sepez2f2ffec2015-07-23 14:42:09 -0700715 }
Tom Sepez85386422014-07-23 10:28:37 -0700716
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700717 if (oldj == j) {
718 bWrongFormat = TRUE;
719 bExit = TRUE;
720 }
721 }
722
723 break;
724 default:
725 if (value.GetLength() <= j) {
726 bExit = TRUE;
727 } else if (format.GetAt(i) != value.GetAt(j)) {
728 bWrongFormat = TRUE;
729 bExit = TRUE;
730 }
731
732 i++;
733 j++;
734 break;
735 }
736 }
737
738 if (bPm)
739 nHour += 12;
740
741 if (nYear >= 0 && nYear <= nYearSub)
742 nYear += 2000;
743
744 if (nMonth < 1 || nMonth > 12)
745 bWrongFormat = TRUE;
746
747 if (nDay < 1 || nDay > 31)
748 bWrongFormat = TRUE;
749
750 if (nHour < 0 || nHour > 24)
751 bWrongFormat = TRUE;
752
753 if (nMin < 0 || nMin > 60)
754 bWrongFormat = TRUE;
755
756 if (nSec < 0 || nSec > 60)
757 bWrongFormat = TRUE;
758
759 double dRet = 0;
760
761 if (bWrongFormat) {
762 dRet = ParseNormalDate(value, bWrongFormat);
763 } else {
764 dRet = JS_MakeDate(JS_MakeDay(nYear, nMonth - 1, nDay),
765 JS_MakeTime(nHour, nMin, nSec, 0));
766
767 if (JS_PortIsNan(dRet)) {
768 dRet = JS_DateParse(value.c_str());
769 }
770 }
771
772 if (JS_PortIsNan(dRet)) {
773 dRet = ParseNormalDate(value, bWrongFormat);
774 }
775
776 return dRet;
777}
778
779CFX_WideString CJS_PublicMethods::MakeFormatDate(double dDate,
780 const CFX_WideString& format) {
781 CFX_WideString sRet = L"", sPart = L"";
782
783 int nYear = JS_GetYearFromTime(dDate);
784 int nMonth = JS_GetMonthFromTime(dDate) + 1;
785 int nDay = JS_GetDayFromTime(dDate);
786 int nHour = JS_GetHourFromTime(dDate);
787 int nMin = JS_GetMinFromTime(dDate);
788 int nSec = JS_GetSecFromTime(dDate);
789
790 int i = 0;
791 while (i < format.GetLength()) {
792 FX_WCHAR c = format.GetAt(i);
793 int remaining = format.GetLength() - i - 1;
794 sPart = L"";
795 switch (c) {
796 case 'y':
797 case 'm':
798 case 'd':
799 case 'H':
800 case 'h':
801 case 'M':
802 case 's':
803 case 't':
804 if (remaining == 0 || format.GetAt(i + 1) != c) {
805 switch (c) {
806 case 'y':
807 sPart += c;
808 break;
809 case 'm':
810 sPart.Format(L"%d", nMonth);
811 break;
812 case 'd':
813 sPart.Format(L"%d", nDay);
814 break;
815 case 'H':
816 sPart.Format(L"%d", nHour);
817 break;
818 case 'h':
819 sPart.Format(L"%d", nHour > 12 ? nHour - 12 : nHour);
820 break;
821 case 'M':
822 sPart.Format(L"%d", nMin);
823 break;
824 case 's':
825 sPart.Format(L"%d", nSec);
826 break;
827 case 't':
828 sPart += nHour > 12 ? 'p' : 'a';
829 break;
830 }
831 i++;
832 } else if (remaining == 1 || format.GetAt(i + 2) != c) {
833 switch (c) {
834 case 'y':
835 sPart.Format(L"%02d", nYear - (nYear / 100) * 100);
836 break;
837 case 'm':
838 sPart.Format(L"%02d", nMonth);
839 break;
840 case 'd':
841 sPart.Format(L"%02d", nDay);
842 break;
843 case 'H':
844 sPart.Format(L"%02d", nHour);
845 break;
846 case 'h':
847 sPart.Format(L"%02d", nHour > 12 ? nHour - 12 : nHour);
848 break;
849 case 'M':
850 sPart.Format(L"%02d", nMin);
851 break;
852 case 's':
853 sPart.Format(L"%02d", nSec);
854 break;
855 case 't':
856 sPart = nHour > 12 ? L"pm" : L"am";
857 break;
858 }
859 i += 2;
860 } else if (remaining == 2 || format.GetAt(i + 3) != c) {
861 switch (c) {
862 case 'm':
863 i += 3;
864 if (nMonth > 0 && nMonth <= 12)
865 sPart += months[nMonth - 1];
866 break;
867 default:
868 i += 3;
869 sPart += c;
870 sPart += c;
871 sPart += c;
872 break;
873 }
874 } else if (remaining == 3 || format.GetAt(i + 4) != c) {
875 switch (c) {
876 case 'y':
877 sPart.Format(L"%04d", nYear);
878 i += 4;
879 break;
880 case 'm':
881 i += 4;
882 if (nMonth > 0 && nMonth <= 12)
883 sPart += fullmonths[nMonth - 1];
884 break;
885 default:
886 i += 4;
887 sPart += c;
888 sPart += c;
889 sPart += c;
890 sPart += c;
891 break;
892 }
893 } else {
894 i++;
895 sPart += c;
896 }
897 break;
898 default:
899 i++;
900 sPart += c;
901 break;
Tom Sepez2f2ffec2015-07-23 14:42:09 -0700902 }
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700903
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700904 sRet += sPart;
905 }
906
907 return sRet;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700908}
909
910/* -------------------------------------------------------------------------- */
911
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700912// function AFNumber_Format(nDec, sepStyle, negStyle, currStyle, strCurrency,
913// bCurrencyPrepend)
Tom Sepezba038bc2015-10-08 12:03:00 -0700914FX_BOOL CJS_PublicMethods::AFNumber_Format(IJS_Context* cc,
Lei Zhang945fdb72015-11-11 10:18:16 -0800915 const std::vector<CJS_Value>& params,
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700916 CJS_Value& vRet,
917 CFX_WideString& sError) {
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700918#if _FX_OS_ != _FX_ANDROID_
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700919 CJS_Context* pContext = (CJS_Context*)cc;
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700920 if (params.size() != 6) {
921 sError = JSGetStringFromID(pContext, IDS_STRING_JSPARAMERROR);
922 return FALSE;
923 }
Tom Sepez67fd5df2015-10-08 12:24:19 -0700924
925 CJS_Runtime* pRuntime = CJS_Runtime::FromContext(cc);
926 CJS_EventHandler* pEvent = pContext->GetEventHandler();
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700927 if (!pEvent->m_pValue)
928 return FALSE;
Tom Sepez67fd5df2015-10-08 12:24:19 -0700929
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700930 CFX_WideString& Value = pEvent->Value();
931 CFX_ByteString strValue = StrTrim(CFX_ByteString::FromUnicode(Value));
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700932 if (strValue.IsEmpty())
Tom Sepez2f2ffec2015-07-23 14:42:09 -0700933 return TRUE;
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700934
935 int iDec = params[0].ToInt();
936 int iSepStyle = params[1].ToInt();
937 int iNegStyle = params[2].ToInt();
938 // params[3] is iCurrStyle, it's not used.
939 std::wstring wstrCurrency(params[4].ToCFXWideString().c_str());
940 FX_BOOL bCurrencyPrepend = params[5].ToBool();
941
942 if (iDec < 0)
943 iDec = -iDec;
944
945 if (iSepStyle < 0 || iSepStyle > 3)
946 iSepStyle = 0;
947
948 if (iNegStyle < 0 || iNegStyle > 3)
949 iNegStyle = 0;
950
951 //////////////////////////////////////////////////////
952 // for processing decimal places
953 strValue.Replace(",", ".");
954 double dValue = atof(strValue);
955 if (iDec > 0)
Tom Sepezdfbf8e72015-10-14 14:17:26 -0700956 dValue += DOUBLE_CORRECT;
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700957
958 int iDec2;
959 int iNegative = 0;
960
961 strValue = fcvt(dValue, iDec, &iDec2, &iNegative);
962 if (strValue.IsEmpty()) {
963 dValue = 0;
964 strValue = fcvt(dValue, iDec, &iDec2, &iNegative);
965 if (strValue.IsEmpty()) {
966 strValue = "0";
967 iDec2 = 1;
968 }
969 }
970
971 if (iDec2 < 0) {
972 for (int iNum = 0; iNum < abs(iDec2); iNum++) {
973 strValue = "0" + strValue;
974 }
975 iDec2 = 0;
976 }
977 int iMax = strValue.GetLength();
978 if (iDec2 > iMax) {
979 for (int iNum = 0; iNum <= iDec2 - iMax; iNum++) {
980 strValue += "0";
981 }
982 iMax = iDec2 + 1;
983 }
984 ///////////////////////////////////////////////////////
985 // for processing seperator style
986 if (iDec2 < iMax) {
987 if (iSepStyle == 0 || iSepStyle == 1) {
988 strValue.Insert(iDec2, '.');
989 iMax++;
990 } else if (iSepStyle == 2 || iSepStyle == 3) {
991 strValue.Insert(iDec2, ',');
992 iMax++;
993 }
994
995 if (iDec2 == 0)
996 strValue.Insert(iDec2, '0');
997 }
998 if (iSepStyle == 0 || iSepStyle == 2) {
999 char cSeperator;
1000 if (iSepStyle == 0)
1001 cSeperator = ',';
1002 else
1003 cSeperator = '.';
1004
Tom Sepezdfbf8e72015-10-14 14:17:26 -07001005 for (int iDecPositive = iDec2 - 3; iDecPositive > 0; iDecPositive -= 3) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001006 strValue.Insert(iDecPositive, cSeperator);
1007 iMax++;
1008 }
1009 }
1010
1011 //////////////////////////////////////////////////////////////////////
1012 // for processing currency string
1013
1014 Value = CFX_WideString::FromLocal(strValue);
1015 std::wstring strValue2 = Value.c_str();
1016
1017 if (bCurrencyPrepend)
1018 strValue2 = wstrCurrency + strValue2;
1019 else
1020 strValue2 = strValue2 + wstrCurrency;
1021
1022 /////////////////////////////////////////////////////////////////////////
1023 // for processing negative style
1024 if (iNegative) {
1025 if (iNegStyle == 0) {
1026 strValue2.insert(0, L"-");
1027 }
1028 if (iNegStyle == 2 || iNegStyle == 3) {
1029 strValue2.insert(0, L"(");
1030 strValue2.insert(strValue2.length(), L")");
1031 }
1032 if (iNegStyle == 1 || iNegStyle == 3) {
1033 if (Field* fTarget = pEvent->Target_Field()) {
Tom Sepez67fd5df2015-10-08 12:24:19 -07001034 CJS_Array arColor(pRuntime);
1035 CJS_Value vColElm(pRuntime);
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001036 vColElm = L"RGB";
1037 arColor.SetElement(0, vColElm);
1038 vColElm = 1;
1039 arColor.SetElement(1, vColElm);
1040 vColElm = 0;
1041 arColor.SetElement(2, vColElm);
1042
1043 arColor.SetElement(3, vColElm);
1044
Tom Sepez67fd5df2015-10-08 12:24:19 -07001045 CJS_PropValue vProp(pRuntime);
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001046 vProp.StartGetting();
1047 vProp << arColor;
1048 vProp.StartSetting();
1049 fTarget->textColor(cc, vProp, sError); // red
1050 }
1051 }
1052 } else {
1053 if (iNegStyle == 1 || iNegStyle == 3) {
1054 if (Field* fTarget = pEvent->Target_Field()) {
Tom Sepez67fd5df2015-10-08 12:24:19 -07001055 CJS_Array arColor(pRuntime);
1056 CJS_Value vColElm(pRuntime);
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001057 vColElm = L"RGB";
1058 arColor.SetElement(0, vColElm);
1059 vColElm = 0;
1060 arColor.SetElement(1, vColElm);
1061 arColor.SetElement(2, vColElm);
1062 arColor.SetElement(3, vColElm);
1063
Tom Sepez67fd5df2015-10-08 12:24:19 -07001064 CJS_PropValue vProp(pRuntime);
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001065 vProp.StartGetting();
1066 fTarget->textColor(cc, vProp, sError);
1067
Tom Sepez67fd5df2015-10-08 12:24:19 -07001068 CJS_Array aProp(pRuntime);
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001069 vProp.ConvertToArray(aProp);
1070
1071 CPWL_Color crProp;
1072 CPWL_Color crColor;
1073 color::ConvertArrayToPWLColor(aProp, crProp);
1074 color::ConvertArrayToPWLColor(arColor, crColor);
1075
1076 if (crColor != crProp) {
Tom Sepez67fd5df2015-10-08 12:24:19 -07001077 CJS_PropValue vProp2(pRuntime);
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001078 vProp2.StartGetting();
1079 vProp2 << arColor;
1080 vProp2.StartSetting();
1081 fTarget->textColor(cc, vProp2, sError);
1082 }
1083 }
1084 }
1085 }
1086 Value = strValue2.c_str();
1087#endif
1088 return TRUE;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07001089}
1090
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001091// function AFNumber_Keystroke(nDec, sepStyle, negStyle, currStyle, strCurrency,
1092// bCurrencyPrepend)
Lei Zhang945fdb72015-11-11 10:18:16 -08001093FX_BOOL CJS_PublicMethods::AFNumber_Keystroke(
1094 IJS_Context* cc,
1095 const std::vector<CJS_Value>& params,
1096 CJS_Value& vRet,
1097 CFX_WideString& sError) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001098 CJS_Context* pContext = (CJS_Context*)cc;
1099 ASSERT(pContext != NULL);
1100 CJS_EventHandler* pEvent = pContext->GetEventHandler();
1101 ASSERT(pEvent != NULL);
Lei Zhanga6d9f0e2015-06-13 00:48:38 -07001102
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001103 if (params.size() < 2)
1104 return FALSE;
1105 int iSepStyle = params[1].ToInt();
Lei Zhanga6d9f0e2015-06-13 00:48:38 -07001106
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001107 if (iSepStyle < 0 || iSepStyle > 3)
1108 iSepStyle = 0;
1109 if (!pEvent->m_pValue)
1110 return FALSE;
1111 CFX_WideString& val = pEvent->Value();
1112 CFX_WideString& w_strChange = pEvent->Change();
1113 CFX_WideString w_strValue = val;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07001114
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001115 if (pEvent->WillCommit()) {
1116 CFX_WideString wstrChange = w_strChange;
1117 CFX_WideString wstrValue = StrLTrim(w_strValue.c_str());
1118 if (wstrValue.IsEmpty())
1119 return TRUE;
Lei Zhanga6d9f0e2015-06-13 00:48:38 -07001120
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001121 CFX_WideString swTemp = wstrValue;
1122 swTemp.Replace(L",", L".");
1123 if (!IsNumber(swTemp.c_str())) {
1124 pEvent->Rc() = FALSE;
1125 sError = JSGetStringFromID(pContext, IDS_STRING_JSAFNUMBER_KEYSTROKE);
1126 Alert(pContext, sError.c_str());
1127 return TRUE;
Tom Sepez2f2ffec2015-07-23 14:42:09 -07001128 }
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001129 return TRUE; // it happens after the last keystroke and before validating,
1130 }
Tom Sepez4f7bc042015-04-27 12:06:58 -07001131
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001132 std::wstring w_strValue2 = w_strValue.c_str();
1133 std::wstring w_strChange2 = w_strChange.c_str();
1134 std::wstring w_strSelected;
1135 if (-1 != pEvent->SelStart())
1136 w_strSelected = w_strValue2.substr(pEvent->SelStart(),
1137 (pEvent->SelEnd() - pEvent->SelStart()));
Lei Zhangb9c31972015-08-11 14:09:35 -07001138 bool bHasSign = (w_strValue2.find('-') != std::wstring::npos) &&
1139 (w_strSelected.find('-') == std::wstring::npos);
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001140 if (bHasSign) {
1141 // can't insert "change" in front to sign postion.
1142 if (pEvent->SelStart() == 0) {
1143 FX_BOOL& bRc = pEvent->Rc();
1144 bRc = FALSE;
1145 return TRUE;
Tom Sepez2f2ffec2015-07-23 14:42:09 -07001146 }
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001147 }
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07001148
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001149 char cSep = L'.';
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07001150
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001151 switch (iSepStyle) {
Tom Sepez2f2ffec2015-07-23 14:42:09 -07001152 case 0:
1153 case 1:
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001154 cSep = L'.';
1155 break;
Tom Sepez2f2ffec2015-07-23 14:42:09 -07001156 case 2:
1157 case 3:
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001158 cSep = L',';
1159 break;
1160 }
Lei Zhanga6d9f0e2015-06-13 00:48:38 -07001161
Lei Zhangb9c31972015-08-11 14:09:35 -07001162 bool bHasSep = (w_strValue2.find(cSep) != std::wstring::npos);
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001163 for (std::wstring::iterator it = w_strChange2.begin();
1164 it != w_strChange2.end(); it++) {
1165 if (*it == cSep) {
1166 if (bHasSep) {
1167 FX_BOOL& bRc = pEvent->Rc();
1168 bRc = FALSE;
Tom Sepez2f2ffec2015-07-23 14:42:09 -07001169 return TRUE;
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001170 }
1171 bHasSep = TRUE;
1172 continue;
1173 }
1174 if (*it == L'-') {
1175 if (bHasSign) {
1176 FX_BOOL& bRc = pEvent->Rc();
1177 bRc = FALSE;
1178 return TRUE;
1179 }
1180 if (it != w_strChange2.begin()) // sign's position is not correct
1181 {
1182 FX_BOOL& bRc = pEvent->Rc();
1183 bRc = FALSE;
1184 return TRUE;
1185 }
1186 if (pEvent->SelStart() != 0) {
1187 FX_BOOL& bRc = pEvent->Rc();
1188 bRc = FALSE;
1189 return TRUE;
1190 }
1191 bHasSign = TRUE;
1192 continue;
1193 }
1194
1195 if (!IsDigit(*it)) {
1196 FX_BOOL& bRc = pEvent->Rc();
1197 bRc = FALSE;
1198 return TRUE;
1199 }
1200 }
1201
1202 std::wstring w_prefix = w_strValue2.substr(0, pEvent->SelStart());
1203 std::wstring w_postfix;
1204 if (pEvent->SelEnd() < (int)w_strValue2.length())
1205 w_postfix = w_strValue2.substr(pEvent->SelEnd());
1206 w_strValue2 = w_prefix + w_strChange2 + w_postfix;
1207 w_strValue = w_strValue2.c_str();
1208 val = w_strValue;
1209 return TRUE;
1210}
1211
1212// function AFPercent_Format(nDec, sepStyle)
Lei Zhang945fdb72015-11-11 10:18:16 -08001213FX_BOOL CJS_PublicMethods::AFPercent_Format(
1214 IJS_Context* cc,
1215 const std::vector<CJS_Value>& params,
1216 CJS_Value& vRet,
1217 CFX_WideString& sError) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001218#if _FX_OS_ != _FX_ANDROID_
1219 CJS_Context* pContext = (CJS_Context*)cc;
1220 ASSERT(pContext != NULL);
1221 CJS_EventHandler* pEvent = pContext->GetEventHandler();
1222 ASSERT(pEvent != NULL);
1223
1224 if (params.size() != 2) {
1225 sError = JSGetStringFromID(pContext, IDS_STRING_JSPARAMERROR);
1226 return FALSE;
1227 }
1228 if (!pEvent->m_pValue)
1229 return FALSE;
1230
1231 CFX_WideString& Value = pEvent->Value();
1232 CFX_ByteString strValue = StrTrim(CFX_ByteString::FromUnicode(Value));
1233 if (strValue.IsEmpty())
1234 return TRUE;
1235
1236 int iDec = params[0].ToInt();
1237 if (iDec < 0)
1238 iDec = -iDec;
1239
1240 int iSepStyle = params[1].ToInt();
1241 if (iSepStyle < 0 || iSepStyle > 3)
1242 iSepStyle = 0;
1243
1244 //////////////////////////////////////////////////////
1245 // for processing decimal places
1246 double dValue = atof(strValue);
1247 dValue *= 100;
1248 if (iDec > 0)
1249 dValue += DOUBLE_CORRECT; //УÕý
1250
1251 int iDec2;
1252 int iNegative = 0;
1253 strValue = fcvt(dValue, iDec, &iDec2, &iNegative);
1254 if (strValue.IsEmpty()) {
1255 dValue = 0;
1256 strValue = fcvt(dValue, iDec, &iDec2, &iNegative);
1257 }
1258
1259 if (iDec2 < 0) {
1260 for (int iNum = 0; iNum < abs(iDec2); iNum++) {
1261 strValue = "0" + strValue;
1262 }
1263 iDec2 = 0;
1264 }
1265 int iMax = strValue.GetLength();
1266 if (iDec2 > iMax) {
1267 for (int iNum = 0; iNum <= iDec2 - iMax; iNum++) {
1268 strValue += "0";
1269 }
1270 iMax = iDec2 + 1;
1271 }
1272 ///////////////////////////////////////////////////////
1273 // for processing seperator style
1274 if (iDec2 < iMax) {
1275 if (iSepStyle == 0 || iSepStyle == 1) {
1276 strValue.Insert(iDec2, '.');
1277 iMax++;
1278 } else if (iSepStyle == 2 || iSepStyle == 3) {
1279 strValue.Insert(iDec2, ',');
1280 iMax++;
1281 }
1282
1283 if (iDec2 == 0)
1284 strValue.Insert(iDec2, '0');
1285 }
1286 if (iSepStyle == 0 || iSepStyle == 2) {
1287 char cSeperator;
1288 if (iSepStyle == 0)
1289 cSeperator = ',';
1290 else
1291 cSeperator = '.';
1292
Tom Sepezdfbf8e72015-10-14 14:17:26 -07001293 for (int iDecPositive = iDec2 - 3; iDecPositive > 0; iDecPositive -= 3) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001294 strValue.Insert(iDecPositive, cSeperator);
1295 iMax++;
1296 }
1297 }
1298 ////////////////////////////////////////////////////////////////////
1299 // negative mark
1300 if (iNegative)
1301 strValue = "-" + strValue;
1302 strValue += "%";
1303 Value = CFX_WideString::FromLocal(strValue);
1304#endif
1305 return TRUE;
1306}
1307// AFPercent_Keystroke(nDec, sepStyle)
Lei Zhang945fdb72015-11-11 10:18:16 -08001308FX_BOOL CJS_PublicMethods::AFPercent_Keystroke(
1309 IJS_Context* cc,
1310 const std::vector<CJS_Value>& params,
1311 CJS_Value& vRet,
1312 CFX_WideString& sError) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001313 return AFNumber_Keystroke(cc, params, vRet, sError);
1314}
1315
1316// function AFDate_FormatEx(cFormat)
Tom Sepezba038bc2015-10-08 12:03:00 -07001317FX_BOOL CJS_PublicMethods::AFDate_FormatEx(IJS_Context* cc,
Lei Zhang945fdb72015-11-11 10:18:16 -08001318 const std::vector<CJS_Value>& params,
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001319 CJS_Value& vRet,
1320 CFX_WideString& sError) {
1321 CJS_Context* pContext = (CJS_Context*)cc;
1322 ASSERT(pContext != NULL);
1323 CJS_EventHandler* pEvent = pContext->GetEventHandler();
1324 ASSERT(pEvent != NULL);
1325
1326 if (params.size() != 1) {
1327 sError = JSGetStringFromID(pContext, IDS_STRING_JSPARAMERROR);
1328 return FALSE;
1329 }
1330 if (!pEvent->m_pValue)
1331 return FALSE;
1332
1333 CFX_WideString& val = pEvent->Value();
1334 CFX_WideString strValue = val;
1335 if (strValue.IsEmpty())
1336 return TRUE;
1337
1338 CFX_WideString sFormat = params[0].ToCFXWideString();
1339 FX_BOOL bWrongFormat = FALSE;
1340 double dDate = 0.0f;
1341
1342 if (strValue.Find(L"GMT") != -1) {
1343 // for GMT format time
1344 // such as "Tue Aug 11 14:24:16 GMT+08002009"
1345 dDate = MakeInterDate(strValue);
1346 } else {
1347 dDate = MakeRegularDate(strValue, sFormat, bWrongFormat);
1348 }
1349
1350 if (JS_PortIsNan(dDate)) {
1351 CFX_WideString swMsg;
1352 swMsg.Format(JSGetStringFromID(pContext, IDS_STRING_JSPARSEDATE).c_str(),
1353 sFormat.c_str());
1354 Alert(pContext, swMsg.c_str());
1355 return FALSE;
1356 }
1357
1358 val = MakeFormatDate(dDate, sFormat);
1359 return TRUE;
1360}
1361
1362double CJS_PublicMethods::MakeInterDate(CFX_WideString strValue) {
1363 int nHour;
1364 int nMin;
1365 int nSec;
1366 int nYear;
1367 int nMonth;
1368 int nDay;
1369
1370 CFX_WideStringArray wsArray;
1371 CFX_WideString sMonth = L"";
1372 CFX_WideString sTemp = L"";
1373 int nSize = strValue.GetLength();
1374
1375 for (int i = 0; i < nSize; i++) {
1376 FX_WCHAR c = strValue.GetAt(i);
1377 if (c == L' ' || c == L':') {
1378 wsArray.Add(sTemp);
1379 sTemp = L"";
1380 continue;
1381 }
1382
1383 sTemp += c;
1384 }
1385
1386 wsArray.Add(sTemp);
1387 if (wsArray.GetSize() != 8)
1388 return 0;
1389
1390 sTemp = wsArray[1];
1391 if (sTemp.Compare(L"Jan") == 0)
1392 nMonth = 1;
1393 if (sTemp.Compare(L"Feb") == 0)
1394 nMonth = 2;
1395 if (sTemp.Compare(L"Mar") == 0)
1396 nMonth = 3;
1397 if (sTemp.Compare(L"Apr") == 0)
1398 nMonth = 4;
1399 if (sTemp.Compare(L"May") == 0)
1400 nMonth = 5;
1401 if (sTemp.Compare(L"Jun") == 0)
1402 nMonth = 6;
1403 if (sTemp.Compare(L"Jul") == 0)
1404 nMonth = 7;
1405 if (sTemp.Compare(L"Aug") == 0)
1406 nMonth = 8;
1407 if (sTemp.Compare(L"Sep") == 0)
1408 nMonth = 9;
1409 if (sTemp.Compare(L"Oct") == 0)
1410 nMonth = 10;
1411 if (sTemp.Compare(L"Nov") == 0)
1412 nMonth = 11;
1413 if (sTemp.Compare(L"Dec") == 0)
1414 nMonth = 12;
1415
1416 nDay = (int)ParseStringToNumber(wsArray[2].c_str());
1417 nHour = (int)ParseStringToNumber(wsArray[3].c_str());
1418 nMin = (int)ParseStringToNumber(wsArray[4].c_str());
1419 nSec = (int)ParseStringToNumber(wsArray[5].c_str());
1420 nYear = (int)ParseStringToNumber(wsArray[7].c_str());
1421
1422 double dRet = JS_MakeDate(JS_MakeDay(nYear, nMonth - 1, nDay),
1423 JS_MakeTime(nHour, nMin, nSec, 0));
1424
1425 if (JS_PortIsNan(dRet)) {
1426 dRet = JS_DateParse(strValue.c_str());
1427 }
1428
1429 return dRet;
1430}
1431
1432// AFDate_KeystrokeEx(cFormat)
Lei Zhang945fdb72015-11-11 10:18:16 -08001433FX_BOOL CJS_PublicMethods::AFDate_KeystrokeEx(
1434 IJS_Context* cc,
1435 const std::vector<CJS_Value>& params,
1436 CJS_Value& vRet,
1437 CFX_WideString& sError) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001438 CJS_Context* pContext = (CJS_Context*)cc;
1439 ASSERT(pContext != NULL);
1440 CJS_EventHandler* pEvent = pContext->GetEventHandler();
1441 ASSERT(pEvent != NULL);
1442
1443 if (params.size() != 1) {
1444 sError = L"AFDate_KeystrokeEx's parameters' size r not correct";
1445 return FALSE;
1446 }
1447
1448 if (pEvent->WillCommit()) {
1449 if (!pEvent->m_pValue)
1450 return FALSE;
1451 CFX_WideString strValue = pEvent->Value();
1452 if (strValue.IsEmpty())
1453 return TRUE;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07001454
Tom Sepez2f2ffec2015-07-23 14:42:09 -07001455 CFX_WideString sFormat = params[0].ToCFXWideString();
1456 FX_BOOL bWrongFormat = FALSE;
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001457 double dRet = MakeRegularDate(strValue, sFormat, bWrongFormat);
1458 if (bWrongFormat || JS_PortIsNan(dRet)) {
1459 CFX_WideString swMsg;
1460 swMsg.Format(JSGetStringFromID(pContext, IDS_STRING_JSPARSEDATE).c_str(),
1461 sFormat.c_str());
1462 Alert(pContext, swMsg.c_str());
1463 pEvent->Rc() = FALSE;
1464 return TRUE;
Tom Sepez2f2ffec2015-07-23 14:42:09 -07001465 }
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001466 }
1467 return TRUE;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07001468}
1469
Tom Sepezba038bc2015-10-08 12:03:00 -07001470FX_BOOL CJS_PublicMethods::AFDate_Format(IJS_Context* cc,
Lei Zhang945fdb72015-11-11 10:18:16 -08001471 const std::vector<CJS_Value>& params,
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001472 CJS_Value& vRet,
1473 CFX_WideString& sError) {
Tom Sepez67fd5df2015-10-08 12:24:19 -07001474 CJS_Context* pContext = (CJS_Context*)cc;
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001475 if (params.size() != 1) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001476 sError = JSGetStringFromID(pContext, IDS_STRING_JSPARAMERROR);
1477 return FALSE;
1478 }
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07001479
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001480 int iIndex = params[0].ToInt();
1481 const FX_WCHAR* cFormats[] = {L"m/d",
1482 L"m/d/yy",
1483 L"mm/dd/yy",
1484 L"mm/yy",
1485 L"d-mmm",
1486 L"d-mmm-yy",
1487 L"dd-mmm-yy",
1488 L"yy-mm-dd",
1489 L"mmm-yy",
1490 L"mmmm-yy",
1491 L"mmm d, yyyy",
1492 L"mmmm d, yyyy",
1493 L"m/d/yy h:MM tt",
1494 L"m/d/yy HH:MM"};
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07001495
Lei Zhanga0f67242015-08-17 15:39:30 -07001496 if (iIndex < 0 || (static_cast<size_t>(iIndex) >= FX_ArraySize(cFormats)))
1497 iIndex = 0;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07001498
Lei Zhang945fdb72015-11-11 10:18:16 -08001499 std::vector<CJS_Value> newParams;
Tom Sepez67fd5df2015-10-08 12:24:19 -07001500 newParams.push_back(
1501 CJS_Value(CJS_Runtime::FromContext(cc), cFormats[iIndex]));
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001502 return AFDate_FormatEx(cc, newParams, vRet, sError);
1503}
Lei Zhanga6d9f0e2015-06-13 00:48:38 -07001504
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001505// AFDate_KeystrokeEx(cFormat)
Lei Zhang945fdb72015-11-11 10:18:16 -08001506FX_BOOL CJS_PublicMethods::AFDate_Keystroke(
1507 IJS_Context* cc,
1508 const std::vector<CJS_Value>& params,
1509 CJS_Value& vRet,
1510 CFX_WideString& sError) {
Tom Sepez67fd5df2015-10-08 12:24:19 -07001511 CJS_Context* pContext = (CJS_Context*)cc;
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001512 if (params.size() != 1) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001513 sError = JSGetStringFromID(pContext, IDS_STRING_JSPARAMERROR);
1514 return FALSE;
1515 }
1516
1517 int iIndex = params[0].ToInt();
1518 const FX_WCHAR* cFormats[] = {L"m/d",
1519 L"m/d/yy",
1520 L"mm/dd/yy",
1521 L"mm/yy",
1522 L"d-mmm",
1523 L"d-mmm-yy",
1524 L"dd-mmm-yy",
1525 L"yy-mm-dd",
1526 L"mmm-yy",
1527 L"mmmm-yy",
1528 L"mmm d, yyyy",
1529 L"mmmm d, yyyy",
1530 L"m/d/yy h:MM tt",
1531 L"m/d/yy HH:MM"};
1532
Lei Zhanga0f67242015-08-17 15:39:30 -07001533 if (iIndex < 0 || (static_cast<size_t>(iIndex) >= FX_ArraySize(cFormats)))
1534 iIndex = 0;
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001535
Lei Zhang945fdb72015-11-11 10:18:16 -08001536 std::vector<CJS_Value> newParams;
Tom Sepez67fd5df2015-10-08 12:24:19 -07001537 newParams.push_back(
1538 CJS_Value(CJS_Runtime::FromContext(cc), cFormats[iIndex]));
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001539 return AFDate_KeystrokeEx(cc, newParams, vRet, sError);
1540}
1541
1542// function AFTime_Format(ptf)
Tom Sepezba038bc2015-10-08 12:03:00 -07001543FX_BOOL CJS_PublicMethods::AFTime_Format(IJS_Context* cc,
Lei Zhang945fdb72015-11-11 10:18:16 -08001544 const std::vector<CJS_Value>& params,
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001545 CJS_Value& vRet,
1546 CFX_WideString& sError) {
Tom Sepez67fd5df2015-10-08 12:24:19 -07001547 CJS_Context* pContext = (CJS_Context*)cc;
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001548 if (params.size() != 1) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001549 sError = JSGetStringFromID(pContext, IDS_STRING_JSPARAMERROR);
1550 return FALSE;
1551 }
1552
1553 int iIndex = params[0].ToInt();
1554 const FX_WCHAR* cFormats[] = {L"HH:MM", L"h:MM tt", L"HH:MM:ss",
1555 L"h:MM:ss tt"};
1556
Lei Zhanga0f67242015-08-17 15:39:30 -07001557 if (iIndex < 0 || (static_cast<size_t>(iIndex) >= FX_ArraySize(cFormats)))
1558 iIndex = 0;
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001559
Lei Zhang945fdb72015-11-11 10:18:16 -08001560 std::vector<CJS_Value> newParams;
Tom Sepez67fd5df2015-10-08 12:24:19 -07001561 newParams.push_back(
1562 CJS_Value(CJS_Runtime::FromContext(cc), cFormats[iIndex]));
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001563 return AFDate_FormatEx(cc, newParams, vRet, sError);
1564}
1565
Lei Zhang945fdb72015-11-11 10:18:16 -08001566FX_BOOL CJS_PublicMethods::AFTime_Keystroke(
1567 IJS_Context* cc,
1568 const std::vector<CJS_Value>& params,
1569 CJS_Value& vRet,
1570 CFX_WideString& sError) {
Tom Sepez67fd5df2015-10-08 12:24:19 -07001571 CJS_Context* pContext = (CJS_Context*)cc;
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001572 if (params.size() != 1) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001573 sError = JSGetStringFromID(pContext, IDS_STRING_JSPARAMERROR);
1574 return FALSE;
1575 }
1576
1577 int iIndex = params[0].ToInt();
1578 const FX_WCHAR* cFormats[] = {L"HH:MM", L"h:MM tt", L"HH:MM:ss",
1579 L"h:MM:ss tt"};
1580
Lei Zhanga0f67242015-08-17 15:39:30 -07001581 if (iIndex < 0 || (static_cast<size_t>(iIndex) >= FX_ArraySize(cFormats)))
1582 iIndex = 0;
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001583
Lei Zhang945fdb72015-11-11 10:18:16 -08001584 std::vector<CJS_Value> newParams;
Tom Sepez67fd5df2015-10-08 12:24:19 -07001585 newParams.push_back(
1586 CJS_Value(CJS_Runtime::FromContext(cc), cFormats[iIndex]));
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001587 return AFDate_KeystrokeEx(cc, newParams, vRet, sError);
1588}
1589
Tom Sepezba038bc2015-10-08 12:03:00 -07001590FX_BOOL CJS_PublicMethods::AFTime_FormatEx(IJS_Context* cc,
Lei Zhang945fdb72015-11-11 10:18:16 -08001591 const std::vector<CJS_Value>& params,
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001592 CJS_Value& vRet,
1593 CFX_WideString& sError) {
1594 return AFDate_FormatEx(cc, params, vRet, sError);
1595}
1596
Lei Zhang945fdb72015-11-11 10:18:16 -08001597FX_BOOL CJS_PublicMethods::AFTime_KeystrokeEx(
1598 IJS_Context* cc,
1599 const std::vector<CJS_Value>& params,
1600 CJS_Value& vRet,
1601 CFX_WideString& sError) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001602 return AFDate_KeystrokeEx(cc, params, vRet, sError);
1603}
1604
1605// function AFSpecial_Format(psf)
Lei Zhang945fdb72015-11-11 10:18:16 -08001606FX_BOOL CJS_PublicMethods::AFSpecial_Format(
1607 IJS_Context* cc,
1608 const std::vector<CJS_Value>& params,
1609 CJS_Value& vRet,
1610 CFX_WideString& sError) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001611 CJS_Context* pContext = (CJS_Context*)cc;
1612 ASSERT(pContext != NULL);
1613
1614 if (params.size() != 1) {
1615 sError = JSGetStringFromID(pContext, IDS_STRING_JSPARAMERROR);
1616 return FALSE;
1617 }
1618
1619 std::string cFormat;
1620 int iIndex = params[0].ToInt();
1621
1622 CJS_EventHandler* pEvent = pContext->GetEventHandler();
1623 ASSERT(pEvent != NULL);
1624
1625 if (!pEvent->m_pValue)
1626 return FALSE;
1627 CFX_WideString& Value = pEvent->Value();
1628 std::string strSrc = CFX_ByteString::FromUnicode(Value).c_str();
1629
1630 switch (iIndex) {
Tom Sepez2f2ffec2015-07-23 14:42:09 -07001631 case 0:
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001632 cFormat = "99999";
1633 break;
Tom Sepez2f2ffec2015-07-23 14:42:09 -07001634 case 1:
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001635 cFormat = "99999-9999";
1636 break;
1637 case 2: {
1638 std::string NumberStr;
1639 util::printx("9999999999", strSrc, NumberStr);
1640 if (NumberStr.length() >= 10)
1641 cFormat = "(999) 999-9999";
1642 else
1643 cFormat = "999-9999";
1644 break;
1645 }
Tom Sepez2f2ffec2015-07-23 14:42:09 -07001646 case 3:
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001647 cFormat = "999-99-9999";
1648 break;
1649 }
1650
1651 std::string strDes;
1652 util::printx(cFormat, strSrc, strDes);
1653 Value = CFX_WideString::FromLocal(strDes.c_str());
1654 return TRUE;
1655}
1656
1657// function AFSpecial_KeystrokeEx(mask)
Lei Zhang945fdb72015-11-11 10:18:16 -08001658FX_BOOL CJS_PublicMethods::AFSpecial_KeystrokeEx(
1659 IJS_Context* cc,
1660 const std::vector<CJS_Value>& params,
1661 CJS_Value& vRet,
1662 CFX_WideString& sError) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001663 CJS_Context* pContext = (CJS_Context*)cc;
1664 ASSERT(pContext != NULL);
1665 CJS_EventHandler* pEvent = pContext->GetEventHandler();
1666
1667 ASSERT(pEvent != NULL);
1668
1669 if (params.size() < 1) {
1670 sError = JSGetStringFromID(pContext, IDS_STRING_JSPARAMERROR);
1671 return FALSE;
1672 }
1673
1674 if (!pEvent->m_pValue)
1675 return FALSE;
1676 CFX_WideString& valEvent = pEvent->Value();
1677
1678 CFX_WideString wstrMask = params[0].ToCFXWideString();
1679 if (wstrMask.IsEmpty())
1680 return TRUE;
1681
Lei Zhanga0f67242015-08-17 15:39:30 -07001682 const size_t wstrMaskLen = wstrMask.GetLength();
1683 const std::wstring wstrValue = valEvent.c_str();
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001684
1685 if (pEvent->WillCommit()) {
1686 if (wstrValue.empty())
1687 return TRUE;
Lei Zhanga0f67242015-08-17 15:39:30 -07001688 size_t iIndexMask = 0;
1689 for (const auto& w_Value : wstrValue) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001690 if (!maskSatisfied(w_Value, wstrMask[iIndexMask]))
Tom Sepez2f2ffec2015-07-23 14:42:09 -07001691 break;
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001692 iIndexMask++;
Tom Sepez2f2ffec2015-07-23 14:42:09 -07001693 }
Lei Zhanga6d9f0e2015-06-13 00:48:38 -07001694
Lei Zhanga0f67242015-08-17 15:39:30 -07001695 if (iIndexMask != wstrMaskLen ||
1696 (iIndexMask != wstrValue.size() && wstrMaskLen != 0)) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001697 Alert(
1698 pContext,
1699 JSGetStringFromID(pContext, IDS_STRING_JSAFNUMBER_KEYSTROKE).c_str());
1700 pEvent->Rc() = FALSE;
1701 }
Tom Sepez2f2ffec2015-07-23 14:42:09 -07001702 return TRUE;
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001703 }
1704
1705 CFX_WideString& wideChange = pEvent->Change();
1706 std::wstring wChange = wideChange.c_str();
1707 if (wChange.empty())
1708 return TRUE;
1709
1710 int iIndexMask = pEvent->SelStart();
1711
Lei Zhanga0f67242015-08-17 15:39:30 -07001712 size_t combined_len = wstrValue.length() + wChange.length() -
1713 (pEvent->SelEnd() - pEvent->SelStart());
1714 if (combined_len > wstrMaskLen) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001715 Alert(pContext,
1716 JSGetStringFromID(pContext, IDS_STRING_JSPARAM_TOOLONG).c_str());
1717 pEvent->Rc() = FALSE;
1718 return TRUE;
1719 }
1720
Lei Zhanga0f67242015-08-17 15:39:30 -07001721 if (iIndexMask >= wstrMaskLen && (!wChange.empty())) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001722 Alert(pContext,
1723 JSGetStringFromID(pContext, IDS_STRING_JSPARAM_TOOLONG).c_str());
1724 pEvent->Rc() = FALSE;
1725 return TRUE;
1726 }
1727
1728 for (std::wstring::iterator it = wChange.begin(); it != wChange.end(); it++) {
Lei Zhanga0f67242015-08-17 15:39:30 -07001729 if (iIndexMask >= wstrMaskLen) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001730 Alert(pContext,
1731 JSGetStringFromID(pContext, IDS_STRING_JSPARAM_TOOLONG).c_str());
1732 pEvent->Rc() = FALSE;
1733 return TRUE;
1734 }
1735 wchar_t w_Mask = wstrMask[iIndexMask];
1736 if (!isReservedMaskChar(w_Mask)) {
1737 *it = w_Mask;
1738 }
1739 wchar_t w_Change = *it;
1740 if (!maskSatisfied(w_Change, w_Mask)) {
1741 pEvent->Rc() = FALSE;
1742 return TRUE;
1743 }
1744 iIndexMask++;
1745 }
1746
1747 wideChange = wChange.c_str();
1748 return TRUE;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07001749}
1750
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001751// function AFSpecial_Keystroke(psf)
Lei Zhang945fdb72015-11-11 10:18:16 -08001752FX_BOOL CJS_PublicMethods::AFSpecial_Keystroke(
1753 IJS_Context* cc,
1754 const std::vector<CJS_Value>& params,
1755 CJS_Value& vRet,
1756 CFX_WideString& sError) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001757 CJS_Context* pContext = (CJS_Context*)cc;
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001758 if (params.size() != 1) {
1759 sError = JSGetStringFromID(pContext, IDS_STRING_JSPARAMERROR);
1760 return FALSE;
1761 }
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07001762
Tom Sepez67fd5df2015-10-08 12:24:19 -07001763 CJS_EventHandler* pEvent = pContext->GetEventHandler();
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001764 if (!pEvent->m_pValue)
1765 return FALSE;
Tom Sepez67fd5df2015-10-08 12:24:19 -07001766
1767 std::string cFormat;
1768 int iIndex = params[0].ToInt();
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001769 CFX_WideString& val = pEvent->Value();
1770 std::string strSrc = CFX_ByteString::FromUnicode(val).c_str();
1771 std::wstring wstrChange = pEvent->Change().c_str();
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07001772
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001773 switch (iIndex) {
Tom Sepez2f2ffec2015-07-23 14:42:09 -07001774 case 0:
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001775 cFormat = "99999";
1776 break;
Tom Sepez2f2ffec2015-07-23 14:42:09 -07001777 case 1:
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001778 // cFormat = "99999-9999";
1779 cFormat = "999999999";
1780 break;
1781 case 2: {
1782 std::string NumberStr;
1783 util::printx("9999999999", strSrc, NumberStr);
1784 if (strSrc.length() + wstrChange.length() > 7)
1785 // cFormat = "(999) 999-9999";
1786 cFormat = "9999999999";
1787 else
1788 // cFormat = "999-9999";
1789 cFormat = "9999999";
1790 break;
1791 }
Tom Sepez2f2ffec2015-07-23 14:42:09 -07001792 case 3:
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001793 // cFormat = "999-99-9999";
1794 cFormat = "999999999";
1795 break;
1796 }
Lei Zhanga6d9f0e2015-06-13 00:48:38 -07001797
Lei Zhang945fdb72015-11-11 10:18:16 -08001798 std::vector<CJS_Value> params2;
Tom Sepez67fd5df2015-10-08 12:24:19 -07001799 params2.push_back(CJS_Value(CJS_Runtime::FromContext(cc), cFormat.c_str()));
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001800 return AFSpecial_KeystrokeEx(cc, params2, vRet, sError);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07001801}
1802
Tom Sepezba038bc2015-10-08 12:03:00 -07001803FX_BOOL CJS_PublicMethods::AFMergeChange(IJS_Context* cc,
Lei Zhang945fdb72015-11-11 10:18:16 -08001804 const std::vector<CJS_Value>& params,
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001805 CJS_Value& vRet,
1806 CFX_WideString& sError) {
1807 CJS_Context* pContext = (CJS_Context*)cc;
1808 ASSERT(pContext != NULL);
1809 CJS_EventHandler* pEventHandler = pContext->GetEventHandler();
1810 ASSERT(pEventHandler != NULL);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07001811
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001812 if (params.size() != 1) {
1813 sError = JSGetStringFromID(pContext, IDS_STRING_JSPARAMERROR);
1814 return FALSE;
1815 }
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07001816
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001817 CFX_WideString swValue;
Lei Zhang997de612015-11-04 18:17:53 -08001818 if (pEventHandler->m_pValue)
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001819 swValue = pEventHandler->Value();
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07001820
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001821 if (pEventHandler->WillCommit()) {
1822 vRet = swValue.c_str();
Tom Sepez2f2ffec2015-07-23 14:42:09 -07001823 return TRUE;
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001824 }
1825
1826 CFX_WideString prefix, postfix;
1827
1828 if (pEventHandler->SelStart() >= 0)
1829 prefix = swValue.Mid(0, pEventHandler->SelStart());
1830 else
1831 prefix = L"";
1832
1833 if (pEventHandler->SelEnd() >= 0 &&
1834 pEventHandler->SelEnd() <= swValue.GetLength())
1835 postfix = swValue.Mid(pEventHandler->SelEnd(),
1836 swValue.GetLength() - pEventHandler->SelEnd());
1837 else
1838 postfix = L"";
1839
1840 vRet = (prefix + pEventHandler->Change() + postfix).c_str();
1841
1842 return TRUE;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07001843}
1844
Tom Sepezba038bc2015-10-08 12:03:00 -07001845FX_BOOL CJS_PublicMethods::AFParseDateEx(IJS_Context* cc,
Lei Zhang945fdb72015-11-11 10:18:16 -08001846 const std::vector<CJS_Value>& params,
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001847 CJS_Value& vRet,
1848 CFX_WideString& sError) {
1849 CJS_Context* pContext = (CJS_Context*)cc;
1850 ASSERT(pContext != NULL);
1851
1852 if (params.size() != 2) {
1853 sError = JSGetStringFromID(pContext, IDS_STRING_JSPARAMERROR);
1854 return FALSE;
1855 }
1856
1857 CFX_WideString sValue = params[0].ToCFXWideString();
1858 CFX_WideString sFormat = params[1].ToCFXWideString();
1859
1860 FX_BOOL bWrongFormat = FALSE;
1861 double dDate = MakeRegularDate(sValue, sFormat, bWrongFormat);
1862
1863 if (JS_PortIsNan(dDate)) {
1864 CFX_WideString swMsg;
1865 swMsg.Format(JSGetStringFromID(pContext, IDS_STRING_JSPARSEDATE).c_str(),
1866 sFormat.c_str());
1867 Alert((CJS_Context*)cc, swMsg.c_str());
1868 return FALSE;
1869 }
1870
1871 vRet = dDate;
1872 return TRUE;
1873}
1874
Tom Sepezba038bc2015-10-08 12:03:00 -07001875FX_BOOL CJS_PublicMethods::AFSimple(IJS_Context* cc,
Lei Zhang945fdb72015-11-11 10:18:16 -08001876 const std::vector<CJS_Value>& params,
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001877 CJS_Value& vRet,
1878 CFX_WideString& sError) {
1879 if (params.size() != 3) {
1880 CJS_Context* pContext = (CJS_Context*)cc;
Tom Sepez2f2ffec2015-07-23 14:42:09 -07001881 ASSERT(pContext != NULL);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07001882
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001883 sError = JSGetStringFromID(pContext, IDS_STRING_JSPARAMERROR);
1884 return FALSE;
1885 }
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07001886
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001887 vRet = (double)AF_Simple(params[0].ToCFXWideString().c_str(),
1888 params[1].ToDouble(), params[2].ToDouble());
1889 return TRUE;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07001890}
1891
Tom Sepezba038bc2015-10-08 12:03:00 -07001892FX_BOOL CJS_PublicMethods::AFMakeNumber(IJS_Context* cc,
Lei Zhang945fdb72015-11-11 10:18:16 -08001893 const std::vector<CJS_Value>& params,
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001894 CJS_Value& vRet,
1895 CFX_WideString& sError) {
1896 if (params.size() != 1) {
1897 CJS_Context* pContext = (CJS_Context*)cc;
Tom Sepez2f2ffec2015-07-23 14:42:09 -07001898 ASSERT(pContext != NULL);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07001899
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001900 sError = JSGetStringFromID(pContext, IDS_STRING_JSPARAMERROR);
1901 return FALSE;
1902 }
1903 vRet = ParseStringToNumber(params[0].ToCFXWideString().c_str());
1904 return TRUE;
1905}
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07001906
Lei Zhang945fdb72015-11-11 10:18:16 -08001907FX_BOOL CJS_PublicMethods::AFSimple_Calculate(
1908 IJS_Context* cc,
1909 const std::vector<CJS_Value>& params,
1910 CJS_Value& vRet,
1911 CFX_WideString& sError) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001912 CJS_Context* pContext = (CJS_Context*)cc;
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001913 if (params.size() != 2) {
1914 sError = JSGetStringFromID(pContext, IDS_STRING_JSPARAMERROR);
1915 return FALSE;
1916 }
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07001917
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001918 CJS_Value params1 = params[1];
Tom Sepez39bfe122015-09-17 15:25:23 -07001919 if (!params1.IsArrayObject() && params1.GetType() != CJS_Value::VT_string) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001920 sError = JSGetStringFromID(pContext, IDS_STRING_JSPARAMERROR);
1921 return FALSE;
1922 }
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07001923
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001924 CPDFSDK_Document* pReaderDoc = pContext->GetReaderDocument();
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001925 CPDFSDK_InterForm* pReaderInterForm = pReaderDoc->GetInterForm();
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001926 CPDF_InterForm* pInterForm = pReaderInterForm->GetInterForm();
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07001927
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001928 CFX_WideString sFunction = params[0].ToCFXWideString();
Tom Sepez67fd5df2015-10-08 12:24:19 -07001929 double dValue = wcscmp(sFunction.c_str(), L"PRD") == 0 ? 1.0 : 0.0;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07001930
Tom Sepez67fd5df2015-10-08 12:24:19 -07001931 CJS_Runtime* pRuntime = CJS_Runtime::FromContext(cc);
1932 CJS_Array FieldNameArray = AF_MakeArrayFromList(pRuntime, params1);
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001933 int nFieldsCount = 0;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07001934
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001935 for (int i = 0, isz = FieldNameArray.GetLength(); i < isz; i++) {
Tom Sepez67fd5df2015-10-08 12:24:19 -07001936 CJS_Value jsValue(pRuntime);
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001937 FieldNameArray.GetElement(i, jsValue);
1938 CFX_WideString wsFieldName = jsValue.ToCFXWideString();
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07001939
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001940 for (int j = 0, jsz = pInterForm->CountFields(wsFieldName); j < jsz; j++) {
1941 if (CPDF_FormField* pFormField = pInterForm->GetField(j, wsFieldName)) {
1942 double dTemp = 0.0;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07001943
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001944 switch (pFormField->GetFieldType()) {
1945 case FIELDTYPE_TEXTFIELD:
1946 case FIELDTYPE_COMBOBOX: {
1947 dTemp = ParseStringToNumber(pFormField->GetValue().c_str());
1948 break;
1949 }
1950 case FIELDTYPE_PUSHBUTTON: {
1951 dTemp = 0.0;
1952 break;
1953 }
1954 case FIELDTYPE_CHECKBOX:
1955 case FIELDTYPE_RADIOBUTTON: {
1956 dTemp = 0.0;
1957 for (int c = 0, csz = pFormField->CountControls(); c < csz; c++) {
1958 if (CPDF_FormControl* pFormCtrl = pFormField->GetControl(c)) {
1959 if (pFormCtrl->IsChecked()) {
1960 dTemp +=
1961 ParseStringToNumber(pFormCtrl->GetExportValue().c_str());
1962 break;
1963 } else
1964 continue;
1965 }
Tom Sepez2f2ffec2015-07-23 14:42:09 -07001966 }
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001967 break;
1968 }
1969 case FIELDTYPE_LISTBOX: {
1970 dTemp = 0.0;
1971 if (pFormField->CountSelectedItems() > 1)
1972 break;
1973 else {
1974 dTemp = ParseStringToNumber(pFormField->GetValue().c_str());
1975 break;
1976 }
1977 }
1978 default:
1979 break;
Tom Sepez2f2ffec2015-07-23 14:42:09 -07001980 }
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001981
1982 if (i == 0 && j == 0 && (wcscmp(sFunction.c_str(), L"MIN") == 0 ||
1983 wcscmp(sFunction.c_str(), L"MAX") == 0))
1984 dValue = dTemp;
1985
1986 dValue = AF_Simple(sFunction.c_str(), dValue, dTemp);
1987
1988 nFieldsCount++;
1989 }
Tom Sepez2f2ffec2015-07-23 14:42:09 -07001990 }
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001991 }
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07001992
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001993 if (wcscmp(sFunction.c_str(), L"AVG") == 0 && nFieldsCount > 0)
1994 dValue /= nFieldsCount;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07001995
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001996 dValue = (double)floor(dValue * FXSYS_pow((double)10, (double)6) + 0.49) /
1997 FXSYS_pow((double)10, (double)6);
Tom Sepez67fd5df2015-10-08 12:24:19 -07001998 CJS_Value jsValue(pRuntime, dValue);
foxit8b544ed2015-09-10 14:57:54 +08001999 if (pContext->GetEventHandler()->m_pValue)
2000 pContext->GetEventHandler()->Value() = jsValue.ToCFXWideString();
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07002001
Nico Weber9d8ec5a2015-08-04 13:00:21 -07002002 return TRUE;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07002003}
2004
Lei Zhanga6d9f0e2015-06-13 00:48:38 -07002005/* This function validates the current event to ensure that its value is
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07002006** within the specified range. */
2007
Lei Zhang945fdb72015-11-11 10:18:16 -08002008FX_BOOL CJS_PublicMethods::AFRange_Validate(
2009 IJS_Context* cc,
2010 const std::vector<CJS_Value>& params,
2011 CJS_Value& vRet,
2012 CFX_WideString& sError) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -07002013 CJS_Context* pContext = (CJS_Context*)cc;
2014 ASSERT(pContext != NULL);
2015 CJS_EventHandler* pEvent = pContext->GetEventHandler();
2016 ASSERT(pEvent != NULL);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07002017
Nico Weber9d8ec5a2015-08-04 13:00:21 -07002018 if (params.size() != 4) {
2019 sError = JSGetStringFromID(pContext, IDS_STRING_JSPARAMERROR);
2020 return FALSE;
2021 }
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07002022
Nico Weber9d8ec5a2015-08-04 13:00:21 -07002023 if (!pEvent->m_pValue)
2024 return FALSE;
2025 if (pEvent->Value().IsEmpty())
Tom Sepez2f2ffec2015-07-23 14:42:09 -07002026 return TRUE;
Nico Weber9d8ec5a2015-08-04 13:00:21 -07002027 double dEentValue = atof(CFX_ByteString::FromUnicode(pEvent->Value()));
2028 FX_BOOL bGreaterThan = params[0].ToBool();
2029 double dGreaterThan = params[1].ToDouble();
2030 FX_BOOL bLessThan = params[2].ToBool();
2031 double dLessThan = params[3].ToDouble();
2032 CFX_WideString swMsg;
2033
2034 if (bGreaterThan && bLessThan) {
2035 if (dEentValue < dGreaterThan || dEentValue > dLessThan)
2036 swMsg.Format(JSGetStringFromID(pContext, IDS_STRING_JSRANGE1).c_str(),
2037 params[1].ToCFXWideString().c_str(),
2038 params[3].ToCFXWideString().c_str());
2039 } else if (bGreaterThan) {
2040 if (dEentValue < dGreaterThan)
2041 swMsg.Format(JSGetStringFromID(pContext, IDS_STRING_JSRANGE2).c_str(),
2042 params[1].ToCFXWideString().c_str());
2043 } else if (bLessThan) {
2044 if (dEentValue > dLessThan)
2045 swMsg.Format(JSGetStringFromID(pContext, IDS_STRING_JSRANGE3).c_str(),
2046 params[3].ToCFXWideString().c_str());
2047 }
2048
2049 if (!swMsg.IsEmpty()) {
2050 Alert(pContext, swMsg.c_str());
2051 pEvent->Rc() = FALSE;
2052 }
2053 return TRUE;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07002054}
2055
Tom Sepezba038bc2015-10-08 12:03:00 -07002056FX_BOOL CJS_PublicMethods::AFExtractNums(IJS_Context* cc,
Lei Zhang945fdb72015-11-11 10:18:16 -08002057 const std::vector<CJS_Value>& params,
Nico Weber9d8ec5a2015-08-04 13:00:21 -07002058 CJS_Value& vRet,
2059 CFX_WideString& sError) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -07002060 CJS_Context* pContext = (CJS_Context*)cc;
Nico Weber9d8ec5a2015-08-04 13:00:21 -07002061 if (params.size() != 1) {
2062 sError = JSGetStringFromID(pContext, IDS_STRING_JSPARAMERROR);
2063 return FALSE;
2064 }
2065
Tom Sepez67fd5df2015-10-08 12:24:19 -07002066 CJS_Runtime* pRuntime = CJS_Runtime::FromContext(cc);
2067 CJS_Array nums(pRuntime);
Nico Weber9d8ec5a2015-08-04 13:00:21 -07002068
2069 CFX_WideString str = params[0].ToCFXWideString();
2070 CFX_WideString sPart;
2071
2072 if (str.GetAt(0) == L'.' || str.GetAt(0) == L',')
2073 str = L"0" + str;
2074
2075 int nIndex = 0;
2076 for (int i = 0, sz = str.GetLength(); i < sz; i++) {
2077 FX_WCHAR wc = str.GetAt(i);
2078 if (IsDigit((wchar_t)wc)) {
2079 sPart += wc;
2080 } else {
2081 if (sPart.GetLength() > 0) {
Tom Sepez67fd5df2015-10-08 12:24:19 -07002082 nums.SetElement(nIndex, CJS_Value(pRuntime, sPart.c_str()));
Nico Weber9d8ec5a2015-08-04 13:00:21 -07002083 sPart = L"";
2084 nIndex++;
2085 }
Tom Sepez2f2ffec2015-07-23 14:42:09 -07002086 }
Nico Weber9d8ec5a2015-08-04 13:00:21 -07002087 }
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07002088
Nico Weber9d8ec5a2015-08-04 13:00:21 -07002089 if (sPart.GetLength() > 0) {
Tom Sepez67fd5df2015-10-08 12:24:19 -07002090 nums.SetElement(nIndex, CJS_Value(pRuntime, sPart.c_str()));
Nico Weber9d8ec5a2015-08-04 13:00:21 -07002091 }
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07002092
Nico Weber9d8ec5a2015-08-04 13:00:21 -07002093 if (nums.GetLength() > 0)
2094 vRet = nums;
2095 else
2096 vRet.SetNull();
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07002097
Nico Weber9d8ec5a2015-08-04 13:00:21 -07002098 return TRUE;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07002099}