blob: 75327dd631bd2c9223c4de7662d5b0580cd9ba89 [file] [log] [blame]
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07001// Copyright 2014 PDFium Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
Lei Zhanga6d9f0e2015-06-13 00:48:38 -07004
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07005// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
6
Tom Sepez37458412015-10-06 11:33:46 -07007#include "PublicMethods.h"
8
Tom Sepez37458412015-10-06 11:33:46 -07009#include "Field.h"
10#include "JS_Context.h"
11#include "JS_Define.h"
12#include "JS_EventHandler.h"
13#include "JS_Object.h"
14#include "JS_Runtime.h"
15#include "JS_Value.h"
16#include "color.h"
Dan Sinclair10cfea12015-11-16 13:09:00 -050017#include "core/include/fxcrt/fx_ext.h"
Lei Zhangbde53d22015-11-12 22:21:30 -080018#include "fpdfsdk/include/fsdk_mgr.h" // For CPDFDoc_Environment.
19#include "fpdfsdk/include/javascript/IJavaScript.h"
Tom Sepez37458412015-10-06 11:33:46 -070020#include "resource.h"
21#include "util.h"
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -070022
Nico Weber9d8ec5a2015-08-04 13:00:21 -070023#define DOUBLE_CORRECT 0.000000000000001
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -070024
25BEGIN_JS_STATIC_GLOBAL_FUN(CJS_PublicMethods)
Nico Weber9d8ec5a2015-08-04 13:00:21 -070026JS_STATIC_GLOBAL_FUN_ENTRY(AFNumber_Format)
27JS_STATIC_GLOBAL_FUN_ENTRY(AFNumber_Keystroke)
28JS_STATIC_GLOBAL_FUN_ENTRY(AFPercent_Format)
29JS_STATIC_GLOBAL_FUN_ENTRY(AFPercent_Keystroke)
30JS_STATIC_GLOBAL_FUN_ENTRY(AFDate_FormatEx)
31JS_STATIC_GLOBAL_FUN_ENTRY(AFDate_KeystrokeEx)
32JS_STATIC_GLOBAL_FUN_ENTRY(AFDate_Format)
33JS_STATIC_GLOBAL_FUN_ENTRY(AFDate_Keystroke)
34JS_STATIC_GLOBAL_FUN_ENTRY(AFTime_FormatEx)
35JS_STATIC_GLOBAL_FUN_ENTRY(AFTime_KeystrokeEx)
36JS_STATIC_GLOBAL_FUN_ENTRY(AFTime_Format)
37JS_STATIC_GLOBAL_FUN_ENTRY(AFTime_Keystroke)
38JS_STATIC_GLOBAL_FUN_ENTRY(AFSpecial_Format)
39JS_STATIC_GLOBAL_FUN_ENTRY(AFSpecial_Keystroke)
40JS_STATIC_GLOBAL_FUN_ENTRY(AFSpecial_KeystrokeEx)
41JS_STATIC_GLOBAL_FUN_ENTRY(AFSimple)
42JS_STATIC_GLOBAL_FUN_ENTRY(AFMakeNumber)
43JS_STATIC_GLOBAL_FUN_ENTRY(AFSimple_Calculate)
44JS_STATIC_GLOBAL_FUN_ENTRY(AFRange_Validate)
45JS_STATIC_GLOBAL_FUN_ENTRY(AFMergeChange)
46JS_STATIC_GLOBAL_FUN_ENTRY(AFParseDateEx)
47JS_STATIC_GLOBAL_FUN_ENTRY(AFExtractNums)
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -070048END_JS_STATIC_GLOBAL_FUN()
49
50IMPLEMENT_JS_STATIC_GLOBAL_FUN(CJS_PublicMethods)
51
Tom Sepezdfbf8e72015-10-14 14:17:26 -070052static const FX_WCHAR* const months[] = {L"Jan",
53 L"Feb",
54 L"Mar",
55 L"Apr",
56 L"May",
57 L"Jun",
58 L"Jul",
59 L"Aug",
60 L"Sep",
61 L"Oct",
62 L"Nov",
63 L"Dec"};
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -070064
Nico Weber9d8ec5a2015-08-04 13:00:21 -070065static const FX_WCHAR* const fullmonths[] = {
66 L"January", L"February", L"March", L"April",
67 L"May", L"June", L"July", L"August",
68 L"September", L"October", L"November", L"December"};
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -070069
Nico Weber9d8ec5a2015-08-04 13:00:21 -070070FX_BOOL CJS_PublicMethods::IsNumber(const FX_WCHAR* string) {
71 CFX_WideString sTrim = StrTrim(string);
72 const FX_WCHAR* pTrim = sTrim.c_str();
73 const FX_WCHAR* p = pTrim;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -070074
Nico Weber9d8ec5a2015-08-04 13:00:21 -070075 FX_BOOL bDot = FALSE;
76 FX_BOOL bKXJS = FALSE;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -070077
Nico Weber9d8ec5a2015-08-04 13:00:21 -070078 wchar_t c;
79 while ((c = *p)) {
80 if (c == '.' || c == ',') {
81 if (bDot)
82 return FALSE;
83 bDot = TRUE;
84 } else if (c == '-' || c == '+') {
85 if (p != pTrim)
86 return FALSE;
87 } else if (c == 'e' || c == 'E') {
88 if (bKXJS)
89 return FALSE;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -070090
Nico Weber9d8ec5a2015-08-04 13:00:21 -070091 p++;
92 c = *p;
93 if (c == '+' || c == '-') {
94 bKXJS = TRUE;
95 } else {
96 return FALSE;
97 }
98 } else if (!IsDigit(c)) {
99 return FALSE;
100 }
101 p++;
102 }
103
104 return TRUE;
105}
106
107FX_BOOL CJS_PublicMethods::IsDigit(wchar_t ch) {
108 return (ch >= L'0' && ch <= L'9');
109}
110
111FX_BOOL CJS_PublicMethods::IsDigit(char ch) {
Dan Sinclair10cfea12015-11-16 13:09:00 -0500112 return std::isdigit(ch);
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700113}
114
115FX_BOOL CJS_PublicMethods::IsAlphabetic(wchar_t ch) {
116 return ((ch >= L'a' && ch <= L'z') || (ch >= L'A' && ch <= L'Z'));
117}
118
119FX_BOOL CJS_PublicMethods::IsAlphaNumeric(wchar_t ch) {
120 return (IsDigit(ch) || IsAlphabetic(ch));
121}
122
123FX_BOOL CJS_PublicMethods::maskSatisfied(wchar_t c_Change, wchar_t c_Mask) {
124 switch (c_Mask) {
125 case L'9':
126 return IsDigit(c_Change);
127 case L'A':
128 return IsAlphabetic(c_Change);
129 case L'O':
130 return IsAlphaNumeric(c_Change);
131 case L'X':
132 return TRUE;
133 default:
134 return (c_Change == c_Mask);
135 }
136}
137
138FX_BOOL CJS_PublicMethods::isReservedMaskChar(wchar_t ch) {
139 return ch == L'9' || ch == L'A' || ch == L'O' || ch == L'X';
140}
141
142double CJS_PublicMethods::AF_Simple(const FX_WCHAR* sFuction,
143 double dValue1,
144 double dValue2) {
145 if (FXSYS_wcsicmp(sFuction, L"AVG") == 0 ||
146 FXSYS_wcsicmp(sFuction, L"SUM") == 0) {
147 return dValue1 + dValue2;
148 }
149 if (FXSYS_wcsicmp(sFuction, L"PRD") == 0) {
150 return dValue1 * dValue2;
151 }
152 if (FXSYS_wcsicmp(sFuction, L"MIN") == 0) {
153 return FX_MIN(dValue1, dValue2);
154 }
155 if (FXSYS_wcsicmp(sFuction, L"MAX") == 0) {
156 return FX_MAX(dValue1, dValue2);
157 }
158 return dValue1;
159}
160
161CFX_WideString CJS_PublicMethods::StrLTrim(const FX_WCHAR* pStr) {
162 while (*pStr && *pStr == L' ')
163 pStr++;
164
165 return pStr;
166}
167
168CFX_WideString CJS_PublicMethods::StrRTrim(const FX_WCHAR* pStr) {
169 const FX_WCHAR* p = pStr;
170 while (*p)
171 p++;
172 while (p > pStr && *(p - 1) == L' ')
173 p--;
174
175 return CFX_WideString(pStr, p - pStr);
176}
177
178CFX_WideString CJS_PublicMethods::StrTrim(const FX_WCHAR* pStr) {
179 return StrRTrim(StrLTrim(pStr).c_str());
180}
181
182CFX_ByteString CJS_PublicMethods::StrLTrim(const FX_CHAR* pStr) {
183 while (*pStr && *pStr == ' ')
184 pStr++;
185
186 return pStr;
187}
188
189CFX_ByteString CJS_PublicMethods::StrRTrim(const FX_CHAR* pStr) {
190 const FX_CHAR* p = pStr;
191 while (*p)
192 p++;
193 while (p > pStr && *(p - 1) == L' ')
194 p--;
195
196 return CFX_ByteString(pStr, p - pStr);
197}
198
199CFX_ByteString CJS_PublicMethods::StrTrim(const FX_CHAR* pStr) {
200 return StrRTrim(StrLTrim(pStr));
201}
202
203double CJS_PublicMethods::ParseNumber(const FX_WCHAR* swSource,
204 FX_BOOL& bAllDigits,
205 FX_BOOL& bDot,
206 FX_BOOL& bSign,
207 FX_BOOL& bKXJS) {
208 bDot = FALSE;
209 bSign = FALSE;
210 bKXJS = FALSE;
211
212 FX_BOOL bDigitExist = FALSE;
213
214 const FX_WCHAR* p = swSource;
215 wchar_t c;
216
217 const FX_WCHAR* pStart = NULL;
218 const FX_WCHAR* pEnd = NULL;
219
220 while ((c = *p)) {
221 if (!pStart && c != L' ') {
222 pStart = p;
223 }
224
225 pEnd = p;
226 p++;
227 }
228
229 if (!pStart) {
230 bAllDigits = FALSE;
231 return 0;
232 }
233
234 while (pEnd != pStart) {
235 if (*pEnd == L' ')
236 pEnd--;
237 else
238 break;
239 }
240
241 double dRet = 0;
242 p = pStart;
243 bAllDigits = TRUE;
244 CFX_WideString swDigits;
245
246 while (p <= pEnd) {
247 c = *p;
248
249 if (IsDigit(c)) {
250 swDigits += c;
251 bDigitExist = TRUE;
252 } else {
253 switch (c) {
254 case L' ':
255 bAllDigits = FALSE;
256 break;
257 case L'.':
258 case L',':
259 if (!bDot) {
260 if (bDigitExist) {
261 swDigits += L'.';
262 } else {
263 swDigits += L'0';
264 swDigits += L'.';
265 bDigitExist = TRUE;
266 }
267
Tom Sepez2f2ffec2015-07-23 14:42:09 -0700268 bDot = TRUE;
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700269 break;
270 }
271 case 'e':
272 case 'E':
273 if (!bKXJS) {
Tom Sepez2f2ffec2015-07-23 14:42:09 -0700274 p++;
275 c = *p;
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700276 if (c == '+' || c == '-') {
277 bKXJS = TRUE;
278 swDigits += 'e';
279 swDigits += c;
Tom Sepez2f2ffec2015-07-23 14:42:09 -0700280 }
Tom Sepez2f2ffec2015-07-23 14:42:09 -0700281 break;
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700282 }
283 case L'-':
284 if (!bDigitExist && !bSign) {
Tom Sepez2f2ffec2015-07-23 14:42:09 -0700285 swDigits += c;
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700286 bSign = TRUE;
Tom Sepez2f2ffec2015-07-23 14:42:09 -0700287 break;
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700288 }
289 default:
290 bAllDigits = FALSE;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700291
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700292 if (p != pStart && !bDot && bDigitExist) {
293 swDigits += L'.';
294 bDot = TRUE;
295 } else {
296 bDot = FALSE;
297 bDigitExist = FALSE;
298 swDigits = L"";
299 }
300 break;
301 }
Tom Sepez2f2ffec2015-07-23 14:42:09 -0700302 }
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700303
304 p++;
305 }
306
307 if (swDigits.GetLength() > 0 && swDigits.GetLength() < 17) {
308 CFX_ByteString sDigits = swDigits.UTF8Encode();
309
310 if (bKXJS) {
311 dRet = atof(sDigits);
312 } else {
313 if (bDot) {
314 char* pStopString;
315 dRet = ::strtod(sDigits, &pStopString);
316 } else {
317 dRet = atol(sDigits);
318 }
319 }
320 }
321
322 return dRet;
323}
324
325double CJS_PublicMethods::ParseStringToNumber(const FX_WCHAR* swSource) {
326 FX_BOOL bAllDigits = FALSE;
327 FX_BOOL bDot = FALSE;
328 FX_BOOL bSign = FALSE;
329 FX_BOOL bKXJS = FALSE;
330
331 return ParseNumber(swSource, bAllDigits, bDot, bSign, bKXJS);
332}
333
334FX_BOOL CJS_PublicMethods::ConvertStringToNumber(const FX_WCHAR* swSource,
335 double& dRet,
336 FX_BOOL& bDot) {
337 FX_BOOL bAllDigits = FALSE;
338 FX_BOOL bSign = FALSE;
339 FX_BOOL bKXJS = FALSE;
340
341 dRet = ParseNumber(swSource, bAllDigits, bDot, bSign, bKXJS);
342
343 return bAllDigits;
344}
345
Tom Sepez67fd5df2015-10-08 12:24:19 -0700346CJS_Array CJS_PublicMethods::AF_MakeArrayFromList(CJS_Runtime* pRuntime,
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700347 CJS_Value val) {
Tom Sepez67fd5df2015-10-08 12:24:19 -0700348 CJS_Array StrArray(pRuntime);
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700349 if (val.IsArrayObject()) {
350 val.ConvertToArray(StrArray);
Tom Sepez2f2ffec2015-07-23 14:42:09 -0700351 return StrArray;
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700352 }
353 CFX_WideString wsStr = val.ToCFXWideString();
354 CFX_ByteString t = CFX_ByteString::FromUnicode(wsStr);
355 const char* p = (const char*)t;
356
357 int ch = ',';
358 int nIndex = 0;
359
360 while (*p) {
361 const char* pTemp = strchr(p, ch);
Lei Zhang997de612015-11-04 18:17:53 -0800362 if (!pTemp) {
Tom Sepez67fd5df2015-10-08 12:24:19 -0700363 StrArray.SetElement(nIndex, CJS_Value(pRuntime, StrTrim(p).c_str()));
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700364 break;
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700365 }
Lei Zhang997de612015-11-04 18:17:53 -0800366
367 char* pSub = new char[pTemp - p + 1];
368 strncpy(pSub, p, pTemp - p);
369 *(pSub + (pTemp - p)) = '\0';
370
371 StrArray.SetElement(nIndex, CJS_Value(pRuntime, StrTrim(pSub).c_str()));
372 delete[] pSub;
373
374 nIndex++;
375 p = ++pTemp;
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700376 }
377 return StrArray;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700378}
379
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700380int CJS_PublicMethods::ParseStringInteger(const CFX_WideString& string,
381 int nStart,
382 int& nSkip,
383 int nMaxStep) {
384 int nRet = 0;
385 nSkip = 0;
386 for (int i = nStart, sz = string.GetLength(); i < sz; i++) {
387 if (i - nStart > 10)
388 break;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700389
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700390 FX_WCHAR c = string.GetAt(i);
391 if (IsDigit((wchar_t)c)) {
Dan Sinclair10cfea12015-11-16 13:09:00 -0500392 nRet = nRet * 10 + FXSYS_toDecimalDigitWide(c);
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700393 nSkip = i - nStart + 1;
394 if (nSkip >= nMaxStep)
395 break;
396 } else
397 break;
398 }
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700399
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700400 return nRet;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700401}
402
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700403CFX_WideString CJS_PublicMethods::ParseStringString(
404 const CFX_WideString& string,
405 int nStart,
406 int& nSkip) {
407 CFX_WideString swRet;
408 nSkip = 0;
409 for (int i = nStart, sz = string.GetLength(); i < sz; i++) {
410 FX_WCHAR c = string.GetAt(i);
411 if ((c >= L'a' && c <= L'z') || (c >= L'A' && c <= L'Z')) {
412 swRet += c;
413 nSkip = i - nStart + 1;
414 } else
415 break;
416 }
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700417
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700418 return swRet;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700419}
420
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700421double CJS_PublicMethods::ParseNormalDate(const CFX_WideString& value,
422 FX_BOOL& bWrongFormat) {
423 double dt = JS_GetDateTime();
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700424
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700425 int nYear = JS_GetYearFromTime(dt);
426 int nMonth = JS_GetMonthFromTime(dt) + 1;
427 int nDay = JS_GetDayFromTime(dt);
428 int nHour = JS_GetHourFromTime(dt);
429 int nMin = JS_GetMinFromTime(dt);
430 int nSec = JS_GetSecFromTime(dt);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700431
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700432 int number[3];
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700433
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700434 int nSkip = 0;
435 int nLen = value.GetLength();
436 int nIndex = 0;
437 int i = 0;
438 while (i < nLen) {
439 if (nIndex > 2)
440 break;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700441
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700442 FX_WCHAR c = value.GetAt(i);
443 if (IsDigit((wchar_t)c)) {
444 number[nIndex++] = ParseStringInteger(value, i, nSkip, 4);
445 i += nSkip;
446 } else {
447 i++;
448 }
449 }
450
451 if (nIndex == 2) {
452 // case2: month/day
453 // case3: day/month
454 if ((number[0] >= 1 && number[0] <= 12) &&
455 (number[1] >= 1 && number[1] <= 31)) {
456 nMonth = number[0];
457 nDay = number[1];
458 } else if ((number[0] >= 1 && number[0] <= 31) &&
459 (number[1] >= 1 && number[1] <= 12)) {
460 nDay = number[0];
461 nMonth = number[1];
Tom Sepez2f2ffec2015-07-23 14:42:09 -0700462 }
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700463
Tom Sepez2f2ffec2015-07-23 14:42:09 -0700464 bWrongFormat = FALSE;
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700465 } else if (nIndex == 3) {
466 // case1: year/month/day
467 // case2: month/day/year
468 // case3: day/month/year
Tom Sepez5ffacd62014-07-18 14:42:12 -0700469
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700470 if (number[0] > 12 && (number[1] >= 1 && number[1] <= 12) &&
471 (number[2] >= 1 && number[2] <= 31)) {
472 nYear = number[0];
473 nMonth = number[1];
474 nDay = number[2];
475 } else if ((number[0] >= 1 && number[0] <= 12) &&
476 (number[1] >= 1 && number[1] <= 31) && number[2] > 31) {
477 nMonth = number[0];
478 nDay = number[1];
479 nYear = number[2];
480 } else if ((number[0] >= 1 && number[0] <= 31) &&
481 (number[1] >= 1 && number[1] <= 12) && number[2] > 31) {
482 nDay = number[0];
483 nMonth = number[1];
484 nYear = number[2];
Tom Sepez2f2ffec2015-07-23 14:42:09 -0700485 }
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700486
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700487 bWrongFormat = FALSE;
488 } else {
489 bWrongFormat = TRUE;
490 return dt;
491 }
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700492
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700493 CFX_WideString swTemp;
494 swTemp.Format(L"%d/%d/%d %d:%d:%d", nMonth, nDay, nYear, nHour, nMin, nSec);
495 return JS_DateParse(swTemp.c_str());
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700496}
497
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700498double CJS_PublicMethods::MakeRegularDate(const CFX_WideString& value,
499 const CFX_WideString& format,
500 FX_BOOL& bWrongFormat) {
501 double dt = JS_GetDateTime();
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700502
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700503 if (format.IsEmpty() || value.IsEmpty())
504 return dt;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700505
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700506 int nYear = JS_GetYearFromTime(dt);
507 int nMonth = JS_GetMonthFromTime(dt) + 1;
508 int nDay = JS_GetDayFromTime(dt);
509 int nHour = JS_GetHourFromTime(dt);
510 int nMin = JS_GetMinFromTime(dt);
511 int nSec = JS_GetSecFromTime(dt);
512
513 int nYearSub = 99; // nYear - 2000;
514
515 FX_BOOL bPm = FALSE;
516 FX_BOOL bExit = FALSE;
517 bWrongFormat = FALSE;
518
519 int i = 0;
520 int j = 0;
521
522 while (i < format.GetLength()) {
523 if (bExit)
524 break;
525
526 FX_WCHAR c = format.GetAt(i);
527 switch (c) {
528 case ':':
529 case '.':
530 case '-':
531 case '\\':
532 case '/':
533 i++;
534 j++;
535 break;
536
537 case 'y':
538 case 'm':
539 case 'd':
540 case 'H':
541 case 'h':
542 case 'M':
543 case 's':
544 case 't': {
545 int oldj = j;
546 int nSkip = 0;
547 int remaining = format.GetLength() - i - 1;
548
549 if (remaining == 0 || format.GetAt(i + 1) != c) {
550 switch (c) {
Tom Sepez2f2ffec2015-07-23 14:42:09 -0700551 case 'y':
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700552 i++;
553 j++;
554 break;
Tom Sepez2f2ffec2015-07-23 14:42:09 -0700555 case 'm':
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700556 nMonth = ParseStringInteger(value, j, nSkip, 2);
557 i++;
558 j += nSkip;
559 break;
Tom Sepez2f2ffec2015-07-23 14:42:09 -0700560 case 'd':
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700561 nDay = ParseStringInteger(value, j, nSkip, 2);
562 i++;
563 j += nSkip;
564 break;
Tom Sepez2f2ffec2015-07-23 14:42:09 -0700565 case 'H':
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700566 nHour = ParseStringInteger(value, j, nSkip, 2);
567 i++;
568 j += nSkip;
569 break;
Tom Sepez2f2ffec2015-07-23 14:42:09 -0700570 case 'h':
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700571 nHour = ParseStringInteger(value, j, nSkip, 2);
572 i++;
573 j += nSkip;
574 break;
Tom Sepez2f2ffec2015-07-23 14:42:09 -0700575 case 'M':
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700576 nMin = ParseStringInteger(value, j, nSkip, 2);
577 i++;
578 j += nSkip;
579 break;
Tom Sepez2f2ffec2015-07-23 14:42:09 -0700580 case 's':
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700581 nSec = ParseStringInteger(value, j, nSkip, 2);
582 i++;
583 j += nSkip;
584 break;
Tom Sepez2f2ffec2015-07-23 14:42:09 -0700585 case 't':
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700586 bPm = (j < value.GetLength() && value.GetAt(j) == 'p');
587 i++;
588 j++;
589 break;
590 }
591 } else if (remaining == 1 || format.GetAt(i + 2) != c) {
592 switch (c) {
593 case 'y':
594 nYear = ParseStringInteger(value, j, nSkip, 4);
595 i += 2;
596 j += nSkip;
597 break;
598 case 'm':
599 nMonth = ParseStringInteger(value, j, nSkip, 2);
600 i += 2;
601 j += nSkip;
602 break;
603 case 'd':
604 nDay = ParseStringInteger(value, j, nSkip, 2);
605 i += 2;
606 j += nSkip;
607 break;
608 case 'H':
609 nHour = ParseStringInteger(value, j, nSkip, 2);
610 i += 2;
611 j += nSkip;
612 break;
613 case 'h':
614 nHour = ParseStringInteger(value, j, nSkip, 2);
615 i += 2;
616 j += nSkip;
617 break;
618 case 'M':
619 nMin = ParseStringInteger(value, j, nSkip, 2);
620 i += 2;
621 j += nSkip;
622 break;
623 case 's':
624 nSec = ParseStringInteger(value, j, nSkip, 2);
625 i += 2;
626 j += nSkip;
627 break;
628 case 't':
629 bPm = (j + 1 < value.GetLength() && value.GetAt(j) == 'p' &&
630 value.GetAt(j + 1) == 'm');
631 i += 2;
632 j += 2;
633 break;
634 }
635 } else if (remaining == 2 || format.GetAt(i + 3) != c) {
636 switch (c) {
637 case 'm': {
638 CFX_WideString sMonth = ParseStringString(value, j, nSkip);
639 FX_BOOL bFind = FALSE;
640 for (int m = 0; m < 12; m++) {
641 if (sMonth.CompareNoCase(months[m]) == 0) {
642 nMonth = m + 1;
643 i += 3;
644 j += nSkip;
645 bFind = TRUE;
646 break;
Tom Sepez2f2ffec2015-07-23 14:42:09 -0700647 }
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700648 }
649
650 if (!bFind) {
651 nMonth = ParseStringInteger(value, j, nSkip, 3);
652 i += 3;
653 j += nSkip;
654 }
655 } break;
656 case 'y':
657 break;
Tom Sepez2f2ffec2015-07-23 14:42:09 -0700658 default:
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700659 i += 3;
660 j += 3;
661 break;
662 }
663 } else if (remaining == 3 || format.GetAt(i + 4) != c) {
664 switch (c) {
665 case 'y':
666 nYear = ParseStringInteger(value, j, nSkip, 4);
667 j += nSkip;
668 i += 4;
669 break;
670 case 'm': {
671 FX_BOOL bFind = FALSE;
672
673 CFX_WideString sMonth = ParseStringString(value, j, nSkip);
674 sMonth.MakeLower();
675
676 for (int m = 0; m < 12; m++) {
677 CFX_WideString sFullMonths = fullmonths[m];
678 sFullMonths.MakeLower();
679
680 if (sFullMonths.Find(sMonth.c_str(), 0) != -1) {
681 nMonth = m + 1;
682 i += 4;
683 j += nSkip;
684 bFind = TRUE;
685 break;
686 }
687 }
688
689 if (!bFind) {
690 nMonth = ParseStringInteger(value, j, nSkip, 4);
691 i += 4;
692 j += nSkip;
693 }
694 } break;
695 default:
696 i += 4;
697 j += 4;
698 break;
699 }
700 } else {
701 if (j >= value.GetLength() || format.GetAt(i) != value.GetAt(j)) {
702 bWrongFormat = TRUE;
703 bExit = TRUE;
704 }
705 i++;
706 j++;
Tom Sepez2f2ffec2015-07-23 14:42:09 -0700707 }
Tom Sepez85386422014-07-23 10:28:37 -0700708
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700709 if (oldj == j) {
710 bWrongFormat = TRUE;
711 bExit = TRUE;
712 }
713 }
714
715 break;
716 default:
717 if (value.GetLength() <= j) {
718 bExit = TRUE;
719 } else if (format.GetAt(i) != value.GetAt(j)) {
720 bWrongFormat = TRUE;
721 bExit = TRUE;
722 }
723
724 i++;
725 j++;
726 break;
727 }
728 }
729
730 if (bPm)
731 nHour += 12;
732
733 if (nYear >= 0 && nYear <= nYearSub)
734 nYear += 2000;
735
736 if (nMonth < 1 || nMonth > 12)
737 bWrongFormat = TRUE;
738
739 if (nDay < 1 || nDay > 31)
740 bWrongFormat = TRUE;
741
742 if (nHour < 0 || nHour > 24)
743 bWrongFormat = TRUE;
744
745 if (nMin < 0 || nMin > 60)
746 bWrongFormat = TRUE;
747
748 if (nSec < 0 || nSec > 60)
749 bWrongFormat = TRUE;
750
751 double dRet = 0;
752
753 if (bWrongFormat) {
754 dRet = ParseNormalDate(value, bWrongFormat);
755 } else {
756 dRet = JS_MakeDate(JS_MakeDay(nYear, nMonth - 1, nDay),
757 JS_MakeTime(nHour, nMin, nSec, 0));
758
759 if (JS_PortIsNan(dRet)) {
760 dRet = JS_DateParse(value.c_str());
761 }
762 }
763
764 if (JS_PortIsNan(dRet)) {
765 dRet = ParseNormalDate(value, bWrongFormat);
766 }
767
768 return dRet;
769}
770
771CFX_WideString CJS_PublicMethods::MakeFormatDate(double dDate,
772 const CFX_WideString& format) {
773 CFX_WideString sRet = L"", sPart = L"";
774
775 int nYear = JS_GetYearFromTime(dDate);
776 int nMonth = JS_GetMonthFromTime(dDate) + 1;
777 int nDay = JS_GetDayFromTime(dDate);
778 int nHour = JS_GetHourFromTime(dDate);
779 int nMin = JS_GetMinFromTime(dDate);
780 int nSec = JS_GetSecFromTime(dDate);
781
782 int i = 0;
783 while (i < format.GetLength()) {
784 FX_WCHAR c = format.GetAt(i);
785 int remaining = format.GetLength() - i - 1;
786 sPart = L"";
787 switch (c) {
788 case 'y':
789 case 'm':
790 case 'd':
791 case 'H':
792 case 'h':
793 case 'M':
794 case 's':
795 case 't':
796 if (remaining == 0 || format.GetAt(i + 1) != c) {
797 switch (c) {
798 case 'y':
799 sPart += c;
800 break;
801 case 'm':
802 sPart.Format(L"%d", nMonth);
803 break;
804 case 'd':
805 sPart.Format(L"%d", nDay);
806 break;
807 case 'H':
808 sPart.Format(L"%d", nHour);
809 break;
810 case 'h':
811 sPart.Format(L"%d", nHour > 12 ? nHour - 12 : nHour);
812 break;
813 case 'M':
814 sPart.Format(L"%d", nMin);
815 break;
816 case 's':
817 sPart.Format(L"%d", nSec);
818 break;
819 case 't':
820 sPart += nHour > 12 ? 'p' : 'a';
821 break;
822 }
823 i++;
824 } else if (remaining == 1 || format.GetAt(i + 2) != c) {
825 switch (c) {
826 case 'y':
827 sPart.Format(L"%02d", nYear - (nYear / 100) * 100);
828 break;
829 case 'm':
830 sPart.Format(L"%02d", nMonth);
831 break;
832 case 'd':
833 sPart.Format(L"%02d", nDay);
834 break;
835 case 'H':
836 sPart.Format(L"%02d", nHour);
837 break;
838 case 'h':
839 sPart.Format(L"%02d", nHour > 12 ? nHour - 12 : nHour);
840 break;
841 case 'M':
842 sPart.Format(L"%02d", nMin);
843 break;
844 case 's':
845 sPart.Format(L"%02d", nSec);
846 break;
847 case 't':
848 sPart = nHour > 12 ? L"pm" : L"am";
849 break;
850 }
851 i += 2;
852 } else if (remaining == 2 || format.GetAt(i + 3) != c) {
853 switch (c) {
854 case 'm':
855 i += 3;
856 if (nMonth > 0 && nMonth <= 12)
857 sPart += months[nMonth - 1];
858 break;
859 default:
860 i += 3;
861 sPart += c;
862 sPart += c;
863 sPart += c;
864 break;
865 }
866 } else if (remaining == 3 || format.GetAt(i + 4) != c) {
867 switch (c) {
868 case 'y':
869 sPart.Format(L"%04d", nYear);
870 i += 4;
871 break;
872 case 'm':
873 i += 4;
874 if (nMonth > 0 && nMonth <= 12)
875 sPart += fullmonths[nMonth - 1];
876 break;
877 default:
878 i += 4;
879 sPart += c;
880 sPart += c;
881 sPart += c;
882 sPart += c;
883 break;
884 }
885 } else {
886 i++;
887 sPart += c;
888 }
889 break;
890 default:
891 i++;
892 sPart += c;
893 break;
Tom Sepez2f2ffec2015-07-23 14:42:09 -0700894 }
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700895
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700896 sRet += sPart;
897 }
898
899 return sRet;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700900}
901
902/* -------------------------------------------------------------------------- */
903
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700904// function AFNumber_Format(nDec, sepStyle, negStyle, currStyle, strCurrency,
905// bCurrencyPrepend)
Tom Sepezba038bc2015-10-08 12:03:00 -0700906FX_BOOL CJS_PublicMethods::AFNumber_Format(IJS_Context* cc,
Lei Zhang945fdb72015-11-11 10:18:16 -0800907 const std::vector<CJS_Value>& params,
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700908 CJS_Value& vRet,
909 CFX_WideString& sError) {
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700910#if _FX_OS_ != _FX_ANDROID_
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700911 CJS_Context* pContext = (CJS_Context*)cc;
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700912 if (params.size() != 6) {
913 sError = JSGetStringFromID(pContext, IDS_STRING_JSPARAMERROR);
914 return FALSE;
915 }
Tom Sepez67fd5df2015-10-08 12:24:19 -0700916
917 CJS_Runtime* pRuntime = CJS_Runtime::FromContext(cc);
918 CJS_EventHandler* pEvent = pContext->GetEventHandler();
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700919 if (!pEvent->m_pValue)
920 return FALSE;
Tom Sepez67fd5df2015-10-08 12:24:19 -0700921
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700922 CFX_WideString& Value = pEvent->Value();
923 CFX_ByteString strValue = StrTrim(CFX_ByteString::FromUnicode(Value));
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700924 if (strValue.IsEmpty())
Tom Sepez2f2ffec2015-07-23 14:42:09 -0700925 return TRUE;
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700926
927 int iDec = params[0].ToInt();
928 int iSepStyle = params[1].ToInt();
929 int iNegStyle = params[2].ToInt();
930 // params[3] is iCurrStyle, it's not used.
931 std::wstring wstrCurrency(params[4].ToCFXWideString().c_str());
932 FX_BOOL bCurrencyPrepend = params[5].ToBool();
933
934 if (iDec < 0)
935 iDec = -iDec;
936
937 if (iSepStyle < 0 || iSepStyle > 3)
938 iSepStyle = 0;
939
940 if (iNegStyle < 0 || iNegStyle > 3)
941 iNegStyle = 0;
942
943 //////////////////////////////////////////////////////
944 // for processing decimal places
945 strValue.Replace(",", ".");
946 double dValue = atof(strValue);
947 if (iDec > 0)
Tom Sepezdfbf8e72015-10-14 14:17:26 -0700948 dValue += DOUBLE_CORRECT;
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700949
950 int iDec2;
951 int iNegative = 0;
952
953 strValue = fcvt(dValue, iDec, &iDec2, &iNegative);
954 if (strValue.IsEmpty()) {
955 dValue = 0;
956 strValue = fcvt(dValue, iDec, &iDec2, &iNegative);
957 if (strValue.IsEmpty()) {
958 strValue = "0";
959 iDec2 = 1;
960 }
961 }
962
963 if (iDec2 < 0) {
964 for (int iNum = 0; iNum < abs(iDec2); iNum++) {
965 strValue = "0" + strValue;
966 }
967 iDec2 = 0;
968 }
969 int iMax = strValue.GetLength();
970 if (iDec2 > iMax) {
971 for (int iNum = 0; iNum <= iDec2 - iMax; iNum++) {
972 strValue += "0";
973 }
974 iMax = iDec2 + 1;
975 }
976 ///////////////////////////////////////////////////////
977 // for processing seperator style
978 if (iDec2 < iMax) {
979 if (iSepStyle == 0 || iSepStyle == 1) {
980 strValue.Insert(iDec2, '.');
981 iMax++;
982 } else if (iSepStyle == 2 || iSepStyle == 3) {
983 strValue.Insert(iDec2, ',');
984 iMax++;
985 }
986
987 if (iDec2 == 0)
988 strValue.Insert(iDec2, '0');
989 }
990 if (iSepStyle == 0 || iSepStyle == 2) {
991 char cSeperator;
992 if (iSepStyle == 0)
993 cSeperator = ',';
994 else
995 cSeperator = '.';
996
Tom Sepezdfbf8e72015-10-14 14:17:26 -0700997 for (int iDecPositive = iDec2 - 3; iDecPositive > 0; iDecPositive -= 3) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700998 strValue.Insert(iDecPositive, cSeperator);
999 iMax++;
1000 }
1001 }
1002
1003 //////////////////////////////////////////////////////////////////////
1004 // for processing currency string
1005
1006 Value = CFX_WideString::FromLocal(strValue);
1007 std::wstring strValue2 = Value.c_str();
1008
1009 if (bCurrencyPrepend)
1010 strValue2 = wstrCurrency + strValue2;
1011 else
1012 strValue2 = strValue2 + wstrCurrency;
1013
1014 /////////////////////////////////////////////////////////////////////////
1015 // for processing negative style
1016 if (iNegative) {
1017 if (iNegStyle == 0) {
1018 strValue2.insert(0, L"-");
1019 }
1020 if (iNegStyle == 2 || iNegStyle == 3) {
1021 strValue2.insert(0, L"(");
1022 strValue2.insert(strValue2.length(), L")");
1023 }
1024 if (iNegStyle == 1 || iNegStyle == 3) {
1025 if (Field* fTarget = pEvent->Target_Field()) {
Tom Sepez67fd5df2015-10-08 12:24:19 -07001026 CJS_Array arColor(pRuntime);
1027 CJS_Value vColElm(pRuntime);
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001028 vColElm = L"RGB";
1029 arColor.SetElement(0, vColElm);
1030 vColElm = 1;
1031 arColor.SetElement(1, vColElm);
1032 vColElm = 0;
1033 arColor.SetElement(2, vColElm);
1034
1035 arColor.SetElement(3, vColElm);
1036
Tom Sepez67fd5df2015-10-08 12:24:19 -07001037 CJS_PropValue vProp(pRuntime);
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001038 vProp.StartGetting();
1039 vProp << arColor;
1040 vProp.StartSetting();
1041 fTarget->textColor(cc, vProp, sError); // red
1042 }
1043 }
1044 } else {
1045 if (iNegStyle == 1 || iNegStyle == 3) {
1046 if (Field* fTarget = pEvent->Target_Field()) {
Tom Sepez67fd5df2015-10-08 12:24:19 -07001047 CJS_Array arColor(pRuntime);
1048 CJS_Value vColElm(pRuntime);
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001049 vColElm = L"RGB";
1050 arColor.SetElement(0, vColElm);
1051 vColElm = 0;
1052 arColor.SetElement(1, vColElm);
1053 arColor.SetElement(2, vColElm);
1054 arColor.SetElement(3, vColElm);
1055
Tom Sepez67fd5df2015-10-08 12:24:19 -07001056 CJS_PropValue vProp(pRuntime);
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001057 vProp.StartGetting();
1058 fTarget->textColor(cc, vProp, sError);
1059
Tom Sepez67fd5df2015-10-08 12:24:19 -07001060 CJS_Array aProp(pRuntime);
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001061 vProp.ConvertToArray(aProp);
1062
1063 CPWL_Color crProp;
1064 CPWL_Color crColor;
1065 color::ConvertArrayToPWLColor(aProp, crProp);
1066 color::ConvertArrayToPWLColor(arColor, crColor);
1067
1068 if (crColor != crProp) {
Tom Sepez67fd5df2015-10-08 12:24:19 -07001069 CJS_PropValue vProp2(pRuntime);
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001070 vProp2.StartGetting();
1071 vProp2 << arColor;
1072 vProp2.StartSetting();
1073 fTarget->textColor(cc, vProp2, sError);
1074 }
1075 }
1076 }
1077 }
1078 Value = strValue2.c_str();
1079#endif
1080 return TRUE;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07001081}
1082
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001083// function AFNumber_Keystroke(nDec, sepStyle, negStyle, currStyle, strCurrency,
1084// bCurrencyPrepend)
Lei Zhang945fdb72015-11-11 10:18:16 -08001085FX_BOOL CJS_PublicMethods::AFNumber_Keystroke(
1086 IJS_Context* cc,
1087 const std::vector<CJS_Value>& params,
1088 CJS_Value& vRet,
1089 CFX_WideString& sError) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001090 CJS_Context* pContext = (CJS_Context*)cc;
1091 ASSERT(pContext != NULL);
1092 CJS_EventHandler* pEvent = pContext->GetEventHandler();
1093 ASSERT(pEvent != NULL);
Lei Zhanga6d9f0e2015-06-13 00:48:38 -07001094
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001095 if (params.size() < 2)
1096 return FALSE;
1097 int iSepStyle = params[1].ToInt();
Lei Zhanga6d9f0e2015-06-13 00:48:38 -07001098
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001099 if (iSepStyle < 0 || iSepStyle > 3)
1100 iSepStyle = 0;
1101 if (!pEvent->m_pValue)
1102 return FALSE;
1103 CFX_WideString& val = pEvent->Value();
1104 CFX_WideString& w_strChange = pEvent->Change();
1105 CFX_WideString w_strValue = val;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07001106
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001107 if (pEvent->WillCommit()) {
1108 CFX_WideString wstrChange = w_strChange;
1109 CFX_WideString wstrValue = StrLTrim(w_strValue.c_str());
1110 if (wstrValue.IsEmpty())
1111 return TRUE;
Lei Zhanga6d9f0e2015-06-13 00:48:38 -07001112
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001113 CFX_WideString swTemp = wstrValue;
1114 swTemp.Replace(L",", L".");
1115 if (!IsNumber(swTemp.c_str())) {
1116 pEvent->Rc() = FALSE;
1117 sError = JSGetStringFromID(pContext, IDS_STRING_JSAFNUMBER_KEYSTROKE);
1118 Alert(pContext, sError.c_str());
1119 return TRUE;
Tom Sepez2f2ffec2015-07-23 14:42:09 -07001120 }
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001121 return TRUE; // it happens after the last keystroke and before validating,
1122 }
Tom Sepez4f7bc042015-04-27 12:06:58 -07001123
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001124 std::wstring w_strValue2 = w_strValue.c_str();
1125 std::wstring w_strChange2 = w_strChange.c_str();
1126 std::wstring w_strSelected;
1127 if (-1 != pEvent->SelStart())
1128 w_strSelected = w_strValue2.substr(pEvent->SelStart(),
1129 (pEvent->SelEnd() - pEvent->SelStart()));
Lei Zhangb9c31972015-08-11 14:09:35 -07001130 bool bHasSign = (w_strValue2.find('-') != std::wstring::npos) &&
1131 (w_strSelected.find('-') == std::wstring::npos);
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001132 if (bHasSign) {
1133 // can't insert "change" in front to sign postion.
1134 if (pEvent->SelStart() == 0) {
1135 FX_BOOL& bRc = pEvent->Rc();
1136 bRc = FALSE;
1137 return TRUE;
Tom Sepez2f2ffec2015-07-23 14:42:09 -07001138 }
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001139 }
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07001140
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001141 char cSep = L'.';
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07001142
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001143 switch (iSepStyle) {
Tom Sepez2f2ffec2015-07-23 14:42:09 -07001144 case 0:
1145 case 1:
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001146 cSep = L'.';
1147 break;
Tom Sepez2f2ffec2015-07-23 14:42:09 -07001148 case 2:
1149 case 3:
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001150 cSep = L',';
1151 break;
1152 }
Lei Zhanga6d9f0e2015-06-13 00:48:38 -07001153
Lei Zhangb9c31972015-08-11 14:09:35 -07001154 bool bHasSep = (w_strValue2.find(cSep) != std::wstring::npos);
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001155 for (std::wstring::iterator it = w_strChange2.begin();
1156 it != w_strChange2.end(); it++) {
1157 if (*it == cSep) {
1158 if (bHasSep) {
1159 FX_BOOL& bRc = pEvent->Rc();
1160 bRc = FALSE;
Tom Sepez2f2ffec2015-07-23 14:42:09 -07001161 return TRUE;
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001162 }
1163 bHasSep = TRUE;
1164 continue;
1165 }
1166 if (*it == L'-') {
1167 if (bHasSign) {
1168 FX_BOOL& bRc = pEvent->Rc();
1169 bRc = FALSE;
1170 return TRUE;
1171 }
1172 if (it != w_strChange2.begin()) // sign's position is not correct
1173 {
1174 FX_BOOL& bRc = pEvent->Rc();
1175 bRc = FALSE;
1176 return TRUE;
1177 }
1178 if (pEvent->SelStart() != 0) {
1179 FX_BOOL& bRc = pEvent->Rc();
1180 bRc = FALSE;
1181 return TRUE;
1182 }
1183 bHasSign = TRUE;
1184 continue;
1185 }
1186
1187 if (!IsDigit(*it)) {
1188 FX_BOOL& bRc = pEvent->Rc();
1189 bRc = FALSE;
1190 return TRUE;
1191 }
1192 }
1193
1194 std::wstring w_prefix = w_strValue2.substr(0, pEvent->SelStart());
1195 std::wstring w_postfix;
1196 if (pEvent->SelEnd() < (int)w_strValue2.length())
1197 w_postfix = w_strValue2.substr(pEvent->SelEnd());
1198 w_strValue2 = w_prefix + w_strChange2 + w_postfix;
1199 w_strValue = w_strValue2.c_str();
1200 val = w_strValue;
1201 return TRUE;
1202}
1203
1204// function AFPercent_Format(nDec, sepStyle)
Lei Zhang945fdb72015-11-11 10:18:16 -08001205FX_BOOL CJS_PublicMethods::AFPercent_Format(
1206 IJS_Context* cc,
1207 const std::vector<CJS_Value>& params,
1208 CJS_Value& vRet,
1209 CFX_WideString& sError) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001210#if _FX_OS_ != _FX_ANDROID_
1211 CJS_Context* pContext = (CJS_Context*)cc;
1212 ASSERT(pContext != NULL);
1213 CJS_EventHandler* pEvent = pContext->GetEventHandler();
1214 ASSERT(pEvent != NULL);
1215
1216 if (params.size() != 2) {
1217 sError = JSGetStringFromID(pContext, IDS_STRING_JSPARAMERROR);
1218 return FALSE;
1219 }
1220 if (!pEvent->m_pValue)
1221 return FALSE;
1222
1223 CFX_WideString& Value = pEvent->Value();
1224 CFX_ByteString strValue = StrTrim(CFX_ByteString::FromUnicode(Value));
1225 if (strValue.IsEmpty())
1226 return TRUE;
1227
1228 int iDec = params[0].ToInt();
1229 if (iDec < 0)
1230 iDec = -iDec;
1231
1232 int iSepStyle = params[1].ToInt();
1233 if (iSepStyle < 0 || iSepStyle > 3)
1234 iSepStyle = 0;
1235
1236 //////////////////////////////////////////////////////
1237 // for processing decimal places
1238 double dValue = atof(strValue);
1239 dValue *= 100;
1240 if (iDec > 0)
1241 dValue += DOUBLE_CORRECT; //УÕý
1242
1243 int iDec2;
1244 int iNegative = 0;
1245 strValue = fcvt(dValue, iDec, &iDec2, &iNegative);
1246 if (strValue.IsEmpty()) {
1247 dValue = 0;
1248 strValue = fcvt(dValue, iDec, &iDec2, &iNegative);
1249 }
1250
1251 if (iDec2 < 0) {
1252 for (int iNum = 0; iNum < abs(iDec2); iNum++) {
1253 strValue = "0" + strValue;
1254 }
1255 iDec2 = 0;
1256 }
1257 int iMax = strValue.GetLength();
1258 if (iDec2 > iMax) {
1259 for (int iNum = 0; iNum <= iDec2 - iMax; iNum++) {
1260 strValue += "0";
1261 }
1262 iMax = iDec2 + 1;
1263 }
1264 ///////////////////////////////////////////////////////
1265 // for processing seperator style
1266 if (iDec2 < iMax) {
1267 if (iSepStyle == 0 || iSepStyle == 1) {
1268 strValue.Insert(iDec2, '.');
1269 iMax++;
1270 } else if (iSepStyle == 2 || iSepStyle == 3) {
1271 strValue.Insert(iDec2, ',');
1272 iMax++;
1273 }
1274
1275 if (iDec2 == 0)
1276 strValue.Insert(iDec2, '0');
1277 }
1278 if (iSepStyle == 0 || iSepStyle == 2) {
1279 char cSeperator;
1280 if (iSepStyle == 0)
1281 cSeperator = ',';
1282 else
1283 cSeperator = '.';
1284
Tom Sepezdfbf8e72015-10-14 14:17:26 -07001285 for (int iDecPositive = iDec2 - 3; iDecPositive > 0; iDecPositive -= 3) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001286 strValue.Insert(iDecPositive, cSeperator);
1287 iMax++;
1288 }
1289 }
1290 ////////////////////////////////////////////////////////////////////
1291 // negative mark
1292 if (iNegative)
1293 strValue = "-" + strValue;
1294 strValue += "%";
1295 Value = CFX_WideString::FromLocal(strValue);
1296#endif
1297 return TRUE;
1298}
1299// AFPercent_Keystroke(nDec, sepStyle)
Lei Zhang945fdb72015-11-11 10:18:16 -08001300FX_BOOL CJS_PublicMethods::AFPercent_Keystroke(
1301 IJS_Context* cc,
1302 const std::vector<CJS_Value>& params,
1303 CJS_Value& vRet,
1304 CFX_WideString& sError) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001305 return AFNumber_Keystroke(cc, params, vRet, sError);
1306}
1307
1308// function AFDate_FormatEx(cFormat)
Tom Sepezba038bc2015-10-08 12:03:00 -07001309FX_BOOL CJS_PublicMethods::AFDate_FormatEx(IJS_Context* cc,
Lei Zhang945fdb72015-11-11 10:18:16 -08001310 const std::vector<CJS_Value>& params,
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001311 CJS_Value& vRet,
1312 CFX_WideString& sError) {
1313 CJS_Context* pContext = (CJS_Context*)cc;
1314 ASSERT(pContext != NULL);
1315 CJS_EventHandler* pEvent = pContext->GetEventHandler();
1316 ASSERT(pEvent != NULL);
1317
1318 if (params.size() != 1) {
1319 sError = JSGetStringFromID(pContext, IDS_STRING_JSPARAMERROR);
1320 return FALSE;
1321 }
1322 if (!pEvent->m_pValue)
1323 return FALSE;
1324
1325 CFX_WideString& val = pEvent->Value();
1326 CFX_WideString strValue = val;
1327 if (strValue.IsEmpty())
1328 return TRUE;
1329
1330 CFX_WideString sFormat = params[0].ToCFXWideString();
1331 FX_BOOL bWrongFormat = FALSE;
1332 double dDate = 0.0f;
1333
1334 if (strValue.Find(L"GMT") != -1) {
1335 // for GMT format time
1336 // such as "Tue Aug 11 14:24:16 GMT+08002009"
1337 dDate = MakeInterDate(strValue);
1338 } else {
1339 dDate = MakeRegularDate(strValue, sFormat, bWrongFormat);
1340 }
1341
1342 if (JS_PortIsNan(dDate)) {
1343 CFX_WideString swMsg;
1344 swMsg.Format(JSGetStringFromID(pContext, IDS_STRING_JSPARSEDATE).c_str(),
1345 sFormat.c_str());
1346 Alert(pContext, swMsg.c_str());
1347 return FALSE;
1348 }
1349
1350 val = MakeFormatDate(dDate, sFormat);
1351 return TRUE;
1352}
1353
1354double CJS_PublicMethods::MakeInterDate(CFX_WideString strValue) {
1355 int nHour;
1356 int nMin;
1357 int nSec;
1358 int nYear;
1359 int nMonth;
1360 int nDay;
1361
1362 CFX_WideStringArray wsArray;
1363 CFX_WideString sMonth = L"";
1364 CFX_WideString sTemp = L"";
1365 int nSize = strValue.GetLength();
1366
1367 for (int i = 0; i < nSize; i++) {
1368 FX_WCHAR c = strValue.GetAt(i);
1369 if (c == L' ' || c == L':') {
1370 wsArray.Add(sTemp);
1371 sTemp = L"";
1372 continue;
1373 }
1374
1375 sTemp += c;
1376 }
1377
1378 wsArray.Add(sTemp);
1379 if (wsArray.GetSize() != 8)
1380 return 0;
1381
1382 sTemp = wsArray[1];
1383 if (sTemp.Compare(L"Jan") == 0)
1384 nMonth = 1;
1385 if (sTemp.Compare(L"Feb") == 0)
1386 nMonth = 2;
1387 if (sTemp.Compare(L"Mar") == 0)
1388 nMonth = 3;
1389 if (sTemp.Compare(L"Apr") == 0)
1390 nMonth = 4;
1391 if (sTemp.Compare(L"May") == 0)
1392 nMonth = 5;
1393 if (sTemp.Compare(L"Jun") == 0)
1394 nMonth = 6;
1395 if (sTemp.Compare(L"Jul") == 0)
1396 nMonth = 7;
1397 if (sTemp.Compare(L"Aug") == 0)
1398 nMonth = 8;
1399 if (sTemp.Compare(L"Sep") == 0)
1400 nMonth = 9;
1401 if (sTemp.Compare(L"Oct") == 0)
1402 nMonth = 10;
1403 if (sTemp.Compare(L"Nov") == 0)
1404 nMonth = 11;
1405 if (sTemp.Compare(L"Dec") == 0)
1406 nMonth = 12;
1407
1408 nDay = (int)ParseStringToNumber(wsArray[2].c_str());
1409 nHour = (int)ParseStringToNumber(wsArray[3].c_str());
1410 nMin = (int)ParseStringToNumber(wsArray[4].c_str());
1411 nSec = (int)ParseStringToNumber(wsArray[5].c_str());
1412 nYear = (int)ParseStringToNumber(wsArray[7].c_str());
1413
1414 double dRet = JS_MakeDate(JS_MakeDay(nYear, nMonth - 1, nDay),
1415 JS_MakeTime(nHour, nMin, nSec, 0));
1416
1417 if (JS_PortIsNan(dRet)) {
1418 dRet = JS_DateParse(strValue.c_str());
1419 }
1420
1421 return dRet;
1422}
1423
1424// AFDate_KeystrokeEx(cFormat)
Lei Zhang945fdb72015-11-11 10:18:16 -08001425FX_BOOL CJS_PublicMethods::AFDate_KeystrokeEx(
1426 IJS_Context* cc,
1427 const std::vector<CJS_Value>& params,
1428 CJS_Value& vRet,
1429 CFX_WideString& sError) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001430 CJS_Context* pContext = (CJS_Context*)cc;
1431 ASSERT(pContext != NULL);
1432 CJS_EventHandler* pEvent = pContext->GetEventHandler();
1433 ASSERT(pEvent != NULL);
1434
1435 if (params.size() != 1) {
1436 sError = L"AFDate_KeystrokeEx's parameters' size r not correct";
1437 return FALSE;
1438 }
1439
1440 if (pEvent->WillCommit()) {
1441 if (!pEvent->m_pValue)
1442 return FALSE;
1443 CFX_WideString strValue = pEvent->Value();
1444 if (strValue.IsEmpty())
1445 return TRUE;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07001446
Tom Sepez2f2ffec2015-07-23 14:42:09 -07001447 CFX_WideString sFormat = params[0].ToCFXWideString();
1448 FX_BOOL bWrongFormat = FALSE;
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001449 double dRet = MakeRegularDate(strValue, sFormat, bWrongFormat);
1450 if (bWrongFormat || JS_PortIsNan(dRet)) {
1451 CFX_WideString swMsg;
1452 swMsg.Format(JSGetStringFromID(pContext, IDS_STRING_JSPARSEDATE).c_str(),
1453 sFormat.c_str());
1454 Alert(pContext, swMsg.c_str());
1455 pEvent->Rc() = FALSE;
1456 return TRUE;
Tom Sepez2f2ffec2015-07-23 14:42:09 -07001457 }
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001458 }
1459 return TRUE;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07001460}
1461
Tom Sepezba038bc2015-10-08 12:03:00 -07001462FX_BOOL CJS_PublicMethods::AFDate_Format(IJS_Context* cc,
Lei Zhang945fdb72015-11-11 10:18:16 -08001463 const std::vector<CJS_Value>& params,
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001464 CJS_Value& vRet,
1465 CFX_WideString& sError) {
Tom Sepez67fd5df2015-10-08 12:24:19 -07001466 CJS_Context* pContext = (CJS_Context*)cc;
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001467 if (params.size() != 1) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001468 sError = JSGetStringFromID(pContext, IDS_STRING_JSPARAMERROR);
1469 return FALSE;
1470 }
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07001471
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001472 int iIndex = params[0].ToInt();
1473 const FX_WCHAR* cFormats[] = {L"m/d",
1474 L"m/d/yy",
1475 L"mm/dd/yy",
1476 L"mm/yy",
1477 L"d-mmm",
1478 L"d-mmm-yy",
1479 L"dd-mmm-yy",
1480 L"yy-mm-dd",
1481 L"mmm-yy",
1482 L"mmmm-yy",
1483 L"mmm d, yyyy",
1484 L"mmmm d, yyyy",
1485 L"m/d/yy h:MM tt",
1486 L"m/d/yy HH:MM"};
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07001487
Lei Zhanga0f67242015-08-17 15:39:30 -07001488 if (iIndex < 0 || (static_cast<size_t>(iIndex) >= FX_ArraySize(cFormats)))
1489 iIndex = 0;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07001490
Lei Zhang945fdb72015-11-11 10:18:16 -08001491 std::vector<CJS_Value> newParams;
Tom Sepez67fd5df2015-10-08 12:24:19 -07001492 newParams.push_back(
1493 CJS_Value(CJS_Runtime::FromContext(cc), cFormats[iIndex]));
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001494 return AFDate_FormatEx(cc, newParams, vRet, sError);
1495}
Lei Zhanga6d9f0e2015-06-13 00:48:38 -07001496
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001497// AFDate_KeystrokeEx(cFormat)
Lei Zhang945fdb72015-11-11 10:18:16 -08001498FX_BOOL CJS_PublicMethods::AFDate_Keystroke(
1499 IJS_Context* cc,
1500 const std::vector<CJS_Value>& params,
1501 CJS_Value& vRet,
1502 CFX_WideString& sError) {
Tom Sepez67fd5df2015-10-08 12:24:19 -07001503 CJS_Context* pContext = (CJS_Context*)cc;
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001504 if (params.size() != 1) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001505 sError = JSGetStringFromID(pContext, IDS_STRING_JSPARAMERROR);
1506 return FALSE;
1507 }
1508
1509 int iIndex = params[0].ToInt();
1510 const FX_WCHAR* cFormats[] = {L"m/d",
1511 L"m/d/yy",
1512 L"mm/dd/yy",
1513 L"mm/yy",
1514 L"d-mmm",
1515 L"d-mmm-yy",
1516 L"dd-mmm-yy",
1517 L"yy-mm-dd",
1518 L"mmm-yy",
1519 L"mmmm-yy",
1520 L"mmm d, yyyy",
1521 L"mmmm d, yyyy",
1522 L"m/d/yy h:MM tt",
1523 L"m/d/yy HH:MM"};
1524
Lei Zhanga0f67242015-08-17 15:39:30 -07001525 if (iIndex < 0 || (static_cast<size_t>(iIndex) >= FX_ArraySize(cFormats)))
1526 iIndex = 0;
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001527
Lei Zhang945fdb72015-11-11 10:18:16 -08001528 std::vector<CJS_Value> newParams;
Tom Sepez67fd5df2015-10-08 12:24:19 -07001529 newParams.push_back(
1530 CJS_Value(CJS_Runtime::FromContext(cc), cFormats[iIndex]));
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001531 return AFDate_KeystrokeEx(cc, newParams, vRet, sError);
1532}
1533
1534// function AFTime_Format(ptf)
Tom Sepezba038bc2015-10-08 12:03:00 -07001535FX_BOOL CJS_PublicMethods::AFTime_Format(IJS_Context* cc,
Lei Zhang945fdb72015-11-11 10:18:16 -08001536 const std::vector<CJS_Value>& params,
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001537 CJS_Value& vRet,
1538 CFX_WideString& sError) {
Tom Sepez67fd5df2015-10-08 12:24:19 -07001539 CJS_Context* pContext = (CJS_Context*)cc;
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001540 if (params.size() != 1) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001541 sError = JSGetStringFromID(pContext, IDS_STRING_JSPARAMERROR);
1542 return FALSE;
1543 }
1544
1545 int iIndex = params[0].ToInt();
1546 const FX_WCHAR* cFormats[] = {L"HH:MM", L"h:MM tt", L"HH:MM:ss",
1547 L"h:MM:ss tt"};
1548
Lei Zhanga0f67242015-08-17 15:39:30 -07001549 if (iIndex < 0 || (static_cast<size_t>(iIndex) >= FX_ArraySize(cFormats)))
1550 iIndex = 0;
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001551
Lei Zhang945fdb72015-11-11 10:18:16 -08001552 std::vector<CJS_Value> newParams;
Tom Sepez67fd5df2015-10-08 12:24:19 -07001553 newParams.push_back(
1554 CJS_Value(CJS_Runtime::FromContext(cc), cFormats[iIndex]));
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001555 return AFDate_FormatEx(cc, newParams, vRet, sError);
1556}
1557
Lei Zhang945fdb72015-11-11 10:18:16 -08001558FX_BOOL CJS_PublicMethods::AFTime_Keystroke(
1559 IJS_Context* cc,
1560 const std::vector<CJS_Value>& params,
1561 CJS_Value& vRet,
1562 CFX_WideString& sError) {
Tom Sepez67fd5df2015-10-08 12:24:19 -07001563 CJS_Context* pContext = (CJS_Context*)cc;
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001564 if (params.size() != 1) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001565 sError = JSGetStringFromID(pContext, IDS_STRING_JSPARAMERROR);
1566 return FALSE;
1567 }
1568
1569 int iIndex = params[0].ToInt();
1570 const FX_WCHAR* cFormats[] = {L"HH:MM", L"h:MM tt", L"HH:MM:ss",
1571 L"h:MM:ss tt"};
1572
Lei Zhanga0f67242015-08-17 15:39:30 -07001573 if (iIndex < 0 || (static_cast<size_t>(iIndex) >= FX_ArraySize(cFormats)))
1574 iIndex = 0;
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001575
Lei Zhang945fdb72015-11-11 10:18:16 -08001576 std::vector<CJS_Value> newParams;
Tom Sepez67fd5df2015-10-08 12:24:19 -07001577 newParams.push_back(
1578 CJS_Value(CJS_Runtime::FromContext(cc), cFormats[iIndex]));
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001579 return AFDate_KeystrokeEx(cc, newParams, vRet, sError);
1580}
1581
Tom Sepezba038bc2015-10-08 12:03:00 -07001582FX_BOOL CJS_PublicMethods::AFTime_FormatEx(IJS_Context* cc,
Lei Zhang945fdb72015-11-11 10:18:16 -08001583 const std::vector<CJS_Value>& params,
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001584 CJS_Value& vRet,
1585 CFX_WideString& sError) {
1586 return AFDate_FormatEx(cc, params, vRet, sError);
1587}
1588
Lei Zhang945fdb72015-11-11 10:18:16 -08001589FX_BOOL CJS_PublicMethods::AFTime_KeystrokeEx(
1590 IJS_Context* cc,
1591 const std::vector<CJS_Value>& params,
1592 CJS_Value& vRet,
1593 CFX_WideString& sError) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001594 return AFDate_KeystrokeEx(cc, params, vRet, sError);
1595}
1596
1597// function AFSpecial_Format(psf)
Lei Zhang945fdb72015-11-11 10:18:16 -08001598FX_BOOL CJS_PublicMethods::AFSpecial_Format(
1599 IJS_Context* cc,
1600 const std::vector<CJS_Value>& params,
1601 CJS_Value& vRet,
1602 CFX_WideString& sError) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001603 CJS_Context* pContext = (CJS_Context*)cc;
1604 ASSERT(pContext != NULL);
1605
1606 if (params.size() != 1) {
1607 sError = JSGetStringFromID(pContext, IDS_STRING_JSPARAMERROR);
1608 return FALSE;
1609 }
1610
1611 std::string cFormat;
1612 int iIndex = params[0].ToInt();
1613
1614 CJS_EventHandler* pEvent = pContext->GetEventHandler();
1615 ASSERT(pEvent != NULL);
1616
1617 if (!pEvent->m_pValue)
1618 return FALSE;
1619 CFX_WideString& Value = pEvent->Value();
1620 std::string strSrc = CFX_ByteString::FromUnicode(Value).c_str();
1621
1622 switch (iIndex) {
Tom Sepez2f2ffec2015-07-23 14:42:09 -07001623 case 0:
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001624 cFormat = "99999";
1625 break;
Tom Sepez2f2ffec2015-07-23 14:42:09 -07001626 case 1:
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001627 cFormat = "99999-9999";
1628 break;
1629 case 2: {
1630 std::string NumberStr;
1631 util::printx("9999999999", strSrc, NumberStr);
1632 if (NumberStr.length() >= 10)
1633 cFormat = "(999) 999-9999";
1634 else
1635 cFormat = "999-9999";
1636 break;
1637 }
Tom Sepez2f2ffec2015-07-23 14:42:09 -07001638 case 3:
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001639 cFormat = "999-99-9999";
1640 break;
1641 }
1642
1643 std::string strDes;
1644 util::printx(cFormat, strSrc, strDes);
1645 Value = CFX_WideString::FromLocal(strDes.c_str());
1646 return TRUE;
1647}
1648
1649// function AFSpecial_KeystrokeEx(mask)
Lei Zhang945fdb72015-11-11 10:18:16 -08001650FX_BOOL CJS_PublicMethods::AFSpecial_KeystrokeEx(
1651 IJS_Context* cc,
1652 const std::vector<CJS_Value>& params,
1653 CJS_Value& vRet,
1654 CFX_WideString& sError) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001655 CJS_Context* pContext = (CJS_Context*)cc;
1656 ASSERT(pContext != NULL);
1657 CJS_EventHandler* pEvent = pContext->GetEventHandler();
1658
1659 ASSERT(pEvent != NULL);
1660
1661 if (params.size() < 1) {
1662 sError = JSGetStringFromID(pContext, IDS_STRING_JSPARAMERROR);
1663 return FALSE;
1664 }
1665
1666 if (!pEvent->m_pValue)
1667 return FALSE;
1668 CFX_WideString& valEvent = pEvent->Value();
1669
1670 CFX_WideString wstrMask = params[0].ToCFXWideString();
1671 if (wstrMask.IsEmpty())
1672 return TRUE;
1673
Lei Zhanga0f67242015-08-17 15:39:30 -07001674 const size_t wstrMaskLen = wstrMask.GetLength();
1675 const std::wstring wstrValue = valEvent.c_str();
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001676
1677 if (pEvent->WillCommit()) {
1678 if (wstrValue.empty())
1679 return TRUE;
Lei Zhanga0f67242015-08-17 15:39:30 -07001680 size_t iIndexMask = 0;
1681 for (const auto& w_Value : wstrValue) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001682 if (!maskSatisfied(w_Value, wstrMask[iIndexMask]))
Tom Sepez2f2ffec2015-07-23 14:42:09 -07001683 break;
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001684 iIndexMask++;
Tom Sepez2f2ffec2015-07-23 14:42:09 -07001685 }
Lei Zhanga6d9f0e2015-06-13 00:48:38 -07001686
Lei Zhanga0f67242015-08-17 15:39:30 -07001687 if (iIndexMask != wstrMaskLen ||
1688 (iIndexMask != wstrValue.size() && wstrMaskLen != 0)) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001689 Alert(
1690 pContext,
1691 JSGetStringFromID(pContext, IDS_STRING_JSAFNUMBER_KEYSTROKE).c_str());
1692 pEvent->Rc() = FALSE;
1693 }
Tom Sepez2f2ffec2015-07-23 14:42:09 -07001694 return TRUE;
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001695 }
1696
1697 CFX_WideString& wideChange = pEvent->Change();
1698 std::wstring wChange = wideChange.c_str();
1699 if (wChange.empty())
1700 return TRUE;
1701
1702 int iIndexMask = pEvent->SelStart();
1703
Lei Zhanga0f67242015-08-17 15:39:30 -07001704 size_t combined_len = wstrValue.length() + wChange.length() -
1705 (pEvent->SelEnd() - pEvent->SelStart());
1706 if (combined_len > wstrMaskLen) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001707 Alert(pContext,
1708 JSGetStringFromID(pContext, IDS_STRING_JSPARAM_TOOLONG).c_str());
1709 pEvent->Rc() = FALSE;
1710 return TRUE;
1711 }
1712
Lei Zhanga0f67242015-08-17 15:39:30 -07001713 if (iIndexMask >= wstrMaskLen && (!wChange.empty())) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001714 Alert(pContext,
1715 JSGetStringFromID(pContext, IDS_STRING_JSPARAM_TOOLONG).c_str());
1716 pEvent->Rc() = FALSE;
1717 return TRUE;
1718 }
1719
1720 for (std::wstring::iterator it = wChange.begin(); it != wChange.end(); it++) {
Lei Zhanga0f67242015-08-17 15:39:30 -07001721 if (iIndexMask >= wstrMaskLen) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001722 Alert(pContext,
1723 JSGetStringFromID(pContext, IDS_STRING_JSPARAM_TOOLONG).c_str());
1724 pEvent->Rc() = FALSE;
1725 return TRUE;
1726 }
1727 wchar_t w_Mask = wstrMask[iIndexMask];
1728 if (!isReservedMaskChar(w_Mask)) {
1729 *it = w_Mask;
1730 }
1731 wchar_t w_Change = *it;
1732 if (!maskSatisfied(w_Change, w_Mask)) {
1733 pEvent->Rc() = FALSE;
1734 return TRUE;
1735 }
1736 iIndexMask++;
1737 }
1738
1739 wideChange = wChange.c_str();
1740 return TRUE;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07001741}
1742
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001743// function AFSpecial_Keystroke(psf)
Lei Zhang945fdb72015-11-11 10:18:16 -08001744FX_BOOL CJS_PublicMethods::AFSpecial_Keystroke(
1745 IJS_Context* cc,
1746 const std::vector<CJS_Value>& params,
1747 CJS_Value& vRet,
1748 CFX_WideString& sError) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001749 CJS_Context* pContext = (CJS_Context*)cc;
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001750 if (params.size() != 1) {
1751 sError = JSGetStringFromID(pContext, IDS_STRING_JSPARAMERROR);
1752 return FALSE;
1753 }
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07001754
Tom Sepez67fd5df2015-10-08 12:24:19 -07001755 CJS_EventHandler* pEvent = pContext->GetEventHandler();
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001756 if (!pEvent->m_pValue)
1757 return FALSE;
Tom Sepez67fd5df2015-10-08 12:24:19 -07001758
1759 std::string cFormat;
1760 int iIndex = params[0].ToInt();
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001761 CFX_WideString& val = pEvent->Value();
1762 std::string strSrc = CFX_ByteString::FromUnicode(val).c_str();
1763 std::wstring wstrChange = pEvent->Change().c_str();
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07001764
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001765 switch (iIndex) {
Tom Sepez2f2ffec2015-07-23 14:42:09 -07001766 case 0:
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001767 cFormat = "99999";
1768 break;
Tom Sepez2f2ffec2015-07-23 14:42:09 -07001769 case 1:
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001770 // cFormat = "99999-9999";
1771 cFormat = "999999999";
1772 break;
1773 case 2: {
1774 std::string NumberStr;
1775 util::printx("9999999999", strSrc, NumberStr);
1776 if (strSrc.length() + wstrChange.length() > 7)
1777 // cFormat = "(999) 999-9999";
1778 cFormat = "9999999999";
1779 else
1780 // cFormat = "999-9999";
1781 cFormat = "9999999";
1782 break;
1783 }
Tom Sepez2f2ffec2015-07-23 14:42:09 -07001784 case 3:
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001785 // cFormat = "999-99-9999";
1786 cFormat = "999999999";
1787 break;
1788 }
Lei Zhanga6d9f0e2015-06-13 00:48:38 -07001789
Lei Zhang945fdb72015-11-11 10:18:16 -08001790 std::vector<CJS_Value> params2;
Tom Sepez67fd5df2015-10-08 12:24:19 -07001791 params2.push_back(CJS_Value(CJS_Runtime::FromContext(cc), cFormat.c_str()));
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001792 return AFSpecial_KeystrokeEx(cc, params2, vRet, sError);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07001793}
1794
Tom Sepezba038bc2015-10-08 12:03:00 -07001795FX_BOOL CJS_PublicMethods::AFMergeChange(IJS_Context* cc,
Lei Zhang945fdb72015-11-11 10:18:16 -08001796 const std::vector<CJS_Value>& params,
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001797 CJS_Value& vRet,
1798 CFX_WideString& sError) {
1799 CJS_Context* pContext = (CJS_Context*)cc;
1800 ASSERT(pContext != NULL);
1801 CJS_EventHandler* pEventHandler = pContext->GetEventHandler();
1802 ASSERT(pEventHandler != NULL);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07001803
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001804 if (params.size() != 1) {
1805 sError = JSGetStringFromID(pContext, IDS_STRING_JSPARAMERROR);
1806 return FALSE;
1807 }
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07001808
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001809 CFX_WideString swValue;
Lei Zhang997de612015-11-04 18:17:53 -08001810 if (pEventHandler->m_pValue)
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001811 swValue = pEventHandler->Value();
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07001812
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001813 if (pEventHandler->WillCommit()) {
1814 vRet = swValue.c_str();
Tom Sepez2f2ffec2015-07-23 14:42:09 -07001815 return TRUE;
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001816 }
1817
1818 CFX_WideString prefix, postfix;
1819
1820 if (pEventHandler->SelStart() >= 0)
1821 prefix = swValue.Mid(0, pEventHandler->SelStart());
1822 else
1823 prefix = L"";
1824
1825 if (pEventHandler->SelEnd() >= 0 &&
1826 pEventHandler->SelEnd() <= swValue.GetLength())
1827 postfix = swValue.Mid(pEventHandler->SelEnd(),
1828 swValue.GetLength() - pEventHandler->SelEnd());
1829 else
1830 postfix = L"";
1831
1832 vRet = (prefix + pEventHandler->Change() + postfix).c_str();
1833
1834 return TRUE;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07001835}
1836
Tom Sepezba038bc2015-10-08 12:03:00 -07001837FX_BOOL CJS_PublicMethods::AFParseDateEx(IJS_Context* cc,
Lei Zhang945fdb72015-11-11 10:18:16 -08001838 const std::vector<CJS_Value>& params,
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001839 CJS_Value& vRet,
1840 CFX_WideString& sError) {
1841 CJS_Context* pContext = (CJS_Context*)cc;
1842 ASSERT(pContext != NULL);
1843
1844 if (params.size() != 2) {
1845 sError = JSGetStringFromID(pContext, IDS_STRING_JSPARAMERROR);
1846 return FALSE;
1847 }
1848
1849 CFX_WideString sValue = params[0].ToCFXWideString();
1850 CFX_WideString sFormat = params[1].ToCFXWideString();
1851
1852 FX_BOOL bWrongFormat = FALSE;
1853 double dDate = MakeRegularDate(sValue, sFormat, bWrongFormat);
1854
1855 if (JS_PortIsNan(dDate)) {
1856 CFX_WideString swMsg;
1857 swMsg.Format(JSGetStringFromID(pContext, IDS_STRING_JSPARSEDATE).c_str(),
1858 sFormat.c_str());
1859 Alert((CJS_Context*)cc, swMsg.c_str());
1860 return FALSE;
1861 }
1862
1863 vRet = dDate;
1864 return TRUE;
1865}
1866
Tom Sepezba038bc2015-10-08 12:03:00 -07001867FX_BOOL CJS_PublicMethods::AFSimple(IJS_Context* cc,
Lei Zhang945fdb72015-11-11 10:18:16 -08001868 const std::vector<CJS_Value>& params,
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001869 CJS_Value& vRet,
1870 CFX_WideString& sError) {
1871 if (params.size() != 3) {
1872 CJS_Context* pContext = (CJS_Context*)cc;
Tom Sepez2f2ffec2015-07-23 14:42:09 -07001873 ASSERT(pContext != NULL);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07001874
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001875 sError = JSGetStringFromID(pContext, IDS_STRING_JSPARAMERROR);
1876 return FALSE;
1877 }
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07001878
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001879 vRet = (double)AF_Simple(params[0].ToCFXWideString().c_str(),
1880 params[1].ToDouble(), params[2].ToDouble());
1881 return TRUE;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07001882}
1883
Tom Sepezba038bc2015-10-08 12:03:00 -07001884FX_BOOL CJS_PublicMethods::AFMakeNumber(IJS_Context* cc,
Lei Zhang945fdb72015-11-11 10:18:16 -08001885 const std::vector<CJS_Value>& params,
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001886 CJS_Value& vRet,
1887 CFX_WideString& sError) {
1888 if (params.size() != 1) {
1889 CJS_Context* pContext = (CJS_Context*)cc;
Tom Sepez2f2ffec2015-07-23 14:42:09 -07001890 ASSERT(pContext != NULL);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07001891
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001892 sError = JSGetStringFromID(pContext, IDS_STRING_JSPARAMERROR);
1893 return FALSE;
1894 }
1895 vRet = ParseStringToNumber(params[0].ToCFXWideString().c_str());
1896 return TRUE;
1897}
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07001898
Lei Zhang945fdb72015-11-11 10:18:16 -08001899FX_BOOL CJS_PublicMethods::AFSimple_Calculate(
1900 IJS_Context* cc,
1901 const std::vector<CJS_Value>& params,
1902 CJS_Value& vRet,
1903 CFX_WideString& sError) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001904 CJS_Context* pContext = (CJS_Context*)cc;
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001905 if (params.size() != 2) {
1906 sError = JSGetStringFromID(pContext, IDS_STRING_JSPARAMERROR);
1907 return FALSE;
1908 }
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07001909
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001910 CJS_Value params1 = params[1];
Tom Sepez39bfe122015-09-17 15:25:23 -07001911 if (!params1.IsArrayObject() && params1.GetType() != CJS_Value::VT_string) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001912 sError = JSGetStringFromID(pContext, IDS_STRING_JSPARAMERROR);
1913 return FALSE;
1914 }
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07001915
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001916 CPDFSDK_Document* pReaderDoc = pContext->GetReaderDocument();
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001917 CPDFSDK_InterForm* pReaderInterForm = pReaderDoc->GetInterForm();
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001918 CPDF_InterForm* pInterForm = pReaderInterForm->GetInterForm();
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07001919
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001920 CFX_WideString sFunction = params[0].ToCFXWideString();
Tom Sepez67fd5df2015-10-08 12:24:19 -07001921 double dValue = wcscmp(sFunction.c_str(), L"PRD") == 0 ? 1.0 : 0.0;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07001922
Tom Sepez67fd5df2015-10-08 12:24:19 -07001923 CJS_Runtime* pRuntime = CJS_Runtime::FromContext(cc);
1924 CJS_Array FieldNameArray = AF_MakeArrayFromList(pRuntime, params1);
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001925 int nFieldsCount = 0;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07001926
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001927 for (int i = 0, isz = FieldNameArray.GetLength(); i < isz; i++) {
Tom Sepez67fd5df2015-10-08 12:24:19 -07001928 CJS_Value jsValue(pRuntime);
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001929 FieldNameArray.GetElement(i, jsValue);
1930 CFX_WideString wsFieldName = jsValue.ToCFXWideString();
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07001931
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001932 for (int j = 0, jsz = pInterForm->CountFields(wsFieldName); j < jsz; j++) {
1933 if (CPDF_FormField* pFormField = pInterForm->GetField(j, wsFieldName)) {
1934 double dTemp = 0.0;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07001935
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001936 switch (pFormField->GetFieldType()) {
1937 case FIELDTYPE_TEXTFIELD:
1938 case FIELDTYPE_COMBOBOX: {
1939 dTemp = ParseStringToNumber(pFormField->GetValue().c_str());
1940 break;
1941 }
1942 case FIELDTYPE_PUSHBUTTON: {
1943 dTemp = 0.0;
1944 break;
1945 }
1946 case FIELDTYPE_CHECKBOX:
1947 case FIELDTYPE_RADIOBUTTON: {
1948 dTemp = 0.0;
1949 for (int c = 0, csz = pFormField->CountControls(); c < csz; c++) {
1950 if (CPDF_FormControl* pFormCtrl = pFormField->GetControl(c)) {
1951 if (pFormCtrl->IsChecked()) {
1952 dTemp +=
1953 ParseStringToNumber(pFormCtrl->GetExportValue().c_str());
1954 break;
1955 } else
1956 continue;
1957 }
Tom Sepez2f2ffec2015-07-23 14:42:09 -07001958 }
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001959 break;
1960 }
1961 case FIELDTYPE_LISTBOX: {
1962 dTemp = 0.0;
1963 if (pFormField->CountSelectedItems() > 1)
1964 break;
1965 else {
1966 dTemp = ParseStringToNumber(pFormField->GetValue().c_str());
1967 break;
1968 }
1969 }
1970 default:
1971 break;
Tom Sepez2f2ffec2015-07-23 14:42:09 -07001972 }
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001973
1974 if (i == 0 && j == 0 && (wcscmp(sFunction.c_str(), L"MIN") == 0 ||
1975 wcscmp(sFunction.c_str(), L"MAX") == 0))
1976 dValue = dTemp;
1977
1978 dValue = AF_Simple(sFunction.c_str(), dValue, dTemp);
1979
1980 nFieldsCount++;
1981 }
Tom Sepez2f2ffec2015-07-23 14:42:09 -07001982 }
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001983 }
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07001984
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001985 if (wcscmp(sFunction.c_str(), L"AVG") == 0 && nFieldsCount > 0)
1986 dValue /= nFieldsCount;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07001987
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001988 dValue = (double)floor(dValue * FXSYS_pow((double)10, (double)6) + 0.49) /
1989 FXSYS_pow((double)10, (double)6);
Tom Sepez67fd5df2015-10-08 12:24:19 -07001990 CJS_Value jsValue(pRuntime, dValue);
foxit8b544ed2015-09-10 14:57:54 +08001991 if (pContext->GetEventHandler()->m_pValue)
1992 pContext->GetEventHandler()->Value() = jsValue.ToCFXWideString();
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07001993
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001994 return TRUE;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07001995}
1996
Lei Zhanga6d9f0e2015-06-13 00:48:38 -07001997/* This function validates the current event to ensure that its value is
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07001998** within the specified range. */
1999
Lei Zhang945fdb72015-11-11 10:18:16 -08002000FX_BOOL CJS_PublicMethods::AFRange_Validate(
2001 IJS_Context* cc,
2002 const std::vector<CJS_Value>& params,
2003 CJS_Value& vRet,
2004 CFX_WideString& sError) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -07002005 CJS_Context* pContext = (CJS_Context*)cc;
2006 ASSERT(pContext != NULL);
2007 CJS_EventHandler* pEvent = pContext->GetEventHandler();
2008 ASSERT(pEvent != NULL);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07002009
Nico Weber9d8ec5a2015-08-04 13:00:21 -07002010 if (params.size() != 4) {
2011 sError = JSGetStringFromID(pContext, IDS_STRING_JSPARAMERROR);
2012 return FALSE;
2013 }
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07002014
Nico Weber9d8ec5a2015-08-04 13:00:21 -07002015 if (!pEvent->m_pValue)
2016 return FALSE;
2017 if (pEvent->Value().IsEmpty())
Tom Sepez2f2ffec2015-07-23 14:42:09 -07002018 return TRUE;
Nico Weber9d8ec5a2015-08-04 13:00:21 -07002019 double dEentValue = atof(CFX_ByteString::FromUnicode(pEvent->Value()));
2020 FX_BOOL bGreaterThan = params[0].ToBool();
2021 double dGreaterThan = params[1].ToDouble();
2022 FX_BOOL bLessThan = params[2].ToBool();
2023 double dLessThan = params[3].ToDouble();
2024 CFX_WideString swMsg;
2025
2026 if (bGreaterThan && bLessThan) {
2027 if (dEentValue < dGreaterThan || dEentValue > dLessThan)
2028 swMsg.Format(JSGetStringFromID(pContext, IDS_STRING_JSRANGE1).c_str(),
2029 params[1].ToCFXWideString().c_str(),
2030 params[3].ToCFXWideString().c_str());
2031 } else if (bGreaterThan) {
2032 if (dEentValue < dGreaterThan)
2033 swMsg.Format(JSGetStringFromID(pContext, IDS_STRING_JSRANGE2).c_str(),
2034 params[1].ToCFXWideString().c_str());
2035 } else if (bLessThan) {
2036 if (dEentValue > dLessThan)
2037 swMsg.Format(JSGetStringFromID(pContext, IDS_STRING_JSRANGE3).c_str(),
2038 params[3].ToCFXWideString().c_str());
2039 }
2040
2041 if (!swMsg.IsEmpty()) {
2042 Alert(pContext, swMsg.c_str());
2043 pEvent->Rc() = FALSE;
2044 }
2045 return TRUE;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07002046}
2047
Tom Sepezba038bc2015-10-08 12:03:00 -07002048FX_BOOL CJS_PublicMethods::AFExtractNums(IJS_Context* cc,
Lei Zhang945fdb72015-11-11 10:18:16 -08002049 const std::vector<CJS_Value>& params,
Nico Weber9d8ec5a2015-08-04 13:00:21 -07002050 CJS_Value& vRet,
2051 CFX_WideString& sError) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -07002052 CJS_Context* pContext = (CJS_Context*)cc;
Nico Weber9d8ec5a2015-08-04 13:00:21 -07002053 if (params.size() != 1) {
2054 sError = JSGetStringFromID(pContext, IDS_STRING_JSPARAMERROR);
2055 return FALSE;
2056 }
2057
Tom Sepez67fd5df2015-10-08 12:24:19 -07002058 CJS_Runtime* pRuntime = CJS_Runtime::FromContext(cc);
2059 CJS_Array nums(pRuntime);
Nico Weber9d8ec5a2015-08-04 13:00:21 -07002060
2061 CFX_WideString str = params[0].ToCFXWideString();
2062 CFX_WideString sPart;
2063
2064 if (str.GetAt(0) == L'.' || str.GetAt(0) == L',')
2065 str = L"0" + str;
2066
2067 int nIndex = 0;
2068 for (int i = 0, sz = str.GetLength(); i < sz; i++) {
2069 FX_WCHAR wc = str.GetAt(i);
2070 if (IsDigit((wchar_t)wc)) {
2071 sPart += wc;
2072 } else {
2073 if (sPart.GetLength() > 0) {
Tom Sepez67fd5df2015-10-08 12:24:19 -07002074 nums.SetElement(nIndex, CJS_Value(pRuntime, sPart.c_str()));
Nico Weber9d8ec5a2015-08-04 13:00:21 -07002075 sPart = L"";
2076 nIndex++;
2077 }
Tom Sepez2f2ffec2015-07-23 14:42:09 -07002078 }
Nico Weber9d8ec5a2015-08-04 13:00:21 -07002079 }
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07002080
Nico Weber9d8ec5a2015-08-04 13:00:21 -07002081 if (sPart.GetLength() > 0) {
Tom Sepez67fd5df2015-10-08 12:24:19 -07002082 nums.SetElement(nIndex, CJS_Value(pRuntime, sPart.c_str()));
Nico Weber9d8ec5a2015-08-04 13:00:21 -07002083 }
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07002084
Nico Weber9d8ec5a2015-08-04 13:00:21 -07002085 if (nums.GetLength() > 0)
2086 vRet = nums;
2087 else
2088 vRet.SetNull();
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07002089
Nico Weber9d8ec5a2015-08-04 13:00:21 -07002090 return TRUE;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07002091}