blob: c11197d93e1421a9748f34a3a657a5cef04347dc [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
9#include "../../include/fsdk_mgr.h" // For CPDFDoc_Environment.
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -070010#include "../../include/javascript/IJavaScript.h"
Tom Sepez37458412015-10-06 11:33:46 -070011#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 "resource.h"
20#include "util.h"
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -070021
Nico Weber9d8ec5a2015-08-04 13:00:21 -070022#define DOUBLE_CORRECT 0.000000000000001
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -070023
24BEGIN_JS_STATIC_GLOBAL_FUN(CJS_PublicMethods)
Nico Weber9d8ec5a2015-08-04 13:00:21 -070025JS_STATIC_GLOBAL_FUN_ENTRY(AFNumber_Format)
26JS_STATIC_GLOBAL_FUN_ENTRY(AFNumber_Keystroke)
27JS_STATIC_GLOBAL_FUN_ENTRY(AFPercent_Format)
28JS_STATIC_GLOBAL_FUN_ENTRY(AFPercent_Keystroke)
29JS_STATIC_GLOBAL_FUN_ENTRY(AFDate_FormatEx)
30JS_STATIC_GLOBAL_FUN_ENTRY(AFDate_KeystrokeEx)
31JS_STATIC_GLOBAL_FUN_ENTRY(AFDate_Format)
32JS_STATIC_GLOBAL_FUN_ENTRY(AFDate_Keystroke)
33JS_STATIC_GLOBAL_FUN_ENTRY(AFTime_FormatEx)
34JS_STATIC_GLOBAL_FUN_ENTRY(AFTime_KeystrokeEx)
35JS_STATIC_GLOBAL_FUN_ENTRY(AFTime_Format)
36JS_STATIC_GLOBAL_FUN_ENTRY(AFTime_Keystroke)
37JS_STATIC_GLOBAL_FUN_ENTRY(AFSpecial_Format)
38JS_STATIC_GLOBAL_FUN_ENTRY(AFSpecial_Keystroke)
39JS_STATIC_GLOBAL_FUN_ENTRY(AFSpecial_KeystrokeEx)
40JS_STATIC_GLOBAL_FUN_ENTRY(AFSimple)
41JS_STATIC_GLOBAL_FUN_ENTRY(AFMakeNumber)
42JS_STATIC_GLOBAL_FUN_ENTRY(AFSimple_Calculate)
43JS_STATIC_GLOBAL_FUN_ENTRY(AFRange_Validate)
44JS_STATIC_GLOBAL_FUN_ENTRY(AFMergeChange)
45JS_STATIC_GLOBAL_FUN_ENTRY(AFParseDateEx)
46JS_STATIC_GLOBAL_FUN_ENTRY(AFExtractNums)
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -070047END_JS_STATIC_GLOBAL_FUN()
48
49IMPLEMENT_JS_STATIC_GLOBAL_FUN(CJS_PublicMethods)
50
Tom Sepezdfbf8e72015-10-14 14:17:26 -070051static const FX_WCHAR* const months[] = {L"Jan",
52 L"Feb",
53 L"Mar",
54 L"Apr",
55 L"May",
56 L"Jun",
57 L"Jul",
58 L"Aug",
59 L"Sep",
60 L"Oct",
61 L"Nov",
62 L"Dec"};
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -070063
Nico Weber9d8ec5a2015-08-04 13:00:21 -070064static const FX_WCHAR* const fullmonths[] = {
65 L"January", L"February", L"March", L"April",
66 L"May", L"June", L"July", L"August",
67 L"September", L"October", L"November", L"December"};
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -070068
Nico Weber9d8ec5a2015-08-04 13:00:21 -070069FX_BOOL CJS_PublicMethods::IsNumber(const FX_WCHAR* string) {
70 CFX_WideString sTrim = StrTrim(string);
71 const FX_WCHAR* pTrim = sTrim.c_str();
72 const FX_WCHAR* p = pTrim;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -070073
Nico Weber9d8ec5a2015-08-04 13:00:21 -070074 FX_BOOL bDot = FALSE;
75 FX_BOOL bKXJS = FALSE;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -070076
Nico Weber9d8ec5a2015-08-04 13:00:21 -070077 wchar_t c;
78 while ((c = *p)) {
79 if (c == '.' || c == ',') {
80 if (bDot)
81 return FALSE;
82 bDot = TRUE;
83 } else if (c == '-' || c == '+') {
84 if (p != pTrim)
85 return FALSE;
86 } else if (c == 'e' || c == 'E') {
87 if (bKXJS)
88 return FALSE;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -070089
Nico Weber9d8ec5a2015-08-04 13:00:21 -070090 p++;
91 c = *p;
92 if (c == '+' || c == '-') {
93 bKXJS = TRUE;
94 } else {
95 return FALSE;
96 }
97 } else if (!IsDigit(c)) {
98 return FALSE;
99 }
100 p++;
101 }
102
103 return TRUE;
104}
105
106FX_BOOL CJS_PublicMethods::IsDigit(wchar_t ch) {
107 return (ch >= L'0' && ch <= L'9');
108}
109
110FX_BOOL CJS_PublicMethods::IsDigit(char ch) {
111 return (ch >= '0' && ch <= '9');
112}
113
114FX_BOOL CJS_PublicMethods::IsAlphabetic(wchar_t ch) {
115 return ((ch >= L'a' && ch <= L'z') || (ch >= L'A' && ch <= L'Z'));
116}
117
118FX_BOOL CJS_PublicMethods::IsAlphaNumeric(wchar_t ch) {
119 return (IsDigit(ch) || IsAlphabetic(ch));
120}
121
122FX_BOOL CJS_PublicMethods::maskSatisfied(wchar_t c_Change, wchar_t c_Mask) {
123 switch (c_Mask) {
124 case L'9':
125 return IsDigit(c_Change);
126 case L'A':
127 return IsAlphabetic(c_Change);
128 case L'O':
129 return IsAlphaNumeric(c_Change);
130 case L'X':
131 return TRUE;
132 default:
133 return (c_Change == c_Mask);
134 }
135}
136
137FX_BOOL CJS_PublicMethods::isReservedMaskChar(wchar_t ch) {
138 return ch == L'9' || ch == L'A' || ch == L'O' || ch == L'X';
139}
140
141double CJS_PublicMethods::AF_Simple(const FX_WCHAR* sFuction,
142 double dValue1,
143 double dValue2) {
144 if (FXSYS_wcsicmp(sFuction, L"AVG") == 0 ||
145 FXSYS_wcsicmp(sFuction, L"SUM") == 0) {
146 return dValue1 + dValue2;
147 }
148 if (FXSYS_wcsicmp(sFuction, L"PRD") == 0) {
149 return dValue1 * dValue2;
150 }
151 if (FXSYS_wcsicmp(sFuction, L"MIN") == 0) {
152 return FX_MIN(dValue1, dValue2);
153 }
154 if (FXSYS_wcsicmp(sFuction, L"MAX") == 0) {
155 return FX_MAX(dValue1, dValue2);
156 }
157 return dValue1;
158}
159
160CFX_WideString CJS_PublicMethods::StrLTrim(const FX_WCHAR* pStr) {
161 while (*pStr && *pStr == L' ')
162 pStr++;
163
164 return pStr;
165}
166
167CFX_WideString CJS_PublicMethods::StrRTrim(const FX_WCHAR* pStr) {
168 const FX_WCHAR* p = pStr;
169 while (*p)
170 p++;
171 while (p > pStr && *(p - 1) == L' ')
172 p--;
173
174 return CFX_WideString(pStr, p - pStr);
175}
176
177CFX_WideString CJS_PublicMethods::StrTrim(const FX_WCHAR* pStr) {
178 return StrRTrim(StrLTrim(pStr).c_str());
179}
180
181CFX_ByteString CJS_PublicMethods::StrLTrim(const FX_CHAR* pStr) {
182 while (*pStr && *pStr == ' ')
183 pStr++;
184
185 return pStr;
186}
187
188CFX_ByteString CJS_PublicMethods::StrRTrim(const FX_CHAR* pStr) {
189 const FX_CHAR* p = pStr;
190 while (*p)
191 p++;
192 while (p > pStr && *(p - 1) == L' ')
193 p--;
194
195 return CFX_ByteString(pStr, p - pStr);
196}
197
198CFX_ByteString CJS_PublicMethods::StrTrim(const FX_CHAR* pStr) {
199 return StrRTrim(StrLTrim(pStr));
200}
201
202double CJS_PublicMethods::ParseNumber(const FX_WCHAR* swSource,
203 FX_BOOL& bAllDigits,
204 FX_BOOL& bDot,
205 FX_BOOL& bSign,
206 FX_BOOL& bKXJS) {
207 bDot = FALSE;
208 bSign = FALSE;
209 bKXJS = FALSE;
210
211 FX_BOOL bDigitExist = FALSE;
212
213 const FX_WCHAR* p = swSource;
214 wchar_t c;
215
216 const FX_WCHAR* pStart = NULL;
217 const FX_WCHAR* pEnd = NULL;
218
219 while ((c = *p)) {
220 if (!pStart && c != L' ') {
221 pStart = p;
222 }
223
224 pEnd = p;
225 p++;
226 }
227
228 if (!pStart) {
229 bAllDigits = FALSE;
230 return 0;
231 }
232
233 while (pEnd != pStart) {
234 if (*pEnd == L' ')
235 pEnd--;
236 else
237 break;
238 }
239
240 double dRet = 0;
241 p = pStart;
242 bAllDigits = TRUE;
243 CFX_WideString swDigits;
244
245 while (p <= pEnd) {
246 c = *p;
247
248 if (IsDigit(c)) {
249 swDigits += c;
250 bDigitExist = TRUE;
251 } else {
252 switch (c) {
253 case L' ':
254 bAllDigits = FALSE;
255 break;
256 case L'.':
257 case L',':
258 if (!bDot) {
259 if (bDigitExist) {
260 swDigits += L'.';
261 } else {
262 swDigits += L'0';
263 swDigits += L'.';
264 bDigitExist = TRUE;
265 }
266
Tom Sepez2f2ffec2015-07-23 14:42:09 -0700267 bDot = TRUE;
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700268 break;
269 }
270 case 'e':
271 case 'E':
272 if (!bKXJS) {
Tom Sepez2f2ffec2015-07-23 14:42:09 -0700273 p++;
274 c = *p;
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700275 if (c == '+' || c == '-') {
276 bKXJS = TRUE;
277 swDigits += 'e';
278 swDigits += c;
Tom Sepez2f2ffec2015-07-23 14:42:09 -0700279 }
Tom Sepez2f2ffec2015-07-23 14:42:09 -0700280 break;
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700281 }
282 case L'-':
283 if (!bDigitExist && !bSign) {
Tom Sepez2f2ffec2015-07-23 14:42:09 -0700284 swDigits += c;
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700285 bSign = TRUE;
Tom Sepez2f2ffec2015-07-23 14:42:09 -0700286 break;
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700287 }
288 default:
289 bAllDigits = FALSE;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700290
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700291 if (p != pStart && !bDot && bDigitExist) {
292 swDigits += L'.';
293 bDot = TRUE;
294 } else {
295 bDot = FALSE;
296 bDigitExist = FALSE;
297 swDigits = L"";
298 }
299 break;
300 }
Tom Sepez2f2ffec2015-07-23 14:42:09 -0700301 }
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700302
303 p++;
304 }
305
306 if (swDigits.GetLength() > 0 && swDigits.GetLength() < 17) {
307 CFX_ByteString sDigits = swDigits.UTF8Encode();
308
309 if (bKXJS) {
310 dRet = atof(sDigits);
311 } else {
312 if (bDot) {
313 char* pStopString;
314 dRet = ::strtod(sDigits, &pStopString);
315 } else {
316 dRet = atol(sDigits);
317 }
318 }
319 }
320
321 return dRet;
322}
323
324double CJS_PublicMethods::ParseStringToNumber(const FX_WCHAR* swSource) {
325 FX_BOOL bAllDigits = FALSE;
326 FX_BOOL bDot = FALSE;
327 FX_BOOL bSign = FALSE;
328 FX_BOOL bKXJS = FALSE;
329
330 return ParseNumber(swSource, bAllDigits, bDot, bSign, bKXJS);
331}
332
333FX_BOOL CJS_PublicMethods::ConvertStringToNumber(const FX_WCHAR* swSource,
334 double& dRet,
335 FX_BOOL& bDot) {
336 FX_BOOL bAllDigits = FALSE;
337 FX_BOOL bSign = FALSE;
338 FX_BOOL bKXJS = FALSE;
339
340 dRet = ParseNumber(swSource, bAllDigits, bDot, bSign, bKXJS);
341
342 return bAllDigits;
343}
344
Tom Sepez67fd5df2015-10-08 12:24:19 -0700345CJS_Array CJS_PublicMethods::AF_MakeArrayFromList(CJS_Runtime* pRuntime,
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700346 CJS_Value val) {
Tom Sepez67fd5df2015-10-08 12:24:19 -0700347 CJS_Array StrArray(pRuntime);
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700348 if (val.IsArrayObject()) {
349 val.ConvertToArray(StrArray);
Tom Sepez2f2ffec2015-07-23 14:42:09 -0700350 return StrArray;
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700351 }
352 CFX_WideString wsStr = val.ToCFXWideString();
353 CFX_ByteString t = CFX_ByteString::FromUnicode(wsStr);
354 const char* p = (const char*)t;
355
356 int ch = ',';
357 int nIndex = 0;
358
359 while (*p) {
360 const char* pTemp = strchr(p, ch);
Lei Zhang997de612015-11-04 18:17:53 -0800361 if (!pTemp) {
Tom Sepez67fd5df2015-10-08 12:24:19 -0700362 StrArray.SetElement(nIndex, CJS_Value(pRuntime, StrTrim(p).c_str()));
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700363 break;
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700364 }
Lei Zhang997de612015-11-04 18:17:53 -0800365
366 char* pSub = new char[pTemp - p + 1];
367 strncpy(pSub, p, pTemp - p);
368 *(pSub + (pTemp - p)) = '\0';
369
370 StrArray.SetElement(nIndex, CJS_Value(pRuntime, StrTrim(pSub).c_str()));
371 delete[] pSub;
372
373 nIndex++;
374 p = ++pTemp;
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700375 }
376 return StrArray;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700377}
378
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700379int CJS_PublicMethods::ParseStringInteger(const CFX_WideString& string,
380 int nStart,
381 int& nSkip,
382 int nMaxStep) {
383 int nRet = 0;
384 nSkip = 0;
385 for (int i = nStart, sz = string.GetLength(); i < sz; i++) {
386 if (i - nStart > 10)
387 break;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700388
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700389 FX_WCHAR c = string.GetAt(i);
390 if (IsDigit((wchar_t)c)) {
391 nRet = nRet * 10 + (c - '0');
392 nSkip = i - nStart + 1;
393 if (nSkip >= nMaxStep)
394 break;
395 } else
396 break;
397 }
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700398
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700399 return nRet;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700400}
401
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700402CFX_WideString CJS_PublicMethods::ParseStringString(
403 const CFX_WideString& string,
404 int nStart,
405 int& nSkip) {
406 CFX_WideString swRet;
407 nSkip = 0;
408 for (int i = nStart, sz = string.GetLength(); i < sz; i++) {
409 FX_WCHAR c = string.GetAt(i);
410 if ((c >= L'a' && c <= L'z') || (c >= L'A' && c <= L'Z')) {
411 swRet += c;
412 nSkip = i - nStart + 1;
413 } else
414 break;
415 }
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700416
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700417 return swRet;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700418}
419
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700420double CJS_PublicMethods::ParseNormalDate(const CFX_WideString& value,
421 FX_BOOL& bWrongFormat) {
422 double dt = JS_GetDateTime();
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700423
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700424 int nYear = JS_GetYearFromTime(dt);
425 int nMonth = JS_GetMonthFromTime(dt) + 1;
426 int nDay = JS_GetDayFromTime(dt);
427 int nHour = JS_GetHourFromTime(dt);
428 int nMin = JS_GetMinFromTime(dt);
429 int nSec = JS_GetSecFromTime(dt);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700430
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700431 int number[3];
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700432
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700433 int nSkip = 0;
434 int nLen = value.GetLength();
435 int nIndex = 0;
436 int i = 0;
437 while (i < nLen) {
438 if (nIndex > 2)
439 break;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700440
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700441 FX_WCHAR c = value.GetAt(i);
442 if (IsDigit((wchar_t)c)) {
443 number[nIndex++] = ParseStringInteger(value, i, nSkip, 4);
444 i += nSkip;
445 } else {
446 i++;
447 }
448 }
449
450 if (nIndex == 2) {
451 // case2: month/day
452 // case3: day/month
453 if ((number[0] >= 1 && number[0] <= 12) &&
454 (number[1] >= 1 && number[1] <= 31)) {
455 nMonth = number[0];
456 nDay = number[1];
457 } else if ((number[0] >= 1 && number[0] <= 31) &&
458 (number[1] >= 1 && number[1] <= 12)) {
459 nDay = number[0];
460 nMonth = number[1];
Tom Sepez2f2ffec2015-07-23 14:42:09 -0700461 }
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700462
Tom Sepez2f2ffec2015-07-23 14:42:09 -0700463 bWrongFormat = FALSE;
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700464 } else if (nIndex == 3) {
465 // case1: year/month/day
466 // case2: month/day/year
467 // case3: day/month/year
Tom Sepez5ffacd62014-07-18 14:42:12 -0700468
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700469 if (number[0] > 12 && (number[1] >= 1 && number[1] <= 12) &&
470 (number[2] >= 1 && number[2] <= 31)) {
471 nYear = number[0];
472 nMonth = number[1];
473 nDay = number[2];
474 } else if ((number[0] >= 1 && number[0] <= 12) &&
475 (number[1] >= 1 && number[1] <= 31) && number[2] > 31) {
476 nMonth = number[0];
477 nDay = number[1];
478 nYear = number[2];
479 } else if ((number[0] >= 1 && number[0] <= 31) &&
480 (number[1] >= 1 && number[1] <= 12) && number[2] > 31) {
481 nDay = number[0];
482 nMonth = number[1];
483 nYear = number[2];
Tom Sepez2f2ffec2015-07-23 14:42:09 -0700484 }
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700485
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700486 bWrongFormat = FALSE;
487 } else {
488 bWrongFormat = TRUE;
489 return dt;
490 }
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700491
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700492 CFX_WideString swTemp;
493 swTemp.Format(L"%d/%d/%d %d:%d:%d", nMonth, nDay, nYear, nHour, nMin, nSec);
494 return JS_DateParse(swTemp.c_str());
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700495}
496
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700497double CJS_PublicMethods::MakeRegularDate(const CFX_WideString& value,
498 const CFX_WideString& format,
499 FX_BOOL& bWrongFormat) {
500 double dt = JS_GetDateTime();
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700501
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700502 if (format.IsEmpty() || value.IsEmpty())
503 return dt;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700504
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700505 int nYear = JS_GetYearFromTime(dt);
506 int nMonth = JS_GetMonthFromTime(dt) + 1;
507 int nDay = JS_GetDayFromTime(dt);
508 int nHour = JS_GetHourFromTime(dt);
509 int nMin = JS_GetMinFromTime(dt);
510 int nSec = JS_GetSecFromTime(dt);
511
512 int nYearSub = 99; // nYear - 2000;
513
514 FX_BOOL bPm = FALSE;
515 FX_BOOL bExit = FALSE;
516 bWrongFormat = FALSE;
517
518 int i = 0;
519 int j = 0;
520
521 while (i < format.GetLength()) {
522 if (bExit)
523 break;
524
525 FX_WCHAR c = format.GetAt(i);
526 switch (c) {
527 case ':':
528 case '.':
529 case '-':
530 case '\\':
531 case '/':
532 i++;
533 j++;
534 break;
535
536 case 'y':
537 case 'm':
538 case 'd':
539 case 'H':
540 case 'h':
541 case 'M':
542 case 's':
543 case 't': {
544 int oldj = j;
545 int nSkip = 0;
546 int remaining = format.GetLength() - i - 1;
547
548 if (remaining == 0 || format.GetAt(i + 1) != c) {
549 switch (c) {
Tom Sepez2f2ffec2015-07-23 14:42:09 -0700550 case 'y':
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700551 i++;
552 j++;
553 break;
Tom Sepez2f2ffec2015-07-23 14:42:09 -0700554 case 'm':
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700555 nMonth = ParseStringInteger(value, j, nSkip, 2);
556 i++;
557 j += nSkip;
558 break;
Tom Sepez2f2ffec2015-07-23 14:42:09 -0700559 case 'd':
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700560 nDay = ParseStringInteger(value, j, nSkip, 2);
561 i++;
562 j += nSkip;
563 break;
Tom Sepez2f2ffec2015-07-23 14:42:09 -0700564 case 'H':
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700565 nHour = ParseStringInteger(value, j, nSkip, 2);
566 i++;
567 j += nSkip;
568 break;
Tom Sepez2f2ffec2015-07-23 14:42:09 -0700569 case 'h':
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700570 nHour = ParseStringInteger(value, j, nSkip, 2);
571 i++;
572 j += nSkip;
573 break;
Tom Sepez2f2ffec2015-07-23 14:42:09 -0700574 case 'M':
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700575 nMin = ParseStringInteger(value, j, nSkip, 2);
576 i++;
577 j += nSkip;
578 break;
Tom Sepez2f2ffec2015-07-23 14:42:09 -0700579 case 's':
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700580 nSec = ParseStringInteger(value, j, nSkip, 2);
581 i++;
582 j += nSkip;
583 break;
Tom Sepez2f2ffec2015-07-23 14:42:09 -0700584 case 't':
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700585 bPm = (j < value.GetLength() && value.GetAt(j) == 'p');
586 i++;
587 j++;
588 break;
589 }
590 } else if (remaining == 1 || format.GetAt(i + 2) != c) {
591 switch (c) {
592 case 'y':
593 nYear = ParseStringInteger(value, j, nSkip, 4);
594 i += 2;
595 j += nSkip;
596 break;
597 case 'm':
598 nMonth = ParseStringInteger(value, j, nSkip, 2);
599 i += 2;
600 j += nSkip;
601 break;
602 case 'd':
603 nDay = ParseStringInteger(value, j, nSkip, 2);
604 i += 2;
605 j += nSkip;
606 break;
607 case 'H':
608 nHour = ParseStringInteger(value, j, nSkip, 2);
609 i += 2;
610 j += nSkip;
611 break;
612 case 'h':
613 nHour = ParseStringInteger(value, j, nSkip, 2);
614 i += 2;
615 j += nSkip;
616 break;
617 case 'M':
618 nMin = ParseStringInteger(value, j, nSkip, 2);
619 i += 2;
620 j += nSkip;
621 break;
622 case 's':
623 nSec = ParseStringInteger(value, j, nSkip, 2);
624 i += 2;
625 j += nSkip;
626 break;
627 case 't':
628 bPm = (j + 1 < value.GetLength() && value.GetAt(j) == 'p' &&
629 value.GetAt(j + 1) == 'm');
630 i += 2;
631 j += 2;
632 break;
633 }
634 } else if (remaining == 2 || format.GetAt(i + 3) != c) {
635 switch (c) {
636 case 'm': {
637 CFX_WideString sMonth = ParseStringString(value, j, nSkip);
638 FX_BOOL bFind = FALSE;
639 for (int m = 0; m < 12; m++) {
640 if (sMonth.CompareNoCase(months[m]) == 0) {
641 nMonth = m + 1;
642 i += 3;
643 j += nSkip;
644 bFind = TRUE;
645 break;
Tom Sepez2f2ffec2015-07-23 14:42:09 -0700646 }
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700647 }
648
649 if (!bFind) {
650 nMonth = ParseStringInteger(value, j, nSkip, 3);
651 i += 3;
652 j += nSkip;
653 }
654 } break;
655 case 'y':
656 break;
Tom Sepez2f2ffec2015-07-23 14:42:09 -0700657 default:
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700658 i += 3;
659 j += 3;
660 break;
661 }
662 } else if (remaining == 3 || format.GetAt(i + 4) != c) {
663 switch (c) {
664 case 'y':
665 nYear = ParseStringInteger(value, j, nSkip, 4);
666 j += nSkip;
667 i += 4;
668 break;
669 case 'm': {
670 FX_BOOL bFind = FALSE;
671
672 CFX_WideString sMonth = ParseStringString(value, j, nSkip);
673 sMonth.MakeLower();
674
675 for (int m = 0; m < 12; m++) {
676 CFX_WideString sFullMonths = fullmonths[m];
677 sFullMonths.MakeLower();
678
679 if (sFullMonths.Find(sMonth.c_str(), 0) != -1) {
680 nMonth = m + 1;
681 i += 4;
682 j += nSkip;
683 bFind = TRUE;
684 break;
685 }
686 }
687
688 if (!bFind) {
689 nMonth = ParseStringInteger(value, j, nSkip, 4);
690 i += 4;
691 j += nSkip;
692 }
693 } break;
694 default:
695 i += 4;
696 j += 4;
697 break;
698 }
699 } else {
700 if (j >= value.GetLength() || format.GetAt(i) != value.GetAt(j)) {
701 bWrongFormat = TRUE;
702 bExit = TRUE;
703 }
704 i++;
705 j++;
Tom Sepez2f2ffec2015-07-23 14:42:09 -0700706 }
Tom Sepez85386422014-07-23 10:28:37 -0700707
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700708 if (oldj == j) {
709 bWrongFormat = TRUE;
710 bExit = TRUE;
711 }
712 }
713
714 break;
715 default:
716 if (value.GetLength() <= j) {
717 bExit = TRUE;
718 } else if (format.GetAt(i) != value.GetAt(j)) {
719 bWrongFormat = TRUE;
720 bExit = TRUE;
721 }
722
723 i++;
724 j++;
725 break;
726 }
727 }
728
729 if (bPm)
730 nHour += 12;
731
732 if (nYear >= 0 && nYear <= nYearSub)
733 nYear += 2000;
734
735 if (nMonth < 1 || nMonth > 12)
736 bWrongFormat = TRUE;
737
738 if (nDay < 1 || nDay > 31)
739 bWrongFormat = TRUE;
740
741 if (nHour < 0 || nHour > 24)
742 bWrongFormat = TRUE;
743
744 if (nMin < 0 || nMin > 60)
745 bWrongFormat = TRUE;
746
747 if (nSec < 0 || nSec > 60)
748 bWrongFormat = TRUE;
749
750 double dRet = 0;
751
752 if (bWrongFormat) {
753 dRet = ParseNormalDate(value, bWrongFormat);
754 } else {
755 dRet = JS_MakeDate(JS_MakeDay(nYear, nMonth - 1, nDay),
756 JS_MakeTime(nHour, nMin, nSec, 0));
757
758 if (JS_PortIsNan(dRet)) {
759 dRet = JS_DateParse(value.c_str());
760 }
761 }
762
763 if (JS_PortIsNan(dRet)) {
764 dRet = ParseNormalDate(value, bWrongFormat);
765 }
766
767 return dRet;
768}
769
770CFX_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;
Tom Sepez2f2ffec2015-07-23 14:42:09 -0700893 }
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700894
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700895 sRet += sPart;
896 }
897
898 return sRet;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700899}
900
901/* -------------------------------------------------------------------------- */
902
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700903// function AFNumber_Format(nDec, sepStyle, negStyle, currStyle, strCurrency,
904// bCurrencyPrepend)
Tom Sepezba038bc2015-10-08 12:03:00 -0700905FX_BOOL CJS_PublicMethods::AFNumber_Format(IJS_Context* cc,
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700906 const CJS_Parameters& params,
907 CJS_Value& vRet,
908 CFX_WideString& sError) {
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700909#if _FX_OS_ != _FX_ANDROID_
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700910 CJS_Context* pContext = (CJS_Context*)cc;
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700911 if (params.size() != 6) {
912 sError = JSGetStringFromID(pContext, IDS_STRING_JSPARAMERROR);
913 return FALSE;
914 }
Tom Sepez67fd5df2015-10-08 12:24:19 -0700915
916 CJS_Runtime* pRuntime = CJS_Runtime::FromContext(cc);
917 CJS_EventHandler* pEvent = pContext->GetEventHandler();
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700918 if (!pEvent->m_pValue)
919 return FALSE;
Tom Sepez67fd5df2015-10-08 12:24:19 -0700920
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700921 CFX_WideString& Value = pEvent->Value();
922 CFX_ByteString strValue = StrTrim(CFX_ByteString::FromUnicode(Value));
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700923 if (strValue.IsEmpty())
Tom Sepez2f2ffec2015-07-23 14:42:09 -0700924 return TRUE;
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700925
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)
Tom Sepezdfbf8e72015-10-14 14:17:26 -0700947 dValue += DOUBLE_CORRECT;
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700948
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
Tom Sepezdfbf8e72015-10-14 14:17:26 -0700996 for (int iDecPositive = iDec2 - 3; iDecPositive > 0; iDecPositive -= 3) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700997 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()) {
Tom Sepez67fd5df2015-10-08 12:24:19 -07001025 CJS_Array arColor(pRuntime);
1026 CJS_Value vColElm(pRuntime);
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001027 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
Tom Sepez67fd5df2015-10-08 12:24:19 -07001036 CJS_PropValue vProp(pRuntime);
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001037 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()) {
Tom Sepez67fd5df2015-10-08 12:24:19 -07001046 CJS_Array arColor(pRuntime);
1047 CJS_Value vColElm(pRuntime);
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001048 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
Tom Sepez67fd5df2015-10-08 12:24:19 -07001055 CJS_PropValue vProp(pRuntime);
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001056 vProp.StartGetting();
1057 fTarget->textColor(cc, vProp, sError);
1058
Tom Sepez67fd5df2015-10-08 12:24:19 -07001059 CJS_Array aProp(pRuntime);
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001060 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) {
Tom Sepez67fd5df2015-10-08 12:24:19 -07001068 CJS_PropValue vProp2(pRuntime);
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001069 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;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07001080}
1081
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001082// function AFNumber_Keystroke(nDec, sepStyle, negStyle, currStyle, strCurrency,
1083// bCurrencyPrepend)
Tom Sepezba038bc2015-10-08 12:03:00 -07001084FX_BOOL CJS_PublicMethods::AFNumber_Keystroke(IJS_Context* cc,
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001085 const CJS_Parameters& params,
1086 CJS_Value& vRet,
1087 CFX_WideString& sError) {
1088 CJS_Context* pContext = (CJS_Context*)cc;
1089 ASSERT(pContext != NULL);
1090 CJS_EventHandler* pEvent = pContext->GetEventHandler();
1091 ASSERT(pEvent != NULL);
Lei Zhanga6d9f0e2015-06-13 00:48:38 -07001092
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001093 if (params.size() < 2)
1094 return FALSE;
1095 int iSepStyle = params[1].ToInt();
Lei Zhanga6d9f0e2015-06-13 00:48:38 -07001096
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001097 if (iSepStyle < 0 || iSepStyle > 3)
1098 iSepStyle = 0;
1099 if (!pEvent->m_pValue)
1100 return FALSE;
1101 CFX_WideString& val = pEvent->Value();
1102 CFX_WideString& w_strChange = pEvent->Change();
1103 CFX_WideString w_strValue = val;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07001104
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001105 if (pEvent->WillCommit()) {
1106 CFX_WideString wstrChange = w_strChange;
1107 CFX_WideString wstrValue = StrLTrim(w_strValue.c_str());
1108 if (wstrValue.IsEmpty())
1109 return TRUE;
Lei Zhanga6d9f0e2015-06-13 00:48:38 -07001110
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001111 CFX_WideString swTemp = wstrValue;
1112 swTemp.Replace(L",", L".");
1113 if (!IsNumber(swTemp.c_str())) {
1114 pEvent->Rc() = FALSE;
1115 sError = JSGetStringFromID(pContext, IDS_STRING_JSAFNUMBER_KEYSTROKE);
1116 Alert(pContext, sError.c_str());
1117 return TRUE;
Tom Sepez2f2ffec2015-07-23 14:42:09 -07001118 }
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001119 return TRUE; // it happens after the last keystroke and before validating,
1120 }
Tom Sepez4f7bc042015-04-27 12:06:58 -07001121
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001122 std::wstring w_strValue2 = w_strValue.c_str();
1123 std::wstring w_strChange2 = w_strChange.c_str();
1124 std::wstring w_strSelected;
1125 if (-1 != pEvent->SelStart())
1126 w_strSelected = w_strValue2.substr(pEvent->SelStart(),
1127 (pEvent->SelEnd() - pEvent->SelStart()));
Lei Zhangb9c31972015-08-11 14:09:35 -07001128 bool bHasSign = (w_strValue2.find('-') != std::wstring::npos) &&
1129 (w_strSelected.find('-') == std::wstring::npos);
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001130 if (bHasSign) {
1131 // can't insert "change" in front to sign postion.
1132 if (pEvent->SelStart() == 0) {
1133 FX_BOOL& bRc = pEvent->Rc();
1134 bRc = FALSE;
1135 return TRUE;
Tom Sepez2f2ffec2015-07-23 14:42:09 -07001136 }
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001137 }
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07001138
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001139 char cSep = L'.';
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07001140
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001141 switch (iSepStyle) {
Tom Sepez2f2ffec2015-07-23 14:42:09 -07001142 case 0:
1143 case 1:
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001144 cSep = L'.';
1145 break;
Tom Sepez2f2ffec2015-07-23 14:42:09 -07001146 case 2:
1147 case 3:
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001148 cSep = L',';
1149 break;
1150 }
Lei Zhanga6d9f0e2015-06-13 00:48:38 -07001151
Lei Zhangb9c31972015-08-11 14:09:35 -07001152 bool bHasSep = (w_strValue2.find(cSep) != std::wstring::npos);
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001153 for (std::wstring::iterator it = w_strChange2.begin();
1154 it != w_strChange2.end(); it++) {
1155 if (*it == cSep) {
1156 if (bHasSep) {
1157 FX_BOOL& bRc = pEvent->Rc();
1158 bRc = FALSE;
Tom Sepez2f2ffec2015-07-23 14:42:09 -07001159 return TRUE;
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001160 }
1161 bHasSep = TRUE;
1162 continue;
1163 }
1164 if (*it == L'-') {
1165 if (bHasSign) {
1166 FX_BOOL& bRc = pEvent->Rc();
1167 bRc = FALSE;
1168 return TRUE;
1169 }
1170 if (it != w_strChange2.begin()) // sign's position is not correct
1171 {
1172 FX_BOOL& bRc = pEvent->Rc();
1173 bRc = FALSE;
1174 return TRUE;
1175 }
1176 if (pEvent->SelStart() != 0) {
1177 FX_BOOL& bRc = pEvent->Rc();
1178 bRc = FALSE;
1179 return TRUE;
1180 }
1181 bHasSign = TRUE;
1182 continue;
1183 }
1184
1185 if (!IsDigit(*it)) {
1186 FX_BOOL& bRc = pEvent->Rc();
1187 bRc = FALSE;
1188 return TRUE;
1189 }
1190 }
1191
1192 std::wstring w_prefix = w_strValue2.substr(0, pEvent->SelStart());
1193 std::wstring w_postfix;
1194 if (pEvent->SelEnd() < (int)w_strValue2.length())
1195 w_postfix = w_strValue2.substr(pEvent->SelEnd());
1196 w_strValue2 = w_prefix + w_strChange2 + w_postfix;
1197 w_strValue = w_strValue2.c_str();
1198 val = w_strValue;
1199 return TRUE;
1200}
1201
1202// function AFPercent_Format(nDec, sepStyle)
Tom Sepezba038bc2015-10-08 12:03:00 -07001203FX_BOOL CJS_PublicMethods::AFPercent_Format(IJS_Context* cc,
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001204 const CJS_Parameters& params,
1205 CJS_Value& vRet,
1206 CFX_WideString& sError) {
1207#if _FX_OS_ != _FX_ANDROID_
1208 CJS_Context* pContext = (CJS_Context*)cc;
1209 ASSERT(pContext != NULL);
1210 CJS_EventHandler* pEvent = pContext->GetEventHandler();
1211 ASSERT(pEvent != NULL);
1212
1213 if (params.size() != 2) {
1214 sError = JSGetStringFromID(pContext, IDS_STRING_JSPARAMERROR);
1215 return FALSE;
1216 }
1217 if (!pEvent->m_pValue)
1218 return FALSE;
1219
1220 CFX_WideString& Value = pEvent->Value();
1221 CFX_ByteString strValue = StrTrim(CFX_ByteString::FromUnicode(Value));
1222 if (strValue.IsEmpty())
1223 return TRUE;
1224
1225 int iDec = params[0].ToInt();
1226 if (iDec < 0)
1227 iDec = -iDec;
1228
1229 int iSepStyle = params[1].ToInt();
1230 if (iSepStyle < 0 || iSepStyle > 3)
1231 iSepStyle = 0;
1232
1233 //////////////////////////////////////////////////////
1234 // for processing decimal places
1235 double dValue = atof(strValue);
1236 dValue *= 100;
1237 if (iDec > 0)
1238 dValue += DOUBLE_CORRECT; //УÕý
1239
1240 int iDec2;
1241 int iNegative = 0;
1242 strValue = fcvt(dValue, iDec, &iDec2, &iNegative);
1243 if (strValue.IsEmpty()) {
1244 dValue = 0;
1245 strValue = fcvt(dValue, iDec, &iDec2, &iNegative);
1246 }
1247
1248 if (iDec2 < 0) {
1249 for (int iNum = 0; iNum < abs(iDec2); iNum++) {
1250 strValue = "0" + strValue;
1251 }
1252 iDec2 = 0;
1253 }
1254 int iMax = strValue.GetLength();
1255 if (iDec2 > iMax) {
1256 for (int iNum = 0; iNum <= iDec2 - iMax; iNum++) {
1257 strValue += "0";
1258 }
1259 iMax = iDec2 + 1;
1260 }
1261 ///////////////////////////////////////////////////////
1262 // for processing seperator style
1263 if (iDec2 < iMax) {
1264 if (iSepStyle == 0 || iSepStyle == 1) {
1265 strValue.Insert(iDec2, '.');
1266 iMax++;
1267 } else if (iSepStyle == 2 || iSepStyle == 3) {
1268 strValue.Insert(iDec2, ',');
1269 iMax++;
1270 }
1271
1272 if (iDec2 == 0)
1273 strValue.Insert(iDec2, '0');
1274 }
1275 if (iSepStyle == 0 || iSepStyle == 2) {
1276 char cSeperator;
1277 if (iSepStyle == 0)
1278 cSeperator = ',';
1279 else
1280 cSeperator = '.';
1281
Tom Sepezdfbf8e72015-10-14 14:17:26 -07001282 for (int iDecPositive = iDec2 - 3; iDecPositive > 0; iDecPositive -= 3) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001283 strValue.Insert(iDecPositive, cSeperator);
1284 iMax++;
1285 }
1286 }
1287 ////////////////////////////////////////////////////////////////////
1288 // negative mark
1289 if (iNegative)
1290 strValue = "-" + strValue;
1291 strValue += "%";
1292 Value = CFX_WideString::FromLocal(strValue);
1293#endif
1294 return TRUE;
1295}
1296// AFPercent_Keystroke(nDec, sepStyle)
Tom Sepezba038bc2015-10-08 12:03:00 -07001297FX_BOOL CJS_PublicMethods::AFPercent_Keystroke(IJS_Context* cc,
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001298 const CJS_Parameters& params,
1299 CJS_Value& vRet,
1300 CFX_WideString& sError) {
1301 return AFNumber_Keystroke(cc, params, vRet, sError);
1302}
1303
1304// function AFDate_FormatEx(cFormat)
Tom Sepezba038bc2015-10-08 12:03:00 -07001305FX_BOOL CJS_PublicMethods::AFDate_FormatEx(IJS_Context* cc,
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001306 const CJS_Parameters& params,
1307 CJS_Value& vRet,
1308 CFX_WideString& sError) {
1309 CJS_Context* pContext = (CJS_Context*)cc;
1310 ASSERT(pContext != NULL);
1311 CJS_EventHandler* pEvent = pContext->GetEventHandler();
1312 ASSERT(pEvent != NULL);
1313
1314 if (params.size() != 1) {
1315 sError = JSGetStringFromID(pContext, IDS_STRING_JSPARAMERROR);
1316 return FALSE;
1317 }
1318 if (!pEvent->m_pValue)
1319 return FALSE;
1320
1321 CFX_WideString& val = pEvent->Value();
1322 CFX_WideString strValue = val;
1323 if (strValue.IsEmpty())
1324 return TRUE;
1325
1326 CFX_WideString sFormat = params[0].ToCFXWideString();
1327 FX_BOOL bWrongFormat = FALSE;
1328 double dDate = 0.0f;
1329
1330 if (strValue.Find(L"GMT") != -1) {
1331 // for GMT format time
1332 // such as "Tue Aug 11 14:24:16 GMT+08002009"
1333 dDate = MakeInterDate(strValue);
1334 } else {
1335 dDate = MakeRegularDate(strValue, sFormat, bWrongFormat);
1336 }
1337
1338 if (JS_PortIsNan(dDate)) {
1339 CFX_WideString swMsg;
1340 swMsg.Format(JSGetStringFromID(pContext, IDS_STRING_JSPARSEDATE).c_str(),
1341 sFormat.c_str());
1342 Alert(pContext, swMsg.c_str());
1343 return FALSE;
1344 }
1345
1346 val = MakeFormatDate(dDate, sFormat);
1347 return TRUE;
1348}
1349
1350double CJS_PublicMethods::MakeInterDate(CFX_WideString strValue) {
1351 int nHour;
1352 int nMin;
1353 int nSec;
1354 int nYear;
1355 int nMonth;
1356 int nDay;
1357
1358 CFX_WideStringArray wsArray;
1359 CFX_WideString sMonth = L"";
1360 CFX_WideString sTemp = L"";
1361 int nSize = strValue.GetLength();
1362
1363 for (int i = 0; i < nSize; i++) {
1364 FX_WCHAR c = strValue.GetAt(i);
1365 if (c == L' ' || c == L':') {
1366 wsArray.Add(sTemp);
1367 sTemp = L"";
1368 continue;
1369 }
1370
1371 sTemp += c;
1372 }
1373
1374 wsArray.Add(sTemp);
1375 if (wsArray.GetSize() != 8)
1376 return 0;
1377
1378 sTemp = wsArray[1];
1379 if (sTemp.Compare(L"Jan") == 0)
1380 nMonth = 1;
1381 if (sTemp.Compare(L"Feb") == 0)
1382 nMonth = 2;
1383 if (sTemp.Compare(L"Mar") == 0)
1384 nMonth = 3;
1385 if (sTemp.Compare(L"Apr") == 0)
1386 nMonth = 4;
1387 if (sTemp.Compare(L"May") == 0)
1388 nMonth = 5;
1389 if (sTemp.Compare(L"Jun") == 0)
1390 nMonth = 6;
1391 if (sTemp.Compare(L"Jul") == 0)
1392 nMonth = 7;
1393 if (sTemp.Compare(L"Aug") == 0)
1394 nMonth = 8;
1395 if (sTemp.Compare(L"Sep") == 0)
1396 nMonth = 9;
1397 if (sTemp.Compare(L"Oct") == 0)
1398 nMonth = 10;
1399 if (sTemp.Compare(L"Nov") == 0)
1400 nMonth = 11;
1401 if (sTemp.Compare(L"Dec") == 0)
1402 nMonth = 12;
1403
1404 nDay = (int)ParseStringToNumber(wsArray[2].c_str());
1405 nHour = (int)ParseStringToNumber(wsArray[3].c_str());
1406 nMin = (int)ParseStringToNumber(wsArray[4].c_str());
1407 nSec = (int)ParseStringToNumber(wsArray[5].c_str());
1408 nYear = (int)ParseStringToNumber(wsArray[7].c_str());
1409
1410 double dRet = JS_MakeDate(JS_MakeDay(nYear, nMonth - 1, nDay),
1411 JS_MakeTime(nHour, nMin, nSec, 0));
1412
1413 if (JS_PortIsNan(dRet)) {
1414 dRet = JS_DateParse(strValue.c_str());
1415 }
1416
1417 return dRet;
1418}
1419
1420// AFDate_KeystrokeEx(cFormat)
Tom Sepezba038bc2015-10-08 12:03:00 -07001421FX_BOOL CJS_PublicMethods::AFDate_KeystrokeEx(IJS_Context* cc,
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001422 const CJS_Parameters& params,
1423 CJS_Value& vRet,
1424 CFX_WideString& sError) {
1425 CJS_Context* pContext = (CJS_Context*)cc;
1426 ASSERT(pContext != NULL);
1427 CJS_EventHandler* pEvent = pContext->GetEventHandler();
1428 ASSERT(pEvent != NULL);
1429
1430 if (params.size() != 1) {
1431 sError = L"AFDate_KeystrokeEx's parameters' size r not correct";
1432 return FALSE;
1433 }
1434
1435 if (pEvent->WillCommit()) {
1436 if (!pEvent->m_pValue)
1437 return FALSE;
1438 CFX_WideString strValue = pEvent->Value();
1439 if (strValue.IsEmpty())
1440 return TRUE;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07001441
Tom Sepez2f2ffec2015-07-23 14:42:09 -07001442 CFX_WideString sFormat = params[0].ToCFXWideString();
1443 FX_BOOL bWrongFormat = FALSE;
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001444 double dRet = MakeRegularDate(strValue, sFormat, bWrongFormat);
1445 if (bWrongFormat || JS_PortIsNan(dRet)) {
1446 CFX_WideString swMsg;
1447 swMsg.Format(JSGetStringFromID(pContext, IDS_STRING_JSPARSEDATE).c_str(),
1448 sFormat.c_str());
1449 Alert(pContext, swMsg.c_str());
1450 pEvent->Rc() = FALSE;
1451 return TRUE;
Tom Sepez2f2ffec2015-07-23 14:42:09 -07001452 }
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001453 }
1454 return TRUE;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07001455}
1456
Tom Sepezba038bc2015-10-08 12:03:00 -07001457FX_BOOL CJS_PublicMethods::AFDate_Format(IJS_Context* cc,
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001458 const CJS_Parameters& params,
1459 CJS_Value& vRet,
1460 CFX_WideString& sError) {
Tom Sepez67fd5df2015-10-08 12:24:19 -07001461 CJS_Context* pContext = (CJS_Context*)cc;
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001462 if (params.size() != 1) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001463 sError = JSGetStringFromID(pContext, IDS_STRING_JSPARAMERROR);
1464 return FALSE;
1465 }
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07001466
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001467 int iIndex = params[0].ToInt();
1468 const FX_WCHAR* cFormats[] = {L"m/d",
1469 L"m/d/yy",
1470 L"mm/dd/yy",
1471 L"mm/yy",
1472 L"d-mmm",
1473 L"d-mmm-yy",
1474 L"dd-mmm-yy",
1475 L"yy-mm-dd",
1476 L"mmm-yy",
1477 L"mmmm-yy",
1478 L"mmm d, yyyy",
1479 L"mmmm d, yyyy",
1480 L"m/d/yy h:MM tt",
1481 L"m/d/yy HH:MM"};
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07001482
Lei Zhanga0f67242015-08-17 15:39:30 -07001483 if (iIndex < 0 || (static_cast<size_t>(iIndex) >= FX_ArraySize(cFormats)))
1484 iIndex = 0;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07001485
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001486 CJS_Parameters newParams;
Tom Sepez67fd5df2015-10-08 12:24:19 -07001487 newParams.push_back(
1488 CJS_Value(CJS_Runtime::FromContext(cc), cFormats[iIndex]));
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001489 return AFDate_FormatEx(cc, newParams, vRet, sError);
1490}
Lei Zhanga6d9f0e2015-06-13 00:48:38 -07001491
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001492// AFDate_KeystrokeEx(cFormat)
Tom Sepezba038bc2015-10-08 12:03:00 -07001493FX_BOOL CJS_PublicMethods::AFDate_Keystroke(IJS_Context* cc,
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001494 const CJS_Parameters& params,
1495 CJS_Value& vRet,
1496 CFX_WideString& sError) {
Tom Sepez67fd5df2015-10-08 12:24:19 -07001497 CJS_Context* pContext = (CJS_Context*)cc;
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001498 if (params.size() != 1) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001499 sError = JSGetStringFromID(pContext, IDS_STRING_JSPARAMERROR);
1500 return FALSE;
1501 }
1502
1503 int iIndex = params[0].ToInt();
1504 const FX_WCHAR* cFormats[] = {L"m/d",
1505 L"m/d/yy",
1506 L"mm/dd/yy",
1507 L"mm/yy",
1508 L"d-mmm",
1509 L"d-mmm-yy",
1510 L"dd-mmm-yy",
1511 L"yy-mm-dd",
1512 L"mmm-yy",
1513 L"mmmm-yy",
1514 L"mmm d, yyyy",
1515 L"mmmm d, yyyy",
1516 L"m/d/yy h:MM tt",
1517 L"m/d/yy HH:MM"};
1518
Lei Zhanga0f67242015-08-17 15:39:30 -07001519 if (iIndex < 0 || (static_cast<size_t>(iIndex) >= FX_ArraySize(cFormats)))
1520 iIndex = 0;
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001521
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001522 CJS_Parameters newParams;
Tom Sepez67fd5df2015-10-08 12:24:19 -07001523 newParams.push_back(
1524 CJS_Value(CJS_Runtime::FromContext(cc), cFormats[iIndex]));
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001525 return AFDate_KeystrokeEx(cc, newParams, vRet, sError);
1526}
1527
1528// function AFTime_Format(ptf)
Tom Sepezba038bc2015-10-08 12:03:00 -07001529FX_BOOL CJS_PublicMethods::AFTime_Format(IJS_Context* cc,
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001530 const CJS_Parameters& params,
1531 CJS_Value& vRet,
1532 CFX_WideString& sError) {
Tom Sepez67fd5df2015-10-08 12:24:19 -07001533 CJS_Context* pContext = (CJS_Context*)cc;
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001534 if (params.size() != 1) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001535 sError = JSGetStringFromID(pContext, IDS_STRING_JSPARAMERROR);
1536 return FALSE;
1537 }
1538
1539 int iIndex = params[0].ToInt();
1540 const FX_WCHAR* cFormats[] = {L"HH:MM", L"h:MM tt", L"HH:MM:ss",
1541 L"h:MM:ss tt"};
1542
Lei Zhanga0f67242015-08-17 15:39:30 -07001543 if (iIndex < 0 || (static_cast<size_t>(iIndex) >= FX_ArraySize(cFormats)))
1544 iIndex = 0;
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001545
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001546 CJS_Parameters newParams;
Tom Sepez67fd5df2015-10-08 12:24:19 -07001547 newParams.push_back(
1548 CJS_Value(CJS_Runtime::FromContext(cc), cFormats[iIndex]));
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001549 return AFDate_FormatEx(cc, newParams, vRet, sError);
1550}
1551
Tom Sepezba038bc2015-10-08 12:03:00 -07001552FX_BOOL CJS_PublicMethods::AFTime_Keystroke(IJS_Context* cc,
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001553 const CJS_Parameters& params,
1554 CJS_Value& vRet,
1555 CFX_WideString& sError) {
Tom Sepez67fd5df2015-10-08 12:24:19 -07001556 CJS_Context* pContext = (CJS_Context*)cc;
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001557 if (params.size() != 1) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001558 sError = JSGetStringFromID(pContext, IDS_STRING_JSPARAMERROR);
1559 return FALSE;
1560 }
1561
1562 int iIndex = params[0].ToInt();
1563 const FX_WCHAR* cFormats[] = {L"HH:MM", L"h:MM tt", L"HH:MM:ss",
1564 L"h:MM:ss tt"};
1565
Lei Zhanga0f67242015-08-17 15:39:30 -07001566 if (iIndex < 0 || (static_cast<size_t>(iIndex) >= FX_ArraySize(cFormats)))
1567 iIndex = 0;
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001568
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001569 CJS_Parameters newParams;
Tom Sepez67fd5df2015-10-08 12:24:19 -07001570 newParams.push_back(
1571 CJS_Value(CJS_Runtime::FromContext(cc), cFormats[iIndex]));
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001572 return AFDate_KeystrokeEx(cc, newParams, vRet, sError);
1573}
1574
Tom Sepezba038bc2015-10-08 12:03:00 -07001575FX_BOOL CJS_PublicMethods::AFTime_FormatEx(IJS_Context* cc,
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001576 const CJS_Parameters& params,
1577 CJS_Value& vRet,
1578 CFX_WideString& sError) {
1579 return AFDate_FormatEx(cc, params, vRet, sError);
1580}
1581
Tom Sepezba038bc2015-10-08 12:03:00 -07001582FX_BOOL CJS_PublicMethods::AFTime_KeystrokeEx(IJS_Context* cc,
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001583 const CJS_Parameters& params,
1584 CJS_Value& vRet,
1585 CFX_WideString& sError) {
1586 return AFDate_KeystrokeEx(cc, params, vRet, sError);
1587}
1588
1589// function AFSpecial_Format(psf)
Tom Sepezba038bc2015-10-08 12:03:00 -07001590FX_BOOL CJS_PublicMethods::AFSpecial_Format(IJS_Context* cc,
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001591 const CJS_Parameters& params,
1592 CJS_Value& vRet,
1593 CFX_WideString& sError) {
1594 CJS_Context* pContext = (CJS_Context*)cc;
1595 ASSERT(pContext != NULL);
1596
1597 if (params.size() != 1) {
1598 sError = JSGetStringFromID(pContext, IDS_STRING_JSPARAMERROR);
1599 return FALSE;
1600 }
1601
1602 std::string cFormat;
1603 int iIndex = params[0].ToInt();
1604
1605 CJS_EventHandler* pEvent = pContext->GetEventHandler();
1606 ASSERT(pEvent != NULL);
1607
1608 if (!pEvent->m_pValue)
1609 return FALSE;
1610 CFX_WideString& Value = pEvent->Value();
1611 std::string strSrc = CFX_ByteString::FromUnicode(Value).c_str();
1612
1613 switch (iIndex) {
Tom Sepez2f2ffec2015-07-23 14:42:09 -07001614 case 0:
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001615 cFormat = "99999";
1616 break;
Tom Sepez2f2ffec2015-07-23 14:42:09 -07001617 case 1:
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001618 cFormat = "99999-9999";
1619 break;
1620 case 2: {
1621 std::string NumberStr;
1622 util::printx("9999999999", strSrc, NumberStr);
1623 if (NumberStr.length() >= 10)
1624 cFormat = "(999) 999-9999";
1625 else
1626 cFormat = "999-9999";
1627 break;
1628 }
Tom Sepez2f2ffec2015-07-23 14:42:09 -07001629 case 3:
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001630 cFormat = "999-99-9999";
1631 break;
1632 }
1633
1634 std::string strDes;
1635 util::printx(cFormat, strSrc, strDes);
1636 Value = CFX_WideString::FromLocal(strDes.c_str());
1637 return TRUE;
1638}
1639
1640// function AFSpecial_KeystrokeEx(mask)
Tom Sepezba038bc2015-10-08 12:03:00 -07001641FX_BOOL CJS_PublicMethods::AFSpecial_KeystrokeEx(IJS_Context* cc,
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001642 const CJS_Parameters& params,
1643 CJS_Value& vRet,
1644 CFX_WideString& sError) {
1645 CJS_Context* pContext = (CJS_Context*)cc;
1646 ASSERT(pContext != NULL);
1647 CJS_EventHandler* pEvent = pContext->GetEventHandler();
1648
1649 ASSERT(pEvent != NULL);
1650
1651 if (params.size() < 1) {
1652 sError = JSGetStringFromID(pContext, IDS_STRING_JSPARAMERROR);
1653 return FALSE;
1654 }
1655
1656 if (!pEvent->m_pValue)
1657 return FALSE;
1658 CFX_WideString& valEvent = pEvent->Value();
1659
1660 CFX_WideString wstrMask = params[0].ToCFXWideString();
1661 if (wstrMask.IsEmpty())
1662 return TRUE;
1663
Lei Zhanga0f67242015-08-17 15:39:30 -07001664 const size_t wstrMaskLen = wstrMask.GetLength();
1665 const std::wstring wstrValue = valEvent.c_str();
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001666
1667 if (pEvent->WillCommit()) {
1668 if (wstrValue.empty())
1669 return TRUE;
Lei Zhanga0f67242015-08-17 15:39:30 -07001670 size_t iIndexMask = 0;
1671 for (const auto& w_Value : wstrValue) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001672 if (!maskSatisfied(w_Value, wstrMask[iIndexMask]))
Tom Sepez2f2ffec2015-07-23 14:42:09 -07001673 break;
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001674 iIndexMask++;
Tom Sepez2f2ffec2015-07-23 14:42:09 -07001675 }
Lei Zhanga6d9f0e2015-06-13 00:48:38 -07001676
Lei Zhanga0f67242015-08-17 15:39:30 -07001677 if (iIndexMask != wstrMaskLen ||
1678 (iIndexMask != wstrValue.size() && wstrMaskLen != 0)) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001679 Alert(
1680 pContext,
1681 JSGetStringFromID(pContext, IDS_STRING_JSAFNUMBER_KEYSTROKE).c_str());
1682 pEvent->Rc() = FALSE;
1683 }
Tom Sepez2f2ffec2015-07-23 14:42:09 -07001684 return TRUE;
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001685 }
1686
1687 CFX_WideString& wideChange = pEvent->Change();
1688 std::wstring wChange = wideChange.c_str();
1689 if (wChange.empty())
1690 return TRUE;
1691
1692 int iIndexMask = pEvent->SelStart();
1693
Lei Zhanga0f67242015-08-17 15:39:30 -07001694 size_t combined_len = wstrValue.length() + wChange.length() -
1695 (pEvent->SelEnd() - pEvent->SelStart());
1696 if (combined_len > wstrMaskLen) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001697 Alert(pContext,
1698 JSGetStringFromID(pContext, IDS_STRING_JSPARAM_TOOLONG).c_str());
1699 pEvent->Rc() = FALSE;
1700 return TRUE;
1701 }
1702
Lei Zhanga0f67242015-08-17 15:39:30 -07001703 if (iIndexMask >= wstrMaskLen && (!wChange.empty())) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001704 Alert(pContext,
1705 JSGetStringFromID(pContext, IDS_STRING_JSPARAM_TOOLONG).c_str());
1706 pEvent->Rc() = FALSE;
1707 return TRUE;
1708 }
1709
1710 for (std::wstring::iterator it = wChange.begin(); it != wChange.end(); it++) {
Lei Zhanga0f67242015-08-17 15:39:30 -07001711 if (iIndexMask >= wstrMaskLen) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001712 Alert(pContext,
1713 JSGetStringFromID(pContext, IDS_STRING_JSPARAM_TOOLONG).c_str());
1714 pEvent->Rc() = FALSE;
1715 return TRUE;
1716 }
1717 wchar_t w_Mask = wstrMask[iIndexMask];
1718 if (!isReservedMaskChar(w_Mask)) {
1719 *it = w_Mask;
1720 }
1721 wchar_t w_Change = *it;
1722 if (!maskSatisfied(w_Change, w_Mask)) {
1723 pEvent->Rc() = FALSE;
1724 return TRUE;
1725 }
1726 iIndexMask++;
1727 }
1728
1729 wideChange = wChange.c_str();
1730 return TRUE;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07001731}
1732
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001733// function AFSpecial_Keystroke(psf)
Tom Sepezba038bc2015-10-08 12:03:00 -07001734FX_BOOL CJS_PublicMethods::AFSpecial_Keystroke(IJS_Context* cc,
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001735 const CJS_Parameters& params,
1736 CJS_Value& vRet,
1737 CFX_WideString& sError) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001738 CJS_Context* pContext = (CJS_Context*)cc;
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001739 if (params.size() != 1) {
1740 sError = JSGetStringFromID(pContext, IDS_STRING_JSPARAMERROR);
1741 return FALSE;
1742 }
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07001743
Tom Sepez67fd5df2015-10-08 12:24:19 -07001744 CJS_EventHandler* pEvent = pContext->GetEventHandler();
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001745 if (!pEvent->m_pValue)
1746 return FALSE;
Tom Sepez67fd5df2015-10-08 12:24:19 -07001747
1748 std::string cFormat;
1749 int iIndex = params[0].ToInt();
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001750 CFX_WideString& val = pEvent->Value();
1751 std::string strSrc = CFX_ByteString::FromUnicode(val).c_str();
1752 std::wstring wstrChange = pEvent->Change().c_str();
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07001753
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001754 switch (iIndex) {
Tom Sepez2f2ffec2015-07-23 14:42:09 -07001755 case 0:
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001756 cFormat = "99999";
1757 break;
Tom Sepez2f2ffec2015-07-23 14:42:09 -07001758 case 1:
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001759 // cFormat = "99999-9999";
1760 cFormat = "999999999";
1761 break;
1762 case 2: {
1763 std::string NumberStr;
1764 util::printx("9999999999", strSrc, NumberStr);
1765 if (strSrc.length() + wstrChange.length() > 7)
1766 // cFormat = "(999) 999-9999";
1767 cFormat = "9999999999";
1768 else
1769 // cFormat = "999-9999";
1770 cFormat = "9999999";
1771 break;
1772 }
Tom Sepez2f2ffec2015-07-23 14:42:09 -07001773 case 3:
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001774 // cFormat = "999-99-9999";
1775 cFormat = "999999999";
1776 break;
1777 }
Lei Zhanga6d9f0e2015-06-13 00:48:38 -07001778
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001779 CJS_Parameters params2;
Tom Sepez67fd5df2015-10-08 12:24:19 -07001780 params2.push_back(CJS_Value(CJS_Runtime::FromContext(cc), cFormat.c_str()));
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001781 return AFSpecial_KeystrokeEx(cc, params2, vRet, sError);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07001782}
1783
Tom Sepezba038bc2015-10-08 12:03:00 -07001784FX_BOOL CJS_PublicMethods::AFMergeChange(IJS_Context* cc,
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001785 const CJS_Parameters& params,
1786 CJS_Value& vRet,
1787 CFX_WideString& sError) {
1788 CJS_Context* pContext = (CJS_Context*)cc;
1789 ASSERT(pContext != NULL);
1790 CJS_EventHandler* pEventHandler = pContext->GetEventHandler();
1791 ASSERT(pEventHandler != NULL);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07001792
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001793 if (params.size() != 1) {
1794 sError = JSGetStringFromID(pContext, IDS_STRING_JSPARAMERROR);
1795 return FALSE;
1796 }
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07001797
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001798 CFX_WideString swValue;
Lei Zhang997de612015-11-04 18:17:53 -08001799 if (pEventHandler->m_pValue)
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001800 swValue = pEventHandler->Value();
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07001801
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001802 if (pEventHandler->WillCommit()) {
1803 vRet = swValue.c_str();
Tom Sepez2f2ffec2015-07-23 14:42:09 -07001804 return TRUE;
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001805 }
1806
1807 CFX_WideString prefix, postfix;
1808
1809 if (pEventHandler->SelStart() >= 0)
1810 prefix = swValue.Mid(0, pEventHandler->SelStart());
1811 else
1812 prefix = L"";
1813
1814 if (pEventHandler->SelEnd() >= 0 &&
1815 pEventHandler->SelEnd() <= swValue.GetLength())
1816 postfix = swValue.Mid(pEventHandler->SelEnd(),
1817 swValue.GetLength() - pEventHandler->SelEnd());
1818 else
1819 postfix = L"";
1820
1821 vRet = (prefix + pEventHandler->Change() + postfix).c_str();
1822
1823 return TRUE;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07001824}
1825
Tom Sepezba038bc2015-10-08 12:03:00 -07001826FX_BOOL CJS_PublicMethods::AFParseDateEx(IJS_Context* cc,
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001827 const CJS_Parameters& params,
1828 CJS_Value& vRet,
1829 CFX_WideString& sError) {
1830 CJS_Context* pContext = (CJS_Context*)cc;
1831 ASSERT(pContext != NULL);
1832
1833 if (params.size() != 2) {
1834 sError = JSGetStringFromID(pContext, IDS_STRING_JSPARAMERROR);
1835 return FALSE;
1836 }
1837
1838 CFX_WideString sValue = params[0].ToCFXWideString();
1839 CFX_WideString sFormat = params[1].ToCFXWideString();
1840
1841 FX_BOOL bWrongFormat = FALSE;
1842 double dDate = MakeRegularDate(sValue, sFormat, bWrongFormat);
1843
1844 if (JS_PortIsNan(dDate)) {
1845 CFX_WideString swMsg;
1846 swMsg.Format(JSGetStringFromID(pContext, IDS_STRING_JSPARSEDATE).c_str(),
1847 sFormat.c_str());
1848 Alert((CJS_Context*)cc, swMsg.c_str());
1849 return FALSE;
1850 }
1851
1852 vRet = dDate;
1853 return TRUE;
1854}
1855
Tom Sepezba038bc2015-10-08 12:03:00 -07001856FX_BOOL CJS_PublicMethods::AFSimple(IJS_Context* cc,
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001857 const CJS_Parameters& params,
1858 CJS_Value& vRet,
1859 CFX_WideString& sError) {
1860 if (params.size() != 3) {
1861 CJS_Context* pContext = (CJS_Context*)cc;
Tom Sepez2f2ffec2015-07-23 14:42:09 -07001862 ASSERT(pContext != NULL);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07001863
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001864 sError = JSGetStringFromID(pContext, IDS_STRING_JSPARAMERROR);
1865 return FALSE;
1866 }
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07001867
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001868 vRet = (double)AF_Simple(params[0].ToCFXWideString().c_str(),
1869 params[1].ToDouble(), params[2].ToDouble());
1870 return TRUE;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07001871}
1872
Tom Sepezba038bc2015-10-08 12:03:00 -07001873FX_BOOL CJS_PublicMethods::AFMakeNumber(IJS_Context* cc,
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001874 const CJS_Parameters& params,
1875 CJS_Value& vRet,
1876 CFX_WideString& sError) {
1877 if (params.size() != 1) {
1878 CJS_Context* pContext = (CJS_Context*)cc;
Tom Sepez2f2ffec2015-07-23 14:42:09 -07001879 ASSERT(pContext != NULL);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07001880
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001881 sError = JSGetStringFromID(pContext, IDS_STRING_JSPARAMERROR);
1882 return FALSE;
1883 }
1884 vRet = ParseStringToNumber(params[0].ToCFXWideString().c_str());
1885 return TRUE;
1886}
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07001887
Tom Sepezba038bc2015-10-08 12:03:00 -07001888FX_BOOL CJS_PublicMethods::AFSimple_Calculate(IJS_Context* cc,
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001889 const CJS_Parameters& params,
1890 CJS_Value& vRet,
1891 CFX_WideString& sError) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001892 CJS_Context* pContext = (CJS_Context*)cc;
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001893 if (params.size() != 2) {
1894 sError = JSGetStringFromID(pContext, IDS_STRING_JSPARAMERROR);
1895 return FALSE;
1896 }
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07001897
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001898 CJS_Value params1 = params[1];
Tom Sepez39bfe122015-09-17 15:25:23 -07001899 if (!params1.IsArrayObject() && params1.GetType() != CJS_Value::VT_string) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001900 sError = JSGetStringFromID(pContext, IDS_STRING_JSPARAMERROR);
1901 return FALSE;
1902 }
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07001903
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001904 CPDFSDK_Document* pReaderDoc = pContext->GetReaderDocument();
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001905 CPDFSDK_InterForm* pReaderInterForm = pReaderDoc->GetInterForm();
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001906 CPDF_InterForm* pInterForm = pReaderInterForm->GetInterForm();
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07001907
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001908 CFX_WideString sFunction = params[0].ToCFXWideString();
Tom Sepez67fd5df2015-10-08 12:24:19 -07001909 double dValue = wcscmp(sFunction.c_str(), L"PRD") == 0 ? 1.0 : 0.0;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07001910
Tom Sepez67fd5df2015-10-08 12:24:19 -07001911 CJS_Runtime* pRuntime = CJS_Runtime::FromContext(cc);
1912 CJS_Array FieldNameArray = AF_MakeArrayFromList(pRuntime, params1);
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001913 int nFieldsCount = 0;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07001914
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001915 for (int i = 0, isz = FieldNameArray.GetLength(); i < isz; i++) {
Tom Sepez67fd5df2015-10-08 12:24:19 -07001916 CJS_Value jsValue(pRuntime);
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001917 FieldNameArray.GetElement(i, jsValue);
1918 CFX_WideString wsFieldName = jsValue.ToCFXWideString();
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07001919
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001920 for (int j = 0, jsz = pInterForm->CountFields(wsFieldName); j < jsz; j++) {
1921 if (CPDF_FormField* pFormField = pInterForm->GetField(j, wsFieldName)) {
1922 double dTemp = 0.0;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07001923
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001924 switch (pFormField->GetFieldType()) {
1925 case FIELDTYPE_TEXTFIELD:
1926 case FIELDTYPE_COMBOBOX: {
1927 dTemp = ParseStringToNumber(pFormField->GetValue().c_str());
1928 break;
1929 }
1930 case FIELDTYPE_PUSHBUTTON: {
1931 dTemp = 0.0;
1932 break;
1933 }
1934 case FIELDTYPE_CHECKBOX:
1935 case FIELDTYPE_RADIOBUTTON: {
1936 dTemp = 0.0;
1937 for (int c = 0, csz = pFormField->CountControls(); c < csz; c++) {
1938 if (CPDF_FormControl* pFormCtrl = pFormField->GetControl(c)) {
1939 if (pFormCtrl->IsChecked()) {
1940 dTemp +=
1941 ParseStringToNumber(pFormCtrl->GetExportValue().c_str());
1942 break;
1943 } else
1944 continue;
1945 }
Tom Sepez2f2ffec2015-07-23 14:42:09 -07001946 }
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001947 break;
1948 }
1949 case FIELDTYPE_LISTBOX: {
1950 dTemp = 0.0;
1951 if (pFormField->CountSelectedItems() > 1)
1952 break;
1953 else {
1954 dTemp = ParseStringToNumber(pFormField->GetValue().c_str());
1955 break;
1956 }
1957 }
1958 default:
1959 break;
Tom Sepez2f2ffec2015-07-23 14:42:09 -07001960 }
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001961
1962 if (i == 0 && j == 0 && (wcscmp(sFunction.c_str(), L"MIN") == 0 ||
1963 wcscmp(sFunction.c_str(), L"MAX") == 0))
1964 dValue = dTemp;
1965
1966 dValue = AF_Simple(sFunction.c_str(), dValue, dTemp);
1967
1968 nFieldsCount++;
1969 }
Tom Sepez2f2ffec2015-07-23 14:42:09 -07001970 }
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001971 }
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07001972
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001973 if (wcscmp(sFunction.c_str(), L"AVG") == 0 && nFieldsCount > 0)
1974 dValue /= nFieldsCount;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07001975
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001976 dValue = (double)floor(dValue * FXSYS_pow((double)10, (double)6) + 0.49) /
1977 FXSYS_pow((double)10, (double)6);
Tom Sepez67fd5df2015-10-08 12:24:19 -07001978 CJS_Value jsValue(pRuntime, dValue);
foxit8b544ed2015-09-10 14:57:54 +08001979 if (pContext->GetEventHandler()->m_pValue)
1980 pContext->GetEventHandler()->Value() = jsValue.ToCFXWideString();
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07001981
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001982 return TRUE;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07001983}
1984
Lei Zhanga6d9f0e2015-06-13 00:48:38 -07001985/* This function validates the current event to ensure that its value is
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07001986** within the specified range. */
1987
Tom Sepezba038bc2015-10-08 12:03:00 -07001988FX_BOOL CJS_PublicMethods::AFRange_Validate(IJS_Context* cc,
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001989 const CJS_Parameters& params,
1990 CJS_Value& vRet,
1991 CFX_WideString& sError) {
1992 CJS_Context* pContext = (CJS_Context*)cc;
1993 ASSERT(pContext != NULL);
1994 CJS_EventHandler* pEvent = pContext->GetEventHandler();
1995 ASSERT(pEvent != NULL);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07001996
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001997 if (params.size() != 4) {
1998 sError = JSGetStringFromID(pContext, IDS_STRING_JSPARAMERROR);
1999 return FALSE;
2000 }
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07002001
Nico Weber9d8ec5a2015-08-04 13:00:21 -07002002 if (!pEvent->m_pValue)
2003 return FALSE;
2004 if (pEvent->Value().IsEmpty())
Tom Sepez2f2ffec2015-07-23 14:42:09 -07002005 return TRUE;
Nico Weber9d8ec5a2015-08-04 13:00:21 -07002006 double dEentValue = atof(CFX_ByteString::FromUnicode(pEvent->Value()));
2007 FX_BOOL bGreaterThan = params[0].ToBool();
2008 double dGreaterThan = params[1].ToDouble();
2009 FX_BOOL bLessThan = params[2].ToBool();
2010 double dLessThan = params[3].ToDouble();
2011 CFX_WideString swMsg;
2012
2013 if (bGreaterThan && bLessThan) {
2014 if (dEentValue < dGreaterThan || dEentValue > dLessThan)
2015 swMsg.Format(JSGetStringFromID(pContext, IDS_STRING_JSRANGE1).c_str(),
2016 params[1].ToCFXWideString().c_str(),
2017 params[3].ToCFXWideString().c_str());
2018 } else if (bGreaterThan) {
2019 if (dEentValue < dGreaterThan)
2020 swMsg.Format(JSGetStringFromID(pContext, IDS_STRING_JSRANGE2).c_str(),
2021 params[1].ToCFXWideString().c_str());
2022 } else if (bLessThan) {
2023 if (dEentValue > dLessThan)
2024 swMsg.Format(JSGetStringFromID(pContext, IDS_STRING_JSRANGE3).c_str(),
2025 params[3].ToCFXWideString().c_str());
2026 }
2027
2028 if (!swMsg.IsEmpty()) {
2029 Alert(pContext, swMsg.c_str());
2030 pEvent->Rc() = FALSE;
2031 }
2032 return TRUE;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07002033}
2034
Tom Sepezba038bc2015-10-08 12:03:00 -07002035FX_BOOL CJS_PublicMethods::AFExtractNums(IJS_Context* cc,
Nico Weber9d8ec5a2015-08-04 13:00:21 -07002036 const CJS_Parameters& params,
2037 CJS_Value& vRet,
2038 CFX_WideString& sError) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -07002039 CJS_Context* pContext = (CJS_Context*)cc;
Nico Weber9d8ec5a2015-08-04 13:00:21 -07002040 if (params.size() != 1) {
2041 sError = JSGetStringFromID(pContext, IDS_STRING_JSPARAMERROR);
2042 return FALSE;
2043 }
2044
Tom Sepez67fd5df2015-10-08 12:24:19 -07002045 CJS_Runtime* pRuntime = CJS_Runtime::FromContext(cc);
2046 CJS_Array nums(pRuntime);
Nico Weber9d8ec5a2015-08-04 13:00:21 -07002047
2048 CFX_WideString str = params[0].ToCFXWideString();
2049 CFX_WideString sPart;
2050
2051 if (str.GetAt(0) == L'.' || str.GetAt(0) == L',')
2052 str = L"0" + str;
2053
2054 int nIndex = 0;
2055 for (int i = 0, sz = str.GetLength(); i < sz; i++) {
2056 FX_WCHAR wc = str.GetAt(i);
2057 if (IsDigit((wchar_t)wc)) {
2058 sPart += wc;
2059 } else {
2060 if (sPart.GetLength() > 0) {
Tom Sepez67fd5df2015-10-08 12:24:19 -07002061 nums.SetElement(nIndex, CJS_Value(pRuntime, sPart.c_str()));
Nico Weber9d8ec5a2015-08-04 13:00:21 -07002062 sPart = L"";
2063 nIndex++;
2064 }
Tom Sepez2f2ffec2015-07-23 14:42:09 -07002065 }
Nico Weber9d8ec5a2015-08-04 13:00:21 -07002066 }
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07002067
Nico Weber9d8ec5a2015-08-04 13:00:21 -07002068 if (sPart.GetLength() > 0) {
Tom Sepez67fd5df2015-10-08 12:24:19 -07002069 nums.SetElement(nIndex, CJS_Value(pRuntime, sPart.c_str()));
Nico Weber9d8ec5a2015-08-04 13:00:21 -07002070 }
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07002071
Nico Weber9d8ec5a2015-08-04 13:00:21 -07002072 if (nums.GetLength() > 0)
2073 vRet = nums;
2074 else
2075 vRet.SetNull();
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07002076
Nico Weber9d8ec5a2015-08-04 13:00:21 -07002077 return TRUE;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07002078}