blob: c2e15fb11634755c22216d924d43ca3e78f68b37 [file] [log] [blame]
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07001// Copyright 2014 PDFium Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
Lei Zhanga6d9f0e2015-06-13 00:48:38 -07004
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07005// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
6
Tom Sepez37458412015-10-06 11:33:46 -07007#include "PublicMethods.h"
8
Tom Sepez37458412015-10-06 11:33:46 -07009#include "Field.h"
10#include "JS_Context.h"
11#include "JS_Define.h"
12#include "JS_EventHandler.h"
13#include "JS_Object.h"
14#include "JS_Runtime.h"
15#include "JS_Value.h"
16#include "color.h"
Dan Sinclair10cfea12015-11-16 13:09:00 -050017#include "core/include/fxcrt/fx_ext.h"
Lei Zhangbde53d22015-11-12 22:21:30 -080018#include "fpdfsdk/include/fsdk_mgr.h" // For CPDFDoc_Environment.
19#include "fpdfsdk/include/javascript/IJavaScript.h"
Tom Sepez37458412015-10-06 11:33:46 -070020#include "resource.h"
21#include "util.h"
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -070022
Nico Weber9d8ec5a2015-08-04 13:00:21 -070023#define DOUBLE_CORRECT 0.000000000000001
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -070024
25BEGIN_JS_STATIC_GLOBAL_FUN(CJS_PublicMethods)
Nico Weber9d8ec5a2015-08-04 13:00:21 -070026JS_STATIC_GLOBAL_FUN_ENTRY(AFNumber_Format)
27JS_STATIC_GLOBAL_FUN_ENTRY(AFNumber_Keystroke)
28JS_STATIC_GLOBAL_FUN_ENTRY(AFPercent_Format)
29JS_STATIC_GLOBAL_FUN_ENTRY(AFPercent_Keystroke)
30JS_STATIC_GLOBAL_FUN_ENTRY(AFDate_FormatEx)
31JS_STATIC_GLOBAL_FUN_ENTRY(AFDate_KeystrokeEx)
32JS_STATIC_GLOBAL_FUN_ENTRY(AFDate_Format)
33JS_STATIC_GLOBAL_FUN_ENTRY(AFDate_Keystroke)
34JS_STATIC_GLOBAL_FUN_ENTRY(AFTime_FormatEx)
35JS_STATIC_GLOBAL_FUN_ENTRY(AFTime_KeystrokeEx)
36JS_STATIC_GLOBAL_FUN_ENTRY(AFTime_Format)
37JS_STATIC_GLOBAL_FUN_ENTRY(AFTime_Keystroke)
38JS_STATIC_GLOBAL_FUN_ENTRY(AFSpecial_Format)
39JS_STATIC_GLOBAL_FUN_ENTRY(AFSpecial_Keystroke)
40JS_STATIC_GLOBAL_FUN_ENTRY(AFSpecial_KeystrokeEx)
41JS_STATIC_GLOBAL_FUN_ENTRY(AFSimple)
42JS_STATIC_GLOBAL_FUN_ENTRY(AFMakeNumber)
43JS_STATIC_GLOBAL_FUN_ENTRY(AFSimple_Calculate)
44JS_STATIC_GLOBAL_FUN_ENTRY(AFRange_Validate)
45JS_STATIC_GLOBAL_FUN_ENTRY(AFMergeChange)
46JS_STATIC_GLOBAL_FUN_ENTRY(AFParseDateEx)
47JS_STATIC_GLOBAL_FUN_ENTRY(AFExtractNums)
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -070048END_JS_STATIC_GLOBAL_FUN()
49
50IMPLEMENT_JS_STATIC_GLOBAL_FUN(CJS_PublicMethods)
51
Tom Sepezdfbf8e72015-10-14 14:17:26 -070052static const FX_WCHAR* const months[] = {L"Jan",
53 L"Feb",
54 L"Mar",
55 L"Apr",
56 L"May",
57 L"Jun",
58 L"Jul",
59 L"Aug",
60 L"Sep",
61 L"Oct",
62 L"Nov",
63 L"Dec"};
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -070064
Tom Sepezc7e4c4f2015-11-20 09:45:24 -080065static const FX_WCHAR* const fullmonths[] = {L"January",
66 L"February",
67 L"March",
68 L"April",
69 L"May",
70 L"June",
71 L"July",
72 L"August",
73 L"September",
74 L"October",
75 L"November",
76 L"December"};
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -070077
Nico Weber9d8ec5a2015-08-04 13:00:21 -070078FX_BOOL CJS_PublicMethods::IsNumber(const FX_WCHAR* string) {
79 CFX_WideString sTrim = StrTrim(string);
80 const FX_WCHAR* pTrim = sTrim.c_str();
81 const FX_WCHAR* p = pTrim;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -070082
Nico Weber9d8ec5a2015-08-04 13:00:21 -070083 FX_BOOL bDot = FALSE;
84 FX_BOOL bKXJS = FALSE;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -070085
Nico Weber9d8ec5a2015-08-04 13:00:21 -070086 wchar_t c;
87 while ((c = *p)) {
88 if (c == '.' || c == ',') {
89 if (bDot)
90 return FALSE;
91 bDot = TRUE;
92 } else if (c == '-' || c == '+') {
93 if (p != pTrim)
94 return FALSE;
95 } else if (c == 'e' || c == 'E') {
96 if (bKXJS)
97 return FALSE;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -070098
Nico Weber9d8ec5a2015-08-04 13:00:21 -070099 p++;
100 c = *p;
101 if (c == '+' || c == '-') {
102 bKXJS = TRUE;
103 } else {
104 return FALSE;
105 }
106 } else if (!IsDigit(c)) {
107 return FALSE;
108 }
109 p++;
110 }
111
112 return TRUE;
113}
114
115FX_BOOL CJS_PublicMethods::IsDigit(wchar_t ch) {
116 return (ch >= L'0' && ch <= L'9');
117}
118
119FX_BOOL CJS_PublicMethods::IsDigit(char ch) {
Dan Sinclair10cfea12015-11-16 13:09:00 -0500120 return std::isdigit(ch);
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700121}
122
123FX_BOOL CJS_PublicMethods::IsAlphabetic(wchar_t ch) {
124 return ((ch >= L'a' && ch <= L'z') || (ch >= L'A' && ch <= L'Z'));
125}
126
127FX_BOOL CJS_PublicMethods::IsAlphaNumeric(wchar_t ch) {
128 return (IsDigit(ch) || IsAlphabetic(ch));
129}
130
131FX_BOOL CJS_PublicMethods::maskSatisfied(wchar_t c_Change, wchar_t c_Mask) {
132 switch (c_Mask) {
133 case L'9':
134 return IsDigit(c_Change);
135 case L'A':
136 return IsAlphabetic(c_Change);
137 case L'O':
138 return IsAlphaNumeric(c_Change);
139 case L'X':
140 return TRUE;
141 default:
142 return (c_Change == c_Mask);
143 }
144}
145
146FX_BOOL CJS_PublicMethods::isReservedMaskChar(wchar_t ch) {
147 return ch == L'9' || ch == L'A' || ch == L'O' || ch == L'X';
148}
149
150double CJS_PublicMethods::AF_Simple(const FX_WCHAR* sFuction,
151 double dValue1,
152 double dValue2) {
153 if (FXSYS_wcsicmp(sFuction, L"AVG") == 0 ||
154 FXSYS_wcsicmp(sFuction, L"SUM") == 0) {
155 return dValue1 + dValue2;
156 }
157 if (FXSYS_wcsicmp(sFuction, L"PRD") == 0) {
158 return dValue1 * dValue2;
159 }
160 if (FXSYS_wcsicmp(sFuction, L"MIN") == 0) {
161 return FX_MIN(dValue1, dValue2);
162 }
163 if (FXSYS_wcsicmp(sFuction, L"MAX") == 0) {
164 return FX_MAX(dValue1, dValue2);
165 }
166 return dValue1;
167}
168
169CFX_WideString CJS_PublicMethods::StrLTrim(const FX_WCHAR* pStr) {
170 while (*pStr && *pStr == L' ')
171 pStr++;
172
173 return pStr;
174}
175
176CFX_WideString CJS_PublicMethods::StrRTrim(const FX_WCHAR* pStr) {
177 const FX_WCHAR* p = pStr;
178 while (*p)
179 p++;
180 while (p > pStr && *(p - 1) == L' ')
181 p--;
182
183 return CFX_WideString(pStr, p - pStr);
184}
185
186CFX_WideString CJS_PublicMethods::StrTrim(const FX_WCHAR* pStr) {
187 return StrRTrim(StrLTrim(pStr).c_str());
188}
189
190CFX_ByteString CJS_PublicMethods::StrLTrim(const FX_CHAR* pStr) {
191 while (*pStr && *pStr == ' ')
192 pStr++;
193
194 return pStr;
195}
196
197CFX_ByteString CJS_PublicMethods::StrRTrim(const FX_CHAR* pStr) {
198 const FX_CHAR* p = pStr;
199 while (*p)
200 p++;
201 while (p > pStr && *(p - 1) == L' ')
202 p--;
203
204 return CFX_ByteString(pStr, p - pStr);
205}
206
207CFX_ByteString CJS_PublicMethods::StrTrim(const FX_CHAR* pStr) {
208 return StrRTrim(StrLTrim(pStr));
209}
210
211double CJS_PublicMethods::ParseNumber(const FX_WCHAR* swSource,
212 FX_BOOL& bAllDigits,
213 FX_BOOL& bDot,
214 FX_BOOL& bSign,
215 FX_BOOL& bKXJS) {
216 bDot = FALSE;
217 bSign = FALSE;
218 bKXJS = FALSE;
219
220 FX_BOOL bDigitExist = FALSE;
221
222 const FX_WCHAR* p = swSource;
223 wchar_t c;
224
225 const FX_WCHAR* pStart = NULL;
226 const FX_WCHAR* pEnd = NULL;
227
228 while ((c = *p)) {
229 if (!pStart && c != L' ') {
230 pStart = p;
231 }
232
233 pEnd = p;
234 p++;
235 }
236
237 if (!pStart) {
238 bAllDigits = FALSE;
239 return 0;
240 }
241
242 while (pEnd != pStart) {
243 if (*pEnd == L' ')
244 pEnd--;
245 else
246 break;
247 }
248
249 double dRet = 0;
250 p = pStart;
251 bAllDigits = TRUE;
252 CFX_WideString swDigits;
253
254 while (p <= pEnd) {
255 c = *p;
256
257 if (IsDigit(c)) {
258 swDigits += c;
259 bDigitExist = TRUE;
260 } else {
261 switch (c) {
262 case L' ':
263 bAllDigits = FALSE;
264 break;
265 case L'.':
266 case L',':
267 if (!bDot) {
268 if (bDigitExist) {
269 swDigits += L'.';
270 } else {
271 swDigits += L'0';
272 swDigits += L'.';
273 bDigitExist = TRUE;
274 }
275
Tom Sepez2f2ffec2015-07-23 14:42:09 -0700276 bDot = TRUE;
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700277 break;
278 }
279 case 'e':
280 case 'E':
281 if (!bKXJS) {
Tom Sepez2f2ffec2015-07-23 14:42:09 -0700282 p++;
283 c = *p;
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700284 if (c == '+' || c == '-') {
285 bKXJS = TRUE;
286 swDigits += 'e';
287 swDigits += c;
Tom Sepez2f2ffec2015-07-23 14:42:09 -0700288 }
Tom Sepez2f2ffec2015-07-23 14:42:09 -0700289 break;
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700290 }
291 case L'-':
292 if (!bDigitExist && !bSign) {
Tom Sepez2f2ffec2015-07-23 14:42:09 -0700293 swDigits += c;
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700294 bSign = TRUE;
Tom Sepez2f2ffec2015-07-23 14:42:09 -0700295 break;
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700296 }
297 default:
298 bAllDigits = FALSE;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700299
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700300 if (p != pStart && !bDot && bDigitExist) {
301 swDigits += L'.';
302 bDot = TRUE;
303 } else {
304 bDot = FALSE;
305 bDigitExist = FALSE;
306 swDigits = L"";
307 }
308 break;
309 }
Tom Sepez2f2ffec2015-07-23 14:42:09 -0700310 }
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700311
312 p++;
313 }
314
315 if (swDigits.GetLength() > 0 && swDigits.GetLength() < 17) {
316 CFX_ByteString sDigits = swDigits.UTF8Encode();
317
318 if (bKXJS) {
319 dRet = atof(sDigits);
320 } else {
321 if (bDot) {
322 char* pStopString;
323 dRet = ::strtod(sDigits, &pStopString);
324 } else {
325 dRet = atol(sDigits);
326 }
327 }
328 }
329
330 return dRet;
331}
332
333double CJS_PublicMethods::ParseStringToNumber(const FX_WCHAR* swSource) {
334 FX_BOOL bAllDigits = FALSE;
335 FX_BOOL bDot = FALSE;
336 FX_BOOL bSign = FALSE;
337 FX_BOOL bKXJS = FALSE;
338
339 return ParseNumber(swSource, bAllDigits, bDot, bSign, bKXJS);
340}
341
342FX_BOOL CJS_PublicMethods::ConvertStringToNumber(const FX_WCHAR* swSource,
343 double& dRet,
344 FX_BOOL& bDot) {
345 FX_BOOL bAllDigits = FALSE;
346 FX_BOOL bSign = FALSE;
347 FX_BOOL bKXJS = FALSE;
348
349 dRet = ParseNumber(swSource, bAllDigits, bDot, bSign, bKXJS);
350
351 return bAllDigits;
352}
353
Tom Sepez67fd5df2015-10-08 12:24:19 -0700354CJS_Array CJS_PublicMethods::AF_MakeArrayFromList(CJS_Runtime* pRuntime,
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700355 CJS_Value val) {
Tom Sepez67fd5df2015-10-08 12:24:19 -0700356 CJS_Array StrArray(pRuntime);
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700357 if (val.IsArrayObject()) {
358 val.ConvertToArray(StrArray);
Tom Sepez2f2ffec2015-07-23 14:42:09 -0700359 return StrArray;
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700360 }
361 CFX_WideString wsStr = val.ToCFXWideString();
362 CFX_ByteString t = CFX_ByteString::FromUnicode(wsStr);
363 const char* p = (const char*)t;
364
365 int ch = ',';
366 int nIndex = 0;
367
368 while (*p) {
369 const char* pTemp = strchr(p, ch);
Lei Zhang997de612015-11-04 18:17:53 -0800370 if (!pTemp) {
Tom Sepez67fd5df2015-10-08 12:24:19 -0700371 StrArray.SetElement(nIndex, CJS_Value(pRuntime, StrTrim(p).c_str()));
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700372 break;
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700373 }
Lei Zhang997de612015-11-04 18:17:53 -0800374
375 char* pSub = new char[pTemp - p + 1];
376 strncpy(pSub, p, pTemp - p);
377 *(pSub + (pTemp - p)) = '\0';
378
379 StrArray.SetElement(nIndex, CJS_Value(pRuntime, StrTrim(pSub).c_str()));
380 delete[] pSub;
381
382 nIndex++;
383 p = ++pTemp;
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700384 }
385 return StrArray;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700386}
387
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700388int CJS_PublicMethods::ParseStringInteger(const CFX_WideString& string,
389 int nStart,
390 int& nSkip,
391 int nMaxStep) {
392 int nRet = 0;
393 nSkip = 0;
394 for (int i = nStart, sz = string.GetLength(); i < sz; i++) {
395 if (i - nStart > 10)
396 break;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700397
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700398 FX_WCHAR c = string.GetAt(i);
399 if (IsDigit((wchar_t)c)) {
Dan Sinclair10cfea12015-11-16 13:09:00 -0500400 nRet = nRet * 10 + FXSYS_toDecimalDigitWide(c);
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700401 nSkip = i - nStart + 1;
402 if (nSkip >= nMaxStep)
403 break;
404 } else
405 break;
406 }
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700407
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700408 return nRet;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700409}
410
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700411CFX_WideString CJS_PublicMethods::ParseStringString(
412 const CFX_WideString& string,
413 int nStart,
414 int& nSkip) {
415 CFX_WideString swRet;
416 nSkip = 0;
417 for (int i = nStart, sz = string.GetLength(); i < sz; i++) {
418 FX_WCHAR c = string.GetAt(i);
419 if ((c >= L'a' && c <= L'z') || (c >= L'A' && c <= L'Z')) {
420 swRet += c;
421 nSkip = i - nStart + 1;
422 } else
423 break;
424 }
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700425
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700426 return swRet;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700427}
428
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700429double CJS_PublicMethods::ParseNormalDate(const CFX_WideString& value,
430 FX_BOOL& bWrongFormat) {
431 double dt = JS_GetDateTime();
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700432
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700433 int nYear = JS_GetYearFromTime(dt);
434 int nMonth = JS_GetMonthFromTime(dt) + 1;
435 int nDay = JS_GetDayFromTime(dt);
436 int nHour = JS_GetHourFromTime(dt);
437 int nMin = JS_GetMinFromTime(dt);
438 int nSec = JS_GetSecFromTime(dt);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700439
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700440 int number[3];
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700441
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700442 int nSkip = 0;
443 int nLen = value.GetLength();
444 int nIndex = 0;
445 int i = 0;
446 while (i < nLen) {
447 if (nIndex > 2)
448 break;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700449
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700450 FX_WCHAR c = value.GetAt(i);
451 if (IsDigit((wchar_t)c)) {
452 number[nIndex++] = ParseStringInteger(value, i, nSkip, 4);
453 i += nSkip;
454 } else {
455 i++;
456 }
457 }
458
459 if (nIndex == 2) {
460 // case2: month/day
461 // case3: day/month
462 if ((number[0] >= 1 && number[0] <= 12) &&
463 (number[1] >= 1 && number[1] <= 31)) {
464 nMonth = number[0];
465 nDay = number[1];
466 } else if ((number[0] >= 1 && number[0] <= 31) &&
467 (number[1] >= 1 && number[1] <= 12)) {
468 nDay = number[0];
469 nMonth = number[1];
Tom Sepez2f2ffec2015-07-23 14:42:09 -0700470 }
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700471
Tom Sepez2f2ffec2015-07-23 14:42:09 -0700472 bWrongFormat = FALSE;
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700473 } else if (nIndex == 3) {
474 // case1: year/month/day
475 // case2: month/day/year
476 // case3: day/month/year
Tom Sepez5ffacd62014-07-18 14:42:12 -0700477
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700478 if (number[0] > 12 && (number[1] >= 1 && number[1] <= 12) &&
479 (number[2] >= 1 && number[2] <= 31)) {
480 nYear = number[0];
481 nMonth = number[1];
482 nDay = number[2];
483 } else if ((number[0] >= 1 && number[0] <= 12) &&
484 (number[1] >= 1 && number[1] <= 31) && number[2] > 31) {
485 nMonth = number[0];
486 nDay = number[1];
487 nYear = number[2];
488 } else if ((number[0] >= 1 && number[0] <= 31) &&
489 (number[1] >= 1 && number[1] <= 12) && number[2] > 31) {
490 nDay = number[0];
491 nMonth = number[1];
492 nYear = number[2];
Tom Sepez2f2ffec2015-07-23 14:42:09 -0700493 }
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700494
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700495 bWrongFormat = FALSE;
496 } else {
497 bWrongFormat = TRUE;
498 return dt;
499 }
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700500
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700501 CFX_WideString swTemp;
502 swTemp.Format(L"%d/%d/%d %d:%d:%d", nMonth, nDay, nYear, nHour, nMin, nSec);
503 return JS_DateParse(swTemp.c_str());
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700504}
505
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700506double CJS_PublicMethods::MakeRegularDate(const CFX_WideString& value,
507 const CFX_WideString& format,
508 FX_BOOL& bWrongFormat) {
509 double dt = JS_GetDateTime();
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700510
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700511 if (format.IsEmpty() || value.IsEmpty())
512 return dt;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700513
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700514 int nYear = JS_GetYearFromTime(dt);
515 int nMonth = JS_GetMonthFromTime(dt) + 1;
516 int nDay = JS_GetDayFromTime(dt);
517 int nHour = JS_GetHourFromTime(dt);
518 int nMin = JS_GetMinFromTime(dt);
519 int nSec = JS_GetSecFromTime(dt);
520
521 int nYearSub = 99; // nYear - 2000;
522
523 FX_BOOL bPm = FALSE;
524 FX_BOOL bExit = FALSE;
525 bWrongFormat = FALSE;
526
527 int i = 0;
528 int j = 0;
529
530 while (i < format.GetLength()) {
531 if (bExit)
532 break;
533
534 FX_WCHAR c = format.GetAt(i);
535 switch (c) {
536 case ':':
537 case '.':
538 case '-':
539 case '\\':
540 case '/':
541 i++;
542 j++;
543 break;
544
545 case 'y':
546 case 'm':
547 case 'd':
548 case 'H':
549 case 'h':
550 case 'M':
551 case 's':
552 case 't': {
553 int oldj = j;
554 int nSkip = 0;
555 int remaining = format.GetLength() - i - 1;
556
557 if (remaining == 0 || format.GetAt(i + 1) != c) {
558 switch (c) {
Tom Sepez2f2ffec2015-07-23 14:42:09 -0700559 case 'y':
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700560 i++;
561 j++;
562 break;
Tom Sepez2f2ffec2015-07-23 14:42:09 -0700563 case 'm':
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700564 nMonth = ParseStringInteger(value, j, nSkip, 2);
565 i++;
566 j += nSkip;
567 break;
Tom Sepez2f2ffec2015-07-23 14:42:09 -0700568 case 'd':
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700569 nDay = ParseStringInteger(value, j, nSkip, 2);
570 i++;
571 j += nSkip;
572 break;
Tom Sepez2f2ffec2015-07-23 14:42:09 -0700573 case 'H':
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700574 nHour = ParseStringInteger(value, j, nSkip, 2);
575 i++;
576 j += nSkip;
577 break;
Tom Sepez2f2ffec2015-07-23 14:42:09 -0700578 case 'h':
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700579 nHour = ParseStringInteger(value, j, nSkip, 2);
580 i++;
581 j += nSkip;
582 break;
Tom Sepez2f2ffec2015-07-23 14:42:09 -0700583 case 'M':
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700584 nMin = ParseStringInteger(value, j, nSkip, 2);
585 i++;
586 j += nSkip;
587 break;
Tom Sepez2f2ffec2015-07-23 14:42:09 -0700588 case 's':
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700589 nSec = ParseStringInteger(value, j, nSkip, 2);
590 i++;
591 j += nSkip;
592 break;
Tom Sepez2f2ffec2015-07-23 14:42:09 -0700593 case 't':
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700594 bPm = (j < value.GetLength() && value.GetAt(j) == 'p');
595 i++;
596 j++;
597 break;
598 }
599 } else if (remaining == 1 || format.GetAt(i + 2) != c) {
600 switch (c) {
601 case 'y':
602 nYear = ParseStringInteger(value, j, nSkip, 4);
603 i += 2;
604 j += nSkip;
605 break;
606 case 'm':
607 nMonth = ParseStringInteger(value, j, nSkip, 2);
608 i += 2;
609 j += nSkip;
610 break;
611 case 'd':
612 nDay = ParseStringInteger(value, j, nSkip, 2);
613 i += 2;
614 j += nSkip;
615 break;
616 case 'H':
617 nHour = ParseStringInteger(value, j, nSkip, 2);
618 i += 2;
619 j += nSkip;
620 break;
621 case 'h':
622 nHour = ParseStringInteger(value, j, nSkip, 2);
623 i += 2;
624 j += nSkip;
625 break;
626 case 'M':
627 nMin = ParseStringInteger(value, j, nSkip, 2);
628 i += 2;
629 j += nSkip;
630 break;
631 case 's':
632 nSec = ParseStringInteger(value, j, nSkip, 2);
633 i += 2;
634 j += nSkip;
635 break;
636 case 't':
637 bPm = (j + 1 < value.GetLength() && value.GetAt(j) == 'p' &&
638 value.GetAt(j + 1) == 'm');
639 i += 2;
640 j += 2;
641 break;
642 }
643 } else if (remaining == 2 || format.GetAt(i + 3) != c) {
644 switch (c) {
645 case 'm': {
646 CFX_WideString sMonth = ParseStringString(value, j, nSkip);
647 FX_BOOL bFind = FALSE;
648 for (int m = 0; m < 12; m++) {
649 if (sMonth.CompareNoCase(months[m]) == 0) {
650 nMonth = m + 1;
651 i += 3;
652 j += nSkip;
653 bFind = TRUE;
654 break;
Tom Sepez2f2ffec2015-07-23 14:42:09 -0700655 }
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700656 }
657
658 if (!bFind) {
659 nMonth = ParseStringInteger(value, j, nSkip, 3);
660 i += 3;
661 j += nSkip;
662 }
663 } break;
664 case 'y':
665 break;
Tom Sepez2f2ffec2015-07-23 14:42:09 -0700666 default:
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700667 i += 3;
668 j += 3;
669 break;
670 }
671 } else if (remaining == 3 || format.GetAt(i + 4) != c) {
672 switch (c) {
673 case 'y':
674 nYear = ParseStringInteger(value, j, nSkip, 4);
675 j += nSkip;
676 i += 4;
677 break;
678 case 'm': {
679 FX_BOOL bFind = FALSE;
680
681 CFX_WideString sMonth = ParseStringString(value, j, nSkip);
682 sMonth.MakeLower();
683
684 for (int m = 0; m < 12; m++) {
685 CFX_WideString sFullMonths = fullmonths[m];
686 sFullMonths.MakeLower();
687
688 if (sFullMonths.Find(sMonth.c_str(), 0) != -1) {
689 nMonth = m + 1;
690 i += 4;
691 j += nSkip;
692 bFind = TRUE;
693 break;
694 }
695 }
696
697 if (!bFind) {
698 nMonth = ParseStringInteger(value, j, nSkip, 4);
699 i += 4;
700 j += nSkip;
701 }
702 } break;
703 default:
704 i += 4;
705 j += 4;
706 break;
707 }
708 } else {
709 if (j >= value.GetLength() || format.GetAt(i) != value.GetAt(j)) {
710 bWrongFormat = TRUE;
711 bExit = TRUE;
712 }
713 i++;
714 j++;
Tom Sepez2f2ffec2015-07-23 14:42:09 -0700715 }
Tom Sepez85386422014-07-23 10:28:37 -0700716
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700717 if (oldj == j) {
718 bWrongFormat = TRUE;
719 bExit = TRUE;
720 }
721 }
722
723 break;
724 default:
725 if (value.GetLength() <= j) {
726 bExit = TRUE;
727 } else if (format.GetAt(i) != value.GetAt(j)) {
728 bWrongFormat = TRUE;
729 bExit = TRUE;
730 }
731
732 i++;
733 j++;
734 break;
735 }
736 }
737
738 if (bPm)
739 nHour += 12;
740
741 if (nYear >= 0 && nYear <= nYearSub)
742 nYear += 2000;
743
744 if (nMonth < 1 || nMonth > 12)
745 bWrongFormat = TRUE;
746
747 if (nDay < 1 || nDay > 31)
748 bWrongFormat = TRUE;
749
750 if (nHour < 0 || nHour > 24)
751 bWrongFormat = TRUE;
752
753 if (nMin < 0 || nMin > 60)
754 bWrongFormat = TRUE;
755
756 if (nSec < 0 || nSec > 60)
757 bWrongFormat = TRUE;
758
759 double dRet = 0;
760
761 if (bWrongFormat) {
762 dRet = ParseNormalDate(value, bWrongFormat);
763 } else {
764 dRet = JS_MakeDate(JS_MakeDay(nYear, nMonth - 1, nDay),
765 JS_MakeTime(nHour, nMin, nSec, 0));
766
767 if (JS_PortIsNan(dRet)) {
768 dRet = JS_DateParse(value.c_str());
769 }
770 }
771
772 if (JS_PortIsNan(dRet)) {
773 dRet = ParseNormalDate(value, bWrongFormat);
774 }
775
776 return dRet;
777}
778
779CFX_WideString CJS_PublicMethods::MakeFormatDate(double dDate,
780 const CFX_WideString& format) {
781 CFX_WideString sRet = L"", sPart = L"";
782
783 int nYear = JS_GetYearFromTime(dDate);
784 int nMonth = JS_GetMonthFromTime(dDate) + 1;
785 int nDay = JS_GetDayFromTime(dDate);
786 int nHour = JS_GetHourFromTime(dDate);
787 int nMin = JS_GetMinFromTime(dDate);
788 int nSec = JS_GetSecFromTime(dDate);
789
790 int i = 0;
791 while (i < format.GetLength()) {
792 FX_WCHAR c = format.GetAt(i);
793 int remaining = format.GetLength() - i - 1;
794 sPart = L"";
795 switch (c) {
796 case 'y':
797 case 'm':
798 case 'd':
799 case 'H':
800 case 'h':
801 case 'M':
802 case 's':
803 case 't':
804 if (remaining == 0 || format.GetAt(i + 1) != c) {
805 switch (c) {
806 case 'y':
807 sPart += c;
808 break;
809 case 'm':
810 sPart.Format(L"%d", nMonth);
811 break;
812 case 'd':
813 sPart.Format(L"%d", nDay);
814 break;
815 case 'H':
816 sPart.Format(L"%d", nHour);
817 break;
818 case 'h':
819 sPart.Format(L"%d", nHour > 12 ? nHour - 12 : nHour);
820 break;
821 case 'M':
822 sPart.Format(L"%d", nMin);
823 break;
824 case 's':
825 sPart.Format(L"%d", nSec);
826 break;
827 case 't':
828 sPart += nHour > 12 ? 'p' : 'a';
829 break;
830 }
831 i++;
832 } else if (remaining == 1 || format.GetAt(i + 2) != c) {
833 switch (c) {
834 case 'y':
835 sPart.Format(L"%02d", nYear - (nYear / 100) * 100);
836 break;
837 case 'm':
838 sPart.Format(L"%02d", nMonth);
839 break;
840 case 'd':
841 sPart.Format(L"%02d", nDay);
842 break;
843 case 'H':
844 sPart.Format(L"%02d", nHour);
845 break;
846 case 'h':
847 sPart.Format(L"%02d", nHour > 12 ? nHour - 12 : nHour);
848 break;
849 case 'M':
850 sPart.Format(L"%02d", nMin);
851 break;
852 case 's':
853 sPart.Format(L"%02d", nSec);
854 break;
855 case 't':
856 sPart = nHour > 12 ? L"pm" : L"am";
857 break;
858 }
859 i += 2;
860 } else if (remaining == 2 || format.GetAt(i + 3) != c) {
861 switch (c) {
862 case 'm':
863 i += 3;
864 if (nMonth > 0 && nMonth <= 12)
865 sPart += months[nMonth - 1];
866 break;
867 default:
868 i += 3;
869 sPart += c;
870 sPart += c;
871 sPart += c;
872 break;
873 }
874 } else if (remaining == 3 || format.GetAt(i + 4) != c) {
875 switch (c) {
876 case 'y':
877 sPart.Format(L"%04d", nYear);
878 i += 4;
879 break;
880 case 'm':
881 i += 4;
882 if (nMonth > 0 && nMonth <= 12)
883 sPart += fullmonths[nMonth - 1];
884 break;
885 default:
886 i += 4;
887 sPart += c;
888 sPart += c;
889 sPart += c;
890 sPart += c;
891 break;
892 }
893 } else {
894 i++;
895 sPart += c;
896 }
897 break;
898 default:
899 i++;
900 sPart += c;
901 break;
Tom Sepez2f2ffec2015-07-23 14:42:09 -0700902 }
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700903
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700904 sRet += sPart;
905 }
906
907 return sRet;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700908}
909
910/* -------------------------------------------------------------------------- */
911
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700912// function AFNumber_Format(nDec, sepStyle, negStyle, currStyle, strCurrency,
913// bCurrencyPrepend)
Tom Sepezba038bc2015-10-08 12:03:00 -0700914FX_BOOL CJS_PublicMethods::AFNumber_Format(IJS_Context* cc,
Lei Zhang945fdb72015-11-11 10:18:16 -0800915 const std::vector<CJS_Value>& params,
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700916 CJS_Value& vRet,
917 CFX_WideString& sError) {
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700918#if _FX_OS_ != _FX_ANDROID_
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700919 CJS_Context* pContext = (CJS_Context*)cc;
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700920 if (params.size() != 6) {
921 sError = JSGetStringFromID(pContext, IDS_STRING_JSPARAMERROR);
922 return FALSE;
923 }
Tom Sepez67fd5df2015-10-08 12:24:19 -0700924
925 CJS_Runtime* pRuntime = CJS_Runtime::FromContext(cc);
926 CJS_EventHandler* pEvent = pContext->GetEventHandler();
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700927 if (!pEvent->m_pValue)
928 return FALSE;
Tom Sepez67fd5df2015-10-08 12:24:19 -0700929
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700930 CFX_WideString& Value = pEvent->Value();
931 CFX_ByteString strValue = StrTrim(CFX_ByteString::FromUnicode(Value));
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700932 if (strValue.IsEmpty())
Tom Sepez2f2ffec2015-07-23 14:42:09 -0700933 return TRUE;
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700934
935 int iDec = params[0].ToInt();
936 int iSepStyle = params[1].ToInt();
937 int iNegStyle = params[2].ToInt();
938 // params[3] is iCurrStyle, it's not used.
939 std::wstring wstrCurrency(params[4].ToCFXWideString().c_str());
940 FX_BOOL bCurrencyPrepend = params[5].ToBool();
941
942 if (iDec < 0)
943 iDec = -iDec;
944
945 if (iSepStyle < 0 || iSepStyle > 3)
946 iSepStyle = 0;
947
948 if (iNegStyle < 0 || iNegStyle > 3)
949 iNegStyle = 0;
950
951 //////////////////////////////////////////////////////
952 // for processing decimal places
953 strValue.Replace(",", ".");
954 double dValue = atof(strValue);
955 if (iDec > 0)
Tom Sepezdfbf8e72015-10-14 14:17:26 -0700956 dValue += DOUBLE_CORRECT;
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700957
958 int iDec2;
959 int iNegative = 0;
960
961 strValue = fcvt(dValue, iDec, &iDec2, &iNegative);
962 if (strValue.IsEmpty()) {
963 dValue = 0;
964 strValue = fcvt(dValue, iDec, &iDec2, &iNegative);
965 if (strValue.IsEmpty()) {
966 strValue = "0";
967 iDec2 = 1;
968 }
969 }
970
971 if (iDec2 < 0) {
972 for (int iNum = 0; iNum < abs(iDec2); iNum++) {
973 strValue = "0" + strValue;
974 }
975 iDec2 = 0;
976 }
977 int iMax = strValue.GetLength();
978 if (iDec2 > iMax) {
979 for (int iNum = 0; iNum <= iDec2 - iMax; iNum++) {
980 strValue += "0";
981 }
982 iMax = iDec2 + 1;
983 }
984 ///////////////////////////////////////////////////////
985 // for processing seperator style
986 if (iDec2 < iMax) {
987 if (iSepStyle == 0 || iSepStyle == 1) {
988 strValue.Insert(iDec2, '.');
989 iMax++;
990 } else if (iSepStyle == 2 || iSepStyle == 3) {
991 strValue.Insert(iDec2, ',');
992 iMax++;
993 }
994
995 if (iDec2 == 0)
996 strValue.Insert(iDec2, '0');
997 }
998 if (iSepStyle == 0 || iSepStyle == 2) {
999 char cSeperator;
1000 if (iSepStyle == 0)
1001 cSeperator = ',';
1002 else
1003 cSeperator = '.';
1004
Tom Sepezdfbf8e72015-10-14 14:17:26 -07001005 for (int iDecPositive = iDec2 - 3; iDecPositive > 0; iDecPositive -= 3) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001006 strValue.Insert(iDecPositive, cSeperator);
1007 iMax++;
1008 }
1009 }
1010
1011 //////////////////////////////////////////////////////////////////////
1012 // for processing currency string
1013
1014 Value = CFX_WideString::FromLocal(strValue);
1015 std::wstring strValue2 = Value.c_str();
1016
1017 if (bCurrencyPrepend)
1018 strValue2 = wstrCurrency + strValue2;
1019 else
1020 strValue2 = strValue2 + wstrCurrency;
1021
1022 /////////////////////////////////////////////////////////////////////////
1023 // for processing negative style
1024 if (iNegative) {
1025 if (iNegStyle == 0) {
1026 strValue2.insert(0, L"-");
1027 }
1028 if (iNegStyle == 2 || iNegStyle == 3) {
1029 strValue2.insert(0, L"(");
1030 strValue2.insert(strValue2.length(), L")");
1031 }
1032 if (iNegStyle == 1 || iNegStyle == 3) {
1033 if (Field* fTarget = pEvent->Target_Field()) {
Tom Sepez67fd5df2015-10-08 12:24:19 -07001034 CJS_Array arColor(pRuntime);
1035 CJS_Value vColElm(pRuntime);
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001036 vColElm = L"RGB";
1037 arColor.SetElement(0, vColElm);
1038 vColElm = 1;
1039 arColor.SetElement(1, vColElm);
1040 vColElm = 0;
1041 arColor.SetElement(2, vColElm);
1042
1043 arColor.SetElement(3, vColElm);
1044
Tom Sepez67fd5df2015-10-08 12:24:19 -07001045 CJS_PropValue vProp(pRuntime);
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001046 vProp.StartGetting();
1047 vProp << arColor;
1048 vProp.StartSetting();
1049 fTarget->textColor(cc, vProp, sError); // red
1050 }
1051 }
1052 } else {
1053 if (iNegStyle == 1 || iNegStyle == 3) {
1054 if (Field* fTarget = pEvent->Target_Field()) {
Tom Sepez67fd5df2015-10-08 12:24:19 -07001055 CJS_Array arColor(pRuntime);
1056 CJS_Value vColElm(pRuntime);
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001057 vColElm = L"RGB";
1058 arColor.SetElement(0, vColElm);
1059 vColElm = 0;
1060 arColor.SetElement(1, vColElm);
1061 arColor.SetElement(2, vColElm);
1062 arColor.SetElement(3, vColElm);
1063
Tom Sepez67fd5df2015-10-08 12:24:19 -07001064 CJS_PropValue vProp(pRuntime);
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001065 vProp.StartGetting();
1066 fTarget->textColor(cc, vProp, sError);
1067
Tom Sepez67fd5df2015-10-08 12:24:19 -07001068 CJS_Array aProp(pRuntime);
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001069 vProp.ConvertToArray(aProp);
1070
1071 CPWL_Color crProp;
1072 CPWL_Color crColor;
1073 color::ConvertArrayToPWLColor(aProp, crProp);
1074 color::ConvertArrayToPWLColor(arColor, crColor);
1075
1076 if (crColor != crProp) {
Tom Sepez67fd5df2015-10-08 12:24:19 -07001077 CJS_PropValue vProp2(pRuntime);
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001078 vProp2.StartGetting();
1079 vProp2 << arColor;
1080 vProp2.StartSetting();
1081 fTarget->textColor(cc, vProp2, sError);
1082 }
1083 }
1084 }
1085 }
1086 Value = strValue2.c_str();
1087#endif
1088 return TRUE;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07001089}
1090
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001091// function AFNumber_Keystroke(nDec, sepStyle, negStyle, currStyle, strCurrency,
1092// bCurrencyPrepend)
Lei Zhang945fdb72015-11-11 10:18:16 -08001093FX_BOOL CJS_PublicMethods::AFNumber_Keystroke(
1094 IJS_Context* cc,
1095 const std::vector<CJS_Value>& params,
1096 CJS_Value& vRet,
1097 CFX_WideString& sError) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001098 CJS_Context* pContext = (CJS_Context*)cc;
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001099 CJS_EventHandler* pEvent = pContext->GetEventHandler();
Lei Zhanga6d9f0e2015-06-13 00:48:38 -07001100
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001101 if (params.size() < 2)
1102 return FALSE;
1103 int iSepStyle = params[1].ToInt();
Lei Zhanga6d9f0e2015-06-13 00:48:38 -07001104
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001105 if (iSepStyle < 0 || iSepStyle > 3)
1106 iSepStyle = 0;
1107 if (!pEvent->m_pValue)
1108 return FALSE;
1109 CFX_WideString& val = pEvent->Value();
1110 CFX_WideString& w_strChange = pEvent->Change();
1111 CFX_WideString w_strValue = val;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07001112
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001113 if (pEvent->WillCommit()) {
1114 CFX_WideString wstrChange = w_strChange;
1115 CFX_WideString wstrValue = StrLTrim(w_strValue.c_str());
1116 if (wstrValue.IsEmpty())
1117 return TRUE;
Lei Zhanga6d9f0e2015-06-13 00:48:38 -07001118
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001119 CFX_WideString swTemp = wstrValue;
1120 swTemp.Replace(L",", L".");
1121 if (!IsNumber(swTemp.c_str())) {
1122 pEvent->Rc() = FALSE;
1123 sError = JSGetStringFromID(pContext, IDS_STRING_JSAFNUMBER_KEYSTROKE);
1124 Alert(pContext, sError.c_str());
1125 return TRUE;
Tom Sepez2f2ffec2015-07-23 14:42:09 -07001126 }
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001127 return TRUE; // it happens after the last keystroke and before validating,
1128 }
Tom Sepez4f7bc042015-04-27 12:06:58 -07001129
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001130 std::wstring w_strValue2 = w_strValue.c_str();
1131 std::wstring w_strChange2 = w_strChange.c_str();
1132 std::wstring w_strSelected;
1133 if (-1 != pEvent->SelStart())
1134 w_strSelected = w_strValue2.substr(pEvent->SelStart(),
1135 (pEvent->SelEnd() - pEvent->SelStart()));
Lei Zhangb9c31972015-08-11 14:09:35 -07001136 bool bHasSign = (w_strValue2.find('-') != std::wstring::npos) &&
1137 (w_strSelected.find('-') == std::wstring::npos);
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001138 if (bHasSign) {
1139 // can't insert "change" in front to sign postion.
1140 if (pEvent->SelStart() == 0) {
1141 FX_BOOL& bRc = pEvent->Rc();
1142 bRc = FALSE;
1143 return TRUE;
Tom Sepez2f2ffec2015-07-23 14:42:09 -07001144 }
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001145 }
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07001146
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001147 char cSep = L'.';
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07001148
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001149 switch (iSepStyle) {
Tom Sepez2f2ffec2015-07-23 14:42:09 -07001150 case 0:
1151 case 1:
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001152 cSep = L'.';
1153 break;
Tom Sepez2f2ffec2015-07-23 14:42:09 -07001154 case 2:
1155 case 3:
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001156 cSep = L',';
1157 break;
1158 }
Lei Zhanga6d9f0e2015-06-13 00:48:38 -07001159
Lei Zhangb9c31972015-08-11 14:09:35 -07001160 bool bHasSep = (w_strValue2.find(cSep) != std::wstring::npos);
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001161 for (std::wstring::iterator it = w_strChange2.begin();
1162 it != w_strChange2.end(); it++) {
1163 if (*it == cSep) {
1164 if (bHasSep) {
1165 FX_BOOL& bRc = pEvent->Rc();
1166 bRc = FALSE;
Tom Sepez2f2ffec2015-07-23 14:42:09 -07001167 return TRUE;
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001168 }
1169 bHasSep = TRUE;
1170 continue;
1171 }
1172 if (*it == L'-') {
1173 if (bHasSign) {
1174 FX_BOOL& bRc = pEvent->Rc();
1175 bRc = FALSE;
1176 return TRUE;
1177 }
1178 if (it != w_strChange2.begin()) // sign's position is not correct
1179 {
1180 FX_BOOL& bRc = pEvent->Rc();
1181 bRc = FALSE;
1182 return TRUE;
1183 }
1184 if (pEvent->SelStart() != 0) {
1185 FX_BOOL& bRc = pEvent->Rc();
1186 bRc = FALSE;
1187 return TRUE;
1188 }
1189 bHasSign = TRUE;
1190 continue;
1191 }
1192
1193 if (!IsDigit(*it)) {
1194 FX_BOOL& bRc = pEvent->Rc();
1195 bRc = FALSE;
1196 return TRUE;
1197 }
1198 }
1199
1200 std::wstring w_prefix = w_strValue2.substr(0, pEvent->SelStart());
1201 std::wstring w_postfix;
1202 if (pEvent->SelEnd() < (int)w_strValue2.length())
1203 w_postfix = w_strValue2.substr(pEvent->SelEnd());
1204 w_strValue2 = w_prefix + w_strChange2 + w_postfix;
1205 w_strValue = w_strValue2.c_str();
1206 val = w_strValue;
1207 return TRUE;
1208}
1209
1210// function AFPercent_Format(nDec, sepStyle)
Lei Zhang945fdb72015-11-11 10:18:16 -08001211FX_BOOL CJS_PublicMethods::AFPercent_Format(
1212 IJS_Context* cc,
1213 const std::vector<CJS_Value>& params,
1214 CJS_Value& vRet,
1215 CFX_WideString& sError) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001216#if _FX_OS_ != _FX_ANDROID_
1217 CJS_Context* pContext = (CJS_Context*)cc;
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001218 CJS_EventHandler* pEvent = pContext->GetEventHandler();
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001219
1220 if (params.size() != 2) {
1221 sError = JSGetStringFromID(pContext, IDS_STRING_JSPARAMERROR);
1222 return FALSE;
1223 }
1224 if (!pEvent->m_pValue)
1225 return FALSE;
1226
1227 CFX_WideString& Value = pEvent->Value();
1228 CFX_ByteString strValue = StrTrim(CFX_ByteString::FromUnicode(Value));
1229 if (strValue.IsEmpty())
1230 return TRUE;
1231
1232 int iDec = params[0].ToInt();
1233 if (iDec < 0)
1234 iDec = -iDec;
1235
1236 int iSepStyle = params[1].ToInt();
1237 if (iSepStyle < 0 || iSepStyle > 3)
1238 iSepStyle = 0;
1239
1240 //////////////////////////////////////////////////////
1241 // for processing decimal places
1242 double dValue = atof(strValue);
1243 dValue *= 100;
1244 if (iDec > 0)
1245 dValue += DOUBLE_CORRECT; //УÕý
1246
1247 int iDec2;
1248 int iNegative = 0;
1249 strValue = fcvt(dValue, iDec, &iDec2, &iNegative);
1250 if (strValue.IsEmpty()) {
1251 dValue = 0;
1252 strValue = fcvt(dValue, iDec, &iDec2, &iNegative);
1253 }
1254
1255 if (iDec2 < 0) {
1256 for (int iNum = 0; iNum < abs(iDec2); iNum++) {
1257 strValue = "0" + strValue;
1258 }
1259 iDec2 = 0;
1260 }
1261 int iMax = strValue.GetLength();
1262 if (iDec2 > iMax) {
1263 for (int iNum = 0; iNum <= iDec2 - iMax; iNum++) {
1264 strValue += "0";
1265 }
1266 iMax = iDec2 + 1;
1267 }
1268 ///////////////////////////////////////////////////////
1269 // for processing seperator style
1270 if (iDec2 < iMax) {
1271 if (iSepStyle == 0 || iSepStyle == 1) {
1272 strValue.Insert(iDec2, '.');
1273 iMax++;
1274 } else if (iSepStyle == 2 || iSepStyle == 3) {
1275 strValue.Insert(iDec2, ',');
1276 iMax++;
1277 }
1278
1279 if (iDec2 == 0)
1280 strValue.Insert(iDec2, '0');
1281 }
1282 if (iSepStyle == 0 || iSepStyle == 2) {
1283 char cSeperator;
1284 if (iSepStyle == 0)
1285 cSeperator = ',';
1286 else
1287 cSeperator = '.';
1288
Tom Sepezdfbf8e72015-10-14 14:17:26 -07001289 for (int iDecPositive = iDec2 - 3; iDecPositive > 0; iDecPositive -= 3) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001290 strValue.Insert(iDecPositive, cSeperator);
1291 iMax++;
1292 }
1293 }
1294 ////////////////////////////////////////////////////////////////////
1295 // negative mark
1296 if (iNegative)
1297 strValue = "-" + strValue;
1298 strValue += "%";
1299 Value = CFX_WideString::FromLocal(strValue);
1300#endif
1301 return TRUE;
1302}
1303// AFPercent_Keystroke(nDec, sepStyle)
Lei Zhang945fdb72015-11-11 10:18:16 -08001304FX_BOOL CJS_PublicMethods::AFPercent_Keystroke(
1305 IJS_Context* cc,
1306 const std::vector<CJS_Value>& params,
1307 CJS_Value& vRet,
1308 CFX_WideString& sError) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001309 return AFNumber_Keystroke(cc, params, vRet, sError);
1310}
1311
1312// function AFDate_FormatEx(cFormat)
Tom Sepezba038bc2015-10-08 12:03:00 -07001313FX_BOOL CJS_PublicMethods::AFDate_FormatEx(IJS_Context* cc,
Lei Zhang945fdb72015-11-11 10:18:16 -08001314 const std::vector<CJS_Value>& params,
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001315 CJS_Value& vRet,
1316 CFX_WideString& sError) {
1317 CJS_Context* pContext = (CJS_Context*)cc;
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001318 CJS_EventHandler* pEvent = pContext->GetEventHandler();
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001319
1320 if (params.size() != 1) {
1321 sError = JSGetStringFromID(pContext, IDS_STRING_JSPARAMERROR);
1322 return FALSE;
1323 }
1324 if (!pEvent->m_pValue)
1325 return FALSE;
1326
1327 CFX_WideString& val = pEvent->Value();
1328 CFX_WideString strValue = val;
1329 if (strValue.IsEmpty())
1330 return TRUE;
1331
1332 CFX_WideString sFormat = params[0].ToCFXWideString();
1333 FX_BOOL bWrongFormat = FALSE;
1334 double dDate = 0.0f;
1335
1336 if (strValue.Find(L"GMT") != -1) {
1337 // for GMT format time
1338 // such as "Tue Aug 11 14:24:16 GMT+08002009"
1339 dDate = MakeInterDate(strValue);
1340 } else {
1341 dDate = MakeRegularDate(strValue, sFormat, bWrongFormat);
1342 }
1343
1344 if (JS_PortIsNan(dDate)) {
1345 CFX_WideString swMsg;
1346 swMsg.Format(JSGetStringFromID(pContext, IDS_STRING_JSPARSEDATE).c_str(),
1347 sFormat.c_str());
1348 Alert(pContext, swMsg.c_str());
1349 return FALSE;
1350 }
1351
1352 val = MakeFormatDate(dDate, sFormat);
1353 return TRUE;
1354}
1355
1356double CJS_PublicMethods::MakeInterDate(CFX_WideString strValue) {
1357 int nHour;
1358 int nMin;
1359 int nSec;
1360 int nYear;
1361 int nMonth;
1362 int nDay;
1363
1364 CFX_WideStringArray wsArray;
1365 CFX_WideString sMonth = L"";
1366 CFX_WideString sTemp = L"";
1367 int nSize = strValue.GetLength();
1368
1369 for (int i = 0; i < nSize; i++) {
1370 FX_WCHAR c = strValue.GetAt(i);
1371 if (c == L' ' || c == L':') {
1372 wsArray.Add(sTemp);
1373 sTemp = L"";
1374 continue;
1375 }
1376
1377 sTemp += c;
1378 }
1379
1380 wsArray.Add(sTemp);
1381 if (wsArray.GetSize() != 8)
1382 return 0;
1383
1384 sTemp = wsArray[1];
1385 if (sTemp.Compare(L"Jan") == 0)
1386 nMonth = 1;
1387 if (sTemp.Compare(L"Feb") == 0)
1388 nMonth = 2;
1389 if (sTemp.Compare(L"Mar") == 0)
1390 nMonth = 3;
1391 if (sTemp.Compare(L"Apr") == 0)
1392 nMonth = 4;
1393 if (sTemp.Compare(L"May") == 0)
1394 nMonth = 5;
1395 if (sTemp.Compare(L"Jun") == 0)
1396 nMonth = 6;
1397 if (sTemp.Compare(L"Jul") == 0)
1398 nMonth = 7;
1399 if (sTemp.Compare(L"Aug") == 0)
1400 nMonth = 8;
1401 if (sTemp.Compare(L"Sep") == 0)
1402 nMonth = 9;
1403 if (sTemp.Compare(L"Oct") == 0)
1404 nMonth = 10;
1405 if (sTemp.Compare(L"Nov") == 0)
1406 nMonth = 11;
1407 if (sTemp.Compare(L"Dec") == 0)
1408 nMonth = 12;
1409
1410 nDay = (int)ParseStringToNumber(wsArray[2].c_str());
1411 nHour = (int)ParseStringToNumber(wsArray[3].c_str());
1412 nMin = (int)ParseStringToNumber(wsArray[4].c_str());
1413 nSec = (int)ParseStringToNumber(wsArray[5].c_str());
1414 nYear = (int)ParseStringToNumber(wsArray[7].c_str());
1415
1416 double dRet = JS_MakeDate(JS_MakeDay(nYear, nMonth - 1, nDay),
1417 JS_MakeTime(nHour, nMin, nSec, 0));
1418
1419 if (JS_PortIsNan(dRet)) {
1420 dRet = JS_DateParse(strValue.c_str());
1421 }
1422
1423 return dRet;
1424}
1425
1426// AFDate_KeystrokeEx(cFormat)
Lei Zhang945fdb72015-11-11 10:18:16 -08001427FX_BOOL CJS_PublicMethods::AFDate_KeystrokeEx(
1428 IJS_Context* cc,
1429 const std::vector<CJS_Value>& params,
1430 CJS_Value& vRet,
1431 CFX_WideString& sError) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001432 CJS_Context* pContext = (CJS_Context*)cc;
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001433 CJS_EventHandler* pEvent = pContext->GetEventHandler();
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001434
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;
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001604
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();
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001614 if (!pEvent->m_pValue)
1615 return FALSE;
1616 CFX_WideString& Value = pEvent->Value();
1617 std::string strSrc = CFX_ByteString::FromUnicode(Value).c_str();
1618
1619 switch (iIndex) {
Tom Sepez2f2ffec2015-07-23 14:42:09 -07001620 case 0:
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001621 cFormat = "99999";
1622 break;
Tom Sepez2f2ffec2015-07-23 14:42:09 -07001623 case 1:
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001624 cFormat = "99999-9999";
1625 break;
1626 case 2: {
1627 std::string NumberStr;
1628 util::printx("9999999999", strSrc, NumberStr);
1629 if (NumberStr.length() >= 10)
1630 cFormat = "(999) 999-9999";
1631 else
1632 cFormat = "999-9999";
1633 break;
1634 }
Tom Sepez2f2ffec2015-07-23 14:42:09 -07001635 case 3:
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001636 cFormat = "999-99-9999";
1637 break;
1638 }
1639
1640 std::string strDes;
1641 util::printx(cFormat, strSrc, strDes);
1642 Value = CFX_WideString::FromLocal(strDes.c_str());
1643 return TRUE;
1644}
1645
1646// function AFSpecial_KeystrokeEx(mask)
Lei Zhang945fdb72015-11-11 10:18:16 -08001647FX_BOOL CJS_PublicMethods::AFSpecial_KeystrokeEx(
1648 IJS_Context* cc,
1649 const std::vector<CJS_Value>& params,
1650 CJS_Value& vRet,
1651 CFX_WideString& sError) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001652 CJS_Context* pContext = (CJS_Context*)cc;
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001653 CJS_EventHandler* pEvent = pContext->GetEventHandler();
1654
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001655 if (params.size() < 1) {
1656 sError = JSGetStringFromID(pContext, IDS_STRING_JSPARAMERROR);
1657 return FALSE;
1658 }
1659
1660 if (!pEvent->m_pValue)
1661 return FALSE;
1662 CFX_WideString& valEvent = pEvent->Value();
1663
1664 CFX_WideString wstrMask = params[0].ToCFXWideString();
1665 if (wstrMask.IsEmpty())
1666 return TRUE;
1667
Lei Zhanga0f67242015-08-17 15:39:30 -07001668 const size_t wstrMaskLen = wstrMask.GetLength();
1669 const std::wstring wstrValue = valEvent.c_str();
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001670
1671 if (pEvent->WillCommit()) {
1672 if (wstrValue.empty())
1673 return TRUE;
Lei Zhanga0f67242015-08-17 15:39:30 -07001674 size_t iIndexMask = 0;
1675 for (const auto& w_Value : wstrValue) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001676 if (!maskSatisfied(w_Value, wstrMask[iIndexMask]))
Tom Sepez2f2ffec2015-07-23 14:42:09 -07001677 break;
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001678 iIndexMask++;
Tom Sepez2f2ffec2015-07-23 14:42:09 -07001679 }
Lei Zhanga6d9f0e2015-06-13 00:48:38 -07001680
Lei Zhanga0f67242015-08-17 15:39:30 -07001681 if (iIndexMask != wstrMaskLen ||
1682 (iIndexMask != wstrValue.size() && wstrMaskLen != 0)) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001683 Alert(
1684 pContext,
1685 JSGetStringFromID(pContext, IDS_STRING_JSAFNUMBER_KEYSTROKE).c_str());
1686 pEvent->Rc() = FALSE;
1687 }
Tom Sepez2f2ffec2015-07-23 14:42:09 -07001688 return TRUE;
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001689 }
1690
1691 CFX_WideString& wideChange = pEvent->Change();
1692 std::wstring wChange = wideChange.c_str();
1693 if (wChange.empty())
1694 return TRUE;
1695
1696 int iIndexMask = pEvent->SelStart();
1697
Lei Zhanga0f67242015-08-17 15:39:30 -07001698 size_t combined_len = wstrValue.length() + wChange.length() -
1699 (pEvent->SelEnd() - pEvent->SelStart());
1700 if (combined_len > wstrMaskLen) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001701 Alert(pContext,
1702 JSGetStringFromID(pContext, IDS_STRING_JSPARAM_TOOLONG).c_str());
1703 pEvent->Rc() = FALSE;
1704 return TRUE;
1705 }
1706
Lei Zhanga0f67242015-08-17 15:39:30 -07001707 if (iIndexMask >= wstrMaskLen && (!wChange.empty())) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001708 Alert(pContext,
1709 JSGetStringFromID(pContext, IDS_STRING_JSPARAM_TOOLONG).c_str());
1710 pEvent->Rc() = FALSE;
1711 return TRUE;
1712 }
1713
1714 for (std::wstring::iterator it = wChange.begin(); it != wChange.end(); it++) {
Lei Zhanga0f67242015-08-17 15:39:30 -07001715 if (iIndexMask >= wstrMaskLen) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001716 Alert(pContext,
1717 JSGetStringFromID(pContext, IDS_STRING_JSPARAM_TOOLONG).c_str());
1718 pEvent->Rc() = FALSE;
1719 return TRUE;
1720 }
1721 wchar_t w_Mask = wstrMask[iIndexMask];
1722 if (!isReservedMaskChar(w_Mask)) {
1723 *it = w_Mask;
1724 }
1725 wchar_t w_Change = *it;
1726 if (!maskSatisfied(w_Change, w_Mask)) {
1727 pEvent->Rc() = FALSE;
1728 return TRUE;
1729 }
1730 iIndexMask++;
1731 }
1732
1733 wideChange = wChange.c_str();
1734 return TRUE;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07001735}
1736
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001737// function AFSpecial_Keystroke(psf)
Lei Zhang945fdb72015-11-11 10:18:16 -08001738FX_BOOL CJS_PublicMethods::AFSpecial_Keystroke(
1739 IJS_Context* cc,
1740 const std::vector<CJS_Value>& params,
1741 CJS_Value& vRet,
1742 CFX_WideString& sError) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001743 CJS_Context* pContext = (CJS_Context*)cc;
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001744 if (params.size() != 1) {
1745 sError = JSGetStringFromID(pContext, IDS_STRING_JSPARAMERROR);
1746 return FALSE;
1747 }
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07001748
Tom Sepez67fd5df2015-10-08 12:24:19 -07001749 CJS_EventHandler* pEvent = pContext->GetEventHandler();
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001750 if (!pEvent->m_pValue)
1751 return FALSE;
Tom Sepez67fd5df2015-10-08 12:24:19 -07001752
1753 std::string cFormat;
1754 int iIndex = params[0].ToInt();
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001755 CFX_WideString& val = pEvent->Value();
1756 std::string strSrc = CFX_ByteString::FromUnicode(val).c_str();
1757 std::wstring wstrChange = pEvent->Change().c_str();
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07001758
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001759 switch (iIndex) {
Tom Sepez2f2ffec2015-07-23 14:42:09 -07001760 case 0:
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001761 cFormat = "99999";
1762 break;
Tom Sepez2f2ffec2015-07-23 14:42:09 -07001763 case 1:
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001764 // cFormat = "99999-9999";
1765 cFormat = "999999999";
1766 break;
1767 case 2: {
1768 std::string NumberStr;
1769 util::printx("9999999999", strSrc, NumberStr);
1770 if (strSrc.length() + wstrChange.length() > 7)
1771 // cFormat = "(999) 999-9999";
1772 cFormat = "9999999999";
1773 else
1774 // cFormat = "999-9999";
1775 cFormat = "9999999";
1776 break;
1777 }
Tom Sepez2f2ffec2015-07-23 14:42:09 -07001778 case 3:
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001779 // cFormat = "999-99-9999";
1780 cFormat = "999999999";
1781 break;
1782 }
Lei Zhanga6d9f0e2015-06-13 00:48:38 -07001783
Lei Zhang945fdb72015-11-11 10:18:16 -08001784 std::vector<CJS_Value> params2;
Tom Sepez67fd5df2015-10-08 12:24:19 -07001785 params2.push_back(CJS_Value(CJS_Runtime::FromContext(cc), cFormat.c_str()));
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001786 return AFSpecial_KeystrokeEx(cc, params2, vRet, sError);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07001787}
1788
Tom Sepezba038bc2015-10-08 12:03:00 -07001789FX_BOOL CJS_PublicMethods::AFMergeChange(IJS_Context* cc,
Lei Zhang945fdb72015-11-11 10:18:16 -08001790 const std::vector<CJS_Value>& params,
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001791 CJS_Value& vRet,
1792 CFX_WideString& sError) {
1793 CJS_Context* pContext = (CJS_Context*)cc;
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001794 CJS_EventHandler* pEventHandler = pContext->GetEventHandler();
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07001795
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001796 if (params.size() != 1) {
1797 sError = JSGetStringFromID(pContext, IDS_STRING_JSPARAMERROR);
1798 return FALSE;
1799 }
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07001800
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001801 CFX_WideString swValue;
Lei Zhang997de612015-11-04 18:17:53 -08001802 if (pEventHandler->m_pValue)
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001803 swValue = pEventHandler->Value();
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07001804
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001805 if (pEventHandler->WillCommit()) {
1806 vRet = swValue.c_str();
Tom Sepez2f2ffec2015-07-23 14:42:09 -07001807 return TRUE;
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001808 }
1809
1810 CFX_WideString prefix, postfix;
1811
1812 if (pEventHandler->SelStart() >= 0)
1813 prefix = swValue.Mid(0, pEventHandler->SelStart());
1814 else
1815 prefix = L"";
1816
1817 if (pEventHandler->SelEnd() >= 0 &&
1818 pEventHandler->SelEnd() <= swValue.GetLength())
1819 postfix = swValue.Mid(pEventHandler->SelEnd(),
1820 swValue.GetLength() - pEventHandler->SelEnd());
1821 else
1822 postfix = L"";
1823
1824 vRet = (prefix + pEventHandler->Change() + postfix).c_str();
1825
1826 return TRUE;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07001827}
1828
Tom Sepezba038bc2015-10-08 12:03:00 -07001829FX_BOOL CJS_PublicMethods::AFParseDateEx(IJS_Context* cc,
Lei Zhang945fdb72015-11-11 10:18:16 -08001830 const std::vector<CJS_Value>& params,
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001831 CJS_Value& vRet,
1832 CFX_WideString& sError) {
1833 CJS_Context* pContext = (CJS_Context*)cc;
Lei Zhang96660d62015-12-14 18:27:25 -08001834 ASSERT(pContext);
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001835
1836 if (params.size() != 2) {
1837 sError = JSGetStringFromID(pContext, IDS_STRING_JSPARAMERROR);
1838 return FALSE;
1839 }
1840
1841 CFX_WideString sValue = params[0].ToCFXWideString();
1842 CFX_WideString sFormat = params[1].ToCFXWideString();
1843
1844 FX_BOOL bWrongFormat = FALSE;
1845 double dDate = MakeRegularDate(sValue, sFormat, bWrongFormat);
1846
1847 if (JS_PortIsNan(dDate)) {
1848 CFX_WideString swMsg;
1849 swMsg.Format(JSGetStringFromID(pContext, IDS_STRING_JSPARSEDATE).c_str(),
1850 sFormat.c_str());
1851 Alert((CJS_Context*)cc, swMsg.c_str());
1852 return FALSE;
1853 }
1854
1855 vRet = dDate;
1856 return TRUE;
1857}
1858
Tom Sepezba038bc2015-10-08 12:03:00 -07001859FX_BOOL CJS_PublicMethods::AFSimple(IJS_Context* cc,
Lei Zhang945fdb72015-11-11 10:18:16 -08001860 const std::vector<CJS_Value>& params,
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001861 CJS_Value& vRet,
1862 CFX_WideString& sError) {
1863 if (params.size() != 3) {
1864 CJS_Context* pContext = (CJS_Context*)cc;
Lei Zhang96660d62015-12-14 18:27:25 -08001865 ASSERT(pContext);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07001866
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001867 sError = JSGetStringFromID(pContext, IDS_STRING_JSPARAMERROR);
1868 return FALSE;
1869 }
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07001870
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001871 vRet = (double)AF_Simple(params[0].ToCFXWideString().c_str(),
1872 params[1].ToDouble(), params[2].ToDouble());
1873 return TRUE;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07001874}
1875
Tom Sepezba038bc2015-10-08 12:03:00 -07001876FX_BOOL CJS_PublicMethods::AFMakeNumber(IJS_Context* cc,
Lei Zhang945fdb72015-11-11 10:18:16 -08001877 const std::vector<CJS_Value>& params,
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001878 CJS_Value& vRet,
1879 CFX_WideString& sError) {
1880 if (params.size() != 1) {
1881 CJS_Context* pContext = (CJS_Context*)cc;
Lei Zhang96660d62015-12-14 18:27:25 -08001882 ASSERT(pContext);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07001883
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001884 sError = JSGetStringFromID(pContext, IDS_STRING_JSPARAMERROR);
1885 return FALSE;
1886 }
1887 vRet = ParseStringToNumber(params[0].ToCFXWideString().c_str());
1888 return TRUE;
1889}
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07001890
Lei Zhang945fdb72015-11-11 10:18:16 -08001891FX_BOOL CJS_PublicMethods::AFSimple_Calculate(
1892 IJS_Context* cc,
1893 const std::vector<CJS_Value>& params,
1894 CJS_Value& vRet,
1895 CFX_WideString& sError) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001896 CJS_Context* pContext = (CJS_Context*)cc;
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001897 if (params.size() != 2) {
1898 sError = JSGetStringFromID(pContext, IDS_STRING_JSPARAMERROR);
1899 return FALSE;
1900 }
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07001901
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001902 CJS_Value params1 = params[1];
Tom Sepez39bfe122015-09-17 15:25:23 -07001903 if (!params1.IsArrayObject() && params1.GetType() != CJS_Value::VT_string) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001904 sError = JSGetStringFromID(pContext, IDS_STRING_JSPARAMERROR);
1905 return FALSE;
1906 }
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07001907
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001908 CPDFSDK_Document* pReaderDoc = pContext->GetReaderDocument();
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001909 CPDFSDK_InterForm* pReaderInterForm = pReaderDoc->GetInterForm();
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001910 CPDF_InterForm* pInterForm = pReaderInterForm->GetInterForm();
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07001911
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001912 CFX_WideString sFunction = params[0].ToCFXWideString();
Tom Sepez67fd5df2015-10-08 12:24:19 -07001913 double dValue = wcscmp(sFunction.c_str(), L"PRD") == 0 ? 1.0 : 0.0;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07001914
Tom Sepez67fd5df2015-10-08 12:24:19 -07001915 CJS_Runtime* pRuntime = CJS_Runtime::FromContext(cc);
1916 CJS_Array FieldNameArray = AF_MakeArrayFromList(pRuntime, params1);
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001917 int nFieldsCount = 0;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07001918
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001919 for (int i = 0, isz = FieldNameArray.GetLength(); i < isz; i++) {
Tom Sepez67fd5df2015-10-08 12:24:19 -07001920 CJS_Value jsValue(pRuntime);
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001921 FieldNameArray.GetElement(i, jsValue);
1922 CFX_WideString wsFieldName = jsValue.ToCFXWideString();
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07001923
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001924 for (int j = 0, jsz = pInterForm->CountFields(wsFieldName); j < jsz; j++) {
1925 if (CPDF_FormField* pFormField = pInterForm->GetField(j, wsFieldName)) {
1926 double dTemp = 0.0;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07001927
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001928 switch (pFormField->GetFieldType()) {
1929 case FIELDTYPE_TEXTFIELD:
1930 case FIELDTYPE_COMBOBOX: {
1931 dTemp = ParseStringToNumber(pFormField->GetValue().c_str());
1932 break;
1933 }
1934 case FIELDTYPE_PUSHBUTTON: {
1935 dTemp = 0.0;
1936 break;
1937 }
1938 case FIELDTYPE_CHECKBOX:
1939 case FIELDTYPE_RADIOBUTTON: {
1940 dTemp = 0.0;
1941 for (int c = 0, csz = pFormField->CountControls(); c < csz; c++) {
1942 if (CPDF_FormControl* pFormCtrl = pFormField->GetControl(c)) {
1943 if (pFormCtrl->IsChecked()) {
1944 dTemp +=
1945 ParseStringToNumber(pFormCtrl->GetExportValue().c_str());
1946 break;
1947 } else
1948 continue;
1949 }
Tom Sepez2f2ffec2015-07-23 14:42:09 -07001950 }
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001951 break;
1952 }
1953 case FIELDTYPE_LISTBOX: {
1954 dTemp = 0.0;
1955 if (pFormField->CountSelectedItems() > 1)
1956 break;
1957 else {
1958 dTemp = ParseStringToNumber(pFormField->GetValue().c_str());
1959 break;
1960 }
1961 }
1962 default:
1963 break;
Tom Sepez2f2ffec2015-07-23 14:42:09 -07001964 }
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001965
1966 if (i == 0 && j == 0 && (wcscmp(sFunction.c_str(), L"MIN") == 0 ||
1967 wcscmp(sFunction.c_str(), L"MAX") == 0))
1968 dValue = dTemp;
1969
1970 dValue = AF_Simple(sFunction.c_str(), dValue, dTemp);
1971
1972 nFieldsCount++;
1973 }
Tom Sepez2f2ffec2015-07-23 14:42:09 -07001974 }
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001975 }
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07001976
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001977 if (wcscmp(sFunction.c_str(), L"AVG") == 0 && nFieldsCount > 0)
1978 dValue /= nFieldsCount;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07001979
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001980 dValue = (double)floor(dValue * FXSYS_pow((double)10, (double)6) + 0.49) /
1981 FXSYS_pow((double)10, (double)6);
Tom Sepez67fd5df2015-10-08 12:24:19 -07001982 CJS_Value jsValue(pRuntime, dValue);
foxit8b544ed2015-09-10 14:57:54 +08001983 if (pContext->GetEventHandler()->m_pValue)
1984 pContext->GetEventHandler()->Value() = jsValue.ToCFXWideString();
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07001985
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001986 return TRUE;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07001987}
1988
Lei Zhanga6d9f0e2015-06-13 00:48:38 -07001989/* This function validates the current event to ensure that its value is
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07001990** within the specified range. */
1991
Lei Zhang945fdb72015-11-11 10:18:16 -08001992FX_BOOL CJS_PublicMethods::AFRange_Validate(
1993 IJS_Context* cc,
1994 const std::vector<CJS_Value>& params,
1995 CJS_Value& vRet,
1996 CFX_WideString& sError) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001997 CJS_Context* pContext = (CJS_Context*)cc;
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001998 CJS_EventHandler* pEvent = pContext->GetEventHandler();
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07001999
Nico Weber9d8ec5a2015-08-04 13:00:21 -07002000 if (params.size() != 4) {
2001 sError = JSGetStringFromID(pContext, IDS_STRING_JSPARAMERROR);
2002 return FALSE;
2003 }
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07002004
Nico Weber9d8ec5a2015-08-04 13:00:21 -07002005 if (!pEvent->m_pValue)
2006 return FALSE;
2007 if (pEvent->Value().IsEmpty())
Tom Sepez2f2ffec2015-07-23 14:42:09 -07002008 return TRUE;
Nico Weber9d8ec5a2015-08-04 13:00:21 -07002009 double dEentValue = atof(CFX_ByteString::FromUnicode(pEvent->Value()));
2010 FX_BOOL bGreaterThan = params[0].ToBool();
2011 double dGreaterThan = params[1].ToDouble();
2012 FX_BOOL bLessThan = params[2].ToBool();
2013 double dLessThan = params[3].ToDouble();
2014 CFX_WideString swMsg;
2015
2016 if (bGreaterThan && bLessThan) {
2017 if (dEentValue < dGreaterThan || dEentValue > dLessThan)
2018 swMsg.Format(JSGetStringFromID(pContext, IDS_STRING_JSRANGE1).c_str(),
2019 params[1].ToCFXWideString().c_str(),
2020 params[3].ToCFXWideString().c_str());
2021 } else if (bGreaterThan) {
2022 if (dEentValue < dGreaterThan)
2023 swMsg.Format(JSGetStringFromID(pContext, IDS_STRING_JSRANGE2).c_str(),
2024 params[1].ToCFXWideString().c_str());
2025 } else if (bLessThan) {
2026 if (dEentValue > dLessThan)
2027 swMsg.Format(JSGetStringFromID(pContext, IDS_STRING_JSRANGE3).c_str(),
2028 params[3].ToCFXWideString().c_str());
2029 }
2030
2031 if (!swMsg.IsEmpty()) {
2032 Alert(pContext, swMsg.c_str());
2033 pEvent->Rc() = FALSE;
2034 }
2035 return TRUE;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07002036}
2037
Tom Sepezba038bc2015-10-08 12:03:00 -07002038FX_BOOL CJS_PublicMethods::AFExtractNums(IJS_Context* cc,
Lei Zhang945fdb72015-11-11 10:18:16 -08002039 const std::vector<CJS_Value>& params,
Nico Weber9d8ec5a2015-08-04 13:00:21 -07002040 CJS_Value& vRet,
2041 CFX_WideString& sError) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -07002042 CJS_Context* pContext = (CJS_Context*)cc;
Nico Weber9d8ec5a2015-08-04 13:00:21 -07002043 if (params.size() != 1) {
2044 sError = JSGetStringFromID(pContext, IDS_STRING_JSPARAMERROR);
2045 return FALSE;
2046 }
2047
Tom Sepez67fd5df2015-10-08 12:24:19 -07002048 CJS_Runtime* pRuntime = CJS_Runtime::FromContext(cc);
2049 CJS_Array nums(pRuntime);
Nico Weber9d8ec5a2015-08-04 13:00:21 -07002050
2051 CFX_WideString str = params[0].ToCFXWideString();
2052 CFX_WideString sPart;
2053
2054 if (str.GetAt(0) == L'.' || str.GetAt(0) == L',')
2055 str = L"0" + str;
2056
2057 int nIndex = 0;
2058 for (int i = 0, sz = str.GetLength(); i < sz; i++) {
2059 FX_WCHAR wc = str.GetAt(i);
2060 if (IsDigit((wchar_t)wc)) {
2061 sPart += wc;
2062 } else {
2063 if (sPart.GetLength() > 0) {
Tom Sepez67fd5df2015-10-08 12:24:19 -07002064 nums.SetElement(nIndex, CJS_Value(pRuntime, sPart.c_str()));
Nico Weber9d8ec5a2015-08-04 13:00:21 -07002065 sPart = L"";
2066 nIndex++;
2067 }
Tom Sepez2f2ffec2015-07-23 14:42:09 -07002068 }
Nico Weber9d8ec5a2015-08-04 13:00:21 -07002069 }
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07002070
Nico Weber9d8ec5a2015-08-04 13:00:21 -07002071 if (sPart.GetLength() > 0) {
Tom Sepez67fd5df2015-10-08 12:24:19 -07002072 nums.SetElement(nIndex, CJS_Value(pRuntime, sPart.c_str()));
Nico Weber9d8ec5a2015-08-04 13:00:21 -07002073 }
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07002074
Nico Weber9d8ec5a2015-08-04 13:00:21 -07002075 if (nums.GetLength() > 0)
2076 vRet = nums;
2077 else
2078 vRet.SetNull();
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07002079
Nico Weber9d8ec5a2015-08-04 13:00:21 -07002080 return TRUE;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07002081}