blob: 0b3b38f8f184dcb42436308e7ad5ec5648776425 [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
Nico Weber9d8ec5a2015-08-04 13:00:21 -070051static const FX_WCHAR* months[] = {L"Jan", L"Feb", L"Mar", L"Apr",
52 L"May", L"Jun", L"Jul", L"Aug",
53 L"Sep", L"Oct", L"Nov", L"Dec"};
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -070054
Nico Weber9d8ec5a2015-08-04 13:00:21 -070055static const FX_WCHAR* const fullmonths[] = {
56 L"January", L"February", L"March", L"April",
57 L"May", L"June", L"July", L"August",
58 L"September", L"October", L"November", L"December"};
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -070059
Nico Weber9d8ec5a2015-08-04 13:00:21 -070060FX_BOOL CJS_PublicMethods::IsNumber(const FX_WCHAR* string) {
61 CFX_WideString sTrim = StrTrim(string);
62 const FX_WCHAR* pTrim = sTrim.c_str();
63 const FX_WCHAR* p = pTrim;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -070064
Nico Weber9d8ec5a2015-08-04 13:00:21 -070065 FX_BOOL bDot = FALSE;
66 FX_BOOL bKXJS = FALSE;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -070067
Nico Weber9d8ec5a2015-08-04 13:00:21 -070068 wchar_t c;
69 while ((c = *p)) {
70 if (c == '.' || c == ',') {
71 if (bDot)
72 return FALSE;
73 bDot = TRUE;
74 } else if (c == '-' || c == '+') {
75 if (p != pTrim)
76 return FALSE;
77 } else if (c == 'e' || c == 'E') {
78 if (bKXJS)
79 return FALSE;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -070080
Nico Weber9d8ec5a2015-08-04 13:00:21 -070081 p++;
82 c = *p;
83 if (c == '+' || c == '-') {
84 bKXJS = TRUE;
85 } else {
86 return FALSE;
87 }
88 } else if (!IsDigit(c)) {
89 return FALSE;
90 }
91 p++;
92 }
93
94 return TRUE;
95}
96
97FX_BOOL CJS_PublicMethods::IsDigit(wchar_t ch) {
98 return (ch >= L'0' && ch <= L'9');
99}
100
101FX_BOOL CJS_PublicMethods::IsDigit(char ch) {
102 return (ch >= '0' && ch <= '9');
103}
104
105FX_BOOL CJS_PublicMethods::IsAlphabetic(wchar_t ch) {
106 return ((ch >= L'a' && ch <= L'z') || (ch >= L'A' && ch <= L'Z'));
107}
108
109FX_BOOL CJS_PublicMethods::IsAlphaNumeric(wchar_t ch) {
110 return (IsDigit(ch) || IsAlphabetic(ch));
111}
112
113FX_BOOL CJS_PublicMethods::maskSatisfied(wchar_t c_Change, wchar_t c_Mask) {
114 switch (c_Mask) {
115 case L'9':
116 return IsDigit(c_Change);
117 case L'A':
118 return IsAlphabetic(c_Change);
119 case L'O':
120 return IsAlphaNumeric(c_Change);
121 case L'X':
122 return TRUE;
123 default:
124 return (c_Change == c_Mask);
125 }
126}
127
128FX_BOOL CJS_PublicMethods::isReservedMaskChar(wchar_t ch) {
129 return ch == L'9' || ch == L'A' || ch == L'O' || ch == L'X';
130}
131
132double CJS_PublicMethods::AF_Simple(const FX_WCHAR* sFuction,
133 double dValue1,
134 double dValue2) {
135 if (FXSYS_wcsicmp(sFuction, L"AVG") == 0 ||
136 FXSYS_wcsicmp(sFuction, L"SUM") == 0) {
137 return dValue1 + dValue2;
138 }
139 if (FXSYS_wcsicmp(sFuction, L"PRD") == 0) {
140 return dValue1 * dValue2;
141 }
142 if (FXSYS_wcsicmp(sFuction, L"MIN") == 0) {
143 return FX_MIN(dValue1, dValue2);
144 }
145 if (FXSYS_wcsicmp(sFuction, L"MAX") == 0) {
146 return FX_MAX(dValue1, dValue2);
147 }
148 return dValue1;
149}
150
151CFX_WideString CJS_PublicMethods::StrLTrim(const FX_WCHAR* pStr) {
152 while (*pStr && *pStr == L' ')
153 pStr++;
154
155 return pStr;
156}
157
158CFX_WideString CJS_PublicMethods::StrRTrim(const FX_WCHAR* pStr) {
159 const FX_WCHAR* p = pStr;
160 while (*p)
161 p++;
162 while (p > pStr && *(p - 1) == L' ')
163 p--;
164
165 return CFX_WideString(pStr, p - pStr);
166}
167
168CFX_WideString CJS_PublicMethods::StrTrim(const FX_WCHAR* pStr) {
169 return StrRTrim(StrLTrim(pStr).c_str());
170}
171
172CFX_ByteString CJS_PublicMethods::StrLTrim(const FX_CHAR* pStr) {
173 while (*pStr && *pStr == ' ')
174 pStr++;
175
176 return pStr;
177}
178
179CFX_ByteString CJS_PublicMethods::StrRTrim(const FX_CHAR* pStr) {
180 const FX_CHAR* p = pStr;
181 while (*p)
182 p++;
183 while (p > pStr && *(p - 1) == L' ')
184 p--;
185
186 return CFX_ByteString(pStr, p - pStr);
187}
188
189CFX_ByteString CJS_PublicMethods::StrTrim(const FX_CHAR* pStr) {
190 return StrRTrim(StrLTrim(pStr));
191}
192
193double CJS_PublicMethods::ParseNumber(const FX_WCHAR* swSource,
194 FX_BOOL& bAllDigits,
195 FX_BOOL& bDot,
196 FX_BOOL& bSign,
197 FX_BOOL& bKXJS) {
198 bDot = FALSE;
199 bSign = FALSE;
200 bKXJS = FALSE;
201
202 FX_BOOL bDigitExist = FALSE;
203
204 const FX_WCHAR* p = swSource;
205 wchar_t c;
206
207 const FX_WCHAR* pStart = NULL;
208 const FX_WCHAR* pEnd = NULL;
209
210 while ((c = *p)) {
211 if (!pStart && c != L' ') {
212 pStart = p;
213 }
214
215 pEnd = p;
216 p++;
217 }
218
219 if (!pStart) {
220 bAllDigits = FALSE;
221 return 0;
222 }
223
224 while (pEnd != pStart) {
225 if (*pEnd == L' ')
226 pEnd--;
227 else
228 break;
229 }
230
231 double dRet = 0;
232 p = pStart;
233 bAllDigits = TRUE;
234 CFX_WideString swDigits;
235
236 while (p <= pEnd) {
237 c = *p;
238
239 if (IsDigit(c)) {
240 swDigits += c;
241 bDigitExist = TRUE;
242 } else {
243 switch (c) {
244 case L' ':
245 bAllDigits = FALSE;
246 break;
247 case L'.':
248 case L',':
249 if (!bDot) {
250 if (bDigitExist) {
251 swDigits += L'.';
252 } else {
253 swDigits += L'0';
254 swDigits += L'.';
255 bDigitExist = TRUE;
256 }
257
Tom Sepez2f2ffec2015-07-23 14:42:09 -0700258 bDot = TRUE;
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700259 break;
260 }
261 case 'e':
262 case 'E':
263 if (!bKXJS) {
Tom Sepez2f2ffec2015-07-23 14:42:09 -0700264 p++;
265 c = *p;
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700266 if (c == '+' || c == '-') {
267 bKXJS = TRUE;
268 swDigits += 'e';
269 swDigits += c;
Tom Sepez2f2ffec2015-07-23 14:42:09 -0700270 }
Tom Sepez2f2ffec2015-07-23 14:42:09 -0700271 break;
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700272 }
273 case L'-':
274 if (!bDigitExist && !bSign) {
Tom Sepez2f2ffec2015-07-23 14:42:09 -0700275 swDigits += c;
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700276 bSign = TRUE;
Tom Sepez2f2ffec2015-07-23 14:42:09 -0700277 break;
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700278 }
279 default:
280 bAllDigits = FALSE;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700281
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700282 if (p != pStart && !bDot && bDigitExist) {
283 swDigits += L'.';
284 bDot = TRUE;
285 } else {
286 bDot = FALSE;
287 bDigitExist = FALSE;
288 swDigits = L"";
289 }
290 break;
291 }
Tom Sepez2f2ffec2015-07-23 14:42:09 -0700292 }
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700293
294 p++;
295 }
296
297 if (swDigits.GetLength() > 0 && swDigits.GetLength() < 17) {
298 CFX_ByteString sDigits = swDigits.UTF8Encode();
299
300 if (bKXJS) {
301 dRet = atof(sDigits);
302 } else {
303 if (bDot) {
304 char* pStopString;
305 dRet = ::strtod(sDigits, &pStopString);
306 } else {
307 dRet = atol(sDigits);
308 }
309 }
310 }
311
312 return dRet;
313}
314
315double CJS_PublicMethods::ParseStringToNumber(const FX_WCHAR* swSource) {
316 FX_BOOL bAllDigits = FALSE;
317 FX_BOOL bDot = FALSE;
318 FX_BOOL bSign = FALSE;
319 FX_BOOL bKXJS = FALSE;
320
321 return ParseNumber(swSource, bAllDigits, bDot, bSign, bKXJS);
322}
323
324FX_BOOL CJS_PublicMethods::ConvertStringToNumber(const FX_WCHAR* swSource,
325 double& dRet,
326 FX_BOOL& bDot) {
327 FX_BOOL bAllDigits = FALSE;
328 FX_BOOL bSign = FALSE;
329 FX_BOOL bKXJS = FALSE;
330
331 dRet = ParseNumber(swSource, bAllDigits, bDot, bSign, bKXJS);
332
333 return bAllDigits;
334}
335
Tom Sepez67fd5df2015-10-08 12:24:19 -0700336CJS_Array CJS_PublicMethods::AF_MakeArrayFromList(CJS_Runtime* pRuntime,
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700337 CJS_Value val) {
Tom Sepez67fd5df2015-10-08 12:24:19 -0700338 CJS_Array StrArray(pRuntime);
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700339 if (val.IsArrayObject()) {
340 val.ConvertToArray(StrArray);
Tom Sepez2f2ffec2015-07-23 14:42:09 -0700341 return StrArray;
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700342 }
343 CFX_WideString wsStr = val.ToCFXWideString();
344 CFX_ByteString t = CFX_ByteString::FromUnicode(wsStr);
345 const char* p = (const char*)t;
346
347 int ch = ',';
348 int nIndex = 0;
349
350 while (*p) {
351 const char* pTemp = strchr(p, ch);
352 if (pTemp == NULL) {
Tom Sepez67fd5df2015-10-08 12:24:19 -0700353 StrArray.SetElement(nIndex, CJS_Value(pRuntime, StrTrim(p).c_str()));
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700354 break;
355 } else {
356 char* pSub = new char[pTemp - p + 1];
357 strncpy(pSub, p, pTemp - p);
358 *(pSub + (pTemp - p)) = '\0';
359
Tom Sepez67fd5df2015-10-08 12:24:19 -0700360 StrArray.SetElement(nIndex, CJS_Value(pRuntime, StrTrim(pSub).c_str()));
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700361 delete[] pSub;
362
363 nIndex++;
364 p = ++pTemp;
365 }
366 }
367 return StrArray;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700368}
369
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700370int CJS_PublicMethods::ParseStringInteger(const CFX_WideString& string,
371 int nStart,
372 int& nSkip,
373 int nMaxStep) {
374 int nRet = 0;
375 nSkip = 0;
376 for (int i = nStart, sz = string.GetLength(); i < sz; i++) {
377 if (i - nStart > 10)
378 break;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700379
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700380 FX_WCHAR c = string.GetAt(i);
381 if (IsDigit((wchar_t)c)) {
382 nRet = nRet * 10 + (c - '0');
383 nSkip = i - nStart + 1;
384 if (nSkip >= nMaxStep)
385 break;
386 } else
387 break;
388 }
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700389
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700390 return nRet;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700391}
392
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700393CFX_WideString CJS_PublicMethods::ParseStringString(
394 const CFX_WideString& string,
395 int nStart,
396 int& nSkip) {
397 CFX_WideString swRet;
398 nSkip = 0;
399 for (int i = nStart, sz = string.GetLength(); i < sz; i++) {
400 FX_WCHAR c = string.GetAt(i);
401 if ((c >= L'a' && c <= L'z') || (c >= L'A' && c <= L'Z')) {
402 swRet += c;
403 nSkip = i - nStart + 1;
404 } else
405 break;
406 }
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700407
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700408 return swRet;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700409}
410
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700411double CJS_PublicMethods::ParseNormalDate(const CFX_WideString& value,
412 FX_BOOL& bWrongFormat) {
413 double dt = JS_GetDateTime();
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700414
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700415 int nYear = JS_GetYearFromTime(dt);
416 int nMonth = JS_GetMonthFromTime(dt) + 1;
417 int nDay = JS_GetDayFromTime(dt);
418 int nHour = JS_GetHourFromTime(dt);
419 int nMin = JS_GetMinFromTime(dt);
420 int nSec = JS_GetSecFromTime(dt);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700421
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700422 int number[3];
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700423
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700424 int nSkip = 0;
425 int nLen = value.GetLength();
426 int nIndex = 0;
427 int i = 0;
428 while (i < nLen) {
429 if (nIndex > 2)
430 break;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700431
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700432 FX_WCHAR c = value.GetAt(i);
433 if (IsDigit((wchar_t)c)) {
434 number[nIndex++] = ParseStringInteger(value, i, nSkip, 4);
435 i += nSkip;
436 } else {
437 i++;
438 }
439 }
440
441 if (nIndex == 2) {
442 // case2: month/day
443 // case3: day/month
444 if ((number[0] >= 1 && number[0] <= 12) &&
445 (number[1] >= 1 && number[1] <= 31)) {
446 nMonth = number[0];
447 nDay = number[1];
448 } else if ((number[0] >= 1 && number[0] <= 31) &&
449 (number[1] >= 1 && number[1] <= 12)) {
450 nDay = number[0];
451 nMonth = number[1];
Tom Sepez2f2ffec2015-07-23 14:42:09 -0700452 }
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700453
Tom Sepez2f2ffec2015-07-23 14:42:09 -0700454 bWrongFormat = FALSE;
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700455 } else if (nIndex == 3) {
456 // case1: year/month/day
457 // case2: month/day/year
458 // case3: day/month/year
Tom Sepez5ffacd62014-07-18 14:42:12 -0700459
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700460 if (number[0] > 12 && (number[1] >= 1 && number[1] <= 12) &&
461 (number[2] >= 1 && number[2] <= 31)) {
462 nYear = number[0];
463 nMonth = number[1];
464 nDay = number[2];
465 } else if ((number[0] >= 1 && number[0] <= 12) &&
466 (number[1] >= 1 && number[1] <= 31) && number[2] > 31) {
467 nMonth = number[0];
468 nDay = number[1];
469 nYear = number[2];
470 } else if ((number[0] >= 1 && number[0] <= 31) &&
471 (number[1] >= 1 && number[1] <= 12) && number[2] > 31) {
472 nDay = number[0];
473 nMonth = number[1];
474 nYear = number[2];
Tom Sepez2f2ffec2015-07-23 14:42:09 -0700475 }
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700476
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700477 bWrongFormat = FALSE;
478 } else {
479 bWrongFormat = TRUE;
480 return dt;
481 }
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700482
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700483 CFX_WideString swTemp;
484 swTemp.Format(L"%d/%d/%d %d:%d:%d", nMonth, nDay, nYear, nHour, nMin, nSec);
485 return JS_DateParse(swTemp.c_str());
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700486}
487
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700488double CJS_PublicMethods::MakeRegularDate(const CFX_WideString& value,
489 const CFX_WideString& format,
490 FX_BOOL& bWrongFormat) {
491 double dt = JS_GetDateTime();
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700492
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700493 if (format.IsEmpty() || value.IsEmpty())
494 return dt;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700495
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700496 int nYear = JS_GetYearFromTime(dt);
497 int nMonth = JS_GetMonthFromTime(dt) + 1;
498 int nDay = JS_GetDayFromTime(dt);
499 int nHour = JS_GetHourFromTime(dt);
500 int nMin = JS_GetMinFromTime(dt);
501 int nSec = JS_GetSecFromTime(dt);
502
503 int nYearSub = 99; // nYear - 2000;
504
505 FX_BOOL bPm = FALSE;
506 FX_BOOL bExit = FALSE;
507 bWrongFormat = FALSE;
508
509 int i = 0;
510 int j = 0;
511
512 while (i < format.GetLength()) {
513 if (bExit)
514 break;
515
516 FX_WCHAR c = format.GetAt(i);
517 switch (c) {
518 case ':':
519 case '.':
520 case '-':
521 case '\\':
522 case '/':
523 i++;
524 j++;
525 break;
526
527 case 'y':
528 case 'm':
529 case 'd':
530 case 'H':
531 case 'h':
532 case 'M':
533 case 's':
534 case 't': {
535 int oldj = j;
536 int nSkip = 0;
537 int remaining = format.GetLength() - i - 1;
538
539 if (remaining == 0 || format.GetAt(i + 1) != c) {
540 switch (c) {
Tom Sepez2f2ffec2015-07-23 14:42:09 -0700541 case 'y':
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700542 i++;
543 j++;
544 break;
Tom Sepez2f2ffec2015-07-23 14:42:09 -0700545 case 'm':
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700546 nMonth = ParseStringInteger(value, j, nSkip, 2);
547 i++;
548 j += nSkip;
549 break;
Tom Sepez2f2ffec2015-07-23 14:42:09 -0700550 case 'd':
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700551 nDay = ParseStringInteger(value, j, nSkip, 2);
552 i++;
553 j += nSkip;
554 break;
Tom Sepez2f2ffec2015-07-23 14:42:09 -0700555 case 'H':
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700556 nHour = ParseStringInteger(value, j, nSkip, 2);
557 i++;
558 j += nSkip;
559 break;
Tom Sepez2f2ffec2015-07-23 14:42:09 -0700560 case 'h':
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700561 nHour = ParseStringInteger(value, j, nSkip, 2);
562 i++;
563 j += nSkip;
564 break;
Tom Sepez2f2ffec2015-07-23 14:42:09 -0700565 case 'M':
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700566 nMin = ParseStringInteger(value, j, nSkip, 2);
567 i++;
568 j += nSkip;
569 break;
Tom Sepez2f2ffec2015-07-23 14:42:09 -0700570 case 's':
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700571 nSec = ParseStringInteger(value, j, nSkip, 2);
572 i++;
573 j += nSkip;
574 break;
Tom Sepez2f2ffec2015-07-23 14:42:09 -0700575 case 't':
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700576 bPm = (j < value.GetLength() && value.GetAt(j) == 'p');
577 i++;
578 j++;
579 break;
580 }
581 } else if (remaining == 1 || format.GetAt(i + 2) != c) {
582 switch (c) {
583 case 'y':
584 nYear = ParseStringInteger(value, j, nSkip, 4);
585 i += 2;
586 j += nSkip;
587 break;
588 case 'm':
589 nMonth = ParseStringInteger(value, j, nSkip, 2);
590 i += 2;
591 j += nSkip;
592 break;
593 case 'd':
594 nDay = ParseStringInteger(value, j, nSkip, 2);
595 i += 2;
596 j += nSkip;
597 break;
598 case 'H':
599 nHour = ParseStringInteger(value, j, nSkip, 2);
600 i += 2;
601 j += nSkip;
602 break;
603 case 'h':
604 nHour = ParseStringInteger(value, j, nSkip, 2);
605 i += 2;
606 j += nSkip;
607 break;
608 case 'M':
609 nMin = ParseStringInteger(value, j, nSkip, 2);
610 i += 2;
611 j += nSkip;
612 break;
613 case 's':
614 nSec = ParseStringInteger(value, j, nSkip, 2);
615 i += 2;
616 j += nSkip;
617 break;
618 case 't':
619 bPm = (j + 1 < value.GetLength() && value.GetAt(j) == 'p' &&
620 value.GetAt(j + 1) == 'm');
621 i += 2;
622 j += 2;
623 break;
624 }
625 } else if (remaining == 2 || format.GetAt(i + 3) != c) {
626 switch (c) {
627 case 'm': {
628 CFX_WideString sMonth = ParseStringString(value, j, nSkip);
629 FX_BOOL bFind = FALSE;
630 for (int m = 0; m < 12; m++) {
631 if (sMonth.CompareNoCase(months[m]) == 0) {
632 nMonth = m + 1;
633 i += 3;
634 j += nSkip;
635 bFind = TRUE;
636 break;
Tom Sepez2f2ffec2015-07-23 14:42:09 -0700637 }
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700638 }
639
640 if (!bFind) {
641 nMonth = ParseStringInteger(value, j, nSkip, 3);
642 i += 3;
643 j += nSkip;
644 }
645 } break;
646 case 'y':
647 break;
Tom Sepez2f2ffec2015-07-23 14:42:09 -0700648 default:
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700649 i += 3;
650 j += 3;
651 break;
652 }
653 } else if (remaining == 3 || format.GetAt(i + 4) != c) {
654 switch (c) {
655 case 'y':
656 nYear = ParseStringInteger(value, j, nSkip, 4);
657 j += nSkip;
658 i += 4;
659 break;
660 case 'm': {
661 FX_BOOL bFind = FALSE;
662
663 CFX_WideString sMonth = ParseStringString(value, j, nSkip);
664 sMonth.MakeLower();
665
666 for (int m = 0; m < 12; m++) {
667 CFX_WideString sFullMonths = fullmonths[m];
668 sFullMonths.MakeLower();
669
670 if (sFullMonths.Find(sMonth.c_str(), 0) != -1) {
671 nMonth = m + 1;
672 i += 4;
673 j += nSkip;
674 bFind = TRUE;
675 break;
676 }
677 }
678
679 if (!bFind) {
680 nMonth = ParseStringInteger(value, j, nSkip, 4);
681 i += 4;
682 j += nSkip;
683 }
684 } break;
685 default:
686 i += 4;
687 j += 4;
688 break;
689 }
690 } else {
691 if (j >= value.GetLength() || format.GetAt(i) != value.GetAt(j)) {
692 bWrongFormat = TRUE;
693 bExit = TRUE;
694 }
695 i++;
696 j++;
Tom Sepez2f2ffec2015-07-23 14:42:09 -0700697 }
Tom Sepez85386422014-07-23 10:28:37 -0700698
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700699 if (oldj == j) {
700 bWrongFormat = TRUE;
701 bExit = TRUE;
702 }
703 }
704
705 break;
706 default:
707 if (value.GetLength() <= j) {
708 bExit = TRUE;
709 } else if (format.GetAt(i) != value.GetAt(j)) {
710 bWrongFormat = TRUE;
711 bExit = TRUE;
712 }
713
714 i++;
715 j++;
716 break;
717 }
718 }
719
720 if (bPm)
721 nHour += 12;
722
723 if (nYear >= 0 && nYear <= nYearSub)
724 nYear += 2000;
725
726 if (nMonth < 1 || nMonth > 12)
727 bWrongFormat = TRUE;
728
729 if (nDay < 1 || nDay > 31)
730 bWrongFormat = TRUE;
731
732 if (nHour < 0 || nHour > 24)
733 bWrongFormat = TRUE;
734
735 if (nMin < 0 || nMin > 60)
736 bWrongFormat = TRUE;
737
738 if (nSec < 0 || nSec > 60)
739 bWrongFormat = TRUE;
740
741 double dRet = 0;
742
743 if (bWrongFormat) {
744 dRet = ParseNormalDate(value, bWrongFormat);
745 } else {
746 dRet = JS_MakeDate(JS_MakeDay(nYear, nMonth - 1, nDay),
747 JS_MakeTime(nHour, nMin, nSec, 0));
748
749 if (JS_PortIsNan(dRet)) {
750 dRet = JS_DateParse(value.c_str());
751 }
752 }
753
754 if (JS_PortIsNan(dRet)) {
755 dRet = ParseNormalDate(value, bWrongFormat);
756 }
757
758 return dRet;
759}
760
761CFX_WideString CJS_PublicMethods::MakeFormatDate(double dDate,
762 const CFX_WideString& format) {
763 CFX_WideString sRet = L"", sPart = L"";
764
765 int nYear = JS_GetYearFromTime(dDate);
766 int nMonth = JS_GetMonthFromTime(dDate) + 1;
767 int nDay = JS_GetDayFromTime(dDate);
768 int nHour = JS_GetHourFromTime(dDate);
769 int nMin = JS_GetMinFromTime(dDate);
770 int nSec = JS_GetSecFromTime(dDate);
771
772 int i = 0;
773 while (i < format.GetLength()) {
774 FX_WCHAR c = format.GetAt(i);
775 int remaining = format.GetLength() - i - 1;
776 sPart = L"";
777 switch (c) {
778 case 'y':
779 case 'm':
780 case 'd':
781 case 'H':
782 case 'h':
783 case 'M':
784 case 's':
785 case 't':
786 if (remaining == 0 || format.GetAt(i + 1) != c) {
787 switch (c) {
788 case 'y':
789 sPart += c;
790 break;
791 case 'm':
792 sPart.Format(L"%d", nMonth);
793 break;
794 case 'd':
795 sPart.Format(L"%d", nDay);
796 break;
797 case 'H':
798 sPart.Format(L"%d", nHour);
799 break;
800 case 'h':
801 sPart.Format(L"%d", nHour > 12 ? nHour - 12 : nHour);
802 break;
803 case 'M':
804 sPart.Format(L"%d", nMin);
805 break;
806 case 's':
807 sPart.Format(L"%d", nSec);
808 break;
809 case 't':
810 sPart += nHour > 12 ? 'p' : 'a';
811 break;
812 }
813 i++;
814 } else if (remaining == 1 || format.GetAt(i + 2) != c) {
815 switch (c) {
816 case 'y':
817 sPart.Format(L"%02d", nYear - (nYear / 100) * 100);
818 break;
819 case 'm':
820 sPart.Format(L"%02d", nMonth);
821 break;
822 case 'd':
823 sPart.Format(L"%02d", nDay);
824 break;
825 case 'H':
826 sPart.Format(L"%02d", nHour);
827 break;
828 case 'h':
829 sPart.Format(L"%02d", nHour > 12 ? nHour - 12 : nHour);
830 break;
831 case 'M':
832 sPart.Format(L"%02d", nMin);
833 break;
834 case 's':
835 sPart.Format(L"%02d", nSec);
836 break;
837 case 't':
838 sPart = nHour > 12 ? L"pm" : L"am";
839 break;
840 }
841 i += 2;
842 } else if (remaining == 2 || format.GetAt(i + 3) != c) {
843 switch (c) {
844 case 'm':
845 i += 3;
846 if (nMonth > 0 && nMonth <= 12)
847 sPart += months[nMonth - 1];
848 break;
849 default:
850 i += 3;
851 sPart += c;
852 sPart += c;
853 sPart += c;
854 break;
855 }
856 } else if (remaining == 3 || format.GetAt(i + 4) != c) {
857 switch (c) {
858 case 'y':
859 sPart.Format(L"%04d", nYear);
860 i += 4;
861 break;
862 case 'm':
863 i += 4;
864 if (nMonth > 0 && nMonth <= 12)
865 sPart += fullmonths[nMonth - 1];
866 break;
867 default:
868 i += 4;
869 sPart += c;
870 sPart += c;
871 sPart += c;
872 sPart += c;
873 break;
874 }
875 } else {
876 i++;
877 sPart += c;
878 }
879 break;
880 default:
881 i++;
882 sPart += c;
883 break;
Tom Sepez2f2ffec2015-07-23 14:42:09 -0700884 }
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700885
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700886 sRet += sPart;
887 }
888
889 return sRet;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700890}
891
892/* -------------------------------------------------------------------------- */
893
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700894// function AFNumber_Format(nDec, sepStyle, negStyle, currStyle, strCurrency,
895// bCurrencyPrepend)
Tom Sepezba038bc2015-10-08 12:03:00 -0700896FX_BOOL CJS_PublicMethods::AFNumber_Format(IJS_Context* cc,
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700897 const CJS_Parameters& params,
898 CJS_Value& vRet,
899 CFX_WideString& sError) {
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700900#if _FX_OS_ != _FX_ANDROID_
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700901 CJS_Context* pContext = (CJS_Context*)cc;
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700902 if (params.size() != 6) {
903 sError = JSGetStringFromID(pContext, IDS_STRING_JSPARAMERROR);
904 return FALSE;
905 }
Tom Sepez67fd5df2015-10-08 12:24:19 -0700906
907 CJS_Runtime* pRuntime = CJS_Runtime::FromContext(cc);
908 CJS_EventHandler* pEvent = pContext->GetEventHandler();
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700909 if (!pEvent->m_pValue)
910 return FALSE;
Tom Sepez67fd5df2015-10-08 12:24:19 -0700911
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700912 CFX_WideString& Value = pEvent->Value();
913 CFX_ByteString strValue = StrTrim(CFX_ByteString::FromUnicode(Value));
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700914 if (strValue.IsEmpty())
Tom Sepez2f2ffec2015-07-23 14:42:09 -0700915 return TRUE;
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700916
917 int iDec = params[0].ToInt();
918 int iSepStyle = params[1].ToInt();
919 int iNegStyle = params[2].ToInt();
920 // params[3] is iCurrStyle, it's not used.
921 std::wstring wstrCurrency(params[4].ToCFXWideString().c_str());
922 FX_BOOL bCurrencyPrepend = params[5].ToBool();
923
924 if (iDec < 0)
925 iDec = -iDec;
926
927 if (iSepStyle < 0 || iSepStyle > 3)
928 iSepStyle = 0;
929
930 if (iNegStyle < 0 || iNegStyle > 3)
931 iNegStyle = 0;
932
933 //////////////////////////////////////////////////////
934 // for processing decimal places
935 strValue.Replace(",", ".");
936 double dValue = atof(strValue);
937 if (iDec > 0)
938 dValue += DOUBLE_CORRECT; //
939
940 int iDec2;
941 int iNegative = 0;
942
943 strValue = fcvt(dValue, iDec, &iDec2, &iNegative);
944 if (strValue.IsEmpty()) {
945 dValue = 0;
946 strValue = fcvt(dValue, iDec, &iDec2, &iNegative);
947 if (strValue.IsEmpty()) {
948 strValue = "0";
949 iDec2 = 1;
950 }
951 }
952
953 if (iDec2 < 0) {
954 for (int iNum = 0; iNum < abs(iDec2); iNum++) {
955 strValue = "0" + strValue;
956 }
957 iDec2 = 0;
958 }
959 int iMax = strValue.GetLength();
960 if (iDec2 > iMax) {
961 for (int iNum = 0; iNum <= iDec2 - iMax; iNum++) {
962 strValue += "0";
963 }
964 iMax = iDec2 + 1;
965 }
966 ///////////////////////////////////////////////////////
967 // for processing seperator style
968 if (iDec2 < iMax) {
969 if (iSepStyle == 0 || iSepStyle == 1) {
970 strValue.Insert(iDec2, '.');
971 iMax++;
972 } else if (iSepStyle == 2 || iSepStyle == 3) {
973 strValue.Insert(iDec2, ',');
974 iMax++;
975 }
976
977 if (iDec2 == 0)
978 strValue.Insert(iDec2, '0');
979 }
980 if (iSepStyle == 0 || iSepStyle == 2) {
981 char cSeperator;
982 if (iSepStyle == 0)
983 cSeperator = ',';
984 else
985 cSeperator = '.';
986
987 int iDecPositive, iDecNegative;
988 iDecPositive = iDec2;
989 iDecNegative = iDec2;
990
991 for (iDecPositive = iDec2 - 3; iDecPositive > 0; iDecPositive -= 3) {
992 strValue.Insert(iDecPositive, cSeperator);
993 iMax++;
994 }
995 }
996
997 //////////////////////////////////////////////////////////////////////
998 // for processing currency string
999
1000 Value = CFX_WideString::FromLocal(strValue);
1001 std::wstring strValue2 = Value.c_str();
1002
1003 if (bCurrencyPrepend)
1004 strValue2 = wstrCurrency + strValue2;
1005 else
1006 strValue2 = strValue2 + wstrCurrency;
1007
1008 /////////////////////////////////////////////////////////////////////////
1009 // for processing negative style
1010 if (iNegative) {
1011 if (iNegStyle == 0) {
1012 strValue2.insert(0, L"-");
1013 }
1014 if (iNegStyle == 2 || iNegStyle == 3) {
1015 strValue2.insert(0, L"(");
1016 strValue2.insert(strValue2.length(), L")");
1017 }
1018 if (iNegStyle == 1 || iNegStyle == 3) {
1019 if (Field* fTarget = pEvent->Target_Field()) {
Tom Sepez67fd5df2015-10-08 12:24:19 -07001020 CJS_Array arColor(pRuntime);
1021 CJS_Value vColElm(pRuntime);
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001022 vColElm = L"RGB";
1023 arColor.SetElement(0, vColElm);
1024 vColElm = 1;
1025 arColor.SetElement(1, vColElm);
1026 vColElm = 0;
1027 arColor.SetElement(2, vColElm);
1028
1029 arColor.SetElement(3, vColElm);
1030
Tom Sepez67fd5df2015-10-08 12:24:19 -07001031 CJS_PropValue vProp(pRuntime);
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001032 vProp.StartGetting();
1033 vProp << arColor;
1034 vProp.StartSetting();
1035 fTarget->textColor(cc, vProp, sError); // red
1036 }
1037 }
1038 } else {
1039 if (iNegStyle == 1 || iNegStyle == 3) {
1040 if (Field* fTarget = pEvent->Target_Field()) {
Tom Sepez67fd5df2015-10-08 12:24:19 -07001041 CJS_Array arColor(pRuntime);
1042 CJS_Value vColElm(pRuntime);
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001043 vColElm = L"RGB";
1044 arColor.SetElement(0, vColElm);
1045 vColElm = 0;
1046 arColor.SetElement(1, vColElm);
1047 arColor.SetElement(2, vColElm);
1048 arColor.SetElement(3, vColElm);
1049
Tom Sepez67fd5df2015-10-08 12:24:19 -07001050 CJS_PropValue vProp(pRuntime);
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001051 vProp.StartGetting();
1052 fTarget->textColor(cc, vProp, sError);
1053
Tom Sepez67fd5df2015-10-08 12:24:19 -07001054 CJS_Array aProp(pRuntime);
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001055 vProp.ConvertToArray(aProp);
1056
1057 CPWL_Color crProp;
1058 CPWL_Color crColor;
1059 color::ConvertArrayToPWLColor(aProp, crProp);
1060 color::ConvertArrayToPWLColor(arColor, crColor);
1061
1062 if (crColor != crProp) {
Tom Sepez67fd5df2015-10-08 12:24:19 -07001063 CJS_PropValue vProp2(pRuntime);
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001064 vProp2.StartGetting();
1065 vProp2 << arColor;
1066 vProp2.StartSetting();
1067 fTarget->textColor(cc, vProp2, sError);
1068 }
1069 }
1070 }
1071 }
1072 Value = strValue2.c_str();
1073#endif
1074 return TRUE;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07001075}
1076
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001077// function AFNumber_Keystroke(nDec, sepStyle, negStyle, currStyle, strCurrency,
1078// bCurrencyPrepend)
Tom Sepezba038bc2015-10-08 12:03:00 -07001079FX_BOOL CJS_PublicMethods::AFNumber_Keystroke(IJS_Context* cc,
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001080 const CJS_Parameters& params,
1081 CJS_Value& vRet,
1082 CFX_WideString& sError) {
1083 CJS_Context* pContext = (CJS_Context*)cc;
1084 ASSERT(pContext != NULL);
1085 CJS_EventHandler* pEvent = pContext->GetEventHandler();
1086 ASSERT(pEvent != NULL);
Lei Zhanga6d9f0e2015-06-13 00:48:38 -07001087
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001088 if (params.size() < 2)
1089 return FALSE;
1090 int iSepStyle = params[1].ToInt();
Lei Zhanga6d9f0e2015-06-13 00:48:38 -07001091
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001092 if (iSepStyle < 0 || iSepStyle > 3)
1093 iSepStyle = 0;
1094 if (!pEvent->m_pValue)
1095 return FALSE;
1096 CFX_WideString& val = pEvent->Value();
1097 CFX_WideString& w_strChange = pEvent->Change();
1098 CFX_WideString w_strValue = val;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07001099
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001100 if (pEvent->WillCommit()) {
1101 CFX_WideString wstrChange = w_strChange;
1102 CFX_WideString wstrValue = StrLTrim(w_strValue.c_str());
1103 if (wstrValue.IsEmpty())
1104 return TRUE;
Lei Zhanga6d9f0e2015-06-13 00:48:38 -07001105
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001106 CFX_WideString swTemp = wstrValue;
1107 swTemp.Replace(L",", L".");
1108 if (!IsNumber(swTemp.c_str())) {
1109 pEvent->Rc() = FALSE;
1110 sError = JSGetStringFromID(pContext, IDS_STRING_JSAFNUMBER_KEYSTROKE);
1111 Alert(pContext, sError.c_str());
1112 return TRUE;
Tom Sepez2f2ffec2015-07-23 14:42:09 -07001113 }
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001114 return TRUE; // it happens after the last keystroke and before validating,
1115 }
Tom Sepez4f7bc042015-04-27 12:06:58 -07001116
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001117 std::wstring w_strValue2 = w_strValue.c_str();
1118 std::wstring w_strChange2 = w_strChange.c_str();
1119 std::wstring w_strSelected;
1120 if (-1 != pEvent->SelStart())
1121 w_strSelected = w_strValue2.substr(pEvent->SelStart(),
1122 (pEvent->SelEnd() - pEvent->SelStart()));
Lei Zhangb9c31972015-08-11 14:09:35 -07001123 bool bHasSign = (w_strValue2.find('-') != std::wstring::npos) &&
1124 (w_strSelected.find('-') == std::wstring::npos);
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001125 if (bHasSign) {
1126 // can't insert "change" in front to sign postion.
1127 if (pEvent->SelStart() == 0) {
1128 FX_BOOL& bRc = pEvent->Rc();
1129 bRc = FALSE;
1130 return TRUE;
Tom Sepez2f2ffec2015-07-23 14:42:09 -07001131 }
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001132 }
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07001133
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001134 char cSep = L'.';
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07001135
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001136 switch (iSepStyle) {
Tom Sepez2f2ffec2015-07-23 14:42:09 -07001137 case 0:
1138 case 1:
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001139 cSep = L'.';
1140 break;
Tom Sepez2f2ffec2015-07-23 14:42:09 -07001141 case 2:
1142 case 3:
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001143 cSep = L',';
1144 break;
1145 }
Lei Zhanga6d9f0e2015-06-13 00:48:38 -07001146
Lei Zhangb9c31972015-08-11 14:09:35 -07001147 bool bHasSep = (w_strValue2.find(cSep) != std::wstring::npos);
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001148 for (std::wstring::iterator it = w_strChange2.begin();
1149 it != w_strChange2.end(); it++) {
1150 if (*it == cSep) {
1151 if (bHasSep) {
1152 FX_BOOL& bRc = pEvent->Rc();
1153 bRc = FALSE;
Tom Sepez2f2ffec2015-07-23 14:42:09 -07001154 return TRUE;
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001155 }
1156 bHasSep = TRUE;
1157 continue;
1158 }
1159 if (*it == L'-') {
1160 if (bHasSign) {
1161 FX_BOOL& bRc = pEvent->Rc();
1162 bRc = FALSE;
1163 return TRUE;
1164 }
1165 if (it != w_strChange2.begin()) // sign's position is not correct
1166 {
1167 FX_BOOL& bRc = pEvent->Rc();
1168 bRc = FALSE;
1169 return TRUE;
1170 }
1171 if (pEvent->SelStart() != 0) {
1172 FX_BOOL& bRc = pEvent->Rc();
1173 bRc = FALSE;
1174 return TRUE;
1175 }
1176 bHasSign = TRUE;
1177 continue;
1178 }
1179
1180 if (!IsDigit(*it)) {
1181 FX_BOOL& bRc = pEvent->Rc();
1182 bRc = FALSE;
1183 return TRUE;
1184 }
1185 }
1186
1187 std::wstring w_prefix = w_strValue2.substr(0, pEvent->SelStart());
1188 std::wstring w_postfix;
1189 if (pEvent->SelEnd() < (int)w_strValue2.length())
1190 w_postfix = w_strValue2.substr(pEvent->SelEnd());
1191 w_strValue2 = w_prefix + w_strChange2 + w_postfix;
1192 w_strValue = w_strValue2.c_str();
1193 val = w_strValue;
1194 return TRUE;
1195}
1196
1197// function AFPercent_Format(nDec, sepStyle)
Tom Sepezba038bc2015-10-08 12:03:00 -07001198FX_BOOL CJS_PublicMethods::AFPercent_Format(IJS_Context* cc,
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001199 const CJS_Parameters& params,
1200 CJS_Value& vRet,
1201 CFX_WideString& sError) {
1202#if _FX_OS_ != _FX_ANDROID_
1203 CJS_Context* pContext = (CJS_Context*)cc;
1204 ASSERT(pContext != NULL);
1205 CJS_EventHandler* pEvent = pContext->GetEventHandler();
1206 ASSERT(pEvent != NULL);
1207
1208 if (params.size() != 2) {
1209 sError = JSGetStringFromID(pContext, IDS_STRING_JSPARAMERROR);
1210 return FALSE;
1211 }
1212 if (!pEvent->m_pValue)
1213 return FALSE;
1214
1215 CFX_WideString& Value = pEvent->Value();
1216 CFX_ByteString strValue = StrTrim(CFX_ByteString::FromUnicode(Value));
1217 if (strValue.IsEmpty())
1218 return TRUE;
1219
1220 int iDec = params[0].ToInt();
1221 if (iDec < 0)
1222 iDec = -iDec;
1223
1224 int iSepStyle = params[1].ToInt();
1225 if (iSepStyle < 0 || iSepStyle > 3)
1226 iSepStyle = 0;
1227
1228 //////////////////////////////////////////////////////
1229 // for processing decimal places
1230 double dValue = atof(strValue);
1231 dValue *= 100;
1232 if (iDec > 0)
1233 dValue += DOUBLE_CORRECT; //УÕý
1234
1235 int iDec2;
1236 int iNegative = 0;
1237 strValue = fcvt(dValue, iDec, &iDec2, &iNegative);
1238 if (strValue.IsEmpty()) {
1239 dValue = 0;
1240 strValue = fcvt(dValue, iDec, &iDec2, &iNegative);
1241 }
1242
1243 if (iDec2 < 0) {
1244 for (int iNum = 0; iNum < abs(iDec2); iNum++) {
1245 strValue = "0" + strValue;
1246 }
1247 iDec2 = 0;
1248 }
1249 int iMax = strValue.GetLength();
1250 if (iDec2 > iMax) {
1251 for (int iNum = 0; iNum <= iDec2 - iMax; iNum++) {
1252 strValue += "0";
1253 }
1254 iMax = iDec2 + 1;
1255 }
1256 ///////////////////////////////////////////////////////
1257 // for processing seperator style
1258 if (iDec2 < iMax) {
1259 if (iSepStyle == 0 || iSepStyle == 1) {
1260 strValue.Insert(iDec2, '.');
1261 iMax++;
1262 } else if (iSepStyle == 2 || iSepStyle == 3) {
1263 strValue.Insert(iDec2, ',');
1264 iMax++;
1265 }
1266
1267 if (iDec2 == 0)
1268 strValue.Insert(iDec2, '0');
1269 }
1270 if (iSepStyle == 0 || iSepStyle == 2) {
1271 char cSeperator;
1272 if (iSepStyle == 0)
1273 cSeperator = ',';
1274 else
1275 cSeperator = '.';
1276
1277 int iDecPositive, iDecNegative;
1278 iDecPositive = iDec2;
1279 iDecNegative = iDec2;
1280
1281 for (iDecPositive = iDec2 - 3; iDecPositive > 0; iDecPositive -= 3) {
1282 strValue.Insert(iDecPositive, cSeperator);
1283 iMax++;
1284 }
1285 }
1286 ////////////////////////////////////////////////////////////////////
1287 // negative mark
1288 if (iNegative)
1289 strValue = "-" + strValue;
1290 strValue += "%";
1291 Value = CFX_WideString::FromLocal(strValue);
1292#endif
1293 return TRUE;
1294}
1295// AFPercent_Keystroke(nDec, sepStyle)
Tom Sepezba038bc2015-10-08 12:03:00 -07001296FX_BOOL CJS_PublicMethods::AFPercent_Keystroke(IJS_Context* cc,
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001297 const CJS_Parameters& params,
1298 CJS_Value& vRet,
1299 CFX_WideString& sError) {
1300 return AFNumber_Keystroke(cc, params, vRet, sError);
1301}
1302
1303// function AFDate_FormatEx(cFormat)
Tom Sepezba038bc2015-10-08 12:03:00 -07001304FX_BOOL CJS_PublicMethods::AFDate_FormatEx(IJS_Context* cc,
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001305 const CJS_Parameters& params,
1306 CJS_Value& vRet,
1307 CFX_WideString& sError) {
1308 CJS_Context* pContext = (CJS_Context*)cc;
1309 ASSERT(pContext != NULL);
1310 CJS_EventHandler* pEvent = pContext->GetEventHandler();
1311 ASSERT(pEvent != NULL);
1312
1313 if (params.size() != 1) {
1314 sError = JSGetStringFromID(pContext, IDS_STRING_JSPARAMERROR);
1315 return FALSE;
1316 }
1317 if (!pEvent->m_pValue)
1318 return FALSE;
1319
1320 CFX_WideString& val = pEvent->Value();
1321 CFX_WideString strValue = val;
1322 if (strValue.IsEmpty())
1323 return TRUE;
1324
1325 CFX_WideString sFormat = params[0].ToCFXWideString();
1326 FX_BOOL bWrongFormat = FALSE;
1327 double dDate = 0.0f;
1328
1329 if (strValue.Find(L"GMT") != -1) {
1330 // for GMT format time
1331 // such as "Tue Aug 11 14:24:16 GMT+08002009"
1332 dDate = MakeInterDate(strValue);
1333 } else {
1334 dDate = MakeRegularDate(strValue, sFormat, bWrongFormat);
1335 }
1336
1337 if (JS_PortIsNan(dDate)) {
1338 CFX_WideString swMsg;
1339 swMsg.Format(JSGetStringFromID(pContext, IDS_STRING_JSPARSEDATE).c_str(),
1340 sFormat.c_str());
1341 Alert(pContext, swMsg.c_str());
1342 return FALSE;
1343 }
1344
1345 val = MakeFormatDate(dDate, sFormat);
1346 return TRUE;
1347}
1348
1349double CJS_PublicMethods::MakeInterDate(CFX_WideString strValue) {
1350 int nHour;
1351 int nMin;
1352 int nSec;
1353 int nYear;
1354 int nMonth;
1355 int nDay;
1356
1357 CFX_WideStringArray wsArray;
1358 CFX_WideString sMonth = L"";
1359 CFX_WideString sTemp = L"";
1360 int nSize = strValue.GetLength();
1361
1362 for (int i = 0; i < nSize; i++) {
1363 FX_WCHAR c = strValue.GetAt(i);
1364 if (c == L' ' || c == L':') {
1365 wsArray.Add(sTemp);
1366 sTemp = L"";
1367 continue;
1368 }
1369
1370 sTemp += c;
1371 }
1372
1373 wsArray.Add(sTemp);
1374 if (wsArray.GetSize() != 8)
1375 return 0;
1376
1377 sTemp = wsArray[1];
1378 if (sTemp.Compare(L"Jan") == 0)
1379 nMonth = 1;
1380 if (sTemp.Compare(L"Feb") == 0)
1381 nMonth = 2;
1382 if (sTemp.Compare(L"Mar") == 0)
1383 nMonth = 3;
1384 if (sTemp.Compare(L"Apr") == 0)
1385 nMonth = 4;
1386 if (sTemp.Compare(L"May") == 0)
1387 nMonth = 5;
1388 if (sTemp.Compare(L"Jun") == 0)
1389 nMonth = 6;
1390 if (sTemp.Compare(L"Jul") == 0)
1391 nMonth = 7;
1392 if (sTemp.Compare(L"Aug") == 0)
1393 nMonth = 8;
1394 if (sTemp.Compare(L"Sep") == 0)
1395 nMonth = 9;
1396 if (sTemp.Compare(L"Oct") == 0)
1397 nMonth = 10;
1398 if (sTemp.Compare(L"Nov") == 0)
1399 nMonth = 11;
1400 if (sTemp.Compare(L"Dec") == 0)
1401 nMonth = 12;
1402
1403 nDay = (int)ParseStringToNumber(wsArray[2].c_str());
1404 nHour = (int)ParseStringToNumber(wsArray[3].c_str());
1405 nMin = (int)ParseStringToNumber(wsArray[4].c_str());
1406 nSec = (int)ParseStringToNumber(wsArray[5].c_str());
1407 nYear = (int)ParseStringToNumber(wsArray[7].c_str());
1408
1409 double dRet = JS_MakeDate(JS_MakeDay(nYear, nMonth - 1, nDay),
1410 JS_MakeTime(nHour, nMin, nSec, 0));
1411
1412 if (JS_PortIsNan(dRet)) {
1413 dRet = JS_DateParse(strValue.c_str());
1414 }
1415
1416 return dRet;
1417}
1418
1419// AFDate_KeystrokeEx(cFormat)
Tom Sepezba038bc2015-10-08 12:03:00 -07001420FX_BOOL CJS_PublicMethods::AFDate_KeystrokeEx(IJS_Context* cc,
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001421 const CJS_Parameters& params,
1422 CJS_Value& vRet,
1423 CFX_WideString& sError) {
1424 CJS_Context* pContext = (CJS_Context*)cc;
1425 ASSERT(pContext != NULL);
1426 CJS_EventHandler* pEvent = pContext->GetEventHandler();
1427 ASSERT(pEvent != NULL);
1428
1429 if (params.size() != 1) {
1430 sError = L"AFDate_KeystrokeEx's parameters' size r not correct";
1431 return FALSE;
1432 }
1433
1434 if (pEvent->WillCommit()) {
1435 if (!pEvent->m_pValue)
1436 return FALSE;
1437 CFX_WideString strValue = pEvent->Value();
1438 if (strValue.IsEmpty())
1439 return TRUE;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07001440
Tom Sepez2f2ffec2015-07-23 14:42:09 -07001441 CFX_WideString sFormat = params[0].ToCFXWideString();
1442 FX_BOOL bWrongFormat = FALSE;
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001443 double dRet = MakeRegularDate(strValue, sFormat, bWrongFormat);
1444 if (bWrongFormat || JS_PortIsNan(dRet)) {
1445 CFX_WideString swMsg;
1446 swMsg.Format(JSGetStringFromID(pContext, IDS_STRING_JSPARSEDATE).c_str(),
1447 sFormat.c_str());
1448 Alert(pContext, swMsg.c_str());
1449 pEvent->Rc() = FALSE;
1450 return TRUE;
Tom Sepez2f2ffec2015-07-23 14:42:09 -07001451 }
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001452 }
1453 return TRUE;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07001454}
1455
Tom Sepezba038bc2015-10-08 12:03:00 -07001456FX_BOOL CJS_PublicMethods::AFDate_Format(IJS_Context* cc,
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001457 const CJS_Parameters& params,
1458 CJS_Value& vRet,
1459 CFX_WideString& sError) {
Tom Sepez67fd5df2015-10-08 12:24:19 -07001460 CJS_Context* pContext = (CJS_Context*)cc;
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001461 if (params.size() != 1) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001462 sError = JSGetStringFromID(pContext, IDS_STRING_JSPARAMERROR);
1463 return FALSE;
1464 }
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07001465
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001466 int iIndex = params[0].ToInt();
1467 const FX_WCHAR* cFormats[] = {L"m/d",
1468 L"m/d/yy",
1469 L"mm/dd/yy",
1470 L"mm/yy",
1471 L"d-mmm",
1472 L"d-mmm-yy",
1473 L"dd-mmm-yy",
1474 L"yy-mm-dd",
1475 L"mmm-yy",
1476 L"mmmm-yy",
1477 L"mmm d, yyyy",
1478 L"mmmm d, yyyy",
1479 L"m/d/yy h:MM tt",
1480 L"m/d/yy HH:MM"};
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07001481
Lei Zhanga0f67242015-08-17 15:39:30 -07001482 if (iIndex < 0 || (static_cast<size_t>(iIndex) >= FX_ArraySize(cFormats)))
1483 iIndex = 0;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07001484
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001485 CJS_Parameters newParams;
Tom Sepez67fd5df2015-10-08 12:24:19 -07001486 newParams.push_back(
1487 CJS_Value(CJS_Runtime::FromContext(cc), cFormats[iIndex]));
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001488 return AFDate_FormatEx(cc, newParams, vRet, sError);
1489}
Lei Zhanga6d9f0e2015-06-13 00:48:38 -07001490
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001491// AFDate_KeystrokeEx(cFormat)
Tom Sepezba038bc2015-10-08 12:03:00 -07001492FX_BOOL CJS_PublicMethods::AFDate_Keystroke(IJS_Context* cc,
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001493 const CJS_Parameters& params,
1494 CJS_Value& vRet,
1495 CFX_WideString& sError) {
Tom Sepez67fd5df2015-10-08 12:24:19 -07001496 CJS_Context* pContext = (CJS_Context*)cc;
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001497 if (params.size() != 1) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001498 sError = JSGetStringFromID(pContext, IDS_STRING_JSPARAMERROR);
1499 return FALSE;
1500 }
1501
1502 int iIndex = params[0].ToInt();
1503 const FX_WCHAR* cFormats[] = {L"m/d",
1504 L"m/d/yy",
1505 L"mm/dd/yy",
1506 L"mm/yy",
1507 L"d-mmm",
1508 L"d-mmm-yy",
1509 L"dd-mmm-yy",
1510 L"yy-mm-dd",
1511 L"mmm-yy",
1512 L"mmmm-yy",
1513 L"mmm d, yyyy",
1514 L"mmmm d, yyyy",
1515 L"m/d/yy h:MM tt",
1516 L"m/d/yy HH:MM"};
1517
Lei Zhanga0f67242015-08-17 15:39:30 -07001518 if (iIndex < 0 || (static_cast<size_t>(iIndex) >= FX_ArraySize(cFormats)))
1519 iIndex = 0;
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001520
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001521 CJS_Parameters newParams;
Tom Sepez67fd5df2015-10-08 12:24:19 -07001522 newParams.push_back(
1523 CJS_Value(CJS_Runtime::FromContext(cc), cFormats[iIndex]));
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001524 return AFDate_KeystrokeEx(cc, newParams, vRet, sError);
1525}
1526
1527// function AFTime_Format(ptf)
Tom Sepezba038bc2015-10-08 12:03:00 -07001528FX_BOOL CJS_PublicMethods::AFTime_Format(IJS_Context* cc,
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001529 const CJS_Parameters& params,
1530 CJS_Value& vRet,
1531 CFX_WideString& sError) {
Tom Sepez67fd5df2015-10-08 12:24:19 -07001532 CJS_Context* pContext = (CJS_Context*)cc;
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001533 if (params.size() != 1) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001534 sError = JSGetStringFromID(pContext, IDS_STRING_JSPARAMERROR);
1535 return FALSE;
1536 }
1537
1538 int iIndex = params[0].ToInt();
1539 const FX_WCHAR* cFormats[] = {L"HH:MM", L"h:MM tt", L"HH:MM:ss",
1540 L"h:MM:ss tt"};
1541
Lei Zhanga0f67242015-08-17 15:39:30 -07001542 if (iIndex < 0 || (static_cast<size_t>(iIndex) >= FX_ArraySize(cFormats)))
1543 iIndex = 0;
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001544
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001545 CJS_Parameters newParams;
Tom Sepez67fd5df2015-10-08 12:24:19 -07001546 newParams.push_back(
1547 CJS_Value(CJS_Runtime::FromContext(cc), cFormats[iIndex]));
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001548 return AFDate_FormatEx(cc, newParams, vRet, sError);
1549}
1550
Tom Sepezba038bc2015-10-08 12:03:00 -07001551FX_BOOL CJS_PublicMethods::AFTime_Keystroke(IJS_Context* cc,
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001552 const CJS_Parameters& params,
1553 CJS_Value& vRet,
1554 CFX_WideString& sError) {
Tom Sepez67fd5df2015-10-08 12:24:19 -07001555 CJS_Context* pContext = (CJS_Context*)cc;
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001556 if (params.size() != 1) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001557 sError = JSGetStringFromID(pContext, IDS_STRING_JSPARAMERROR);
1558 return FALSE;
1559 }
1560
1561 int iIndex = params[0].ToInt();
1562 const FX_WCHAR* cFormats[] = {L"HH:MM", L"h:MM tt", L"HH:MM:ss",
1563 L"h:MM:ss tt"};
1564
Lei Zhanga0f67242015-08-17 15:39:30 -07001565 if (iIndex < 0 || (static_cast<size_t>(iIndex) >= FX_ArraySize(cFormats)))
1566 iIndex = 0;
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001567
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001568 CJS_Parameters newParams;
Tom Sepez67fd5df2015-10-08 12:24:19 -07001569 newParams.push_back(
1570 CJS_Value(CJS_Runtime::FromContext(cc), cFormats[iIndex]));
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001571 return AFDate_KeystrokeEx(cc, newParams, vRet, sError);
1572}
1573
Tom Sepezba038bc2015-10-08 12:03:00 -07001574FX_BOOL CJS_PublicMethods::AFTime_FormatEx(IJS_Context* cc,
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001575 const CJS_Parameters& params,
1576 CJS_Value& vRet,
1577 CFX_WideString& sError) {
1578 return AFDate_FormatEx(cc, params, vRet, sError);
1579}
1580
Tom Sepezba038bc2015-10-08 12:03:00 -07001581FX_BOOL CJS_PublicMethods::AFTime_KeystrokeEx(IJS_Context* cc,
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001582 const CJS_Parameters& params,
1583 CJS_Value& vRet,
1584 CFX_WideString& sError) {
1585 return AFDate_KeystrokeEx(cc, params, vRet, sError);
1586}
1587
1588// function AFSpecial_Format(psf)
Tom Sepezba038bc2015-10-08 12:03:00 -07001589FX_BOOL CJS_PublicMethods::AFSpecial_Format(IJS_Context* cc,
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001590 const CJS_Parameters& params,
1591 CJS_Value& vRet,
1592 CFX_WideString& sError) {
1593 CJS_Context* pContext = (CJS_Context*)cc;
1594 ASSERT(pContext != NULL);
1595
1596 if (params.size() != 1) {
1597 sError = JSGetStringFromID(pContext, IDS_STRING_JSPARAMERROR);
1598 return FALSE;
1599 }
1600
1601 std::string cFormat;
1602 int iIndex = params[0].ToInt();
1603
1604 CJS_EventHandler* pEvent = pContext->GetEventHandler();
1605 ASSERT(pEvent != NULL);
1606
1607 if (!pEvent->m_pValue)
1608 return FALSE;
1609 CFX_WideString& Value = pEvent->Value();
1610 std::string strSrc = CFX_ByteString::FromUnicode(Value).c_str();
1611
1612 switch (iIndex) {
Tom Sepez2f2ffec2015-07-23 14:42:09 -07001613 case 0:
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001614 cFormat = "99999";
1615 break;
Tom Sepez2f2ffec2015-07-23 14:42:09 -07001616 case 1:
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001617 cFormat = "99999-9999";
1618 break;
1619 case 2: {
1620 std::string NumberStr;
1621 util::printx("9999999999", strSrc, NumberStr);
1622 if (NumberStr.length() >= 10)
1623 cFormat = "(999) 999-9999";
1624 else
1625 cFormat = "999-9999";
1626 break;
1627 }
Tom Sepez2f2ffec2015-07-23 14:42:09 -07001628 case 3:
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001629 cFormat = "999-99-9999";
1630 break;
1631 }
1632
1633 std::string strDes;
1634 util::printx(cFormat, strSrc, strDes);
1635 Value = CFX_WideString::FromLocal(strDes.c_str());
1636 return TRUE;
1637}
1638
1639// function AFSpecial_KeystrokeEx(mask)
Tom Sepezba038bc2015-10-08 12:03:00 -07001640FX_BOOL CJS_PublicMethods::AFSpecial_KeystrokeEx(IJS_Context* cc,
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001641 const CJS_Parameters& params,
1642 CJS_Value& vRet,
1643 CFX_WideString& sError) {
1644 CJS_Context* pContext = (CJS_Context*)cc;
1645 ASSERT(pContext != NULL);
1646 CJS_EventHandler* pEvent = pContext->GetEventHandler();
1647
1648 ASSERT(pEvent != NULL);
1649
1650 if (params.size() < 1) {
1651 sError = JSGetStringFromID(pContext, IDS_STRING_JSPARAMERROR);
1652 return FALSE;
1653 }
1654
1655 if (!pEvent->m_pValue)
1656 return FALSE;
1657 CFX_WideString& valEvent = pEvent->Value();
1658
1659 CFX_WideString wstrMask = params[0].ToCFXWideString();
1660 if (wstrMask.IsEmpty())
1661 return TRUE;
1662
Lei Zhanga0f67242015-08-17 15:39:30 -07001663 const size_t wstrMaskLen = wstrMask.GetLength();
1664 const std::wstring wstrValue = valEvent.c_str();
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001665
1666 if (pEvent->WillCommit()) {
1667 if (wstrValue.empty())
1668 return TRUE;
Lei Zhanga0f67242015-08-17 15:39:30 -07001669 size_t iIndexMask = 0;
1670 for (const auto& w_Value : wstrValue) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001671 if (!maskSatisfied(w_Value, wstrMask[iIndexMask]))
Tom Sepez2f2ffec2015-07-23 14:42:09 -07001672 break;
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001673 iIndexMask++;
Tom Sepez2f2ffec2015-07-23 14:42:09 -07001674 }
Lei Zhanga6d9f0e2015-06-13 00:48:38 -07001675
Lei Zhanga0f67242015-08-17 15:39:30 -07001676 if (iIndexMask != wstrMaskLen ||
1677 (iIndexMask != wstrValue.size() && wstrMaskLen != 0)) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001678 Alert(
1679 pContext,
1680 JSGetStringFromID(pContext, IDS_STRING_JSAFNUMBER_KEYSTROKE).c_str());
1681 pEvent->Rc() = FALSE;
1682 }
Tom Sepez2f2ffec2015-07-23 14:42:09 -07001683 return TRUE;
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001684 }
1685
1686 CFX_WideString& wideChange = pEvent->Change();
1687 std::wstring wChange = wideChange.c_str();
1688 if (wChange.empty())
1689 return TRUE;
1690
1691 int iIndexMask = pEvent->SelStart();
1692
Lei Zhanga0f67242015-08-17 15:39:30 -07001693 size_t combined_len = wstrValue.length() + wChange.length() -
1694 (pEvent->SelEnd() - pEvent->SelStart());
1695 if (combined_len > wstrMaskLen) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001696 Alert(pContext,
1697 JSGetStringFromID(pContext, IDS_STRING_JSPARAM_TOOLONG).c_str());
1698 pEvent->Rc() = FALSE;
1699 return TRUE;
1700 }
1701
Lei Zhanga0f67242015-08-17 15:39:30 -07001702 if (iIndexMask >= wstrMaskLen && (!wChange.empty())) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001703 Alert(pContext,
1704 JSGetStringFromID(pContext, IDS_STRING_JSPARAM_TOOLONG).c_str());
1705 pEvent->Rc() = FALSE;
1706 return TRUE;
1707 }
1708
1709 for (std::wstring::iterator it = wChange.begin(); it != wChange.end(); it++) {
Lei Zhanga0f67242015-08-17 15:39:30 -07001710 if (iIndexMask >= wstrMaskLen) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001711 Alert(pContext,
1712 JSGetStringFromID(pContext, IDS_STRING_JSPARAM_TOOLONG).c_str());
1713 pEvent->Rc() = FALSE;
1714 return TRUE;
1715 }
1716 wchar_t w_Mask = wstrMask[iIndexMask];
1717 if (!isReservedMaskChar(w_Mask)) {
1718 *it = w_Mask;
1719 }
1720 wchar_t w_Change = *it;
1721 if (!maskSatisfied(w_Change, w_Mask)) {
1722 pEvent->Rc() = FALSE;
1723 return TRUE;
1724 }
1725 iIndexMask++;
1726 }
1727
1728 wideChange = wChange.c_str();
1729 return TRUE;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07001730}
1731
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001732// function AFSpecial_Keystroke(psf)
Tom Sepezba038bc2015-10-08 12:03:00 -07001733FX_BOOL CJS_PublicMethods::AFSpecial_Keystroke(IJS_Context* cc,
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001734 const CJS_Parameters& params,
1735 CJS_Value& vRet,
1736 CFX_WideString& sError) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001737 CJS_Context* pContext = (CJS_Context*)cc;
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001738 if (params.size() != 1) {
1739 sError = JSGetStringFromID(pContext, IDS_STRING_JSPARAMERROR);
1740 return FALSE;
1741 }
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07001742
Tom Sepez67fd5df2015-10-08 12:24:19 -07001743 CJS_EventHandler* pEvent = pContext->GetEventHandler();
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001744 if (!pEvent->m_pValue)
1745 return FALSE;
Tom Sepez67fd5df2015-10-08 12:24:19 -07001746
1747 std::string cFormat;
1748 int iIndex = params[0].ToInt();
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001749 CFX_WideString& val = pEvent->Value();
1750 std::string strSrc = CFX_ByteString::FromUnicode(val).c_str();
1751 std::wstring wstrChange = pEvent->Change().c_str();
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07001752
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001753 switch (iIndex) {
Tom Sepez2f2ffec2015-07-23 14:42:09 -07001754 case 0:
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001755 cFormat = "99999";
1756 break;
Tom Sepez2f2ffec2015-07-23 14:42:09 -07001757 case 1:
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001758 // cFormat = "99999-9999";
1759 cFormat = "999999999";
1760 break;
1761 case 2: {
1762 std::string NumberStr;
1763 util::printx("9999999999", strSrc, NumberStr);
1764 if (strSrc.length() + wstrChange.length() > 7)
1765 // cFormat = "(999) 999-9999";
1766 cFormat = "9999999999";
1767 else
1768 // cFormat = "999-9999";
1769 cFormat = "9999999";
1770 break;
1771 }
Tom Sepez2f2ffec2015-07-23 14:42:09 -07001772 case 3:
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001773 // cFormat = "999-99-9999";
1774 cFormat = "999999999";
1775 break;
1776 }
Lei Zhanga6d9f0e2015-06-13 00:48:38 -07001777
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001778 CJS_Parameters params2;
Tom Sepez67fd5df2015-10-08 12:24:19 -07001779 params2.push_back(CJS_Value(CJS_Runtime::FromContext(cc), cFormat.c_str()));
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001780 return AFSpecial_KeystrokeEx(cc, params2, vRet, sError);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07001781}
1782
Tom Sepezba038bc2015-10-08 12:03:00 -07001783FX_BOOL CJS_PublicMethods::AFMergeChange(IJS_Context* cc,
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001784 const CJS_Parameters& params,
1785 CJS_Value& vRet,
1786 CFX_WideString& sError) {
1787 CJS_Context* pContext = (CJS_Context*)cc;
1788 ASSERT(pContext != NULL);
1789 CJS_EventHandler* pEventHandler = pContext->GetEventHandler();
1790 ASSERT(pEventHandler != NULL);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07001791
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001792 if (params.size() != 1) {
1793 sError = JSGetStringFromID(pContext, IDS_STRING_JSPARAMERROR);
1794 return FALSE;
1795 }
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07001796
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001797 CFX_WideString swValue;
1798 if (pEventHandler->m_pValue != NULL)
1799 swValue = pEventHandler->Value();
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07001800
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001801 if (pEventHandler->WillCommit()) {
1802 vRet = swValue.c_str();
Tom Sepez2f2ffec2015-07-23 14:42:09 -07001803 return TRUE;
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001804 }
1805
1806 CFX_WideString prefix, postfix;
1807
1808 if (pEventHandler->SelStart() >= 0)
1809 prefix = swValue.Mid(0, pEventHandler->SelStart());
1810 else
1811 prefix = L"";
1812
1813 if (pEventHandler->SelEnd() >= 0 &&
1814 pEventHandler->SelEnd() <= swValue.GetLength())
1815 postfix = swValue.Mid(pEventHandler->SelEnd(),
1816 swValue.GetLength() - pEventHandler->SelEnd());
1817 else
1818 postfix = L"";
1819
1820 vRet = (prefix + pEventHandler->Change() + postfix).c_str();
1821
1822 return TRUE;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07001823}
1824
Tom Sepezba038bc2015-10-08 12:03:00 -07001825FX_BOOL CJS_PublicMethods::AFParseDateEx(IJS_Context* cc,
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001826 const CJS_Parameters& params,
1827 CJS_Value& vRet,
1828 CFX_WideString& sError) {
1829 CJS_Context* pContext = (CJS_Context*)cc;
1830 ASSERT(pContext != NULL);
1831
1832 if (params.size() != 2) {
1833 sError = JSGetStringFromID(pContext, IDS_STRING_JSPARAMERROR);
1834 return FALSE;
1835 }
1836
1837 CFX_WideString sValue = params[0].ToCFXWideString();
1838 CFX_WideString sFormat = params[1].ToCFXWideString();
1839
1840 FX_BOOL bWrongFormat = FALSE;
1841 double dDate = MakeRegularDate(sValue, sFormat, bWrongFormat);
1842
1843 if (JS_PortIsNan(dDate)) {
1844 CFX_WideString swMsg;
1845 swMsg.Format(JSGetStringFromID(pContext, IDS_STRING_JSPARSEDATE).c_str(),
1846 sFormat.c_str());
1847 Alert((CJS_Context*)cc, swMsg.c_str());
1848 return FALSE;
1849 }
1850
1851 vRet = dDate;
1852 return TRUE;
1853}
1854
Tom Sepezba038bc2015-10-08 12:03:00 -07001855FX_BOOL CJS_PublicMethods::AFSimple(IJS_Context* cc,
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001856 const CJS_Parameters& params,
1857 CJS_Value& vRet,
1858 CFX_WideString& sError) {
1859 if (params.size() != 3) {
1860 CJS_Context* pContext = (CJS_Context*)cc;
Tom Sepez2f2ffec2015-07-23 14:42:09 -07001861 ASSERT(pContext != NULL);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07001862
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001863 sError = JSGetStringFromID(pContext, IDS_STRING_JSPARAMERROR);
1864 return FALSE;
1865 }
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07001866
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001867 vRet = (double)AF_Simple(params[0].ToCFXWideString().c_str(),
1868 params[1].ToDouble(), params[2].ToDouble());
1869 return TRUE;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07001870}
1871
Tom Sepezba038bc2015-10-08 12:03:00 -07001872FX_BOOL CJS_PublicMethods::AFMakeNumber(IJS_Context* cc,
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001873 const CJS_Parameters& params,
1874 CJS_Value& vRet,
1875 CFX_WideString& sError) {
1876 if (params.size() != 1) {
1877 CJS_Context* pContext = (CJS_Context*)cc;
Tom Sepez2f2ffec2015-07-23 14:42:09 -07001878 ASSERT(pContext != NULL);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07001879
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001880 sError = JSGetStringFromID(pContext, IDS_STRING_JSPARAMERROR);
1881 return FALSE;
1882 }
1883 vRet = ParseStringToNumber(params[0].ToCFXWideString().c_str());
1884 return TRUE;
1885}
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07001886
Tom Sepezba038bc2015-10-08 12:03:00 -07001887FX_BOOL CJS_PublicMethods::AFSimple_Calculate(IJS_Context* cc,
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001888 const CJS_Parameters& params,
1889 CJS_Value& vRet,
1890 CFX_WideString& sError) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001891 CJS_Context* pContext = (CJS_Context*)cc;
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001892 if (params.size() != 2) {
1893 sError = JSGetStringFromID(pContext, IDS_STRING_JSPARAMERROR);
1894 return FALSE;
1895 }
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07001896
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001897 CJS_Value params1 = params[1];
Tom Sepez39bfe122015-09-17 15:25:23 -07001898 if (!params1.IsArrayObject() && params1.GetType() != CJS_Value::VT_string) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001899 sError = JSGetStringFromID(pContext, IDS_STRING_JSPARAMERROR);
1900 return FALSE;
1901 }
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07001902
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001903 CPDFSDK_Document* pReaderDoc = pContext->GetReaderDocument();
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001904 CPDFSDK_InterForm* pReaderInterForm = pReaderDoc->GetInterForm();
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001905 CPDF_InterForm* pInterForm = pReaderInterForm->GetInterForm();
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07001906
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001907 CFX_WideString sFunction = params[0].ToCFXWideString();
Tom Sepez67fd5df2015-10-08 12:24:19 -07001908 double dValue = wcscmp(sFunction.c_str(), L"PRD") == 0 ? 1.0 : 0.0;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07001909
Tom Sepez67fd5df2015-10-08 12:24:19 -07001910 CJS_Runtime* pRuntime = CJS_Runtime::FromContext(cc);
1911 CJS_Array FieldNameArray = AF_MakeArrayFromList(pRuntime, params1);
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001912 int nFieldsCount = 0;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07001913
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001914 for (int i = 0, isz = FieldNameArray.GetLength(); i < isz; i++) {
Tom Sepez67fd5df2015-10-08 12:24:19 -07001915 CJS_Value jsValue(pRuntime);
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001916 FieldNameArray.GetElement(i, jsValue);
1917 CFX_WideString wsFieldName = jsValue.ToCFXWideString();
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07001918
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001919 for (int j = 0, jsz = pInterForm->CountFields(wsFieldName); j < jsz; j++) {
1920 if (CPDF_FormField* pFormField = pInterForm->GetField(j, wsFieldName)) {
1921 double dTemp = 0.0;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07001922
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001923 switch (pFormField->GetFieldType()) {
1924 case FIELDTYPE_TEXTFIELD:
1925 case FIELDTYPE_COMBOBOX: {
1926 dTemp = ParseStringToNumber(pFormField->GetValue().c_str());
1927 break;
1928 }
1929 case FIELDTYPE_PUSHBUTTON: {
1930 dTemp = 0.0;
1931 break;
1932 }
1933 case FIELDTYPE_CHECKBOX:
1934 case FIELDTYPE_RADIOBUTTON: {
1935 dTemp = 0.0;
1936 for (int c = 0, csz = pFormField->CountControls(); c < csz; c++) {
1937 if (CPDF_FormControl* pFormCtrl = pFormField->GetControl(c)) {
1938 if (pFormCtrl->IsChecked()) {
1939 dTemp +=
1940 ParseStringToNumber(pFormCtrl->GetExportValue().c_str());
1941 break;
1942 } else
1943 continue;
1944 }
Tom Sepez2f2ffec2015-07-23 14:42:09 -07001945 }
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001946 break;
1947 }
1948 case FIELDTYPE_LISTBOX: {
1949 dTemp = 0.0;
1950 if (pFormField->CountSelectedItems() > 1)
1951 break;
1952 else {
1953 dTemp = ParseStringToNumber(pFormField->GetValue().c_str());
1954 break;
1955 }
1956 }
1957 default:
1958 break;
Tom Sepez2f2ffec2015-07-23 14:42:09 -07001959 }
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001960
1961 if (i == 0 && j == 0 && (wcscmp(sFunction.c_str(), L"MIN") == 0 ||
1962 wcscmp(sFunction.c_str(), L"MAX") == 0))
1963 dValue = dTemp;
1964
1965 dValue = AF_Simple(sFunction.c_str(), dValue, dTemp);
1966
1967 nFieldsCount++;
1968 }
Tom Sepez2f2ffec2015-07-23 14:42:09 -07001969 }
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001970 }
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07001971
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001972 if (wcscmp(sFunction.c_str(), L"AVG") == 0 && nFieldsCount > 0)
1973 dValue /= nFieldsCount;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07001974
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001975 dValue = (double)floor(dValue * FXSYS_pow((double)10, (double)6) + 0.49) /
1976 FXSYS_pow((double)10, (double)6);
Tom Sepez67fd5df2015-10-08 12:24:19 -07001977 CJS_Value jsValue(pRuntime, dValue);
foxit8b544ed2015-09-10 14:57:54 +08001978 if (pContext->GetEventHandler()->m_pValue)
1979 pContext->GetEventHandler()->Value() = jsValue.ToCFXWideString();
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07001980
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001981 return TRUE;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07001982}
1983
Lei Zhanga6d9f0e2015-06-13 00:48:38 -07001984/* This function validates the current event to ensure that its value is
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07001985** within the specified range. */
1986
Tom Sepezba038bc2015-10-08 12:03:00 -07001987FX_BOOL CJS_PublicMethods::AFRange_Validate(IJS_Context* cc,
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001988 const CJS_Parameters& params,
1989 CJS_Value& vRet,
1990 CFX_WideString& sError) {
1991 CJS_Context* pContext = (CJS_Context*)cc;
1992 ASSERT(pContext != NULL);
1993 CJS_EventHandler* pEvent = pContext->GetEventHandler();
1994 ASSERT(pEvent != NULL);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07001995
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001996 if (params.size() != 4) {
1997 sError = JSGetStringFromID(pContext, IDS_STRING_JSPARAMERROR);
1998 return FALSE;
1999 }
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07002000
Nico Weber9d8ec5a2015-08-04 13:00:21 -07002001 if (!pEvent->m_pValue)
2002 return FALSE;
2003 if (pEvent->Value().IsEmpty())
Tom Sepez2f2ffec2015-07-23 14:42:09 -07002004 return TRUE;
Nico Weber9d8ec5a2015-08-04 13:00:21 -07002005 double dEentValue = atof(CFX_ByteString::FromUnicode(pEvent->Value()));
2006 FX_BOOL bGreaterThan = params[0].ToBool();
2007 double dGreaterThan = params[1].ToDouble();
2008 FX_BOOL bLessThan = params[2].ToBool();
2009 double dLessThan = params[3].ToDouble();
2010 CFX_WideString swMsg;
2011
2012 if (bGreaterThan && bLessThan) {
2013 if (dEentValue < dGreaterThan || dEentValue > dLessThan)
2014 swMsg.Format(JSGetStringFromID(pContext, IDS_STRING_JSRANGE1).c_str(),
2015 params[1].ToCFXWideString().c_str(),
2016 params[3].ToCFXWideString().c_str());
2017 } else if (bGreaterThan) {
2018 if (dEentValue < dGreaterThan)
2019 swMsg.Format(JSGetStringFromID(pContext, IDS_STRING_JSRANGE2).c_str(),
2020 params[1].ToCFXWideString().c_str());
2021 } else if (bLessThan) {
2022 if (dEentValue > dLessThan)
2023 swMsg.Format(JSGetStringFromID(pContext, IDS_STRING_JSRANGE3).c_str(),
2024 params[3].ToCFXWideString().c_str());
2025 }
2026
2027 if (!swMsg.IsEmpty()) {
2028 Alert(pContext, swMsg.c_str());
2029 pEvent->Rc() = FALSE;
2030 }
2031 return TRUE;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07002032}
2033
Tom Sepezba038bc2015-10-08 12:03:00 -07002034FX_BOOL CJS_PublicMethods::AFExtractNums(IJS_Context* cc,
Nico Weber9d8ec5a2015-08-04 13:00:21 -07002035 const CJS_Parameters& params,
2036 CJS_Value& vRet,
2037 CFX_WideString& sError) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -07002038 CJS_Context* pContext = (CJS_Context*)cc;
Nico Weber9d8ec5a2015-08-04 13:00:21 -07002039 if (params.size() != 1) {
2040 sError = JSGetStringFromID(pContext, IDS_STRING_JSPARAMERROR);
2041 return FALSE;
2042 }
2043
Tom Sepez67fd5df2015-10-08 12:24:19 -07002044 CJS_Runtime* pRuntime = CJS_Runtime::FromContext(cc);
2045 CJS_Array nums(pRuntime);
Nico Weber9d8ec5a2015-08-04 13:00:21 -07002046
2047 CFX_WideString str = params[0].ToCFXWideString();
2048 CFX_WideString sPart;
2049
2050 if (str.GetAt(0) == L'.' || str.GetAt(0) == L',')
2051 str = L"0" + str;
2052
2053 int nIndex = 0;
2054 for (int i = 0, sz = str.GetLength(); i < sz; i++) {
2055 FX_WCHAR wc = str.GetAt(i);
2056 if (IsDigit((wchar_t)wc)) {
2057 sPart += wc;
2058 } else {
2059 if (sPart.GetLength() > 0) {
Tom Sepez67fd5df2015-10-08 12:24:19 -07002060 nums.SetElement(nIndex, CJS_Value(pRuntime, sPart.c_str()));
Nico Weber9d8ec5a2015-08-04 13:00:21 -07002061 sPart = L"";
2062 nIndex++;
2063 }
Tom Sepez2f2ffec2015-07-23 14:42:09 -07002064 }
Nico Weber9d8ec5a2015-08-04 13:00:21 -07002065 }
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07002066
Nico Weber9d8ec5a2015-08-04 13:00:21 -07002067 if (sPart.GetLength() > 0) {
Tom Sepez67fd5df2015-10-08 12:24:19 -07002068 nums.SetElement(nIndex, CJS_Value(pRuntime, sPart.c_str()));
Nico Weber9d8ec5a2015-08-04 13:00:21 -07002069 }
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07002070
Nico Weber9d8ec5a2015-08-04 13:00:21 -07002071 if (nums.GetLength() > 0)
2072 vRet = nums;
2073 else
2074 vRet.SetNull();
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07002075
Nico Weber9d8ec5a2015-08-04 13:00:21 -07002076 return TRUE;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07002077}