blob: ac9669d564e4643b2d68f791d1cc0985a92b449d [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,
Lei Zhang945fdb72015-11-11 10:18:16 -0800906 const std::vector<CJS_Value>& params,
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700907 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)
Lei Zhang945fdb72015-11-11 10:18:16 -08001084FX_BOOL CJS_PublicMethods::AFNumber_Keystroke(
1085 IJS_Context* cc,
1086 const std::vector<CJS_Value>& params,
1087 CJS_Value& vRet,
1088 CFX_WideString& sError) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001089 CJS_Context* pContext = (CJS_Context*)cc;
1090 ASSERT(pContext != NULL);
1091 CJS_EventHandler* pEvent = pContext->GetEventHandler();
1092 ASSERT(pEvent != NULL);
Lei Zhanga6d9f0e2015-06-13 00:48:38 -07001093
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001094 if (params.size() < 2)
1095 return FALSE;
1096 int iSepStyle = params[1].ToInt();
Lei Zhanga6d9f0e2015-06-13 00:48:38 -07001097
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001098 if (iSepStyle < 0 || iSepStyle > 3)
1099 iSepStyle = 0;
1100 if (!pEvent->m_pValue)
1101 return FALSE;
1102 CFX_WideString& val = pEvent->Value();
1103 CFX_WideString& w_strChange = pEvent->Change();
1104 CFX_WideString w_strValue = val;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07001105
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001106 if (pEvent->WillCommit()) {
1107 CFX_WideString wstrChange = w_strChange;
1108 CFX_WideString wstrValue = StrLTrim(w_strValue.c_str());
1109 if (wstrValue.IsEmpty())
1110 return TRUE;
Lei Zhanga6d9f0e2015-06-13 00:48:38 -07001111
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001112 CFX_WideString swTemp = wstrValue;
1113 swTemp.Replace(L",", L".");
1114 if (!IsNumber(swTemp.c_str())) {
1115 pEvent->Rc() = FALSE;
1116 sError = JSGetStringFromID(pContext, IDS_STRING_JSAFNUMBER_KEYSTROKE);
1117 Alert(pContext, sError.c_str());
1118 return TRUE;
Tom Sepez2f2ffec2015-07-23 14:42:09 -07001119 }
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001120 return TRUE; // it happens after the last keystroke and before validating,
1121 }
Tom Sepez4f7bc042015-04-27 12:06:58 -07001122
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001123 std::wstring w_strValue2 = w_strValue.c_str();
1124 std::wstring w_strChange2 = w_strChange.c_str();
1125 std::wstring w_strSelected;
1126 if (-1 != pEvent->SelStart())
1127 w_strSelected = w_strValue2.substr(pEvent->SelStart(),
1128 (pEvent->SelEnd() - pEvent->SelStart()));
Lei Zhangb9c31972015-08-11 14:09:35 -07001129 bool bHasSign = (w_strValue2.find('-') != std::wstring::npos) &&
1130 (w_strSelected.find('-') == std::wstring::npos);
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001131 if (bHasSign) {
1132 // can't insert "change" in front to sign postion.
1133 if (pEvent->SelStart() == 0) {
1134 FX_BOOL& bRc = pEvent->Rc();
1135 bRc = FALSE;
1136 return TRUE;
Tom Sepez2f2ffec2015-07-23 14:42:09 -07001137 }
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001138 }
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07001139
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001140 char cSep = L'.';
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07001141
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001142 switch (iSepStyle) {
Tom Sepez2f2ffec2015-07-23 14:42:09 -07001143 case 0:
1144 case 1:
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001145 cSep = L'.';
1146 break;
Tom Sepez2f2ffec2015-07-23 14:42:09 -07001147 case 2:
1148 case 3:
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001149 cSep = L',';
1150 break;
1151 }
Lei Zhanga6d9f0e2015-06-13 00:48:38 -07001152
Lei Zhangb9c31972015-08-11 14:09:35 -07001153 bool bHasSep = (w_strValue2.find(cSep) != std::wstring::npos);
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001154 for (std::wstring::iterator it = w_strChange2.begin();
1155 it != w_strChange2.end(); it++) {
1156 if (*it == cSep) {
1157 if (bHasSep) {
1158 FX_BOOL& bRc = pEvent->Rc();
1159 bRc = FALSE;
Tom Sepez2f2ffec2015-07-23 14:42:09 -07001160 return TRUE;
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001161 }
1162 bHasSep = TRUE;
1163 continue;
1164 }
1165 if (*it == L'-') {
1166 if (bHasSign) {
1167 FX_BOOL& bRc = pEvent->Rc();
1168 bRc = FALSE;
1169 return TRUE;
1170 }
1171 if (it != w_strChange2.begin()) // sign's position is not correct
1172 {
1173 FX_BOOL& bRc = pEvent->Rc();
1174 bRc = FALSE;
1175 return TRUE;
1176 }
1177 if (pEvent->SelStart() != 0) {
1178 FX_BOOL& bRc = pEvent->Rc();
1179 bRc = FALSE;
1180 return TRUE;
1181 }
1182 bHasSign = TRUE;
1183 continue;
1184 }
1185
1186 if (!IsDigit(*it)) {
1187 FX_BOOL& bRc = pEvent->Rc();
1188 bRc = FALSE;
1189 return TRUE;
1190 }
1191 }
1192
1193 std::wstring w_prefix = w_strValue2.substr(0, pEvent->SelStart());
1194 std::wstring w_postfix;
1195 if (pEvent->SelEnd() < (int)w_strValue2.length())
1196 w_postfix = w_strValue2.substr(pEvent->SelEnd());
1197 w_strValue2 = w_prefix + w_strChange2 + w_postfix;
1198 w_strValue = w_strValue2.c_str();
1199 val = w_strValue;
1200 return TRUE;
1201}
1202
1203// function AFPercent_Format(nDec, sepStyle)
Lei Zhang945fdb72015-11-11 10:18:16 -08001204FX_BOOL CJS_PublicMethods::AFPercent_Format(
1205 IJS_Context* cc,
1206 const std::vector<CJS_Value>& params,
1207 CJS_Value& vRet,
1208 CFX_WideString& sError) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001209#if _FX_OS_ != _FX_ANDROID_
1210 CJS_Context* pContext = (CJS_Context*)cc;
1211 ASSERT(pContext != NULL);
1212 CJS_EventHandler* pEvent = pContext->GetEventHandler();
1213 ASSERT(pEvent != NULL);
1214
1215 if (params.size() != 2) {
1216 sError = JSGetStringFromID(pContext, IDS_STRING_JSPARAMERROR);
1217 return FALSE;
1218 }
1219 if (!pEvent->m_pValue)
1220 return FALSE;
1221
1222 CFX_WideString& Value = pEvent->Value();
1223 CFX_ByteString strValue = StrTrim(CFX_ByteString::FromUnicode(Value));
1224 if (strValue.IsEmpty())
1225 return TRUE;
1226
1227 int iDec = params[0].ToInt();
1228 if (iDec < 0)
1229 iDec = -iDec;
1230
1231 int iSepStyle = params[1].ToInt();
1232 if (iSepStyle < 0 || iSepStyle > 3)
1233 iSepStyle = 0;
1234
1235 //////////////////////////////////////////////////////
1236 // for processing decimal places
1237 double dValue = atof(strValue);
1238 dValue *= 100;
1239 if (iDec > 0)
1240 dValue += DOUBLE_CORRECT; //УÕý
1241
1242 int iDec2;
1243 int iNegative = 0;
1244 strValue = fcvt(dValue, iDec, &iDec2, &iNegative);
1245 if (strValue.IsEmpty()) {
1246 dValue = 0;
1247 strValue = fcvt(dValue, iDec, &iDec2, &iNegative);
1248 }
1249
1250 if (iDec2 < 0) {
1251 for (int iNum = 0; iNum < abs(iDec2); iNum++) {
1252 strValue = "0" + strValue;
1253 }
1254 iDec2 = 0;
1255 }
1256 int iMax = strValue.GetLength();
1257 if (iDec2 > iMax) {
1258 for (int iNum = 0; iNum <= iDec2 - iMax; iNum++) {
1259 strValue += "0";
1260 }
1261 iMax = iDec2 + 1;
1262 }
1263 ///////////////////////////////////////////////////////
1264 // for processing seperator style
1265 if (iDec2 < iMax) {
1266 if (iSepStyle == 0 || iSepStyle == 1) {
1267 strValue.Insert(iDec2, '.');
1268 iMax++;
1269 } else if (iSepStyle == 2 || iSepStyle == 3) {
1270 strValue.Insert(iDec2, ',');
1271 iMax++;
1272 }
1273
1274 if (iDec2 == 0)
1275 strValue.Insert(iDec2, '0');
1276 }
1277 if (iSepStyle == 0 || iSepStyle == 2) {
1278 char cSeperator;
1279 if (iSepStyle == 0)
1280 cSeperator = ',';
1281 else
1282 cSeperator = '.';
1283
Tom Sepezdfbf8e72015-10-14 14:17:26 -07001284 for (int iDecPositive = iDec2 - 3; iDecPositive > 0; iDecPositive -= 3) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001285 strValue.Insert(iDecPositive, cSeperator);
1286 iMax++;
1287 }
1288 }
1289 ////////////////////////////////////////////////////////////////////
1290 // negative mark
1291 if (iNegative)
1292 strValue = "-" + strValue;
1293 strValue += "%";
1294 Value = CFX_WideString::FromLocal(strValue);
1295#endif
1296 return TRUE;
1297}
1298// AFPercent_Keystroke(nDec, sepStyle)
Lei Zhang945fdb72015-11-11 10:18:16 -08001299FX_BOOL CJS_PublicMethods::AFPercent_Keystroke(
1300 IJS_Context* cc,
1301 const std::vector<CJS_Value>& params,
1302 CJS_Value& vRet,
1303 CFX_WideString& sError) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001304 return AFNumber_Keystroke(cc, params, vRet, sError);
1305}
1306
1307// function AFDate_FormatEx(cFormat)
Tom Sepezba038bc2015-10-08 12:03:00 -07001308FX_BOOL CJS_PublicMethods::AFDate_FormatEx(IJS_Context* cc,
Lei Zhang945fdb72015-11-11 10:18:16 -08001309 const std::vector<CJS_Value>& params,
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001310 CJS_Value& vRet,
1311 CFX_WideString& sError) {
1312 CJS_Context* pContext = (CJS_Context*)cc;
1313 ASSERT(pContext != NULL);
1314 CJS_EventHandler* pEvent = pContext->GetEventHandler();
1315 ASSERT(pEvent != NULL);
1316
1317 if (params.size() != 1) {
1318 sError = JSGetStringFromID(pContext, IDS_STRING_JSPARAMERROR);
1319 return FALSE;
1320 }
1321 if (!pEvent->m_pValue)
1322 return FALSE;
1323
1324 CFX_WideString& val = pEvent->Value();
1325 CFX_WideString strValue = val;
1326 if (strValue.IsEmpty())
1327 return TRUE;
1328
1329 CFX_WideString sFormat = params[0].ToCFXWideString();
1330 FX_BOOL bWrongFormat = FALSE;
1331 double dDate = 0.0f;
1332
1333 if (strValue.Find(L"GMT") != -1) {
1334 // for GMT format time
1335 // such as "Tue Aug 11 14:24:16 GMT+08002009"
1336 dDate = MakeInterDate(strValue);
1337 } else {
1338 dDate = MakeRegularDate(strValue, sFormat, bWrongFormat);
1339 }
1340
1341 if (JS_PortIsNan(dDate)) {
1342 CFX_WideString swMsg;
1343 swMsg.Format(JSGetStringFromID(pContext, IDS_STRING_JSPARSEDATE).c_str(),
1344 sFormat.c_str());
1345 Alert(pContext, swMsg.c_str());
1346 return FALSE;
1347 }
1348
1349 val = MakeFormatDate(dDate, sFormat);
1350 return TRUE;
1351}
1352
1353double CJS_PublicMethods::MakeInterDate(CFX_WideString strValue) {
1354 int nHour;
1355 int nMin;
1356 int nSec;
1357 int nYear;
1358 int nMonth;
1359 int nDay;
1360
1361 CFX_WideStringArray wsArray;
1362 CFX_WideString sMonth = L"";
1363 CFX_WideString sTemp = L"";
1364 int nSize = strValue.GetLength();
1365
1366 for (int i = 0; i < nSize; i++) {
1367 FX_WCHAR c = strValue.GetAt(i);
1368 if (c == L' ' || c == L':') {
1369 wsArray.Add(sTemp);
1370 sTemp = L"";
1371 continue;
1372 }
1373
1374 sTemp += c;
1375 }
1376
1377 wsArray.Add(sTemp);
1378 if (wsArray.GetSize() != 8)
1379 return 0;
1380
1381 sTemp = wsArray[1];
1382 if (sTemp.Compare(L"Jan") == 0)
1383 nMonth = 1;
1384 if (sTemp.Compare(L"Feb") == 0)
1385 nMonth = 2;
1386 if (sTemp.Compare(L"Mar") == 0)
1387 nMonth = 3;
1388 if (sTemp.Compare(L"Apr") == 0)
1389 nMonth = 4;
1390 if (sTemp.Compare(L"May") == 0)
1391 nMonth = 5;
1392 if (sTemp.Compare(L"Jun") == 0)
1393 nMonth = 6;
1394 if (sTemp.Compare(L"Jul") == 0)
1395 nMonth = 7;
1396 if (sTemp.Compare(L"Aug") == 0)
1397 nMonth = 8;
1398 if (sTemp.Compare(L"Sep") == 0)
1399 nMonth = 9;
1400 if (sTemp.Compare(L"Oct") == 0)
1401 nMonth = 10;
1402 if (sTemp.Compare(L"Nov") == 0)
1403 nMonth = 11;
1404 if (sTemp.Compare(L"Dec") == 0)
1405 nMonth = 12;
1406
1407 nDay = (int)ParseStringToNumber(wsArray[2].c_str());
1408 nHour = (int)ParseStringToNumber(wsArray[3].c_str());
1409 nMin = (int)ParseStringToNumber(wsArray[4].c_str());
1410 nSec = (int)ParseStringToNumber(wsArray[5].c_str());
1411 nYear = (int)ParseStringToNumber(wsArray[7].c_str());
1412
1413 double dRet = JS_MakeDate(JS_MakeDay(nYear, nMonth - 1, nDay),
1414 JS_MakeTime(nHour, nMin, nSec, 0));
1415
1416 if (JS_PortIsNan(dRet)) {
1417 dRet = JS_DateParse(strValue.c_str());
1418 }
1419
1420 return dRet;
1421}
1422
1423// AFDate_KeystrokeEx(cFormat)
Lei Zhang945fdb72015-11-11 10:18:16 -08001424FX_BOOL CJS_PublicMethods::AFDate_KeystrokeEx(
1425 IJS_Context* cc,
1426 const std::vector<CJS_Value>& params,
1427 CJS_Value& vRet,
1428 CFX_WideString& sError) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001429 CJS_Context* pContext = (CJS_Context*)cc;
1430 ASSERT(pContext != NULL);
1431 CJS_EventHandler* pEvent = pContext->GetEventHandler();
1432 ASSERT(pEvent != NULL);
1433
1434 if (params.size() != 1) {
1435 sError = L"AFDate_KeystrokeEx's parameters' size r not correct";
1436 return FALSE;
1437 }
1438
1439 if (pEvent->WillCommit()) {
1440 if (!pEvent->m_pValue)
1441 return FALSE;
1442 CFX_WideString strValue = pEvent->Value();
1443 if (strValue.IsEmpty())
1444 return TRUE;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07001445
Tom Sepez2f2ffec2015-07-23 14:42:09 -07001446 CFX_WideString sFormat = params[0].ToCFXWideString();
1447 FX_BOOL bWrongFormat = FALSE;
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001448 double dRet = MakeRegularDate(strValue, sFormat, bWrongFormat);
1449 if (bWrongFormat || JS_PortIsNan(dRet)) {
1450 CFX_WideString swMsg;
1451 swMsg.Format(JSGetStringFromID(pContext, IDS_STRING_JSPARSEDATE).c_str(),
1452 sFormat.c_str());
1453 Alert(pContext, swMsg.c_str());
1454 pEvent->Rc() = FALSE;
1455 return TRUE;
Tom Sepez2f2ffec2015-07-23 14:42:09 -07001456 }
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001457 }
1458 return TRUE;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07001459}
1460
Tom Sepezba038bc2015-10-08 12:03:00 -07001461FX_BOOL CJS_PublicMethods::AFDate_Format(IJS_Context* cc,
Lei Zhang945fdb72015-11-11 10:18:16 -08001462 const std::vector<CJS_Value>& params,
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001463 CJS_Value& vRet,
1464 CFX_WideString& sError) {
Tom Sepez67fd5df2015-10-08 12:24:19 -07001465 CJS_Context* pContext = (CJS_Context*)cc;
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001466 if (params.size() != 1) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001467 sError = JSGetStringFromID(pContext, IDS_STRING_JSPARAMERROR);
1468 return FALSE;
1469 }
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07001470
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001471 int iIndex = params[0].ToInt();
1472 const FX_WCHAR* cFormats[] = {L"m/d",
1473 L"m/d/yy",
1474 L"mm/dd/yy",
1475 L"mm/yy",
1476 L"d-mmm",
1477 L"d-mmm-yy",
1478 L"dd-mmm-yy",
1479 L"yy-mm-dd",
1480 L"mmm-yy",
1481 L"mmmm-yy",
1482 L"mmm d, yyyy",
1483 L"mmmm d, yyyy",
1484 L"m/d/yy h:MM tt",
1485 L"m/d/yy HH:MM"};
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07001486
Lei Zhanga0f67242015-08-17 15:39:30 -07001487 if (iIndex < 0 || (static_cast<size_t>(iIndex) >= FX_ArraySize(cFormats)))
1488 iIndex = 0;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07001489
Lei Zhang945fdb72015-11-11 10:18:16 -08001490 std::vector<CJS_Value> newParams;
Tom Sepez67fd5df2015-10-08 12:24:19 -07001491 newParams.push_back(
1492 CJS_Value(CJS_Runtime::FromContext(cc), cFormats[iIndex]));
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001493 return AFDate_FormatEx(cc, newParams, vRet, sError);
1494}
Lei Zhanga6d9f0e2015-06-13 00:48:38 -07001495
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001496// AFDate_KeystrokeEx(cFormat)
Lei Zhang945fdb72015-11-11 10:18:16 -08001497FX_BOOL CJS_PublicMethods::AFDate_Keystroke(
1498 IJS_Context* cc,
1499 const std::vector<CJS_Value>& params,
1500 CJS_Value& vRet,
1501 CFX_WideString& sError) {
Tom Sepez67fd5df2015-10-08 12:24:19 -07001502 CJS_Context* pContext = (CJS_Context*)cc;
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001503 if (params.size() != 1) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001504 sError = JSGetStringFromID(pContext, IDS_STRING_JSPARAMERROR);
1505 return FALSE;
1506 }
1507
1508 int iIndex = params[0].ToInt();
1509 const FX_WCHAR* cFormats[] = {L"m/d",
1510 L"m/d/yy",
1511 L"mm/dd/yy",
1512 L"mm/yy",
1513 L"d-mmm",
1514 L"d-mmm-yy",
1515 L"dd-mmm-yy",
1516 L"yy-mm-dd",
1517 L"mmm-yy",
1518 L"mmmm-yy",
1519 L"mmm d, yyyy",
1520 L"mmmm d, yyyy",
1521 L"m/d/yy h:MM tt",
1522 L"m/d/yy HH:MM"};
1523
Lei Zhanga0f67242015-08-17 15:39:30 -07001524 if (iIndex < 0 || (static_cast<size_t>(iIndex) >= FX_ArraySize(cFormats)))
1525 iIndex = 0;
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001526
Lei Zhang945fdb72015-11-11 10:18:16 -08001527 std::vector<CJS_Value> newParams;
Tom Sepez67fd5df2015-10-08 12:24:19 -07001528 newParams.push_back(
1529 CJS_Value(CJS_Runtime::FromContext(cc), cFormats[iIndex]));
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001530 return AFDate_KeystrokeEx(cc, newParams, vRet, sError);
1531}
1532
1533// function AFTime_Format(ptf)
Tom Sepezba038bc2015-10-08 12:03:00 -07001534FX_BOOL CJS_PublicMethods::AFTime_Format(IJS_Context* cc,
Lei Zhang945fdb72015-11-11 10:18:16 -08001535 const std::vector<CJS_Value>& params,
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001536 CJS_Value& vRet,
1537 CFX_WideString& sError) {
Tom Sepez67fd5df2015-10-08 12:24:19 -07001538 CJS_Context* pContext = (CJS_Context*)cc;
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001539 if (params.size() != 1) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001540 sError = JSGetStringFromID(pContext, IDS_STRING_JSPARAMERROR);
1541 return FALSE;
1542 }
1543
1544 int iIndex = params[0].ToInt();
1545 const FX_WCHAR* cFormats[] = {L"HH:MM", L"h:MM tt", L"HH:MM:ss",
1546 L"h:MM:ss tt"};
1547
Lei Zhanga0f67242015-08-17 15:39:30 -07001548 if (iIndex < 0 || (static_cast<size_t>(iIndex) >= FX_ArraySize(cFormats)))
1549 iIndex = 0;
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001550
Lei Zhang945fdb72015-11-11 10:18:16 -08001551 std::vector<CJS_Value> newParams;
Tom Sepez67fd5df2015-10-08 12:24:19 -07001552 newParams.push_back(
1553 CJS_Value(CJS_Runtime::FromContext(cc), cFormats[iIndex]));
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001554 return AFDate_FormatEx(cc, newParams, vRet, sError);
1555}
1556
Lei Zhang945fdb72015-11-11 10:18:16 -08001557FX_BOOL CJS_PublicMethods::AFTime_Keystroke(
1558 IJS_Context* cc,
1559 const std::vector<CJS_Value>& params,
1560 CJS_Value& vRet,
1561 CFX_WideString& sError) {
Tom Sepez67fd5df2015-10-08 12:24:19 -07001562 CJS_Context* pContext = (CJS_Context*)cc;
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001563 if (params.size() != 1) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001564 sError = JSGetStringFromID(pContext, IDS_STRING_JSPARAMERROR);
1565 return FALSE;
1566 }
1567
1568 int iIndex = params[0].ToInt();
1569 const FX_WCHAR* cFormats[] = {L"HH:MM", L"h:MM tt", L"HH:MM:ss",
1570 L"h:MM:ss tt"};
1571
Lei Zhanga0f67242015-08-17 15:39:30 -07001572 if (iIndex < 0 || (static_cast<size_t>(iIndex) >= FX_ArraySize(cFormats)))
1573 iIndex = 0;
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001574
Lei Zhang945fdb72015-11-11 10:18:16 -08001575 std::vector<CJS_Value> newParams;
Tom Sepez67fd5df2015-10-08 12:24:19 -07001576 newParams.push_back(
1577 CJS_Value(CJS_Runtime::FromContext(cc), cFormats[iIndex]));
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001578 return AFDate_KeystrokeEx(cc, newParams, vRet, sError);
1579}
1580
Tom Sepezba038bc2015-10-08 12:03:00 -07001581FX_BOOL CJS_PublicMethods::AFTime_FormatEx(IJS_Context* cc,
Lei Zhang945fdb72015-11-11 10:18:16 -08001582 const std::vector<CJS_Value>& params,
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001583 CJS_Value& vRet,
1584 CFX_WideString& sError) {
1585 return AFDate_FormatEx(cc, params, vRet, sError);
1586}
1587
Lei Zhang945fdb72015-11-11 10:18:16 -08001588FX_BOOL CJS_PublicMethods::AFTime_KeystrokeEx(
1589 IJS_Context* cc,
1590 const std::vector<CJS_Value>& params,
1591 CJS_Value& vRet,
1592 CFX_WideString& sError) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001593 return AFDate_KeystrokeEx(cc, params, vRet, sError);
1594}
1595
1596// function AFSpecial_Format(psf)
Lei Zhang945fdb72015-11-11 10:18:16 -08001597FX_BOOL CJS_PublicMethods::AFSpecial_Format(
1598 IJS_Context* cc,
1599 const std::vector<CJS_Value>& params,
1600 CJS_Value& vRet,
1601 CFX_WideString& sError) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001602 CJS_Context* pContext = (CJS_Context*)cc;
1603 ASSERT(pContext != NULL);
1604
1605 if (params.size() != 1) {
1606 sError = JSGetStringFromID(pContext, IDS_STRING_JSPARAMERROR);
1607 return FALSE;
1608 }
1609
1610 std::string cFormat;
1611 int iIndex = params[0].ToInt();
1612
1613 CJS_EventHandler* pEvent = pContext->GetEventHandler();
1614 ASSERT(pEvent != NULL);
1615
1616 if (!pEvent->m_pValue)
1617 return FALSE;
1618 CFX_WideString& Value = pEvent->Value();
1619 std::string strSrc = CFX_ByteString::FromUnicode(Value).c_str();
1620
1621 switch (iIndex) {
Tom Sepez2f2ffec2015-07-23 14:42:09 -07001622 case 0:
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001623 cFormat = "99999";
1624 break;
Tom Sepez2f2ffec2015-07-23 14:42:09 -07001625 case 1:
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001626 cFormat = "99999-9999";
1627 break;
1628 case 2: {
1629 std::string NumberStr;
1630 util::printx("9999999999", strSrc, NumberStr);
1631 if (NumberStr.length() >= 10)
1632 cFormat = "(999) 999-9999";
1633 else
1634 cFormat = "999-9999";
1635 break;
1636 }
Tom Sepez2f2ffec2015-07-23 14:42:09 -07001637 case 3:
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001638 cFormat = "999-99-9999";
1639 break;
1640 }
1641
1642 std::string strDes;
1643 util::printx(cFormat, strSrc, strDes);
1644 Value = CFX_WideString::FromLocal(strDes.c_str());
1645 return TRUE;
1646}
1647
1648// function AFSpecial_KeystrokeEx(mask)
Lei Zhang945fdb72015-11-11 10:18:16 -08001649FX_BOOL CJS_PublicMethods::AFSpecial_KeystrokeEx(
1650 IJS_Context* cc,
1651 const std::vector<CJS_Value>& params,
1652 CJS_Value& vRet,
1653 CFX_WideString& sError) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001654 CJS_Context* pContext = (CJS_Context*)cc;
1655 ASSERT(pContext != NULL);
1656 CJS_EventHandler* pEvent = pContext->GetEventHandler();
1657
1658 ASSERT(pEvent != NULL);
1659
1660 if (params.size() < 1) {
1661 sError = JSGetStringFromID(pContext, IDS_STRING_JSPARAMERROR);
1662 return FALSE;
1663 }
1664
1665 if (!pEvent->m_pValue)
1666 return FALSE;
1667 CFX_WideString& valEvent = pEvent->Value();
1668
1669 CFX_WideString wstrMask = params[0].ToCFXWideString();
1670 if (wstrMask.IsEmpty())
1671 return TRUE;
1672
Lei Zhanga0f67242015-08-17 15:39:30 -07001673 const size_t wstrMaskLen = wstrMask.GetLength();
1674 const std::wstring wstrValue = valEvent.c_str();
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001675
1676 if (pEvent->WillCommit()) {
1677 if (wstrValue.empty())
1678 return TRUE;
Lei Zhanga0f67242015-08-17 15:39:30 -07001679 size_t iIndexMask = 0;
1680 for (const auto& w_Value : wstrValue) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001681 if (!maskSatisfied(w_Value, wstrMask[iIndexMask]))
Tom Sepez2f2ffec2015-07-23 14:42:09 -07001682 break;
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001683 iIndexMask++;
Tom Sepez2f2ffec2015-07-23 14:42:09 -07001684 }
Lei Zhanga6d9f0e2015-06-13 00:48:38 -07001685
Lei Zhanga0f67242015-08-17 15:39:30 -07001686 if (iIndexMask != wstrMaskLen ||
1687 (iIndexMask != wstrValue.size() && wstrMaskLen != 0)) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001688 Alert(
1689 pContext,
1690 JSGetStringFromID(pContext, IDS_STRING_JSAFNUMBER_KEYSTROKE).c_str());
1691 pEvent->Rc() = FALSE;
1692 }
Tom Sepez2f2ffec2015-07-23 14:42:09 -07001693 return TRUE;
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001694 }
1695
1696 CFX_WideString& wideChange = pEvent->Change();
1697 std::wstring wChange = wideChange.c_str();
1698 if (wChange.empty())
1699 return TRUE;
1700
1701 int iIndexMask = pEvent->SelStart();
1702
Lei Zhanga0f67242015-08-17 15:39:30 -07001703 size_t combined_len = wstrValue.length() + wChange.length() -
1704 (pEvent->SelEnd() - pEvent->SelStart());
1705 if (combined_len > wstrMaskLen) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001706 Alert(pContext,
1707 JSGetStringFromID(pContext, IDS_STRING_JSPARAM_TOOLONG).c_str());
1708 pEvent->Rc() = FALSE;
1709 return TRUE;
1710 }
1711
Lei Zhanga0f67242015-08-17 15:39:30 -07001712 if (iIndexMask >= wstrMaskLen && (!wChange.empty())) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001713 Alert(pContext,
1714 JSGetStringFromID(pContext, IDS_STRING_JSPARAM_TOOLONG).c_str());
1715 pEvent->Rc() = FALSE;
1716 return TRUE;
1717 }
1718
1719 for (std::wstring::iterator it = wChange.begin(); it != wChange.end(); it++) {
Lei Zhanga0f67242015-08-17 15:39:30 -07001720 if (iIndexMask >= wstrMaskLen) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001721 Alert(pContext,
1722 JSGetStringFromID(pContext, IDS_STRING_JSPARAM_TOOLONG).c_str());
1723 pEvent->Rc() = FALSE;
1724 return TRUE;
1725 }
1726 wchar_t w_Mask = wstrMask[iIndexMask];
1727 if (!isReservedMaskChar(w_Mask)) {
1728 *it = w_Mask;
1729 }
1730 wchar_t w_Change = *it;
1731 if (!maskSatisfied(w_Change, w_Mask)) {
1732 pEvent->Rc() = FALSE;
1733 return TRUE;
1734 }
1735 iIndexMask++;
1736 }
1737
1738 wideChange = wChange.c_str();
1739 return TRUE;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07001740}
1741
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001742// function AFSpecial_Keystroke(psf)
Lei Zhang945fdb72015-11-11 10:18:16 -08001743FX_BOOL CJS_PublicMethods::AFSpecial_Keystroke(
1744 IJS_Context* cc,
1745 const std::vector<CJS_Value>& params,
1746 CJS_Value& vRet,
1747 CFX_WideString& sError) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001748 CJS_Context* pContext = (CJS_Context*)cc;
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001749 if (params.size() != 1) {
1750 sError = JSGetStringFromID(pContext, IDS_STRING_JSPARAMERROR);
1751 return FALSE;
1752 }
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07001753
Tom Sepez67fd5df2015-10-08 12:24:19 -07001754 CJS_EventHandler* pEvent = pContext->GetEventHandler();
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001755 if (!pEvent->m_pValue)
1756 return FALSE;
Tom Sepez67fd5df2015-10-08 12:24:19 -07001757
1758 std::string cFormat;
1759 int iIndex = params[0].ToInt();
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001760 CFX_WideString& val = pEvent->Value();
1761 std::string strSrc = CFX_ByteString::FromUnicode(val).c_str();
1762 std::wstring wstrChange = pEvent->Change().c_str();
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07001763
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001764 switch (iIndex) {
Tom Sepez2f2ffec2015-07-23 14:42:09 -07001765 case 0:
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001766 cFormat = "99999";
1767 break;
Tom Sepez2f2ffec2015-07-23 14:42:09 -07001768 case 1:
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001769 // cFormat = "99999-9999";
1770 cFormat = "999999999";
1771 break;
1772 case 2: {
1773 std::string NumberStr;
1774 util::printx("9999999999", strSrc, NumberStr);
1775 if (strSrc.length() + wstrChange.length() > 7)
1776 // cFormat = "(999) 999-9999";
1777 cFormat = "9999999999";
1778 else
1779 // cFormat = "999-9999";
1780 cFormat = "9999999";
1781 break;
1782 }
Tom Sepez2f2ffec2015-07-23 14:42:09 -07001783 case 3:
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001784 // cFormat = "999-99-9999";
1785 cFormat = "999999999";
1786 break;
1787 }
Lei Zhanga6d9f0e2015-06-13 00:48:38 -07001788
Lei Zhang945fdb72015-11-11 10:18:16 -08001789 std::vector<CJS_Value> params2;
Tom Sepez67fd5df2015-10-08 12:24:19 -07001790 params2.push_back(CJS_Value(CJS_Runtime::FromContext(cc), cFormat.c_str()));
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001791 return AFSpecial_KeystrokeEx(cc, params2, vRet, sError);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07001792}
1793
Tom Sepezba038bc2015-10-08 12:03:00 -07001794FX_BOOL CJS_PublicMethods::AFMergeChange(IJS_Context* cc,
Lei Zhang945fdb72015-11-11 10:18:16 -08001795 const std::vector<CJS_Value>& params,
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001796 CJS_Value& vRet,
1797 CFX_WideString& sError) {
1798 CJS_Context* pContext = (CJS_Context*)cc;
1799 ASSERT(pContext != NULL);
1800 CJS_EventHandler* pEventHandler = pContext->GetEventHandler();
1801 ASSERT(pEventHandler != NULL);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07001802
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001803 if (params.size() != 1) {
1804 sError = JSGetStringFromID(pContext, IDS_STRING_JSPARAMERROR);
1805 return FALSE;
1806 }
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07001807
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001808 CFX_WideString swValue;
Lei Zhang997de612015-11-04 18:17:53 -08001809 if (pEventHandler->m_pValue)
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001810 swValue = pEventHandler->Value();
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07001811
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001812 if (pEventHandler->WillCommit()) {
1813 vRet = swValue.c_str();
Tom Sepez2f2ffec2015-07-23 14:42:09 -07001814 return TRUE;
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001815 }
1816
1817 CFX_WideString prefix, postfix;
1818
1819 if (pEventHandler->SelStart() >= 0)
1820 prefix = swValue.Mid(0, pEventHandler->SelStart());
1821 else
1822 prefix = L"";
1823
1824 if (pEventHandler->SelEnd() >= 0 &&
1825 pEventHandler->SelEnd() <= swValue.GetLength())
1826 postfix = swValue.Mid(pEventHandler->SelEnd(),
1827 swValue.GetLength() - pEventHandler->SelEnd());
1828 else
1829 postfix = L"";
1830
1831 vRet = (prefix + pEventHandler->Change() + postfix).c_str();
1832
1833 return TRUE;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07001834}
1835
Tom Sepezba038bc2015-10-08 12:03:00 -07001836FX_BOOL CJS_PublicMethods::AFParseDateEx(IJS_Context* cc,
Lei Zhang945fdb72015-11-11 10:18:16 -08001837 const std::vector<CJS_Value>& params,
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001838 CJS_Value& vRet,
1839 CFX_WideString& sError) {
1840 CJS_Context* pContext = (CJS_Context*)cc;
1841 ASSERT(pContext != NULL);
1842
1843 if (params.size() != 2) {
1844 sError = JSGetStringFromID(pContext, IDS_STRING_JSPARAMERROR);
1845 return FALSE;
1846 }
1847
1848 CFX_WideString sValue = params[0].ToCFXWideString();
1849 CFX_WideString sFormat = params[1].ToCFXWideString();
1850
1851 FX_BOOL bWrongFormat = FALSE;
1852 double dDate = MakeRegularDate(sValue, sFormat, bWrongFormat);
1853
1854 if (JS_PortIsNan(dDate)) {
1855 CFX_WideString swMsg;
1856 swMsg.Format(JSGetStringFromID(pContext, IDS_STRING_JSPARSEDATE).c_str(),
1857 sFormat.c_str());
1858 Alert((CJS_Context*)cc, swMsg.c_str());
1859 return FALSE;
1860 }
1861
1862 vRet = dDate;
1863 return TRUE;
1864}
1865
Tom Sepezba038bc2015-10-08 12:03:00 -07001866FX_BOOL CJS_PublicMethods::AFSimple(IJS_Context* cc,
Lei Zhang945fdb72015-11-11 10:18:16 -08001867 const std::vector<CJS_Value>& params,
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001868 CJS_Value& vRet,
1869 CFX_WideString& sError) {
1870 if (params.size() != 3) {
1871 CJS_Context* pContext = (CJS_Context*)cc;
Tom Sepez2f2ffec2015-07-23 14:42:09 -07001872 ASSERT(pContext != NULL);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07001873
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001874 sError = JSGetStringFromID(pContext, IDS_STRING_JSPARAMERROR);
1875 return FALSE;
1876 }
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07001877
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001878 vRet = (double)AF_Simple(params[0].ToCFXWideString().c_str(),
1879 params[1].ToDouble(), params[2].ToDouble());
1880 return TRUE;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07001881}
1882
Tom Sepezba038bc2015-10-08 12:03:00 -07001883FX_BOOL CJS_PublicMethods::AFMakeNumber(IJS_Context* cc,
Lei Zhang945fdb72015-11-11 10:18:16 -08001884 const std::vector<CJS_Value>& params,
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001885 CJS_Value& vRet,
1886 CFX_WideString& sError) {
1887 if (params.size() != 1) {
1888 CJS_Context* pContext = (CJS_Context*)cc;
Tom Sepez2f2ffec2015-07-23 14:42:09 -07001889 ASSERT(pContext != NULL);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07001890
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001891 sError = JSGetStringFromID(pContext, IDS_STRING_JSPARAMERROR);
1892 return FALSE;
1893 }
1894 vRet = ParseStringToNumber(params[0].ToCFXWideString().c_str());
1895 return TRUE;
1896}
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07001897
Lei Zhang945fdb72015-11-11 10:18:16 -08001898FX_BOOL CJS_PublicMethods::AFSimple_Calculate(
1899 IJS_Context* cc,
1900 const std::vector<CJS_Value>& params,
1901 CJS_Value& vRet,
1902 CFX_WideString& sError) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001903 CJS_Context* pContext = (CJS_Context*)cc;
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001904 if (params.size() != 2) {
1905 sError = JSGetStringFromID(pContext, IDS_STRING_JSPARAMERROR);
1906 return FALSE;
1907 }
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07001908
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001909 CJS_Value params1 = params[1];
Tom Sepez39bfe122015-09-17 15:25:23 -07001910 if (!params1.IsArrayObject() && params1.GetType() != CJS_Value::VT_string) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001911 sError = JSGetStringFromID(pContext, IDS_STRING_JSPARAMERROR);
1912 return FALSE;
1913 }
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07001914
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001915 CPDFSDK_Document* pReaderDoc = pContext->GetReaderDocument();
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001916 CPDFSDK_InterForm* pReaderInterForm = pReaderDoc->GetInterForm();
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001917 CPDF_InterForm* pInterForm = pReaderInterForm->GetInterForm();
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07001918
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001919 CFX_WideString sFunction = params[0].ToCFXWideString();
Tom Sepez67fd5df2015-10-08 12:24:19 -07001920 double dValue = wcscmp(sFunction.c_str(), L"PRD") == 0 ? 1.0 : 0.0;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07001921
Tom Sepez67fd5df2015-10-08 12:24:19 -07001922 CJS_Runtime* pRuntime = CJS_Runtime::FromContext(cc);
1923 CJS_Array FieldNameArray = AF_MakeArrayFromList(pRuntime, params1);
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001924 int nFieldsCount = 0;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07001925
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001926 for (int i = 0, isz = FieldNameArray.GetLength(); i < isz; i++) {
Tom Sepez67fd5df2015-10-08 12:24:19 -07001927 CJS_Value jsValue(pRuntime);
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001928 FieldNameArray.GetElement(i, jsValue);
1929 CFX_WideString wsFieldName = jsValue.ToCFXWideString();
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07001930
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001931 for (int j = 0, jsz = pInterForm->CountFields(wsFieldName); j < jsz; j++) {
1932 if (CPDF_FormField* pFormField = pInterForm->GetField(j, wsFieldName)) {
1933 double dTemp = 0.0;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07001934
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001935 switch (pFormField->GetFieldType()) {
1936 case FIELDTYPE_TEXTFIELD:
1937 case FIELDTYPE_COMBOBOX: {
1938 dTemp = ParseStringToNumber(pFormField->GetValue().c_str());
1939 break;
1940 }
1941 case FIELDTYPE_PUSHBUTTON: {
1942 dTemp = 0.0;
1943 break;
1944 }
1945 case FIELDTYPE_CHECKBOX:
1946 case FIELDTYPE_RADIOBUTTON: {
1947 dTemp = 0.0;
1948 for (int c = 0, csz = pFormField->CountControls(); c < csz; c++) {
1949 if (CPDF_FormControl* pFormCtrl = pFormField->GetControl(c)) {
1950 if (pFormCtrl->IsChecked()) {
1951 dTemp +=
1952 ParseStringToNumber(pFormCtrl->GetExportValue().c_str());
1953 break;
1954 } else
1955 continue;
1956 }
Tom Sepez2f2ffec2015-07-23 14:42:09 -07001957 }
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001958 break;
1959 }
1960 case FIELDTYPE_LISTBOX: {
1961 dTemp = 0.0;
1962 if (pFormField->CountSelectedItems() > 1)
1963 break;
1964 else {
1965 dTemp = ParseStringToNumber(pFormField->GetValue().c_str());
1966 break;
1967 }
1968 }
1969 default:
1970 break;
Tom Sepez2f2ffec2015-07-23 14:42:09 -07001971 }
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001972
1973 if (i == 0 && j == 0 && (wcscmp(sFunction.c_str(), L"MIN") == 0 ||
1974 wcscmp(sFunction.c_str(), L"MAX") == 0))
1975 dValue = dTemp;
1976
1977 dValue = AF_Simple(sFunction.c_str(), dValue, dTemp);
1978
1979 nFieldsCount++;
1980 }
Tom Sepez2f2ffec2015-07-23 14:42:09 -07001981 }
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001982 }
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07001983
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001984 if (wcscmp(sFunction.c_str(), L"AVG") == 0 && nFieldsCount > 0)
1985 dValue /= nFieldsCount;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07001986
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001987 dValue = (double)floor(dValue * FXSYS_pow((double)10, (double)6) + 0.49) /
1988 FXSYS_pow((double)10, (double)6);
Tom Sepez67fd5df2015-10-08 12:24:19 -07001989 CJS_Value jsValue(pRuntime, dValue);
foxit8b544ed2015-09-10 14:57:54 +08001990 if (pContext->GetEventHandler()->m_pValue)
1991 pContext->GetEventHandler()->Value() = jsValue.ToCFXWideString();
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07001992
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001993 return TRUE;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07001994}
1995
Lei Zhanga6d9f0e2015-06-13 00:48:38 -07001996/* This function validates the current event to ensure that its value is
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07001997** within the specified range. */
1998
Lei Zhang945fdb72015-11-11 10:18:16 -08001999FX_BOOL CJS_PublicMethods::AFRange_Validate(
2000 IJS_Context* cc,
2001 const std::vector<CJS_Value>& params,
2002 CJS_Value& vRet,
2003 CFX_WideString& sError) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -07002004 CJS_Context* pContext = (CJS_Context*)cc;
2005 ASSERT(pContext != NULL);
2006 CJS_EventHandler* pEvent = pContext->GetEventHandler();
2007 ASSERT(pEvent != NULL);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07002008
Nico Weber9d8ec5a2015-08-04 13:00:21 -07002009 if (params.size() != 4) {
2010 sError = JSGetStringFromID(pContext, IDS_STRING_JSPARAMERROR);
2011 return FALSE;
2012 }
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07002013
Nico Weber9d8ec5a2015-08-04 13:00:21 -07002014 if (!pEvent->m_pValue)
2015 return FALSE;
2016 if (pEvent->Value().IsEmpty())
Tom Sepez2f2ffec2015-07-23 14:42:09 -07002017 return TRUE;
Nico Weber9d8ec5a2015-08-04 13:00:21 -07002018 double dEentValue = atof(CFX_ByteString::FromUnicode(pEvent->Value()));
2019 FX_BOOL bGreaterThan = params[0].ToBool();
2020 double dGreaterThan = params[1].ToDouble();
2021 FX_BOOL bLessThan = params[2].ToBool();
2022 double dLessThan = params[3].ToDouble();
2023 CFX_WideString swMsg;
2024
2025 if (bGreaterThan && bLessThan) {
2026 if (dEentValue < dGreaterThan || dEentValue > dLessThan)
2027 swMsg.Format(JSGetStringFromID(pContext, IDS_STRING_JSRANGE1).c_str(),
2028 params[1].ToCFXWideString().c_str(),
2029 params[3].ToCFXWideString().c_str());
2030 } else if (bGreaterThan) {
2031 if (dEentValue < dGreaterThan)
2032 swMsg.Format(JSGetStringFromID(pContext, IDS_STRING_JSRANGE2).c_str(),
2033 params[1].ToCFXWideString().c_str());
2034 } else if (bLessThan) {
2035 if (dEentValue > dLessThan)
2036 swMsg.Format(JSGetStringFromID(pContext, IDS_STRING_JSRANGE3).c_str(),
2037 params[3].ToCFXWideString().c_str());
2038 }
2039
2040 if (!swMsg.IsEmpty()) {
2041 Alert(pContext, swMsg.c_str());
2042 pEvent->Rc() = FALSE;
2043 }
2044 return TRUE;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07002045}
2046
Tom Sepezba038bc2015-10-08 12:03:00 -07002047FX_BOOL CJS_PublicMethods::AFExtractNums(IJS_Context* cc,
Lei Zhang945fdb72015-11-11 10:18:16 -08002048 const std::vector<CJS_Value>& params,
Nico Weber9d8ec5a2015-08-04 13:00:21 -07002049 CJS_Value& vRet,
2050 CFX_WideString& sError) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -07002051 CJS_Context* pContext = (CJS_Context*)cc;
Nico Weber9d8ec5a2015-08-04 13:00:21 -07002052 if (params.size() != 1) {
2053 sError = JSGetStringFromID(pContext, IDS_STRING_JSPARAMERROR);
2054 return FALSE;
2055 }
2056
Tom Sepez67fd5df2015-10-08 12:24:19 -07002057 CJS_Runtime* pRuntime = CJS_Runtime::FromContext(cc);
2058 CJS_Array nums(pRuntime);
Nico Weber9d8ec5a2015-08-04 13:00:21 -07002059
2060 CFX_WideString str = params[0].ToCFXWideString();
2061 CFX_WideString sPart;
2062
2063 if (str.GetAt(0) == L'.' || str.GetAt(0) == L',')
2064 str = L"0" + str;
2065
2066 int nIndex = 0;
2067 for (int i = 0, sz = str.GetLength(); i < sz; i++) {
2068 FX_WCHAR wc = str.GetAt(i);
2069 if (IsDigit((wchar_t)wc)) {
2070 sPart += wc;
2071 } else {
2072 if (sPart.GetLength() > 0) {
Tom Sepez67fd5df2015-10-08 12:24:19 -07002073 nums.SetElement(nIndex, CJS_Value(pRuntime, sPart.c_str()));
Nico Weber9d8ec5a2015-08-04 13:00:21 -07002074 sPart = L"";
2075 nIndex++;
2076 }
Tom Sepez2f2ffec2015-07-23 14:42:09 -07002077 }
Nico Weber9d8ec5a2015-08-04 13:00:21 -07002078 }
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07002079
Nico Weber9d8ec5a2015-08-04 13:00:21 -07002080 if (sPart.GetLength() > 0) {
Tom Sepez67fd5df2015-10-08 12:24:19 -07002081 nums.SetElement(nIndex, CJS_Value(pRuntime, sPart.c_str()));
Nico Weber9d8ec5a2015-08-04 13:00:21 -07002082 }
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07002083
Nico Weber9d8ec5a2015-08-04 13:00:21 -07002084 if (nums.GetLength() > 0)
2085 vRet = nums;
2086 else
2087 vRet.SetNull();
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07002088
Nico Weber9d8ec5a2015-08-04 13:00:21 -07002089 return TRUE;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07002090}