blob: 62659e4163011d1901dc97053b039a5016d759d5 [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"
Lei Zhangbde53d22015-11-12 22:21:30 -080014#include "fpdfsdk/include/fsdk_mgr.h" // For CPDFDoc_Environment.
15#include "fpdfsdk/include/javascript/IJavaScript.h"
Dan Sinclairf766ad22016-03-14 13:51:24 -040016#include "fpdfsdk/javascript/Field.h"
17#include "fpdfsdk/javascript/JS_Context.h"
18#include "fpdfsdk/javascript/JS_Define.h"
19#include "fpdfsdk/javascript/JS_EventHandler.h"
20#include "fpdfsdk/javascript/JS_Object.h"
21#include "fpdfsdk/javascript/JS_Runtime.h"
22#include "fpdfsdk/javascript/JS_Value.h"
23#include "fpdfsdk/javascript/color.h"
24#include "fpdfsdk/javascript/resource.h"
25#include "fpdfsdk/javascript/util.h"
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -070026
Nico Weber9d8ec5a2015-08-04 13:00:21 -070027#define DOUBLE_CORRECT 0.000000000000001
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -070028
29BEGIN_JS_STATIC_GLOBAL_FUN(CJS_PublicMethods)
Nico Weber9d8ec5a2015-08-04 13:00:21 -070030JS_STATIC_GLOBAL_FUN_ENTRY(AFNumber_Format)
31JS_STATIC_GLOBAL_FUN_ENTRY(AFNumber_Keystroke)
32JS_STATIC_GLOBAL_FUN_ENTRY(AFPercent_Format)
33JS_STATIC_GLOBAL_FUN_ENTRY(AFPercent_Keystroke)
34JS_STATIC_GLOBAL_FUN_ENTRY(AFDate_FormatEx)
35JS_STATIC_GLOBAL_FUN_ENTRY(AFDate_KeystrokeEx)
36JS_STATIC_GLOBAL_FUN_ENTRY(AFDate_Format)
37JS_STATIC_GLOBAL_FUN_ENTRY(AFDate_Keystroke)
38JS_STATIC_GLOBAL_FUN_ENTRY(AFTime_FormatEx)
39JS_STATIC_GLOBAL_FUN_ENTRY(AFTime_KeystrokeEx)
40JS_STATIC_GLOBAL_FUN_ENTRY(AFTime_Format)
41JS_STATIC_GLOBAL_FUN_ENTRY(AFTime_Keystroke)
42JS_STATIC_GLOBAL_FUN_ENTRY(AFSpecial_Format)
43JS_STATIC_GLOBAL_FUN_ENTRY(AFSpecial_Keystroke)
44JS_STATIC_GLOBAL_FUN_ENTRY(AFSpecial_KeystrokeEx)
45JS_STATIC_GLOBAL_FUN_ENTRY(AFSimple)
46JS_STATIC_GLOBAL_FUN_ENTRY(AFMakeNumber)
47JS_STATIC_GLOBAL_FUN_ENTRY(AFSimple_Calculate)
48JS_STATIC_GLOBAL_FUN_ENTRY(AFRange_Validate)
49JS_STATIC_GLOBAL_FUN_ENTRY(AFMergeChange)
50JS_STATIC_GLOBAL_FUN_ENTRY(AFParseDateEx)
51JS_STATIC_GLOBAL_FUN_ENTRY(AFExtractNums)
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -070052END_JS_STATIC_GLOBAL_FUN()
53
54IMPLEMENT_JS_STATIC_GLOBAL_FUN(CJS_PublicMethods)
55
Dan Sinclairf766ad22016-03-14 13:51:24 -040056static const FX_WCHAR* const months[] = {L"Jan", L"Feb", L"Mar", L"Apr",
57 L"May", L"Jun", L"Jul", L"Aug",
58 L"Sep", L"Oct", L"Nov", L"Dec"};
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -070059
Dan Sinclairf766ad22016-03-14 13:51:24 -040060static const FX_WCHAR* const fullmonths[] = {
61 L"January", L"February", L"March", L"April",
62 L"May", L"June", L"July", L"August",
63 L"September", L"October", L"November", L"December"};
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -070064
Wei Li614d20a2016-03-15 13:55:12 -070065bool CJS_PublicMethods::IsNumber(const FX_WCHAR* str) {
Dan Sinclair3ebd1212016-03-09 09:59:23 -050066 CFX_WideString sTrim = StrTrim(str);
Nico Weber9d8ec5a2015-08-04 13:00:21 -070067 const FX_WCHAR* pTrim = sTrim.c_str();
68 const FX_WCHAR* p = pTrim;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -070069
Wei Li614d20a2016-03-15 13:55:12 -070070 bool bDot = false;
71 bool bKXJS = false;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -070072
Nico Weber9d8ec5a2015-08-04 13:00:21 -070073 wchar_t c;
Wei Li614d20a2016-03-15 13:55:12 -070074 while ((c = *p) != L'\0') {
75 if (c == L'.' || c == L',') {
Nico Weber9d8ec5a2015-08-04 13:00:21 -070076 if (bDot)
Wei Li614d20a2016-03-15 13:55:12 -070077 return false;
78 bDot = true;
79 } else if (c == L'-' || c == L'+') {
Nico Weber9d8ec5a2015-08-04 13:00:21 -070080 if (p != pTrim)
Wei Li614d20a2016-03-15 13:55:12 -070081 return false;
82 } else if (c == L'e' || c == L'E') {
Nico Weber9d8ec5a2015-08-04 13:00:21 -070083 if (bKXJS)
Wei Li614d20a2016-03-15 13:55:12 -070084 return false;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -070085
Nico Weber9d8ec5a2015-08-04 13:00:21 -070086 p++;
87 c = *p;
Wei Li614d20a2016-03-15 13:55:12 -070088 if (c == L'+' || c == L'-') {
89 bKXJS = true;
Nico Weber9d8ec5a2015-08-04 13:00:21 -070090 } else {
Wei Li614d20a2016-03-15 13:55:12 -070091 return false;
Nico Weber9d8ec5a2015-08-04 13:00:21 -070092 }
Lei Zhang9559b7a2015-12-21 11:12:20 -080093 } else if (!FXSYS_iswdigit(c)) {
Wei Li614d20a2016-03-15 13:55:12 -070094 return false;
Nico Weber9d8ec5a2015-08-04 13:00:21 -070095 }
96 p++;
97 }
98
Wei Li614d20a2016-03-15 13:55:12 -070099 return true;
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700100}
101
Wei Li614d20a2016-03-15 13:55:12 -0700102bool CJS_PublicMethods::maskSatisfied(wchar_t c_Change, wchar_t c_Mask) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700103 switch (c_Mask) {
104 case L'9':
Lei Zhang9559b7a2015-12-21 11:12:20 -0800105 return FXSYS_iswdigit(c_Change);
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700106 case L'A':
Lei Zhang9559b7a2015-12-21 11:12:20 -0800107 return FXSYS_iswalpha(c_Change);
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700108 case L'O':
Lei Zhang9559b7a2015-12-21 11:12:20 -0800109 return FXSYS_iswalnum(c_Change);
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700110 case L'X':
Wei Li614d20a2016-03-15 13:55:12 -0700111 return true;
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700112 default:
113 return (c_Change == c_Mask);
114 }
115}
116
Wei Li614d20a2016-03-15 13:55:12 -0700117bool CJS_PublicMethods::isReservedMaskChar(wchar_t ch) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700118 return ch == L'9' || ch == L'A' || ch == L'O' || ch == L'X';
119}
120
121double CJS_PublicMethods::AF_Simple(const FX_WCHAR* sFuction,
122 double dValue1,
123 double dValue2) {
124 if (FXSYS_wcsicmp(sFuction, L"AVG") == 0 ||
125 FXSYS_wcsicmp(sFuction, L"SUM") == 0) {
126 return dValue1 + dValue2;
127 }
128 if (FXSYS_wcsicmp(sFuction, L"PRD") == 0) {
129 return dValue1 * dValue2;
130 }
131 if (FXSYS_wcsicmp(sFuction, L"MIN") == 0) {
Lei Zhang375a8642016-01-11 11:59:17 -0800132 return std::min(dValue1, dValue2);
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700133 }
134 if (FXSYS_wcsicmp(sFuction, L"MAX") == 0) {
Lei Zhang375a8642016-01-11 11:59:17 -0800135 return std::max(dValue1, dValue2);
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700136 }
137 return dValue1;
138}
139
140CFX_WideString CJS_PublicMethods::StrLTrim(const FX_WCHAR* pStr) {
141 while (*pStr && *pStr == L' ')
142 pStr++;
143
144 return pStr;
145}
146
147CFX_WideString CJS_PublicMethods::StrRTrim(const FX_WCHAR* pStr) {
148 const FX_WCHAR* p = pStr;
149 while (*p)
150 p++;
151 while (p > pStr && *(p - 1) == L' ')
152 p--;
153
154 return CFX_WideString(pStr, p - pStr);
155}
156
157CFX_WideString CJS_PublicMethods::StrTrim(const FX_WCHAR* pStr) {
158 return StrRTrim(StrLTrim(pStr).c_str());
159}
160
161CFX_ByteString CJS_PublicMethods::StrLTrim(const FX_CHAR* pStr) {
162 while (*pStr && *pStr == ' ')
163 pStr++;
164
165 return pStr;
166}
167
168CFX_ByteString CJS_PublicMethods::StrRTrim(const FX_CHAR* pStr) {
169 const FX_CHAR* p = pStr;
170 while (*p)
171 p++;
172 while (p > pStr && *(p - 1) == L' ')
173 p--;
174
175 return CFX_ByteString(pStr, p - pStr);
176}
177
178CFX_ByteString CJS_PublicMethods::StrTrim(const FX_CHAR* pStr) {
179 return StrRTrim(StrLTrim(pStr));
180}
181
Tom Sepez67fd5df2015-10-08 12:24:19 -0700182CJS_Array CJS_PublicMethods::AF_MakeArrayFromList(CJS_Runtime* pRuntime,
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700183 CJS_Value val) {
Tom Sepez67fd5df2015-10-08 12:24:19 -0700184 CJS_Array StrArray(pRuntime);
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700185 if (val.IsArrayObject()) {
186 val.ConvertToArray(StrArray);
Tom Sepez2f2ffec2015-07-23 14:42:09 -0700187 return StrArray;
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700188 }
189 CFX_WideString wsStr = val.ToCFXWideString();
190 CFX_ByteString t = CFX_ByteString::FromUnicode(wsStr);
191 const char* p = (const char*)t;
192
193 int ch = ',';
194 int nIndex = 0;
195
196 while (*p) {
197 const char* pTemp = strchr(p, ch);
Lei Zhang997de612015-11-04 18:17:53 -0800198 if (!pTemp) {
Tom Sepez67fd5df2015-10-08 12:24:19 -0700199 StrArray.SetElement(nIndex, CJS_Value(pRuntime, StrTrim(p).c_str()));
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700200 break;
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700201 }
Lei Zhang997de612015-11-04 18:17:53 -0800202
203 char* pSub = new char[pTemp - p + 1];
204 strncpy(pSub, p, pTemp - p);
205 *(pSub + (pTemp - p)) = '\0';
206
207 StrArray.SetElement(nIndex, CJS_Value(pRuntime, StrTrim(pSub).c_str()));
208 delete[] pSub;
209
210 nIndex++;
211 p = ++pTemp;
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700212 }
213 return StrArray;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700214}
215
Dan Sinclair3ebd1212016-03-09 09:59:23 -0500216int CJS_PublicMethods::ParseStringInteger(const CFX_WideString& str,
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700217 int nStart,
218 int& nSkip,
219 int nMaxStep) {
220 int nRet = 0;
221 nSkip = 0;
Dan Sinclair3ebd1212016-03-09 09:59:23 -0500222 for (int i = nStart, sz = str.GetLength(); i < sz; i++) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700223 if (i - nStart > 10)
224 break;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700225
Dan Sinclair3ebd1212016-03-09 09:59:23 -0500226 FX_WCHAR c = str.GetAt(i);
Lei Zhang9559b7a2015-12-21 11:12:20 -0800227 if (!FXSYS_iswdigit(c))
228 break;
229
Dan Sinclair1c915372016-03-03 17:12:58 -0500230 nRet = nRet * 10 + FXSYS_toDecimalDigit(c);
Lei Zhang9559b7a2015-12-21 11:12:20 -0800231 nSkip = i - nStart + 1;
232 if (nSkip >= nMaxStep)
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700233 break;
234 }
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700235
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700236 return nRet;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700237}
238
Dan Sinclair3ebd1212016-03-09 09:59:23 -0500239CFX_WideString CJS_PublicMethods::ParseStringString(const CFX_WideString& str,
240 int nStart,
241 int& nSkip) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700242 CFX_WideString swRet;
243 nSkip = 0;
Dan Sinclair3ebd1212016-03-09 09:59:23 -0500244 for (int i = nStart, sz = str.GetLength(); i < sz; i++) {
245 FX_WCHAR c = str.GetAt(i);
Lei Zhang9559b7a2015-12-21 11:12:20 -0800246 if (!FXSYS_iswdigit(c))
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700247 break;
Lei Zhang9559b7a2015-12-21 11:12:20 -0800248
249 swRet += c;
250 nSkip = i - nStart + 1;
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700251 }
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700252
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700253 return swRet;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700254}
255
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700256double CJS_PublicMethods::ParseNormalDate(const CFX_WideString& value,
Lei Zhang9559b7a2015-12-21 11:12:20 -0800257 bool* bWrongFormat) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700258 double dt = JS_GetDateTime();
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700259
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700260 int nYear = JS_GetYearFromTime(dt);
261 int nMonth = JS_GetMonthFromTime(dt) + 1;
262 int nDay = JS_GetDayFromTime(dt);
263 int nHour = JS_GetHourFromTime(dt);
264 int nMin = JS_GetMinFromTime(dt);
265 int nSec = JS_GetSecFromTime(dt);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700266
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700267 int number[3];
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700268
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700269 int nSkip = 0;
270 int nLen = value.GetLength();
271 int nIndex = 0;
272 int i = 0;
273 while (i < nLen) {
274 if (nIndex > 2)
275 break;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700276
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700277 FX_WCHAR c = value.GetAt(i);
Lei Zhang9559b7a2015-12-21 11:12:20 -0800278 if (FXSYS_iswdigit(c)) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700279 number[nIndex++] = ParseStringInteger(value, i, nSkip, 4);
280 i += nSkip;
281 } else {
282 i++;
283 }
284 }
285
286 if (nIndex == 2) {
287 // case2: month/day
288 // case3: day/month
289 if ((number[0] >= 1 && number[0] <= 12) &&
290 (number[1] >= 1 && number[1] <= 31)) {
291 nMonth = number[0];
292 nDay = number[1];
293 } else if ((number[0] >= 1 && number[0] <= 31) &&
294 (number[1] >= 1 && number[1] <= 12)) {
295 nDay = number[0];
296 nMonth = number[1];
Tom Sepez2f2ffec2015-07-23 14:42:09 -0700297 }
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700298
Lei Zhang9559b7a2015-12-21 11:12:20 -0800299 if (bWrongFormat)
300 *bWrongFormat = false;
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700301 } else if (nIndex == 3) {
302 // case1: year/month/day
303 // case2: month/day/year
304 // case3: day/month/year
Tom Sepez5ffacd62014-07-18 14:42:12 -0700305
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700306 if (number[0] > 12 && (number[1] >= 1 && number[1] <= 12) &&
307 (number[2] >= 1 && number[2] <= 31)) {
308 nYear = number[0];
309 nMonth = number[1];
310 nDay = number[2];
311 } else if ((number[0] >= 1 && number[0] <= 12) &&
312 (number[1] >= 1 && number[1] <= 31) && number[2] > 31) {
313 nMonth = number[0];
314 nDay = number[1];
315 nYear = number[2];
316 } else if ((number[0] >= 1 && number[0] <= 31) &&
317 (number[1] >= 1 && number[1] <= 12) && number[2] > 31) {
318 nDay = number[0];
319 nMonth = number[1];
320 nYear = number[2];
Tom Sepez2f2ffec2015-07-23 14:42:09 -0700321 }
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700322
Lei Zhang9559b7a2015-12-21 11:12:20 -0800323 if (bWrongFormat)
324 *bWrongFormat = false;
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700325 } else {
Lei Zhang9559b7a2015-12-21 11:12:20 -0800326 if (bWrongFormat)
327 *bWrongFormat = true;
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700328 return dt;
329 }
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700330
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700331 CFX_WideString swTemp;
332 swTemp.Format(L"%d/%d/%d %d:%d:%d", nMonth, nDay, nYear, nHour, nMin, nSec);
333 return JS_DateParse(swTemp.c_str());
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700334}
335
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700336double CJS_PublicMethods::MakeRegularDate(const CFX_WideString& value,
337 const CFX_WideString& format,
Lei Zhang9559b7a2015-12-21 11:12:20 -0800338 bool* bWrongFormat) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700339 double dt = JS_GetDateTime();
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700340
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700341 if (format.IsEmpty() || value.IsEmpty())
342 return dt;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700343
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700344 int nYear = JS_GetYearFromTime(dt);
345 int nMonth = JS_GetMonthFromTime(dt) + 1;
346 int nDay = JS_GetDayFromTime(dt);
347 int nHour = JS_GetHourFromTime(dt);
348 int nMin = JS_GetMinFromTime(dt);
349 int nSec = JS_GetSecFromTime(dt);
350
351 int nYearSub = 99; // nYear - 2000;
352
353 FX_BOOL bPm = FALSE;
354 FX_BOOL bExit = FALSE;
Lei Zhang9559b7a2015-12-21 11:12:20 -0800355 bool bBadFormat = false;
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700356
357 int i = 0;
358 int j = 0;
359
360 while (i < format.GetLength()) {
361 if (bExit)
362 break;
363
364 FX_WCHAR c = format.GetAt(i);
365 switch (c) {
366 case ':':
367 case '.':
368 case '-':
369 case '\\':
370 case '/':
371 i++;
372 j++;
373 break;
374
375 case 'y':
376 case 'm':
377 case 'd':
378 case 'H':
379 case 'h':
380 case 'M':
381 case 's':
382 case 't': {
383 int oldj = j;
384 int nSkip = 0;
385 int remaining = format.GetLength() - i - 1;
386
387 if (remaining == 0 || format.GetAt(i + 1) != c) {
388 switch (c) {
Tom Sepez2f2ffec2015-07-23 14:42:09 -0700389 case 'y':
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700390 i++;
391 j++;
392 break;
Tom Sepez2f2ffec2015-07-23 14:42:09 -0700393 case 'm':
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700394 nMonth = ParseStringInteger(value, j, nSkip, 2);
395 i++;
396 j += nSkip;
397 break;
Tom Sepez2f2ffec2015-07-23 14:42:09 -0700398 case 'd':
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700399 nDay = ParseStringInteger(value, j, nSkip, 2);
400 i++;
401 j += nSkip;
402 break;
Tom Sepez2f2ffec2015-07-23 14:42:09 -0700403 case 'H':
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700404 nHour = ParseStringInteger(value, j, nSkip, 2);
405 i++;
406 j += nSkip;
407 break;
Tom Sepez2f2ffec2015-07-23 14:42:09 -0700408 case 'h':
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700409 nHour = ParseStringInteger(value, j, nSkip, 2);
410 i++;
411 j += nSkip;
412 break;
Tom Sepez2f2ffec2015-07-23 14:42:09 -0700413 case 'M':
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700414 nMin = ParseStringInteger(value, j, nSkip, 2);
415 i++;
416 j += nSkip;
417 break;
Tom Sepez2f2ffec2015-07-23 14:42:09 -0700418 case 's':
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700419 nSec = ParseStringInteger(value, j, nSkip, 2);
420 i++;
421 j += nSkip;
422 break;
Tom Sepez2f2ffec2015-07-23 14:42:09 -0700423 case 't':
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700424 bPm = (j < value.GetLength() && value.GetAt(j) == 'p');
425 i++;
426 j++;
427 break;
428 }
429 } else if (remaining == 1 || format.GetAt(i + 2) != c) {
430 switch (c) {
431 case 'y':
432 nYear = ParseStringInteger(value, j, nSkip, 4);
433 i += 2;
434 j += nSkip;
435 break;
436 case 'm':
437 nMonth = ParseStringInteger(value, j, nSkip, 2);
438 i += 2;
439 j += nSkip;
440 break;
441 case 'd':
442 nDay = ParseStringInteger(value, j, nSkip, 2);
443 i += 2;
444 j += nSkip;
445 break;
446 case 'H':
447 nHour = ParseStringInteger(value, j, nSkip, 2);
448 i += 2;
449 j += nSkip;
450 break;
451 case 'h':
452 nHour = ParseStringInteger(value, j, nSkip, 2);
453 i += 2;
454 j += nSkip;
455 break;
456 case 'M':
457 nMin = ParseStringInteger(value, j, nSkip, 2);
458 i += 2;
459 j += nSkip;
460 break;
461 case 's':
462 nSec = ParseStringInteger(value, j, nSkip, 2);
463 i += 2;
464 j += nSkip;
465 break;
466 case 't':
467 bPm = (j + 1 < value.GetLength() && value.GetAt(j) == 'p' &&
468 value.GetAt(j + 1) == 'm');
469 i += 2;
470 j += 2;
471 break;
472 }
473 } else if (remaining == 2 || format.GetAt(i + 3) != c) {
474 switch (c) {
475 case 'm': {
476 CFX_WideString sMonth = ParseStringString(value, j, nSkip);
477 FX_BOOL bFind = FALSE;
478 for (int m = 0; m < 12; m++) {
479 if (sMonth.CompareNoCase(months[m]) == 0) {
480 nMonth = m + 1;
481 i += 3;
482 j += nSkip;
483 bFind = TRUE;
484 break;
Tom Sepez2f2ffec2015-07-23 14:42:09 -0700485 }
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700486 }
487
488 if (!bFind) {
489 nMonth = ParseStringInteger(value, j, nSkip, 3);
490 i += 3;
491 j += nSkip;
492 }
493 } break;
494 case 'y':
495 break;
Tom Sepez2f2ffec2015-07-23 14:42:09 -0700496 default:
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700497 i += 3;
498 j += 3;
499 break;
500 }
501 } else if (remaining == 3 || format.GetAt(i + 4) != c) {
502 switch (c) {
503 case 'y':
504 nYear = ParseStringInteger(value, j, nSkip, 4);
505 j += nSkip;
506 i += 4;
507 break;
508 case 'm': {
509 FX_BOOL bFind = FALSE;
510
511 CFX_WideString sMonth = ParseStringString(value, j, nSkip);
512 sMonth.MakeLower();
513
514 for (int m = 0; m < 12; m++) {
515 CFX_WideString sFullMonths = fullmonths[m];
516 sFullMonths.MakeLower();
517
518 if (sFullMonths.Find(sMonth.c_str(), 0) != -1) {
519 nMonth = m + 1;
520 i += 4;
521 j += nSkip;
522 bFind = TRUE;
523 break;
524 }
525 }
526
527 if (!bFind) {
528 nMonth = ParseStringInteger(value, j, nSkip, 4);
529 i += 4;
530 j += nSkip;
531 }
532 } break;
533 default:
534 i += 4;
535 j += 4;
536 break;
537 }
538 } else {
539 if (j >= value.GetLength() || format.GetAt(i) != value.GetAt(j)) {
Lei Zhang9559b7a2015-12-21 11:12:20 -0800540 bBadFormat = true;
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700541 bExit = TRUE;
542 }
543 i++;
544 j++;
Tom Sepez2f2ffec2015-07-23 14:42:09 -0700545 }
Tom Sepez85386422014-07-23 10:28:37 -0700546
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700547 if (oldj == j) {
Lei Zhang9559b7a2015-12-21 11:12:20 -0800548 bBadFormat = true;
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700549 bExit = TRUE;
550 }
551 }
552
553 break;
554 default:
555 if (value.GetLength() <= j) {
556 bExit = TRUE;
557 } else if (format.GetAt(i) != value.GetAt(j)) {
Lei Zhang9559b7a2015-12-21 11:12:20 -0800558 bBadFormat = true;
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700559 bExit = TRUE;
560 }
561
562 i++;
563 j++;
564 break;
565 }
566 }
567
568 if (bPm)
569 nHour += 12;
570
571 if (nYear >= 0 && nYear <= nYearSub)
572 nYear += 2000;
573
574 if (nMonth < 1 || nMonth > 12)
Lei Zhang9559b7a2015-12-21 11:12:20 -0800575 bBadFormat = true;
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700576
577 if (nDay < 1 || nDay > 31)
Lei Zhang9559b7a2015-12-21 11:12:20 -0800578 bBadFormat = true;
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700579
580 if (nHour < 0 || nHour > 24)
Lei Zhang9559b7a2015-12-21 11:12:20 -0800581 bBadFormat = true;
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700582
583 if (nMin < 0 || nMin > 60)
Lei Zhang9559b7a2015-12-21 11:12:20 -0800584 bBadFormat = true;
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700585
586 if (nSec < 0 || nSec > 60)
Lei Zhang9559b7a2015-12-21 11:12:20 -0800587 bBadFormat = true;
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700588
589 double dRet = 0;
590
Lei Zhang9559b7a2015-12-21 11:12:20 -0800591 if (bBadFormat) {
592 dRet = ParseNormalDate(value, &bBadFormat);
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700593 } else {
594 dRet = JS_MakeDate(JS_MakeDay(nYear, nMonth - 1, nDay),
595 JS_MakeTime(nHour, nMin, nSec, 0));
596
597 if (JS_PortIsNan(dRet)) {
598 dRet = JS_DateParse(value.c_str());
599 }
600 }
601
602 if (JS_PortIsNan(dRet)) {
Lei Zhang9559b7a2015-12-21 11:12:20 -0800603 dRet = ParseNormalDate(value, &bBadFormat);
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700604 }
605
Lei Zhang9559b7a2015-12-21 11:12:20 -0800606 if (bWrongFormat)
607 *bWrongFormat = bBadFormat;
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700608 return dRet;
609}
610
611CFX_WideString CJS_PublicMethods::MakeFormatDate(double dDate,
612 const CFX_WideString& format) {
613 CFX_WideString sRet = L"", sPart = L"";
614
615 int nYear = JS_GetYearFromTime(dDate);
616 int nMonth = JS_GetMonthFromTime(dDate) + 1;
617 int nDay = JS_GetDayFromTime(dDate);
618 int nHour = JS_GetHourFromTime(dDate);
619 int nMin = JS_GetMinFromTime(dDate);
620 int nSec = JS_GetSecFromTime(dDate);
621
622 int i = 0;
623 while (i < format.GetLength()) {
624 FX_WCHAR c = format.GetAt(i);
625 int remaining = format.GetLength() - i - 1;
626 sPart = L"";
627 switch (c) {
628 case 'y':
629 case 'm':
630 case 'd':
631 case 'H':
632 case 'h':
633 case 'M':
634 case 's':
635 case 't':
636 if (remaining == 0 || format.GetAt(i + 1) != c) {
637 switch (c) {
638 case 'y':
639 sPart += c;
640 break;
641 case 'm':
642 sPart.Format(L"%d", nMonth);
643 break;
644 case 'd':
645 sPart.Format(L"%d", nDay);
646 break;
647 case 'H':
648 sPart.Format(L"%d", nHour);
649 break;
650 case 'h':
651 sPart.Format(L"%d", nHour > 12 ? nHour - 12 : nHour);
652 break;
653 case 'M':
654 sPart.Format(L"%d", nMin);
655 break;
656 case 's':
657 sPart.Format(L"%d", nSec);
658 break;
659 case 't':
660 sPart += nHour > 12 ? 'p' : 'a';
661 break;
662 }
663 i++;
664 } else if (remaining == 1 || format.GetAt(i + 2) != c) {
665 switch (c) {
666 case 'y':
667 sPart.Format(L"%02d", nYear - (nYear / 100) * 100);
668 break;
669 case 'm':
670 sPart.Format(L"%02d", nMonth);
671 break;
672 case 'd':
673 sPart.Format(L"%02d", nDay);
674 break;
675 case 'H':
676 sPart.Format(L"%02d", nHour);
677 break;
678 case 'h':
679 sPart.Format(L"%02d", nHour > 12 ? nHour - 12 : nHour);
680 break;
681 case 'M':
682 sPart.Format(L"%02d", nMin);
683 break;
684 case 's':
685 sPart.Format(L"%02d", nSec);
686 break;
687 case 't':
688 sPart = nHour > 12 ? L"pm" : L"am";
689 break;
690 }
691 i += 2;
692 } else if (remaining == 2 || format.GetAt(i + 3) != c) {
693 switch (c) {
694 case 'm':
695 i += 3;
696 if (nMonth > 0 && nMonth <= 12)
697 sPart += months[nMonth - 1];
698 break;
699 default:
700 i += 3;
701 sPart += c;
702 sPart += c;
703 sPart += c;
704 break;
705 }
706 } else if (remaining == 3 || format.GetAt(i + 4) != c) {
707 switch (c) {
708 case 'y':
709 sPart.Format(L"%04d", nYear);
710 i += 4;
711 break;
712 case 'm':
713 i += 4;
714 if (nMonth > 0 && nMonth <= 12)
715 sPart += fullmonths[nMonth - 1];
716 break;
717 default:
718 i += 4;
719 sPart += c;
720 sPart += c;
721 sPart += c;
722 sPart += c;
723 break;
724 }
725 } else {
726 i++;
727 sPart += c;
728 }
729 break;
730 default:
731 i++;
732 sPart += c;
733 break;
Tom Sepez2f2ffec2015-07-23 14:42:09 -0700734 }
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700735
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700736 sRet += sPart;
737 }
738
739 return sRet;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700740}
741
742/* -------------------------------------------------------------------------- */
743
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700744// function AFNumber_Format(nDec, sepStyle, negStyle, currStyle, strCurrency,
745// bCurrencyPrepend)
Tom Sepezba038bc2015-10-08 12:03:00 -0700746FX_BOOL CJS_PublicMethods::AFNumber_Format(IJS_Context* cc,
Lei Zhang945fdb72015-11-11 10:18:16 -0800747 const std::vector<CJS_Value>& params,
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700748 CJS_Value& vRet,
749 CFX_WideString& sError) {
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700750#if _FX_OS_ != _FX_ANDROID_
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700751 CJS_Context* pContext = (CJS_Context*)cc;
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700752 if (params.size() != 6) {
753 sError = JSGetStringFromID(pContext, IDS_STRING_JSPARAMERROR);
754 return FALSE;
755 }
Tom Sepez67fd5df2015-10-08 12:24:19 -0700756
757 CJS_Runtime* pRuntime = CJS_Runtime::FromContext(cc);
758 CJS_EventHandler* pEvent = pContext->GetEventHandler();
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700759 if (!pEvent->m_pValue)
760 return FALSE;
Tom Sepez67fd5df2015-10-08 12:24:19 -0700761
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700762 CFX_WideString& Value = pEvent->Value();
763 CFX_ByteString strValue = StrTrim(CFX_ByteString::FromUnicode(Value));
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700764 if (strValue.IsEmpty())
Tom Sepez2f2ffec2015-07-23 14:42:09 -0700765 return TRUE;
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700766
767 int iDec = params[0].ToInt();
768 int iSepStyle = params[1].ToInt();
769 int iNegStyle = params[2].ToInt();
770 // params[3] is iCurrStyle, it's not used.
771 std::wstring wstrCurrency(params[4].ToCFXWideString().c_str());
772 FX_BOOL bCurrencyPrepend = params[5].ToBool();
773
774 if (iDec < 0)
775 iDec = -iDec;
776
777 if (iSepStyle < 0 || iSepStyle > 3)
778 iSepStyle = 0;
779
780 if (iNegStyle < 0 || iNegStyle > 3)
781 iNegStyle = 0;
782
783 //////////////////////////////////////////////////////
784 // for processing decimal places
785 strValue.Replace(",", ".");
786 double dValue = atof(strValue);
787 if (iDec > 0)
Tom Sepezdfbf8e72015-10-14 14:17:26 -0700788 dValue += DOUBLE_CORRECT;
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700789
790 int iDec2;
791 int iNegative = 0;
792
793 strValue = fcvt(dValue, iDec, &iDec2, &iNegative);
794 if (strValue.IsEmpty()) {
795 dValue = 0;
796 strValue = fcvt(dValue, iDec, &iDec2, &iNegative);
797 if (strValue.IsEmpty()) {
798 strValue = "0";
799 iDec2 = 1;
800 }
801 }
802
803 if (iDec2 < 0) {
804 for (int iNum = 0; iNum < abs(iDec2); iNum++) {
805 strValue = "0" + strValue;
806 }
807 iDec2 = 0;
808 }
809 int iMax = strValue.GetLength();
810 if (iDec2 > iMax) {
811 for (int iNum = 0; iNum <= iDec2 - iMax; iNum++) {
812 strValue += "0";
813 }
814 iMax = iDec2 + 1;
815 }
816 ///////////////////////////////////////////////////////
817 // for processing seperator style
818 if (iDec2 < iMax) {
819 if (iSepStyle == 0 || iSepStyle == 1) {
820 strValue.Insert(iDec2, '.');
821 iMax++;
822 } else if (iSepStyle == 2 || iSepStyle == 3) {
823 strValue.Insert(iDec2, ',');
824 iMax++;
825 }
826
827 if (iDec2 == 0)
828 strValue.Insert(iDec2, '0');
829 }
830 if (iSepStyle == 0 || iSepStyle == 2) {
831 char cSeperator;
832 if (iSepStyle == 0)
833 cSeperator = ',';
834 else
835 cSeperator = '.';
836
Tom Sepezdfbf8e72015-10-14 14:17:26 -0700837 for (int iDecPositive = iDec2 - 3; iDecPositive > 0; iDecPositive -= 3) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700838 strValue.Insert(iDecPositive, cSeperator);
839 iMax++;
840 }
841 }
842
843 //////////////////////////////////////////////////////////////////////
844 // for processing currency string
845
846 Value = CFX_WideString::FromLocal(strValue);
847 std::wstring strValue2 = Value.c_str();
848
849 if (bCurrencyPrepend)
850 strValue2 = wstrCurrency + strValue2;
851 else
852 strValue2 = strValue2 + wstrCurrency;
853
854 /////////////////////////////////////////////////////////////////////////
855 // for processing negative style
856 if (iNegative) {
857 if (iNegStyle == 0) {
858 strValue2.insert(0, L"-");
859 }
860 if (iNegStyle == 2 || iNegStyle == 3) {
861 strValue2.insert(0, L"(");
862 strValue2.insert(strValue2.length(), L")");
863 }
864 if (iNegStyle == 1 || iNegStyle == 3) {
865 if (Field* fTarget = pEvent->Target_Field()) {
Tom Sepez67fd5df2015-10-08 12:24:19 -0700866 CJS_Array arColor(pRuntime);
867 CJS_Value vColElm(pRuntime);
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700868 vColElm = L"RGB";
869 arColor.SetElement(0, vColElm);
870 vColElm = 1;
871 arColor.SetElement(1, vColElm);
872 vColElm = 0;
873 arColor.SetElement(2, vColElm);
874
875 arColor.SetElement(3, vColElm);
876
Tom Sepez67fd5df2015-10-08 12:24:19 -0700877 CJS_PropValue vProp(pRuntime);
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700878 vProp.StartGetting();
879 vProp << arColor;
880 vProp.StartSetting();
881 fTarget->textColor(cc, vProp, sError); // red
882 }
883 }
884 } else {
885 if (iNegStyle == 1 || iNegStyle == 3) {
886 if (Field* fTarget = pEvent->Target_Field()) {
Tom Sepez67fd5df2015-10-08 12:24:19 -0700887 CJS_Array arColor(pRuntime);
888 CJS_Value vColElm(pRuntime);
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700889 vColElm = L"RGB";
890 arColor.SetElement(0, vColElm);
891 vColElm = 0;
892 arColor.SetElement(1, vColElm);
893 arColor.SetElement(2, vColElm);
894 arColor.SetElement(3, vColElm);
895
Tom Sepez67fd5df2015-10-08 12:24:19 -0700896 CJS_PropValue vProp(pRuntime);
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700897 vProp.StartGetting();
898 fTarget->textColor(cc, vProp, sError);
899
Tom Sepez67fd5df2015-10-08 12:24:19 -0700900 CJS_Array aProp(pRuntime);
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700901 vProp.ConvertToArray(aProp);
902
903 CPWL_Color crProp;
904 CPWL_Color crColor;
905 color::ConvertArrayToPWLColor(aProp, crProp);
906 color::ConvertArrayToPWLColor(arColor, crColor);
907
908 if (crColor != crProp) {
Tom Sepez67fd5df2015-10-08 12:24:19 -0700909 CJS_PropValue vProp2(pRuntime);
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700910 vProp2.StartGetting();
911 vProp2 << arColor;
912 vProp2.StartSetting();
913 fTarget->textColor(cc, vProp2, sError);
914 }
915 }
916 }
917 }
918 Value = strValue2.c_str();
919#endif
920 return TRUE;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700921}
922
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700923// function AFNumber_Keystroke(nDec, sepStyle, negStyle, currStyle, strCurrency,
924// bCurrencyPrepend)
Lei Zhang945fdb72015-11-11 10:18:16 -0800925FX_BOOL CJS_PublicMethods::AFNumber_Keystroke(
926 IJS_Context* cc,
927 const std::vector<CJS_Value>& params,
928 CJS_Value& vRet,
929 CFX_WideString& sError) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700930 CJS_Context* pContext = (CJS_Context*)cc;
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700931 CJS_EventHandler* pEvent = pContext->GetEventHandler();
Lei Zhanga6d9f0e2015-06-13 00:48:38 -0700932
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700933 if (params.size() < 2)
934 return FALSE;
935 int iSepStyle = params[1].ToInt();
Lei Zhanga6d9f0e2015-06-13 00:48:38 -0700936
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700937 if (iSepStyle < 0 || iSepStyle > 3)
938 iSepStyle = 0;
939 if (!pEvent->m_pValue)
940 return FALSE;
941 CFX_WideString& val = pEvent->Value();
942 CFX_WideString& w_strChange = pEvent->Change();
943 CFX_WideString w_strValue = val;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700944
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700945 if (pEvent->WillCommit()) {
946 CFX_WideString wstrChange = w_strChange;
947 CFX_WideString wstrValue = StrLTrim(w_strValue.c_str());
948 if (wstrValue.IsEmpty())
949 return TRUE;
Lei Zhanga6d9f0e2015-06-13 00:48:38 -0700950
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700951 CFX_WideString swTemp = wstrValue;
952 swTemp.Replace(L",", L".");
953 if (!IsNumber(swTemp.c_str())) {
954 pEvent->Rc() = FALSE;
955 sError = JSGetStringFromID(pContext, IDS_STRING_JSAFNUMBER_KEYSTROKE);
956 Alert(pContext, sError.c_str());
957 return TRUE;
Tom Sepez2f2ffec2015-07-23 14:42:09 -0700958 }
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700959 return TRUE; // it happens after the last keystroke and before validating,
960 }
Tom Sepez4f7bc042015-04-27 12:06:58 -0700961
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700962 std::wstring w_strValue2 = w_strValue.c_str();
963 std::wstring w_strChange2 = w_strChange.c_str();
964 std::wstring w_strSelected;
965 if (-1 != pEvent->SelStart())
966 w_strSelected = w_strValue2.substr(pEvent->SelStart(),
967 (pEvent->SelEnd() - pEvent->SelStart()));
Lei Zhangb9c31972015-08-11 14:09:35 -0700968 bool bHasSign = (w_strValue2.find('-') != std::wstring::npos) &&
969 (w_strSelected.find('-') == std::wstring::npos);
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700970 if (bHasSign) {
971 // can't insert "change" in front to sign postion.
972 if (pEvent->SelStart() == 0) {
973 FX_BOOL& bRc = pEvent->Rc();
974 bRc = FALSE;
975 return TRUE;
Tom Sepez2f2ffec2015-07-23 14:42:09 -0700976 }
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700977 }
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700978
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700979 char cSep = L'.';
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700980
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700981 switch (iSepStyle) {
Tom Sepez2f2ffec2015-07-23 14:42:09 -0700982 case 0:
983 case 1:
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700984 cSep = L'.';
985 break;
Tom Sepez2f2ffec2015-07-23 14:42:09 -0700986 case 2:
987 case 3:
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700988 cSep = L',';
989 break;
990 }
Lei Zhanga6d9f0e2015-06-13 00:48:38 -0700991
Lei Zhangb9c31972015-08-11 14:09:35 -0700992 bool bHasSep = (w_strValue2.find(cSep) != std::wstring::npos);
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700993 for (std::wstring::iterator it = w_strChange2.begin();
994 it != w_strChange2.end(); it++) {
995 if (*it == cSep) {
996 if (bHasSep) {
997 FX_BOOL& bRc = pEvent->Rc();
998 bRc = FALSE;
Tom Sepez2f2ffec2015-07-23 14:42:09 -0700999 return TRUE;
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001000 }
1001 bHasSep = TRUE;
1002 continue;
1003 }
1004 if (*it == L'-') {
1005 if (bHasSign) {
1006 FX_BOOL& bRc = pEvent->Rc();
1007 bRc = FALSE;
1008 return TRUE;
1009 }
Lei Zhang9559b7a2015-12-21 11:12:20 -08001010 // sign's position is not correct
1011 if (it != w_strChange2.begin()) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001012 FX_BOOL& bRc = pEvent->Rc();
1013 bRc = FALSE;
1014 return TRUE;
1015 }
1016 if (pEvent->SelStart() != 0) {
1017 FX_BOOL& bRc = pEvent->Rc();
1018 bRc = FALSE;
1019 return TRUE;
1020 }
1021 bHasSign = TRUE;
1022 continue;
1023 }
1024
Lei Zhang9559b7a2015-12-21 11:12:20 -08001025 if (!FXSYS_iswdigit(*it)) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001026 FX_BOOL& bRc = pEvent->Rc();
1027 bRc = FALSE;
1028 return TRUE;
1029 }
1030 }
1031
1032 std::wstring w_prefix = w_strValue2.substr(0, pEvent->SelStart());
1033 std::wstring w_postfix;
1034 if (pEvent->SelEnd() < (int)w_strValue2.length())
1035 w_postfix = w_strValue2.substr(pEvent->SelEnd());
1036 w_strValue2 = w_prefix + w_strChange2 + w_postfix;
1037 w_strValue = w_strValue2.c_str();
1038 val = w_strValue;
1039 return TRUE;
1040}
1041
1042// function AFPercent_Format(nDec, sepStyle)
Lei Zhang945fdb72015-11-11 10:18:16 -08001043FX_BOOL CJS_PublicMethods::AFPercent_Format(
1044 IJS_Context* cc,
1045 const std::vector<CJS_Value>& params,
1046 CJS_Value& vRet,
1047 CFX_WideString& sError) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001048#if _FX_OS_ != _FX_ANDROID_
1049 CJS_Context* pContext = (CJS_Context*)cc;
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001050 CJS_EventHandler* pEvent = pContext->GetEventHandler();
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001051
1052 if (params.size() != 2) {
1053 sError = JSGetStringFromID(pContext, IDS_STRING_JSPARAMERROR);
1054 return FALSE;
1055 }
1056 if (!pEvent->m_pValue)
1057 return FALSE;
1058
1059 CFX_WideString& Value = pEvent->Value();
1060 CFX_ByteString strValue = StrTrim(CFX_ByteString::FromUnicode(Value));
1061 if (strValue.IsEmpty())
1062 return TRUE;
1063
1064 int iDec = params[0].ToInt();
1065 if (iDec < 0)
1066 iDec = -iDec;
1067
1068 int iSepStyle = params[1].ToInt();
1069 if (iSepStyle < 0 || iSepStyle > 3)
1070 iSepStyle = 0;
1071
1072 //////////////////////////////////////////////////////
1073 // for processing decimal places
1074 double dValue = atof(strValue);
1075 dValue *= 100;
1076 if (iDec > 0)
Lei Zhang9559b7a2015-12-21 11:12:20 -08001077 dValue += DOUBLE_CORRECT;
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001078
1079 int iDec2;
1080 int iNegative = 0;
1081 strValue = fcvt(dValue, iDec, &iDec2, &iNegative);
1082 if (strValue.IsEmpty()) {
1083 dValue = 0;
1084 strValue = fcvt(dValue, iDec, &iDec2, &iNegative);
1085 }
1086
1087 if (iDec2 < 0) {
1088 for (int iNum = 0; iNum < abs(iDec2); iNum++) {
1089 strValue = "0" + strValue;
1090 }
1091 iDec2 = 0;
1092 }
1093 int iMax = strValue.GetLength();
1094 if (iDec2 > iMax) {
1095 for (int iNum = 0; iNum <= iDec2 - iMax; iNum++) {
1096 strValue += "0";
1097 }
1098 iMax = iDec2 + 1;
1099 }
1100 ///////////////////////////////////////////////////////
1101 // for processing seperator style
1102 if (iDec2 < iMax) {
1103 if (iSepStyle == 0 || iSepStyle == 1) {
1104 strValue.Insert(iDec2, '.');
1105 iMax++;
1106 } else if (iSepStyle == 2 || iSepStyle == 3) {
1107 strValue.Insert(iDec2, ',');
1108 iMax++;
1109 }
1110
1111 if (iDec2 == 0)
1112 strValue.Insert(iDec2, '0');
1113 }
1114 if (iSepStyle == 0 || iSepStyle == 2) {
1115 char cSeperator;
1116 if (iSepStyle == 0)
1117 cSeperator = ',';
1118 else
1119 cSeperator = '.';
1120
Tom Sepezdfbf8e72015-10-14 14:17:26 -07001121 for (int iDecPositive = iDec2 - 3; iDecPositive > 0; iDecPositive -= 3) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001122 strValue.Insert(iDecPositive, cSeperator);
1123 iMax++;
1124 }
1125 }
1126 ////////////////////////////////////////////////////////////////////
1127 // negative mark
1128 if (iNegative)
1129 strValue = "-" + strValue;
1130 strValue += "%";
1131 Value = CFX_WideString::FromLocal(strValue);
1132#endif
1133 return TRUE;
1134}
1135// AFPercent_Keystroke(nDec, sepStyle)
Lei Zhang945fdb72015-11-11 10:18:16 -08001136FX_BOOL CJS_PublicMethods::AFPercent_Keystroke(
1137 IJS_Context* cc,
1138 const std::vector<CJS_Value>& params,
1139 CJS_Value& vRet,
1140 CFX_WideString& sError) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001141 return AFNumber_Keystroke(cc, params, vRet, sError);
1142}
1143
1144// function AFDate_FormatEx(cFormat)
Tom Sepezba038bc2015-10-08 12:03:00 -07001145FX_BOOL CJS_PublicMethods::AFDate_FormatEx(IJS_Context* cc,
Lei Zhang945fdb72015-11-11 10:18:16 -08001146 const std::vector<CJS_Value>& params,
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001147 CJS_Value& vRet,
1148 CFX_WideString& sError) {
1149 CJS_Context* pContext = (CJS_Context*)cc;
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001150 CJS_EventHandler* pEvent = pContext->GetEventHandler();
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001151
1152 if (params.size() != 1) {
1153 sError = JSGetStringFromID(pContext, IDS_STRING_JSPARAMERROR);
1154 return FALSE;
1155 }
1156 if (!pEvent->m_pValue)
1157 return FALSE;
1158
1159 CFX_WideString& val = pEvent->Value();
1160 CFX_WideString strValue = val;
1161 if (strValue.IsEmpty())
1162 return TRUE;
1163
1164 CFX_WideString sFormat = params[0].ToCFXWideString();
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001165 double dDate = 0.0f;
1166
1167 if (strValue.Find(L"GMT") != -1) {
1168 // for GMT format time
1169 // such as "Tue Aug 11 14:24:16 GMT+08002009"
1170 dDate = MakeInterDate(strValue);
1171 } else {
Lei Zhang9559b7a2015-12-21 11:12:20 -08001172 dDate = MakeRegularDate(strValue, sFormat, nullptr);
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001173 }
1174
1175 if (JS_PortIsNan(dDate)) {
1176 CFX_WideString swMsg;
1177 swMsg.Format(JSGetStringFromID(pContext, IDS_STRING_JSPARSEDATE).c_str(),
1178 sFormat.c_str());
1179 Alert(pContext, swMsg.c_str());
1180 return FALSE;
1181 }
1182
1183 val = MakeFormatDate(dDate, sFormat);
1184 return TRUE;
1185}
1186
1187double CJS_PublicMethods::MakeInterDate(CFX_WideString strValue) {
Tom Sepezab277682016-02-17 10:07:21 -08001188 std::vector<CFX_WideString> wsArray;
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001189 CFX_WideString sTemp = L"";
Tom Sepez4246b002016-01-20 11:48:29 -08001190 for (int i = 0; i < strValue.GetLength(); ++i) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001191 FX_WCHAR c = strValue.GetAt(i);
1192 if (c == L' ' || c == L':') {
Tom Sepezab277682016-02-17 10:07:21 -08001193 wsArray.push_back(sTemp);
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001194 sTemp = L"";
1195 continue;
1196 }
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001197 sTemp += c;
1198 }
Tom Sepezab277682016-02-17 10:07:21 -08001199 wsArray.push_back(sTemp);
1200 if (wsArray.size() != 8)
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001201 return 0;
1202
Tom Sepez4246b002016-01-20 11:48:29 -08001203 int nMonth = 1;
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001204 sTemp = wsArray[1];
1205 if (sTemp.Compare(L"Jan") == 0)
1206 nMonth = 1;
Tom Sepez4246b002016-01-20 11:48:29 -08001207 else if (sTemp.Compare(L"Feb") == 0)
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001208 nMonth = 2;
Tom Sepez4246b002016-01-20 11:48:29 -08001209 else if (sTemp.Compare(L"Mar") == 0)
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001210 nMonth = 3;
Tom Sepez4246b002016-01-20 11:48:29 -08001211 else if (sTemp.Compare(L"Apr") == 0)
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001212 nMonth = 4;
Tom Sepez4246b002016-01-20 11:48:29 -08001213 else if (sTemp.Compare(L"May") == 0)
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001214 nMonth = 5;
Tom Sepez4246b002016-01-20 11:48:29 -08001215 else if (sTemp.Compare(L"Jun") == 0)
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001216 nMonth = 6;
Tom Sepez4246b002016-01-20 11:48:29 -08001217 else if (sTemp.Compare(L"Jul") == 0)
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001218 nMonth = 7;
Tom Sepez4246b002016-01-20 11:48:29 -08001219 else if (sTemp.Compare(L"Aug") == 0)
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001220 nMonth = 8;
Tom Sepez4246b002016-01-20 11:48:29 -08001221 else if (sTemp.Compare(L"Sep") == 0)
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001222 nMonth = 9;
Tom Sepez4246b002016-01-20 11:48:29 -08001223 else if (sTemp.Compare(L"Oct") == 0)
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001224 nMonth = 10;
Tom Sepez4246b002016-01-20 11:48:29 -08001225 else if (sTemp.Compare(L"Nov") == 0)
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001226 nMonth = 11;
Tom Sepez4246b002016-01-20 11:48:29 -08001227 else if (sTemp.Compare(L"Dec") == 0)
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001228 nMonth = 12;
1229
Tom Sepez4246b002016-01-20 11:48:29 -08001230 int nDay = FX_atof(wsArray[2]);
1231 int nHour = FX_atof(wsArray[3]);
1232 int nMin = FX_atof(wsArray[4]);
1233 int nSec = FX_atof(wsArray[5]);
1234 int nYear = FX_atof(wsArray[7]);
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001235 double dRet = JS_MakeDate(JS_MakeDay(nYear, nMonth - 1, nDay),
1236 JS_MakeTime(nHour, nMin, nSec, 0));
Tom Sepez4246b002016-01-20 11:48:29 -08001237 if (JS_PortIsNan(dRet))
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001238 dRet = JS_DateParse(strValue.c_str());
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001239
1240 return dRet;
1241}
1242
1243// AFDate_KeystrokeEx(cFormat)
Lei Zhang945fdb72015-11-11 10:18:16 -08001244FX_BOOL CJS_PublicMethods::AFDate_KeystrokeEx(
1245 IJS_Context* cc,
1246 const std::vector<CJS_Value>& params,
1247 CJS_Value& vRet,
1248 CFX_WideString& sError) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001249 CJS_Context* pContext = (CJS_Context*)cc;
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001250 CJS_EventHandler* pEvent = pContext->GetEventHandler();
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001251
1252 if (params.size() != 1) {
1253 sError = L"AFDate_KeystrokeEx's parameters' size r not correct";
1254 return FALSE;
1255 }
1256
1257 if (pEvent->WillCommit()) {
1258 if (!pEvent->m_pValue)
1259 return FALSE;
1260 CFX_WideString strValue = pEvent->Value();
1261 if (strValue.IsEmpty())
1262 return TRUE;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07001263
Tom Sepez2f2ffec2015-07-23 14:42:09 -07001264 CFX_WideString sFormat = params[0].ToCFXWideString();
Lei Zhang9559b7a2015-12-21 11:12:20 -08001265 bool bWrongFormat = FALSE;
1266 double dRet = MakeRegularDate(strValue, sFormat, &bWrongFormat);
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001267 if (bWrongFormat || JS_PortIsNan(dRet)) {
1268 CFX_WideString swMsg;
1269 swMsg.Format(JSGetStringFromID(pContext, IDS_STRING_JSPARSEDATE).c_str(),
1270 sFormat.c_str());
1271 Alert(pContext, swMsg.c_str());
1272 pEvent->Rc() = FALSE;
1273 return TRUE;
Tom Sepez2f2ffec2015-07-23 14:42:09 -07001274 }
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001275 }
1276 return TRUE;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07001277}
1278
Tom Sepezba038bc2015-10-08 12:03:00 -07001279FX_BOOL CJS_PublicMethods::AFDate_Format(IJS_Context* cc,
Lei Zhang945fdb72015-11-11 10:18:16 -08001280 const std::vector<CJS_Value>& params,
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001281 CJS_Value& vRet,
1282 CFX_WideString& sError) {
Tom Sepez67fd5df2015-10-08 12:24:19 -07001283 CJS_Context* pContext = (CJS_Context*)cc;
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001284 if (params.size() != 1) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001285 sError = JSGetStringFromID(pContext, IDS_STRING_JSPARAMERROR);
1286 return FALSE;
1287 }
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07001288
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001289 int iIndex = params[0].ToInt();
1290 const FX_WCHAR* cFormats[] = {L"m/d",
1291 L"m/d/yy",
1292 L"mm/dd/yy",
1293 L"mm/yy",
1294 L"d-mmm",
1295 L"d-mmm-yy",
1296 L"dd-mmm-yy",
1297 L"yy-mm-dd",
1298 L"mmm-yy",
1299 L"mmmm-yy",
1300 L"mmm d, yyyy",
1301 L"mmmm d, yyyy",
1302 L"m/d/yy h:MM tt",
1303 L"m/d/yy HH:MM"};
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07001304
Lei Zhanga0f67242015-08-17 15:39:30 -07001305 if (iIndex < 0 || (static_cast<size_t>(iIndex) >= FX_ArraySize(cFormats)))
1306 iIndex = 0;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07001307
Lei Zhang945fdb72015-11-11 10:18:16 -08001308 std::vector<CJS_Value> newParams;
Tom Sepez67fd5df2015-10-08 12:24:19 -07001309 newParams.push_back(
1310 CJS_Value(CJS_Runtime::FromContext(cc), cFormats[iIndex]));
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001311 return AFDate_FormatEx(cc, newParams, vRet, sError);
1312}
Lei Zhanga6d9f0e2015-06-13 00:48:38 -07001313
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001314// AFDate_KeystrokeEx(cFormat)
Lei Zhang945fdb72015-11-11 10:18:16 -08001315FX_BOOL CJS_PublicMethods::AFDate_Keystroke(
1316 IJS_Context* cc,
1317 const std::vector<CJS_Value>& params,
1318 CJS_Value& vRet,
1319 CFX_WideString& sError) {
Tom Sepez67fd5df2015-10-08 12:24:19 -07001320 CJS_Context* pContext = (CJS_Context*)cc;
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001321 if (params.size() != 1) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001322 sError = JSGetStringFromID(pContext, IDS_STRING_JSPARAMERROR);
1323 return FALSE;
1324 }
1325
1326 int iIndex = params[0].ToInt();
1327 const FX_WCHAR* cFormats[] = {L"m/d",
1328 L"m/d/yy",
1329 L"mm/dd/yy",
1330 L"mm/yy",
1331 L"d-mmm",
1332 L"d-mmm-yy",
1333 L"dd-mmm-yy",
1334 L"yy-mm-dd",
1335 L"mmm-yy",
1336 L"mmmm-yy",
1337 L"mmm d, yyyy",
1338 L"mmmm d, yyyy",
1339 L"m/d/yy h:MM tt",
1340 L"m/d/yy HH:MM"};
1341
Lei Zhanga0f67242015-08-17 15:39:30 -07001342 if (iIndex < 0 || (static_cast<size_t>(iIndex) >= FX_ArraySize(cFormats)))
1343 iIndex = 0;
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001344
Lei Zhang945fdb72015-11-11 10:18:16 -08001345 std::vector<CJS_Value> newParams;
Tom Sepez67fd5df2015-10-08 12:24:19 -07001346 newParams.push_back(
1347 CJS_Value(CJS_Runtime::FromContext(cc), cFormats[iIndex]));
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001348 return AFDate_KeystrokeEx(cc, newParams, vRet, sError);
1349}
1350
1351// function AFTime_Format(ptf)
Tom Sepezba038bc2015-10-08 12:03:00 -07001352FX_BOOL CJS_PublicMethods::AFTime_Format(IJS_Context* cc,
Lei Zhang945fdb72015-11-11 10:18:16 -08001353 const std::vector<CJS_Value>& params,
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001354 CJS_Value& vRet,
1355 CFX_WideString& sError) {
Tom Sepez67fd5df2015-10-08 12:24:19 -07001356 CJS_Context* pContext = (CJS_Context*)cc;
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001357 if (params.size() != 1) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001358 sError = JSGetStringFromID(pContext, IDS_STRING_JSPARAMERROR);
1359 return FALSE;
1360 }
1361
1362 int iIndex = params[0].ToInt();
1363 const FX_WCHAR* cFormats[] = {L"HH:MM", L"h:MM tt", L"HH:MM:ss",
1364 L"h:MM:ss tt"};
1365
Lei Zhanga0f67242015-08-17 15:39:30 -07001366 if (iIndex < 0 || (static_cast<size_t>(iIndex) >= FX_ArraySize(cFormats)))
1367 iIndex = 0;
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001368
Lei Zhang945fdb72015-11-11 10:18:16 -08001369 std::vector<CJS_Value> newParams;
Tom Sepez67fd5df2015-10-08 12:24:19 -07001370 newParams.push_back(
1371 CJS_Value(CJS_Runtime::FromContext(cc), cFormats[iIndex]));
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001372 return AFDate_FormatEx(cc, newParams, vRet, sError);
1373}
1374
Lei Zhang945fdb72015-11-11 10:18:16 -08001375FX_BOOL CJS_PublicMethods::AFTime_Keystroke(
1376 IJS_Context* cc,
1377 const std::vector<CJS_Value>& params,
1378 CJS_Value& vRet,
1379 CFX_WideString& sError) {
Tom Sepez67fd5df2015-10-08 12:24:19 -07001380 CJS_Context* pContext = (CJS_Context*)cc;
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001381 if (params.size() != 1) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001382 sError = JSGetStringFromID(pContext, IDS_STRING_JSPARAMERROR);
1383 return FALSE;
1384 }
1385
1386 int iIndex = params[0].ToInt();
1387 const FX_WCHAR* cFormats[] = {L"HH:MM", L"h:MM tt", L"HH:MM:ss",
1388 L"h:MM:ss tt"};
1389
Lei Zhanga0f67242015-08-17 15:39:30 -07001390 if (iIndex < 0 || (static_cast<size_t>(iIndex) >= FX_ArraySize(cFormats)))
1391 iIndex = 0;
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001392
Lei Zhang945fdb72015-11-11 10:18:16 -08001393 std::vector<CJS_Value> newParams;
Tom Sepez67fd5df2015-10-08 12:24:19 -07001394 newParams.push_back(
1395 CJS_Value(CJS_Runtime::FromContext(cc), cFormats[iIndex]));
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001396 return AFDate_KeystrokeEx(cc, newParams, vRet, sError);
1397}
1398
Tom Sepezba038bc2015-10-08 12:03:00 -07001399FX_BOOL CJS_PublicMethods::AFTime_FormatEx(IJS_Context* cc,
Lei Zhang945fdb72015-11-11 10:18:16 -08001400 const std::vector<CJS_Value>& params,
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001401 CJS_Value& vRet,
1402 CFX_WideString& sError) {
1403 return AFDate_FormatEx(cc, params, vRet, sError);
1404}
1405
Lei Zhang945fdb72015-11-11 10:18:16 -08001406FX_BOOL CJS_PublicMethods::AFTime_KeystrokeEx(
1407 IJS_Context* cc,
1408 const std::vector<CJS_Value>& params,
1409 CJS_Value& vRet,
1410 CFX_WideString& sError) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001411 return AFDate_KeystrokeEx(cc, params, vRet, sError);
1412}
1413
1414// function AFSpecial_Format(psf)
Lei Zhang945fdb72015-11-11 10:18:16 -08001415FX_BOOL CJS_PublicMethods::AFSpecial_Format(
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
1422 if (params.size() != 1) {
1423 sError = JSGetStringFromID(pContext, IDS_STRING_JSPARAMERROR);
1424 return FALSE;
1425 }
1426
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001427 CJS_EventHandler* pEvent = pContext->GetEventHandler();
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001428 if (!pEvent->m_pValue)
1429 return FALSE;
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001430
tsepez4f1f41f2016-03-28 14:13:16 -07001431 CFX_WideString wsSource = pEvent->Value();
1432 CFX_WideString wsFormat;
1433 switch (params[0].ToInt()) {
Tom Sepez2f2ffec2015-07-23 14:42:09 -07001434 case 0:
tsepez4f1f41f2016-03-28 14:13:16 -07001435 wsFormat = L"99999";
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001436 break;
Tom Sepez2f2ffec2015-07-23 14:42:09 -07001437 case 1:
tsepez4f1f41f2016-03-28 14:13:16 -07001438 wsFormat = L"99999-9999";
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001439 break;
tsepez4f1f41f2016-03-28 14:13:16 -07001440 case 2:
1441 if (util::printx(L"9999999999", wsSource).GetLength() >= 10)
1442 wsFormat = L"(999) 999-9999";
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001443 else
tsepez4f1f41f2016-03-28 14:13:16 -07001444 wsFormat = L"999-9999";
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001445 break;
Tom Sepez2f2ffec2015-07-23 14:42:09 -07001446 case 3:
tsepez4f1f41f2016-03-28 14:13:16 -07001447 wsFormat = L"999-99-9999";
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001448 break;
1449 }
1450
tsepez4f1f41f2016-03-28 14:13:16 -07001451 pEvent->Value() = util::printx(wsFormat, wsSource);
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001452 return TRUE;
1453}
1454
1455// function AFSpecial_KeystrokeEx(mask)
Lei Zhang945fdb72015-11-11 10:18:16 -08001456FX_BOOL CJS_PublicMethods::AFSpecial_KeystrokeEx(
1457 IJS_Context* cc,
1458 const std::vector<CJS_Value>& params,
1459 CJS_Value& vRet,
1460 CFX_WideString& sError) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001461 CJS_Context* pContext = (CJS_Context*)cc;
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001462 CJS_EventHandler* pEvent = pContext->GetEventHandler();
1463
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001464 if (params.size() < 1) {
1465 sError = JSGetStringFromID(pContext, IDS_STRING_JSPARAMERROR);
1466 return FALSE;
1467 }
1468
1469 if (!pEvent->m_pValue)
1470 return FALSE;
1471 CFX_WideString& valEvent = pEvent->Value();
1472
1473 CFX_WideString wstrMask = params[0].ToCFXWideString();
1474 if (wstrMask.IsEmpty())
1475 return TRUE;
1476
Lei Zhanga0f67242015-08-17 15:39:30 -07001477 const size_t wstrMaskLen = wstrMask.GetLength();
1478 const std::wstring wstrValue = valEvent.c_str();
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001479
1480 if (pEvent->WillCommit()) {
1481 if (wstrValue.empty())
1482 return TRUE;
Lei Zhanga0f67242015-08-17 15:39:30 -07001483 size_t iIndexMask = 0;
1484 for (const auto& w_Value : wstrValue) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001485 if (!maskSatisfied(w_Value, wstrMask[iIndexMask]))
Tom Sepez2f2ffec2015-07-23 14:42:09 -07001486 break;
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001487 iIndexMask++;
Tom Sepez2f2ffec2015-07-23 14:42:09 -07001488 }
Lei Zhanga6d9f0e2015-06-13 00:48:38 -07001489
Lei Zhanga0f67242015-08-17 15:39:30 -07001490 if (iIndexMask != wstrMaskLen ||
1491 (iIndexMask != wstrValue.size() && wstrMaskLen != 0)) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001492 Alert(
1493 pContext,
1494 JSGetStringFromID(pContext, IDS_STRING_JSAFNUMBER_KEYSTROKE).c_str());
1495 pEvent->Rc() = FALSE;
1496 }
Tom Sepez2f2ffec2015-07-23 14:42:09 -07001497 return TRUE;
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001498 }
1499
1500 CFX_WideString& wideChange = pEvent->Change();
1501 std::wstring wChange = wideChange.c_str();
1502 if (wChange.empty())
1503 return TRUE;
1504
Wei Li05d53f02016-03-29 16:42:53 -07001505 size_t iIndexMask = pEvent->SelStart();
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001506
Lei Zhanga0f67242015-08-17 15:39:30 -07001507 size_t combined_len = wstrValue.length() + wChange.length() -
1508 (pEvent->SelEnd() - pEvent->SelStart());
1509 if (combined_len > wstrMaskLen) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001510 Alert(pContext,
1511 JSGetStringFromID(pContext, IDS_STRING_JSPARAM_TOOLONG).c_str());
1512 pEvent->Rc() = FALSE;
1513 return TRUE;
1514 }
1515
Lei Zhanga0f67242015-08-17 15:39:30 -07001516 if (iIndexMask >= wstrMaskLen && (!wChange.empty())) {
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
1523 for (std::wstring::iterator it = wChange.begin(); it != wChange.end(); it++) {
Lei Zhanga0f67242015-08-17 15:39:30 -07001524 if (iIndexMask >= wstrMaskLen) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001525 Alert(pContext,
1526 JSGetStringFromID(pContext, IDS_STRING_JSPARAM_TOOLONG).c_str());
1527 pEvent->Rc() = FALSE;
1528 return TRUE;
1529 }
1530 wchar_t w_Mask = wstrMask[iIndexMask];
1531 if (!isReservedMaskChar(w_Mask)) {
1532 *it = w_Mask;
1533 }
1534 wchar_t w_Change = *it;
1535 if (!maskSatisfied(w_Change, w_Mask)) {
1536 pEvent->Rc() = FALSE;
1537 return TRUE;
1538 }
1539 iIndexMask++;
1540 }
1541
1542 wideChange = wChange.c_str();
1543 return TRUE;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07001544}
1545
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001546// function AFSpecial_Keystroke(psf)
Lei Zhang945fdb72015-11-11 10:18:16 -08001547FX_BOOL CJS_PublicMethods::AFSpecial_Keystroke(
1548 IJS_Context* cc,
1549 const std::vector<CJS_Value>& params,
1550 CJS_Value& vRet,
1551 CFX_WideString& sError) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001552 CJS_Context* pContext = (CJS_Context*)cc;
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001553 if (params.size() != 1) {
1554 sError = JSGetStringFromID(pContext, IDS_STRING_JSPARAMERROR);
1555 return FALSE;
1556 }
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07001557
Tom Sepez67fd5df2015-10-08 12:24:19 -07001558 CJS_EventHandler* pEvent = pContext->GetEventHandler();
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001559 if (!pEvent->m_pValue)
1560 return FALSE;
Tom Sepez67fd5df2015-10-08 12:24:19 -07001561
1562 std::string cFormat;
1563 int iIndex = params[0].ToInt();
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001564 CFX_WideString& val = pEvent->Value();
1565 std::string strSrc = CFX_ByteString::FromUnicode(val).c_str();
1566 std::wstring wstrChange = pEvent->Change().c_str();
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07001567
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001568 switch (iIndex) {
Tom Sepez2f2ffec2015-07-23 14:42:09 -07001569 case 0:
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001570 cFormat = "99999";
1571 break;
Tom Sepez2f2ffec2015-07-23 14:42:09 -07001572 case 1:
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001573 cFormat = "999999999";
1574 break;
tsepez4f1f41f2016-03-28 14:13:16 -07001575 case 2:
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001576 if (strSrc.length() + wstrChange.length() > 7)
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001577 cFormat = "9999999999";
1578 else
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001579 cFormat = "9999999";
1580 break;
Tom Sepez2f2ffec2015-07-23 14:42:09 -07001581 case 3:
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001582 cFormat = "999999999";
1583 break;
1584 }
Lei Zhanga6d9f0e2015-06-13 00:48:38 -07001585
Lei Zhang945fdb72015-11-11 10:18:16 -08001586 std::vector<CJS_Value> params2;
Tom Sepez67fd5df2015-10-08 12:24:19 -07001587 params2.push_back(CJS_Value(CJS_Runtime::FromContext(cc), cFormat.c_str()));
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001588 return AFSpecial_KeystrokeEx(cc, params2, vRet, sError);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07001589}
1590
Tom Sepezba038bc2015-10-08 12:03:00 -07001591FX_BOOL CJS_PublicMethods::AFMergeChange(IJS_Context* cc,
Lei Zhang945fdb72015-11-11 10:18:16 -08001592 const std::vector<CJS_Value>& params,
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001593 CJS_Value& vRet,
1594 CFX_WideString& sError) {
1595 CJS_Context* pContext = (CJS_Context*)cc;
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001596 CJS_EventHandler* pEventHandler = pContext->GetEventHandler();
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07001597
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001598 if (params.size() != 1) {
1599 sError = JSGetStringFromID(pContext, IDS_STRING_JSPARAMERROR);
1600 return FALSE;
1601 }
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07001602
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001603 CFX_WideString swValue;
Lei Zhang997de612015-11-04 18:17:53 -08001604 if (pEventHandler->m_pValue)
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001605 swValue = pEventHandler->Value();
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07001606
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001607 if (pEventHandler->WillCommit()) {
1608 vRet = swValue.c_str();
Tom Sepez2f2ffec2015-07-23 14:42:09 -07001609 return TRUE;
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001610 }
1611
1612 CFX_WideString prefix, postfix;
1613
1614 if (pEventHandler->SelStart() >= 0)
1615 prefix = swValue.Mid(0, pEventHandler->SelStart());
1616 else
1617 prefix = L"";
1618
1619 if (pEventHandler->SelEnd() >= 0 &&
1620 pEventHandler->SelEnd() <= swValue.GetLength())
1621 postfix = swValue.Mid(pEventHandler->SelEnd(),
1622 swValue.GetLength() - pEventHandler->SelEnd());
1623 else
1624 postfix = L"";
1625
1626 vRet = (prefix + pEventHandler->Change() + postfix).c_str();
1627
1628 return TRUE;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07001629}
1630
Tom Sepezba038bc2015-10-08 12:03:00 -07001631FX_BOOL CJS_PublicMethods::AFParseDateEx(IJS_Context* cc,
Lei Zhang945fdb72015-11-11 10:18:16 -08001632 const std::vector<CJS_Value>& params,
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001633 CJS_Value& vRet,
1634 CFX_WideString& sError) {
1635 CJS_Context* pContext = (CJS_Context*)cc;
Lei Zhang96660d62015-12-14 18:27:25 -08001636 ASSERT(pContext);
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001637
1638 if (params.size() != 2) {
1639 sError = JSGetStringFromID(pContext, IDS_STRING_JSPARAMERROR);
1640 return FALSE;
1641 }
1642
1643 CFX_WideString sValue = params[0].ToCFXWideString();
1644 CFX_WideString sFormat = params[1].ToCFXWideString();
1645
Lei Zhang9559b7a2015-12-21 11:12:20 -08001646 double dDate = MakeRegularDate(sValue, sFormat, nullptr);
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001647
1648 if (JS_PortIsNan(dDate)) {
1649 CFX_WideString swMsg;
1650 swMsg.Format(JSGetStringFromID(pContext, IDS_STRING_JSPARSEDATE).c_str(),
1651 sFormat.c_str());
1652 Alert((CJS_Context*)cc, swMsg.c_str());
1653 return FALSE;
1654 }
1655
1656 vRet = dDate;
1657 return TRUE;
1658}
1659
Tom Sepezba038bc2015-10-08 12:03:00 -07001660FX_BOOL CJS_PublicMethods::AFSimple(IJS_Context* cc,
Lei Zhang945fdb72015-11-11 10:18:16 -08001661 const std::vector<CJS_Value>& params,
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001662 CJS_Value& vRet,
1663 CFX_WideString& sError) {
1664 if (params.size() != 3) {
1665 CJS_Context* pContext = (CJS_Context*)cc;
Lei Zhang96660d62015-12-14 18:27:25 -08001666 ASSERT(pContext);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07001667
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001668 sError = JSGetStringFromID(pContext, IDS_STRING_JSPARAMERROR);
1669 return FALSE;
1670 }
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07001671
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001672 vRet = (double)AF_Simple(params[0].ToCFXWideString().c_str(),
1673 params[1].ToDouble(), params[2].ToDouble());
1674 return TRUE;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07001675}
1676
Tom Sepezba038bc2015-10-08 12:03:00 -07001677FX_BOOL CJS_PublicMethods::AFMakeNumber(IJS_Context* cc,
Lei Zhang945fdb72015-11-11 10:18:16 -08001678 const std::vector<CJS_Value>& params,
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001679 CJS_Value& vRet,
1680 CFX_WideString& sError) {
Tom Sepez4246b002016-01-20 11:48:29 -08001681 CJS_Context* pContext = (CJS_Context*)cc;
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001682 if (params.size() != 1) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001683 sError = JSGetStringFromID(pContext, IDS_STRING_JSPARAMERROR);
1684 return FALSE;
1685 }
Tom Sepez4246b002016-01-20 11:48:29 -08001686 CFX_WideString ws = params[0].ToCFXWideString();
1687 ws.Replace(L",", L".");
1688 vRet = ws;
1689 vRet.MaybeCoerceToNumber();
1690 if (vRet.GetType() != CJS_Value::VT_number)
1691 vRet = 0;
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001692 return TRUE;
1693}
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07001694
Lei Zhang945fdb72015-11-11 10:18:16 -08001695FX_BOOL CJS_PublicMethods::AFSimple_Calculate(
1696 IJS_Context* cc,
1697 const std::vector<CJS_Value>& params,
1698 CJS_Value& vRet,
1699 CFX_WideString& sError) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001700 CJS_Context* pContext = (CJS_Context*)cc;
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001701 if (params.size() != 2) {
1702 sError = JSGetStringFromID(pContext, IDS_STRING_JSPARAMERROR);
1703 return FALSE;
1704 }
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07001705
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001706 CJS_Value params1 = params[1];
Tom Sepez39bfe122015-09-17 15:25:23 -07001707 if (!params1.IsArrayObject() && params1.GetType() != CJS_Value::VT_string) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001708 sError = JSGetStringFromID(pContext, IDS_STRING_JSPARAMERROR);
1709 return FALSE;
1710 }
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07001711
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001712 CPDFSDK_Document* pReaderDoc = pContext->GetReaderDocument();
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001713 CPDFSDK_InterForm* pReaderInterForm = pReaderDoc->GetInterForm();
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001714 CPDF_InterForm* pInterForm = pReaderInterForm->GetInterForm();
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07001715
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001716 CFX_WideString sFunction = params[0].ToCFXWideString();
Tom Sepez67fd5df2015-10-08 12:24:19 -07001717 double dValue = wcscmp(sFunction.c_str(), L"PRD") == 0 ? 1.0 : 0.0;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07001718
Tom Sepez67fd5df2015-10-08 12:24:19 -07001719 CJS_Runtime* pRuntime = CJS_Runtime::FromContext(cc);
1720 CJS_Array FieldNameArray = AF_MakeArrayFromList(pRuntime, params1);
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001721 int nFieldsCount = 0;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07001722
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001723 for (int i = 0, isz = FieldNameArray.GetLength(); i < isz; i++) {
Tom Sepez67fd5df2015-10-08 12:24:19 -07001724 CJS_Value jsValue(pRuntime);
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001725 FieldNameArray.GetElement(i, jsValue);
1726 CFX_WideString wsFieldName = jsValue.ToCFXWideString();
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07001727
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001728 for (int j = 0, jsz = pInterForm->CountFields(wsFieldName); j < jsz; j++) {
1729 if (CPDF_FormField* pFormField = pInterForm->GetField(j, wsFieldName)) {
1730 double dTemp = 0.0;
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001731 switch (pFormField->GetFieldType()) {
1732 case FIELDTYPE_TEXTFIELD:
1733 case FIELDTYPE_COMBOBOX: {
Tom Sepez4246b002016-01-20 11:48:29 -08001734 CFX_WideString trimmed = pFormField->GetValue();
1735 trimmed.TrimRight();
1736 trimmed.TrimLeft();
1737 dTemp = FX_atof(trimmed);
1738 } break;
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001739 case FIELDTYPE_PUSHBUTTON: {
1740 dTemp = 0.0;
Tom Sepez4246b002016-01-20 11:48:29 -08001741 } break;
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001742 case FIELDTYPE_CHECKBOX:
1743 case FIELDTYPE_RADIOBUTTON: {
1744 dTemp = 0.0;
1745 for (int c = 0, csz = pFormField->CountControls(); c < csz; c++) {
1746 if (CPDF_FormControl* pFormCtrl = pFormField->GetControl(c)) {
1747 if (pFormCtrl->IsChecked()) {
Tom Sepez4246b002016-01-20 11:48:29 -08001748 CFX_WideString trimmed = pFormCtrl->GetExportValue();
1749 trimmed.TrimRight();
1750 trimmed.TrimLeft();
1751 dTemp = FX_atof(trimmed);
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001752 break;
Lei Zhang9559b7a2015-12-21 11:12:20 -08001753 }
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001754 }
Tom Sepez2f2ffec2015-07-23 14:42:09 -07001755 }
Tom Sepez4246b002016-01-20 11:48:29 -08001756 } break;
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001757 case FIELDTYPE_LISTBOX: {
Tom Sepez4246b002016-01-20 11:48:29 -08001758 if (pFormField->CountSelectedItems() <= 1) {
1759 CFX_WideString trimmed = pFormField->GetValue();
1760 trimmed.TrimRight();
1761 trimmed.TrimLeft();
1762 dTemp = FX_atof(trimmed);
1763 }
1764 } break;
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001765 default:
1766 break;
Tom Sepez2f2ffec2015-07-23 14:42:09 -07001767 }
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001768
1769 if (i == 0 && j == 0 && (wcscmp(sFunction.c_str(), L"MIN") == 0 ||
1770 wcscmp(sFunction.c_str(), L"MAX") == 0))
1771 dValue = dTemp;
1772
1773 dValue = AF_Simple(sFunction.c_str(), dValue, dTemp);
1774
1775 nFieldsCount++;
1776 }
Tom Sepez2f2ffec2015-07-23 14:42:09 -07001777 }
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001778 }
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07001779
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001780 if (wcscmp(sFunction.c_str(), L"AVG") == 0 && nFieldsCount > 0)
1781 dValue /= nFieldsCount;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07001782
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001783 dValue = (double)floor(dValue * FXSYS_pow((double)10, (double)6) + 0.49) /
1784 FXSYS_pow((double)10, (double)6);
Tom Sepez67fd5df2015-10-08 12:24:19 -07001785 CJS_Value jsValue(pRuntime, dValue);
foxit8b544ed2015-09-10 14:57:54 +08001786 if (pContext->GetEventHandler()->m_pValue)
1787 pContext->GetEventHandler()->Value() = jsValue.ToCFXWideString();
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07001788
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001789 return TRUE;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07001790}
1791
Lei Zhanga6d9f0e2015-06-13 00:48:38 -07001792/* This function validates the current event to ensure that its value is
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07001793** within the specified range. */
1794
Lei Zhang945fdb72015-11-11 10:18:16 -08001795FX_BOOL CJS_PublicMethods::AFRange_Validate(
1796 IJS_Context* cc,
1797 const std::vector<CJS_Value>& params,
1798 CJS_Value& vRet,
1799 CFX_WideString& sError) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001800 CJS_Context* pContext = (CJS_Context*)cc;
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001801 CJS_EventHandler* pEvent = pContext->GetEventHandler();
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07001802
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001803 if (params.size() != 4) {
1804 sError = JSGetStringFromID(pContext, IDS_STRING_JSPARAMERROR);
1805 return FALSE;
1806 }
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07001807
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001808 if (!pEvent->m_pValue)
1809 return FALSE;
1810 if (pEvent->Value().IsEmpty())
Tom Sepez2f2ffec2015-07-23 14:42:09 -07001811 return TRUE;
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001812 double dEentValue = atof(CFX_ByteString::FromUnicode(pEvent->Value()));
1813 FX_BOOL bGreaterThan = params[0].ToBool();
1814 double dGreaterThan = params[1].ToDouble();
1815 FX_BOOL bLessThan = params[2].ToBool();
1816 double dLessThan = params[3].ToDouble();
1817 CFX_WideString swMsg;
1818
1819 if (bGreaterThan && bLessThan) {
1820 if (dEentValue < dGreaterThan || dEentValue > dLessThan)
1821 swMsg.Format(JSGetStringFromID(pContext, IDS_STRING_JSRANGE1).c_str(),
1822 params[1].ToCFXWideString().c_str(),
1823 params[3].ToCFXWideString().c_str());
1824 } else if (bGreaterThan) {
1825 if (dEentValue < dGreaterThan)
1826 swMsg.Format(JSGetStringFromID(pContext, IDS_STRING_JSRANGE2).c_str(),
1827 params[1].ToCFXWideString().c_str());
1828 } else if (bLessThan) {
1829 if (dEentValue > dLessThan)
1830 swMsg.Format(JSGetStringFromID(pContext, IDS_STRING_JSRANGE3).c_str(),
1831 params[3].ToCFXWideString().c_str());
1832 }
1833
1834 if (!swMsg.IsEmpty()) {
1835 Alert(pContext, swMsg.c_str());
1836 pEvent->Rc() = FALSE;
1837 }
1838 return TRUE;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07001839}
1840
Tom Sepezba038bc2015-10-08 12:03:00 -07001841FX_BOOL CJS_PublicMethods::AFExtractNums(IJS_Context* cc,
Lei Zhang945fdb72015-11-11 10:18:16 -08001842 const std::vector<CJS_Value>& params,
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001843 CJS_Value& vRet,
1844 CFX_WideString& sError) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001845 CJS_Context* pContext = (CJS_Context*)cc;
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001846 if (params.size() != 1) {
1847 sError = JSGetStringFromID(pContext, IDS_STRING_JSPARAMERROR);
1848 return FALSE;
1849 }
1850
Tom Sepez67fd5df2015-10-08 12:24:19 -07001851 CJS_Runtime* pRuntime = CJS_Runtime::FromContext(cc);
1852 CJS_Array nums(pRuntime);
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001853
1854 CFX_WideString str = params[0].ToCFXWideString();
1855 CFX_WideString sPart;
1856
1857 if (str.GetAt(0) == L'.' || str.GetAt(0) == L',')
1858 str = L"0" + str;
1859
1860 int nIndex = 0;
1861 for (int i = 0, sz = str.GetLength(); i < sz; i++) {
1862 FX_WCHAR wc = str.GetAt(i);
Lei Zhang9559b7a2015-12-21 11:12:20 -08001863 if (FXSYS_iswdigit(wc)) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001864 sPart += wc;
1865 } else {
1866 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 sPart = L"";
1869 nIndex++;
1870 }
Tom Sepez2f2ffec2015-07-23 14:42:09 -07001871 }
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001872 }
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07001873
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001874 if (sPart.GetLength() > 0) {
Tom Sepez67fd5df2015-10-08 12:24:19 -07001875 nums.SetElement(nIndex, CJS_Value(pRuntime, sPart.c_str()));
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001876 }
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07001877
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001878 if (nums.GetLength() > 0)
1879 vRet = nums;
1880 else
1881 vRet.SetNull();
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07001882
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001883 return TRUE;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07001884}