blob: 60973694302600340d7ca0ec013916b896ac5a62 [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 Sinclair10cfea12015-11-16 13:09:00 -050013#include "core/include/fxcrt/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
1427 std::string cFormat;
1428 int iIndex = params[0].ToInt();
1429
1430 CJS_EventHandler* pEvent = pContext->GetEventHandler();
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001431 if (!pEvent->m_pValue)
1432 return FALSE;
1433 CFX_WideString& Value = pEvent->Value();
1434 std::string strSrc = CFX_ByteString::FromUnicode(Value).c_str();
1435
1436 switch (iIndex) {
Tom Sepez2f2ffec2015-07-23 14:42:09 -07001437 case 0:
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001438 cFormat = "99999";
1439 break;
Tom Sepez2f2ffec2015-07-23 14:42:09 -07001440 case 1:
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001441 cFormat = "99999-9999";
1442 break;
1443 case 2: {
1444 std::string NumberStr;
1445 util::printx("9999999999", strSrc, NumberStr);
1446 if (NumberStr.length() >= 10)
1447 cFormat = "(999) 999-9999";
1448 else
1449 cFormat = "999-9999";
1450 break;
1451 }
Tom Sepez2f2ffec2015-07-23 14:42:09 -07001452 case 3:
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001453 cFormat = "999-99-9999";
1454 break;
1455 }
1456
1457 std::string strDes;
1458 util::printx(cFormat, strSrc, strDes);
1459 Value = CFX_WideString::FromLocal(strDes.c_str());
1460 return TRUE;
1461}
1462
1463// function AFSpecial_KeystrokeEx(mask)
Lei Zhang945fdb72015-11-11 10:18:16 -08001464FX_BOOL CJS_PublicMethods::AFSpecial_KeystrokeEx(
1465 IJS_Context* cc,
1466 const std::vector<CJS_Value>& params,
1467 CJS_Value& vRet,
1468 CFX_WideString& sError) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001469 CJS_Context* pContext = (CJS_Context*)cc;
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001470 CJS_EventHandler* pEvent = pContext->GetEventHandler();
1471
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001472 if (params.size() < 1) {
1473 sError = JSGetStringFromID(pContext, IDS_STRING_JSPARAMERROR);
1474 return FALSE;
1475 }
1476
1477 if (!pEvent->m_pValue)
1478 return FALSE;
1479 CFX_WideString& valEvent = pEvent->Value();
1480
1481 CFX_WideString wstrMask = params[0].ToCFXWideString();
1482 if (wstrMask.IsEmpty())
1483 return TRUE;
1484
Lei Zhanga0f67242015-08-17 15:39:30 -07001485 const size_t wstrMaskLen = wstrMask.GetLength();
1486 const std::wstring wstrValue = valEvent.c_str();
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001487
1488 if (pEvent->WillCommit()) {
1489 if (wstrValue.empty())
1490 return TRUE;
Lei Zhanga0f67242015-08-17 15:39:30 -07001491 size_t iIndexMask = 0;
1492 for (const auto& w_Value : wstrValue) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001493 if (!maskSatisfied(w_Value, wstrMask[iIndexMask]))
Tom Sepez2f2ffec2015-07-23 14:42:09 -07001494 break;
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001495 iIndexMask++;
Tom Sepez2f2ffec2015-07-23 14:42:09 -07001496 }
Lei Zhanga6d9f0e2015-06-13 00:48:38 -07001497
Lei Zhanga0f67242015-08-17 15:39:30 -07001498 if (iIndexMask != wstrMaskLen ||
1499 (iIndexMask != wstrValue.size() && wstrMaskLen != 0)) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001500 Alert(
1501 pContext,
1502 JSGetStringFromID(pContext, IDS_STRING_JSAFNUMBER_KEYSTROKE).c_str());
1503 pEvent->Rc() = FALSE;
1504 }
Tom Sepez2f2ffec2015-07-23 14:42:09 -07001505 return TRUE;
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001506 }
1507
1508 CFX_WideString& wideChange = pEvent->Change();
1509 std::wstring wChange = wideChange.c_str();
1510 if (wChange.empty())
1511 return TRUE;
1512
1513 int iIndexMask = pEvent->SelStart();
1514
Lei Zhanga0f67242015-08-17 15:39:30 -07001515 size_t combined_len = wstrValue.length() + wChange.length() -
1516 (pEvent->SelEnd() - pEvent->SelStart());
1517 if (combined_len > wstrMaskLen) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001518 Alert(pContext,
1519 JSGetStringFromID(pContext, IDS_STRING_JSPARAM_TOOLONG).c_str());
1520 pEvent->Rc() = FALSE;
1521 return TRUE;
1522 }
1523
Lei Zhanga0f67242015-08-17 15:39:30 -07001524 if (iIndexMask >= wstrMaskLen && (!wChange.empty())) {
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
1531 for (std::wstring::iterator it = wChange.begin(); it != wChange.end(); it++) {
Lei Zhanga0f67242015-08-17 15:39:30 -07001532 if (iIndexMask >= wstrMaskLen) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001533 Alert(pContext,
1534 JSGetStringFromID(pContext, IDS_STRING_JSPARAM_TOOLONG).c_str());
1535 pEvent->Rc() = FALSE;
1536 return TRUE;
1537 }
1538 wchar_t w_Mask = wstrMask[iIndexMask];
1539 if (!isReservedMaskChar(w_Mask)) {
1540 *it = w_Mask;
1541 }
1542 wchar_t w_Change = *it;
1543 if (!maskSatisfied(w_Change, w_Mask)) {
1544 pEvent->Rc() = FALSE;
1545 return TRUE;
1546 }
1547 iIndexMask++;
1548 }
1549
1550 wideChange = wChange.c_str();
1551 return TRUE;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07001552}
1553
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001554// function AFSpecial_Keystroke(psf)
Lei Zhang945fdb72015-11-11 10:18:16 -08001555FX_BOOL CJS_PublicMethods::AFSpecial_Keystroke(
1556 IJS_Context* cc,
1557 const std::vector<CJS_Value>& params,
1558 CJS_Value& vRet,
1559 CFX_WideString& sError) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001560 CJS_Context* pContext = (CJS_Context*)cc;
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001561 if (params.size() != 1) {
1562 sError = JSGetStringFromID(pContext, IDS_STRING_JSPARAMERROR);
1563 return FALSE;
1564 }
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07001565
Tom Sepez67fd5df2015-10-08 12:24:19 -07001566 CJS_EventHandler* pEvent = pContext->GetEventHandler();
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001567 if (!pEvent->m_pValue)
1568 return FALSE;
Tom Sepez67fd5df2015-10-08 12:24:19 -07001569
1570 std::string cFormat;
1571 int iIndex = params[0].ToInt();
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001572 CFX_WideString& val = pEvent->Value();
1573 std::string strSrc = CFX_ByteString::FromUnicode(val).c_str();
1574 std::wstring wstrChange = pEvent->Change().c_str();
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07001575
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001576 switch (iIndex) {
Tom Sepez2f2ffec2015-07-23 14:42:09 -07001577 case 0:
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001578 cFormat = "99999";
1579 break;
Tom Sepez2f2ffec2015-07-23 14:42:09 -07001580 case 1:
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001581 // cFormat = "99999-9999";
1582 cFormat = "999999999";
1583 break;
1584 case 2: {
1585 std::string NumberStr;
1586 util::printx("9999999999", strSrc, NumberStr);
1587 if (strSrc.length() + wstrChange.length() > 7)
1588 // cFormat = "(999) 999-9999";
1589 cFormat = "9999999999";
1590 else
1591 // cFormat = "999-9999";
1592 cFormat = "9999999";
1593 break;
1594 }
Tom Sepez2f2ffec2015-07-23 14:42:09 -07001595 case 3:
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001596 // cFormat = "999-99-9999";
1597 cFormat = "999999999";
1598 break;
1599 }
Lei Zhanga6d9f0e2015-06-13 00:48:38 -07001600
Lei Zhang945fdb72015-11-11 10:18:16 -08001601 std::vector<CJS_Value> params2;
Tom Sepez67fd5df2015-10-08 12:24:19 -07001602 params2.push_back(CJS_Value(CJS_Runtime::FromContext(cc), cFormat.c_str()));
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001603 return AFSpecial_KeystrokeEx(cc, params2, vRet, sError);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07001604}
1605
Tom Sepezba038bc2015-10-08 12:03:00 -07001606FX_BOOL CJS_PublicMethods::AFMergeChange(IJS_Context* cc,
Lei Zhang945fdb72015-11-11 10:18:16 -08001607 const std::vector<CJS_Value>& params,
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001608 CJS_Value& vRet,
1609 CFX_WideString& sError) {
1610 CJS_Context* pContext = (CJS_Context*)cc;
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001611 CJS_EventHandler* pEventHandler = pContext->GetEventHandler();
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07001612
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001613 if (params.size() != 1) {
1614 sError = JSGetStringFromID(pContext, IDS_STRING_JSPARAMERROR);
1615 return FALSE;
1616 }
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07001617
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001618 CFX_WideString swValue;
Lei Zhang997de612015-11-04 18:17:53 -08001619 if (pEventHandler->m_pValue)
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001620 swValue = pEventHandler->Value();
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07001621
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001622 if (pEventHandler->WillCommit()) {
1623 vRet = swValue.c_str();
Tom Sepez2f2ffec2015-07-23 14:42:09 -07001624 return TRUE;
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001625 }
1626
1627 CFX_WideString prefix, postfix;
1628
1629 if (pEventHandler->SelStart() >= 0)
1630 prefix = swValue.Mid(0, pEventHandler->SelStart());
1631 else
1632 prefix = L"";
1633
1634 if (pEventHandler->SelEnd() >= 0 &&
1635 pEventHandler->SelEnd() <= swValue.GetLength())
1636 postfix = swValue.Mid(pEventHandler->SelEnd(),
1637 swValue.GetLength() - pEventHandler->SelEnd());
1638 else
1639 postfix = L"";
1640
1641 vRet = (prefix + pEventHandler->Change() + postfix).c_str();
1642
1643 return TRUE;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07001644}
1645
Tom Sepezba038bc2015-10-08 12:03:00 -07001646FX_BOOL CJS_PublicMethods::AFParseDateEx(IJS_Context* cc,
Lei Zhang945fdb72015-11-11 10:18:16 -08001647 const std::vector<CJS_Value>& params,
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001648 CJS_Value& vRet,
1649 CFX_WideString& sError) {
1650 CJS_Context* pContext = (CJS_Context*)cc;
Lei Zhang96660d62015-12-14 18:27:25 -08001651 ASSERT(pContext);
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001652
1653 if (params.size() != 2) {
1654 sError = JSGetStringFromID(pContext, IDS_STRING_JSPARAMERROR);
1655 return FALSE;
1656 }
1657
1658 CFX_WideString sValue = params[0].ToCFXWideString();
1659 CFX_WideString sFormat = params[1].ToCFXWideString();
1660
Lei Zhang9559b7a2015-12-21 11:12:20 -08001661 double dDate = MakeRegularDate(sValue, sFormat, nullptr);
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001662
1663 if (JS_PortIsNan(dDate)) {
1664 CFX_WideString swMsg;
1665 swMsg.Format(JSGetStringFromID(pContext, IDS_STRING_JSPARSEDATE).c_str(),
1666 sFormat.c_str());
1667 Alert((CJS_Context*)cc, swMsg.c_str());
1668 return FALSE;
1669 }
1670
1671 vRet = dDate;
1672 return TRUE;
1673}
1674
Tom Sepezba038bc2015-10-08 12:03:00 -07001675FX_BOOL CJS_PublicMethods::AFSimple(IJS_Context* cc,
Lei Zhang945fdb72015-11-11 10:18:16 -08001676 const std::vector<CJS_Value>& params,
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001677 CJS_Value& vRet,
1678 CFX_WideString& sError) {
1679 if (params.size() != 3) {
1680 CJS_Context* pContext = (CJS_Context*)cc;
Lei Zhang96660d62015-12-14 18:27:25 -08001681 ASSERT(pContext);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07001682
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001683 sError = JSGetStringFromID(pContext, IDS_STRING_JSPARAMERROR);
1684 return FALSE;
1685 }
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07001686
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001687 vRet = (double)AF_Simple(params[0].ToCFXWideString().c_str(),
1688 params[1].ToDouble(), params[2].ToDouble());
1689 return TRUE;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07001690}
1691
Tom Sepezba038bc2015-10-08 12:03:00 -07001692FX_BOOL CJS_PublicMethods::AFMakeNumber(IJS_Context* cc,
Lei Zhang945fdb72015-11-11 10:18:16 -08001693 const std::vector<CJS_Value>& params,
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001694 CJS_Value& vRet,
1695 CFX_WideString& sError) {
Tom Sepez4246b002016-01-20 11:48:29 -08001696 CJS_Context* pContext = (CJS_Context*)cc;
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001697 if (params.size() != 1) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001698 sError = JSGetStringFromID(pContext, IDS_STRING_JSPARAMERROR);
1699 return FALSE;
1700 }
Tom Sepez4246b002016-01-20 11:48:29 -08001701 CFX_WideString ws = params[0].ToCFXWideString();
1702 ws.Replace(L",", L".");
1703 vRet = ws;
1704 vRet.MaybeCoerceToNumber();
1705 if (vRet.GetType() != CJS_Value::VT_number)
1706 vRet = 0;
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001707 return TRUE;
1708}
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07001709
Lei Zhang945fdb72015-11-11 10:18:16 -08001710FX_BOOL CJS_PublicMethods::AFSimple_Calculate(
1711 IJS_Context* cc,
1712 const std::vector<CJS_Value>& params,
1713 CJS_Value& vRet,
1714 CFX_WideString& sError) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001715 CJS_Context* pContext = (CJS_Context*)cc;
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001716 if (params.size() != 2) {
1717 sError = JSGetStringFromID(pContext, IDS_STRING_JSPARAMERROR);
1718 return FALSE;
1719 }
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07001720
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001721 CJS_Value params1 = params[1];
Tom Sepez39bfe122015-09-17 15:25:23 -07001722 if (!params1.IsArrayObject() && params1.GetType() != CJS_Value::VT_string) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001723 sError = JSGetStringFromID(pContext, IDS_STRING_JSPARAMERROR);
1724 return FALSE;
1725 }
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07001726
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001727 CPDFSDK_Document* pReaderDoc = pContext->GetReaderDocument();
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001728 CPDFSDK_InterForm* pReaderInterForm = pReaderDoc->GetInterForm();
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001729 CPDF_InterForm* pInterForm = pReaderInterForm->GetInterForm();
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07001730
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001731 CFX_WideString sFunction = params[0].ToCFXWideString();
Tom Sepez67fd5df2015-10-08 12:24:19 -07001732 double dValue = wcscmp(sFunction.c_str(), L"PRD") == 0 ? 1.0 : 0.0;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07001733
Tom Sepez67fd5df2015-10-08 12:24:19 -07001734 CJS_Runtime* pRuntime = CJS_Runtime::FromContext(cc);
1735 CJS_Array FieldNameArray = AF_MakeArrayFromList(pRuntime, params1);
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001736 int nFieldsCount = 0;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07001737
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001738 for (int i = 0, isz = FieldNameArray.GetLength(); i < isz; i++) {
Tom Sepez67fd5df2015-10-08 12:24:19 -07001739 CJS_Value jsValue(pRuntime);
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001740 FieldNameArray.GetElement(i, jsValue);
1741 CFX_WideString wsFieldName = jsValue.ToCFXWideString();
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07001742
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001743 for (int j = 0, jsz = pInterForm->CountFields(wsFieldName); j < jsz; j++) {
1744 if (CPDF_FormField* pFormField = pInterForm->GetField(j, wsFieldName)) {
1745 double dTemp = 0.0;
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001746 switch (pFormField->GetFieldType()) {
1747 case FIELDTYPE_TEXTFIELD:
1748 case FIELDTYPE_COMBOBOX: {
Tom Sepez4246b002016-01-20 11:48:29 -08001749 CFX_WideString trimmed = pFormField->GetValue();
1750 trimmed.TrimRight();
1751 trimmed.TrimLeft();
1752 dTemp = FX_atof(trimmed);
1753 } break;
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001754 case FIELDTYPE_PUSHBUTTON: {
1755 dTemp = 0.0;
Tom Sepez4246b002016-01-20 11:48:29 -08001756 } break;
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001757 case FIELDTYPE_CHECKBOX:
1758 case FIELDTYPE_RADIOBUTTON: {
1759 dTemp = 0.0;
1760 for (int c = 0, csz = pFormField->CountControls(); c < csz; c++) {
1761 if (CPDF_FormControl* pFormCtrl = pFormField->GetControl(c)) {
1762 if (pFormCtrl->IsChecked()) {
Tom Sepez4246b002016-01-20 11:48:29 -08001763 CFX_WideString trimmed = pFormCtrl->GetExportValue();
1764 trimmed.TrimRight();
1765 trimmed.TrimLeft();
1766 dTemp = FX_atof(trimmed);
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001767 break;
Lei Zhang9559b7a2015-12-21 11:12:20 -08001768 }
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001769 }
Tom Sepez2f2ffec2015-07-23 14:42:09 -07001770 }
Tom Sepez4246b002016-01-20 11:48:29 -08001771 } break;
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001772 case FIELDTYPE_LISTBOX: {
Tom Sepez4246b002016-01-20 11:48:29 -08001773 if (pFormField->CountSelectedItems() <= 1) {
1774 CFX_WideString trimmed = pFormField->GetValue();
1775 trimmed.TrimRight();
1776 trimmed.TrimLeft();
1777 dTemp = FX_atof(trimmed);
1778 }
1779 } break;
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001780 default:
1781 break;
Tom Sepez2f2ffec2015-07-23 14:42:09 -07001782 }
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001783
1784 if (i == 0 && j == 0 && (wcscmp(sFunction.c_str(), L"MIN") == 0 ||
1785 wcscmp(sFunction.c_str(), L"MAX") == 0))
1786 dValue = dTemp;
1787
1788 dValue = AF_Simple(sFunction.c_str(), dValue, dTemp);
1789
1790 nFieldsCount++;
1791 }
Tom Sepez2f2ffec2015-07-23 14:42:09 -07001792 }
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001793 }
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07001794
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001795 if (wcscmp(sFunction.c_str(), L"AVG") == 0 && nFieldsCount > 0)
1796 dValue /= nFieldsCount;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07001797
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001798 dValue = (double)floor(dValue * FXSYS_pow((double)10, (double)6) + 0.49) /
1799 FXSYS_pow((double)10, (double)6);
Tom Sepez67fd5df2015-10-08 12:24:19 -07001800 CJS_Value jsValue(pRuntime, dValue);
foxit8b544ed2015-09-10 14:57:54 +08001801 if (pContext->GetEventHandler()->m_pValue)
1802 pContext->GetEventHandler()->Value() = jsValue.ToCFXWideString();
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07001803
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001804 return TRUE;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07001805}
1806
Lei Zhanga6d9f0e2015-06-13 00:48:38 -07001807/* This function validates the current event to ensure that its value is
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07001808** within the specified range. */
1809
Lei Zhang945fdb72015-11-11 10:18:16 -08001810FX_BOOL CJS_PublicMethods::AFRange_Validate(
1811 IJS_Context* cc,
1812 const std::vector<CJS_Value>& params,
1813 CJS_Value& vRet,
1814 CFX_WideString& sError) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001815 CJS_Context* pContext = (CJS_Context*)cc;
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001816 CJS_EventHandler* pEvent = pContext->GetEventHandler();
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07001817
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001818 if (params.size() != 4) {
1819 sError = JSGetStringFromID(pContext, IDS_STRING_JSPARAMERROR);
1820 return FALSE;
1821 }
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07001822
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001823 if (!pEvent->m_pValue)
1824 return FALSE;
1825 if (pEvent->Value().IsEmpty())
Tom Sepez2f2ffec2015-07-23 14:42:09 -07001826 return TRUE;
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001827 double dEentValue = atof(CFX_ByteString::FromUnicode(pEvent->Value()));
1828 FX_BOOL bGreaterThan = params[0].ToBool();
1829 double dGreaterThan = params[1].ToDouble();
1830 FX_BOOL bLessThan = params[2].ToBool();
1831 double dLessThan = params[3].ToDouble();
1832 CFX_WideString swMsg;
1833
1834 if (bGreaterThan && bLessThan) {
1835 if (dEentValue < dGreaterThan || dEentValue > dLessThan)
1836 swMsg.Format(JSGetStringFromID(pContext, IDS_STRING_JSRANGE1).c_str(),
1837 params[1].ToCFXWideString().c_str(),
1838 params[3].ToCFXWideString().c_str());
1839 } else if (bGreaterThan) {
1840 if (dEentValue < dGreaterThan)
1841 swMsg.Format(JSGetStringFromID(pContext, IDS_STRING_JSRANGE2).c_str(),
1842 params[1].ToCFXWideString().c_str());
1843 } else if (bLessThan) {
1844 if (dEentValue > dLessThan)
1845 swMsg.Format(JSGetStringFromID(pContext, IDS_STRING_JSRANGE3).c_str(),
1846 params[3].ToCFXWideString().c_str());
1847 }
1848
1849 if (!swMsg.IsEmpty()) {
1850 Alert(pContext, swMsg.c_str());
1851 pEvent->Rc() = FALSE;
1852 }
1853 return TRUE;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07001854}
1855
Tom Sepezba038bc2015-10-08 12:03:00 -07001856FX_BOOL CJS_PublicMethods::AFExtractNums(IJS_Context* cc,
Lei Zhang945fdb72015-11-11 10:18:16 -08001857 const std::vector<CJS_Value>& params,
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001858 CJS_Value& vRet,
1859 CFX_WideString& sError) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001860 CJS_Context* pContext = (CJS_Context*)cc;
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001861 if (params.size() != 1) {
1862 sError = JSGetStringFromID(pContext, IDS_STRING_JSPARAMERROR);
1863 return FALSE;
1864 }
1865
Tom Sepez67fd5df2015-10-08 12:24:19 -07001866 CJS_Runtime* pRuntime = CJS_Runtime::FromContext(cc);
1867 CJS_Array nums(pRuntime);
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001868
1869 CFX_WideString str = params[0].ToCFXWideString();
1870 CFX_WideString sPart;
1871
1872 if (str.GetAt(0) == L'.' || str.GetAt(0) == L',')
1873 str = L"0" + str;
1874
1875 int nIndex = 0;
1876 for (int i = 0, sz = str.GetLength(); i < sz; i++) {
1877 FX_WCHAR wc = str.GetAt(i);
Lei Zhang9559b7a2015-12-21 11:12:20 -08001878 if (FXSYS_iswdigit(wc)) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001879 sPart += wc;
1880 } else {
1881 if (sPart.GetLength() > 0) {
Tom Sepez67fd5df2015-10-08 12:24:19 -07001882 nums.SetElement(nIndex, CJS_Value(pRuntime, sPart.c_str()));
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001883 sPart = L"";
1884 nIndex++;
1885 }
Tom Sepez2f2ffec2015-07-23 14:42:09 -07001886 }
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001887 }
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07001888
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001889 if (sPart.GetLength() > 0) {
Tom Sepez67fd5df2015-10-08 12:24:19 -07001890 nums.SetElement(nIndex, CJS_Value(pRuntime, sPart.c_str()));
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001891 }
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07001892
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001893 if (nums.GetLength() > 0)
1894 vRet = nums;
1895 else
1896 vRet.SetNull();
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07001897
Nico Weber9d8ec5a2015-08-04 13:00:21 -07001898 return TRUE;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07001899}