blob: 6db31de1e7097568d69b9df129e4f2a9ab875263 [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 }
Lei Zhang9559b7a2015-12-21 11:12:20 -0800106 } else if (!FXSYS_iswdigit(c)) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700107 return FALSE;
108 }
109 p++;
110 }
111
112 return TRUE;
113}
114
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700115FX_BOOL CJS_PublicMethods::maskSatisfied(wchar_t c_Change, wchar_t c_Mask) {
116 switch (c_Mask) {
117 case L'9':
Lei Zhang9559b7a2015-12-21 11:12:20 -0800118 return FXSYS_iswdigit(c_Change);
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700119 case L'A':
Lei Zhang9559b7a2015-12-21 11:12:20 -0800120 return FXSYS_iswalpha(c_Change);
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700121 case L'O':
Lei Zhang9559b7a2015-12-21 11:12:20 -0800122 return FXSYS_iswalnum(c_Change);
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700123 case L'X':
124 return TRUE;
125 default:
126 return (c_Change == c_Mask);
127 }
128}
129
130FX_BOOL CJS_PublicMethods::isReservedMaskChar(wchar_t ch) {
131 return ch == L'9' || ch == L'A' || ch == L'O' || ch == L'X';
132}
133
134double CJS_PublicMethods::AF_Simple(const FX_WCHAR* sFuction,
135 double dValue1,
136 double dValue2) {
137 if (FXSYS_wcsicmp(sFuction, L"AVG") == 0 ||
138 FXSYS_wcsicmp(sFuction, L"SUM") == 0) {
139 return dValue1 + dValue2;
140 }
141 if (FXSYS_wcsicmp(sFuction, L"PRD") == 0) {
142 return dValue1 * dValue2;
143 }
144 if (FXSYS_wcsicmp(sFuction, L"MIN") == 0) {
145 return FX_MIN(dValue1, dValue2);
146 }
147 if (FXSYS_wcsicmp(sFuction, L"MAX") == 0) {
148 return FX_MAX(dValue1, dValue2);
149 }
150 return dValue1;
151}
152
153CFX_WideString CJS_PublicMethods::StrLTrim(const FX_WCHAR* pStr) {
154 while (*pStr && *pStr == L' ')
155 pStr++;
156
157 return pStr;
158}
159
160CFX_WideString CJS_PublicMethods::StrRTrim(const FX_WCHAR* pStr) {
161 const FX_WCHAR* p = pStr;
162 while (*p)
163 p++;
164 while (p > pStr && *(p - 1) == L' ')
165 p--;
166
167 return CFX_WideString(pStr, p - pStr);
168}
169
170CFX_WideString CJS_PublicMethods::StrTrim(const FX_WCHAR* pStr) {
171 return StrRTrim(StrLTrim(pStr).c_str());
172}
173
174CFX_ByteString CJS_PublicMethods::StrLTrim(const FX_CHAR* pStr) {
175 while (*pStr && *pStr == ' ')
176 pStr++;
177
178 return pStr;
179}
180
181CFX_ByteString CJS_PublicMethods::StrRTrim(const FX_CHAR* pStr) {
182 const FX_CHAR* p = pStr;
183 while (*p)
184 p++;
185 while (p > pStr && *(p - 1) == L' ')
186 p--;
187
188 return CFX_ByteString(pStr, p - pStr);
189}
190
191CFX_ByteString CJS_PublicMethods::StrTrim(const FX_CHAR* pStr) {
192 return StrRTrim(StrLTrim(pStr));
193}
194
195double CJS_PublicMethods::ParseNumber(const FX_WCHAR* swSource,
196 FX_BOOL& bAllDigits,
197 FX_BOOL& bDot,
198 FX_BOOL& bSign,
199 FX_BOOL& bKXJS) {
200 bDot = FALSE;
201 bSign = FALSE;
202 bKXJS = FALSE;
203
204 FX_BOOL bDigitExist = FALSE;
205
206 const FX_WCHAR* p = swSource;
207 wchar_t c;
208
209 const FX_WCHAR* pStart = NULL;
210 const FX_WCHAR* pEnd = NULL;
211
212 while ((c = *p)) {
213 if (!pStart && c != L' ') {
214 pStart = p;
215 }
216
217 pEnd = p;
218 p++;
219 }
220
221 if (!pStart) {
222 bAllDigits = FALSE;
223 return 0;
224 }
225
226 while (pEnd != pStart) {
227 if (*pEnd == L' ')
228 pEnd--;
229 else
230 break;
231 }
232
233 double dRet = 0;
234 p = pStart;
235 bAllDigits = TRUE;
236 CFX_WideString swDigits;
237
238 while (p <= pEnd) {
239 c = *p;
240
Lei Zhang9559b7a2015-12-21 11:12:20 -0800241 if (FXSYS_iswdigit(c)) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700242 swDigits += c;
243 bDigitExist = TRUE;
244 } else {
245 switch (c) {
246 case L' ':
247 bAllDigits = FALSE;
248 break;
249 case L'.':
250 case L',':
251 if (!bDot) {
252 if (bDigitExist) {
253 swDigits += L'.';
254 } else {
255 swDigits += L'0';
256 swDigits += L'.';
257 bDigitExist = TRUE;
258 }
259
Tom Sepez2f2ffec2015-07-23 14:42:09 -0700260 bDot = TRUE;
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700261 break;
262 }
263 case 'e':
264 case 'E':
265 if (!bKXJS) {
Tom Sepez2f2ffec2015-07-23 14:42:09 -0700266 p++;
267 c = *p;
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700268 if (c == '+' || c == '-') {
269 bKXJS = TRUE;
270 swDigits += 'e';
271 swDigits += c;
Tom Sepez2f2ffec2015-07-23 14:42:09 -0700272 }
Tom Sepez2f2ffec2015-07-23 14:42:09 -0700273 break;
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700274 }
275 case L'-':
276 if (!bDigitExist && !bSign) {
Tom Sepez2f2ffec2015-07-23 14:42:09 -0700277 swDigits += c;
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700278 bSign = TRUE;
Tom Sepez2f2ffec2015-07-23 14:42:09 -0700279 break;
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700280 }
281 default:
282 bAllDigits = FALSE;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700283
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700284 if (p != pStart && !bDot && bDigitExist) {
285 swDigits += L'.';
286 bDot = TRUE;
287 } else {
288 bDot = FALSE;
289 bDigitExist = FALSE;
290 swDigits = L"";
291 }
292 break;
293 }
Tom Sepez2f2ffec2015-07-23 14:42:09 -0700294 }
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700295
296 p++;
297 }
298
299 if (swDigits.GetLength() > 0 && swDigits.GetLength() < 17) {
300 CFX_ByteString sDigits = swDigits.UTF8Encode();
301
302 if (bKXJS) {
303 dRet = atof(sDigits);
304 } else {
305 if (bDot) {
306 char* pStopString;
307 dRet = ::strtod(sDigits, &pStopString);
308 } else {
309 dRet = atol(sDigits);
310 }
311 }
312 }
313
314 return dRet;
315}
316
317double CJS_PublicMethods::ParseStringToNumber(const FX_WCHAR* swSource) {
318 FX_BOOL bAllDigits = FALSE;
319 FX_BOOL bDot = FALSE;
320 FX_BOOL bSign = FALSE;
321 FX_BOOL bKXJS = FALSE;
322
323 return ParseNumber(swSource, bAllDigits, bDot, bSign, bKXJS);
324}
325
326FX_BOOL CJS_PublicMethods::ConvertStringToNumber(const FX_WCHAR* swSource,
327 double& dRet,
328 FX_BOOL& bDot) {
329 FX_BOOL bAllDigits = FALSE;
330 FX_BOOL bSign = FALSE;
331 FX_BOOL bKXJS = FALSE;
332
333 dRet = ParseNumber(swSource, bAllDigits, bDot, bSign, bKXJS);
334
335 return bAllDigits;
336}
337
Tom Sepez67fd5df2015-10-08 12:24:19 -0700338CJS_Array CJS_PublicMethods::AF_MakeArrayFromList(CJS_Runtime* pRuntime,
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700339 CJS_Value val) {
Tom Sepez67fd5df2015-10-08 12:24:19 -0700340 CJS_Array StrArray(pRuntime);
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700341 if (val.IsArrayObject()) {
342 val.ConvertToArray(StrArray);
Tom Sepez2f2ffec2015-07-23 14:42:09 -0700343 return StrArray;
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700344 }
345 CFX_WideString wsStr = val.ToCFXWideString();
346 CFX_ByteString t = CFX_ByteString::FromUnicode(wsStr);
347 const char* p = (const char*)t;
348
349 int ch = ',';
350 int nIndex = 0;
351
352 while (*p) {
353 const char* pTemp = strchr(p, ch);
Lei Zhang997de612015-11-04 18:17:53 -0800354 if (!pTemp) {
Tom Sepez67fd5df2015-10-08 12:24:19 -0700355 StrArray.SetElement(nIndex, CJS_Value(pRuntime, StrTrim(p).c_str()));
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700356 break;
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700357 }
Lei Zhang997de612015-11-04 18:17:53 -0800358
359 char* pSub = new char[pTemp - p + 1];
360 strncpy(pSub, p, pTemp - p);
361 *(pSub + (pTemp - p)) = '\0';
362
363 StrArray.SetElement(nIndex, CJS_Value(pRuntime, StrTrim(pSub).c_str()));
364 delete[] pSub;
365
366 nIndex++;
367 p = ++pTemp;
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700368 }
369 return StrArray;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700370}
371
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700372int CJS_PublicMethods::ParseStringInteger(const CFX_WideString& string,
373 int nStart,
374 int& nSkip,
375 int nMaxStep) {
376 int nRet = 0;
377 nSkip = 0;
378 for (int i = nStart, sz = string.GetLength(); i < sz; i++) {
379 if (i - nStart > 10)
380 break;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700381
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700382 FX_WCHAR c = string.GetAt(i);
Lei Zhang9559b7a2015-12-21 11:12:20 -0800383 if (!FXSYS_iswdigit(c))
384 break;
385
386 nRet = nRet * 10 + FXSYS_toDecimalDigitWide(c);
387 nSkip = i - nStart + 1;
388 if (nSkip >= nMaxStep)
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700389 break;
390 }
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700391
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700392 return nRet;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700393}
394
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700395CFX_WideString CJS_PublicMethods::ParseStringString(
396 const CFX_WideString& string,
397 int nStart,
398 int& nSkip) {
399 CFX_WideString swRet;
400 nSkip = 0;
401 for (int i = nStart, sz = string.GetLength(); i < sz; i++) {
402 FX_WCHAR c = string.GetAt(i);
Lei Zhang9559b7a2015-12-21 11:12:20 -0800403 if (!FXSYS_iswdigit(c))
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700404 break;
Lei Zhang9559b7a2015-12-21 11:12:20 -0800405
406 swRet += c;
407 nSkip = i - nStart + 1;
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700408 }
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700409
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700410 return swRet;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700411}
412
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700413double CJS_PublicMethods::ParseNormalDate(const CFX_WideString& value,
Lei Zhang9559b7a2015-12-21 11:12:20 -0800414 bool* bWrongFormat) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700415 double dt = JS_GetDateTime();
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700416
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700417 int nYear = JS_GetYearFromTime(dt);
418 int nMonth = JS_GetMonthFromTime(dt) + 1;
419 int nDay = JS_GetDayFromTime(dt);
420 int nHour = JS_GetHourFromTime(dt);
421 int nMin = JS_GetMinFromTime(dt);
422 int nSec = JS_GetSecFromTime(dt);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700423
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700424 int number[3];
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700425
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700426 int nSkip = 0;
427 int nLen = value.GetLength();
428 int nIndex = 0;
429 int i = 0;
430 while (i < nLen) {
431 if (nIndex > 2)
432 break;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700433
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700434 FX_WCHAR c = value.GetAt(i);
Lei Zhang9559b7a2015-12-21 11:12:20 -0800435 if (FXSYS_iswdigit(c)) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700436 number[nIndex++] = ParseStringInteger(value, i, nSkip, 4);
437 i += nSkip;
438 } else {
439 i++;
440 }
441 }
442
443 if (nIndex == 2) {
444 // case2: month/day
445 // case3: day/month
446 if ((number[0] >= 1 && number[0] <= 12) &&
447 (number[1] >= 1 && number[1] <= 31)) {
448 nMonth = number[0];
449 nDay = number[1];
450 } else if ((number[0] >= 1 && number[0] <= 31) &&
451 (number[1] >= 1 && number[1] <= 12)) {
452 nDay = number[0];
453 nMonth = number[1];
Tom Sepez2f2ffec2015-07-23 14:42:09 -0700454 }
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700455
Lei Zhang9559b7a2015-12-21 11:12:20 -0800456 if (bWrongFormat)
457 *bWrongFormat = false;
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700458 } else if (nIndex == 3) {
459 // case1: year/month/day
460 // case2: month/day/year
461 // case3: day/month/year
Tom Sepez5ffacd62014-07-18 14:42:12 -0700462
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700463 if (number[0] > 12 && (number[1] >= 1 && number[1] <= 12) &&
464 (number[2] >= 1 && number[2] <= 31)) {
465 nYear = number[0];
466 nMonth = number[1];
467 nDay = number[2];
468 } else if ((number[0] >= 1 && number[0] <= 12) &&
469 (number[1] >= 1 && number[1] <= 31) && number[2] > 31) {
470 nMonth = number[0];
471 nDay = number[1];
472 nYear = number[2];
473 } else if ((number[0] >= 1 && number[0] <= 31) &&
474 (number[1] >= 1 && number[1] <= 12) && number[2] > 31) {
475 nDay = number[0];
476 nMonth = number[1];
477 nYear = number[2];
Tom Sepez2f2ffec2015-07-23 14:42:09 -0700478 }
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700479
Lei Zhang9559b7a2015-12-21 11:12:20 -0800480 if (bWrongFormat)
481 *bWrongFormat = false;
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700482 } else {
Lei Zhang9559b7a2015-12-21 11:12:20 -0800483 if (bWrongFormat)
484 *bWrongFormat = true;
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700485 return dt;
486 }
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700487
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700488 CFX_WideString swTemp;
489 swTemp.Format(L"%d/%d/%d %d:%d:%d", nMonth, nDay, nYear, nHour, nMin, nSec);
490 return JS_DateParse(swTemp.c_str());
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700491}
492
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700493double CJS_PublicMethods::MakeRegularDate(const CFX_WideString& value,
494 const CFX_WideString& format,
Lei Zhang9559b7a2015-12-21 11:12:20 -0800495 bool* bWrongFormat) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700496 double dt = JS_GetDateTime();
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700497
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700498 if (format.IsEmpty() || value.IsEmpty())
499 return dt;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700500
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700501 int nYear = JS_GetYearFromTime(dt);
502 int nMonth = JS_GetMonthFromTime(dt) + 1;
503 int nDay = JS_GetDayFromTime(dt);
504 int nHour = JS_GetHourFromTime(dt);
505 int nMin = JS_GetMinFromTime(dt);
506 int nSec = JS_GetSecFromTime(dt);
507
508 int nYearSub = 99; // nYear - 2000;
509
510 FX_BOOL bPm = FALSE;
511 FX_BOOL bExit = FALSE;
Lei Zhang9559b7a2015-12-21 11:12:20 -0800512 bool bBadFormat = false;
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700513
514 int i = 0;
515 int j = 0;
516
517 while (i < format.GetLength()) {
518 if (bExit)
519 break;
520
521 FX_WCHAR c = format.GetAt(i);
522 switch (c) {
523 case ':':
524 case '.':
525 case '-':
526 case '\\':
527 case '/':
528 i++;
529 j++;
530 break;
531
532 case 'y':
533 case 'm':
534 case 'd':
535 case 'H':
536 case 'h':
537 case 'M':
538 case 's':
539 case 't': {
540 int oldj = j;
541 int nSkip = 0;
542 int remaining = format.GetLength() - i - 1;
543
544 if (remaining == 0 || format.GetAt(i + 1) != c) {
545 switch (c) {
Tom Sepez2f2ffec2015-07-23 14:42:09 -0700546 case 'y':
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700547 i++;
548 j++;
549 break;
Tom Sepez2f2ffec2015-07-23 14:42:09 -0700550 case 'm':
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700551 nMonth = ParseStringInteger(value, j, nSkip, 2);
552 i++;
553 j += nSkip;
554 break;
Tom Sepez2f2ffec2015-07-23 14:42:09 -0700555 case 'd':
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700556 nDay = ParseStringInteger(value, j, nSkip, 2);
557 i++;
558 j += nSkip;
559 break;
Tom Sepez2f2ffec2015-07-23 14:42:09 -0700560 case 'H':
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700561 nHour = ParseStringInteger(value, j, nSkip, 2);
562 i++;
563 j += nSkip;
564 break;
Tom Sepez2f2ffec2015-07-23 14:42:09 -0700565 case '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 'M':
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700571 nMin = ParseStringInteger(value, j, nSkip, 2);
572 i++;
573 j += nSkip;
574 break;
Tom Sepez2f2ffec2015-07-23 14:42:09 -0700575 case 's':
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700576 nSec = ParseStringInteger(value, j, nSkip, 2);
577 i++;
578 j += nSkip;
579 break;
Tom Sepez2f2ffec2015-07-23 14:42:09 -0700580 case 't':
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700581 bPm = (j < value.GetLength() && value.GetAt(j) == 'p');
582 i++;
583 j++;
584 break;
585 }
586 } else if (remaining == 1 || format.GetAt(i + 2) != c) {
587 switch (c) {
588 case 'y':
589 nYear = ParseStringInteger(value, j, nSkip, 4);
590 i += 2;
591 j += nSkip;
592 break;
593 case 'm':
594 nMonth = ParseStringInteger(value, j, nSkip, 2);
595 i += 2;
596 j += nSkip;
597 break;
598 case 'd':
599 nDay = ParseStringInteger(value, j, nSkip, 2);
600 i += 2;
601 j += nSkip;
602 break;
603 case 'H':
604 nHour = ParseStringInteger(value, j, nSkip, 2);
605 i += 2;
606 j += nSkip;
607 break;
608 case 'h':
609 nHour = ParseStringInteger(value, j, nSkip, 2);
610 i += 2;
611 j += nSkip;
612 break;
613 case 'M':
614 nMin = ParseStringInteger(value, j, nSkip, 2);
615 i += 2;
616 j += nSkip;
617 break;
618 case 's':
619 nSec = ParseStringInteger(value, j, nSkip, 2);
620 i += 2;
621 j += nSkip;
622 break;
623 case 't':
624 bPm = (j + 1 < value.GetLength() && value.GetAt(j) == 'p' &&
625 value.GetAt(j + 1) == 'm');
626 i += 2;
627 j += 2;
628 break;
629 }
630 } else if (remaining == 2 || format.GetAt(i + 3) != c) {
631 switch (c) {
632 case 'm': {
633 CFX_WideString sMonth = ParseStringString(value, j, nSkip);
634 FX_BOOL bFind = FALSE;
635 for (int m = 0; m < 12; m++) {
636 if (sMonth.CompareNoCase(months[m]) == 0) {
637 nMonth = m + 1;
638 i += 3;
639 j += nSkip;
640 bFind = TRUE;
641 break;
Tom Sepez2f2ffec2015-07-23 14:42:09 -0700642 }
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700643 }
644
645 if (!bFind) {
646 nMonth = ParseStringInteger(value, j, nSkip, 3);
647 i += 3;
648 j += nSkip;
649 }
650 } break;
651 case 'y':
652 break;
Tom Sepez2f2ffec2015-07-23 14:42:09 -0700653 default:
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700654 i += 3;
655 j += 3;
656 break;
657 }
658 } else if (remaining == 3 || format.GetAt(i + 4) != c) {
659 switch (c) {
660 case 'y':
661 nYear = ParseStringInteger(value, j, nSkip, 4);
662 j += nSkip;
663 i += 4;
664 break;
665 case 'm': {
666 FX_BOOL bFind = FALSE;
667
668 CFX_WideString sMonth = ParseStringString(value, j, nSkip);
669 sMonth.MakeLower();
670
671 for (int m = 0; m < 12; m++) {
672 CFX_WideString sFullMonths = fullmonths[m];
673 sFullMonths.MakeLower();
674
675 if (sFullMonths.Find(sMonth.c_str(), 0) != -1) {
676 nMonth = m + 1;
677 i += 4;
678 j += nSkip;
679 bFind = TRUE;
680 break;
681 }
682 }
683
684 if (!bFind) {
685 nMonth = ParseStringInteger(value, j, nSkip, 4);
686 i += 4;
687 j += nSkip;
688 }
689 } break;
690 default:
691 i += 4;
692 j += 4;
693 break;
694 }
695 } else {
696 if (j >= value.GetLength() || format.GetAt(i) != value.GetAt(j)) {
Lei Zhang9559b7a2015-12-21 11:12:20 -0800697 bBadFormat = true;
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700698 bExit = TRUE;
699 }
700 i++;
701 j++;
Tom Sepez2f2ffec2015-07-23 14:42:09 -0700702 }
Tom Sepez85386422014-07-23 10:28:37 -0700703
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700704 if (oldj == j) {
Lei Zhang9559b7a2015-12-21 11:12:20 -0800705 bBadFormat = true;
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700706 bExit = TRUE;
707 }
708 }
709
710 break;
711 default:
712 if (value.GetLength() <= j) {
713 bExit = TRUE;
714 } else if (format.GetAt(i) != value.GetAt(j)) {
Lei Zhang9559b7a2015-12-21 11:12:20 -0800715 bBadFormat = true;
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700716 bExit = TRUE;
717 }
718
719 i++;
720 j++;
721 break;
722 }
723 }
724
725 if (bPm)
726 nHour += 12;
727
728 if (nYear >= 0 && nYear <= nYearSub)
729 nYear += 2000;
730
731 if (nMonth < 1 || nMonth > 12)
Lei Zhang9559b7a2015-12-21 11:12:20 -0800732 bBadFormat = true;
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700733
734 if (nDay < 1 || nDay > 31)
Lei Zhang9559b7a2015-12-21 11:12:20 -0800735 bBadFormat = true;
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700736
737 if (nHour < 0 || nHour > 24)
Lei Zhang9559b7a2015-12-21 11:12:20 -0800738 bBadFormat = true;
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700739
740 if (nMin < 0 || nMin > 60)
Lei Zhang9559b7a2015-12-21 11:12:20 -0800741 bBadFormat = true;
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700742
743 if (nSec < 0 || nSec > 60)
Lei Zhang9559b7a2015-12-21 11:12:20 -0800744 bBadFormat = true;
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700745
746 double dRet = 0;
747
Lei Zhang9559b7a2015-12-21 11:12:20 -0800748 if (bBadFormat) {
749 dRet = ParseNormalDate(value, &bBadFormat);
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700750 } else {
751 dRet = JS_MakeDate(JS_MakeDay(nYear, nMonth - 1, nDay),
752 JS_MakeTime(nHour, nMin, nSec, 0));
753
754 if (JS_PortIsNan(dRet)) {
755 dRet = JS_DateParse(value.c_str());
756 }
757 }
758
759 if (JS_PortIsNan(dRet)) {
Lei Zhang9559b7a2015-12-21 11:12:20 -0800760 dRet = ParseNormalDate(value, &bBadFormat);
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700761 }
762
Lei Zhang9559b7a2015-12-21 11:12:20 -0800763 if (bWrongFormat)
764 *bWrongFormat = bBadFormat;
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700765 return dRet;
766}
767
768CFX_WideString CJS_PublicMethods::MakeFormatDate(double dDate,
769 const CFX_WideString& format) {
770 CFX_WideString sRet = L"", sPart = L"";
771
772 int nYear = JS_GetYearFromTime(dDate);
773 int nMonth = JS_GetMonthFromTime(dDate) + 1;
774 int nDay = JS_GetDayFromTime(dDate);
775 int nHour = JS_GetHourFromTime(dDate);
776 int nMin = JS_GetMinFromTime(dDate);
777 int nSec = JS_GetSecFromTime(dDate);
778
779 int i = 0;
780 while (i < format.GetLength()) {
781 FX_WCHAR c = format.GetAt(i);
782 int remaining = format.GetLength() - i - 1;
783 sPart = L"";
784 switch (c) {
785 case 'y':
786 case 'm':
787 case 'd':
788 case 'H':
789 case 'h':
790 case 'M':
791 case 's':
792 case 't':
793 if (remaining == 0 || format.GetAt(i + 1) != c) {
794 switch (c) {
795 case 'y':
796 sPart += c;
797 break;
798 case 'm':
799 sPart.Format(L"%d", nMonth);
800 break;
801 case 'd':
802 sPart.Format(L"%d", nDay);
803 break;
804 case 'H':
805 sPart.Format(L"%d", nHour);
806 break;
807 case 'h':
808 sPart.Format(L"%d", nHour > 12 ? nHour - 12 : nHour);
809 break;
810 case 'M':
811 sPart.Format(L"%d", nMin);
812 break;
813 case 's':
814 sPart.Format(L"%d", nSec);
815 break;
816 case 't':
817 sPart += nHour > 12 ? 'p' : 'a';
818 break;
819 }
820 i++;
821 } else if (remaining == 1 || format.GetAt(i + 2) != c) {
822 switch (c) {
823 case 'y':
824 sPart.Format(L"%02d", nYear - (nYear / 100) * 100);
825 break;
826 case 'm':
827 sPart.Format(L"%02d", nMonth);
828 break;
829 case 'd':
830 sPart.Format(L"%02d", nDay);
831 break;
832 case 'H':
833 sPart.Format(L"%02d", nHour);
834 break;
835 case 'h':
836 sPart.Format(L"%02d", nHour > 12 ? nHour - 12 : nHour);
837 break;
838 case 'M':
839 sPart.Format(L"%02d", nMin);
840 break;
841 case 's':
842 sPart.Format(L"%02d", nSec);
843 break;
844 case 't':
845 sPart = nHour > 12 ? L"pm" : L"am";
846 break;
847 }
848 i += 2;
849 } else if (remaining == 2 || format.GetAt(i + 3) != c) {
850 switch (c) {
851 case 'm':
852 i += 3;
853 if (nMonth > 0 && nMonth <= 12)
854 sPart += months[nMonth - 1];
855 break;
856 default:
857 i += 3;
858 sPart += c;
859 sPart += c;
860 sPart += c;
861 break;
862 }
863 } else if (remaining == 3 || format.GetAt(i + 4) != c) {
864 switch (c) {
865 case 'y':
866 sPart.Format(L"%04d", nYear);
867 i += 4;
868 break;
869 case 'm':
870 i += 4;
871 if (nMonth > 0 && nMonth <= 12)
872 sPart += fullmonths[nMonth - 1];
873 break;
874 default:
875 i += 4;
876 sPart += c;
877 sPart += c;
878 sPart += c;
879 sPart += c;
880 break;
881 }
882 } else {
883 i++;
884 sPart += c;
885 }
886 break;
887 default:
888 i++;
889 sPart += c;
890 break;
Tom Sepez2f2ffec2015-07-23 14:42:09 -0700891 }
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700892
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700893 sRet += sPart;
894 }
895
896 return sRet;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700897}
898
899/* -------------------------------------------------------------------------- */
900
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700901// function AFNumber_Format(nDec, sepStyle, negStyle, currStyle, strCurrency,
902// bCurrencyPrepend)
Tom Sepezba038bc2015-10-08 12:03:00 -0700903FX_BOOL CJS_PublicMethods::AFNumber_Format(IJS_Context* cc,
Lei Zhang945fdb72015-11-11 10:18:16 -0800904 const std::vector<CJS_Value>& params,
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700905 CJS_Value& vRet,
906 CFX_WideString& sError) {
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700907#if _FX_OS_ != _FX_ANDROID_
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700908 CJS_Context* pContext = (CJS_Context*)cc;
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700909 if (params.size() != 6) {
910 sError = JSGetStringFromID(pContext, IDS_STRING_JSPARAMERROR);
911 return FALSE;
912 }
Tom Sepez67fd5df2015-10-08 12:24:19 -0700913
914 CJS_Runtime* pRuntime = CJS_Runtime::FromContext(cc);
915 CJS_EventHandler* pEvent = pContext->GetEventHandler();
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700916 if (!pEvent->m_pValue)
917 return FALSE;
Tom Sepez67fd5df2015-10-08 12:24:19 -0700918
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700919 CFX_WideString& Value = pEvent->Value();
920 CFX_ByteString strValue = StrTrim(CFX_ByteString::FromUnicode(Value));
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700921 if (strValue.IsEmpty())
Tom Sepez2f2ffec2015-07-23 14:42:09 -0700922 return TRUE;
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700923
924 int iDec = params[0].ToInt();
925 int iSepStyle = params[1].ToInt();
926 int iNegStyle = params[2].ToInt();
927 // params[3] is iCurrStyle, it's not used.
928 std::wstring wstrCurrency(params[4].ToCFXWideString().c_str());
929 FX_BOOL bCurrencyPrepend = params[5].ToBool();
930
931 if (iDec < 0)
932 iDec = -iDec;
933
934 if (iSepStyle < 0 || iSepStyle > 3)
935 iSepStyle = 0;
936
937 if (iNegStyle < 0 || iNegStyle > 3)
938 iNegStyle = 0;
939
940 //////////////////////////////////////////////////////
941 // for processing decimal places
942 strValue.Replace(",", ".");
943 double dValue = atof(strValue);
944 if (iDec > 0)
Tom Sepezdfbf8e72015-10-14 14:17:26 -0700945 dValue += DOUBLE_CORRECT;
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700946
947 int iDec2;
948 int iNegative = 0;
949
950 strValue = fcvt(dValue, iDec, &iDec2, &iNegative);
951 if (strValue.IsEmpty()) {
952 dValue = 0;
953 strValue = fcvt(dValue, iDec, &iDec2, &iNegative);
954 if (strValue.IsEmpty()) {
955 strValue = "0";
956 iDec2 = 1;
957 }
958 }
959
960 if (iDec2 < 0) {
961 for (int iNum = 0; iNum < abs(iDec2); iNum++) {
962 strValue = "0" + strValue;
963 }
964 iDec2 = 0;
965 }
966 int iMax = strValue.GetLength();
967 if (iDec2 > iMax) {
968 for (int iNum = 0; iNum <= iDec2 - iMax; iNum++) {
969 strValue += "0";
970 }
971 iMax = iDec2 + 1;
972 }
973 ///////////////////////////////////////////////////////
974 // for processing seperator style
975 if (iDec2 < iMax) {
976 if (iSepStyle == 0 || iSepStyle == 1) {
977 strValue.Insert(iDec2, '.');
978 iMax++;
979 } else if (iSepStyle == 2 || iSepStyle == 3) {
980 strValue.Insert(iDec2, ',');
981 iMax++;
982 }
983
984 if (iDec2 == 0)
985 strValue.Insert(iDec2, '0');
986 }
987 if (iSepStyle == 0 || iSepStyle == 2) {
988 char cSeperator;
989 if (iSepStyle == 0)
990 cSeperator = ',';
991 else
992 cSeperator = '.';
993
Tom Sepezdfbf8e72015-10-14 14:17:26 -0700994 for (int iDecPositive = iDec2 - 3; iDecPositive > 0; iDecPositive -= 3) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700995 strValue.Insert(iDecPositive, cSeperator);
996 iMax++;
997 }
998 }
999
1000 //////////////////////////////////////////////////////////////////////
1001 // for processing currency string
1002
1003 Value = CFX_WideString::FromLocal(strValue);
1004 std::wstring strValue2 = Value.c_str();
1005
1006 if (bCurrencyPrepend)
1007 strValue2 = wstrCurrency + strValue2;
1008 else
1009 strValue2 = strValue2 + wstrCurrency;
1010
1011 /////////////////////////////////////////////////////////////////////////
1012 // for processing negative style
1013 if (iNegative) {
1014 if (iNegStyle == 0) {
1015 strValue2.insert(0, L"-");
1016 }
1017 if (iNegStyle == 2 || iNegStyle == 3) {
1018 strValue2.insert(0, L"(");
1019 strValue2.insert(strValue2.length(), L")");
1020 }
1021 if (iNegStyle == 1 || iNegStyle == 3) {
1022 if (Field* fTarget = pEvent->Target_Field()) {
Tom Sepez67fd5df2015-10-08 12:24:19 -07001023 CJS_Array arColor(pRuntime);
1024 CJS_Value vColElm(pRuntime);
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001025 vColElm = L"RGB";
1026 arColor.SetElement(0, vColElm);
1027 vColElm = 1;
1028 arColor.SetElement(1, vColElm);
1029 vColElm = 0;
1030 arColor.SetElement(2, vColElm);
1031
1032 arColor.SetElement(3, vColElm);
1033
Tom Sepez67fd5df2015-10-08 12:24:19 -07001034 CJS_PropValue vProp(pRuntime);
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001035 vProp.StartGetting();
1036 vProp << arColor;
1037 vProp.StartSetting();
1038 fTarget->textColor(cc, vProp, sError); // red
1039 }
1040 }
1041 } else {
1042 if (iNegStyle == 1 || iNegStyle == 3) {
1043 if (Field* fTarget = pEvent->Target_Field()) {
Tom Sepez67fd5df2015-10-08 12:24:19 -07001044 CJS_Array arColor(pRuntime);
1045 CJS_Value vColElm(pRuntime);
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001046 vColElm = L"RGB";
1047 arColor.SetElement(0, vColElm);
1048 vColElm = 0;
1049 arColor.SetElement(1, vColElm);
1050 arColor.SetElement(2, vColElm);
1051 arColor.SetElement(3, vColElm);
1052
Tom Sepez67fd5df2015-10-08 12:24:19 -07001053 CJS_PropValue vProp(pRuntime);
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001054 vProp.StartGetting();
1055 fTarget->textColor(cc, vProp, sError);
1056
Tom Sepez67fd5df2015-10-08 12:24:19 -07001057 CJS_Array aProp(pRuntime);
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001058 vProp.ConvertToArray(aProp);
1059
1060 CPWL_Color crProp;
1061 CPWL_Color crColor;
1062 color::ConvertArrayToPWLColor(aProp, crProp);
1063 color::ConvertArrayToPWLColor(arColor, crColor);
1064
1065 if (crColor != crProp) {
Tom Sepez67fd5df2015-10-08 12:24:19 -07001066 CJS_PropValue vProp2(pRuntime);
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001067 vProp2.StartGetting();
1068 vProp2 << arColor;
1069 vProp2.StartSetting();
1070 fTarget->textColor(cc, vProp2, sError);
1071 }
1072 }
1073 }
1074 }
1075 Value = strValue2.c_str();
1076#endif
1077 return TRUE;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07001078}
1079
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001080// function AFNumber_Keystroke(nDec, sepStyle, negStyle, currStyle, strCurrency,
1081// bCurrencyPrepend)
Lei Zhang945fdb72015-11-11 10:18:16 -08001082FX_BOOL CJS_PublicMethods::AFNumber_Keystroke(
1083 IJS_Context* cc,
1084 const std::vector<CJS_Value>& params,
1085 CJS_Value& vRet,
1086 CFX_WideString& sError) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001087 CJS_Context* pContext = (CJS_Context*)cc;
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001088 CJS_EventHandler* pEvent = pContext->GetEventHandler();
Lei Zhanga6d9f0e2015-06-13 00:48:38 -07001089
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001090 if (params.size() < 2)
1091 return FALSE;
1092 int iSepStyle = params[1].ToInt();
Lei Zhanga6d9f0e2015-06-13 00:48:38 -07001093
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001094 if (iSepStyle < 0 || iSepStyle > 3)
1095 iSepStyle = 0;
1096 if (!pEvent->m_pValue)
1097 return FALSE;
1098 CFX_WideString& val = pEvent->Value();
1099 CFX_WideString& w_strChange = pEvent->Change();
1100 CFX_WideString w_strValue = val;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07001101
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001102 if (pEvent->WillCommit()) {
1103 CFX_WideString wstrChange = w_strChange;
1104 CFX_WideString wstrValue = StrLTrim(w_strValue.c_str());
1105 if (wstrValue.IsEmpty())
1106 return TRUE;
Lei Zhanga6d9f0e2015-06-13 00:48:38 -07001107
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001108 CFX_WideString swTemp = wstrValue;
1109 swTemp.Replace(L",", L".");
1110 if (!IsNumber(swTemp.c_str())) {
1111 pEvent->Rc() = FALSE;
1112 sError = JSGetStringFromID(pContext, IDS_STRING_JSAFNUMBER_KEYSTROKE);
1113 Alert(pContext, sError.c_str());
1114 return TRUE;
Tom Sepez2f2ffec2015-07-23 14:42:09 -07001115 }
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001116 return TRUE; // it happens after the last keystroke and before validating,
1117 }
Tom Sepez4f7bc042015-04-27 12:06:58 -07001118
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001119 std::wstring w_strValue2 = w_strValue.c_str();
1120 std::wstring w_strChange2 = w_strChange.c_str();
1121 std::wstring w_strSelected;
1122 if (-1 != pEvent->SelStart())
1123 w_strSelected = w_strValue2.substr(pEvent->SelStart(),
1124 (pEvent->SelEnd() - pEvent->SelStart()));
Lei Zhangb9c31972015-08-11 14:09:35 -07001125 bool bHasSign = (w_strValue2.find('-') != std::wstring::npos) &&
1126 (w_strSelected.find('-') == std::wstring::npos);
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001127 if (bHasSign) {
1128 // can't insert "change" in front to sign postion.
1129 if (pEvent->SelStart() == 0) {
1130 FX_BOOL& bRc = pEvent->Rc();
1131 bRc = FALSE;
1132 return TRUE;
Tom Sepez2f2ffec2015-07-23 14:42:09 -07001133 }
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001134 }
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07001135
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001136 char cSep = L'.';
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07001137
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001138 switch (iSepStyle) {
Tom Sepez2f2ffec2015-07-23 14:42:09 -07001139 case 0:
1140 case 1:
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001141 cSep = L'.';
1142 break;
Tom Sepez2f2ffec2015-07-23 14:42:09 -07001143 case 2:
1144 case 3:
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001145 cSep = L',';
1146 break;
1147 }
Lei Zhanga6d9f0e2015-06-13 00:48:38 -07001148
Lei Zhangb9c31972015-08-11 14:09:35 -07001149 bool bHasSep = (w_strValue2.find(cSep) != std::wstring::npos);
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001150 for (std::wstring::iterator it = w_strChange2.begin();
1151 it != w_strChange2.end(); it++) {
1152 if (*it == cSep) {
1153 if (bHasSep) {
1154 FX_BOOL& bRc = pEvent->Rc();
1155 bRc = FALSE;
Tom Sepez2f2ffec2015-07-23 14:42:09 -07001156 return TRUE;
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001157 }
1158 bHasSep = TRUE;
1159 continue;
1160 }
1161 if (*it == L'-') {
1162 if (bHasSign) {
1163 FX_BOOL& bRc = pEvent->Rc();
1164 bRc = FALSE;
1165 return TRUE;
1166 }
Lei Zhang9559b7a2015-12-21 11:12:20 -08001167 // sign's position is not correct
1168 if (it != w_strChange2.begin()) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001169 FX_BOOL& bRc = pEvent->Rc();
1170 bRc = FALSE;
1171 return TRUE;
1172 }
1173 if (pEvent->SelStart() != 0) {
1174 FX_BOOL& bRc = pEvent->Rc();
1175 bRc = FALSE;
1176 return TRUE;
1177 }
1178 bHasSign = TRUE;
1179 continue;
1180 }
1181
Lei Zhang9559b7a2015-12-21 11:12:20 -08001182 if (!FXSYS_iswdigit(*it)) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001183 FX_BOOL& bRc = pEvent->Rc();
1184 bRc = FALSE;
1185 return TRUE;
1186 }
1187 }
1188
1189 std::wstring w_prefix = w_strValue2.substr(0, pEvent->SelStart());
1190 std::wstring w_postfix;
1191 if (pEvent->SelEnd() < (int)w_strValue2.length())
1192 w_postfix = w_strValue2.substr(pEvent->SelEnd());
1193 w_strValue2 = w_prefix + w_strChange2 + w_postfix;
1194 w_strValue = w_strValue2.c_str();
1195 val = w_strValue;
1196 return TRUE;
1197}
1198
1199// function AFPercent_Format(nDec, sepStyle)
Lei Zhang945fdb72015-11-11 10:18:16 -08001200FX_BOOL CJS_PublicMethods::AFPercent_Format(
1201 IJS_Context* cc,
1202 const std::vector<CJS_Value>& params,
1203 CJS_Value& vRet,
1204 CFX_WideString& sError) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001205#if _FX_OS_ != _FX_ANDROID_
1206 CJS_Context* pContext = (CJS_Context*)cc;
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001207 CJS_EventHandler* pEvent = pContext->GetEventHandler();
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001208
1209 if (params.size() != 2) {
1210 sError = JSGetStringFromID(pContext, IDS_STRING_JSPARAMERROR);
1211 return FALSE;
1212 }
1213 if (!pEvent->m_pValue)
1214 return FALSE;
1215
1216 CFX_WideString& Value = pEvent->Value();
1217 CFX_ByteString strValue = StrTrim(CFX_ByteString::FromUnicode(Value));
1218 if (strValue.IsEmpty())
1219 return TRUE;
1220
1221 int iDec = params[0].ToInt();
1222 if (iDec < 0)
1223 iDec = -iDec;
1224
1225 int iSepStyle = params[1].ToInt();
1226 if (iSepStyle < 0 || iSepStyle > 3)
1227 iSepStyle = 0;
1228
1229 //////////////////////////////////////////////////////
1230 // for processing decimal places
1231 double dValue = atof(strValue);
1232 dValue *= 100;
1233 if (iDec > 0)
Lei Zhang9559b7a2015-12-21 11:12:20 -08001234 dValue += DOUBLE_CORRECT;
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001235
1236 int iDec2;
1237 int iNegative = 0;
1238 strValue = fcvt(dValue, iDec, &iDec2, &iNegative);
1239 if (strValue.IsEmpty()) {
1240 dValue = 0;
1241 strValue = fcvt(dValue, iDec, &iDec2, &iNegative);
1242 }
1243
1244 if (iDec2 < 0) {
1245 for (int iNum = 0; iNum < abs(iDec2); iNum++) {
1246 strValue = "0" + strValue;
1247 }
1248 iDec2 = 0;
1249 }
1250 int iMax = strValue.GetLength();
1251 if (iDec2 > iMax) {
1252 for (int iNum = 0; iNum <= iDec2 - iMax; iNum++) {
1253 strValue += "0";
1254 }
1255 iMax = iDec2 + 1;
1256 }
1257 ///////////////////////////////////////////////////////
1258 // for processing seperator style
1259 if (iDec2 < iMax) {
1260 if (iSepStyle == 0 || iSepStyle == 1) {
1261 strValue.Insert(iDec2, '.');
1262 iMax++;
1263 } else if (iSepStyle == 2 || iSepStyle == 3) {
1264 strValue.Insert(iDec2, ',');
1265 iMax++;
1266 }
1267
1268 if (iDec2 == 0)
1269 strValue.Insert(iDec2, '0');
1270 }
1271 if (iSepStyle == 0 || iSepStyle == 2) {
1272 char cSeperator;
1273 if (iSepStyle == 0)
1274 cSeperator = ',';
1275 else
1276 cSeperator = '.';
1277
Tom Sepezdfbf8e72015-10-14 14:17:26 -07001278 for (int iDecPositive = iDec2 - 3; iDecPositive > 0; iDecPositive -= 3) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001279 strValue.Insert(iDecPositive, cSeperator);
1280 iMax++;
1281 }
1282 }
1283 ////////////////////////////////////////////////////////////////////
1284 // negative mark
1285 if (iNegative)
1286 strValue = "-" + strValue;
1287 strValue += "%";
1288 Value = CFX_WideString::FromLocal(strValue);
1289#endif
1290 return TRUE;
1291}
1292// AFPercent_Keystroke(nDec, sepStyle)
Lei Zhang945fdb72015-11-11 10:18:16 -08001293FX_BOOL CJS_PublicMethods::AFPercent_Keystroke(
1294 IJS_Context* cc,
1295 const std::vector<CJS_Value>& params,
1296 CJS_Value& vRet,
1297 CFX_WideString& sError) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001298 return AFNumber_Keystroke(cc, params, vRet, sError);
1299}
1300
1301// function AFDate_FormatEx(cFormat)
Tom Sepezba038bc2015-10-08 12:03:00 -07001302FX_BOOL CJS_PublicMethods::AFDate_FormatEx(IJS_Context* cc,
Lei Zhang945fdb72015-11-11 10:18:16 -08001303 const std::vector<CJS_Value>& params,
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001304 CJS_Value& vRet,
1305 CFX_WideString& sError) {
1306 CJS_Context* pContext = (CJS_Context*)cc;
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001307 CJS_EventHandler* pEvent = pContext->GetEventHandler();
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001308
1309 if (params.size() != 1) {
1310 sError = JSGetStringFromID(pContext, IDS_STRING_JSPARAMERROR);
1311 return FALSE;
1312 }
1313 if (!pEvent->m_pValue)
1314 return FALSE;
1315
1316 CFX_WideString& val = pEvent->Value();
1317 CFX_WideString strValue = val;
1318 if (strValue.IsEmpty())
1319 return TRUE;
1320
1321 CFX_WideString sFormat = params[0].ToCFXWideString();
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001322 double dDate = 0.0f;
1323
1324 if (strValue.Find(L"GMT") != -1) {
1325 // for GMT format time
1326 // such as "Tue Aug 11 14:24:16 GMT+08002009"
1327 dDate = MakeInterDate(strValue);
1328 } else {
Lei Zhang9559b7a2015-12-21 11:12:20 -08001329 dDate = MakeRegularDate(strValue, sFormat, nullptr);
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001330 }
1331
1332 if (JS_PortIsNan(dDate)) {
1333 CFX_WideString swMsg;
1334 swMsg.Format(JSGetStringFromID(pContext, IDS_STRING_JSPARSEDATE).c_str(),
1335 sFormat.c_str());
1336 Alert(pContext, swMsg.c_str());
1337 return FALSE;
1338 }
1339
1340 val = MakeFormatDate(dDate, sFormat);
1341 return TRUE;
1342}
1343
1344double CJS_PublicMethods::MakeInterDate(CFX_WideString strValue) {
1345 int nHour;
1346 int nMin;
1347 int nSec;
1348 int nYear;
1349 int nMonth;
1350 int nDay;
1351
1352 CFX_WideStringArray wsArray;
1353 CFX_WideString sMonth = L"";
1354 CFX_WideString sTemp = L"";
1355 int nSize = strValue.GetLength();
1356
1357 for (int i = 0; i < nSize; i++) {
1358 FX_WCHAR c = strValue.GetAt(i);
1359 if (c == L' ' || c == L':') {
1360 wsArray.Add(sTemp);
1361 sTemp = L"";
1362 continue;
1363 }
1364
1365 sTemp += c;
1366 }
1367
1368 wsArray.Add(sTemp);
1369 if (wsArray.GetSize() != 8)
1370 return 0;
1371
1372 sTemp = wsArray[1];
1373 if (sTemp.Compare(L"Jan") == 0)
1374 nMonth = 1;
1375 if (sTemp.Compare(L"Feb") == 0)
1376 nMonth = 2;
1377 if (sTemp.Compare(L"Mar") == 0)
1378 nMonth = 3;
1379 if (sTemp.Compare(L"Apr") == 0)
1380 nMonth = 4;
1381 if (sTemp.Compare(L"May") == 0)
1382 nMonth = 5;
1383 if (sTemp.Compare(L"Jun") == 0)
1384 nMonth = 6;
1385 if (sTemp.Compare(L"Jul") == 0)
1386 nMonth = 7;
1387 if (sTemp.Compare(L"Aug") == 0)
1388 nMonth = 8;
1389 if (sTemp.Compare(L"Sep") == 0)
1390 nMonth = 9;
1391 if (sTemp.Compare(L"Oct") == 0)
1392 nMonth = 10;
1393 if (sTemp.Compare(L"Nov") == 0)
1394 nMonth = 11;
1395 if (sTemp.Compare(L"Dec") == 0)
1396 nMonth = 12;
1397
1398 nDay = (int)ParseStringToNumber(wsArray[2].c_str());
1399 nHour = (int)ParseStringToNumber(wsArray[3].c_str());
1400 nMin = (int)ParseStringToNumber(wsArray[4].c_str());
1401 nSec = (int)ParseStringToNumber(wsArray[5].c_str());
1402 nYear = (int)ParseStringToNumber(wsArray[7].c_str());
1403
1404 double dRet = JS_MakeDate(JS_MakeDay(nYear, nMonth - 1, nDay),
1405 JS_MakeTime(nHour, nMin, nSec, 0));
1406
1407 if (JS_PortIsNan(dRet)) {
1408 dRet = JS_DateParse(strValue.c_str());
1409 }
1410
1411 return dRet;
1412}
1413
1414// AFDate_KeystrokeEx(cFormat)
Lei Zhang945fdb72015-11-11 10:18:16 -08001415FX_BOOL CJS_PublicMethods::AFDate_KeystrokeEx(
1416 IJS_Context* cc,
1417 const std::vector<CJS_Value>& params,
1418 CJS_Value& vRet,
1419 CFX_WideString& sError) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001420 CJS_Context* pContext = (CJS_Context*)cc;
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001421 CJS_EventHandler* pEvent = pContext->GetEventHandler();
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001422
1423 if (params.size() != 1) {
1424 sError = L"AFDate_KeystrokeEx's parameters' size r not correct";
1425 return FALSE;
1426 }
1427
1428 if (pEvent->WillCommit()) {
1429 if (!pEvent->m_pValue)
1430 return FALSE;
1431 CFX_WideString strValue = pEvent->Value();
1432 if (strValue.IsEmpty())
1433 return TRUE;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07001434
Tom Sepez2f2ffec2015-07-23 14:42:09 -07001435 CFX_WideString sFormat = params[0].ToCFXWideString();
Lei Zhang9559b7a2015-12-21 11:12:20 -08001436 bool bWrongFormat = FALSE;
1437 double dRet = MakeRegularDate(strValue, sFormat, &bWrongFormat);
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001438 if (bWrongFormat || JS_PortIsNan(dRet)) {
1439 CFX_WideString swMsg;
1440 swMsg.Format(JSGetStringFromID(pContext, IDS_STRING_JSPARSEDATE).c_str(),
1441 sFormat.c_str());
1442 Alert(pContext, swMsg.c_str());
1443 pEvent->Rc() = FALSE;
1444 return TRUE;
Tom Sepez2f2ffec2015-07-23 14:42:09 -07001445 }
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001446 }
1447 return TRUE;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07001448}
1449
Tom Sepezba038bc2015-10-08 12:03:00 -07001450FX_BOOL CJS_PublicMethods::AFDate_Format(IJS_Context* cc,
Lei Zhang945fdb72015-11-11 10:18:16 -08001451 const std::vector<CJS_Value>& params,
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001452 CJS_Value& vRet,
1453 CFX_WideString& sError) {
Tom Sepez67fd5df2015-10-08 12:24:19 -07001454 CJS_Context* pContext = (CJS_Context*)cc;
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001455 if (params.size() != 1) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001456 sError = JSGetStringFromID(pContext, IDS_STRING_JSPARAMERROR);
1457 return FALSE;
1458 }
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07001459
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001460 int iIndex = params[0].ToInt();
1461 const FX_WCHAR* cFormats[] = {L"m/d",
1462 L"m/d/yy",
1463 L"mm/dd/yy",
1464 L"mm/yy",
1465 L"d-mmm",
1466 L"d-mmm-yy",
1467 L"dd-mmm-yy",
1468 L"yy-mm-dd",
1469 L"mmm-yy",
1470 L"mmmm-yy",
1471 L"mmm d, yyyy",
1472 L"mmmm d, yyyy",
1473 L"m/d/yy h:MM tt",
1474 L"m/d/yy HH:MM"};
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07001475
Lei Zhanga0f67242015-08-17 15:39:30 -07001476 if (iIndex < 0 || (static_cast<size_t>(iIndex) >= FX_ArraySize(cFormats)))
1477 iIndex = 0;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07001478
Lei Zhang945fdb72015-11-11 10:18:16 -08001479 std::vector<CJS_Value> newParams;
Tom Sepez67fd5df2015-10-08 12:24:19 -07001480 newParams.push_back(
1481 CJS_Value(CJS_Runtime::FromContext(cc), cFormats[iIndex]));
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001482 return AFDate_FormatEx(cc, newParams, vRet, sError);
1483}
Lei Zhanga6d9f0e2015-06-13 00:48:38 -07001484
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001485// AFDate_KeystrokeEx(cFormat)
Lei Zhang945fdb72015-11-11 10:18:16 -08001486FX_BOOL CJS_PublicMethods::AFDate_Keystroke(
1487 IJS_Context* cc,
1488 const std::vector<CJS_Value>& params,
1489 CJS_Value& vRet,
1490 CFX_WideString& sError) {
Tom Sepez67fd5df2015-10-08 12:24:19 -07001491 CJS_Context* pContext = (CJS_Context*)cc;
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001492 if (params.size() != 1) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001493 sError = JSGetStringFromID(pContext, IDS_STRING_JSPARAMERROR);
1494 return FALSE;
1495 }
1496
1497 int iIndex = params[0].ToInt();
1498 const FX_WCHAR* cFormats[] = {L"m/d",
1499 L"m/d/yy",
1500 L"mm/dd/yy",
1501 L"mm/yy",
1502 L"d-mmm",
1503 L"d-mmm-yy",
1504 L"dd-mmm-yy",
1505 L"yy-mm-dd",
1506 L"mmm-yy",
1507 L"mmmm-yy",
1508 L"mmm d, yyyy",
1509 L"mmmm d, yyyy",
1510 L"m/d/yy h:MM tt",
1511 L"m/d/yy HH:MM"};
1512
Lei Zhanga0f67242015-08-17 15:39:30 -07001513 if (iIndex < 0 || (static_cast<size_t>(iIndex) >= FX_ArraySize(cFormats)))
1514 iIndex = 0;
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001515
Lei Zhang945fdb72015-11-11 10:18:16 -08001516 std::vector<CJS_Value> newParams;
Tom Sepez67fd5df2015-10-08 12:24:19 -07001517 newParams.push_back(
1518 CJS_Value(CJS_Runtime::FromContext(cc), cFormats[iIndex]));
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001519 return AFDate_KeystrokeEx(cc, newParams, vRet, sError);
1520}
1521
1522// function AFTime_Format(ptf)
Tom Sepezba038bc2015-10-08 12:03:00 -07001523FX_BOOL CJS_PublicMethods::AFTime_Format(IJS_Context* cc,
Lei Zhang945fdb72015-11-11 10:18:16 -08001524 const std::vector<CJS_Value>& params,
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001525 CJS_Value& vRet,
1526 CFX_WideString& sError) {
Tom Sepez67fd5df2015-10-08 12:24:19 -07001527 CJS_Context* pContext = (CJS_Context*)cc;
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001528 if (params.size() != 1) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001529 sError = JSGetStringFromID(pContext, IDS_STRING_JSPARAMERROR);
1530 return FALSE;
1531 }
1532
1533 int iIndex = params[0].ToInt();
1534 const FX_WCHAR* cFormats[] = {L"HH:MM", L"h:MM tt", L"HH:MM:ss",
1535 L"h:MM:ss tt"};
1536
Lei Zhanga0f67242015-08-17 15:39:30 -07001537 if (iIndex < 0 || (static_cast<size_t>(iIndex) >= FX_ArraySize(cFormats)))
1538 iIndex = 0;
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001539
Lei Zhang945fdb72015-11-11 10:18:16 -08001540 std::vector<CJS_Value> newParams;
Tom Sepez67fd5df2015-10-08 12:24:19 -07001541 newParams.push_back(
1542 CJS_Value(CJS_Runtime::FromContext(cc), cFormats[iIndex]));
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001543 return AFDate_FormatEx(cc, newParams, vRet, sError);
1544}
1545
Lei Zhang945fdb72015-11-11 10:18:16 -08001546FX_BOOL CJS_PublicMethods::AFTime_Keystroke(
1547 IJS_Context* cc,
1548 const std::vector<CJS_Value>& params,
1549 CJS_Value& vRet,
1550 CFX_WideString& sError) {
Tom Sepez67fd5df2015-10-08 12:24:19 -07001551 CJS_Context* pContext = (CJS_Context*)cc;
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001552 if (params.size() != 1) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001553 sError = JSGetStringFromID(pContext, IDS_STRING_JSPARAMERROR);
1554 return FALSE;
1555 }
1556
1557 int iIndex = params[0].ToInt();
1558 const FX_WCHAR* cFormats[] = {L"HH:MM", L"h:MM tt", L"HH:MM:ss",
1559 L"h:MM:ss tt"};
1560
Lei Zhanga0f67242015-08-17 15:39:30 -07001561 if (iIndex < 0 || (static_cast<size_t>(iIndex) >= FX_ArraySize(cFormats)))
1562 iIndex = 0;
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001563
Lei Zhang945fdb72015-11-11 10:18:16 -08001564 std::vector<CJS_Value> newParams;
Tom Sepez67fd5df2015-10-08 12:24:19 -07001565 newParams.push_back(
1566 CJS_Value(CJS_Runtime::FromContext(cc), cFormats[iIndex]));
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001567 return AFDate_KeystrokeEx(cc, newParams, vRet, sError);
1568}
1569
Tom Sepezba038bc2015-10-08 12:03:00 -07001570FX_BOOL CJS_PublicMethods::AFTime_FormatEx(IJS_Context* cc,
Lei Zhang945fdb72015-11-11 10:18:16 -08001571 const std::vector<CJS_Value>& params,
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001572 CJS_Value& vRet,
1573 CFX_WideString& sError) {
1574 return AFDate_FormatEx(cc, params, vRet, sError);
1575}
1576
Lei Zhang945fdb72015-11-11 10:18:16 -08001577FX_BOOL CJS_PublicMethods::AFTime_KeystrokeEx(
1578 IJS_Context* cc,
1579 const std::vector<CJS_Value>& params,
1580 CJS_Value& vRet,
1581 CFX_WideString& sError) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001582 return AFDate_KeystrokeEx(cc, params, vRet, sError);
1583}
1584
1585// function AFSpecial_Format(psf)
Lei Zhang945fdb72015-11-11 10:18:16 -08001586FX_BOOL CJS_PublicMethods::AFSpecial_Format(
1587 IJS_Context* cc,
1588 const std::vector<CJS_Value>& params,
1589 CJS_Value& vRet,
1590 CFX_WideString& sError) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001591 CJS_Context* pContext = (CJS_Context*)cc;
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001592
1593 if (params.size() != 1) {
1594 sError = JSGetStringFromID(pContext, IDS_STRING_JSPARAMERROR);
1595 return FALSE;
1596 }
1597
1598 std::string cFormat;
1599 int iIndex = params[0].ToInt();
1600
1601 CJS_EventHandler* pEvent = pContext->GetEventHandler();
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001602 if (!pEvent->m_pValue)
1603 return FALSE;
1604 CFX_WideString& Value = pEvent->Value();
1605 std::string strSrc = CFX_ByteString::FromUnicode(Value).c_str();
1606
1607 switch (iIndex) {
Tom Sepez2f2ffec2015-07-23 14:42:09 -07001608 case 0:
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001609 cFormat = "99999";
1610 break;
Tom Sepez2f2ffec2015-07-23 14:42:09 -07001611 case 1:
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001612 cFormat = "99999-9999";
1613 break;
1614 case 2: {
1615 std::string NumberStr;
1616 util::printx("9999999999", strSrc, NumberStr);
1617 if (NumberStr.length() >= 10)
1618 cFormat = "(999) 999-9999";
1619 else
1620 cFormat = "999-9999";
1621 break;
1622 }
Tom Sepez2f2ffec2015-07-23 14:42:09 -07001623 case 3:
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001624 cFormat = "999-99-9999";
1625 break;
1626 }
1627
1628 std::string strDes;
1629 util::printx(cFormat, strSrc, strDes);
1630 Value = CFX_WideString::FromLocal(strDes.c_str());
1631 return TRUE;
1632}
1633
1634// function AFSpecial_KeystrokeEx(mask)
Lei Zhang945fdb72015-11-11 10:18:16 -08001635FX_BOOL CJS_PublicMethods::AFSpecial_KeystrokeEx(
1636 IJS_Context* cc,
1637 const std::vector<CJS_Value>& params,
1638 CJS_Value& vRet,
1639 CFX_WideString& sError) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001640 CJS_Context* pContext = (CJS_Context*)cc;
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001641 CJS_EventHandler* pEvent = pContext->GetEventHandler();
1642
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001643 if (params.size() < 1) {
1644 sError = JSGetStringFromID(pContext, IDS_STRING_JSPARAMERROR);
1645 return FALSE;
1646 }
1647
1648 if (!pEvent->m_pValue)
1649 return FALSE;
1650 CFX_WideString& valEvent = pEvent->Value();
1651
1652 CFX_WideString wstrMask = params[0].ToCFXWideString();
1653 if (wstrMask.IsEmpty())
1654 return TRUE;
1655
Lei Zhanga0f67242015-08-17 15:39:30 -07001656 const size_t wstrMaskLen = wstrMask.GetLength();
1657 const std::wstring wstrValue = valEvent.c_str();
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001658
1659 if (pEvent->WillCommit()) {
1660 if (wstrValue.empty())
1661 return TRUE;
Lei Zhanga0f67242015-08-17 15:39:30 -07001662 size_t iIndexMask = 0;
1663 for (const auto& w_Value : wstrValue) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001664 if (!maskSatisfied(w_Value, wstrMask[iIndexMask]))
Tom Sepez2f2ffec2015-07-23 14:42:09 -07001665 break;
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001666 iIndexMask++;
Tom Sepez2f2ffec2015-07-23 14:42:09 -07001667 }
Lei Zhanga6d9f0e2015-06-13 00:48:38 -07001668
Lei Zhanga0f67242015-08-17 15:39:30 -07001669 if (iIndexMask != wstrMaskLen ||
1670 (iIndexMask != wstrValue.size() && wstrMaskLen != 0)) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001671 Alert(
1672 pContext,
1673 JSGetStringFromID(pContext, IDS_STRING_JSAFNUMBER_KEYSTROKE).c_str());
1674 pEvent->Rc() = FALSE;
1675 }
Tom Sepez2f2ffec2015-07-23 14:42:09 -07001676 return TRUE;
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001677 }
1678
1679 CFX_WideString& wideChange = pEvent->Change();
1680 std::wstring wChange = wideChange.c_str();
1681 if (wChange.empty())
1682 return TRUE;
1683
1684 int iIndexMask = pEvent->SelStart();
1685
Lei Zhanga0f67242015-08-17 15:39:30 -07001686 size_t combined_len = wstrValue.length() + wChange.length() -
1687 (pEvent->SelEnd() - pEvent->SelStart());
1688 if (combined_len > wstrMaskLen) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001689 Alert(pContext,
1690 JSGetStringFromID(pContext, IDS_STRING_JSPARAM_TOOLONG).c_str());
1691 pEvent->Rc() = FALSE;
1692 return TRUE;
1693 }
1694
Lei Zhanga0f67242015-08-17 15:39:30 -07001695 if (iIndexMask >= wstrMaskLen && (!wChange.empty())) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001696 Alert(pContext,
1697 JSGetStringFromID(pContext, IDS_STRING_JSPARAM_TOOLONG).c_str());
1698 pEvent->Rc() = FALSE;
1699 return TRUE;
1700 }
1701
1702 for (std::wstring::iterator it = wChange.begin(); it != wChange.end(); it++) {
Lei Zhanga0f67242015-08-17 15:39:30 -07001703 if (iIndexMask >= wstrMaskLen) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001704 Alert(pContext,
1705 JSGetStringFromID(pContext, IDS_STRING_JSPARAM_TOOLONG).c_str());
1706 pEvent->Rc() = FALSE;
1707 return TRUE;
1708 }
1709 wchar_t w_Mask = wstrMask[iIndexMask];
1710 if (!isReservedMaskChar(w_Mask)) {
1711 *it = w_Mask;
1712 }
1713 wchar_t w_Change = *it;
1714 if (!maskSatisfied(w_Change, w_Mask)) {
1715 pEvent->Rc() = FALSE;
1716 return TRUE;
1717 }
1718 iIndexMask++;
1719 }
1720
1721 wideChange = wChange.c_str();
1722 return TRUE;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07001723}
1724
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001725// function AFSpecial_Keystroke(psf)
Lei Zhang945fdb72015-11-11 10:18:16 -08001726FX_BOOL CJS_PublicMethods::AFSpecial_Keystroke(
1727 IJS_Context* cc,
1728 const std::vector<CJS_Value>& params,
1729 CJS_Value& vRet,
1730 CFX_WideString& sError) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001731 CJS_Context* pContext = (CJS_Context*)cc;
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001732 if (params.size() != 1) {
1733 sError = JSGetStringFromID(pContext, IDS_STRING_JSPARAMERROR);
1734 return FALSE;
1735 }
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07001736
Tom Sepez67fd5df2015-10-08 12:24:19 -07001737 CJS_EventHandler* pEvent = pContext->GetEventHandler();
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001738 if (!pEvent->m_pValue)
1739 return FALSE;
Tom Sepez67fd5df2015-10-08 12:24:19 -07001740
1741 std::string cFormat;
1742 int iIndex = params[0].ToInt();
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001743 CFX_WideString& val = pEvent->Value();
1744 std::string strSrc = CFX_ByteString::FromUnicode(val).c_str();
1745 std::wstring wstrChange = pEvent->Change().c_str();
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07001746
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001747 switch (iIndex) {
Tom Sepez2f2ffec2015-07-23 14:42:09 -07001748 case 0:
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001749 cFormat = "99999";
1750 break;
Tom Sepez2f2ffec2015-07-23 14:42:09 -07001751 case 1:
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001752 // cFormat = "99999-9999";
1753 cFormat = "999999999";
1754 break;
1755 case 2: {
1756 std::string NumberStr;
1757 util::printx("9999999999", strSrc, NumberStr);
1758 if (strSrc.length() + wstrChange.length() > 7)
1759 // cFormat = "(999) 999-9999";
1760 cFormat = "9999999999";
1761 else
1762 // cFormat = "999-9999";
1763 cFormat = "9999999";
1764 break;
1765 }
Tom Sepez2f2ffec2015-07-23 14:42:09 -07001766 case 3:
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001767 // cFormat = "999-99-9999";
1768 cFormat = "999999999";
1769 break;
1770 }
Lei Zhanga6d9f0e2015-06-13 00:48:38 -07001771
Lei Zhang945fdb72015-11-11 10:18:16 -08001772 std::vector<CJS_Value> params2;
Tom Sepez67fd5df2015-10-08 12:24:19 -07001773 params2.push_back(CJS_Value(CJS_Runtime::FromContext(cc), cFormat.c_str()));
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001774 return AFSpecial_KeystrokeEx(cc, params2, vRet, sError);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07001775}
1776
Tom Sepezba038bc2015-10-08 12:03:00 -07001777FX_BOOL CJS_PublicMethods::AFMergeChange(IJS_Context* cc,
Lei Zhang945fdb72015-11-11 10:18:16 -08001778 const std::vector<CJS_Value>& params,
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001779 CJS_Value& vRet,
1780 CFX_WideString& sError) {
1781 CJS_Context* pContext = (CJS_Context*)cc;
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001782 CJS_EventHandler* pEventHandler = pContext->GetEventHandler();
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07001783
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001784 if (params.size() != 1) {
1785 sError = JSGetStringFromID(pContext, IDS_STRING_JSPARAMERROR);
1786 return FALSE;
1787 }
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07001788
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001789 CFX_WideString swValue;
Lei Zhang997de612015-11-04 18:17:53 -08001790 if (pEventHandler->m_pValue)
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001791 swValue = pEventHandler->Value();
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07001792
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001793 if (pEventHandler->WillCommit()) {
1794 vRet = swValue.c_str();
Tom Sepez2f2ffec2015-07-23 14:42:09 -07001795 return TRUE;
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001796 }
1797
1798 CFX_WideString prefix, postfix;
1799
1800 if (pEventHandler->SelStart() >= 0)
1801 prefix = swValue.Mid(0, pEventHandler->SelStart());
1802 else
1803 prefix = L"";
1804
1805 if (pEventHandler->SelEnd() >= 0 &&
1806 pEventHandler->SelEnd() <= swValue.GetLength())
1807 postfix = swValue.Mid(pEventHandler->SelEnd(),
1808 swValue.GetLength() - pEventHandler->SelEnd());
1809 else
1810 postfix = L"";
1811
1812 vRet = (prefix + pEventHandler->Change() + postfix).c_str();
1813
1814 return TRUE;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07001815}
1816
Tom Sepezba038bc2015-10-08 12:03:00 -07001817FX_BOOL CJS_PublicMethods::AFParseDateEx(IJS_Context* cc,
Lei Zhang945fdb72015-11-11 10:18:16 -08001818 const std::vector<CJS_Value>& params,
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001819 CJS_Value& vRet,
1820 CFX_WideString& sError) {
1821 CJS_Context* pContext = (CJS_Context*)cc;
Lei Zhang96660d62015-12-14 18:27:25 -08001822 ASSERT(pContext);
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001823
1824 if (params.size() != 2) {
1825 sError = JSGetStringFromID(pContext, IDS_STRING_JSPARAMERROR);
1826 return FALSE;
1827 }
1828
1829 CFX_WideString sValue = params[0].ToCFXWideString();
1830 CFX_WideString sFormat = params[1].ToCFXWideString();
1831
Lei Zhang9559b7a2015-12-21 11:12:20 -08001832 double dDate = MakeRegularDate(sValue, sFormat, nullptr);
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001833
1834 if (JS_PortIsNan(dDate)) {
1835 CFX_WideString swMsg;
1836 swMsg.Format(JSGetStringFromID(pContext, IDS_STRING_JSPARSEDATE).c_str(),
1837 sFormat.c_str());
1838 Alert((CJS_Context*)cc, swMsg.c_str());
1839 return FALSE;
1840 }
1841
1842 vRet = dDate;
1843 return TRUE;
1844}
1845
Tom Sepezba038bc2015-10-08 12:03:00 -07001846FX_BOOL CJS_PublicMethods::AFSimple(IJS_Context* cc,
Lei Zhang945fdb72015-11-11 10:18:16 -08001847 const std::vector<CJS_Value>& params,
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001848 CJS_Value& vRet,
1849 CFX_WideString& sError) {
1850 if (params.size() != 3) {
1851 CJS_Context* pContext = (CJS_Context*)cc;
Lei Zhang96660d62015-12-14 18:27:25 -08001852 ASSERT(pContext);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07001853
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001854 sError = JSGetStringFromID(pContext, IDS_STRING_JSPARAMERROR);
1855 return FALSE;
1856 }
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07001857
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001858 vRet = (double)AF_Simple(params[0].ToCFXWideString().c_str(),
1859 params[1].ToDouble(), params[2].ToDouble());
1860 return TRUE;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07001861}
1862
Tom Sepezba038bc2015-10-08 12:03:00 -07001863FX_BOOL CJS_PublicMethods::AFMakeNumber(IJS_Context* cc,
Lei Zhang945fdb72015-11-11 10:18:16 -08001864 const std::vector<CJS_Value>& params,
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001865 CJS_Value& vRet,
1866 CFX_WideString& sError) {
1867 if (params.size() != 1) {
1868 CJS_Context* pContext = (CJS_Context*)cc;
Lei Zhang96660d62015-12-14 18:27:25 -08001869 ASSERT(pContext);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07001870
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001871 sError = JSGetStringFromID(pContext, IDS_STRING_JSPARAMERROR);
1872 return FALSE;
1873 }
1874 vRet = ParseStringToNumber(params[0].ToCFXWideString().c_str());
1875 return TRUE;
1876}
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07001877
Lei Zhang945fdb72015-11-11 10:18:16 -08001878FX_BOOL CJS_PublicMethods::AFSimple_Calculate(
1879 IJS_Context* cc,
1880 const std::vector<CJS_Value>& params,
1881 CJS_Value& vRet,
1882 CFX_WideString& sError) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001883 CJS_Context* pContext = (CJS_Context*)cc;
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001884 if (params.size() != 2) {
1885 sError = JSGetStringFromID(pContext, IDS_STRING_JSPARAMERROR);
1886 return FALSE;
1887 }
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07001888
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001889 CJS_Value params1 = params[1];
Tom Sepez39bfe122015-09-17 15:25:23 -07001890 if (!params1.IsArrayObject() && params1.GetType() != CJS_Value::VT_string) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001891 sError = JSGetStringFromID(pContext, IDS_STRING_JSPARAMERROR);
1892 return FALSE;
1893 }
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07001894
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001895 CPDFSDK_Document* pReaderDoc = pContext->GetReaderDocument();
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001896 CPDFSDK_InterForm* pReaderInterForm = pReaderDoc->GetInterForm();
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001897 CPDF_InterForm* pInterForm = pReaderInterForm->GetInterForm();
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07001898
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001899 CFX_WideString sFunction = params[0].ToCFXWideString();
Tom Sepez67fd5df2015-10-08 12:24:19 -07001900 double dValue = wcscmp(sFunction.c_str(), L"PRD") == 0 ? 1.0 : 0.0;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07001901
Tom Sepez67fd5df2015-10-08 12:24:19 -07001902 CJS_Runtime* pRuntime = CJS_Runtime::FromContext(cc);
1903 CJS_Array FieldNameArray = AF_MakeArrayFromList(pRuntime, params1);
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001904 int nFieldsCount = 0;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07001905
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001906 for (int i = 0, isz = FieldNameArray.GetLength(); i < isz; i++) {
Tom Sepez67fd5df2015-10-08 12:24:19 -07001907 CJS_Value jsValue(pRuntime);
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001908 FieldNameArray.GetElement(i, jsValue);
1909 CFX_WideString wsFieldName = jsValue.ToCFXWideString();
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07001910
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001911 for (int j = 0, jsz = pInterForm->CountFields(wsFieldName); j < jsz; j++) {
1912 if (CPDF_FormField* pFormField = pInterForm->GetField(j, wsFieldName)) {
1913 double dTemp = 0.0;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07001914
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001915 switch (pFormField->GetFieldType()) {
1916 case FIELDTYPE_TEXTFIELD:
1917 case FIELDTYPE_COMBOBOX: {
1918 dTemp = ParseStringToNumber(pFormField->GetValue().c_str());
1919 break;
1920 }
1921 case FIELDTYPE_PUSHBUTTON: {
1922 dTemp = 0.0;
1923 break;
1924 }
1925 case FIELDTYPE_CHECKBOX:
1926 case FIELDTYPE_RADIOBUTTON: {
1927 dTemp = 0.0;
1928 for (int c = 0, csz = pFormField->CountControls(); c < csz; c++) {
1929 if (CPDF_FormControl* pFormCtrl = pFormField->GetControl(c)) {
1930 if (pFormCtrl->IsChecked()) {
1931 dTemp +=
1932 ParseStringToNumber(pFormCtrl->GetExportValue().c_str());
1933 break;
Lei Zhang9559b7a2015-12-21 11:12:20 -08001934 }
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001935 }
Tom Sepez2f2ffec2015-07-23 14:42:09 -07001936 }
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001937 break;
1938 }
1939 case FIELDTYPE_LISTBOX: {
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001940 if (pFormField->CountSelectedItems() > 1)
1941 break;
Lei Zhang9559b7a2015-12-21 11:12:20 -08001942
1943 dTemp = ParseStringToNumber(pFormField->GetValue().c_str());
1944 break;
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001945 }
1946 default:
1947 break;
Tom Sepez2f2ffec2015-07-23 14:42:09 -07001948 }
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001949
1950 if (i == 0 && j == 0 && (wcscmp(sFunction.c_str(), L"MIN") == 0 ||
1951 wcscmp(sFunction.c_str(), L"MAX") == 0))
1952 dValue = dTemp;
1953
1954 dValue = AF_Simple(sFunction.c_str(), dValue, dTemp);
1955
1956 nFieldsCount++;
1957 }
Tom Sepez2f2ffec2015-07-23 14:42:09 -07001958 }
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001959 }
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07001960
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001961 if (wcscmp(sFunction.c_str(), L"AVG") == 0 && nFieldsCount > 0)
1962 dValue /= nFieldsCount;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07001963
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001964 dValue = (double)floor(dValue * FXSYS_pow((double)10, (double)6) + 0.49) /
1965 FXSYS_pow((double)10, (double)6);
Tom Sepez67fd5df2015-10-08 12:24:19 -07001966 CJS_Value jsValue(pRuntime, dValue);
foxit8b544ed2015-09-10 14:57:54 +08001967 if (pContext->GetEventHandler()->m_pValue)
1968 pContext->GetEventHandler()->Value() = jsValue.ToCFXWideString();
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07001969
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001970 return TRUE;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07001971}
1972
Lei Zhanga6d9f0e2015-06-13 00:48:38 -07001973/* This function validates the current event to ensure that its value is
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07001974** within the specified range. */
1975
Lei Zhang945fdb72015-11-11 10:18:16 -08001976FX_BOOL CJS_PublicMethods::AFRange_Validate(
1977 IJS_Context* cc,
1978 const std::vector<CJS_Value>& params,
1979 CJS_Value& vRet,
1980 CFX_WideString& sError) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001981 CJS_Context* pContext = (CJS_Context*)cc;
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001982 CJS_EventHandler* pEvent = pContext->GetEventHandler();
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07001983
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001984 if (params.size() != 4) {
1985 sError = JSGetStringFromID(pContext, IDS_STRING_JSPARAMERROR);
1986 return FALSE;
1987 }
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07001988
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001989 if (!pEvent->m_pValue)
1990 return FALSE;
1991 if (pEvent->Value().IsEmpty())
Tom Sepez2f2ffec2015-07-23 14:42:09 -07001992 return TRUE;
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001993 double dEentValue = atof(CFX_ByteString::FromUnicode(pEvent->Value()));
1994 FX_BOOL bGreaterThan = params[0].ToBool();
1995 double dGreaterThan = params[1].ToDouble();
1996 FX_BOOL bLessThan = params[2].ToBool();
1997 double dLessThan = params[3].ToDouble();
1998 CFX_WideString swMsg;
1999
2000 if (bGreaterThan && bLessThan) {
2001 if (dEentValue < dGreaterThan || dEentValue > dLessThan)
2002 swMsg.Format(JSGetStringFromID(pContext, IDS_STRING_JSRANGE1).c_str(),
2003 params[1].ToCFXWideString().c_str(),
2004 params[3].ToCFXWideString().c_str());
2005 } else if (bGreaterThan) {
2006 if (dEentValue < dGreaterThan)
2007 swMsg.Format(JSGetStringFromID(pContext, IDS_STRING_JSRANGE2).c_str(),
2008 params[1].ToCFXWideString().c_str());
2009 } else if (bLessThan) {
2010 if (dEentValue > dLessThan)
2011 swMsg.Format(JSGetStringFromID(pContext, IDS_STRING_JSRANGE3).c_str(),
2012 params[3].ToCFXWideString().c_str());
2013 }
2014
2015 if (!swMsg.IsEmpty()) {
2016 Alert(pContext, swMsg.c_str());
2017 pEvent->Rc() = FALSE;
2018 }
2019 return TRUE;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07002020}
2021
Tom Sepezba038bc2015-10-08 12:03:00 -07002022FX_BOOL CJS_PublicMethods::AFExtractNums(IJS_Context* cc,
Lei Zhang945fdb72015-11-11 10:18:16 -08002023 const std::vector<CJS_Value>& params,
Nico Weber9d8ec5a2015-08-04 13:00:21 -07002024 CJS_Value& vRet,
2025 CFX_WideString& sError) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -07002026 CJS_Context* pContext = (CJS_Context*)cc;
Nico Weber9d8ec5a2015-08-04 13:00:21 -07002027 if (params.size() != 1) {
2028 sError = JSGetStringFromID(pContext, IDS_STRING_JSPARAMERROR);
2029 return FALSE;
2030 }
2031
Tom Sepez67fd5df2015-10-08 12:24:19 -07002032 CJS_Runtime* pRuntime = CJS_Runtime::FromContext(cc);
2033 CJS_Array nums(pRuntime);
Nico Weber9d8ec5a2015-08-04 13:00:21 -07002034
2035 CFX_WideString str = params[0].ToCFXWideString();
2036 CFX_WideString sPart;
2037
2038 if (str.GetAt(0) == L'.' || str.GetAt(0) == L',')
2039 str = L"0" + str;
2040
2041 int nIndex = 0;
2042 for (int i = 0, sz = str.GetLength(); i < sz; i++) {
2043 FX_WCHAR wc = str.GetAt(i);
Lei Zhang9559b7a2015-12-21 11:12:20 -08002044 if (FXSYS_iswdigit(wc)) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -07002045 sPart += wc;
2046 } else {
2047 if (sPart.GetLength() > 0) {
Tom Sepez67fd5df2015-10-08 12:24:19 -07002048 nums.SetElement(nIndex, CJS_Value(pRuntime, sPart.c_str()));
Nico Weber9d8ec5a2015-08-04 13:00:21 -07002049 sPart = L"";
2050 nIndex++;
2051 }
Tom Sepez2f2ffec2015-07-23 14:42:09 -07002052 }
Nico Weber9d8ec5a2015-08-04 13:00:21 -07002053 }
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07002054
Nico Weber9d8ec5a2015-08-04 13:00:21 -07002055 if (sPart.GetLength() > 0) {
Tom Sepez67fd5df2015-10-08 12:24:19 -07002056 nums.SetElement(nIndex, CJS_Value(pRuntime, sPart.c_str()));
Nico Weber9d8ec5a2015-08-04 13:00:21 -07002057 }
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07002058
Nico Weber9d8ec5a2015-08-04 13:00:21 -07002059 if (nums.GetLength() > 0)
2060 vRet = nums;
2061 else
2062 vRet.SetNull();
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07002063
Nico Weber9d8ec5a2015-08-04 13:00:21 -07002064 return TRUE;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07002065}