blob: eb0bd1b30622f27713a5b5e27ebaccd2f07d2ba1 [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
Dan Sinclairf766ad22016-03-14 13:51:24 -04007#include "fpdfsdk/javascript/PublicMethods.h"
Tom Sepez37458412015-10-06 11:33:46 -07008
Lei Zhang375a8642016-01-11 11:59:17 -08009#include <algorithm>
Dan Sinclair3ebd1212016-03-09 09:59:23 -050010#include <string>
11#include <vector>
Lei Zhang375a8642016-01-11 11:59:17 -080012
Dan Sinclaira8a28e02016-03-23 15:41:39 -040013#include "core/fxcrt/include/fx_ext.h"
dsinclair64376be2016-03-31 20:03:24 -070014#include "fpdfsdk/include/fsdk_mgr.h"
Dan Sinclairf766ad22016-03-14 13:51:24 -040015#include "fpdfsdk/javascript/Field.h"
Dan Sinclairf766ad22016-03-14 13:51:24 -040016#include "fpdfsdk/javascript/JS_Define.h"
17#include "fpdfsdk/javascript/JS_EventHandler.h"
18#include "fpdfsdk/javascript/JS_Object.h"
Dan Sinclairf766ad22016-03-14 13:51:24 -040019#include "fpdfsdk/javascript/JS_Value.h"
dsinclair64376be2016-03-31 20:03:24 -070020#include "fpdfsdk/javascript/cjs_context.h"
21#include "fpdfsdk/javascript/cjs_runtime.h"
Dan Sinclairf766ad22016-03-14 13:51:24 -040022#include "fpdfsdk/javascript/color.h"
23#include "fpdfsdk/javascript/resource.h"
24#include "fpdfsdk/javascript/util.h"
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -070025
Nico Weber9d8ec5a2015-08-04 13:00:21 -070026#define DOUBLE_CORRECT 0.000000000000001
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -070027
28BEGIN_JS_STATIC_GLOBAL_FUN(CJS_PublicMethods)
Nico Weber9d8ec5a2015-08-04 13:00:21 -070029JS_STATIC_GLOBAL_FUN_ENTRY(AFNumber_Format)
30JS_STATIC_GLOBAL_FUN_ENTRY(AFNumber_Keystroke)
31JS_STATIC_GLOBAL_FUN_ENTRY(AFPercent_Format)
32JS_STATIC_GLOBAL_FUN_ENTRY(AFPercent_Keystroke)
33JS_STATIC_GLOBAL_FUN_ENTRY(AFDate_FormatEx)
34JS_STATIC_GLOBAL_FUN_ENTRY(AFDate_KeystrokeEx)
35JS_STATIC_GLOBAL_FUN_ENTRY(AFDate_Format)
36JS_STATIC_GLOBAL_FUN_ENTRY(AFDate_Keystroke)
37JS_STATIC_GLOBAL_FUN_ENTRY(AFTime_FormatEx)
38JS_STATIC_GLOBAL_FUN_ENTRY(AFTime_KeystrokeEx)
39JS_STATIC_GLOBAL_FUN_ENTRY(AFTime_Format)
40JS_STATIC_GLOBAL_FUN_ENTRY(AFTime_Keystroke)
41JS_STATIC_GLOBAL_FUN_ENTRY(AFSpecial_Format)
42JS_STATIC_GLOBAL_FUN_ENTRY(AFSpecial_Keystroke)
43JS_STATIC_GLOBAL_FUN_ENTRY(AFSpecial_KeystrokeEx)
44JS_STATIC_GLOBAL_FUN_ENTRY(AFSimple)
45JS_STATIC_GLOBAL_FUN_ENTRY(AFMakeNumber)
46JS_STATIC_GLOBAL_FUN_ENTRY(AFSimple_Calculate)
47JS_STATIC_GLOBAL_FUN_ENTRY(AFRange_Validate)
48JS_STATIC_GLOBAL_FUN_ENTRY(AFMergeChange)
49JS_STATIC_GLOBAL_FUN_ENTRY(AFParseDateEx)
50JS_STATIC_GLOBAL_FUN_ENTRY(AFExtractNums)
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -070051END_JS_STATIC_GLOBAL_FUN()
52
53IMPLEMENT_JS_STATIC_GLOBAL_FUN(CJS_PublicMethods)
54
Dan Sinclairf766ad22016-03-14 13:51:24 -040055static const FX_WCHAR* const months[] = {L"Jan", L"Feb", L"Mar", L"Apr",
56 L"May", L"Jun", L"Jul", L"Aug",
57 L"Sep", L"Oct", L"Nov", L"Dec"};
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -070058
Dan Sinclairf766ad22016-03-14 13:51:24 -040059static const FX_WCHAR* const fullmonths[] = {
60 L"January", L"February", L"March", L"April",
61 L"May", L"June", L"July", L"August",
62 L"September", L"October", L"November", L"December"};
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -070063
Wei Li614d20a2016-03-15 13:55:12 -070064bool CJS_PublicMethods::IsNumber(const FX_WCHAR* str) {
Dan Sinclair3ebd1212016-03-09 09:59:23 -050065 CFX_WideString sTrim = StrTrim(str);
Nico Weber9d8ec5a2015-08-04 13:00:21 -070066 const FX_WCHAR* pTrim = sTrim.c_str();
67 const FX_WCHAR* p = pTrim;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -070068
Wei Li614d20a2016-03-15 13:55:12 -070069 bool bDot = false;
70 bool bKXJS = false;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -070071
Nico Weber9d8ec5a2015-08-04 13:00:21 -070072 wchar_t c;
Wei Li614d20a2016-03-15 13:55:12 -070073 while ((c = *p) != L'\0') {
74 if (c == L'.' || c == L',') {
Nico Weber9d8ec5a2015-08-04 13:00:21 -070075 if (bDot)
Wei Li614d20a2016-03-15 13:55:12 -070076 return false;
77 bDot = true;
78 } else if (c == L'-' || c == L'+') {
Nico Weber9d8ec5a2015-08-04 13:00:21 -070079 if (p != pTrim)
Wei Li614d20a2016-03-15 13:55:12 -070080 return false;
81 } else if (c == L'e' || c == L'E') {
Nico Weber9d8ec5a2015-08-04 13:00:21 -070082 if (bKXJS)
Wei Li614d20a2016-03-15 13:55:12 -070083 return false;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -070084
Nico Weber9d8ec5a2015-08-04 13:00:21 -070085 p++;
86 c = *p;
Wei Li614d20a2016-03-15 13:55:12 -070087 if (c == L'+' || c == L'-') {
88 bKXJS = true;
Nico Weber9d8ec5a2015-08-04 13:00:21 -070089 } else {
Wei Li614d20a2016-03-15 13:55:12 -070090 return false;
Nico Weber9d8ec5a2015-08-04 13:00:21 -070091 }
Lei Zhang9559b7a2015-12-21 11:12:20 -080092 } else if (!FXSYS_iswdigit(c)) {
Wei Li614d20a2016-03-15 13:55:12 -070093 return false;
Nico Weber9d8ec5a2015-08-04 13:00:21 -070094 }
95 p++;
96 }
97
Wei Li614d20a2016-03-15 13:55:12 -070098 return true;
Nico Weber9d8ec5a2015-08-04 13:00:21 -070099}
100
Wei Li614d20a2016-03-15 13:55:12 -0700101bool CJS_PublicMethods::maskSatisfied(wchar_t c_Change, wchar_t c_Mask) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700102 switch (c_Mask) {
103 case L'9':
Lei Zhang9559b7a2015-12-21 11:12:20 -0800104 return FXSYS_iswdigit(c_Change);
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700105 case L'A':
Lei Zhang9559b7a2015-12-21 11:12:20 -0800106 return FXSYS_iswalpha(c_Change);
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700107 case L'O':
Lei Zhang9559b7a2015-12-21 11:12:20 -0800108 return FXSYS_iswalnum(c_Change);
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700109 case L'X':
Wei Li614d20a2016-03-15 13:55:12 -0700110 return true;
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700111 default:
112 return (c_Change == c_Mask);
113 }
114}
115
Wei Li614d20a2016-03-15 13:55:12 -0700116bool CJS_PublicMethods::isReservedMaskChar(wchar_t ch) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700117 return ch == L'9' || ch == L'A' || ch == L'O' || ch == L'X';
118}
119
120double CJS_PublicMethods::AF_Simple(const FX_WCHAR* sFuction,
121 double dValue1,
122 double dValue2) {
123 if (FXSYS_wcsicmp(sFuction, L"AVG") == 0 ||
124 FXSYS_wcsicmp(sFuction, L"SUM") == 0) {
125 return dValue1 + dValue2;
126 }
127 if (FXSYS_wcsicmp(sFuction, L"PRD") == 0) {
128 return dValue1 * dValue2;
129 }
130 if (FXSYS_wcsicmp(sFuction, L"MIN") == 0) {
Lei Zhang375a8642016-01-11 11:59:17 -0800131 return std::min(dValue1, dValue2);
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700132 }
133 if (FXSYS_wcsicmp(sFuction, L"MAX") == 0) {
Lei Zhang375a8642016-01-11 11:59:17 -0800134 return std::max(dValue1, dValue2);
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700135 }
136 return dValue1;
137}
138
139CFX_WideString CJS_PublicMethods::StrLTrim(const FX_WCHAR* pStr) {
140 while (*pStr && *pStr == L' ')
141 pStr++;
142
143 return pStr;
144}
145
146CFX_WideString CJS_PublicMethods::StrRTrim(const FX_WCHAR* pStr) {
147 const FX_WCHAR* p = pStr;
148 while (*p)
149 p++;
150 while (p > pStr && *(p - 1) == L' ')
151 p--;
152
153 return CFX_WideString(pStr, p - pStr);
154}
155
156CFX_WideString CJS_PublicMethods::StrTrim(const FX_WCHAR* pStr) {
157 return StrRTrim(StrLTrim(pStr).c_str());
158}
159
160CFX_ByteString CJS_PublicMethods::StrLTrim(const FX_CHAR* pStr) {
161 while (*pStr && *pStr == ' ')
162 pStr++;
163
164 return pStr;
165}
166
167CFX_ByteString CJS_PublicMethods::StrRTrim(const FX_CHAR* pStr) {
168 const FX_CHAR* p = pStr;
169 while (*p)
170 p++;
171 while (p > pStr && *(p - 1) == L' ')
172 p--;
173
174 return CFX_ByteString(pStr, p - pStr);
175}
176
177CFX_ByteString CJS_PublicMethods::StrTrim(const FX_CHAR* pStr) {
178 return StrRTrim(StrLTrim(pStr));
179}
180
Tom Sepez67fd5df2015-10-08 12:24:19 -0700181CJS_Array CJS_PublicMethods::AF_MakeArrayFromList(CJS_Runtime* pRuntime,
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700182 CJS_Value val) {
Tom Sepez67fd5df2015-10-08 12:24:19 -0700183 CJS_Array StrArray(pRuntime);
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700184 if (val.IsArrayObject()) {
185 val.ConvertToArray(StrArray);
Tom Sepez2f2ffec2015-07-23 14:42:09 -0700186 return StrArray;
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700187 }
188 CFX_WideString wsStr = val.ToCFXWideString();
189 CFX_ByteString t = CFX_ByteString::FromUnicode(wsStr);
190 const char* p = (const char*)t;
191
192 int ch = ',';
193 int nIndex = 0;
194
195 while (*p) {
196 const char* pTemp = strchr(p, ch);
Lei Zhang997de612015-11-04 18:17:53 -0800197 if (!pTemp) {
Tom Sepez67fd5df2015-10-08 12:24:19 -0700198 StrArray.SetElement(nIndex, CJS_Value(pRuntime, StrTrim(p).c_str()));
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700199 break;
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700200 }
Lei Zhang997de612015-11-04 18:17:53 -0800201
202 char* pSub = new char[pTemp - p + 1];
203 strncpy(pSub, p, pTemp - p);
204 *(pSub + (pTemp - p)) = '\0';
205
206 StrArray.SetElement(nIndex, CJS_Value(pRuntime, StrTrim(pSub).c_str()));
207 delete[] pSub;
208
209 nIndex++;
210 p = ++pTemp;
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700211 }
212 return StrArray;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700213}
214
Dan Sinclair3ebd1212016-03-09 09:59:23 -0500215int CJS_PublicMethods::ParseStringInteger(const CFX_WideString& str,
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700216 int nStart,
217 int& nSkip,
218 int nMaxStep) {
219 int nRet = 0;
220 nSkip = 0;
Dan Sinclair3ebd1212016-03-09 09:59:23 -0500221 for (int i = nStart, sz = str.GetLength(); i < sz; i++) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700222 if (i - nStart > 10)
223 break;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700224
Dan Sinclair3ebd1212016-03-09 09:59:23 -0500225 FX_WCHAR c = str.GetAt(i);
Lei Zhang9559b7a2015-12-21 11:12:20 -0800226 if (!FXSYS_iswdigit(c))
227 break;
228
Dan Sinclair1c915372016-03-03 17:12:58 -0500229 nRet = nRet * 10 + FXSYS_toDecimalDigit(c);
Lei Zhang9559b7a2015-12-21 11:12:20 -0800230 nSkip = i - nStart + 1;
231 if (nSkip >= nMaxStep)
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700232 break;
233 }
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700234
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700235 return nRet;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700236}
237
Dan Sinclair3ebd1212016-03-09 09:59:23 -0500238CFX_WideString CJS_PublicMethods::ParseStringString(const CFX_WideString& str,
239 int nStart,
240 int& nSkip) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700241 CFX_WideString swRet;
242 nSkip = 0;
Dan Sinclair3ebd1212016-03-09 09:59:23 -0500243 for (int i = nStart, sz = str.GetLength(); i < sz; i++) {
244 FX_WCHAR c = str.GetAt(i);
Lei Zhang9559b7a2015-12-21 11:12:20 -0800245 if (!FXSYS_iswdigit(c))
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700246 break;
Lei Zhang9559b7a2015-12-21 11:12:20 -0800247
248 swRet += c;
249 nSkip = i - nStart + 1;
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700250 }
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700251
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700252 return swRet;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700253}
254
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700255double CJS_PublicMethods::ParseNormalDate(const CFX_WideString& value,
Lei Zhang9559b7a2015-12-21 11:12:20 -0800256 bool* bWrongFormat) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700257 double dt = JS_GetDateTime();
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700258
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700259 int nYear = JS_GetYearFromTime(dt);
260 int nMonth = JS_GetMonthFromTime(dt) + 1;
261 int nDay = JS_GetDayFromTime(dt);
262 int nHour = JS_GetHourFromTime(dt);
263 int nMin = JS_GetMinFromTime(dt);
264 int nSec = JS_GetSecFromTime(dt);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700265
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700266 int number[3];
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700267
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700268 int nSkip = 0;
269 int nLen = value.GetLength();
270 int nIndex = 0;
271 int i = 0;
272 while (i < nLen) {
273 if (nIndex > 2)
274 break;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700275
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700276 FX_WCHAR c = value.GetAt(i);
Lei Zhang9559b7a2015-12-21 11:12:20 -0800277 if (FXSYS_iswdigit(c)) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700278 number[nIndex++] = ParseStringInteger(value, i, nSkip, 4);
279 i += nSkip;
280 } else {
281 i++;
282 }
283 }
284
285 if (nIndex == 2) {
286 // case2: month/day
287 // case3: day/month
288 if ((number[0] >= 1 && number[0] <= 12) &&
289 (number[1] >= 1 && number[1] <= 31)) {
290 nMonth = number[0];
291 nDay = number[1];
292 } else if ((number[0] >= 1 && number[0] <= 31) &&
293 (number[1] >= 1 && number[1] <= 12)) {
294 nDay = number[0];
295 nMonth = number[1];
Tom Sepez2f2ffec2015-07-23 14:42:09 -0700296 }
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700297
Lei Zhang9559b7a2015-12-21 11:12:20 -0800298 if (bWrongFormat)
299 *bWrongFormat = false;
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700300 } else if (nIndex == 3) {
301 // case1: year/month/day
302 // case2: month/day/year
303 // case3: day/month/year
Tom Sepez5ffacd62014-07-18 14:42:12 -0700304
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700305 if (number[0] > 12 && (number[1] >= 1 && number[1] <= 12) &&
306 (number[2] >= 1 && number[2] <= 31)) {
307 nYear = number[0];
308 nMonth = number[1];
309 nDay = number[2];
310 } else if ((number[0] >= 1 && number[0] <= 12) &&
311 (number[1] >= 1 && number[1] <= 31) && number[2] > 31) {
312 nMonth = number[0];
313 nDay = number[1];
314 nYear = number[2];
315 } else if ((number[0] >= 1 && number[0] <= 31) &&
316 (number[1] >= 1 && number[1] <= 12) && number[2] > 31) {
317 nDay = number[0];
318 nMonth = number[1];
319 nYear = number[2];
Tom Sepez2f2ffec2015-07-23 14:42:09 -0700320 }
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700321
Lei Zhang9559b7a2015-12-21 11:12:20 -0800322 if (bWrongFormat)
323 *bWrongFormat = false;
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700324 } else {
Lei Zhang9559b7a2015-12-21 11:12:20 -0800325 if (bWrongFormat)
326 *bWrongFormat = true;
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700327 return dt;
328 }
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700329
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700330 CFX_WideString swTemp;
331 swTemp.Format(L"%d/%d/%d %d:%d:%d", nMonth, nDay, nYear, nHour, nMin, nSec);
332 return JS_DateParse(swTemp.c_str());
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700333}
334
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700335double CJS_PublicMethods::MakeRegularDate(const CFX_WideString& value,
336 const CFX_WideString& format,
Lei Zhang9559b7a2015-12-21 11:12:20 -0800337 bool* bWrongFormat) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700338 double dt = JS_GetDateTime();
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700339
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700340 if (format.IsEmpty() || value.IsEmpty())
341 return dt;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700342
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700343 int nYear = JS_GetYearFromTime(dt);
344 int nMonth = JS_GetMonthFromTime(dt) + 1;
345 int nDay = JS_GetDayFromTime(dt);
346 int nHour = JS_GetHourFromTime(dt);
347 int nMin = JS_GetMinFromTime(dt);
348 int nSec = JS_GetSecFromTime(dt);
349
350 int nYearSub = 99; // nYear - 2000;
351
352 FX_BOOL bPm = FALSE;
353 FX_BOOL bExit = FALSE;
Lei Zhang9559b7a2015-12-21 11:12:20 -0800354 bool bBadFormat = false;
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700355
356 int i = 0;
357 int j = 0;
358
359 while (i < format.GetLength()) {
360 if (bExit)
361 break;
362
363 FX_WCHAR c = format.GetAt(i);
364 switch (c) {
365 case ':':
366 case '.':
367 case '-':
368 case '\\':
369 case '/':
370 i++;
371 j++;
372 break;
373
374 case 'y':
375 case 'm':
376 case 'd':
377 case 'H':
378 case 'h':
379 case 'M':
380 case 's':
381 case 't': {
382 int oldj = j;
383 int nSkip = 0;
384 int remaining = format.GetLength() - i - 1;
385
386 if (remaining == 0 || format.GetAt(i + 1) != c) {
387 switch (c) {
Tom Sepez2f2ffec2015-07-23 14:42:09 -0700388 case 'y':
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700389 i++;
390 j++;
391 break;
Tom Sepez2f2ffec2015-07-23 14:42:09 -0700392 case 'm':
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700393 nMonth = ParseStringInteger(value, j, nSkip, 2);
394 i++;
395 j += nSkip;
396 break;
Tom Sepez2f2ffec2015-07-23 14:42:09 -0700397 case 'd':
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700398 nDay = ParseStringInteger(value, j, nSkip, 2);
399 i++;
400 j += nSkip;
401 break;
Tom Sepez2f2ffec2015-07-23 14:42:09 -0700402 case 'H':
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700403 nHour = ParseStringInteger(value, j, nSkip, 2);
404 i++;
405 j += nSkip;
406 break;
Tom Sepez2f2ffec2015-07-23 14:42:09 -0700407 case 'h':
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700408 nHour = ParseStringInteger(value, j, nSkip, 2);
409 i++;
410 j += nSkip;
411 break;
Tom Sepez2f2ffec2015-07-23 14:42:09 -0700412 case 'M':
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700413 nMin = ParseStringInteger(value, j, nSkip, 2);
414 i++;
415 j += nSkip;
416 break;
Tom Sepez2f2ffec2015-07-23 14:42:09 -0700417 case 's':
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700418 nSec = ParseStringInteger(value, j, nSkip, 2);
419 i++;
420 j += nSkip;
421 break;
Tom Sepez2f2ffec2015-07-23 14:42:09 -0700422 case 't':
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700423 bPm = (j < value.GetLength() && value.GetAt(j) == 'p');
424 i++;
425 j++;
426 break;
427 }
428 } else if (remaining == 1 || format.GetAt(i + 2) != c) {
429 switch (c) {
430 case 'y':
431 nYear = ParseStringInteger(value, j, nSkip, 4);
432 i += 2;
433 j += nSkip;
434 break;
435 case 'm':
436 nMonth = ParseStringInteger(value, j, nSkip, 2);
437 i += 2;
438 j += nSkip;
439 break;
440 case 'd':
441 nDay = ParseStringInteger(value, j, nSkip, 2);
442 i += 2;
443 j += nSkip;
444 break;
445 case 'H':
446 nHour = ParseStringInteger(value, j, nSkip, 2);
447 i += 2;
448 j += nSkip;
449 break;
450 case 'h':
451 nHour = ParseStringInteger(value, j, nSkip, 2);
452 i += 2;
453 j += nSkip;
454 break;
455 case 'M':
456 nMin = ParseStringInteger(value, j, nSkip, 2);
457 i += 2;
458 j += nSkip;
459 break;
460 case 's':
461 nSec = ParseStringInteger(value, j, nSkip, 2);
462 i += 2;
463 j += nSkip;
464 break;
465 case 't':
466 bPm = (j + 1 < value.GetLength() && value.GetAt(j) == 'p' &&
467 value.GetAt(j + 1) == 'm');
468 i += 2;
469 j += 2;
470 break;
471 }
472 } else if (remaining == 2 || format.GetAt(i + 3) != c) {
473 switch (c) {
474 case 'm': {
475 CFX_WideString sMonth = ParseStringString(value, j, nSkip);
476 FX_BOOL bFind = FALSE;
477 for (int m = 0; m < 12; m++) {
478 if (sMonth.CompareNoCase(months[m]) == 0) {
479 nMonth = m + 1;
480 i += 3;
481 j += nSkip;
482 bFind = TRUE;
483 break;
Tom Sepez2f2ffec2015-07-23 14:42:09 -0700484 }
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700485 }
486
487 if (!bFind) {
488 nMonth = ParseStringInteger(value, j, nSkip, 3);
489 i += 3;
490 j += nSkip;
491 }
492 } break;
493 case 'y':
494 break;
Tom Sepez2f2ffec2015-07-23 14:42:09 -0700495 default:
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700496 i += 3;
497 j += 3;
498 break;
499 }
500 } else if (remaining == 3 || format.GetAt(i + 4) != c) {
501 switch (c) {
502 case 'y':
503 nYear = ParseStringInteger(value, j, nSkip, 4);
504 j += nSkip;
505 i += 4;
506 break;
507 case 'm': {
508 FX_BOOL bFind = FALSE;
509
510 CFX_WideString sMonth = ParseStringString(value, j, nSkip);
511 sMonth.MakeLower();
512
513 for (int m = 0; m < 12; m++) {
514 CFX_WideString sFullMonths = fullmonths[m];
515 sFullMonths.MakeLower();
516
517 if (sFullMonths.Find(sMonth.c_str(), 0) != -1) {
518 nMonth = m + 1;
519 i += 4;
520 j += nSkip;
521 bFind = TRUE;
522 break;
523 }
524 }
525
526 if (!bFind) {
527 nMonth = ParseStringInteger(value, j, nSkip, 4);
528 i += 4;
529 j += nSkip;
530 }
531 } break;
532 default:
533 i += 4;
534 j += 4;
535 break;
536 }
537 } else {
538 if (j >= value.GetLength() || format.GetAt(i) != value.GetAt(j)) {
Lei Zhang9559b7a2015-12-21 11:12:20 -0800539 bBadFormat = true;
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700540 bExit = TRUE;
541 }
542 i++;
543 j++;
Tom Sepez2f2ffec2015-07-23 14:42:09 -0700544 }
Tom Sepez85386422014-07-23 10:28:37 -0700545
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700546 if (oldj == j) {
Lei Zhang9559b7a2015-12-21 11:12:20 -0800547 bBadFormat = true;
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700548 bExit = TRUE;
549 }
550 }
551
552 break;
553 default:
554 if (value.GetLength() <= j) {
555 bExit = TRUE;
556 } else if (format.GetAt(i) != value.GetAt(j)) {
Lei Zhang9559b7a2015-12-21 11:12:20 -0800557 bBadFormat = true;
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700558 bExit = TRUE;
559 }
560
561 i++;
562 j++;
563 break;
564 }
565 }
566
567 if (bPm)
568 nHour += 12;
569
570 if (nYear >= 0 && nYear <= nYearSub)
571 nYear += 2000;
572
573 if (nMonth < 1 || nMonth > 12)
Lei Zhang9559b7a2015-12-21 11:12:20 -0800574 bBadFormat = true;
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700575
576 if (nDay < 1 || nDay > 31)
Lei Zhang9559b7a2015-12-21 11:12:20 -0800577 bBadFormat = true;
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700578
579 if (nHour < 0 || nHour > 24)
Lei Zhang9559b7a2015-12-21 11:12:20 -0800580 bBadFormat = true;
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700581
582 if (nMin < 0 || nMin > 60)
Lei Zhang9559b7a2015-12-21 11:12:20 -0800583 bBadFormat = true;
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700584
585 if (nSec < 0 || nSec > 60)
Lei Zhang9559b7a2015-12-21 11:12:20 -0800586 bBadFormat = true;
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700587
588 double dRet = 0;
589
Lei Zhang9559b7a2015-12-21 11:12:20 -0800590 if (bBadFormat) {
591 dRet = ParseNormalDate(value, &bBadFormat);
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700592 } else {
593 dRet = JS_MakeDate(JS_MakeDay(nYear, nMonth - 1, nDay),
594 JS_MakeTime(nHour, nMin, nSec, 0));
595
596 if (JS_PortIsNan(dRet)) {
597 dRet = JS_DateParse(value.c_str());
598 }
599 }
600
601 if (JS_PortIsNan(dRet)) {
Lei Zhang9559b7a2015-12-21 11:12:20 -0800602 dRet = ParseNormalDate(value, &bBadFormat);
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700603 }
604
Lei Zhang9559b7a2015-12-21 11:12:20 -0800605 if (bWrongFormat)
606 *bWrongFormat = bBadFormat;
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700607 return dRet;
608}
609
610CFX_WideString CJS_PublicMethods::MakeFormatDate(double dDate,
611 const CFX_WideString& format) {
612 CFX_WideString sRet = L"", sPart = L"";
613
614 int nYear = JS_GetYearFromTime(dDate);
615 int nMonth = JS_GetMonthFromTime(dDate) + 1;
616 int nDay = JS_GetDayFromTime(dDate);
617 int nHour = JS_GetHourFromTime(dDate);
618 int nMin = JS_GetMinFromTime(dDate);
619 int nSec = JS_GetSecFromTime(dDate);
620
621 int i = 0;
622 while (i < format.GetLength()) {
623 FX_WCHAR c = format.GetAt(i);
624 int remaining = format.GetLength() - i - 1;
625 sPart = L"";
626 switch (c) {
627 case 'y':
628 case 'm':
629 case 'd':
630 case 'H':
631 case 'h':
632 case 'M':
633 case 's':
634 case 't':
635 if (remaining == 0 || format.GetAt(i + 1) != c) {
636 switch (c) {
637 case 'y':
638 sPart += c;
639 break;
640 case 'm':
641 sPart.Format(L"%d", nMonth);
642 break;
643 case 'd':
644 sPart.Format(L"%d", nDay);
645 break;
646 case 'H':
647 sPart.Format(L"%d", nHour);
648 break;
649 case 'h':
650 sPart.Format(L"%d", nHour > 12 ? nHour - 12 : nHour);
651 break;
652 case 'M':
653 sPart.Format(L"%d", nMin);
654 break;
655 case 's':
656 sPart.Format(L"%d", nSec);
657 break;
658 case 't':
659 sPart += nHour > 12 ? 'p' : 'a';
660 break;
661 }
662 i++;
663 } else if (remaining == 1 || format.GetAt(i + 2) != c) {
664 switch (c) {
665 case 'y':
666 sPart.Format(L"%02d", nYear - (nYear / 100) * 100);
667 break;
668 case 'm':
669 sPart.Format(L"%02d", nMonth);
670 break;
671 case 'd':
672 sPart.Format(L"%02d", nDay);
673 break;
674 case 'H':
675 sPart.Format(L"%02d", nHour);
676 break;
677 case 'h':
678 sPart.Format(L"%02d", nHour > 12 ? nHour - 12 : nHour);
679 break;
680 case 'M':
681 sPart.Format(L"%02d", nMin);
682 break;
683 case 's':
684 sPart.Format(L"%02d", nSec);
685 break;
686 case 't':
687 sPart = nHour > 12 ? L"pm" : L"am";
688 break;
689 }
690 i += 2;
691 } else if (remaining == 2 || format.GetAt(i + 3) != c) {
692 switch (c) {
693 case 'm':
694 i += 3;
695 if (nMonth > 0 && nMonth <= 12)
696 sPart += months[nMonth - 1];
697 break;
698 default:
699 i += 3;
700 sPart += c;
701 sPart += c;
702 sPart += c;
703 break;
704 }
705 } else if (remaining == 3 || format.GetAt(i + 4) != c) {
706 switch (c) {
707 case 'y':
708 sPart.Format(L"%04d", nYear);
709 i += 4;
710 break;
711 case 'm':
712 i += 4;
713 if (nMonth > 0 && nMonth <= 12)
714 sPart += fullmonths[nMonth - 1];
715 break;
716 default:
717 i += 4;
718 sPart += c;
719 sPart += c;
720 sPart += c;
721 sPart += c;
722 break;
723 }
724 } else {
725 i++;
726 sPart += c;
727 }
728 break;
729 default:
730 i++;
731 sPart += c;
732 break;
Tom Sepez2f2ffec2015-07-23 14:42:09 -0700733 }
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700734
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700735 sRet += sPart;
736 }
737
738 return sRet;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700739}
740
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700741// function AFNumber_Format(nDec, sepStyle, negStyle, currStyle, strCurrency,
742// bCurrencyPrepend)
Tom Sepezba038bc2015-10-08 12:03:00 -0700743FX_BOOL CJS_PublicMethods::AFNumber_Format(IJS_Context* cc,
Lei Zhang945fdb72015-11-11 10:18:16 -0800744 const std::vector<CJS_Value>& params,
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700745 CJS_Value& vRet,
746 CFX_WideString& sError) {
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700747#if _FX_OS_ != _FX_ANDROID_
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700748 CJS_Context* pContext = (CJS_Context*)cc;
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700749 if (params.size() != 6) {
750 sError = JSGetStringFromID(pContext, IDS_STRING_JSPARAMERROR);
751 return FALSE;
752 }
Tom Sepez67fd5df2015-10-08 12:24:19 -0700753
754 CJS_Runtime* pRuntime = CJS_Runtime::FromContext(cc);
755 CJS_EventHandler* pEvent = pContext->GetEventHandler();
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700756 if (!pEvent->m_pValue)
757 return FALSE;
Tom Sepez67fd5df2015-10-08 12:24:19 -0700758
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700759 CFX_WideString& Value = pEvent->Value();
760 CFX_ByteString strValue = StrTrim(CFX_ByteString::FromUnicode(Value));
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700761 if (strValue.IsEmpty())
Tom Sepez2f2ffec2015-07-23 14:42:09 -0700762 return TRUE;
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700763
764 int iDec = params[0].ToInt();
765 int iSepStyle = params[1].ToInt();
766 int iNegStyle = params[2].ToInt();
767 // params[3] is iCurrStyle, it's not used.
768 std::wstring wstrCurrency(params[4].ToCFXWideString().c_str());
769 FX_BOOL bCurrencyPrepend = params[5].ToBool();
770
771 if (iDec < 0)
772 iDec = -iDec;
773
774 if (iSepStyle < 0 || iSepStyle > 3)
775 iSepStyle = 0;
776
777 if (iNegStyle < 0 || iNegStyle > 3)
778 iNegStyle = 0;
779
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700780 // for processing decimal places
781 strValue.Replace(",", ".");
782 double dValue = atof(strValue);
783 if (iDec > 0)
Tom Sepezdfbf8e72015-10-14 14:17:26 -0700784 dValue += DOUBLE_CORRECT;
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700785
786 int iDec2;
787 int iNegative = 0;
788
789 strValue = fcvt(dValue, iDec, &iDec2, &iNegative);
790 if (strValue.IsEmpty()) {
791 dValue = 0;
792 strValue = fcvt(dValue, iDec, &iDec2, &iNegative);
793 if (strValue.IsEmpty()) {
794 strValue = "0";
795 iDec2 = 1;
796 }
797 }
798
799 if (iDec2 < 0) {
800 for (int iNum = 0; iNum < abs(iDec2); iNum++) {
801 strValue = "0" + strValue;
802 }
803 iDec2 = 0;
804 }
805 int iMax = strValue.GetLength();
806 if (iDec2 > iMax) {
807 for (int iNum = 0; iNum <= iDec2 - iMax; iNum++) {
808 strValue += "0";
809 }
810 iMax = iDec2 + 1;
811 }
dsinclair64376be2016-03-31 20:03:24 -0700812
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700813 // for processing seperator style
814 if (iDec2 < iMax) {
815 if (iSepStyle == 0 || iSepStyle == 1) {
816 strValue.Insert(iDec2, '.');
817 iMax++;
818 } else if (iSepStyle == 2 || iSepStyle == 3) {
819 strValue.Insert(iDec2, ',');
820 iMax++;
821 }
822
823 if (iDec2 == 0)
824 strValue.Insert(iDec2, '0');
825 }
826 if (iSepStyle == 0 || iSepStyle == 2) {
827 char cSeperator;
828 if (iSepStyle == 0)
829 cSeperator = ',';
830 else
831 cSeperator = '.';
832
Tom Sepezdfbf8e72015-10-14 14:17:26 -0700833 for (int iDecPositive = iDec2 - 3; iDecPositive > 0; iDecPositive -= 3) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700834 strValue.Insert(iDecPositive, cSeperator);
835 iMax++;
836 }
837 }
838
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700839 // for processing currency string
tsepez4c3debb2016-04-08 12:20:38 -0700840 Value = CFX_WideString::FromLocal(strValue.AsStringC());
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700841 std::wstring strValue2 = Value.c_str();
842
843 if (bCurrencyPrepend)
844 strValue2 = wstrCurrency + strValue2;
845 else
846 strValue2 = strValue2 + wstrCurrency;
847
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700848 // for processing negative style
849 if (iNegative) {
850 if (iNegStyle == 0) {
851 strValue2.insert(0, L"-");
852 }
853 if (iNegStyle == 2 || iNegStyle == 3) {
854 strValue2.insert(0, L"(");
855 strValue2.insert(strValue2.length(), L")");
856 }
857 if (iNegStyle == 1 || iNegStyle == 3) {
858 if (Field* fTarget = pEvent->Target_Field()) {
Tom Sepez67fd5df2015-10-08 12:24:19 -0700859 CJS_Array arColor(pRuntime);
860 CJS_Value vColElm(pRuntime);
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700861 vColElm = L"RGB";
862 arColor.SetElement(0, vColElm);
863 vColElm = 1;
864 arColor.SetElement(1, vColElm);
865 vColElm = 0;
866 arColor.SetElement(2, vColElm);
867
868 arColor.SetElement(3, vColElm);
869
Tom Sepez67fd5df2015-10-08 12:24:19 -0700870 CJS_PropValue vProp(pRuntime);
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700871 vProp.StartGetting();
872 vProp << arColor;
873 vProp.StartSetting();
874 fTarget->textColor(cc, vProp, sError); // red
875 }
876 }
877 } else {
878 if (iNegStyle == 1 || iNegStyle == 3) {
879 if (Field* fTarget = pEvent->Target_Field()) {
Tom Sepez67fd5df2015-10-08 12:24:19 -0700880 CJS_Array arColor(pRuntime);
881 CJS_Value vColElm(pRuntime);
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700882 vColElm = L"RGB";
883 arColor.SetElement(0, vColElm);
884 vColElm = 0;
885 arColor.SetElement(1, vColElm);
886 arColor.SetElement(2, vColElm);
887 arColor.SetElement(3, vColElm);
888
Tom Sepez67fd5df2015-10-08 12:24:19 -0700889 CJS_PropValue vProp(pRuntime);
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700890 vProp.StartGetting();
891 fTarget->textColor(cc, vProp, sError);
892
Tom Sepez67fd5df2015-10-08 12:24:19 -0700893 CJS_Array aProp(pRuntime);
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700894 vProp.ConvertToArray(aProp);
895
896 CPWL_Color crProp;
897 CPWL_Color crColor;
898 color::ConvertArrayToPWLColor(aProp, crProp);
899 color::ConvertArrayToPWLColor(arColor, crColor);
900
901 if (crColor != crProp) {
Tom Sepez67fd5df2015-10-08 12:24:19 -0700902 CJS_PropValue vProp2(pRuntime);
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700903 vProp2.StartGetting();
904 vProp2 << arColor;
905 vProp2.StartSetting();
906 fTarget->textColor(cc, vProp2, sError);
907 }
908 }
909 }
910 }
911 Value = strValue2.c_str();
912#endif
913 return TRUE;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700914}
915
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700916// function AFNumber_Keystroke(nDec, sepStyle, negStyle, currStyle, strCurrency,
917// bCurrencyPrepend)
Lei Zhang945fdb72015-11-11 10:18:16 -0800918FX_BOOL CJS_PublicMethods::AFNumber_Keystroke(
919 IJS_Context* cc,
920 const std::vector<CJS_Value>& params,
921 CJS_Value& vRet,
922 CFX_WideString& sError) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700923 CJS_Context* pContext = (CJS_Context*)cc;
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700924 CJS_EventHandler* pEvent = pContext->GetEventHandler();
Lei Zhanga6d9f0e2015-06-13 00:48:38 -0700925
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700926 if (params.size() < 2)
927 return FALSE;
928 int iSepStyle = params[1].ToInt();
Lei Zhanga6d9f0e2015-06-13 00:48:38 -0700929
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700930 if (iSepStyle < 0 || iSepStyle > 3)
931 iSepStyle = 0;
932 if (!pEvent->m_pValue)
933 return FALSE;
934 CFX_WideString& val = pEvent->Value();
935 CFX_WideString& w_strChange = pEvent->Change();
936 CFX_WideString w_strValue = val;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700937
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700938 if (pEvent->WillCommit()) {
939 CFX_WideString wstrChange = w_strChange;
940 CFX_WideString wstrValue = StrLTrim(w_strValue.c_str());
941 if (wstrValue.IsEmpty())
942 return TRUE;
Lei Zhanga6d9f0e2015-06-13 00:48:38 -0700943
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700944 CFX_WideString swTemp = wstrValue;
945 swTemp.Replace(L",", L".");
946 if (!IsNumber(swTemp.c_str())) {
947 pEvent->Rc() = FALSE;
948 sError = JSGetStringFromID(pContext, IDS_STRING_JSAFNUMBER_KEYSTROKE);
949 Alert(pContext, sError.c_str());
950 return TRUE;
Tom Sepez2f2ffec2015-07-23 14:42:09 -0700951 }
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700952 return TRUE; // it happens after the last keystroke and before validating,
953 }
Tom Sepez4f7bc042015-04-27 12:06:58 -0700954
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700955 std::wstring w_strValue2 = w_strValue.c_str();
956 std::wstring w_strChange2 = w_strChange.c_str();
957 std::wstring w_strSelected;
958 if (-1 != pEvent->SelStart())
959 w_strSelected = w_strValue2.substr(pEvent->SelStart(),
960 (pEvent->SelEnd() - pEvent->SelStart()));
Lei Zhangb9c31972015-08-11 14:09:35 -0700961 bool bHasSign = (w_strValue2.find('-') != std::wstring::npos) &&
962 (w_strSelected.find('-') == std::wstring::npos);
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700963 if (bHasSign) {
964 // can't insert "change" in front to sign postion.
965 if (pEvent->SelStart() == 0) {
966 FX_BOOL& bRc = pEvent->Rc();
967 bRc = FALSE;
968 return TRUE;
Tom Sepez2f2ffec2015-07-23 14:42:09 -0700969 }
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700970 }
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700971
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700972 char cSep = L'.';
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700973
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700974 switch (iSepStyle) {
Tom Sepez2f2ffec2015-07-23 14:42:09 -0700975 case 0:
976 case 1:
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700977 cSep = L'.';
978 break;
Tom Sepez2f2ffec2015-07-23 14:42:09 -0700979 case 2:
980 case 3:
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700981 cSep = L',';
982 break;
983 }
Lei Zhanga6d9f0e2015-06-13 00:48:38 -0700984
Lei Zhangb9c31972015-08-11 14:09:35 -0700985 bool bHasSep = (w_strValue2.find(cSep) != std::wstring::npos);
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700986 for (std::wstring::iterator it = w_strChange2.begin();
987 it != w_strChange2.end(); it++) {
988 if (*it == cSep) {
989 if (bHasSep) {
990 FX_BOOL& bRc = pEvent->Rc();
991 bRc = FALSE;
Tom Sepez2f2ffec2015-07-23 14:42:09 -0700992 return TRUE;
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700993 }
994 bHasSep = TRUE;
995 continue;
996 }
997 if (*it == L'-') {
998 if (bHasSign) {
999 FX_BOOL& bRc = pEvent->Rc();
1000 bRc = FALSE;
1001 return TRUE;
1002 }
Lei Zhang9559b7a2015-12-21 11:12:20 -08001003 // sign's position is not correct
1004 if (it != w_strChange2.begin()) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001005 FX_BOOL& bRc = pEvent->Rc();
1006 bRc = FALSE;
1007 return TRUE;
1008 }
1009 if (pEvent->SelStart() != 0) {
1010 FX_BOOL& bRc = pEvent->Rc();
1011 bRc = FALSE;
1012 return TRUE;
1013 }
1014 bHasSign = TRUE;
1015 continue;
1016 }
1017
Lei Zhang9559b7a2015-12-21 11:12:20 -08001018 if (!FXSYS_iswdigit(*it)) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001019 FX_BOOL& bRc = pEvent->Rc();
1020 bRc = FALSE;
1021 return TRUE;
1022 }
1023 }
1024
1025 std::wstring w_prefix = w_strValue2.substr(0, pEvent->SelStart());
1026 std::wstring w_postfix;
1027 if (pEvent->SelEnd() < (int)w_strValue2.length())
1028 w_postfix = w_strValue2.substr(pEvent->SelEnd());
1029 w_strValue2 = w_prefix + w_strChange2 + w_postfix;
1030 w_strValue = w_strValue2.c_str();
1031 val = w_strValue;
1032 return TRUE;
1033}
1034
1035// function AFPercent_Format(nDec, sepStyle)
Lei Zhang945fdb72015-11-11 10:18:16 -08001036FX_BOOL CJS_PublicMethods::AFPercent_Format(
1037 IJS_Context* cc,
1038 const std::vector<CJS_Value>& params,
1039 CJS_Value& vRet,
1040 CFX_WideString& sError) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001041#if _FX_OS_ != _FX_ANDROID_
1042 CJS_Context* pContext = (CJS_Context*)cc;
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001043 CJS_EventHandler* pEvent = pContext->GetEventHandler();
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001044
1045 if (params.size() != 2) {
1046 sError = JSGetStringFromID(pContext, IDS_STRING_JSPARAMERROR);
1047 return FALSE;
1048 }
1049 if (!pEvent->m_pValue)
1050 return FALSE;
1051
1052 CFX_WideString& Value = pEvent->Value();
1053 CFX_ByteString strValue = StrTrim(CFX_ByteString::FromUnicode(Value));
1054 if (strValue.IsEmpty())
1055 return TRUE;
1056
1057 int iDec = params[0].ToInt();
1058 if (iDec < 0)
1059 iDec = -iDec;
1060
1061 int iSepStyle = params[1].ToInt();
1062 if (iSepStyle < 0 || iSepStyle > 3)
1063 iSepStyle = 0;
1064
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001065 // for processing decimal places
1066 double dValue = atof(strValue);
1067 dValue *= 100;
1068 if (iDec > 0)
Lei Zhang9559b7a2015-12-21 11:12:20 -08001069 dValue += DOUBLE_CORRECT;
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001070
1071 int iDec2;
1072 int iNegative = 0;
1073 strValue = fcvt(dValue, iDec, &iDec2, &iNegative);
1074 if (strValue.IsEmpty()) {
1075 dValue = 0;
1076 strValue = fcvt(dValue, iDec, &iDec2, &iNegative);
1077 }
1078
1079 if (iDec2 < 0) {
1080 for (int iNum = 0; iNum < abs(iDec2); iNum++) {
1081 strValue = "0" + strValue;
1082 }
1083 iDec2 = 0;
1084 }
1085 int iMax = strValue.GetLength();
1086 if (iDec2 > iMax) {
1087 for (int iNum = 0; iNum <= iDec2 - iMax; iNum++) {
1088 strValue += "0";
1089 }
1090 iMax = iDec2 + 1;
1091 }
dsinclair64376be2016-03-31 20:03:24 -07001092
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001093 // for processing seperator style
1094 if (iDec2 < iMax) {
1095 if (iSepStyle == 0 || iSepStyle == 1) {
1096 strValue.Insert(iDec2, '.');
1097 iMax++;
1098 } else if (iSepStyle == 2 || iSepStyle == 3) {
1099 strValue.Insert(iDec2, ',');
1100 iMax++;
1101 }
1102
1103 if (iDec2 == 0)
1104 strValue.Insert(iDec2, '0');
1105 }
1106 if (iSepStyle == 0 || iSepStyle == 2) {
1107 char cSeperator;
1108 if (iSepStyle == 0)
1109 cSeperator = ',';
1110 else
1111 cSeperator = '.';
1112
Tom Sepezdfbf8e72015-10-14 14:17:26 -07001113 for (int iDecPositive = iDec2 - 3; iDecPositive > 0; iDecPositive -= 3) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001114 strValue.Insert(iDecPositive, cSeperator);
1115 iMax++;
1116 }
1117 }
dsinclair64376be2016-03-31 20:03:24 -07001118
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001119 // negative mark
1120 if (iNegative)
1121 strValue = "-" + strValue;
1122 strValue += "%";
tsepez4c3debb2016-04-08 12:20:38 -07001123 Value = CFX_WideString::FromLocal(strValue.AsStringC());
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001124#endif
1125 return TRUE;
1126}
1127// AFPercent_Keystroke(nDec, sepStyle)
Lei Zhang945fdb72015-11-11 10:18:16 -08001128FX_BOOL CJS_PublicMethods::AFPercent_Keystroke(
1129 IJS_Context* cc,
1130 const std::vector<CJS_Value>& params,
1131 CJS_Value& vRet,
1132 CFX_WideString& sError) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001133 return AFNumber_Keystroke(cc, params, vRet, sError);
1134}
1135
1136// function AFDate_FormatEx(cFormat)
Tom Sepezba038bc2015-10-08 12:03:00 -07001137FX_BOOL CJS_PublicMethods::AFDate_FormatEx(IJS_Context* cc,
Lei Zhang945fdb72015-11-11 10:18:16 -08001138 const std::vector<CJS_Value>& params,
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001139 CJS_Value& vRet,
1140 CFX_WideString& sError) {
1141 CJS_Context* pContext = (CJS_Context*)cc;
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001142 CJS_EventHandler* pEvent = pContext->GetEventHandler();
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001143
1144 if (params.size() != 1) {
1145 sError = JSGetStringFromID(pContext, IDS_STRING_JSPARAMERROR);
1146 return FALSE;
1147 }
1148 if (!pEvent->m_pValue)
1149 return FALSE;
1150
1151 CFX_WideString& val = pEvent->Value();
1152 CFX_WideString strValue = val;
1153 if (strValue.IsEmpty())
1154 return TRUE;
1155
1156 CFX_WideString sFormat = params[0].ToCFXWideString();
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001157 double dDate = 0.0f;
1158
1159 if (strValue.Find(L"GMT") != -1) {
1160 // for GMT format time
1161 // such as "Tue Aug 11 14:24:16 GMT+08002009"
1162 dDate = MakeInterDate(strValue);
1163 } else {
Lei Zhang9559b7a2015-12-21 11:12:20 -08001164 dDate = MakeRegularDate(strValue, sFormat, nullptr);
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001165 }
1166
1167 if (JS_PortIsNan(dDate)) {
1168 CFX_WideString swMsg;
1169 swMsg.Format(JSGetStringFromID(pContext, IDS_STRING_JSPARSEDATE).c_str(),
1170 sFormat.c_str());
1171 Alert(pContext, swMsg.c_str());
1172 return FALSE;
1173 }
1174
1175 val = MakeFormatDate(dDate, sFormat);
1176 return TRUE;
1177}
1178
1179double CJS_PublicMethods::MakeInterDate(CFX_WideString strValue) {
Tom Sepezab277682016-02-17 10:07:21 -08001180 std::vector<CFX_WideString> wsArray;
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001181 CFX_WideString sTemp = L"";
Tom Sepez4246b002016-01-20 11:48:29 -08001182 for (int i = 0; i < strValue.GetLength(); ++i) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001183 FX_WCHAR c = strValue.GetAt(i);
1184 if (c == L' ' || c == L':') {
Tom Sepezab277682016-02-17 10:07:21 -08001185 wsArray.push_back(sTemp);
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001186 sTemp = L"";
1187 continue;
1188 }
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001189 sTemp += c;
1190 }
Tom Sepezab277682016-02-17 10:07:21 -08001191 wsArray.push_back(sTemp);
1192 if (wsArray.size() != 8)
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001193 return 0;
1194
Tom Sepez4246b002016-01-20 11:48:29 -08001195 int nMonth = 1;
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001196 sTemp = wsArray[1];
1197 if (sTemp.Compare(L"Jan") == 0)
1198 nMonth = 1;
Tom Sepez4246b002016-01-20 11:48:29 -08001199 else if (sTemp.Compare(L"Feb") == 0)
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001200 nMonth = 2;
Tom Sepez4246b002016-01-20 11:48:29 -08001201 else if (sTemp.Compare(L"Mar") == 0)
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001202 nMonth = 3;
Tom Sepez4246b002016-01-20 11:48:29 -08001203 else if (sTemp.Compare(L"Apr") == 0)
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001204 nMonth = 4;
Tom Sepez4246b002016-01-20 11:48:29 -08001205 else if (sTemp.Compare(L"May") == 0)
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001206 nMonth = 5;
Tom Sepez4246b002016-01-20 11:48:29 -08001207 else if (sTemp.Compare(L"Jun") == 0)
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001208 nMonth = 6;
Tom Sepez4246b002016-01-20 11:48:29 -08001209 else if (sTemp.Compare(L"Jul") == 0)
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001210 nMonth = 7;
Tom Sepez4246b002016-01-20 11:48:29 -08001211 else if (sTemp.Compare(L"Aug") == 0)
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001212 nMonth = 8;
Tom Sepez4246b002016-01-20 11:48:29 -08001213 else if (sTemp.Compare(L"Sep") == 0)
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001214 nMonth = 9;
Tom Sepez4246b002016-01-20 11:48:29 -08001215 else if (sTemp.Compare(L"Oct") == 0)
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001216 nMonth = 10;
Tom Sepez4246b002016-01-20 11:48:29 -08001217 else if (sTemp.Compare(L"Nov") == 0)
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001218 nMonth = 11;
Tom Sepez4246b002016-01-20 11:48:29 -08001219 else if (sTemp.Compare(L"Dec") == 0)
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001220 nMonth = 12;
1221
tsepez4c3debb2016-04-08 12:20:38 -07001222 int nDay = FX_atof(wsArray[2].AsStringC());
1223 int nHour = FX_atof(wsArray[3].AsStringC());
1224 int nMin = FX_atof(wsArray[4].AsStringC());
1225 int nSec = FX_atof(wsArray[5].AsStringC());
1226 int nYear = FX_atof(wsArray[7].AsStringC());
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001227 double dRet = JS_MakeDate(JS_MakeDay(nYear, nMonth - 1, nDay),
1228 JS_MakeTime(nHour, nMin, nSec, 0));
Tom Sepez4246b002016-01-20 11:48:29 -08001229 if (JS_PortIsNan(dRet))
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001230 dRet = JS_DateParse(strValue.c_str());
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001231
1232 return dRet;
1233}
1234
1235// AFDate_KeystrokeEx(cFormat)
Lei Zhang945fdb72015-11-11 10:18:16 -08001236FX_BOOL CJS_PublicMethods::AFDate_KeystrokeEx(
1237 IJS_Context* cc,
1238 const std::vector<CJS_Value>& params,
1239 CJS_Value& vRet,
1240 CFX_WideString& sError) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001241 CJS_Context* pContext = (CJS_Context*)cc;
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001242 CJS_EventHandler* pEvent = pContext->GetEventHandler();
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001243
1244 if (params.size() != 1) {
1245 sError = L"AFDate_KeystrokeEx's parameters' size r not correct";
1246 return FALSE;
1247 }
1248
1249 if (pEvent->WillCommit()) {
1250 if (!pEvent->m_pValue)
1251 return FALSE;
1252 CFX_WideString strValue = pEvent->Value();
1253 if (strValue.IsEmpty())
1254 return TRUE;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07001255
Tom Sepez2f2ffec2015-07-23 14:42:09 -07001256 CFX_WideString sFormat = params[0].ToCFXWideString();
Lei Zhang9559b7a2015-12-21 11:12:20 -08001257 bool bWrongFormat = FALSE;
1258 double dRet = MakeRegularDate(strValue, sFormat, &bWrongFormat);
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001259 if (bWrongFormat || JS_PortIsNan(dRet)) {
1260 CFX_WideString swMsg;
1261 swMsg.Format(JSGetStringFromID(pContext, IDS_STRING_JSPARSEDATE).c_str(),
1262 sFormat.c_str());
1263 Alert(pContext, swMsg.c_str());
1264 pEvent->Rc() = FALSE;
1265 return TRUE;
Tom Sepez2f2ffec2015-07-23 14:42:09 -07001266 }
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001267 }
1268 return TRUE;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07001269}
1270
Tom Sepezba038bc2015-10-08 12:03:00 -07001271FX_BOOL CJS_PublicMethods::AFDate_Format(IJS_Context* cc,
Lei Zhang945fdb72015-11-11 10:18:16 -08001272 const std::vector<CJS_Value>& params,
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001273 CJS_Value& vRet,
1274 CFX_WideString& sError) {
Tom Sepez67fd5df2015-10-08 12:24:19 -07001275 CJS_Context* pContext = (CJS_Context*)cc;
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001276 if (params.size() != 1) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001277 sError = JSGetStringFromID(pContext, IDS_STRING_JSPARAMERROR);
1278 return FALSE;
1279 }
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07001280
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001281 int iIndex = params[0].ToInt();
1282 const FX_WCHAR* cFormats[] = {L"m/d",
1283 L"m/d/yy",
1284 L"mm/dd/yy",
1285 L"mm/yy",
1286 L"d-mmm",
1287 L"d-mmm-yy",
1288 L"dd-mmm-yy",
1289 L"yy-mm-dd",
1290 L"mmm-yy",
1291 L"mmmm-yy",
1292 L"mmm d, yyyy",
1293 L"mmmm d, yyyy",
1294 L"m/d/yy h:MM tt",
1295 L"m/d/yy HH:MM"};
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07001296
Lei Zhanga0f67242015-08-17 15:39:30 -07001297 if (iIndex < 0 || (static_cast<size_t>(iIndex) >= FX_ArraySize(cFormats)))
1298 iIndex = 0;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07001299
Lei Zhang945fdb72015-11-11 10:18:16 -08001300 std::vector<CJS_Value> newParams;
Tom Sepez67fd5df2015-10-08 12:24:19 -07001301 newParams.push_back(
1302 CJS_Value(CJS_Runtime::FromContext(cc), cFormats[iIndex]));
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001303 return AFDate_FormatEx(cc, newParams, vRet, sError);
1304}
Lei Zhanga6d9f0e2015-06-13 00:48:38 -07001305
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001306// AFDate_KeystrokeEx(cFormat)
Lei Zhang945fdb72015-11-11 10:18:16 -08001307FX_BOOL CJS_PublicMethods::AFDate_Keystroke(
1308 IJS_Context* cc,
1309 const std::vector<CJS_Value>& params,
1310 CJS_Value& vRet,
1311 CFX_WideString& sError) {
Tom Sepez67fd5df2015-10-08 12:24:19 -07001312 CJS_Context* pContext = (CJS_Context*)cc;
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001313 if (params.size() != 1) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001314 sError = JSGetStringFromID(pContext, IDS_STRING_JSPARAMERROR);
1315 return FALSE;
1316 }
1317
1318 int iIndex = params[0].ToInt();
1319 const FX_WCHAR* cFormats[] = {L"m/d",
1320 L"m/d/yy",
1321 L"mm/dd/yy",
1322 L"mm/yy",
1323 L"d-mmm",
1324 L"d-mmm-yy",
1325 L"dd-mmm-yy",
1326 L"yy-mm-dd",
1327 L"mmm-yy",
1328 L"mmmm-yy",
1329 L"mmm d, yyyy",
1330 L"mmmm d, yyyy",
1331 L"m/d/yy h:MM tt",
1332 L"m/d/yy HH:MM"};
1333
Lei Zhanga0f67242015-08-17 15:39:30 -07001334 if (iIndex < 0 || (static_cast<size_t>(iIndex) >= FX_ArraySize(cFormats)))
1335 iIndex = 0;
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001336
Lei Zhang945fdb72015-11-11 10:18:16 -08001337 std::vector<CJS_Value> newParams;
Tom Sepez67fd5df2015-10-08 12:24:19 -07001338 newParams.push_back(
1339 CJS_Value(CJS_Runtime::FromContext(cc), cFormats[iIndex]));
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001340 return AFDate_KeystrokeEx(cc, newParams, vRet, sError);
1341}
1342
1343// function AFTime_Format(ptf)
Tom Sepezba038bc2015-10-08 12:03:00 -07001344FX_BOOL CJS_PublicMethods::AFTime_Format(IJS_Context* cc,
Lei Zhang945fdb72015-11-11 10:18:16 -08001345 const std::vector<CJS_Value>& params,
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001346 CJS_Value& vRet,
1347 CFX_WideString& sError) {
Tom Sepez67fd5df2015-10-08 12:24:19 -07001348 CJS_Context* pContext = (CJS_Context*)cc;
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001349 if (params.size() != 1) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001350 sError = JSGetStringFromID(pContext, IDS_STRING_JSPARAMERROR);
1351 return FALSE;
1352 }
1353
1354 int iIndex = params[0].ToInt();
1355 const FX_WCHAR* cFormats[] = {L"HH:MM", L"h:MM tt", L"HH:MM:ss",
1356 L"h:MM:ss tt"};
1357
Lei Zhanga0f67242015-08-17 15:39:30 -07001358 if (iIndex < 0 || (static_cast<size_t>(iIndex) >= FX_ArraySize(cFormats)))
1359 iIndex = 0;
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001360
Lei Zhang945fdb72015-11-11 10:18:16 -08001361 std::vector<CJS_Value> newParams;
Tom Sepez67fd5df2015-10-08 12:24:19 -07001362 newParams.push_back(
1363 CJS_Value(CJS_Runtime::FromContext(cc), cFormats[iIndex]));
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001364 return AFDate_FormatEx(cc, newParams, vRet, sError);
1365}
1366
Lei Zhang945fdb72015-11-11 10:18:16 -08001367FX_BOOL CJS_PublicMethods::AFTime_Keystroke(
1368 IJS_Context* cc,
1369 const std::vector<CJS_Value>& params,
1370 CJS_Value& vRet,
1371 CFX_WideString& sError) {
Tom Sepez67fd5df2015-10-08 12:24:19 -07001372 CJS_Context* pContext = (CJS_Context*)cc;
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001373 if (params.size() != 1) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001374 sError = JSGetStringFromID(pContext, IDS_STRING_JSPARAMERROR);
1375 return FALSE;
1376 }
1377
1378 int iIndex = params[0].ToInt();
1379 const FX_WCHAR* cFormats[] = {L"HH:MM", L"h:MM tt", L"HH:MM:ss",
1380 L"h:MM:ss tt"};
1381
Lei Zhanga0f67242015-08-17 15:39:30 -07001382 if (iIndex < 0 || (static_cast<size_t>(iIndex) >= FX_ArraySize(cFormats)))
1383 iIndex = 0;
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001384
Lei Zhang945fdb72015-11-11 10:18:16 -08001385 std::vector<CJS_Value> newParams;
Tom Sepez67fd5df2015-10-08 12:24:19 -07001386 newParams.push_back(
1387 CJS_Value(CJS_Runtime::FromContext(cc), cFormats[iIndex]));
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001388 return AFDate_KeystrokeEx(cc, newParams, vRet, sError);
1389}
1390
Tom Sepezba038bc2015-10-08 12:03:00 -07001391FX_BOOL CJS_PublicMethods::AFTime_FormatEx(IJS_Context* cc,
Lei Zhang945fdb72015-11-11 10:18:16 -08001392 const std::vector<CJS_Value>& params,
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001393 CJS_Value& vRet,
1394 CFX_WideString& sError) {
1395 return AFDate_FormatEx(cc, params, vRet, sError);
1396}
1397
Lei Zhang945fdb72015-11-11 10:18:16 -08001398FX_BOOL CJS_PublicMethods::AFTime_KeystrokeEx(
1399 IJS_Context* cc,
1400 const std::vector<CJS_Value>& params,
1401 CJS_Value& vRet,
1402 CFX_WideString& sError) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001403 return AFDate_KeystrokeEx(cc, params, vRet, sError);
1404}
1405
1406// function AFSpecial_Format(psf)
Lei Zhang945fdb72015-11-11 10:18:16 -08001407FX_BOOL CJS_PublicMethods::AFSpecial_Format(
1408 IJS_Context* cc,
1409 const std::vector<CJS_Value>& params,
1410 CJS_Value& vRet,
1411 CFX_WideString& sError) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001412 CJS_Context* pContext = (CJS_Context*)cc;
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001413
1414 if (params.size() != 1) {
1415 sError = JSGetStringFromID(pContext, IDS_STRING_JSPARAMERROR);
1416 return FALSE;
1417 }
1418
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001419 CJS_EventHandler* pEvent = pContext->GetEventHandler();
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001420 if (!pEvent->m_pValue)
1421 return FALSE;
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001422
tsepez4f1f41f2016-03-28 14:13:16 -07001423 CFX_WideString wsSource = pEvent->Value();
1424 CFX_WideString wsFormat;
1425 switch (params[0].ToInt()) {
Tom Sepez2f2ffec2015-07-23 14:42:09 -07001426 case 0:
tsepez4f1f41f2016-03-28 14:13:16 -07001427 wsFormat = L"99999";
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001428 break;
Tom Sepez2f2ffec2015-07-23 14:42:09 -07001429 case 1:
tsepez4f1f41f2016-03-28 14:13:16 -07001430 wsFormat = L"99999-9999";
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001431 break;
tsepez4f1f41f2016-03-28 14:13:16 -07001432 case 2:
1433 if (util::printx(L"9999999999", wsSource).GetLength() >= 10)
1434 wsFormat = L"(999) 999-9999";
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001435 else
tsepez4f1f41f2016-03-28 14:13:16 -07001436 wsFormat = L"999-9999";
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001437 break;
Tom Sepez2f2ffec2015-07-23 14:42:09 -07001438 case 3:
tsepez4f1f41f2016-03-28 14:13:16 -07001439 wsFormat = L"999-99-9999";
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001440 break;
1441 }
1442
tsepez4f1f41f2016-03-28 14:13:16 -07001443 pEvent->Value() = util::printx(wsFormat, wsSource);
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001444 return TRUE;
1445}
1446
1447// function AFSpecial_KeystrokeEx(mask)
Lei Zhang945fdb72015-11-11 10:18:16 -08001448FX_BOOL CJS_PublicMethods::AFSpecial_KeystrokeEx(
1449 IJS_Context* cc,
1450 const std::vector<CJS_Value>& params,
1451 CJS_Value& vRet,
1452 CFX_WideString& sError) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001453 CJS_Context* pContext = (CJS_Context*)cc;
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001454 CJS_EventHandler* pEvent = pContext->GetEventHandler();
1455
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001456 if (params.size() < 1) {
1457 sError = JSGetStringFromID(pContext, IDS_STRING_JSPARAMERROR);
1458 return FALSE;
1459 }
1460
1461 if (!pEvent->m_pValue)
1462 return FALSE;
1463 CFX_WideString& valEvent = pEvent->Value();
1464
1465 CFX_WideString wstrMask = params[0].ToCFXWideString();
1466 if (wstrMask.IsEmpty())
1467 return TRUE;
1468
Lei Zhanga0f67242015-08-17 15:39:30 -07001469 const size_t wstrMaskLen = wstrMask.GetLength();
1470 const std::wstring wstrValue = valEvent.c_str();
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001471
1472 if (pEvent->WillCommit()) {
1473 if (wstrValue.empty())
1474 return TRUE;
Lei Zhanga0f67242015-08-17 15:39:30 -07001475 size_t iIndexMask = 0;
1476 for (const auto& w_Value : wstrValue) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001477 if (!maskSatisfied(w_Value, wstrMask[iIndexMask]))
Tom Sepez2f2ffec2015-07-23 14:42:09 -07001478 break;
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001479 iIndexMask++;
Tom Sepez2f2ffec2015-07-23 14:42:09 -07001480 }
Lei Zhanga6d9f0e2015-06-13 00:48:38 -07001481
Lei Zhanga0f67242015-08-17 15:39:30 -07001482 if (iIndexMask != wstrMaskLen ||
1483 (iIndexMask != wstrValue.size() && wstrMaskLen != 0)) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001484 Alert(
1485 pContext,
1486 JSGetStringFromID(pContext, IDS_STRING_JSAFNUMBER_KEYSTROKE).c_str());
1487 pEvent->Rc() = FALSE;
1488 }
Tom Sepez2f2ffec2015-07-23 14:42:09 -07001489 return TRUE;
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001490 }
1491
1492 CFX_WideString& wideChange = pEvent->Change();
1493 std::wstring wChange = wideChange.c_str();
1494 if (wChange.empty())
1495 return TRUE;
1496
Wei Li05d53f02016-03-29 16:42:53 -07001497 size_t iIndexMask = pEvent->SelStart();
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001498
Lei Zhanga0f67242015-08-17 15:39:30 -07001499 size_t combined_len = wstrValue.length() + wChange.length() -
1500 (pEvent->SelEnd() - pEvent->SelStart());
1501 if (combined_len > wstrMaskLen) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001502 Alert(pContext,
1503 JSGetStringFromID(pContext, IDS_STRING_JSPARAM_TOOLONG).c_str());
1504 pEvent->Rc() = FALSE;
1505 return TRUE;
1506 }
1507
Lei Zhanga0f67242015-08-17 15:39:30 -07001508 if (iIndexMask >= wstrMaskLen && (!wChange.empty())) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001509 Alert(pContext,
1510 JSGetStringFromID(pContext, IDS_STRING_JSPARAM_TOOLONG).c_str());
1511 pEvent->Rc() = FALSE;
1512 return TRUE;
1513 }
1514
1515 for (std::wstring::iterator it = wChange.begin(); it != wChange.end(); it++) {
Lei Zhanga0f67242015-08-17 15:39:30 -07001516 if (iIndexMask >= wstrMaskLen) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001517 Alert(pContext,
1518 JSGetStringFromID(pContext, IDS_STRING_JSPARAM_TOOLONG).c_str());
1519 pEvent->Rc() = FALSE;
1520 return TRUE;
1521 }
1522 wchar_t w_Mask = wstrMask[iIndexMask];
1523 if (!isReservedMaskChar(w_Mask)) {
1524 *it = w_Mask;
1525 }
1526 wchar_t w_Change = *it;
1527 if (!maskSatisfied(w_Change, w_Mask)) {
1528 pEvent->Rc() = FALSE;
1529 return TRUE;
1530 }
1531 iIndexMask++;
1532 }
1533
1534 wideChange = wChange.c_str();
1535 return TRUE;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07001536}
1537
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001538// function AFSpecial_Keystroke(psf)
Lei Zhang945fdb72015-11-11 10:18:16 -08001539FX_BOOL CJS_PublicMethods::AFSpecial_Keystroke(
1540 IJS_Context* cc,
1541 const std::vector<CJS_Value>& params,
1542 CJS_Value& vRet,
1543 CFX_WideString& sError) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001544 CJS_Context* pContext = (CJS_Context*)cc;
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001545 if (params.size() != 1) {
1546 sError = JSGetStringFromID(pContext, IDS_STRING_JSPARAMERROR);
1547 return FALSE;
1548 }
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07001549
Tom Sepez67fd5df2015-10-08 12:24:19 -07001550 CJS_EventHandler* pEvent = pContext->GetEventHandler();
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001551 if (!pEvent->m_pValue)
1552 return FALSE;
Tom Sepez67fd5df2015-10-08 12:24:19 -07001553
1554 std::string cFormat;
1555 int iIndex = params[0].ToInt();
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001556 CFX_WideString& val = pEvent->Value();
1557 std::string strSrc = CFX_ByteString::FromUnicode(val).c_str();
1558 std::wstring wstrChange = pEvent->Change().c_str();
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07001559
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001560 switch (iIndex) {
Tom Sepez2f2ffec2015-07-23 14:42:09 -07001561 case 0:
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001562 cFormat = "99999";
1563 break;
Tom Sepez2f2ffec2015-07-23 14:42:09 -07001564 case 1:
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001565 cFormat = "999999999";
1566 break;
tsepez4f1f41f2016-03-28 14:13:16 -07001567 case 2:
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001568 if (strSrc.length() + wstrChange.length() > 7)
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001569 cFormat = "9999999999";
1570 else
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001571 cFormat = "9999999";
1572 break;
Tom Sepez2f2ffec2015-07-23 14:42:09 -07001573 case 3:
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001574 cFormat = "999999999";
1575 break;
1576 }
Lei Zhanga6d9f0e2015-06-13 00:48:38 -07001577
Lei Zhang945fdb72015-11-11 10:18:16 -08001578 std::vector<CJS_Value> params2;
Tom Sepez67fd5df2015-10-08 12:24:19 -07001579 params2.push_back(CJS_Value(CJS_Runtime::FromContext(cc), cFormat.c_str()));
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001580 return AFSpecial_KeystrokeEx(cc, params2, vRet, sError);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07001581}
1582
Tom Sepezba038bc2015-10-08 12:03:00 -07001583FX_BOOL CJS_PublicMethods::AFMergeChange(IJS_Context* cc,
Lei Zhang945fdb72015-11-11 10:18:16 -08001584 const std::vector<CJS_Value>& params,
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001585 CJS_Value& vRet,
1586 CFX_WideString& sError) {
1587 CJS_Context* pContext = (CJS_Context*)cc;
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001588 CJS_EventHandler* pEventHandler = pContext->GetEventHandler();
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07001589
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001590 if (params.size() != 1) {
1591 sError = JSGetStringFromID(pContext, IDS_STRING_JSPARAMERROR);
1592 return FALSE;
1593 }
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07001594
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001595 CFX_WideString swValue;
Lei Zhang997de612015-11-04 18:17:53 -08001596 if (pEventHandler->m_pValue)
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001597 swValue = pEventHandler->Value();
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07001598
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001599 if (pEventHandler->WillCommit()) {
1600 vRet = swValue.c_str();
Tom Sepez2f2ffec2015-07-23 14:42:09 -07001601 return TRUE;
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001602 }
1603
1604 CFX_WideString prefix, postfix;
1605
1606 if (pEventHandler->SelStart() >= 0)
1607 prefix = swValue.Mid(0, pEventHandler->SelStart());
1608 else
1609 prefix = L"";
1610
1611 if (pEventHandler->SelEnd() >= 0 &&
1612 pEventHandler->SelEnd() <= swValue.GetLength())
1613 postfix = swValue.Mid(pEventHandler->SelEnd(),
1614 swValue.GetLength() - pEventHandler->SelEnd());
1615 else
1616 postfix = L"";
1617
1618 vRet = (prefix + pEventHandler->Change() + postfix).c_str();
1619
1620 return TRUE;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07001621}
1622
Tom Sepezba038bc2015-10-08 12:03:00 -07001623FX_BOOL CJS_PublicMethods::AFParseDateEx(IJS_Context* cc,
Lei Zhang945fdb72015-11-11 10:18:16 -08001624 const std::vector<CJS_Value>& params,
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001625 CJS_Value& vRet,
1626 CFX_WideString& sError) {
1627 CJS_Context* pContext = (CJS_Context*)cc;
Lei Zhang96660d62015-12-14 18:27:25 -08001628 ASSERT(pContext);
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001629
1630 if (params.size() != 2) {
1631 sError = JSGetStringFromID(pContext, IDS_STRING_JSPARAMERROR);
1632 return FALSE;
1633 }
1634
1635 CFX_WideString sValue = params[0].ToCFXWideString();
1636 CFX_WideString sFormat = params[1].ToCFXWideString();
1637
Lei Zhang9559b7a2015-12-21 11:12:20 -08001638 double dDate = MakeRegularDate(sValue, sFormat, nullptr);
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001639
1640 if (JS_PortIsNan(dDate)) {
1641 CFX_WideString swMsg;
1642 swMsg.Format(JSGetStringFromID(pContext, IDS_STRING_JSPARSEDATE).c_str(),
1643 sFormat.c_str());
1644 Alert((CJS_Context*)cc, swMsg.c_str());
1645 return FALSE;
1646 }
1647
1648 vRet = dDate;
1649 return TRUE;
1650}
1651
Tom Sepezba038bc2015-10-08 12:03:00 -07001652FX_BOOL CJS_PublicMethods::AFSimple(IJS_Context* cc,
Lei Zhang945fdb72015-11-11 10:18:16 -08001653 const std::vector<CJS_Value>& params,
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001654 CJS_Value& vRet,
1655 CFX_WideString& sError) {
1656 if (params.size() != 3) {
1657 CJS_Context* pContext = (CJS_Context*)cc;
Lei Zhang96660d62015-12-14 18:27:25 -08001658 ASSERT(pContext);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07001659
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001660 sError = JSGetStringFromID(pContext, IDS_STRING_JSPARAMERROR);
1661 return FALSE;
1662 }
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07001663
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001664 vRet = (double)AF_Simple(params[0].ToCFXWideString().c_str(),
1665 params[1].ToDouble(), params[2].ToDouble());
1666 return TRUE;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07001667}
1668
Tom Sepezba038bc2015-10-08 12:03:00 -07001669FX_BOOL CJS_PublicMethods::AFMakeNumber(IJS_Context* cc,
Lei Zhang945fdb72015-11-11 10:18:16 -08001670 const std::vector<CJS_Value>& params,
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001671 CJS_Value& vRet,
1672 CFX_WideString& sError) {
Tom Sepez4246b002016-01-20 11:48:29 -08001673 CJS_Context* pContext = (CJS_Context*)cc;
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001674 if (params.size() != 1) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001675 sError = JSGetStringFromID(pContext, IDS_STRING_JSPARAMERROR);
1676 return FALSE;
1677 }
Tom Sepez4246b002016-01-20 11:48:29 -08001678 CFX_WideString ws = params[0].ToCFXWideString();
1679 ws.Replace(L",", L".");
1680 vRet = ws;
1681 vRet.MaybeCoerceToNumber();
1682 if (vRet.GetType() != CJS_Value::VT_number)
1683 vRet = 0;
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001684 return TRUE;
1685}
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07001686
Lei Zhang945fdb72015-11-11 10:18:16 -08001687FX_BOOL CJS_PublicMethods::AFSimple_Calculate(
1688 IJS_Context* cc,
1689 const std::vector<CJS_Value>& params,
1690 CJS_Value& vRet,
1691 CFX_WideString& sError) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001692 CJS_Context* pContext = (CJS_Context*)cc;
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001693 if (params.size() != 2) {
1694 sError = JSGetStringFromID(pContext, IDS_STRING_JSPARAMERROR);
1695 return FALSE;
1696 }
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07001697
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001698 CJS_Value params1 = params[1];
Tom Sepez39bfe122015-09-17 15:25:23 -07001699 if (!params1.IsArrayObject() && params1.GetType() != CJS_Value::VT_string) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001700 sError = JSGetStringFromID(pContext, IDS_STRING_JSPARAMERROR);
1701 return FALSE;
1702 }
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07001703
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001704 CPDFSDK_Document* pReaderDoc = pContext->GetReaderDocument();
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001705 CPDFSDK_InterForm* pReaderInterForm = pReaderDoc->GetInterForm();
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001706 CPDF_InterForm* pInterForm = pReaderInterForm->GetInterForm();
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07001707
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001708 CFX_WideString sFunction = params[0].ToCFXWideString();
Tom Sepez67fd5df2015-10-08 12:24:19 -07001709 double dValue = wcscmp(sFunction.c_str(), L"PRD") == 0 ? 1.0 : 0.0;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07001710
Tom Sepez67fd5df2015-10-08 12:24:19 -07001711 CJS_Runtime* pRuntime = CJS_Runtime::FromContext(cc);
1712 CJS_Array FieldNameArray = AF_MakeArrayFromList(pRuntime, params1);
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001713 int nFieldsCount = 0;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07001714
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001715 for (int i = 0, isz = FieldNameArray.GetLength(); i < isz; i++) {
Tom Sepez67fd5df2015-10-08 12:24:19 -07001716 CJS_Value jsValue(pRuntime);
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001717 FieldNameArray.GetElement(i, jsValue);
1718 CFX_WideString wsFieldName = jsValue.ToCFXWideString();
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07001719
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001720 for (int j = 0, jsz = pInterForm->CountFields(wsFieldName); j < jsz; j++) {
1721 if (CPDF_FormField* pFormField = pInterForm->GetField(j, wsFieldName)) {
1722 double dTemp = 0.0;
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001723 switch (pFormField->GetFieldType()) {
1724 case FIELDTYPE_TEXTFIELD:
1725 case FIELDTYPE_COMBOBOX: {
Tom Sepez4246b002016-01-20 11:48:29 -08001726 CFX_WideString trimmed = pFormField->GetValue();
1727 trimmed.TrimRight();
1728 trimmed.TrimLeft();
tsepez4c3debb2016-04-08 12:20:38 -07001729 dTemp = FX_atof(trimmed.AsStringC());
Tom Sepez4246b002016-01-20 11:48:29 -08001730 } break;
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001731 case FIELDTYPE_PUSHBUTTON: {
1732 dTemp = 0.0;
Tom Sepez4246b002016-01-20 11:48:29 -08001733 } break;
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001734 case FIELDTYPE_CHECKBOX:
1735 case FIELDTYPE_RADIOBUTTON: {
1736 dTemp = 0.0;
1737 for (int c = 0, csz = pFormField->CountControls(); c < csz; c++) {
1738 if (CPDF_FormControl* pFormCtrl = pFormField->GetControl(c)) {
1739 if (pFormCtrl->IsChecked()) {
Tom Sepez4246b002016-01-20 11:48:29 -08001740 CFX_WideString trimmed = pFormCtrl->GetExportValue();
1741 trimmed.TrimRight();
1742 trimmed.TrimLeft();
tsepez4c3debb2016-04-08 12:20:38 -07001743 dTemp = FX_atof(trimmed.AsStringC());
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001744 break;
Lei Zhang9559b7a2015-12-21 11:12:20 -08001745 }
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001746 }
Tom Sepez2f2ffec2015-07-23 14:42:09 -07001747 }
Tom Sepez4246b002016-01-20 11:48:29 -08001748 } break;
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001749 case FIELDTYPE_LISTBOX: {
Tom Sepez4246b002016-01-20 11:48:29 -08001750 if (pFormField->CountSelectedItems() <= 1) {
1751 CFX_WideString trimmed = pFormField->GetValue();
1752 trimmed.TrimRight();
1753 trimmed.TrimLeft();
tsepez4c3debb2016-04-08 12:20:38 -07001754 dTemp = FX_atof(trimmed.AsStringC());
Tom Sepez4246b002016-01-20 11:48:29 -08001755 }
1756 } break;
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001757 default:
1758 break;
Tom Sepez2f2ffec2015-07-23 14:42:09 -07001759 }
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001760
1761 if (i == 0 && j == 0 && (wcscmp(sFunction.c_str(), L"MIN") == 0 ||
1762 wcscmp(sFunction.c_str(), L"MAX") == 0))
1763 dValue = dTemp;
1764
1765 dValue = AF_Simple(sFunction.c_str(), dValue, dTemp);
1766
1767 nFieldsCount++;
1768 }
Tom Sepez2f2ffec2015-07-23 14:42:09 -07001769 }
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001770 }
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07001771
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001772 if (wcscmp(sFunction.c_str(), L"AVG") == 0 && nFieldsCount > 0)
1773 dValue /= nFieldsCount;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07001774
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001775 dValue = (double)floor(dValue * FXSYS_pow((double)10, (double)6) + 0.49) /
1776 FXSYS_pow((double)10, (double)6);
Tom Sepez67fd5df2015-10-08 12:24:19 -07001777 CJS_Value jsValue(pRuntime, dValue);
foxit8b544ed2015-09-10 14:57:54 +08001778 if (pContext->GetEventHandler()->m_pValue)
1779 pContext->GetEventHandler()->Value() = jsValue.ToCFXWideString();
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07001780
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001781 return TRUE;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07001782}
1783
Lei Zhanga6d9f0e2015-06-13 00:48:38 -07001784/* This function validates the current event to ensure that its value is
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07001785** within the specified range. */
1786
Lei Zhang945fdb72015-11-11 10:18:16 -08001787FX_BOOL CJS_PublicMethods::AFRange_Validate(
1788 IJS_Context* cc,
1789 const std::vector<CJS_Value>& params,
1790 CJS_Value& vRet,
1791 CFX_WideString& sError) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001792 CJS_Context* pContext = (CJS_Context*)cc;
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001793 CJS_EventHandler* pEvent = pContext->GetEventHandler();
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07001794
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001795 if (params.size() != 4) {
1796 sError = JSGetStringFromID(pContext, IDS_STRING_JSPARAMERROR);
1797 return FALSE;
1798 }
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07001799
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001800 if (!pEvent->m_pValue)
1801 return FALSE;
1802 if (pEvent->Value().IsEmpty())
Tom Sepez2f2ffec2015-07-23 14:42:09 -07001803 return TRUE;
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001804 double dEentValue = atof(CFX_ByteString::FromUnicode(pEvent->Value()));
1805 FX_BOOL bGreaterThan = params[0].ToBool();
1806 double dGreaterThan = params[1].ToDouble();
1807 FX_BOOL bLessThan = params[2].ToBool();
1808 double dLessThan = params[3].ToDouble();
1809 CFX_WideString swMsg;
1810
1811 if (bGreaterThan && bLessThan) {
1812 if (dEentValue < dGreaterThan || dEentValue > dLessThan)
1813 swMsg.Format(JSGetStringFromID(pContext, IDS_STRING_JSRANGE1).c_str(),
1814 params[1].ToCFXWideString().c_str(),
1815 params[3].ToCFXWideString().c_str());
1816 } else if (bGreaterThan) {
1817 if (dEentValue < dGreaterThan)
1818 swMsg.Format(JSGetStringFromID(pContext, IDS_STRING_JSRANGE2).c_str(),
1819 params[1].ToCFXWideString().c_str());
1820 } else if (bLessThan) {
1821 if (dEentValue > dLessThan)
1822 swMsg.Format(JSGetStringFromID(pContext, IDS_STRING_JSRANGE3).c_str(),
1823 params[3].ToCFXWideString().c_str());
1824 }
1825
1826 if (!swMsg.IsEmpty()) {
1827 Alert(pContext, swMsg.c_str());
1828 pEvent->Rc() = FALSE;
1829 }
1830 return TRUE;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07001831}
1832
Tom Sepezba038bc2015-10-08 12:03:00 -07001833FX_BOOL CJS_PublicMethods::AFExtractNums(IJS_Context* cc,
Lei Zhang945fdb72015-11-11 10:18:16 -08001834 const std::vector<CJS_Value>& params,
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001835 CJS_Value& vRet,
1836 CFX_WideString& sError) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001837 CJS_Context* pContext = (CJS_Context*)cc;
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001838 if (params.size() != 1) {
1839 sError = JSGetStringFromID(pContext, IDS_STRING_JSPARAMERROR);
1840 return FALSE;
1841 }
1842
Tom Sepez67fd5df2015-10-08 12:24:19 -07001843 CJS_Runtime* pRuntime = CJS_Runtime::FromContext(cc);
1844 CJS_Array nums(pRuntime);
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001845
1846 CFX_WideString str = params[0].ToCFXWideString();
1847 CFX_WideString sPart;
1848
1849 if (str.GetAt(0) == L'.' || str.GetAt(0) == L',')
1850 str = L"0" + str;
1851
1852 int nIndex = 0;
1853 for (int i = 0, sz = str.GetLength(); i < sz; i++) {
1854 FX_WCHAR wc = str.GetAt(i);
Lei Zhang9559b7a2015-12-21 11:12:20 -08001855 if (FXSYS_iswdigit(wc)) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001856 sPart += wc;
1857 } else {
1858 if (sPart.GetLength() > 0) {
Tom Sepez67fd5df2015-10-08 12:24:19 -07001859 nums.SetElement(nIndex, CJS_Value(pRuntime, sPart.c_str()));
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001860 sPart = L"";
1861 nIndex++;
1862 }
Tom Sepez2f2ffec2015-07-23 14:42:09 -07001863 }
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001864 }
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07001865
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001866 if (sPart.GetLength() > 0) {
Tom Sepez67fd5df2015-10-08 12:24:19 -07001867 nums.SetElement(nIndex, CJS_Value(pRuntime, sPart.c_str()));
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001868 }
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07001869
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001870 if (nums.GetLength() > 0)
1871 vRet = nums;
1872 else
1873 vRet.SetNull();
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07001874
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001875 return TRUE;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07001876}