PageRenderTime 83ms CodeModel.GetById 17ms RepoModel.GetById 1ms app.codeStats 2ms

/js/yii/vendors/phpjs/php.js

http://github.com/phpnode/YiiJS
JavaScript | 7274 lines | 4178 code | 533 blank | 2563 comment | 1166 complexity | f435a70ee00a32b18ecea0911100c6b9 MD5 | raw file
  1. /*
  2. * More info at: http://phpjs.org
  3. *
  4. * This is version: 3.24
  5. * php.js is copyright 2011 Kevin van Zonneveld.
  6. *
  7. * Portions copyright Brett Zamir (http://brett-zamir.me), Kevin van Zonneveld
  8. * (http://kevin.vanzonneveld.net), Onno Marsman, Theriault, Michael White
  9. * (http://getsprink.com), Waldo Malqui Silva, Paulo Freitas, Jonas Raoni
  10. * Soares Silva (http://www.jsfromhell.com), Jack, Philip Peterson, Ates Goral
  11. * (http://magnetiq.com), Legaev Andrey, Ratheous, Alex, Martijn Wieringa,
  12. * Nate, lmeyrick (https://sourceforge.net/projects/bcmath-js/), Enrique
  13. * Gonzalez, Philippe Baumann, Rafał Kukawski (http://blog.kukawski.pl),
  14. * Webtoolkit.info (http://www.webtoolkit.info/), Ole Vrijenhoek, Ash Searle
  15. * (http://hexmen.com/blog/), travc, Carlos R. L. Rodrigues
  16. * (http://www.jsfromhell.com), Jani Hartikainen, stag019, GeekFG
  17. * (http://geekfg.blogspot.com), WebDevHobo (http://webdevhobo.blogspot.com/),
  18. * Erkekjetter, pilus, Rafał Kukawski (http://blog.kukawski.pl/), Johnny Mast
  19. * (http://www.phpvrouwen.nl), T.Wild,
  20. * http://stackoverflow.com/questions/57803/how-to-convert-decimal-to-hex-in-javascript,
  21. * d3x, Michael Grier, Andrea Giammarchi (http://webreflection.blogspot.com),
  22. * marrtins, Mailfaker (http://www.weedem.fr/), Steve Hilder, gettimeofday,
  23. * mdsjack (http://www.mdsjack.bo.it), felix, majak, Steven Levithan
  24. * (http://blog.stevenlevithan.com), Mirek Slugen, Oleg Eremeev, Felix
  25. * Geisendoerfer (http://www.debuggable.com/felix), Martin
  26. * (http://www.erlenwiese.de/), gorthaur, Lars Fischer, Joris, AJ, Paul Smith,
  27. * Tim de Koning (http://www.kingsquare.nl), KELAN, Josh Fraser
  28. * (http://onlineaspect.com/2007/06/08/auto-detect-a-time-zone-with-javascript/),
  29. * Chris, Marc Palau, Kevin van Zonneveld (http://kevin.vanzonneveld.net/),
  30. * Arpad Ray (mailto:arpad@php.net), Breaking Par Consulting Inc
  31. * (http://www.breakingpar.com/bkp/home.nsf/0/87256B280015193F87256CFB006C45F7),
  32. * Nathan, Karol Kowalski, David, Dreamer, Diplom@t (http://difane.com/), Caio
  33. * Ariede (http://caioariede.com), Robin, Imgen Tata (http://www.myipdf.com/),
  34. * Pellentesque Malesuada, saulius, Aman Gupta, Sakimori, Tyler Akins
  35. * (http://rumkin.com), Thunder.m, Public Domain
  36. * (http://www.json.org/json2.js), Michael White, Kankrelune
  37. * (http://www.webfaktory.info/), Alfonso Jimenez
  38. * (http://www.alfonsojimenez.com), Frank Forte, vlado houba, Marco, Billy,
  39. * David James, madipta, noname, sankai, class_exists, Jalal Berrami, ger,
  40. * Itsacon (http://www.itsacon.net/), Scott Cariss, nobbler, Arno, Denny
  41. * Wardhana, ReverseSyntax, Mateusz "loonquawl" Zalega, Slawomir Kaniecki,
  42. * Francois, Fox, mktime, Douglas Crockford (http://javascript.crockford.com),
  43. * john (http://www.jd-tech.net), Oskar Larsson Högfeldt
  44. * (http://oskar-lh.name/), marc andreu, Nick Kolosov (http://sammy.ru), date,
  45. * Marc Jansen, Steve Clay, Olivier Louvignes (http://mg-crea.com/), Soren
  46. * Hansen, merabi, Subhasis Deb, josh, T0bsn, Tim Wiel, Brad Touesnard, MeEtc
  47. * (http://yass.meetcweb.com), Peter-Paul Koch
  48. * (http://www.quirksmode.org/js/beat.html), Pyerre, Jon Hohle, duncan, Bayron
  49. * Guevara, Adam Wallner (http://web2.bitbaro.hu/), paulo kuong, Gilbert,
  50. * Lincoln Ramsay, Thiago Mata (http://thiagomata.blog.com), Linuxworld,
  51. * lmeyrick (https://sourceforge.net/projects/bcmath-js/this.), djmix, Bryan
  52. * Elliott, David Randall, Sanjoy Roy, jmweb, Francesco, Stoyan Kyosev
  53. * (http://www.svest.org/), J A R, kenneth, T. Wild, Ole Vrijenhoek
  54. * (http://www.nervous.nl/), Raphael (Ao RUDLER), Shingo, LH, JB, nord_ua, jd,
  55. * JT, Thomas Beaucourt (http://www.webapp.fr), Ozh, XoraX
  56. * (http://www.xorax.info), EdorFaus, Eugene Bulkin (http://doubleaw.com/),
  57. * Der Simon (http://innerdom.sourceforge.net/), 0m3r, echo is bad,
  58. * FremyCompany, stensi, Kristof Coomans (SCK-CEN Belgian Nucleair Research
  59. * Centre), Devan Penner-Woelk, Pierre-Luc Paour, Martin Pool, Brant Messenger
  60. * (http://www.brantmessenger.com/), Kirk Strobeck, Saulo Vallory, Christoph,
  61. * Wagner B. Soares, Artur Tchernychev, Valentina De Rosa, Jason Wong
  62. * (http://carrot.org/), Daniel Esteban, strftime, Rick Waldron, Mick@el,
  63. * Anton Ongson, Bjorn Roesbeke (http://www.bjornroesbeke.be/), Simon Willison
  64. * (http://simonwillison.net), Gabriel Paderni, Philipp Lenssen, Marco van
  65. * Oort, Bug?, Blues (http://tech.bluesmoon.info/), Tomasz Wesolowski, rezna,
  66. * Eric Nagel, Evertjan Garretsen, Luke Godfrey, Pul, Bobby Drake, uestla,
  67. * Alan C, Ulrich, Zahlii, Yves Sucaet, sowberry, Norman "zEh" Fuchs, hitwork,
  68. * johnrembo, Brian Tafoya (http://www.premasolutions.com/), Nick Callen,
  69. * Steven Levithan (stevenlevithan.com), ejsanders, Scott Baker, Philippe
  70. * Jausions (http://pear.php.net/user/jausions), Aidan Lister
  71. * (http://aidanlister.com/), Rob, e-mike, HKM, ChaosNo1, metjay, strcasecmp,
  72. * strcmp, Taras Bogach, jpfle, Alexander Ermolaev
  73. * (http://snippets.dzone.com/user/AlexanderErmolaev), DxGx, kilops, Orlando,
  74. * dptr1988, Le Torbi, James (http://www.james-bell.co.uk/), Pedro Tainha
  75. * (http://www.pedrotainha.com), James, penutbutterjelly, Arnout Kazemier
  76. * (http://www.3rd-Eden.com), 3D-GRAF, daniel airton wermann
  77. * (http://wermann.com.br), jakes, Yannoo, FGFEmperor, gabriel paderni, Atli
  78. * Þór, Maximusya, Diogo Resende, Rival, Howard Yeend, Allan Jensen
  79. * (http://www.winternet.no), davook, Benjamin Lupton, baris ozdil, Greg
  80. * Frazier, Manish, Matt Bradley, Cord, fearphage
  81. * (http://http/my.opera.com/fearphage/), Matteo, Victor, taith, Tim de
  82. * Koning, Ryan W Tenney (http://ryan.10e.us), Tod Gentille, Alexander M
  83. * Beedie, Riddler (http://www.frontierwebdev.com/), Luis Salazar
  84. * (http://www.freaky-media.com/), Rafał Kukawski, T.J. Leahy, Luke Smith
  85. * (http://lucassmith.name), Kheang Hok Chin (http://www.distantia.ca/),
  86. * Russell Walker (http://www.nbill.co.uk/), Jamie Beck
  87. * (http://www.terabit.ca/), Garagoth, Andrej Pavlovic, Dino, Le Torbi
  88. * (http://www.letorbi.de/), Ben (http://benblume.co.uk/), DtTvB
  89. * (http://dt.in.th/2008-09-16.string-length-in-bytes.html), Michael, Chris
  90. * McMacken, setcookie, YUI Library:
  91. * http://developer.yahoo.com/yui/docs/YAHOO.util.DateLocale.html, Andreas,
  92. * Blues at http://hacks.bluesmoon.info/strftime/strftime.js, rem, Josep Sanz
  93. * (http://www.ws3.es/), Cagri Ekin, Lorenzo Pisani, incidence, Amirouche, Jay
  94. * Klehr, Amir Habibi (http://www.residence-mixte.com/), Tony, booeyOH, meo,
  95. * William, Greenseed, Yen-Wei Liu, Ben Bryan, Leslie Hoare, mk.keck
  96. *
  97. * Dual licensed under the MIT (MIT-LICENSE.txt)
  98. * and GPL (GPL-LICENSE.txt) licenses.
  99. *
  100. * Permission is hereby granted, free of charge, to any person obtaining a
  101. * copy of this software and associated documentation files (the
  102. * "Software"), to deal in the Software without restriction, including
  103. * without limitation the rights to use, copy, modify, merge, publish,
  104. * distribute, sublicense, and/or sell copies of the Software, and to
  105. * permit persons to whom the Software is furnished to do so, subject to
  106. * the following conditions:
  107. *
  108. * The above copyright notice and this permission notice shall be included
  109. * in all copies or substantial portions of the Software.
  110. *
  111. * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
  112. * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
  113. * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
  114. * IN NO EVENT SHALL KEVIN VAN ZONNEVELD BE LIABLE FOR ANY CLAIM, DAMAGES
  115. * OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
  116. * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
  117. * OTHER DEALINGS IN THE SOFTWARE.
  118. */
  119. // jslint.com configuration options. See: http://wiki.github.com/kvz/phpjs/jslint-options
  120. /* global window */
  121. /* jslint adsafe: false, bitwise: false, browser: false, cap: false, css: false, debug: false, devel: false, eqeqeq: true, evil: false, forin: false, fragment: false, immed: true, indent: 4, laxbreak: false, maxerr: 100, maxlen: 80, newcap: true, nomen: false, on: true, onevar: false, passfail: false, plusplus: false, regexp: false, rhino: false, safe: false, sidebar: false, strict: false, sub: false, undef: true, white: false, widget: false */
  122. // Our idea with CommonJS is that you can do the following:
  123. // var php = require('php');
  124. // php.md5('test');
  125. var php = {};
  126. php.ini_set = function (varname, newvalue) {
  127. // http://kevin.vanzonneveld.net
  128. // + original by: Brett Zamir (http://brett-zamir.me)
  129. // % note 1: This will not set a global_value or access level for the ini item
  130. // * example 1: ini_set('date.timezone', 'America/Chicago');
  131. // * returns 1: 'Asia/Hong_Kong'
  132. var oldval = '',
  133. that = this;
  134. this.php_js = this.php_js || {};
  135. this.php_js.ini = this.php_js.ini || {};
  136. this.php_js.ini[varname] = this.php_js.ini[varname] || {};
  137. oldval = this.php_js.ini[varname].local_value;
  138. var _setArr = function (oldval) { // Although these are set individually, they are all accumulated
  139. if (typeof oldval === 'undefined') {
  140. that.php_js.ini[varname].local_value = [];
  141. }
  142. that.php_js.ini[varname].local_value.push(newvalue);
  143. };
  144. switch (varname) {
  145. case 'extension':
  146. if (typeof this.dl === 'function') {
  147. this.dl(newvalue); // This function is only experimental in php.js
  148. }
  149. _setArr(oldval, newvalue);
  150. break;
  151. default:
  152. this.php_js.ini[varname].local_value = newvalue;
  153. break;
  154. }
  155. return oldval;
  156. };
  157. php.ini_get = function (varname) {
  158. // http://kevin.vanzonneveld.net
  159. // + original by: Brett Zamir (http://brett-zamir.me)
  160. // % note 1: The ini values must be set by ini_set or manually within an ini file
  161. // * example 1: ini_get('date.timezone');
  162. // * returns 1: 'Asia/Hong_Kong'
  163. if (this.php_js && this.php_js.ini && this.php_js.ini[varname] && this.php_js.ini[varname].local_value !== undefined) {
  164. if (this.php_js.ini[varname].local_value === null) {
  165. return '';
  166. }
  167. return this.php_js.ini[varname].local_value;
  168. }
  169. return '';
  170. }
  171. php.ctype_digit = function (text) {
  172. // http://kevin.vanzonneveld.net
  173. // + original by: Brett Zamir (http://brett-zamir.me)
  174. // - depends on: setlocale
  175. // * example 1: ctype_digit('150');
  176. // * returns 1: true
  177. if (typeof text !== 'string') {
  178. return false;
  179. }
  180. // BEGIN REDUNDANT
  181. this.setlocale('LC_ALL', 0); // ensure setup of localization variables takes place
  182. // END REDUNDANT
  183. return text.search(this.php_js.locales[this.php_js.localeCategories.LC_CTYPE].LC_CTYPE.dg) !== -1;
  184. };
  185. php.gmmktime = function () {
  186. // http://kevin.vanzonneveld.net
  187. // + original by: Brett Zamir (http://brett-zamir.me)
  188. // + derived from: mktime
  189. // * example 1: gmmktime(14, 10, 2, 2, 1, 2008);
  190. // * returns 1: 1201875002
  191. // * example 2: gmmktime(0, 0, -1, 1, 1, 1970);
  192. // * returns 2: -1
  193. var d = new Date(),
  194. r = arguments,
  195. i = 0,
  196. e = ['Hours', 'Minutes', 'Seconds', 'Month', 'Date', 'FullYear'];
  197. for (i = 0; i < e.length; i++) {
  198. if (typeof r[i] === 'undefined') {
  199. r[i] = d['getUTC' + e[i]]();
  200. r[i] += (i === 3); // +1 to fix JS months.
  201. } else {
  202. r[i] = parseInt(r[i], 10);
  203. if (isNaN(r[i])) {
  204. return false;
  205. }
  206. }
  207. }
  208. // Map years 0-69 to 2000-2069 and years 70-100 to 1970-2000.
  209. r[5] += (r[5] >= 0 ? (r[5] <= 69 ? 2e3 : (r[5] <= 100 ? 1900 : 0)) : 0);
  210. // Set year, month (-1 to fix JS months), and date.
  211. // !This must come before the call to setHours!
  212. d.setUTCFullYear(r[5], r[3] - 1, r[4]);
  213. // Set hours, minutes, and seconds.
  214. d.setUTCHours(r[0], r[1], r[2]);
  215. // Divide milliseconds by 1000 to return seconds and drop decimal.
  216. // Add 1 second if negative or it'll be off from PHP by 1 second.
  217. return (d.getTime() / 1e3 >> 0) - (d.getTime() < 0);
  218. };
  219. php.getdate = function (timestamp) {
  220. // http://kevin.vanzonneveld.net
  221. // + original by: Paulo Freitas
  222. // + input by: Alex
  223. // + bugfixed by: Brett Zamir (http://brett-zamir.me)
  224. // * example 1: getdate(1055901520);
  225. // * returns 1: {'seconds': 40, 'minutes': 58, 'hours': 21, 'mday': 17, 'wday': 2, 'mon': 6, 'year': 2003, 'yday': 167, 'weekday': 'Tuesday', 'month': 'June', '0': 1055901520}
  226. var _w = ['Sun', 'Mon', 'Tues', 'Wednes', 'Thurs', 'Fri', 'Satur'];
  227. var _m = ['January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December'];
  228. var d = ((typeof(timestamp) == 'undefined') ? new Date() : // Not provided
  229. (typeof(timestamp) == 'object') ? new Date(timestamp) : // Javascript Date()
  230. new Date(timestamp * 1000) // UNIX timestamp (auto-convert to int)
  231. );
  232. var w = d.getDay();
  233. var m = d.getMonth();
  234. var y = d.getFullYear();
  235. var r = {};
  236. r.seconds = d.getSeconds();
  237. r.minutes = d.getMinutes();
  238. r.hours = d.getHours();
  239. r.mday = d.getDate();
  240. r.wday = w;
  241. r.mon = m + 1;
  242. r.year = y;
  243. r.yday = Math.floor((d - (new Date(y, 0, 1))) / 86400000);
  244. r.weekday = _w[w] + 'day';
  245. r.month = _m[m];
  246. r['0'] = parseInt(d.getTime() / 1000, 10);
  247. return r;
  248. };
  249. php.checkdate = function (m, d, y) {
  250. // Returns true(1) if it is a valid date in gregorian calendar
  251. //
  252. // version: 1103.1210
  253. // discuss at: http://phpjs.org/functions/checkdate
  254. // + original by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
  255. // + improved by: Pyerre
  256. // + improved by: Theriault
  257. // * example 1: checkdate(12, 31, 2000);
  258. // * returns 1: true
  259. // * example 2: checkdate(2, 29, 2001);
  260. // * returns 2: false
  261. // * example 3: checkdate(3, 31, 2008);
  262. // * returns 3: true
  263. // * example 4: checkdate(1, 390, 2000);
  264. // * returns 4: false
  265. return m > 0 && m < 13 && y > 0 && y < 32768 && d > 0 && d <= (new Date(y, m, 0)).getDate();
  266. };
  267. php.gmdate = function (format, timestamp) {
  268. // Format a GMT date/time
  269. //
  270. // version: 1103.1210
  271. // discuss at: http://phpjs.org/functions/gmdate
  272. // + original by: Brett Zamir (http://brett-zamir.me)
  273. // + input by: Alex
  274. // + bugfixed by: Brett Zamir (http://brett-zamir.me)
  275. // - depends on: date
  276. // * example 1: gmdate('H:m:s \\m \\i\\s \\m\\o\\n\\t\\h', 1062402400); // Return will depend on your timezone
  277. // * returns 1: '07:09:40 m is month'
  278. var dt = ((typeof(timestamp) == 'undefined') ? new Date() : // Not provided
  279. (typeof(timestamp) == 'object') ? new Date(timestamp) : // Javascript Date()
  280. new Date(timestamp * 1000) // UNIX timestamp (auto-convert to int)
  281. );
  282. timestamp = Date.parse(dt.toUTCString().slice(0, -4)) / 1000;
  283. return this.date(format, timestamp);
  284. };
  285. php.mt_rand = function (min, max) {
  286. // Returns a random number from Mersenne Twister
  287. //
  288. // version: 1103.1210
  289. // discuss at: http://phpjs.org/functions/mt_rand
  290. // + original by: Onno Marsman
  291. // * example 1: mt_rand(1, 1);
  292. // * returns 1: 1
  293. var argc = arguments.length;
  294. if (argc === 0) {
  295. min = 0;
  296. max = 2147483647;
  297. } else if (argc === 1) {
  298. throw new Error('Warning: mt_rand() expects exactly 2 parameters, 1 given');
  299. }
  300. return Math.floor(Math.random() * (max - min + 1)) + min;
  301. };
  302. php.abs = function (mixed_number) {
  303. // Return the absolute value of the number
  304. //
  305. // version: 1103.1210
  306. // discuss at: http://phpjs.org/functions/abs
  307. // + original by: Waldo Malqui Silva
  308. // + improved by: Karol Kowalski
  309. // + improved by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
  310. // + improved by: Jonas Raoni Soares Silva (http://www.jsfromhell.com)
  311. // * example 1: \php.abs(4.2);
  312. // * returns 1: 4.2
  313. // * example 2: \php.abs(-4.2);
  314. // * returns 2: 4.2
  315. // * example 3: \php.abs(-5);
  316. // * returns 3: 5
  317. // * example 4: \php.abs('_argos');
  318. // * returns 4: 0
  319. return Math.abs(mixed_number) || 0;
  320. };
  321. php.addcslashes = function (str, charlist) {
  322. // Escapes all chars mentioned in charlist with backslash. It creates octal representations if asked to backslash characters with 8th bit set or with ASCII<32 (except '\n', '\r', '\t' etc...)
  323. //
  324. // version: 1103.1210
  325. // discuss at: http://phpjs.org/functions/addcslashes
  326. // + original by: Brett Zamir (http://brett-zamir.me)
  327. // % note 1: We show double backslashes in the return value example code below because a JavaScript string will not
  328. // % note 1: render them as backslashes otherwise
  329. // * example 1: \php.addcslashes('foo[ ]', 'A..z'); // Escape all ASCII within capital A to lower z range, including square brackets
  330. // * returns 1: "\\f\\o\\o\\[ \\]"
  331. // * example 2: \php.addcslashes("zoo['.']", 'z..A'); // Only escape z, period, and A here since not a lower-to-higher range
  332. // * returns 2: "\\zoo['\\.']"
  333. // * example 3: \php.addcslashes("@a\u0000\u0010\u00A9", "\0..\37!@\177..\377") == '\\@a\\000\\020\\302\\251'); // Escape as octals those specified and less than 32 (0x20) or greater than 126 (0x7E), but not otherwise
  334. // * returns 3: true
  335. // * example 4: \php.addcslashes("\u0020\u007E", "\40..\175") == '\\ ~'); // Those between 32 (0x20 or 040) and 126 (0x7E or 0176) decimal value will be backslashed if specified (not octalized)
  336. // * returns 4: true
  337. // * example 5: \php.addcslashes("\r\u0007\n", '\0..\37'); // Recognize C escape sequences if specified
  338. // * returns 5: "\\r\\a\\n"
  339. // * example 6: \php.addcslashes("\r\u0007\n", '\0'); // Do not recognize C escape sequences if not specified
  340. // * returns 7: "\r\u0007\n"
  341. var target = '',
  342. chrs = [],
  343. i = 0,
  344. j = 0,
  345. c = '',
  346. next = '',
  347. rangeBegin = '',
  348. rangeEnd = '',
  349. chr = '',
  350. begin = 0,
  351. end = 0,
  352. octalLength = 0,
  353. postOctalPos = 0,
  354. cca = 0,
  355. escHexGrp = [],
  356. encoded = '',
  357. percentHex = /%([\dA-Fa-f]+)/g;
  358. var _pad = function (n, c) {
  359. if ((n = n + "").length < c) {
  360. return new Array(++c - n.length).join("0") + n;
  361. } else {
  362. return n;
  363. }
  364. };
  365. for (i = 0; i < charlist.length; i++) {
  366. c = charlist.charAt(i);
  367. next = charlist.charAt(i + 1);
  368. if (c === '\\' && next && (/\d/).test(next)) { // Octal
  369. rangeBegin = charlist.slice(i + 1).match(/^\d+/)[0];
  370. octalLength = rangeBegin.length;
  371. postOctalPos = i + octalLength + 1;
  372. if (charlist.charAt(postOctalPos) + charlist.charAt(postOctalPos + 1) === '..') { // Octal begins range
  373. begin = rangeBegin.charCodeAt(0);
  374. if ((/\\\d/).test(charlist.charAt(postOctalPos + 2) + charlist.charAt(postOctalPos + 3))) { // Range ends with octal
  375. rangeEnd = charlist.slice(postOctalPos + 3).match(/^\d+/)[0];
  376. i += 1; // Skip range end backslash
  377. } else if (charlist.charAt(postOctalPos + 2)) { // Range ends with character
  378. rangeEnd = charlist.charAt(postOctalPos + 2);
  379. } else {
  380. throw 'Range with no end point';
  381. }
  382. end = rangeEnd.charCodeAt(0);
  383. if (end > begin) { // Treat as a range
  384. for (j = begin; j <= end; j++) {
  385. chrs.push(String.fromCharCode(j));
  386. }
  387. } else { // Supposed to treat period, begin and end as individual characters only, not a range
  388. chrs.push('.', rangeBegin, rangeEnd);
  389. }
  390. i += rangeEnd.length + 2; // Skip dots and range end (already skipped range end backslash if present)
  391. } else { // Octal is by itself
  392. chr = String.fromCharCode(parseInt(rangeBegin, 8));
  393. chrs.push(chr);
  394. }
  395. i += octalLength; // Skip range begin
  396. } else if (next + charlist.charAt(i + 2) === '..') { // Character begins range
  397. rangeBegin = c;
  398. begin = rangeBegin.charCodeAt(0);
  399. if ((/\\\d/).test(charlist.charAt(i + 3) + charlist.charAt(i + 4))) { // Range ends with octal
  400. rangeEnd = charlist.slice(i + 4).match(/^\d+/)[0];
  401. i += 1; // Skip range end backslash
  402. } else if (charlist.charAt(i + 3)) { // Range ends with character
  403. rangeEnd = charlist.charAt(i + 3);
  404. } else {
  405. throw 'Range with no end point';
  406. }
  407. end = rangeEnd.charCodeAt(0);
  408. if (end > begin) { // Treat as a range
  409. for (j = begin; j <= end; j++) {
  410. chrs.push(String.fromCharCode(j));
  411. }
  412. } else { // Supposed to treat period, begin and end as individual characters only, not a range
  413. chrs.push('.', rangeBegin, rangeEnd);
  414. }
  415. i += rangeEnd.length + 2; // Skip dots and range end (already skipped range end backslash if present)
  416. } else { // Character is by itself
  417. chrs.push(c);
  418. }
  419. }
  420. for (i = 0; i < str.length; i++) {
  421. c = str.charAt(i);
  422. if (chrs.indexOf(c) !== -1) {
  423. target += '\\';
  424. cca = c.charCodeAt(0);
  425. if (cca < 32 || cca > 126) { // Needs special escaping
  426. switch (c) {
  427. case '\n':
  428. target += 'n';
  429. break;
  430. case '\t':
  431. target += 't';
  432. break;
  433. case '\u000D':
  434. target += 'r';
  435. break;
  436. case '\u0007':
  437. target += 'a';
  438. break;
  439. case '\v':
  440. target += 'v';
  441. break;
  442. case '\b':
  443. target += 'b';
  444. break;
  445. case '\f':
  446. target += 'f';
  447. break;
  448. default:
  449. //target += _pad(cca.toString(8), 3);break; // Sufficient for UTF-16
  450. encoded = encodeURIComponent(c);
  451. // 3-length-padded UTF-8 octets
  452. if ((escHexGrp = percentHex.exec(encoded)) !== null) {
  453. target += _pad(parseInt(escHexGrp[1], 16).toString(8), 3); // already added a slash above
  454. }
  455. while ((escHexGrp = percentHex.exec(encoded)) !== null) {
  456. target += '\\' + _pad(parseInt(escHexGrp[1], 16).toString(8), 3);
  457. }
  458. break;
  459. }
  460. } else { // Perform regular backslashed escaping
  461. target += c;
  462. }
  463. } else { // Just add the character unescaped
  464. target += c;
  465. }
  466. }
  467. return target;
  468. };
  469. php.addslashes = function (str) {
  470. // Escapes single quote, double quotes and backslash characters in a string with backslashes
  471. //
  472. // version: 1103.1210
  473. // discuss at: http://phpjs.org/functions/addslashes
  474. // + original by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
  475. // + improved by: Ates Goral (http://magnetiq.com)
  476. // + improved by: marrtins
  477. // + improved by: Nate
  478. // + improved by: Onno Marsman
  479. // + input by: Denny Wardhana
  480. // + improved by: Brett Zamir (http://brett-zamir.me)
  481. // + improved by: Oskar Larsson Högfeldt (http://oskar-lh.name/)
  482. // * example 1: \php.addslashes("kevin's birthday");
  483. // * returns 1: 'kevin\'s birthday'
  484. return (str + '').replace(/[\\"']/g, '\\$&').replace(/\u0000/g, '\\0');
  485. };
  486. php.array_chunk = function (input, size) {
  487. // Split array into chunks
  488. //
  489. // version: 1103.1210
  490. // discuss at: http://phpjs.org/functions/array_chunk
  491. // + original by: Carlos R. L. Rodrigues (http://www.jsfromhell.com)
  492. // * example 1: \php.array_chunk(['Kevin', 'van', 'Zonneveld'], 2);
  493. // * returns 1: {0 : {0: 'Kevin', 1: 'van'} , 1 : {0: 'Zonneveld'}}
  494. for (var x, i = 0, c = -1, l = input.length, n = []; i < l; i++) {
  495. (x = i % size) ? n[c][x] = input[i] : n[++c] = [input[i]];
  496. }
  497. return n;
  498. };
  499. php.array_combine = function (keys, values) {
  500. // Creates an array by using the elements of the first parameter as keys and the elements of the second as the corresponding values
  501. //
  502. // version: 1103.1210
  503. // discuss at: http://phpjs.org/functions/array_combine
  504. // + original by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
  505. // + improved by: Brett Zamir (http://brett-zamir.me)
  506. // * example 1: \php.array_combine([0,1,2], ['kevin','van','zonneveld']);
  507. // * returns 1: {0: 'kevin', 1: 'van', 2: 'zonneveld'}
  508. var new_array = {},
  509. keycount = keys && keys.length,
  510. i = 0;
  511. // input sanitation
  512. if (typeof keys !== 'object' || typeof values !== 'object' || // Only accept arrays or array-like objects
  513. typeof keycount !== 'number' || typeof values.length !== 'number' || !keycount) { // Require arrays to have a count
  514. return false;
  515. }
  516. // number of elements does not match
  517. if (keycount != values.length) {
  518. return false;
  519. }
  520. for (i = 0; i < keycount; i++) {
  521. new_array[keys[i]] = values[i];
  522. }
  523. return new_array;
  524. };
  525. php.array_diff = function () {
  526. // Returns the entries of arr1 that have values which are not present in any of the others arguments.
  527. //
  528. // version: 1103.1210
  529. // discuss at: http://phpjs.org/functions/array_diff
  530. // + original by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
  531. // + improved by: Sanjoy Roy
  532. // + revised by: Brett Zamir (http://brett-zamir.me)
  533. // * example 1: \php.array_diff(['Kevin', 'van', 'Zonneveld'], ['van', 'Zonneveld']);
  534. // * returns 1: {0:'Kevin'}
  535. var arr1 = arguments[0],
  536. retArr = {};
  537. var k1 = '',
  538. i = 1,
  539. k = '',
  540. arr = {};
  541. arr1keys: for (k1 in arr1) {
  542. for (i = 1; i < arguments.length; i++) {
  543. arr = arguments[i];
  544. for (k in arr) {
  545. if (arr[k] === arr1[k1]) {
  546. // If it reaches here, it was found in at least one array, so try next value
  547. continue arr1keys;
  548. }
  549. }
  550. retArr[k1] = arr1[k1];
  551. }
  552. }
  553. return retArr;
  554. };
  555. php.array_fill = function (start_index, num, mixed_val) {
  556. // Create an array containing num elements starting with index start_key each initialized to val
  557. //
  558. // version: 1103.1210
  559. // discuss at: http://phpjs.org/functions/array_fill
  560. // + original by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
  561. // + improved by: Waldo Malqui Silva
  562. // * example 1: \php.array_fill(5, 6, 'banana');
  563. // * returns 1: { 5: 'banana', 6: 'banana', 7: 'banana', 8: 'banana', 9: 'banana', 10: 'banana' }
  564. var key, tmp_arr = {};
  565. if (!isNaN(start_index) && !isNaN(num)) {
  566. for (key = 0; key < num; key++) {
  567. tmp_arr[(key + start_index)] = mixed_val;
  568. }
  569. }
  570. return tmp_arr;
  571. };
  572. php.array_fill_keys = function (keys, value) {
  573. // Create an array using the elements of the first parameter as keys each initialized to val
  574. //
  575. // version: 1103.1210
  576. // discuss at: http://phpjs.org/functions/array_fill_keys
  577. // + original by: Brett Zamir (http://brett-zamir.me)
  578. // + bugfixed by: Brett Zamir (http://brett-zamir.me)
  579. // * example 1: \php.keys = {'a': 'foo', 2: 5, 3: 10, 4: 'bar'}
  580. // * example 1: \php.array_fill_keys(keys, 'banana')
  581. // * returns 1: {"foo": "banana", 5: "banana", 10: "banana", "bar": "banana"}
  582. var retObj = {},
  583. key = '';
  584. for (key in keys) {
  585. retObj[keys[key]] = value;
  586. }
  587. return retObj;
  588. };
  589. php.array_filter = function (arr, func) {
  590. // Filters elements from the array via the callback.
  591. //
  592. // version: 1103.1210
  593. // discuss at: http://phpjs.org/functions/array_filter
  594. // + original by: Brett Zamir (http://brett-zamir.me)
  595. // % note 1: Takes a function as an argument, not a function's name
  596. // * example 1: \php.var odd = function (num) {return (num & 1);};
  597. // * example 1: \php.array_filter({"a": 1, "b": 2, "c": 3, "d": 4, "e": 5}, odd);
  598. // * returns 1: {"a": 1, "c": 3, "e": 5}
  599. // * example 2: \php.var even = function (num) {return (!(num & 1));}
  600. // * example 2: \php.array_filter([6, 7, 8, 9, 10, 11, 12], even);
  601. // * returns 2: {0: 6, 2: 8, 4: 10, 6: 12}
  602. var retObj = {},
  603. k;
  604. for (k in arr) {
  605. if (func(arr[k])) {
  606. retObj[k] = arr[k];
  607. }
  608. }
  609. return retObj;
  610. };
  611. php.array_flip = function (trans) {
  612. // Return array with key <-> value flipped
  613. //
  614. // version: 1103.1210
  615. // discuss at: http://phpjs.org/functions/array_flip
  616. // + original by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
  617. // * example 1: \php.array_flip( {a: 1, b: 1, c: 2} );
  618. // * returns 1: {1: 'b', 2: 'c'}
  619. var key, tmp_ar = {};
  620. for (key in trans) {
  621. tmp_ar[trans[key]] = key;
  622. }
  623. return tmp_ar;
  624. };
  625. php.array_intersect = function () {
  626. // Returns the entries of arr1 that have values which are present in all the other arguments
  627. //
  628. // version: 1103.1210
  629. // discuss at: http://phpjs.org/functions/array_intersect
  630. // + original by: Brett Zamir (http://brett-zamir.me)
  631. // % note 1: These only output associative arrays (would need to be
  632. // % note 1: all numeric and counting from zero to be numeric)
  633. // * example 1: $array1 = {'a' : 'green', 0:'red', 1: 'blue'};
  634. // * example 1: $array2 = {'b' : 'green', 0:'yellow', 1:'red'};
  635. // * example 1: $array3 = ['green', 'red'];
  636. // * example 1: $result = array_intersect($array1, $array2, $array3);
  637. // * returns 1: {0: 'red', a: 'green'}
  638. var arr1 = arguments[0],
  639. retArr = {};
  640. var k1 = '',
  641. arr = {},
  642. i = 0,
  643. k = '';
  644. arr1keys: for (k1 in arr1) {
  645. arrs: for (i = 1; i < arguments.length; i++) {
  646. arr = arguments[i];
  647. for (k in arr) {
  648. if (arr[k] === arr1[k1]) {
  649. if (i === arguments.length - 1) {
  650. retArr[k1] = arr1[k1];
  651. }
  652. // If the innermost loop always leads at least once to an equal value, continue the loop until done
  653. continue arrs;
  654. }
  655. }
  656. // If it reaches here, it wasn't found in at least one array, so try next value
  657. continue arr1keys;
  658. }
  659. }
  660. return retArr;
  661. };
  662. php.array_key_exists = function (key, search) {
  663. // Checks if the given key or index exists in the array
  664. //
  665. // version: 1103.1210
  666. // discuss at: http://phpjs.org/functions/array_key_exists
  667. // + original by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
  668. // + improved by: Felix Geisendoerfer (http://www.debuggable.com/felix)
  669. // * example 1: \php.array_key_exists('kevin', {'kevin': 'van Zonneveld'});
  670. // * returns 1: true
  671. // input sanitation
  672. if (!search || (search.constructor !== Array && search.constructor !== Object)) {
  673. return false;
  674. }
  675. return key in search;
  676. };
  677. php.array_keys = function (input, search_value, argStrict) {
  678. // Return just the keys from the input array, optionally only for the specified search_value
  679. //
  680. // version: 1103.1210
  681. // discuss at: http://phpjs.org/functions/array_keys
  682. // + original by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
  683. // + input by: Brett Zamir (http://brett-zamir.me)
  684. // + bugfixed by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
  685. // + improved by: jd
  686. // + improved by: Brett Zamir (http://brett-zamir.me)
  687. // * example 1: \php.array_keys( {firstname: 'Kevin', surname: 'van Zonneveld'} );
  688. // * returns 1: {0: 'firstname', 1: 'surname'}
  689. var search = typeof search_value !== 'undefined',
  690. tmp_arr = [],
  691. strict = !!argStrict,
  692. include = true,
  693. key = '';
  694. for (key in input) {
  695. if (input.hasOwnProperty(key)) {
  696. include = true;
  697. if (search) {
  698. if (strict && input[key] !== search_value) {
  699. include = false;
  700. }
  701. else if (input[key] != search_value) {
  702. include = false;
  703. }
  704. }
  705. if (include) {
  706. tmp_arr[tmp_arr.length] = key;
  707. }
  708. }
  709. }
  710. return tmp_arr;
  711. };
  712. php.array_map = function (callback) {
  713. // Applies the callback to the elements in given arrays.
  714. //
  715. // version: 1103.1210
  716. // discuss at: http://phpjs.org/functions/array_map
  717. // + original by: Andrea Giammarchi (http://webreflection.blogspot.com)
  718. // + improved by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
  719. // + improved by: Brett Zamir (http://brett-zamir.me)
  720. // % note 1: Takes a function as an argument, not a function's name
  721. // % note 2: If the callback is a string, it can only work if the function name is in the global context
  722. // * example 1: \php.array_map( function (a){return (a * a * a)}, [1, 2, 3, 4, 5] );
  723. // * returns 1: [ 1, 8, 27, 64, 125 ]
  724. var argc = arguments.length,
  725. argv = arguments;
  726. var j = argv[1].length,
  727. i = 0,
  728. k = 1,
  729. m = 0;
  730. var tmp = [],
  731. tmp_ar = [];
  732. while (i < j) {
  733. while (k < argc) {
  734. tmp[m++] = argv[k++][i];
  735. }
  736. m = 0;
  737. k = 1;
  738. if (callback) {
  739. if (typeof callback === 'string') {
  740. callback = this.window[callback];
  741. }
  742. tmp_ar[i++] = callback.apply(null, tmp);
  743. } else {
  744. tmp_ar[i++] = tmp;
  745. }
  746. tmp = [];
  747. }
  748. return tmp_ar;
  749. };
  750. php.array_merge = function () {
  751. // Merges elements from passed arrays into one array
  752. //
  753. // version: 1103.1210
  754. // discuss at: http://phpjs.org/functions/array_merge
  755. // + original by: Brett Zamir (http://brett-zamir.me)
  756. // + bugfixed by: Nate
  757. // + input by: josh
  758. // + bugfixed by: Brett Zamir (http://brett-zamir.me)
  759. // * example 1: \php.arr1 = {"color": "red", 0: 2, 1: 4}
  760. // * example 1: \php.arr2 = {0: "a", 1: "b", "color": "green", "shape": "trapezoid", 2: 4}
  761. // * example 1: \php.array_merge(arr1, arr2)
  762. // * returns 1: {"color": "green", 0: 2, 1: 4, 2: "a", 3: "b", "shape": "trapezoid", 4: 4}
  763. // * example 2: \php.arr1 = []
  764. // * example 2: \php.arr2 = {1: "data"}
  765. // * example 2: \php.array_merge(arr1, arr2)
  766. // * returns 2: {0: "data"}
  767. var args = Array.prototype.slice.call(arguments),
  768. retObj = {},
  769. k, j = 0,
  770. i = 0,
  771. retArr = true;
  772. for (i = 0; i < args.length; i++) {
  773. if (!(args[i] instanceof Array)) {
  774. retArr = false;
  775. break;
  776. }
  777. }
  778. if (retArr) {
  779. retArr = [];
  780. for (i = 0; i < args.length; i++) {
  781. retArr = retArr.concat(args[i]);
  782. }
  783. return retArr;
  784. }
  785. var ct = 0;
  786. for (i = 0, ct = 0; i < args.length; i++) {
  787. if (args[i] instanceof Array) {
  788. for (j = 0; j < args[i].length; j++) {
  789. retObj[ct++] = args[i][j];
  790. }
  791. } else {
  792. for (k in args[i]) {
  793. if (args[i].hasOwnProperty(k)) {
  794. if (parseInt(k, 10) + '' === k) {
  795. retObj[ct++] = args[i][k];
  796. } else {
  797. retObj[k] = args[i][k];
  798. }
  799. }
  800. }
  801. }
  802. }
  803. return retObj;
  804. };
  805. php.array_merge_recursive = function (arr1, arr2) {
  806. // Recursively merges elements from passed arrays into one array
  807. //
  808. // version: 1103.1210
  809. // discuss at: http://phpjs.org/functions/array_merge_recursive
  810. // + original by: Subhasis Deb
  811. // + input by: Brett Zamir (http://brett-zamir.me)
  812. // + bugfixed by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
  813. // - depends on: array_merge
  814. // * example 1: \php.arr1 = {'color': {'favourite': 'read'}, 0: 5}
  815. // * example 1: \php.arr2 = {0: 10, 'color': {'favorite': 'green', 0: 'blue'}}
  816. // * example 1: \php.array_merge_recursive(arr1, arr2)
  817. // * returns 1: {'color': {'favorite': {0: 'red', 1: 'green'}, 0: 'blue'}, 1: 5, 1: 10}
  818. var idx = '';
  819. if ((arr1 && (arr1 instanceof Array)) && (arr2 && (arr2 instanceof Array))) {
  820. for (idx in arr2) {
  821. arr1.push(arr2[idx]);
  822. }
  823. } else if ((arr1 && (arr1 instanceof Object)) && (arr2 && (arr2 instanceof Object))) {
  824. for (idx in arr2) {
  825. if (idx in arr1) {
  826. if (typeof arr1[idx] == 'object' && typeof arr2 == 'object') {
  827. arr1[idx] = this.array_merge(arr1[idx], arr2[idx]);
  828. } else {
  829. arr1[idx] = arr2[idx];
  830. }
  831. } else {
  832. arr1[idx] = arr2[idx];
  833. }
  834. }
  835. }
  836. return arr1;
  837. };
  838. php.array_pop = function (inputArr) {
  839. // Pops an element off the end of the array
  840. //
  841. // version: 1103.1210
  842. // discuss at: http://phpjs.org/functions/array_pop
  843. // + original by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
  844. // + improved by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
  845. // + input by: Brett Zamir (http://brett-zamir.me)
  846. // + bugfixed by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
  847. // + bugfixed by: Brett Zamir (http://brett-zamir.me)
  848. // + input by: Theriault
  849. // % note 1: While IE (and other browsers) support iterating an object's
  850. // % note 1: own properties in order, if one attempts to add back properties
  851. // % note 1: in IE, they may end up in their former position due to their position
  852. // % note 1: being retained. So use of this function with "associative arrays"
  853. // % note 1: (objects) may lead to unexpected behavior in an IE environment if
  854. // % note 1: you add back properties with the same keys that you removed
  855. // * example 1: \php.array_pop([0,1,2]);
  856. // * returns 1: 2
  857. // * example 2: \php.data = {firstName: 'Kevin', surName: 'van Zonneveld'};
  858. // * example 2: \php.lastElem = array_pop(data);
  859. // * returns 2: 'van Zonneveld'
  860. // * results 2: data == {firstName: 'Kevin'}
  861. var key = '',
  862. lastKey = '';
  863. if (inputArr.hasOwnProperty('length')) {
  864. // Indexed
  865. if (!inputArr.length) {
  866. // Done popping, are we?
  867. return null;
  868. }
  869. return inputArr.pop();
  870. } else {
  871. // Associative
  872. for (key in inputArr) {
  873. if (inputArr.hasOwnProperty(key)) {
  874. lastKey = key;
  875. }
  876. }
  877. if (lastKey) {
  878. var tmp = inputArr[lastKey];
  879. delete(inputArr[lastKey]);
  880. return tmp;
  881. } else {
  882. return null;
  883. }
  884. }
  885. };
  886. php.array_push = function (inputArr) {
  887. // Pushes elements onto the end of the array
  888. //
  889. // version: 1103.1210
  890. // discuss at: http://phpjs.org/functions/array_push
  891. // + original by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
  892. // + improved by: Brett Zamir (http://brett-zamir.me)
  893. // % note 1: Note also that IE retains information about property position even
  894. // % note 1: after being supposedly deleted, so if you delete properties and then
  895. // % note 1: add back properties with the same keys (including numeric) that had
  896. // % note 1: been deleted, the order will be as before; thus, this function is not
  897. // % note 1: really recommended with associative arrays (objects) in IE environments
  898. // * example 1: \php.array_push(['kevin','van'], 'zonneveld');
  899. // * returns 1: 3
  900. var i = 0,
  901. pr = '',
  902. argv = arguments,
  903. argc = argv.length,
  904. allDigits = /^\d$/,
  905. size = 0,
  906. highestIdx = 0,
  907. len = 0;
  908. if (inputArr.hasOwnProperty('length')) {
  909. for (i = 1; i < argc; i++) {
  910. inputArr[inputArr.length] = argv[i];
  911. }
  912. return inputArr.length;
  913. }
  914. // Associative (object)
  915. for (pr in inputArr) {
  916. if (inputArr.hasOwnProperty(pr)) {
  917. ++len;
  918. if (pr.search(allDigits) !== -1) {
  919. size = parseInt(pr, 10);
  920. highestIdx = size > highestIdx ? size : highestIdx;
  921. }
  922. }
  923. }
  924. for (i = 1; i < argc; i++) {
  925. inputArr[++highestIdx] = argv[i];
  926. }
  927. return len + i - 1;
  928. };
  929. php.array_reduce = function (a_input, callback) {
  930. // Iteratively reduce the array to a single value via the callback.
  931. //
  932. // version: 1103.1210
  933. // discuss at: http://phpjs.org/functions/array_reduce
  934. // + original by: Alfonso Jimenez (http://www.alfonsojimenez.com)
  935. // % note 1: Takes a function as an argument, not a function's name
  936. // * example 1: \php.array_reduce([1, 2, 3, 4, 5], function (v, w){v += w;return v;});
  937. // * returns 1: 15
  938. var lon = a_input.length;
  939. var res = 0,
  940. i = 0;
  941. var tmp = [];
  942. for (i = 0; i < lon; i += 2) {
  943. tmp[0] = a_input[i];
  944. if (a_input[(i + 1)]) {
  945. tmp[1] = a_input[(i + 1)];
  946. } else {
  947. tmp[1] = 0;
  948. }
  949. res += callback.apply(null, tmp);
  950. tmp = [];
  951. }
  952. return res;
  953. };
  954. php.array_reverse = function (array, preserve_keys) {
  955. // Return input as a new array with the order of the entries reversed
  956. //
  957. // version: 1103.1210
  958. // discuss at: http://phpjs.org/functions/array_reverse
  959. // + original by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
  960. // + improved by: Karol Kowalski
  961. // * example 1: \php.array_reverse( [ 'php', '4.0', ['green', 'red'] ], true);
  962. // * returns 1: { 2: ['green', 'red'], 1: 4, 0: 'php'}
  963. var arr_len = array.length,
  964. newkey = 0,
  965. tmp_arr = {},
  966. key = '';
  967. preserve_keys = !! preserve_keys;
  968. for (key in array) {
  969. newkey = arr_len - key - 1;
  970. tmp_arr[preserve_keys ? key : newkey] = array[key];
  971. }
  972. return tmp_arr;
  973. };
  974. php.array_shift = function (inputArr) {
  975. // Pops an element off the beginning of the array
  976. //
  977. // version: 1103.1210
  978. // discuss at: http://phpjs.org/functions/array_shift
  979. // + original by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
  980. // + improved by: Martijn Wieringa
  981. // % note 1: Currently does not handle objects
  982. // * example 1: \php.array_shift(['Kevin', 'van', 'Zonneveld']);
  983. // * returns 1: 'Kevin'
  984. var props = false,
  985. shift = undefined,
  986. pr = '',
  987. allDigits = /^\d$/,
  988. int_ct = -1,
  989. _checkToUpIndices = function (arr, ct, key) {
  990. // Deal with situation, e.g., if encounter index 4 and try to set it to 0, but 0 exists later in loop (need to
  991. // increment all subsequent (skipping current key, since we need its value below) until find unused)
  992. if (arr[ct] !== undefined) {
  993. var tmp = ct;
  994. ct += 1;
  995. if (ct === key) {
  996. ct += 1;
  997. }
  998. ct = _checkToUpIndices(arr, ct, key);
  999. arr[ct] = arr[tmp];
  1000. delete arr[tmp];
  1001. }
  1002. return ct;
  1003. };
  1004. if (inputArr.length === 0) {
  1005. return null;
  1006. }
  1007. if (inputArr.length > 0) {
  1008. return inputArr.shift();
  1009. }
  1010. /*
  1011. UNFINISHED FOR HANDLING OBJECTS
  1012. for (pr in inputArr) {
  1013. if (inputArr.hasOwnProperty(pr)) {
  1014. props = true;
  1015. shift = inputArr[pr];
  1016. delete inputArr[pr];
  1017. break;
  1018. }
  1019. }
  1020. for (pr in inputArr) {
  1021. if (inputArr.hasOwnProperty(pr)) {
  1022. if (pr.search(allDigits) !== -1) {
  1023. int_ct += 1;
  1024. if (parseInt(pr, 10) === int_ct) { // Key is already numbered ok, so don't need to change key for value
  1025. continue;
  1026. }
  1027. _checkToUpIndices(inputArr, int_ct, pr);
  1028. arr[int_ct] = arr[pr];
  1029. delete arr[pr];
  1030. }
  1031. }
  1032. }
  1033. if (!props) {
  1034. return null;
  1035. }
  1036. return shift;
  1037. */
  1038. };
  1039. php.array_slice = function (arr, offst, lgth, preserve_keys) {
  1040. // Returns elements specified by offset and length
  1041. //
  1042. // version: 1103.1210
  1043. // discuss at: http://phpjs.org/functions/array_slice
  1044. // + original by: Brett Zamir (http://brett-zamir.me)
  1045. // - depends on: is_int
  1046. // + input by: Brett Zamir (http://brett-zamir.me)
  1047. // + bugfixed by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
  1048. // % note: Relies on is_int because !isNaN accepts floats
  1049. // * example 1: \php.array_slice(["a", "b", "c", "d", "e"], 2, -1);
  1050. // * returns 1: {0: 'c', 1: 'd'}
  1051. // * example 2: \php.array_slice(["a", "b", "c", "d", "e"], 2, -1, true);
  1052. // * returns 2: {2: 'c', 3: 'd'}
  1053. /*
  1054. if ('callee' in arr && 'length' in arr) {
  1055. arr = Array.prototype.slice.call(arr);
  1056. }
  1057. */
  1058. var key = '';
  1059. if (!(arr instanceof Array) || (preserve_keys && offst !== 0)) { // Assoc. array as input or if required as output
  1060. var lgt = 0,
  1061. newAssoc = {};
  1062. for (key in arr) {
  1063. //if (key !== 'length') {
  1064. lgt += 1;
  1065. newAssoc[key] = arr[key];
  1066. //}
  1067. }
  1068. arr = newAssoc;
  1069. offst = (offst < 0) ? lgt + offst : offst;
  1070. lgth = lgth === undefined ? lgt : (lgth < 0) ? lgt + lgth - offst : lgth;
  1071. var assoc = {};
  1072. var start = false,
  1073. it = -1,
  1074. arrlgth = 0,
  1075. no_pk_idx = 0;
  1076. for (key in arr) {
  1077. ++it;
  1078. if (arrlgth >= lgth) {
  1079. break;
  1080. }
  1081. if (it == offst) {
  1082. start = true;
  1083. }
  1084. if (!start) {
  1085. continue;
  1086. }++arrlgth;
  1087. if (this.is_int(key) && !preserve_keys) {
  1088. assoc[no_pk_idx++] = arr[key];
  1089. } else {
  1090. assoc[key] = arr[key];
  1091. }
  1092. }
  1093. //assoc.length = arrlgth; // Make as array-like object (though length will not be dynamic)
  1094. return assoc;
  1095. }
  1096. if (lgth === undefined) {
  1097. return arr.slice(offst);
  1098. } else if (lgth >= 0) {
  1099. return arr.slice(offst, offst + lgth);
  1100. } else {
  1101. return arr.slice(offst, lgth);
  1102. }
  1103. };
  1104. php.array_splice = function (arr, offst, lgth, replacement) {
  1105. // Removes the elements designated by offset and length and replace them with supplied array
  1106. //
  1107. // version: 1103.1210
  1108. // discuss at: http://phpjs.org/functions/array_splice
  1109. // + original by: Brett Zamir (http://brett-zamir.me)
  1110. // + input by: Theriault
  1111. // % note 1: Order does get shifted in associative array input with numeric indices,
  1112. // % note 1: since PHP behavior doesn't preserve keys, but I understand order is
  1113. // % note 1: not reliable anyways
  1114. // % note 2: Note also that IE retains information about property position even
  1115. // % note 2: after being supposedly deleted, so use of this function may produce
  1116. // % note 2: unexpected results in IE if you later attempt to add back properties
  1117. // % note 2: with the same keys that had been deleted
  1118. // - depends on: is_int
  1119. // * example 1: \php.input = {4: "red", 'abc': "green", 2: "blue", 'dud': "yellow"};
  1120. // * example 1: \php.array_splice(input, 2);
  1121. // * returns 1: {0: "blue", 'dud': "yellow"}
  1122. // * results 1: input == {'abc':"green", 0:"red"}
  1123. // * example 2: \php.input = ["red", "green", "blue", "yellow"];
  1124. // * example 2: \php.array_splice(input, 3, 0, "purple");
  1125. // * returns 2: []
  1126. // * results 2: input == ["red", "green", "blue", "purple", "yellow"]
  1127. // * example 3: \php.input = ["red", "green", "blue", "yellow"]
  1128. // * example 3: \php.array_splice(input, -1, 1, ["black", "maroon"]);
  1129. // * returns 3: ["yellow"]
  1130. // * results 3: input == ["red", "green", "blue", "black", "maroon"]
  1131. var _checkToUpIndices = function (arr, ct, key) {
  1132. // Deal with situation, e.g., if encounter index 4 and try to set it to 0, but 0 exists later in loop (need to
  1133. // increment all subsequent (skipping current key, since we need its value below) until find unused)
  1134. if (arr[ct] !== undefined) {
  1135. var tmp = ct;
  1136. ct += 1;
  1137. if (ct === key) {
  1138. ct += 1;
  1139. }
  1140. ct = _checkToUpIndices(arr, ct, key);
  1141. arr[ct] = arr[tmp];
  1142. delete arr[tmp];
  1143. }
  1144. return ct;
  1145. };
  1146. if (replacement && typeof replacement !== 'object') {
  1147. replacement = [replacement];
  1148. }
  1149. if (lgth === undefined) {
  1150. lgth = offst >= 0 ? arr.length - offst : -offst;
  1151. } else if (lgth < 0) {
  1152. lgth = (offst >= 0 ? arr.length - offst : -offst) + lgth;
  1153. }
  1154. if (!(arr instanceof Array)) {
  1155. /*if (arr.length !== undefined) { // Deal with array-like objects as input
  1156. delete arr.length;
  1157. }*/
  1158. var lgt = 0,
  1159. ct = -1,
  1160. rmvd = [],
  1161. rmvdObj = {},
  1162. repl_ct = -1,
  1163. int_ct = -1;
  1164. var returnArr = true,
  1165. rmvd_ct = 0,
  1166. rmvd_lgth = 0,
  1167. key = '';
  1168. // rmvdObj.length = 0;
  1169. for (key in arr) { // Can do arr.__count__ in some browsers
  1170. lgt += 1;
  1171. }
  1172. offst = (offst >= 0) ? offst : lgt + offst;
  1173. for (key in arr) {
  1174. ct += 1;
  1175. if (ct < offst) {
  1176. if (this.is_int(key)) {
  1177. int_ct += 1;
  1178. if (parseInt(key, 10) === int_ct) { // Key is already numbered ok, so don't need to change key for value
  1179. continue;
  1180. }
  1181. _checkToUpIndices(arr, int_ct, key); // Deal with situation, e.g.,
  1182. // if encounter index 4 and try to set it to 0, but 0 exists later in loop
  1183. arr[int_ct] = arr[key];
  1184. delete arr[key];
  1185. }
  1186. continue;
  1187. }
  1188. if (returnArr && this.is_int(key)) {
  1189. rmvd.push(arr[key]);
  1190. rmvdObj[rmvd_ct++] = arr[key]; // PHP starts over here too
  1191. } else {
  1192. rmvdObj[key] = arr[key];
  1193. returnArr = false;
  1194. }
  1195. rmvd_lgth += 1;
  1196. // rmvdObj.length += 1;
  1197. if (replacement && replacement[++repl_ct]) {
  1198. arr[key] = replacement[repl_ct];
  1199. } else {
  1200. delete arr[key];
  1201. }
  1202. }
  1203. // arr.length = lgt - rmvd_lgth + (replacement ? replacement.length : 0); // Make (back) into an array-like object
  1204. return returnArr ? rmvd : rmvdObj;
  1205. }
  1206. if (replacement) {
  1207. replacement.unshift(offst, lgth);
  1208. return Array.prototype.splice.apply(arr, replacement);
  1209. }
  1210. return arr.splice(offst, lgth);
  1211. };
  1212. php.array_sum = function (array) {
  1213. // Returns the sum of the array entries
  1214. //
  1215. // version: 1103.1210
  1216. // discuss at: http://phpjs.org/functions/array_sum
  1217. // + original by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
  1218. // + bugfixed by: Nate
  1219. // + bugfixed by: Gilbert
  1220. // * example 1: \php.array_sum([4, 9, 182.6]);
  1221. // * returns 1: 195.6
  1222. // * example 2: \php.total = []; index = 0.1; for (y=0; y < 12; y++){total[y] = y + index;}
  1223. // * example 2: \php.array_sum(total);
  1224. // * returns 2: 67.2
  1225. var key, sum = 0;
  1226. // input sanitation
  1227. if (typeof array !== 'object') {
  1228. return null;
  1229. }
  1230. for (key in array) {
  1231. //tester_print_r(typeof sum);
  1232. sum += (array[key] * 1);
  1233. }
  1234. return sum;
  1235. };
  1236. php.array_unique = function (inputArr) {
  1237. // Removes duplicate values from array
  1238. //
  1239. // version: 1103.1210
  1240. // discuss at: http://phpjs.org/functions/array_unique
  1241. // + original by: Carlos R. L. Rodrigues (http://www.jsfromhell.com)
  1242. // + input by: duncan
  1243. // + bugfixed by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
  1244. // + bugfixed by: Nate
  1245. // + input by: Brett Zamir (http://brett-zamir.me)
  1246. // + bugfixed by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
  1247. // + improved by: Michael Grier
  1248. // + bugfixed by: Brett Zamir (http://brett-zamir.me)
  1249. // % note 1: The second argument, sort_flags is not implemented;
  1250. // % note 1: also should be sorted (asort?) first according to docs
  1251. // * example 1: \php.array_unique(['Kevin','Kevin','van','Zonneveld','Kevin']);
  1252. // * returns 1: {0: 'Kevin', 2: 'van', 3: 'Zonneveld'}
  1253. // * example 2: \php.array_unique({'a': 'green', 0: 'red', 'b': 'green', 1: 'blue', 2: 'red'});
  1254. // * returns 2: {a: 'green', 0: 'red', 1: 'blue'}
  1255. var key = '',
  1256. tmp_arr2 = {},
  1257. val = '';
  1258. var __array_search = function (needle, haystack) {
  1259. var fkey = '';
  1260. for (fkey in haystack) {
  1261. if (haystack.hasOwnProperty(fkey)) {
  1262. if ((haystack[fkey] + '') === (needle + '')) {
  1263. return fkey;
  1264. }
  1265. }
  1266. }
  1267. return false;
  1268. };
  1269. for (key in inputArr) {
  1270. if (inputArr.hasOwnProperty(key)) {
  1271. val = inputArr[key];
  1272. if (false === __array_search(val, tmp_arr2)) {
  1273. tmp_arr2[key] = val;
  1274. }
  1275. }
  1276. }
  1277. return tmp_arr2;
  1278. };
  1279. php.array_unshift = function (array) {
  1280. // Pushes elements onto the beginning of the array
  1281. //
  1282. // version: 1103.1210
  1283. // discuss at: http://phpjs.org/functions/array_unshift
  1284. // + original by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
  1285. // + improved by: Martijn Wieringa
  1286. // + improved by: jmweb
  1287. // % note 1: Currently does not handle objects
  1288. // * example 1: \php.array_unshift(['van', 'Zonneveld'], 'Kevin');
  1289. // * returns 1: 3
  1290. var i = arguments.length;
  1291. while (--i !== 0) {
  1292. arguments[0].unshift(arguments[i]);
  1293. }
  1294. return arguments[0].length;
  1295. };
  1296. php.array_values = function (input) {
  1297. // Return just the values from the input array
  1298. //
  1299. // version: 1103.1210
  1300. // discuss at: http://phpjs.org/functions/array_values
  1301. // + original by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
  1302. // * example 1: \php.array_values( {firstname: 'Kevin', surname: 'van Zonneveld'} );
  1303. // * returns 1: {0: 'Kevin', 1: 'van Zonneveld'}
  1304. var tmp_arr = [],
  1305. cnt = 0;
  1306. var key = '';
  1307. for (key in input) {
  1308. tmp_arr[cnt] = input[key];
  1309. cnt++;
  1310. }
  1311. return tmp_arr;
  1312. };
  1313. php.array_walk = function (array, funcname, userdata) {
  1314. // Apply a user function to every member of an array
  1315. //
  1316. // version: 1103.1210
  1317. // discuss at: http://phpjs.org/functions/array_walk
  1318. // + original by: Johnny Mast (http://www.phpvrouwen.nl)
  1319. // * example 1: \php.array_walk ({'a':'b'}, 'void', 'userdata');
  1320. // * returns 1: true
  1321. // * example 2: \php.array_walk ('a', 'void', 'userdata');
  1322. // * returns 2: false
  1323. var key;
  1324. if (typeof array !== 'object' || array === null) {
  1325. return false;
  1326. }
  1327. for (key in array) {
  1328. if (typeof(userdata) !== 'undefined') {
  1329. eval(funcname + '( array [key] , key , userdata )');
  1330. } else {
  1331. eval(funcname + '( userdata ) ');
  1332. }
  1333. }
  1334. return true;
  1335. };
  1336. php.array_walk_recursive = function (array, funcname, userdata) {
  1337. // Apply a user function recursively to every member of an array
  1338. //
  1339. // version: 1103.1210
  1340. // discuss at: http://phpjs.org/functions/array_walk_recursive
  1341. // + original by: Johnny Mast (http://www.phpvrouwen.nl)
  1342. // * example 1: \php.array_walk_recursive ({'a': 'b', 'c': {'d': 'e'}}, 'void', 'userdata');
  1343. // * returns 1: true
  1344. // * example 2: \php.array_walk_recursive ('a', 'void', 'userdata');
  1345. // * returns 2: false
  1346. var key;
  1347. if (typeof array != 'object') {
  1348. return false;
  1349. }
  1350. for (key in array) {
  1351. if (typeof array[key] == 'object') {
  1352. return this.array_walk_recursive(array[key], funcname, userdata);
  1353. }
  1354. if (typeof(userdata) != 'undefined') {
  1355. eval(funcname + '( array [key] , key , userdata )');
  1356. } else {
  1357. eval(funcname + '( userdata ) ');
  1358. }
  1359. }
  1360. return true;
  1361. };
  1362. php.arsort = function (inputArr, sort_flags) {
  1363. // Sort an array in reverse order and maintain index association
  1364. //
  1365. // version: 1103.1210
  1366. // discuss at: http://phpjs.org/functions/arsort
  1367. // + original by: Brett Zamir (http://brett-zamir.me)
  1368. // + improved by: Brett Zamir (http://brett-zamir.me)
  1369. // % note 1: SORT_STRING (as well as natsort and natcasesort) might also be
  1370. // % note 1: integrated into all of these functions by adapting the code at
  1371. // % note 1: http://sourcefrog.net/projects/natsort/natcompare.js
  1372. // % note 2: The examples are correct, this is a new way
  1373. // % note 2: Credits to: http://javascript.internet.com/math-related/bubble-sort.html
  1374. // % note 3: This function deviates from PHP in returning a copy of the array instead
  1375. // % note 3: of acting by reference and returning true; this was necessary because
  1376. // % note 3: IE does not allow deleting and re-adding of properties without caching
  1377. // % note 3: of property position; you can set the ini of "phpjs.strictForIn" to true to
  1378. // % note 3: get the PHP behavior, but use this only if you are in an environment
  1379. // % note 3: such as Firefox extensions where for-in iteration order is fixed and true
  1380. // % note 3: property deletion is supported. Note that we intend to implement the PHP
  1381. // % note 3: behavior by default if IE ever does allow it; only gives shallow copy since
  1382. // % note 3: is by reference in PHP anyways
  1383. // % note 4: Since JS objects' keys are always strings, and (the
  1384. // % note 4: default) SORT_REGULAR flag distinguishes by key type,
  1385. // % note 4: if the content is a numeric string, we treat the
  1386. // % note 4: "original type" as numeric.
  1387. // - depends on: i18n_loc_get_default
  1388. // * example 1: \php.data = {d: 'lemon', a: 'orange', b: 'banana', c: 'apple'};
  1389. // * example 1: \php.data = arsort(data);
  1390. // * returns 1: data == {a: 'orange', d: 'lemon', b: 'banana', c: 'apple'}
  1391. // * example 2: \php.ini_set('phpjs.strictForIn', true);
  1392. // * example 2: \php.data = {d: 'lemon', a: 'orange', b: 'banana', c: 'apple'};
  1393. // * example 2: \php.arsort(data);
  1394. // * results 2: data == {a: 'orange', d: 'lemon', b: 'banana', c: 'apple'}
  1395. // * returns 2: true
  1396. var valArr = [],
  1397. keyArr = [],
  1398. k, i, ret, sorter, that = this,
  1399. strictForIn = false,
  1400. populateArr = {};
  1401. switch (sort_flags) {
  1402. case 'SORT_STRING':
  1403. // compare items as strings
  1404. sorter = function (a, b) {
  1405. return that.strnatcmp(b, a);
  1406. };
  1407. break;
  1408. case 'SORT_LOCALE_STRING':
  1409. // compare items as strings, based on the current locale (set with i18n_loc_set_default() as of PHP6)
  1410. var loc = this.i18n_loc_get_default();
  1411. sorter = this.php_js.i18nLocales[loc].sorting;
  1412. break;
  1413. case 'SORT_NUMERIC':
  1414. // compare items numerically
  1415. sorter = function (a, b) {
  1416. return (a - b);
  1417. };
  1418. break;
  1419. case 'SORT_REGULAR':
  1420. // compare items normally (don't change types)
  1421. default:
  1422. sorter = function (b, a) {
  1423. var aFloat = parseFloat(a),
  1424. bFloat = parseFloat(b),
  1425. aNumeric = aFloat + '' === a,
  1426. bNumeric = bFloat + '' === b;
  1427. if (aNumeric && bNumeric) {
  1428. return aFloat > bFloat ? 1 : aFloat < bFloat ? -1 : 0;
  1429. } else if (aNumeric && !bNumeric) {
  1430. return 1;
  1431. } else if (!aNumeric && bNumeric) {
  1432. return -1;
  1433. }
  1434. return a > b ? 1 : a < b ? -1 : 0;
  1435. };
  1436. break;
  1437. }
  1438. var bubbleSort = function (keyArr, inputArr) {
  1439. var i, j, tempValue, tempKeyVal;
  1440. for (i = inputArr.length - 2; i >= 0; i--) {
  1441. for (j = 0; j <= i; j++) {
  1442. ret = sorter(inputArr[j + 1], inputArr[j]);
  1443. if (ret > 0) {
  1444. tempValue = inputArr[j];
  1445. inputArr[j] = inputArr[j + 1];
  1446. inputArr[j + 1] = tempValue;
  1447. tempKeyVal = keyArr[j];
  1448. keyArr[j] = keyArr[j + 1];
  1449. keyArr[j + 1] = tempKeyVal;
  1450. }
  1451. }
  1452. }
  1453. };
  1454. // BEGIN REDUNDANT
  1455. this.php_js = this.php_js || {};
  1456. this.php_js.ini = this.php_js.ini || {};
  1457. // END REDUNDANT
  1458. strictForIn = this.php_js.ini['phpjs.strictForIn'] && this.php_js.ini['phpjs.strictForIn'].local_value && this.php_js.ini['phpjs.strictForIn'].local_value !== 'off';
  1459. populateArr = strictForIn ? inputArr : populateArr;
  1460. // Get key and value arrays
  1461. for (k in inputArr) {
  1462. if (inputArr.hasOwnProperty(k)) {
  1463. valArr.push(inputArr[k]);
  1464. keyArr.push(k);
  1465. if (strictForIn) {
  1466. delete inputArr[k];
  1467. }
  1468. }
  1469. }
  1470. try {
  1471. // Sort our new temporary arrays
  1472. bubbleSort(keyArr, valArr);
  1473. } catch (e) {
  1474. return false;
  1475. }
  1476. // Repopulate the old array
  1477. for (i = 0; i < valArr.length; i++) {
  1478. populateArr[keyArr[i]] = valArr[i];
  1479. }
  1480. return strictForIn || populateArr;
  1481. };
  1482. php.asort = function (inputArr, sort_flags) {
  1483. // Sort an array and maintain index association
  1484. //
  1485. // version: 1103.1210
  1486. // discuss at: http://phpjs.org/functions/asort
  1487. // + original by: Brett Zamir (http://brett-zamir.me)
  1488. // + improved by: Brett Zamir (http://brett-zamir.me)
  1489. // + input by: paulo kuong
  1490. // + improved by: Brett Zamir (http://brett-zamir.me)
  1491. // + bugfixed by: Adam Wallner (http://web2.bitbaro.hu/)
  1492. // % note 1: SORT_STRING (as well as natsort and natcasesort) might also be
  1493. // % note 1: integrated into all of these functions by adapting the code at
  1494. // % note 1: http://sourcefrog.net/projects/natsort/natcompare.js
  1495. // % note 2: The examples are correct, this is a new way
  1496. // % note 2: Credits to: http://javascript.internet.com/math-related/bubble-sort.html
  1497. // % note 3: This function deviates from PHP in returning a copy of the array instead
  1498. // % note 3: of acting by reference and returning true; this was necessary because
  1499. // % note 3: IE does not allow deleting and re-adding of properties without caching
  1500. // % note 3: of property position; you can set the ini of "phpjs.strictForIn" to true to
  1501. // % note 3: get the PHP behavior, but use this only if you are in an environment
  1502. // % note 3: such as Firefox extensions where for-in iteration order is fixed and true
  1503. // % note 3: property deletion is supported. Note that we intend to implement the PHP
  1504. // % note 3: behavior by default if IE ever does allow it; only gives shallow copy since
  1505. // % note 3: is by reference in PHP anyways
  1506. // % note 4: Since JS objects' keys are always strings, and (the
  1507. // % note 4: default) SORT_REGULAR flag distinguishes by key type,
  1508. // % note 4: if the content is a numeric string, we treat the
  1509. // % note 4: "original type" as numeric.
  1510. // - depends on: strnatcmp
  1511. // - depends on: i18n_loc_get_default
  1512. // * example 1: \php.data = {d: 'lemon', a: 'orange', b: 'banana', c: 'apple'};
  1513. // * example 1: \php.data = asort(data);
  1514. // * results 1: data == {c: 'apple', b: 'banana', d: 'lemon', a: 'orange'}
  1515. // * returns 1: true
  1516. // * example 2: \php.ini_set('phpjs.strictForIn', true);
  1517. // * example 2: \php.data = {d: 'lemon', a: 'orange', b: 'banana', c: 'apple'};
  1518. // * example 2: \php.asort(data);
  1519. // * results 2: data == {c: 'apple', b: 'banana', d: 'lemon', a: 'orange'}
  1520. // * returns 2: true
  1521. var valArr = [],
  1522. keyArr = [],
  1523. k, i, ret, sorter, that = this,
  1524. strictForIn = false,
  1525. populateArr = {};
  1526. switch (sort_flags) {
  1527. case 'SORT_STRING':
  1528. // compare items as strings
  1529. sorter = function (a, b) {
  1530. return that.strnatcmp(a, b);
  1531. };
  1532. break;
  1533. case 'SORT_LOCALE_STRING':
  1534. // compare items as strings, based on the current locale (set with i18n_loc_set_default() as of PHP6)
  1535. var loc = this.i18n_loc_get_default();
  1536. sorter = this.php_js.i18nLocales[loc].sorting;
  1537. break;
  1538. case 'SORT_NUMERIC':
  1539. // compare items numerically
  1540. sorter = function (a, b) {
  1541. return (a - b);
  1542. };
  1543. break;
  1544. case 'SORT_REGULAR':
  1545. // compare items normally (don't change types)
  1546. default:
  1547. sorter = function (a, b) {
  1548. var aFloat = parseFloat(a),
  1549. bFloat = parseFloat(b),
  1550. aNumeric = aFloat + '' === a,
  1551. bNumeric = bFloat + '' === b;
  1552. if (aNumeric && bNumeric) {
  1553. return aFloat > bFloat ? 1 : aFloat < bFloat ? -1 : 0;
  1554. } else if (aNumeric && !bNumeric) {
  1555. return 1;
  1556. } else if (!aNumeric && bNumeric) {
  1557. return -1;
  1558. }
  1559. return a > b ? 1 : a < b ? -1 : 0;
  1560. };
  1561. break;
  1562. }
  1563. var bubbleSort = function (keyArr, inputArr) {
  1564. var i, j, tempValue, tempKeyVal;
  1565. for (i = inputArr.length - 2; i >= 0; i--) {
  1566. for (j = 0; j <= i; j++) {
  1567. ret = sorter(inputArr[j + 1], inputArr[j]);
  1568. if (ret < 0) {
  1569. tempValue = inputArr[j];
  1570. inputArr[j] = inputArr[j + 1];
  1571. inputArr[j + 1] = tempValue;
  1572. tempKeyVal = keyArr[j];
  1573. keyArr[j] = keyArr[j + 1];
  1574. keyArr[j + 1] = tempKeyVal;
  1575. }
  1576. }
  1577. }
  1578. };
  1579. // BEGIN REDUNDANT
  1580. this.php_js = this.php_js || {};
  1581. this.php_js.ini = this.php_js.ini || {};
  1582. // END REDUNDANT
  1583. strictForIn = this.php_js.ini['phpjs.strictForIn'] && this.php_js.ini['phpjs.strictForIn'].local_value && this.php_js.ini['phpjs.strictForIn'].local_value !== 'off';
  1584. populateArr = strictForIn ? inputArr : populateArr;
  1585. // Get key and value arrays
  1586. for (k in inputArr) {
  1587. if (inputArr.hasOwnProperty(k)) {
  1588. valArr.push(inputArr[k]);
  1589. keyArr.push(k);
  1590. if (strictForIn) {
  1591. delete inputArr[k];
  1592. }
  1593. }
  1594. }
  1595. try {
  1596. // Sort our new temporary arrays
  1597. bubbleSort(keyArr, valArr);
  1598. } catch (e) {
  1599. return false;
  1600. }
  1601. // Repopulate the old array
  1602. for (i = 0; i < valArr.length; i++) {
  1603. populateArr[keyArr[i]] = valArr[i];
  1604. }
  1605. return strictForIn || populateArr;
  1606. };
  1607. php.base64_decode = function (data) {
  1608. // Decodes string using MIME base64 algorithm
  1609. //
  1610. // version: 1103.1210
  1611. // discuss at: http://phpjs.org/functions/base64_decode
  1612. // + original by: Tyler Akins (http://rumkin.com)
  1613. // + improved by: Thunder.m
  1614. // + input by: Aman Gupta
  1615. // + improved by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
  1616. // + bugfixed by: Onno Marsman
  1617. // + bugfixed by: Pellentesque Malesuada
  1618. // + improved by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
  1619. // + input by: Brett Zamir (http://brett-zamir.me)
  1620. // + bugfixed by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
  1621. // - depends on: utf8_decode
  1622. // * example 1: \php.base64_decode('S2V2aW4gdmFuIFpvbm5ldmVsZA==');
  1623. // * returns 1: 'Kevin van Zonneveld'
  1624. // mozilla has this native
  1625. // - but breaks in 2.0.0.12!
  1626. //if (typeof this.window['btoa'] == 'function') {
  1627. // return btoa(data);
  1628. //}
  1629. var b64 = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=";
  1630. var o1, o2, o3, h1, h2, h3, h4, bits, i = 0,
  1631. ac = 0,
  1632. dec = "",
  1633. tmp_arr = [];
  1634. if (!data) {
  1635. return data;
  1636. }
  1637. data += '';
  1638. do { // unpack four hexets into three octets using index points in b64
  1639. h1 = b64.indexOf(data.charAt(i++));
  1640. h2 = b64.indexOf(data.charAt(i++));
  1641. h3 = b64.indexOf(data.charAt(i++));
  1642. h4 = b64.indexOf(data.charAt(i++));
  1643. bits = h1 << 18 | h2 << 12 | h3 << 6 | h4;
  1644. o1 = bits >> 16 & 0xff;
  1645. o2 = bits >> 8 & 0xff;
  1646. o3 = bits & 0xff;
  1647. if (h3 == 64) {
  1648. tmp_arr[ac++] = String.fromCharCode(o1);
  1649. } else if (h4 == 64) {
  1650. tmp_arr[ac++] = String.fromCharCode(o1, o2);
  1651. } else {
  1652. tmp_arr[ac++] = String.fromCharCode(o1, o2, o3);
  1653. }
  1654. } while (i < data.length);
  1655. dec = tmp_arr.join('');
  1656. dec = this.utf8_decode(dec);
  1657. return dec;
  1658. };
  1659. php.base64_encode = function (data) {
  1660. // Encodes string using MIME base64 algorithm
  1661. //
  1662. // version: 1103.1210
  1663. // discuss at: http://phpjs.org/functions/base64_encode
  1664. // + original by: Tyler Akins (http://rumkin.com)
  1665. // + improved by: Bayron Guevara
  1666. // + improved by: Thunder.m
  1667. // + improved by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
  1668. // + bugfixed by: Pellentesque Malesuada
  1669. // + improved by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
  1670. // - depends on: utf8_encode
  1671. // * example 1: \php.base64_encode('Kevin van Zonneveld');
  1672. // * returns 1: 'S2V2aW4gdmFuIFpvbm5ldmVsZA=='
  1673. // mozilla has this native
  1674. // - but breaks in 2.0.0.12!
  1675. //if (typeof this.window['atob'] == 'function') {
  1676. // return atob(data);
  1677. //}
  1678. var b64 = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=";
  1679. var o1, o2, o3, h1, h2, h3, h4, bits, i = 0,
  1680. ac = 0,
  1681. enc = "",
  1682. tmp_arr = [];
  1683. if (!data) {
  1684. return data;
  1685. }
  1686. data = this.utf8_encode(data + '');
  1687. do { // pack three octets into four hexets
  1688. o1 = data.charCodeAt(i++);
  1689. o2 = data.charCodeAt(i++);
  1690. o3 = data.charCodeAt(i++);
  1691. bits = o1 << 16 | o2 << 8 | o3;
  1692. h1 = bits >> 18 & 0x3f;
  1693. h2 = bits >> 12 & 0x3f;
  1694. h3 = bits >> 6 & 0x3f;
  1695. h4 = bits & 0x3f;
  1696. // use hexets to index into b64, and append result to encoded string
  1697. tmp_arr[ac++] = b64.charAt(h1) + b64.charAt(h2) + b64.charAt(h3) + b64.charAt(h4);
  1698. } while (i < data.length);
  1699. enc = tmp_arr.join('');
  1700. switch (data.length % 3) {
  1701. case 1:
  1702. enc = enc.slice(0, -2) + '==';
  1703. break;
  1704. case 2:
  1705. enc = enc.slice(0, -1) + '=';
  1706. break;
  1707. }
  1708. return enc;
  1709. };
  1710. php.base_convert = function (number, frombase, tobase) {
  1711. // Converts a number in a string from any base <= 36 to any base <= 36
  1712. //
  1713. // version: 1103.1210
  1714. // discuss at: http://phpjs.org/functions/base_convert
  1715. // + original by: Philippe Baumann
  1716. // + improved by: Rafał Kukawski (http://blog.kukawski.pl)
  1717. // * example 1: \php.base_convert('A37334', 16, 2);
  1718. // * returns 1: '101000110111001100110100'
  1719. return parseInt(number + '', frombase | 0).toString(tobase | 0);
  1720. };
  1721. php.basename = function (path, suffix) {
  1722. // Returns the filename component of the path
  1723. //
  1724. // version: 1103.1210
  1725. // discuss at: http://phpjs.org/functions/basename
  1726. // + original by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
  1727. // + improved by: Ash Searle (http://hexmen.com/blog/)
  1728. // + improved by: Lincoln Ramsay
  1729. // + improved by: djmix
  1730. // * example 1: \php.basename('/www/site/home.htm', '.htm');
  1731. // * returns 1: 'home'
  1732. // * example 2: \php.basename('ecra.php?p=1');
  1733. // * returns 2: 'ecra.php?p=1'
  1734. var b = path.replace(/^.*[\/\\]/g, '');
  1735. if (typeof(suffix) == 'string' && b.substr(b.length - suffix.length) == suffix) {
  1736. b = b.substr(0, b.length - suffix.length);
  1737. }
  1738. return b;
  1739. };
  1740. php.call_user_func = function (cb) {
  1741. // Call a user function which is the first parameter
  1742. //
  1743. // version: 1103.1210
  1744. // discuss at: http://phpjs.org/functions/call_user_func
  1745. // + original by: Brett Zamir (http://brett-zamir.me)
  1746. // + improved by: Diplom@t (http://difane.com/)
  1747. // + improved by: Brett Zamir (http://brett-zamir.me)
  1748. // * example 1: \php.call_user_func('isNaN', 'a');
  1749. // * returns 1: true
  1750. var func;
  1751. if (typeof cb === 'string') {
  1752. func = (typeof this[cb] === 'function') ? this[cb] : func = (new Function(null, 'return ' + cb))();
  1753. } else if (cb instanceof Array) {
  1754. func = (typeof cb[0] == 'string') ? eval(cb[0] + "['" + cb[1] + "']") : func = cb[0][cb[1]];
  1755. } else if (typeof cb === 'function') {
  1756. func = cb;
  1757. }
  1758. if (typeof func != 'function') {
  1759. throw new Error(func + ' is not a valid function');
  1760. }
  1761. var parameters = Array.prototype.slice.call(arguments, 1);
  1762. return (typeof cb[0] === 'string') ? func.apply(eval(cb[0]), parameters) : (typeof cb[0] !== 'object') ? func.apply(null, parameters) : func.apply(cb[0], parameters);
  1763. };
  1764. php.call_user_func_array = function (cb, parameters) {
  1765. // Call a user function which is the first parameter with the arguments contained in array
  1766. //
  1767. // version: 1103.1210
  1768. // discuss at: http://phpjs.org/functions/call_user_func_array
  1769. // + original by: Thiago Mata (http://thiagomata.blog.com)
  1770. // + revised by: Jon Hohle
  1771. // + improved by: Brett Zamir (http://brett-zamir.me)
  1772. // + improved by: Diplom@t (http://difane.com/)
  1773. // + improved by: Brett Zamir (http://brett-zamir.me)
  1774. // * example 1: \php.call_user_func_array('isNaN', ['a']);
  1775. // * returns 1: true
  1776. // * example 2: \php.call_user_func_array('isNaN', [1]);
  1777. // * returns 2: false
  1778. var func;
  1779. if (typeof cb === 'string') {
  1780. func = (typeof this[cb] === 'function') ? this[cb] : func = (new Function(null, 'return ' + cb))();
  1781. } else if (cb instanceof Array) {
  1782. func = (typeof cb[0] == 'string') ? eval(cb[0] + "['" + cb[1] + "']") : func = cb[0][cb[1]];
  1783. } else if (typeof cb === 'function') {
  1784. func = cb;
  1785. }
  1786. if (typeof func !== 'function') {
  1787. throw new Error(func + ' is not a valid function');
  1788. }
  1789. return (typeof cb[0] === 'string') ? func.apply(eval(cb[0]), parameters) : (typeof cb[0] !== 'object') ? func.apply(null, parameters) : func.apply(cb[0], parameters);
  1790. };
  1791. php.ceil = function (value) {
  1792. // Returns the next highest integer value of the number
  1793. //
  1794. // version: 1103.1210
  1795. // discuss at: http://phpjs.org/functions/ceil
  1796. // + original by: Onno Marsman
  1797. // * example 1: \php.ceil(8723321.4);
  1798. // * returns 1: 8723322
  1799. return Math.ceil(value);
  1800. };
  1801. php.chr = function (codePt) {
  1802. // Converts a codepoint number to a character
  1803. //
  1804. // version: 1103.1210
  1805. // discuss at: http://phpjs.org/functions/chr
  1806. // + original by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
  1807. // + improved by: Brett Zamir (http://brett-zamir.me)
  1808. // * example 1: \php.chr(75);
  1809. // * returns 1: 'K'
  1810. // * example 1: \php.chr(65536) === '\uD800\uDC00';
  1811. // * returns 1: true
  1812. if (codePt > 0xFFFF) { // Create a four-byte string (length 2) since this code point is high
  1813. // enough for the UTF-16 encoding (JavaScript internal use), to
  1814. // require representation with two surrogates (reserved non-characters
  1815. // used for building other characters; the first is "high" and the next "low")
  1816. codePt -= 0x10000;
  1817. return String.fromCharCode(0xD800 + (codePt >> 10), 0xDC00 + (codePt & 0x3FF));
  1818. }
  1819. return String.fromCharCode(codePt);
  1820. };
  1821. php.class_exists = function (cls) {
  1822. // Checks if the class exists
  1823. //
  1824. // version: 1103.1210
  1825. // discuss at: http://phpjs.org/functions/class_exists
  1826. // + original by: Brett Zamir (http://brett-zamir.me)
  1827. // * example 1: \php.function class_a() {this.meth1 = function () {return true;}};
  1828. // * example 1: \php.var instance_a = new class_a();
  1829. // * example 1: \php.class_exists('class_a');
  1830. // * returns 1: true
  1831. var i = '';
  1832. cls = this.window[cls]; // Note: will prevent inner classes
  1833. if (typeof cls !== 'function') {
  1834. return false;
  1835. }
  1836. for (i in cls.prototype) {
  1837. return true;
  1838. }
  1839. for (i in cls) { // If static members exist, then consider a "class"
  1840. if (i !== 'prototype') {
  1841. return true;
  1842. }
  1843. }
  1844. if (cls.toSource && cls.toSource().match(/this\./)) {
  1845. // Hackish and non-standard but can probably detect if setting
  1846. // a property (we don't want to test by instantiating as that
  1847. // may have side-effects)
  1848. return true;
  1849. }
  1850. return false;
  1851. };
  1852. php.compact = function () {
  1853. // Creates a hash containing variables and their values
  1854. //
  1855. // version: 1103.1210
  1856. // discuss at: http://phpjs.org/functions/compact
  1857. // + original by: Waldo Malqui Silva
  1858. // + tweaked by: Jack
  1859. // + input by: Brett Zamir (http://brett-zamir.me)
  1860. // + bugfixed by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
  1861. // * example 1: \php.var1 = 'Kevin'; var2 = 'van'; var3 = 'Zonneveld';
  1862. // * example 1: \php.compact('var1', 'var2', 'var3');
  1863. // * returns 1: {'var1': 'Kevin', 'var2': 'van', 'var3': 'Zonneveld'}
  1864. var matrix = {},
  1865. that = this;
  1866. var process = function (value) {
  1867. var i = 0,
  1868. l = value.length,
  1869. key_value = '';
  1870. for (i = 0; i < l; i++) {
  1871. key_value = value[i];
  1872. if (key_value instanceof Array) {
  1873. process(key_value);
  1874. } else {
  1875. if (typeof that.window[key_value] !== 'undefined') {
  1876. matrix[key_value] = that.window[key_value];
  1877. }
  1878. }
  1879. }
  1880. return true;
  1881. };
  1882. process(arguments);
  1883. return matrix;
  1884. };
  1885. php.count = function (mixed_var, mode) {
  1886. // Count the number of elements in a variable (usually an array)
  1887. //
  1888. // version: 1103.1210
  1889. // discuss at: http://phpjs.org/functions/count
  1890. // + original by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
  1891. // + input by: Waldo Malqui Silva
  1892. // + bugfixed by: Soren Hansen
  1893. // + input by: merabi
  1894. // + improved by: Brett Zamir (http://brett-zamir.me)
  1895. // + bugfixed by: Olivier Louvignes (http://mg-crea.com/)
  1896. // * example 1: \php.count([[0,0],[0,-4]], 'COUNT_RECURSIVE');
  1897. // * returns 1: 6
  1898. // * example 2: \php.count({'one' : [1,2,3,4,5]}, 'COUNT_RECURSIVE');
  1899. // * returns 2: 6
  1900. var key, cnt = 0;
  1901. if (mixed_var === null || typeof mixed_var === 'undefined') {
  1902. return 0;
  1903. } else if (mixed_var.constructor !== Array && mixed_var.constructor !== Object) {
  1904. return 1;
  1905. }
  1906. if (mode === 'COUNT_RECURSIVE') {
  1907. mode = 1;
  1908. }
  1909. if (mode != 1) {
  1910. mode = 0;
  1911. }
  1912. for (key in mixed_var) {
  1913. if (mixed_var.hasOwnProperty(key)) {
  1914. cnt++;
  1915. if (mode == 1 && mixed_var[key] && (mixed_var[key].constructor === Array || mixed_var[key].constructor === Object)) {
  1916. cnt += this.count(mixed_var[key], 1);
  1917. }
  1918. }
  1919. }
  1920. return cnt;
  1921. };
  1922. php.crc32 = function (str) {
  1923. // Calculate the crc32 polynomial of a string
  1924. //
  1925. // version: 1103.1210
  1926. // discuss at: http://phpjs.org/functions/crc32
  1927. // + original by: Webtoolkit.info (http://www.webtoolkit.info/)
  1928. // + improved by: T0bsn
  1929. // - depends on: utf8_encode
  1930. // * example 1: \php.crc32('Kevin van Zonneveld');
  1931. // * returns 1: 1249991249
  1932. str = this.utf8_encode(str);
  1933. var table = "00000000 77073096 EE0E612C 990951BA 076DC419 706AF48F E963A535 9E6495A3 0EDB8832 79DCB8A4 E0D5E91E 97D2D988 09B64C2B 7EB17CBD E7B82D07 90BF1D91 1DB71064 6AB020F2 F3B97148 84BE41DE 1ADAD47D 6DDDE4EB F4D4B551 83D385C7 136C9856 646BA8C0 FD62F97A 8A65C9EC 14015C4F 63066CD9 FA0F3D63 8D080DF5 3B6E20C8 4C69105E D56041E4 A2677172 3C03E4D1 4B04D447 D20D85FD A50AB56B 35B5A8FA 42B2986C DBBBC9D6 ACBCF940 32D86CE3 45DF5C75 DCD60DCF ABD13D59 26D930AC 51DE003A C8D75180 BFD06116 21B4F4B5 56B3C423 CFBA9599 B8BDA50F 2802B89E 5F058808 C60CD9B2 B10BE924 2F6F7C87 58684C11 C1611DAB B6662D3D 76DC4190 01DB7106 98D220BC EFD5102A 71B18589 06B6B51F 9FBFE4A5 E8B8D433 7807C9A2 0F00F934 9609A88E E10E9818 7F6A0DBB 086D3D2D 91646C97 E6635C01 6B6B51F4 1C6C6162 856530D8 F262004E 6C0695ED 1B01A57B 8208F4C1 F50FC457 65B0D9C6 12B7E950 8BBEB8EA FCB9887C 62DD1DDF 15DA2D49 8CD37CF3 FBD44C65 4DB26158 3AB551CE A3BC0074 D4BB30E2 4ADFA541 3DD895D7 A4D1C46D D3D6F4FB 4369E96A 346ED9FC AD678846 DA60B8D0 44042D73 33031DE5 AA0A4C5F DD0D7CC9 5005713C 270241AA BE0B1010 C90C2086 5768B525 206F85B3 B966D409 CE61E49F 5EDEF90E 29D9C998 B0D09822 C7D7A8B4 59B33D17 2EB40D81 B7BD5C3B C0BA6CAD EDB88320 9ABFB3B6 03B6E20C 74B1D29A EAD54739 9DD277AF 04DB2615 73DC1683 E3630B12 94643B84 0D6D6A3E 7A6A5AA8 E40ECF0B 9309FF9D 0A00AE27 7D079EB1 F00F9344 8708A3D2 1E01F268 6906C2FE F762575D 806567CB 196C3671 6E6B06E7 FED41B76 89D32BE0 10DA7A5A 67DD4ACC F9B9DF6F 8EBEEFF9 17B7BE43 60B08ED5 D6D6A3E8 A1D1937E 38D8C2C4 4FDFF252 D1BB67F1 A6BC5767 3FB506DD 48B2364B D80D2BDA AF0A1B4C 36034AF6 41047A60 DF60EFC3 A867DF55 316E8EEF 4669BE79 CB61B38C BC66831A 256FD2A0 5268E236 CC0C7795 BB0B4703 220216B9 5505262F C5BA3BBE B2BD0B28 2BB45A92 5CB36A04 C2D7FFA7 B5D0CF31 2CD99E8B 5BDEAE1D 9B64C2B0 EC63F226 756AA39C 026D930A 9C0906A9 EB0E363F 72076785 05005713 95BF4A82 E2B87A14 7BB12BAE 0CB61B38 92D28E9B E5D5BE0D 7CDCEFB7 0BDBDF21 86D3D2D4 F1D4E242 68DDB3F8 1FDA836E 81BE16CD F6B9265B 6FB077E1 18B74777 88085AE6 FF0F6A70 66063BCA 11010B5C 8F659EFF F862AE69 616BFFD3 166CCF45 A00AE278 D70DD2EE 4E048354 3903B3C2 A7672661 D06016F7 4969474D 3E6E77DB AED16A4A D9D65ADC 40DF0B66 37D83BF0 A9BCAE53 DEBB9EC5 47B2CF7F 30B5FFE9 BDBDF21C CABAC28A 53B39330 24B4A3A6 BAD03605 CDD70693 54DE5729 23D967BF B3667A2E C4614AB8 5D681B02 2A6F2B94 B40BBE37 C30C8EA1 5A05DF1B 2D02EF8D";
  1934. var crc = 0;
  1935. var x = 0;
  1936. var y = 0;
  1937. crc = crc ^ (-1);
  1938. for (var i = 0, iTop = str.length; i < iTop; i++) {
  1939. y = (crc ^ str.charCodeAt(i)) & 0xFF;
  1940. x = "0x" + table.substr(y * 9, 8);
  1941. crc = (crc >>> 8) ^ x;
  1942. }
  1943. return crc ^ (-1);
  1944. };
  1945. php.date = function (format, timestamp) {
  1946. // Format a local date/time
  1947. //
  1948. // version: 1103.1210
  1949. // discuss at: http://phpjs.org/functions/date
  1950. // + original by: Carlos R. L. Rodrigues (http://www.jsfromhell.com)
  1951. // + parts by: Peter-Paul Koch (http://www.quirksmode.org/js/beat.html)
  1952. // + improved by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
  1953. // + improved by: MeEtc (http://yass.meetcweb.com)
  1954. // + improved by: Brad Touesnard
  1955. // + improved by: Tim Wiel
  1956. // + improved by: Bryan Elliott
  1957. //
  1958. // + improved by: Brett Zamir (http://brett-zamir.me)
  1959. // + improved by: David Randall
  1960. // + input by: Brett Zamir (http://brett-zamir.me)
  1961. // + bugfixed by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
  1962. // + improved by: Brett Zamir (http://brett-zamir.me)
  1963. // + improved by: Brett Zamir (http://brett-zamir.me)
  1964. // + improved by: Theriault
  1965. // + derived from: gettimeofday
  1966. // + input by: majak
  1967. // + bugfixed by: majak
  1968. // + bugfixed by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
  1969. // + input by: Alex
  1970. // + bugfixed by: Brett Zamir (http://brett-zamir.me)
  1971. // + improved by: Theriault
  1972. // + improved by: Brett Zamir (http://brett-zamir.me)
  1973. // + improved by: Theriault
  1974. // + improved by: Thomas Beaucourt (http://www.webapp.fr)
  1975. // + improved by: JT
  1976. // + improved by: Theriault
  1977. // + improved by: Rafał Kukawski (http://blog.kukawski.pl)
  1978. // % note 1: Uses global: php_js to store the default timezone
  1979. // % note 2: Although the function potentially allows timezone info (see notes), it currently does not set
  1980. // % note 2: per a timezone specified by date_default_timezone_set(). Implementers might use
  1981. // % note 2: this.php_js.currentTimezoneOffset and this.php_js.currentTimezoneDST set by that function
  1982. // % note 2: in order to adjust the dates in this function (or our other date functions!) accordingly
  1983. // * example 1: \php.date('H:m:s \\m \\i\\s \\m\\o\\n\\t\\h', 1062402400);
  1984. // * returns 1: '09:09:40 m is month'
  1985. // * example 2: \php.date('F j, Y, g:i a', 1062462400);
  1986. // * returns 2: 'September 2, 2003, 2:26 am'
  1987. // * example 3: \php.date('Y W o', 1062462400);
  1988. // * returns 3: '2003 36 2003'
  1989. // * example 4: x = date('Y m d', (new Date()).getTime()/1000);
  1990. // * example 4: (x+'').length == 10 // 2009 01 09
  1991. // * returns 4: true
  1992. // * example 5: \php.date('W', 1104534000);
  1993. // * returns 5: '53'
  1994. // * example 6: \php.date('B t', 1104534000);
  1995. // * returns 6: '999 31'
  1996. // * example 7: \php.date('W U', 1293750000.82); // 2010-12-31
  1997. // * returns 7: '52 1293750000'
  1998. // * example 8: \php.date('W', 1293836400); // 2011-01-01
  1999. // * returns 8: '52'
  2000. // * example 9: \php.date('W Y-m-d', 1293974054); // 2011-01-02
  2001. // * returns 9: '52 2011-01-02'
  2002. var that = this,
  2003. jsdate, f, formatChr = /\\?([a-z])/gi,
  2004. formatChrCb,
  2005. // Keep this here (works, but for code commented-out
  2006. // below for file size reasons)
  2007. //, tal= [],
  2008. _pad = function (n, c) {
  2009. if ((n = n + "").length < c) {
  2010. return new Array((++c) - n.length).join("0") + n;
  2011. } else {
  2012. return n;
  2013. }
  2014. },
  2015. txt_words = ["Sun", "Mon", "Tues", "Wednes", "Thurs", "Fri", "Satur", "January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"],
  2016. txt_ordin = {
  2017. 1: "st",
  2018. 2: "nd",
  2019. 3: "rd",
  2020. 21: "st",
  2021. 22: "nd",
  2022. 23: "rd",
  2023. 31: "st"
  2024. };
  2025. formatChrCb = function (t, s) {
  2026. return f[t] ? f[t]() : s;
  2027. };
  2028. f = {
  2029. // Day
  2030. d: function () { // Day of month w/leading 0; 01..31
  2031. return _pad(f.j(), 2);
  2032. },
  2033. D: function () { // Shorthand day name; Mon...Sun
  2034. return f.l().slice(0, 3);
  2035. },
  2036. j: function () { // Day of month; 1..31
  2037. return jsdate.getDate();
  2038. },
  2039. l: function () { // Full day name; Monday...Sunday
  2040. return txt_words[f.w()] + 'day';
  2041. },
  2042. N: function () { // ISO-8601 day of week; 1[Mon]..7[Sun]
  2043. return f.w() || 7;
  2044. },
  2045. S: function () { // Ordinal suffix for day of month; st, nd, rd, th
  2046. return txt_ordin[f.j()] || 'th';
  2047. },
  2048. w: function () { // Day of week; 0[Sun]..6[Sat]
  2049. return jsdate.getDay();
  2050. },
  2051. z: function () { // Day of year; 0..365
  2052. var a = new Date(f.Y(), f.n() - 1, f.j()),
  2053. b = new Date(f.Y(), 0, 1);
  2054. return Math.round((a - b) / 864e5) + 1;
  2055. },
  2056. // Week
  2057. W: function () { // ISO-8601 week number
  2058. var a = new Date(f.Y(), f.n() - 1, f.j() - f.N() + 3),
  2059. b = new Date(a.getFullYear(), 0, 4);
  2060. return 1 + Math.round((a - b) / 864e5 / 7);
  2061. },
  2062. // Month
  2063. F: function () { // Full month name; January...December
  2064. return txt_words[6 + f.n()];
  2065. },
  2066. m: function () { // Month w/leading 0; 01...12
  2067. return _pad(f.n(), 2);
  2068. },
  2069. M: function () { // Shorthand month name; Jan...Dec
  2070. return f.F().slice(0, 3);
  2071. },
  2072. n: function () { // Month; 1...12
  2073. return jsdate.getMonth() + 1;
  2074. },
  2075. t: function () { // Days in month; 28...31
  2076. return (new Date(f.Y(), f.n(), 0)).getDate();
  2077. },
  2078. // Year
  2079. L: function () { // Is leap year?; 0 or 1
  2080. return new Date(f.Y(), 1, 29).getMonth() === 1 | 0;
  2081. },
  2082. o: function () { // ISO-8601 year
  2083. var n = f.n(),
  2084. W = f.W(),
  2085. Y = f.Y();
  2086. return Y + (n === 12 && W < 9 ? -1 : n === 1 && W > 9);
  2087. },
  2088. Y: function () { // Full year; e.g. 1980...2010
  2089. return jsdate.getFullYear();
  2090. },
  2091. y: function () { // Last two digits of year; 00...99
  2092. return (f.Y() + "").slice(-2);
  2093. },
  2094. // Time
  2095. a: function () { // am or pm
  2096. return jsdate.getHours() > 11 ? "pm" : "am";
  2097. },
  2098. A: function () { // AM or PM
  2099. return f.a().toUpperCase();
  2100. },
  2101. B: function () { // Swatch Internet time; 000..999
  2102. var H = jsdate.getUTCHours() * 36e2,
  2103. // Hours
  2104. i = jsdate.getUTCMinutes() * 60,
  2105. // Minutes
  2106. s = jsdate.getUTCSeconds(); // Seconds
  2107. return _pad(Math.floor((H + i + s + 36e2) / 86.4) % 1e3, 3);
  2108. },
  2109. g: function () { // 12-Hours; 1..12
  2110. return f.G() % 12 || 12;
  2111. },
  2112. G: function () { // 24-Hours; 0..23
  2113. return jsdate.getHours();
  2114. },
  2115. h: function () { // 12-Hours w/leading 0; 01..12
  2116. return _pad(f.g(), 2);
  2117. },
  2118. H: function () { // 24-Hours w/leading 0; 00..23
  2119. return _pad(f.G(), 2);
  2120. },
  2121. i: function () { // Minutes w/leading 0; 00..59
  2122. return _pad(jsdate.getMinutes(), 2);
  2123. },
  2124. s: function () { // Seconds w/leading 0; 00..59
  2125. return _pad(jsdate.getSeconds(), 2);
  2126. },
  2127. u: function () { // Microseconds; 000000-999000
  2128. return _pad(jsdate.getMilliseconds() * 1000, 6);
  2129. },
  2130. // Timezone
  2131. e: function () { // Timezone identifier; e.g. Atlantic/Azores, ...
  2132. // The following works, but requires inclusion of the very large
  2133. // timezone_abbreviations_list() function.
  2134. /* return this.date_default_timezone_get();
  2135. */
  2136. throw 'Not supported (see source code of date() for timezone on how to add support)';
  2137. },
  2138. I: function () { // DST observed?; 0 or 1
  2139. // Compares Jan 1 minus Jan 1 UTC to Jul 1 minus Jul 1 UTC.
  2140. // If they are not equal, then DST is observed.
  2141. var a = new Date(f.Y(), 0),
  2142. // Jan 1
  2143. c = Date.UTC(f.Y(), 0),
  2144. // Jan 1 UTC
  2145. b = new Date(f.Y(), 6),
  2146. // Jul 1
  2147. d = Date.UTC(f.Y(), 6); // Jul 1 UTC
  2148. return 0 + ((a - c) !== (b - d));
  2149. },
  2150. O: function () { // Difference to GMT in hour format; e.g. +0200
  2151. var a = jsdate.getTimezoneOffset();
  2152. return (a > 0 ? "-" : "+") + _pad(Math.abs(a / 60 * 100), 4);
  2153. },
  2154. P: function () { // Difference to GMT w/colon; e.g. +02:00
  2155. var O = f.O();
  2156. return (O.substr(0, 3) + ":" + O.substr(3, 2));
  2157. },
  2158. T: function () { // Timezone abbreviation; e.g. EST, MDT, ...
  2159. // The following works, but requires inclusion of the very
  2160. // large timezone_abbreviations_list() function.
  2161. /* var abbr = '', i = 0, os = 0, default = 0;
  2162. if (!tal.length) {
  2163. tal = that.timezone_abbreviations_list();
  2164. }
  2165. if (that.php_js && that.php_js.default_timezone) {
  2166. default = that.php_js.default_timezone;
  2167. for (abbr in tal) {
  2168. for (i=0; i < tal[abbr].length; i++) {
  2169. if (tal[abbr][i].timezone_id === default) {
  2170. return abbr.toUpperCase();
  2171. }
  2172. }
  2173. }
  2174. }
  2175. for (abbr in tal) {
  2176. for (i = 0; i < tal[abbr].length; i++) {
  2177. os = -jsdate.getTimezoneOffset() * 60;
  2178. if (tal[abbr][i].offset === os) {
  2179. return abbr.toUpperCase();
  2180. }
  2181. }
  2182. }
  2183. */
  2184. return 'UTC';
  2185. },
  2186. Z: function () { // Timezone offset in seconds (-43200...50400)
  2187. return -jsdate.getTimezoneOffset() * 60;
  2188. },
  2189. // Full Date/Time
  2190. c: function () { // ISO-8601 date.
  2191. return 'Y-m-d\\Th:i:sP'.replace(formatChr, formatChrCb);
  2192. },
  2193. r: function () { // RFC 2822
  2194. return 'D, d M Y H:i:s O'.replace(formatChr, formatChrCb);
  2195. },
  2196. U: function () { // Seconds since UNIX epoch
  2197. return jsdate.getTime() / 1000 | 0;
  2198. }
  2199. };
  2200. this.date = function (format, timestamp) {
  2201. that = this;
  2202. jsdate = ((typeof timestamp === 'undefined') ? new Date() : // Not provided
  2203. (timestamp instanceof Date) ? new Date(timestamp) : // JS Date()
  2204. new Date(timestamp * 1000) // UNIX timestamp (auto-convert to int)
  2205. );
  2206. return format.replace(formatChr, formatChrCb);
  2207. };
  2208. return this.date(format, timestamp);
  2209. };
  2210. php.dirname = function (path) {
  2211. // Returns the directory name component of the path
  2212. //
  2213. // version: 1103.1210
  2214. // discuss at: http://phpjs.org/functions/dirname
  2215. // + original by: Ozh
  2216. // + improved by: XoraX (http://www.xorax.info)
  2217. // * example 1: \php.dirname('/etc/passwd');
  2218. // * returns 1: '/etc'
  2219. // * example 2: \php.dirname('c:/Temp/x');
  2220. // * returns 2: 'c:/Temp'
  2221. // * example 3: \php.dirname('/dir/test/');
  2222. // * returns 3: '/dir'
  2223. return path.replace(/\\/g, '/').replace(/\/[^\/]*\/?$/, '');
  2224. };
  2225. php.empty = function (mixed_var) {
  2226. // !No description available for empty. @php.js developers: Please update the function summary text file.
  2227. //
  2228. // version: 1103.1210
  2229. // discuss at: http://phpjs.org/functions/empty
  2230. // + original by: Philippe Baumann
  2231. // + input by: Onno Marsman
  2232. // + bugfixed by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
  2233. // + input by: LH
  2234. // + improved by: Onno Marsman
  2235. // + improved by: Francesco
  2236. // + improved by: Marc Jansen
  2237. // + input by: Stoyan Kyosev (http://www.svest.org/)
  2238. // * example 1: \php.empty(null);
  2239. // * returns 1: true
  2240. // * example 2: \php.empty(undefined);
  2241. // * returns 2: true
  2242. // * example 3: \php.empty([]);
  2243. // * returns 3: true
  2244. // * example 4: \php.empty({});
  2245. // * returns 4: true
  2246. // * example 5: \php.empty({'aFunc' : function () { alert('humpty'); } });
  2247. // * returns 5: false
  2248. var key;
  2249. if (mixed_var === "" || mixed_var === 0 || mixed_var === "0" || mixed_var === null || mixed_var === false || typeof mixed_var === 'undefined') {
  2250. return true;
  2251. }
  2252. if (typeof mixed_var == 'object') {
  2253. for (key in mixed_var) {
  2254. return false;
  2255. }
  2256. return true;
  2257. }
  2258. return false;
  2259. };
  2260. php.end = function (arr) {
  2261. // Advances array argument's internal pointer to the last element and return it
  2262. //
  2263. // version: 1103.1210
  2264. // discuss at: http://phpjs.org/functions/end
  2265. // + original by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
  2266. // + bugfixed by: Legaev Andrey
  2267. // + revised by: J A R
  2268. // + improved by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
  2269. // + restored by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
  2270. // + revised by: Brett Zamir (http://brett-zamir.me)
  2271. // % note 1: Uses global: php_js to store the array pointer
  2272. // * example 1: \php.end({0: 'Kevin', 1: 'van', 2: 'Zonneveld'});
  2273. // * returns 1: 'Zonneveld'
  2274. // * example 2: \php.end(['Kevin', 'van', 'Zonneveld']);
  2275. // * returns 2: 'Zonneveld'
  2276. // BEGIN REDUNDANT
  2277. this.php_js = this.php_js || {};
  2278. this.php_js.pointers = this.php_js.pointers || [];
  2279. var indexOf = function (value) {
  2280. for (var i = 0, length = this.length; i < length; i++) {
  2281. if (this[i] === value) {
  2282. return i;
  2283. }
  2284. }
  2285. return -1;
  2286. };
  2287. // END REDUNDANT
  2288. var pointers = this.php_js.pointers;
  2289. if (!pointers.indexOf) {
  2290. pointers.indexOf = indexOf;
  2291. }
  2292. if (pointers.indexOf(arr) === -1) {
  2293. pointers.push(arr, 0);
  2294. }
  2295. var arrpos = pointers.indexOf(arr);
  2296. if (!(arr instanceof Array)) {
  2297. var ct = 0;
  2298. for (var k in arr) {
  2299. ct++;
  2300. var val = arr[k];
  2301. }
  2302. if (ct === 0) {
  2303. return false; // Empty
  2304. }
  2305. pointers[arrpos + 1] = ct - 1;
  2306. return val;
  2307. }
  2308. if (arr.length === 0) {
  2309. return false;
  2310. }
  2311. pointers[arrpos + 1] = arr.length - 1;
  2312. return arr[pointers[arrpos + 1]];
  2313. };
  2314. php.extract = function (arr, type, prefix) {
  2315. // Imports variables into symbol table from an array
  2316. //
  2317. // version: 1103.1210
  2318. // discuss at: http://phpjs.org/functions/extract
  2319. // + original by: Brett Zamir (http://brett-zamir.me)
  2320. // % note 1: Only works by extracting into global context (whether called in the global scope or
  2321. // % note 1: within a function); also, the EXTR_REFS flag I believe can't be made to work
  2322. // * example 1: \php.size = 'large';
  2323. // * example 1: \php.var_array = {'color' : 'blue', 'size' : 'medium', 'shape' : 'sphere'};
  2324. // * example 1: \php.extract(var_array, 'EXTR_PREFIX_SAME', 'wddx');
  2325. // * example 1: \php.color+'-'+size+'-'+shape+'-'+wddx_size;
  2326. // * returns 1: 'blue-large-sphere-medium'
  2327. if (arr instanceof Array && (type !== 'EXTR_PREFIX_ALL' && type !== 'EXTR_PREFIX_INVALID')) {
  2328. return 0;
  2329. }
  2330. var targetObj = this.window;
  2331. if (this.php_js && this.php_js.ini && this.php_js.ini['phpjs.extractTargetObj'] && this.php_js.ini['phpjs.extractTargetObj'].local_value) { // Allow designated object to be used instead of window
  2332. targetObj = this.php_js.ini['phpjs.extractTargetObj'].local_value;
  2333. }
  2334. var chng = 0;
  2335. for (var i in arr) {
  2336. var validIdent = /^[_a-zA-Z$][\w|$]*$/; // TODO: Refine regexp to allow JS 1.5+ Unicode identifiers
  2337. var prefixed = prefix + '_' + i;
  2338. try {
  2339. switch (type) {
  2340. case 'EXTR_PREFIX_SAME' || 2:
  2341. if (targetObj[i] !== undefined) {
  2342. if (prefixed.match(validIdent) !== null) {
  2343. targetObj[prefixed] = arr[i];
  2344. ++chng;
  2345. }
  2346. } else {
  2347. targetObj[i] = arr[i];
  2348. ++chng;
  2349. }
  2350. break;
  2351. case 'EXTR_SKIP' || 1:
  2352. if (targetObj[i] === undefined) {
  2353. targetObj[i] = arr[i];
  2354. ++chng;
  2355. }
  2356. break;
  2357. case 'EXTR_PREFIX_ALL' || 3:
  2358. if (prefixed.match(validIdent) !== null) {
  2359. targetObj[prefixed] = arr[i];
  2360. ++chng;
  2361. }
  2362. break;
  2363. case 'EXTR_PREFIX_INVALID' || 4:
  2364. if (i.match(validIdent) !== null) {
  2365. if (prefixed.match(validIdent) !== null) {
  2366. targetObj[prefixed] = arr[i];
  2367. ++chng;
  2368. }
  2369. } else {
  2370. targetObj[i] = arr[i];
  2371. ++chng;
  2372. }
  2373. break;
  2374. case 'EXTR_IF_EXISTS' || 6:
  2375. if (targetObj[i] !== undefined) {
  2376. targetObj[i] = arr[i];
  2377. ++chng;
  2378. }
  2379. break;
  2380. case 'EXTR_PREFIX_IF_EXISTS' || 5:
  2381. if (targetObj[i] !== undefined && prefixed.match(validIdent) !== null) {
  2382. targetObj[prefixed] = arr[i];
  2383. ++chng;
  2384. }
  2385. break;
  2386. case 'EXTR_REFS' || 256:
  2387. throw 'The EXTR_REFS type will not work in JavaScript';
  2388. case 'EXTR_OVERWRITE' || 0:
  2389. // Fall-through
  2390. default:
  2391. targetObj[i] = arr[i];
  2392. ++chng;
  2393. break;
  2394. }
  2395. } catch (e) { // Just won't increment for problem assignments
  2396. }
  2397. }
  2398. return chng;
  2399. };
  2400. php.floor = function (value) {
  2401. // Returns the next lowest integer value from the number
  2402. //
  2403. // version: 1103.1210
  2404. // discuss at: http://phpjs.org/functions/floor
  2405. // + original by: Onno Marsman
  2406. // * example 1: \php.floor(8723321.4);
  2407. // * returns 1: 8723321
  2408. return Math.floor(value);
  2409. };
  2410. php.get_class = function (obj) {
  2411. // Retrieves the class name
  2412. //
  2413. // version: 1103.1210
  2414. // discuss at: http://phpjs.org/functions/get_class
  2415. // + original by: Ates Goral (http://magnetiq.com)
  2416. // + improved by: David James
  2417. // * example 1: \php.get_class(new (function MyClass() {}));
  2418. // * returns 1: "MyClass"
  2419. // * example 2: \php.get_class({});
  2420. // * returns 2: "Object"
  2421. // * example 3: \php.get_class([]);
  2422. // * returns 3: false
  2423. // * example 4: \php.get_class(42);
  2424. // * returns 4: false
  2425. // * example 5: \php.get_class(window);
  2426. // * returns 5: false
  2427. // * example 6: \php.get_class(function MyFunction() {});
  2428. // * returns 6: false
  2429. if (obj instanceof Object && !(obj instanceof Array) && !(obj instanceof Function) && obj.constructor && obj != this.window) {
  2430. var arr = obj.constructor.toString().match(/function\s*(\w+)/);
  2431. if (arr && arr.length == 2) {
  2432. return arr[1];
  2433. }
  2434. }
  2435. return false;
  2436. };
  2437. php.get_html_translation_table = function (table, quote_style) {
  2438. // Returns the internal translation table used by htmlspecialchars and htmlentities
  2439. //
  2440. // version: 1103.1210
  2441. // discuss at: http://phpjs.org/functions/get_html_translation_table
  2442. // + original by: Philip Peterson
  2443. // + revised by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
  2444. // + bugfixed by: noname
  2445. // + bugfixed by: Alex
  2446. // + bugfixed by: Marco
  2447. // + bugfixed by: madipta
  2448. // + improved by: KELAN
  2449. // + improved by: Brett Zamir (http://brett-zamir.me)
  2450. // + bugfixed by: Brett Zamir (http://brett-zamir.me)
  2451. // + input by: Frank Forte
  2452. // + bugfixed by: T.Wild
  2453. // + input by: Ratheous
  2454. // % note: It has been decided that we're not going to add global
  2455. // % note: dependencies to php.js, meaning the constants are not
  2456. // % note: real constants, but strings instead. Integers are also supported if someone
  2457. // % note: chooses to create the constants themselves.
  2458. // * example 1: \php.get_html_translation_table('HTML_SPECIALCHARS');
  2459. // * returns 1: {'"': '&quot;', '&': '&amp;', '<': '&lt;', '>': '&gt;'}
  2460. var entities = {},
  2461. hash_map = {},
  2462. decimal = 0,
  2463. symbol = '';
  2464. var constMappingTable = {},
  2465. constMappingQuoteStyle = {};
  2466. var useTable = {},
  2467. useQuoteStyle = {};
  2468. // Translate arguments
  2469. constMappingTable[0] = 'HTML_SPECIALCHARS';
  2470. constMappingTable[1] = 'HTML_ENTITIES';
  2471. constMappingQuoteStyle[0] = 'ENT_NOQUOTES';
  2472. constMappingQuoteStyle[2] = 'ENT_COMPAT';
  2473. constMappingQuoteStyle[3] = 'ENT_QUOTES';
  2474. useTable = !isNaN(table) ? constMappingTable[table] : table ? table.toUpperCase() : 'HTML_SPECIALCHARS';
  2475. useQuoteStyle = !isNaN(quote_style) ? constMappingQuoteStyle[quote_style] : quote_style ? quote_style.toUpperCase() : 'ENT_COMPAT';
  2476. if (useTable !== 'HTML_SPECIALCHARS' && useTable !== 'HTML_ENTITIES') {
  2477. throw new Error("Table: " + useTable + ' not supported');
  2478. // return false;
  2479. }
  2480. entities['38'] = '&amp;';
  2481. if (useTable === 'HTML_ENTITIES') {
  2482. entities['160'] = '&nbsp;';
  2483. entities['161'] = '&iexcl;';
  2484. entities['162'] = '&cent;';
  2485. entities['163'] = '&pound;';
  2486. entities['164'] = '&curren;';
  2487. entities['165'] = '&yen;';
  2488. entities['166'] = '&brvbar;';
  2489. entities['167'] = '&sect;';
  2490. entities['168'] = '&uml;';
  2491. entities['169'] = '&copy;';
  2492. entities['170'] = '&ordf;';
  2493. entities['171'] = '&laquo;';
  2494. entities['172'] = '&not;';
  2495. entities['173'] = '&shy;';
  2496. entities['174'] = '&reg;';
  2497. entities['175'] = '&macr;';
  2498. entities['176'] = '&deg;';
  2499. entities['177'] = '&plusmn;';
  2500. entities['178'] = '&sup2;';
  2501. entities['179'] = '&sup3;';
  2502. entities['180'] = '&acute;';
  2503. entities['181'] = '&micro;';
  2504. entities['182'] = '&para;';
  2505. entities['183'] = '&middot;';
  2506. entities['184'] = '&cedil;';
  2507. entities['185'] = '&sup1;';
  2508. entities['186'] = '&ordm;';
  2509. entities['187'] = '&raquo;';
  2510. entities['188'] = '&frac14;';
  2511. entities['189'] = '&frac12;';
  2512. entities['190'] = '&frac34;';
  2513. entities['191'] = '&iquest;';
  2514. entities['192'] = '&Agrave;';
  2515. entities['193'] = '&Aacute;';
  2516. entities['194'] = '&Acirc;';
  2517. entities['195'] = '&Atilde;';
  2518. entities['196'] = '&Auml;';
  2519. entities['197'] = '&Aring;';
  2520. entities['198'] = '&AElig;';
  2521. entities['199'] = '&Ccedil;';
  2522. entities['200'] = '&Egrave;';
  2523. entities['201'] = '&Eacute;';
  2524. entities['202'] = '&Ecirc;';
  2525. entities['203'] = '&Euml;';
  2526. entities['204'] = '&Igrave;';
  2527. entities['205'] = '&Iacute;';
  2528. entities['206'] = '&Icirc;';
  2529. entities['207'] = '&Iuml;';
  2530. entities['208'] = '&ETH;';
  2531. entities['209'] = '&Ntilde;';
  2532. entities['210'] = '&Ograve;';
  2533. entities['211'] = '&Oacute;';
  2534. entities['212'] = '&Ocirc;';
  2535. entities['213'] = '&Otilde;';
  2536. entities['214'] = '&Ouml;';
  2537. entities['215'] = '&times;';
  2538. entities['216'] = '&Oslash;';
  2539. entities['217'] = '&Ugrave;';
  2540. entities['218'] = '&Uacute;';
  2541. entities['219'] = '&Ucirc;';
  2542. entities['220'] = '&Uuml;';
  2543. entities['221'] = '&Yacute;';
  2544. entities['222'] = '&THORN;';
  2545. entities['223'] = '&szlig;';
  2546. entities['224'] = '&agrave;';
  2547. entities['225'] = '&aacute;';
  2548. entities['226'] = '&acirc;';
  2549. entities['227'] = '&atilde;';
  2550. entities['228'] = '&auml;';
  2551. entities['229'] = '&aring;';
  2552. entities['230'] = '&aelig;';
  2553. entities['231'] = '&ccedil;';
  2554. entities['232'] = '&egrave;';
  2555. entities['233'] = '&eacute;';
  2556. entities['234'] = '&ecirc;';
  2557. entities['235'] = '&euml;';
  2558. entities['236'] = '&igrave;';
  2559. entities['237'] = '&iacute;';
  2560. entities['238'] = '&icirc;';
  2561. entities['239'] = '&iuml;';
  2562. entities['240'] = '&eth;';
  2563. entities['241'] = '&ntilde;';
  2564. entities['242'] = '&ograve;';
  2565. entities['243'] = '&oacute;';
  2566. entities['244'] = '&ocirc;';
  2567. entities['245'] = '&otilde;';
  2568. entities['246'] = '&ouml;';
  2569. entities['247'] = '&divide;';
  2570. entities['248'] = '&oslash;';
  2571. entities['249'] = '&ugrave;';
  2572. entities['250'] = '&uacute;';
  2573. entities['251'] = '&ucirc;';
  2574. entities['252'] = '&uuml;';
  2575. entities['253'] = '&yacute;';
  2576. entities['254'] = '&thorn;';
  2577. entities['255'] = '&yuml;';
  2578. }
  2579. if (useQuoteStyle !== 'ENT_NOQUOTES') {
  2580. entities['34'] = '&quot;';
  2581. }
  2582. if (useQuoteStyle === 'ENT_QUOTES') {
  2583. entities['39'] = '&#39;';
  2584. }
  2585. entities['60'] = '&lt;';
  2586. entities['62'] = '&gt;';
  2587. // ascii decimals to real symbols
  2588. for (decimal in entities) {
  2589. symbol = String.fromCharCode(decimal);
  2590. hash_map[symbol] = entities[decimal];
  2591. }
  2592. return hash_map;
  2593. };
  2594. php.gettype = function (mixed_var) {
  2595. // Returns the type of the variable
  2596. //
  2597. // version: 1103.1210
  2598. // discuss at: http://phpjs.org/functions/gettype
  2599. // + original by: Paulo Freitas
  2600. // + improved by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
  2601. // + improved by: Douglas Crockford (http://javascript.crockford.com)
  2602. // + input by: KELAN
  2603. // + improved by: Brett Zamir (http://brett-zamir.me)
  2604. // - depends on: is_float
  2605. // % note 1: 1.0 is simplified to 1 before it can be accessed by the function, this makes
  2606. // % note 1: it different from the PHP implementation. We can't fix this unfortunately.
  2607. // * example 1: \php.gettype(1);
  2608. // * returns 1: 'integer'
  2609. // * example 2: \php.gettype(undefined);
  2610. // * returns 2: 'undefined'
  2611. // * example 3: \php.gettype({0: 'Kevin van Zonneveld'});
  2612. // * returns 3: 'array'
  2613. // * example 4: \php.gettype('foo');
  2614. // * returns 4: 'string'
  2615. // * example 5: \php.gettype({0: function () {return false;}});
  2616. // * returns 5: 'array'
  2617. var s = typeof mixed_var,
  2618. name;
  2619. var getFuncName = function (fn) {
  2620. var name = (/\W*function\s+([\w\$]+)\s*\(/).exec(fn);
  2621. if (!name) {
  2622. return '(Anonymous)';
  2623. }
  2624. return name[1];
  2625. };
  2626. if (s === 'object') {
  2627. if (mixed_var !== null) { // From: http://javascript.crockford.com/remedial.html
  2628. if (typeof mixed_var.length === 'number' && !(mixed_var.propertyIsEnumerable('length')) && typeof mixed_var.splice === 'function') {
  2629. s = 'array';
  2630. } else if (mixed_var.constructor && getFuncName(mixed_var.constructor)) {
  2631. name = getFuncName(mixed_var.constructor);
  2632. if (name === 'Date') {
  2633. s = 'date'; // not in PHP
  2634. } else if (name === 'RegExp') {
  2635. s = 'regexp'; // not in PHP
  2636. } else if (name === 'PHPJS_Resource') { // Check against our own resource constructor
  2637. s = 'resource';
  2638. }
  2639. }
  2640. } else {
  2641. s = 'null';
  2642. }
  2643. } else if (s === 'number') {
  2644. s = this.is_float(mixed_var) ? 'double' : 'integer';
  2645. }
  2646. return s;
  2647. };
  2648. php.html_entity_decode = function (string, quote_style) {
  2649. // Convert all HTML entities to their applicable characters
  2650. //
  2651. // version: 1103.1210
  2652. // discuss at: http://phpjs.org/functions/html_entity_decode
  2653. // + original by: john (http://www.jd-tech.net)
  2654. // + input by: ger
  2655. // + improved by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
  2656. // + revised by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
  2657. // + bugfixed by: Onno Marsman
  2658. // + improved by: marc andreu
  2659. // + revised by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
  2660. // + input by: Ratheous
  2661. // + bugfixed by: Brett Zamir (http://brett-zamir.me)
  2662. // + input by: Nick Kolosov (http://sammy.ru)
  2663. // + bugfixed by: Fox
  2664. // - depends on: get_html_translation_table
  2665. // * example 1: \php.html_entity_decode('Kevin &amp; van Zonneveld');
  2666. // * returns 1: 'Kevin & van Zonneveld'
  2667. // * example 2: \php.html_entity_decode('&amp;lt;');
  2668. // * returns 2: '&lt;'
  2669. var hash_map = {},
  2670. symbol = '',
  2671. tmp_str = '',
  2672. entity = '';
  2673. tmp_str = string.toString();
  2674. if (false === (hash_map = this.get_html_translation_table('HTML_ENTITIES', quote_style))) {
  2675. return false;
  2676. }
  2677. // fix &amp; problem
  2678. // http://phpjs.org/functions/get_html_translation_table:416#comment_97660
  2679. delete(hash_map['&']);
  2680. hash_map['&'] = '&amp;';
  2681. for (symbol in hash_map) {
  2682. entity = hash_map[symbol];
  2683. tmp_str = tmp_str.split(entity).join(symbol);
  2684. }
  2685. tmp_str = tmp_str.split('&#039;').join("'");
  2686. return tmp_str;
  2687. };
  2688. php.htmlentities = function (string, quote_style) {
  2689. // Convert all applicable characters to HTML entities
  2690. //
  2691. // version: 1103.1210
  2692. // discuss at: http://phpjs.org/functions/htmlentities
  2693. // + original by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
  2694. // + revised by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
  2695. // + improved by: nobbler
  2696. // + tweaked by: Jack
  2697. // + bugfixed by: Onno Marsman
  2698. // + revised by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
  2699. // + bugfixed by: Brett Zamir (http://brett-zamir.me)
  2700. // + input by: Ratheous
  2701. // - depends on: get_html_translation_table
  2702. // * example 1: \php.htmlentities('Kevin & van Zonneveld');
  2703. // * returns 1: 'Kevin &amp; van Zonneveld'
  2704. // * example 2: \php.htmlentities("foo'bar","ENT_QUOTES");
  2705. // * returns 2: 'foo&#039;bar'
  2706. var hash_map = {},
  2707. symbol = '',
  2708. tmp_str = '',
  2709. entity = '';
  2710. tmp_str = string.toString();
  2711. if (false === (hash_map = this.get_html_translation_table('HTML_ENTITIES', quote_style))) {
  2712. return false;
  2713. }
  2714. hash_map["'"] = '&#039;';
  2715. for (symbol in hash_map) {
  2716. entity = hash_map[symbol];
  2717. tmp_str = tmp_str.split(symbol).join(entity);
  2718. }
  2719. return tmp_str;
  2720. };
  2721. php.htmlspecialchars = function (string, quote_style, charset, double_encode) {
  2722. // Convert special characters to HTML entities
  2723. //
  2724. // version: 1103.1210
  2725. // discuss at: http://phpjs.org/functions/htmlspecialchars
  2726. // + original by: Mirek Slugen
  2727. // + improved by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
  2728. // + bugfixed by: Nathan
  2729. // + bugfixed by: Arno
  2730. // + revised by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
  2731. // + bugfixed by: Brett Zamir (http://brett-zamir.me)
  2732. // + input by: Ratheous
  2733. // + input by: Mailfaker (http://www.weedem.fr/)
  2734. // + reimplemented by: Brett Zamir (http://brett-zamir.me)
  2735. // + input by: felix
  2736. // + bugfixed by: Brett Zamir (http://brett-zamir.me)
  2737. // % note 1: charset argument not supported
  2738. // * example 1: \php.htmlspecialchars("<a href='test'>Test</a>", 'ENT_QUOTES');
  2739. // * returns 1: '&lt;a href=&#039;test&#039;&gt;Test&lt;/a&gt;'
  2740. // * example 2: \php.htmlspecialchars("ab\"c'd", ['ENT_NOQUOTES', 'ENT_QUOTES']);
  2741. // * returns 2: 'ab"c&#039;d'
  2742. // * example 3: \php.htmlspecialchars("my "&entity;" is still here", null, null, false);
  2743. // * returns 3: 'my &quot;&entity;&quot; is still here'
  2744. var optTemp = 0,
  2745. i = 0,
  2746. noquotes = false;
  2747. if (typeof quote_style === 'undefined' || quote_style === null) {
  2748. quote_style = 2;
  2749. }
  2750. if (string === null) {
  2751. string = "";
  2752. }
  2753. string = string.toString();
  2754. if (double_encode !== false) { // Put this first to avoid double-encoding
  2755. string = string.replace(/&/g, '&amp;');
  2756. }
  2757. string = string.replace(/</g, '&lt;').replace(/>/g, '&gt;');
  2758. var OPTS = {
  2759. 'ENT_NOQUOTES': 0,
  2760. 'ENT_HTML_QUOTE_SINGLE': 1,
  2761. 'ENT_HTML_QUOTE_DOUBLE': 2,
  2762. 'ENT_COMPAT': 2,
  2763. 'ENT_QUOTES': 3,
  2764. 'ENT_IGNORE': 4
  2765. };
  2766. if (quote_style === 0) {
  2767. noquotes = true;
  2768. }
  2769. if (typeof quote_style !== 'number') { // Allow for a single string or an array of string flags
  2770. quote_style = [].concat(quote_style);
  2771. for (i = 0; i < quote_style.length; i++) {
  2772. // Resolve string input to bitwise e.g. 'PATHINFO_EXTENSION' becomes 4
  2773. if (OPTS[quote_style[i]] === 0) {
  2774. noquotes = true;
  2775. } else if (OPTS[quote_style[i]]) {
  2776. optTemp = optTemp | OPTS[quote_style[i]];
  2777. }
  2778. }
  2779. quote_style = optTemp;
  2780. }
  2781. if (quote_style & OPTS.ENT_HTML_QUOTE_SINGLE) {
  2782. string = string.replace(/'/g, '&#039;');
  2783. }
  2784. if (!noquotes) {
  2785. string = string.replace(/"/g, '&quot;');
  2786. }
  2787. return string;
  2788. };
  2789. php.htmlspecialchars_decode = function (string, quote_style) {
  2790. // Convert special HTML entities back to characters
  2791. //
  2792. // version: 1103.1210
  2793. // discuss at: http://phpjs.org/functions/htmlspecialchars_decode
  2794. // + original by: Mirek Slugen
  2795. // + improved by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
  2796. // + bugfixed by: Mateusz "loonquawl" Zalega
  2797. // + input by: ReverseSyntax
  2798. // + input by: Slawomir Kaniecki
  2799. // + input by: Scott Cariss
  2800. // + input by: Francois
  2801. // + bugfixed by: Onno Marsman
  2802. // + revised by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
  2803. // + bugfixed by: Brett Zamir (http://brett-zamir.me)
  2804. // + input by: Ratheous
  2805. // + input by: Mailfaker (http://www.weedem.fr/)
  2806. // + reimplemented by: Brett Zamir (http://brett-zamir.me)
  2807. // + bugfixed by: Brett Zamir (http://brett-zamir.me)
  2808. // * example 1: \php.htmlspecialchars_decode("<p>this -&gt; &quot;</p>", 'ENT_NOQUOTES');
  2809. // * returns 1: '<p>this -> &quot;</p>'
  2810. // * example 2: \php.htmlspecialchars_decode("&amp;quot;");
  2811. // * returns 2: '&quot;'
  2812. var optTemp = 0,
  2813. i = 0,
  2814. noquotes = false;
  2815. if (typeof quote_style === 'undefined') {
  2816. quote_style = 2;
  2817. }
  2818. string = string.toString().replace(/&lt;/g, '<').replace(/&gt;/g, '>');
  2819. var OPTS = {
  2820. 'ENT_NOQUOTES': 0,
  2821. 'ENT_HTML_QUOTE_SINGLE': 1,
  2822. 'ENT_HTML_QUOTE_DOUBLE': 2,
  2823. 'ENT_COMPAT': 2,
  2824. 'ENT_QUOTES': 3,
  2825. 'ENT_IGNORE': 4
  2826. };
  2827. if (quote_style === 0) {
  2828. noquotes = true;
  2829. }
  2830. if (typeof quote_style !== 'number') { // Allow for a single string or an array of string flags
  2831. quote_style = [].concat(quote_style);
  2832. for (i = 0; i < quote_style.length; i++) {
  2833. // Resolve string input to bitwise e.g. 'PATHINFO_EXTENSION' becomes 4
  2834. if (OPTS[quote_style[i]] === 0) {
  2835. noquotes = true;
  2836. } else if (OPTS[quote_style[i]]) {
  2837. optTemp = optTemp | OPTS[quote_style[i]];
  2838. }
  2839. }
  2840. quote_style = optTemp;
  2841. }
  2842. if (quote_style & OPTS.ENT_HTML_QUOTE_SINGLE) {
  2843. string = string.replace(/&#0*39;/g, "'"); // PHP doesn't currently escape if more than one 0, but it should
  2844. // string = string.replace(/&apos;|&#x0*27;/g, "'"); // This would also be useful here, but not a part of PHP
  2845. }
  2846. if (!noquotes) {
  2847. string = string.replace(/&quot;/g, '"');
  2848. }
  2849. // Put this in last place to avoid escape being double-decoded
  2850. string = string.replace(/&amp;/g, '&');
  2851. return string;
  2852. };
  2853. php.http_build_query = function (formdata, numeric_prefix, arg_separator) {
  2854. // Generates a form-encoded query string from an associative array or object.
  2855. //
  2856. // version: 1103.1210
  2857. // discuss at: http://phpjs.org/functions/http_build_query
  2858. // + original by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
  2859. // + improved by: Legaev Andrey
  2860. // + improved by: Michael White (http://getsprink.com)
  2861. // + improved by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
  2862. // + improved by: Brett Zamir (http://brett-zamir.me)
  2863. // + revised by: stag019
  2864. // + input by: Dreamer
  2865. // + bugfixed by: Brett Zamir (http://brett-zamir.me)
  2866. // - depends on: urlencode
  2867. // * example 1: \php.http_build_query({foo: 'bar', php: 'hypertext processor', baz: 'boom', cow: 'milk'}, '', '&amp;');
  2868. // * returns 1: 'foo=bar&amp;php=hypertext+processor&amp;baz=boom&amp;cow=milk'
  2869. // * example 2: \php.http_build_query({'php': 'hypertext processor', 0: 'foo', 1: 'bar', 2: 'baz', 3: 'boom', 'cow': 'milk'}, 'myvar_');
  2870. // * returns 2: 'php=hypertext+processor&myvar_0=foo&myvar_1=bar&myvar_2=baz&myvar_3=boom&cow=milk'
  2871. var value, key, tmp = [],
  2872. that = this;
  2873. var _http_build_query_helper = function (key, val, arg_separator) {
  2874. var k, tmp = [];
  2875. if (val === true) {
  2876. val = "1";
  2877. } else if (val === false) {
  2878. val = "0";
  2879. }
  2880. if (val !== null && typeof(val) === "object") {
  2881. for (k in val) {
  2882. if (val[k] !== null) {
  2883. tmp.push(_http_build_query_helper(key + "[" + k + "]", val[k], arg_separator));
  2884. }
  2885. }
  2886. return tmp.join(arg_separator);
  2887. } else if (typeof(val) !== "function") {
  2888. return that.urlencode(key) + "=" + that.urlencode(val);
  2889. } else {
  2890. throw new Error('There was an error processing for http_build_query().');
  2891. }
  2892. };
  2893. if (!arg_separator) {
  2894. arg_separator = "&";
  2895. }
  2896. for (key in formdata) {
  2897. value = formdata[key];
  2898. if (numeric_prefix && !isNaN(key)) {
  2899. key = String(numeric_prefix) + key;
  2900. }
  2901. tmp.push(_http_build_query_helper(key, value, arg_separator));
  2902. }
  2903. return tmp.join(arg_separator);
  2904. };
  2905. php.in_array = function (needle, haystack, argStrict) {
  2906. // Checks if the given value exists in the array
  2907. //
  2908. // version: 1103.1210
  2909. // discuss at: http://phpjs.org/functions/in_array
  2910. // + original by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
  2911. // + improved by: vlado houba
  2912. // + input by: Billy
  2913. // + bugfixed by: Brett Zamir (http://brett-zamir.me)
  2914. // * example 1: \php.in_array('van', ['Kevin', 'van', 'Zonneveld']);
  2915. // * returns 1: true
  2916. // * example 2: \php.in_array('vlado', {0: 'Kevin', vlado: 'van', 1: 'Zonneveld'});
  2917. // * returns 2: false
  2918. // * example 3: \php.in_array(1, ['1', '2', '3']);
  2919. // * returns 3: true
  2920. // * example 3: \php.in_array(1, ['1', '2', '3'], false);
  2921. // * returns 3: true
  2922. // * example 4: \php.in_array(1, ['1', '2', '3'], true);
  2923. // * returns 4: false
  2924. var key = '',
  2925. strict = !! argStrict;
  2926. if (strict) {
  2927. for (key in haystack) {
  2928. if (haystack[key] === needle) {
  2929. return true;
  2930. }
  2931. }
  2932. } else {
  2933. for (key in haystack) {
  2934. if (haystack[key] == needle) {
  2935. return true;
  2936. }
  2937. }
  2938. }
  2939. return false;
  2940. };
  2941. php.intval = function (mixed_var, base) {
  2942. // Get the integer value of a variable using the optional base for the conversion
  2943. //
  2944. // version: 1103.1210
  2945. // discuss at: http://phpjs.org/functions/intval
  2946. // + original by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
  2947. // + improved by: stensi
  2948. // + bugfixed by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
  2949. // + input by: Matteo
  2950. // + bugfixed by: Brett Zamir (http://brett-zamir.me)
  2951. // * example 1: \php.intval('Kevin van Zonneveld');
  2952. // * returns 1: 0
  2953. // * example 2: \php.intval(4.2);
  2954. // * returns 2: 4
  2955. // * example 3: \php.intval(42, 8);
  2956. // * returns 3: 42
  2957. // * example 4: \php.intval('09');
  2958. // * returns 4: 9
  2959. // * example 5: \php.intval('1e', 16);
  2960. // * returns 5: 30
  2961. var tmp;
  2962. var type = typeof(mixed_var);
  2963. if (type === 'boolean') {
  2964. return (mixed_var) ? 1 : 0;
  2965. } else if (type === 'string') {
  2966. tmp = parseInt(mixed_var, base || 10);
  2967. return (isNaN(tmp) || !isFinite(tmp)) ? 0 : tmp;
  2968. } else if (type === 'number' && isFinite(mixed_var)) {
  2969. return Math.floor(mixed_var);
  2970. } else {
  2971. return 0;
  2972. }
  2973. };
  2974. php.is_callable = function (v, syntax_only, callable_name) {
  2975. // Returns true if var is callable.
  2976. //
  2977. // version: 1103.1210
  2978. // discuss at: http://phpjs.org/functions/is_callable
  2979. // + original by: Brett Zamir (http://brett-zamir.me)
  2980. // % note 1: The variable callable_name cannot work as a string variable passed by reference as in PHP (since JavaScript does not support passing strings by reference), but instead will take the name of a global variable and set that instead
  2981. // % note 2: When used on an object, depends on a constructor property being kept on the object prototype
  2982. // * example 1: \php.is_callable('is_callable');
  2983. // * returns 1: true
  2984. // * example 2: \php.is_callable('bogusFunction', true);
  2985. // * returns 2:true // gives true because does not do strict checking
  2986. // * example 3: \php.function SomeClass () {}
  2987. // * example 3: SomeClass.prototype.someMethod = function (){};
  2988. // * example 3: \php.var testObj = new SomeClass();
  2989. // * example 3: \php.is_callable([testObj, 'someMethod'], true, 'myVar');
  2990. // * example 3: \php.alert(myVar); // 'SomeClass::someMethod'
  2991. var name = '',
  2992. obj = {},
  2993. method = '';
  2994. var getFuncName = function (fn) {
  2995. var name = (/\W*function\s+([\w\$]+)\s*\(/).exec(fn);
  2996. if (!name) {
  2997. return '(Anonymous)';
  2998. }
  2999. return name[1];
  3000. };
  3001. if (typeof v === 'string') {
  3002. obj = this.window;
  3003. method = v;
  3004. name = v;
  3005. } else if (v instanceof Array && v.length === 2 && typeof v[0] === 'object' && typeof v[1] === 'string') {
  3006. obj = v[0];
  3007. method = v[1];
  3008. name = (obj.constructor && getFuncName(obj.constructor)) + '::' + method;
  3009. } else {
  3010. return false;
  3011. }
  3012. if (syntax_only || typeof obj[method] === 'function') {
  3013. if (callable_name) {
  3014. this.window[callable_name] = name;
  3015. }
  3016. return true;
  3017. }
  3018. return false;
  3019. };
  3020. php.is_float = function (mixed_var) {
  3021. // Returns true if variable is float point
  3022. //
  3023. // version: 1103.1210
  3024. // discuss at: http://phpjs.org/functions/is_float
  3025. // + original by: Paulo Freitas
  3026. // + bugfixed by: Brett Zamir (http://brett-zamir.me)
  3027. // + improved by: WebDevHobo (http://webdevhobo.blogspot.com/)
  3028. // % note 1: 1.0 is simplified to 1 before it can be accessed by the function, this makes
  3029. // % note 1: it different from the PHP implementation. We can't fix this unfortunately.
  3030. // * example 1: \php.is_float(186.31);
  3031. // * returns 1: true
  3032. if (typeof mixed_var !== 'number') {
  3033. return false;
  3034. }
  3035. return !!(mixed_var % 1);
  3036. };
  3037. php.is_int = function (mixed_var) {
  3038. // !No description available for is_int. @php.js developers: Please update the function summary text file.
  3039. //
  3040. // version: 1103.1210
  3041. // discuss at: http://phpjs.org/functions/is_int
  3042. // + original by: Alex
  3043. // + improved by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
  3044. // + revised by: Matt Bradley
  3045. // + bugfixed by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
  3046. // + improved by: WebDevHobo (http://webdevhobo.blogspot.com/)
  3047. // % note 1: 1.0 is simplified to 1 before it can be accessed by the function, this makes
  3048. // % note 1: it different from the PHP implementation. We can't fix this unfortunately.
  3049. // * example 1: \php.is_int(23)
  3050. // * returns 1: true
  3051. // * example 2: \php.is_int('23')
  3052. // * returns 2: false
  3053. // * example 3: \php.is_int(23.5)
  3054. // * returns 3: false
  3055. // * example 4: \php.is_int(true)
  3056. // * returns 4: false
  3057. if (typeof mixed_var !== 'number') {
  3058. return false;
  3059. }
  3060. return !(mixed_var % 1);
  3061. };
  3062. php.krsort = function (inputArr, sort_flags) {
  3063. // Sort an array by key value in reverse order
  3064. //
  3065. // version: 1103.1210
  3066. // discuss at: http://phpjs.org/functions/krsort
  3067. // + original by: GeekFG (http://geekfg.blogspot.com)
  3068. // + improved by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
  3069. // + improved by: Brett Zamir (http://brett-zamir.me)
  3070. // % note 1: The examples are correct, this is a new way
  3071. // % note 2: This function deviates from PHP in returning a copy of the array instead
  3072. // % note 2: of acting by reference and returning true; this was necessary because
  3073. // % note 2: IE does not allow deleting and re-adding of properties without caching
  3074. // % note 2: of property position; you can set the ini of "phpjs.strictForIn" to true to
  3075. // % note 2: get the PHP behavior, but use this only if you are in an environment
  3076. // % note 2: such as Firefox extensions where for-in iteration order is fixed and true
  3077. // % note 2: property deletion is supported. Note that we intend to implement the PHP
  3078. // % note 2: behavior by default if IE ever does allow it; only gives shallow copy since
  3079. // % note 2: is by reference in PHP anyways
  3080. // % note 3: Since JS objects' keys are always strings, and (the
  3081. // % note 3: default) SORT_REGULAR flag distinguishes by key type,
  3082. // % note 3: if the content is a numeric string, we treat the
  3083. // % note 3: "original type" as numeric.
  3084. // - depends on: i18n_loc_get_default
  3085. // * example 1: \php.data = {d: 'lemon', a: 'orange', b: 'banana', c: 'apple'};
  3086. // * example 1: \php.data = krsort(data);
  3087. // * results 1: {d: 'lemon', c: 'apple', b: 'banana', a: 'orange'}
  3088. // * example 2: \php.ini_set('phpjs.strictForIn', true);
  3089. // * example 2: \php.data = {2: 'van', 3: 'Zonneveld', 1: 'Kevin'};
  3090. // * example 2: \php.krsort(data);
  3091. // * results 2: data == {3: 'Kevin', 2: 'van', 1: 'Zonneveld'}
  3092. // * returns 2: true
  3093. var tmp_arr = {},
  3094. keys = [],
  3095. sorter, i, k, that = this,
  3096. strictForIn = false,
  3097. populateArr = {};
  3098. switch (sort_flags) {
  3099. case 'SORT_STRING':
  3100. // compare items as strings
  3101. sorter = function (a, b) {
  3102. return that.strnatcmp(b, a);
  3103. };
  3104. break;
  3105. case 'SORT_LOCALE_STRING':
  3106. // compare items as strings, based on the current locale (set with i18n_loc_set_default() as of PHP6)
  3107. var loc = this.i18n_loc_get_default();
  3108. sorter = this.php_js.i18nLocales[loc].sorting;
  3109. break;
  3110. case 'SORT_NUMERIC':
  3111. // compare items numerically
  3112. sorter = function (a, b) {
  3113. return (b - a);
  3114. };
  3115. break;
  3116. case 'SORT_REGULAR':
  3117. // compare items normally (don't change types)
  3118. default:
  3119. sorter = function (b, a) {
  3120. var aFloat = parseFloat(a),
  3121. bFloat = parseFloat(b),
  3122. aNumeric = aFloat + '' === a,
  3123. bNumeric = bFloat + '' === b;
  3124. if (aNumeric && bNumeric) {
  3125. return aFloat > bFloat ? 1 : aFloat < bFloat ? -1 : 0;
  3126. } else if (aNumeric && !bNumeric) {
  3127. return 1;
  3128. } else if (!aNumeric && bNumeric) {
  3129. return -1;
  3130. }
  3131. return a > b ? 1 : a < b ? -1 : 0;
  3132. };
  3133. break;
  3134. }
  3135. // Make a list of key names
  3136. for (k in inputArr) {
  3137. if (inputArr.hasOwnProperty(k)) {
  3138. keys.push(k);
  3139. }
  3140. }
  3141. keys.sort(sorter);
  3142. // BEGIN REDUNDANT
  3143. this.php_js = this.php_js || {};
  3144. this.php_js.ini = this.php_js.ini || {};
  3145. // END REDUNDANT
  3146. strictForIn = this.php_js.ini['phpjs.strictForIn'] && this.php_js.ini['phpjs.strictForIn'].local_value && this.php_js.ini['phpjs.strictForIn'].local_value !== 'off';
  3147. populateArr = strictForIn ? inputArr : populateArr;
  3148. // Rebuild array with sorted key names
  3149. for (i = 0; i < keys.length; i++) {
  3150. k = keys[i];
  3151. tmp_arr[k] = inputArr[k];
  3152. if (strictForIn) {
  3153. delete inputArr[k];
  3154. }
  3155. }
  3156. for (i in tmp_arr) {
  3157. if (tmp_arr.hasOwnProperty(i)) {
  3158. populateArr[i] = tmp_arr[i];
  3159. }
  3160. }
  3161. return strictForIn || populateArr;
  3162. };
  3163. php.ksort = function (inputArr, sort_flags) {
  3164. // Sort an array by key
  3165. //
  3166. // version: 1103.1210
  3167. // discuss at: http://phpjs.org/functions/ksort
  3168. // + original by: GeekFG (http://geekfg.blogspot.com)
  3169. // + improved by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
  3170. // + improved by: Brett Zamir (http://brett-zamir.me)
  3171. // % note 1: The examples are correct, this is a new way
  3172. // % note 2: This function deviates from PHP in returning a copy of the array instead
  3173. // % note 2: of acting by reference and returning true; this was necessary because
  3174. // % note 2: IE does not allow deleting and re-adding of properties without caching
  3175. // % note 2: of property position; you can set the ini of "phpjs.strictForIn" to true to
  3176. // % note 2: get the PHP behavior, but use this only if you are in an environment
  3177. // % note 2: such as Firefox extensions where for-in iteration order is fixed and true
  3178. // % note 2: property deletion is supported. Note that we intend to implement the PHP
  3179. // % note 2: behavior by default if IE ever does allow it; only gives shallow copy since
  3180. // % note 2: is by reference in PHP anyways
  3181. // % note 3: Since JS objects' keys are always strings, and (the
  3182. // % note 3: default) SORT_REGULAR flag distinguishes by key type,
  3183. // % note 3: if the content is a numeric string, we treat the
  3184. // % note 3: "original type" as numeric.
  3185. // - depends on: i18n_loc_get_default
  3186. // - depends on: strnatcmp
  3187. // * example 1: \php.data = {d: 'lemon', a: 'orange', b: 'banana', c: 'apple'};
  3188. // * example 1: \php.data = ksort(data);
  3189. // * results 1: {a: 'orange', b: 'banana', c: 'apple', d: 'lemon'}
  3190. // * example 2: \php.ini_set('phpjs.strictForIn', true);
  3191. // * example 2: \php.data = {2: 'van', 3: 'Zonneveld', 1: 'Kevin'};
  3192. // * example 2: \php.ksort(data);
  3193. // * results 2: data == {1: 'Kevin', 2: 'van', 3: 'Zonneveld'}
  3194. // * returns 2: true
  3195. var tmp_arr = {},
  3196. keys = [],
  3197. sorter, i, k, that = this,
  3198. strictForIn = false,
  3199. populateArr = {};
  3200. switch (sort_flags) {
  3201. case 'SORT_STRING':
  3202. // compare items as strings
  3203. sorter = function (a, b) {
  3204. return that.strnatcmp(a, b);
  3205. };
  3206. break;
  3207. case 'SORT_LOCALE_STRING':
  3208. // compare items as strings, based on the current locale (set with i18n_loc_set_default() as of PHP6)
  3209. var loc = this.i18n_loc_get_default();
  3210. sorter = this.php_js.i18nLocales[loc].sorting;
  3211. break;
  3212. case 'SORT_NUMERIC':
  3213. // compare items numerically
  3214. sorter = function (a, b) {
  3215. return ((a + 0) - (b + 0));
  3216. };
  3217. break;
  3218. // case 'SORT_REGULAR': // compare items normally (don't change types)
  3219. default:
  3220. sorter = function (a, b) {
  3221. var aFloat = parseFloat(a),
  3222. bFloat = parseFloat(b),
  3223. aNumeric = aFloat + '' === a,
  3224. bNumeric = bFloat + '' === b;
  3225. if (aNumeric && bNumeric) {
  3226. return aFloat > bFloat ? 1 : aFloat < bFloat ? -1 : 0;
  3227. } else if (aNumeric && !bNumeric) {
  3228. return 1;
  3229. } else if (!aNumeric && bNumeric) {
  3230. return -1;
  3231. }
  3232. return a > b ? 1 : a < b ? -1 : 0;
  3233. };
  3234. break;
  3235. }
  3236. // Make a list of key names
  3237. for (k in inputArr) {
  3238. if (inputArr.hasOwnProperty(k)) {
  3239. keys.push(k);
  3240. }
  3241. }
  3242. keys.sort(sorter);
  3243. // BEGIN REDUNDANT
  3244. this.php_js = this.php_js || {};
  3245. this.php_js.ini = this.php_js.ini || {};
  3246. // END REDUNDANT
  3247. strictForIn = this.php_js.ini['phpjs.strictForIn'] && this.php_js.ini['phpjs.strictForIn'].local_value && this.php_js.ini['phpjs.strictForIn'].local_value !== 'off';
  3248. populateArr = strictForIn ? inputArr : populateArr;
  3249. // Rebuild array with sorted key names
  3250. for (i = 0; i < keys.length; i++) {
  3251. k = keys[i];
  3252. tmp_arr[k] = inputArr[k];
  3253. if (strictForIn) {
  3254. delete inputArr[k];
  3255. }
  3256. }
  3257. for (i in tmp_arr) {
  3258. if (tmp_arr.hasOwnProperty(i)) {
  3259. populateArr[i] = tmp_arr[i];
  3260. }
  3261. }
  3262. return strictForIn || populateArr;
  3263. };
  3264. php.lcfirst = function (str) {
  3265. // !No description available for lcfirst. @php.js developers: Please update the function summary text file.
  3266. //
  3267. // version: 1103.1210
  3268. // discuss at: http://phpjs.org/functions/lcfirst
  3269. // + original by: Brett Zamir (http://brett-zamir.me)
  3270. // * example 1: \php.lcfirst('Kevin Van Zonneveld');
  3271. // * returns 1: 'kevin Van Zonneveld'
  3272. str += '';
  3273. var f = str.charAt(0).toLowerCase();
  3274. return f + str.substr(1);
  3275. };
  3276. php.ltrim = function (str, charlist) {
  3277. // Strips whitespace from the beginning of a string
  3278. //
  3279. // version: 1103.1210
  3280. // discuss at: http://phpjs.org/functions/ltrim
  3281. // + original by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
  3282. // + input by: Erkekjetter
  3283. // + improved by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
  3284. // + bugfixed by: Onno Marsman
  3285. // * example 1: \php.ltrim(' Kevin van Zonneveld ');
  3286. // * returns 1: 'Kevin van Zonneveld '
  3287. charlist = !charlist ? ' \\s\u00A0' : (charlist + '').replace(/([\[\]\(\)\.\?\/\*\{\}\+\$\^\:])/g, '$1');
  3288. var re = new RegExp('^[' + charlist + ']+', 'g');
  3289. return (str + '').replace(re, '');
  3290. };
  3291. php.rtrim = function (str, charlist) {
  3292. // Removes trailing whitespace
  3293. //
  3294. // version: 1103.1210
  3295. // discuss at: http://phpjs.org/functions/rtrim
  3296. // + original by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
  3297. // + input by: Erkekjetter
  3298. // + improved by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
  3299. // + bugfixed by: Onno Marsman
  3300. // + input by: rem
  3301. // + bugfixed by: Brett Zamir (http://brett-zamir.me)
  3302. // * example 1: rtrim(' Kevin van Zonneveld ');
  3303. // * returns 1: ' Kevin van Zonneveld'
  3304. charlist = !charlist ? ' \\s\u00A0' : (charlist + '').replace(/([\[\]\(\)\.\?\/\*\{\}\+\$\^\:])/g, '\\$1');
  3305. var re = new RegExp('[' + charlist + ']+$', 'g');
  3306. return (str + '').replace(re, '');
  3307. };
  3308. php.max = function () {
  3309. // Return the highest value in an array or a series of arguments
  3310. //
  3311. // version: 1103.1210
  3312. // discuss at: http://phpjs.org/functions/max
  3313. // + original by: Onno Marsman
  3314. // + revised by: Onno Marsman
  3315. // + tweaked by: Jack
  3316. // % note: Long code cause we're aiming for maximum PHP compatibility
  3317. // * example 1: \php.max(1, 3, 5, 6, 7);
  3318. // * returns 1: 7
  3319. // * example 2: \php.max([2, 4, 5]);
  3320. // * returns 2: 5
  3321. // * example 3: \php.max(0, 'hello');
  3322. // * returns 3: 0
  3323. // * example 4: \php.max('hello', 0);
  3324. // * returns 4: 'hello'
  3325. // * example 5: \php.max(-1, 'hello');
  3326. // * returns 5: 'hello'
  3327. // * example 6: \php.max([2, 4, 8], [2, 5, 7]);
  3328. // * returns 6: [2, 5, 7]
  3329. var ar, retVal, i = 0,
  3330. n = 0;
  3331. var argv = arguments,
  3332. argc = argv.length;
  3333. var _obj2Array = function (obj) {
  3334. if (obj instanceof Array) {
  3335. return obj;
  3336. } else {
  3337. var ar = [];
  3338. for (var i in obj) {
  3339. ar.push(obj[i]);
  3340. }
  3341. return ar;
  3342. }
  3343. }; //function _obj2Array
  3344. var _compare = function (current, next) {
  3345. var i = 0,
  3346. n = 0,
  3347. tmp = 0;
  3348. var nl = 0,
  3349. cl = 0;
  3350. if (current === next) {
  3351. return 0;
  3352. } else if (typeof current == 'object') {
  3353. if (typeof next == 'object') {
  3354. current = _obj2Array(current);
  3355. next = _obj2Array(next);
  3356. cl = current.length;
  3357. nl = next.length;
  3358. if (nl > cl) {
  3359. return 1;
  3360. } else if (nl < cl) {
  3361. return -1;
  3362. } else {
  3363. for (i = 0, n = cl; i < n; ++i) {
  3364. tmp = _compare(current[i], next[i]);
  3365. if (tmp == 1) {
  3366. return 1;
  3367. } else if (tmp == -1) {
  3368. return -1;
  3369. }
  3370. }
  3371. return 0;
  3372. }
  3373. } else {
  3374. return -1;
  3375. }
  3376. } else if (typeof next == 'object') {
  3377. return 1;
  3378. } else if (isNaN(next) && !isNaN(current)) {
  3379. if (current == 0) {
  3380. return 0;
  3381. } else {
  3382. return (current < 0 ? 1 : -1);
  3383. }
  3384. } else if (isNaN(current) && !isNaN(next)) {
  3385. if (next == 0) {
  3386. return 0;
  3387. } else {
  3388. return (next > 0 ? 1 : -1);
  3389. }
  3390. } else {
  3391. if (next == current) {
  3392. return 0;
  3393. } else {
  3394. return (next > current ? 1 : -1);
  3395. }
  3396. }
  3397. }; //function _compare
  3398. if (argc === 0) {
  3399. throw new Error('At least one value should be passed to max()');
  3400. } else if (argc === 1) {
  3401. if (typeof argv[0] === 'object') {
  3402. ar = _obj2Array(argv[0]);
  3403. } else {
  3404. throw new Error('Wrong parameter count for max()');
  3405. }
  3406. if (ar.length === 0) {
  3407. throw new Error('Array must contain at least one element for max()');
  3408. }
  3409. } else {
  3410. ar = argv;
  3411. }
  3412. retVal = ar[0];
  3413. for (i = 1, n = ar.length; i < n; ++i) {
  3414. if (_compare(retVal, ar[i]) == 1) {
  3415. retVal = ar[i];
  3416. }
  3417. }
  3418. return retVal;
  3419. };
  3420. php.md5 = function (str) {
  3421. // Calculate the md5 hash of a string
  3422. //
  3423. // version: 1103.1210
  3424. // discuss at: http://phpjs.org/functions/md5
  3425. // + original by: Webtoolkit.info (http://www.webtoolkit.info/)
  3426. // + namespaced by: Michael White (http://getsprink.com)
  3427. // + tweaked by: Jack
  3428. // + improved by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
  3429. // + input by: Brett Zamir (http://brett-zamir.me)
  3430. // + bugfixed by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
  3431. // - depends on: utf8_encode
  3432. // * example 1: \php.md5('Kevin van Zonneveld');
  3433. // * returns 1: '6e658d4bfcb59cc13f96c14450ac40b9'
  3434. var xl;
  3435. var rotateLeft = function (lValue, iShiftBits) {
  3436. return (lValue << iShiftBits) | (lValue >>> (32 - iShiftBits));
  3437. };
  3438. var addUnsigned = function (lX, lY) {
  3439. var lX4, lY4, lX8, lY8, lResult;
  3440. lX8 = (lX & 0x80000000);
  3441. lY8 = (lY & 0x80000000);
  3442. lX4 = (lX & 0x40000000);
  3443. lY4 = (lY & 0x40000000);
  3444. lResult = (lX & 0x3FFFFFFF) + (lY & 0x3FFFFFFF);
  3445. if (lX4 & lY4) {
  3446. return (lResult ^ 0x80000000 ^ lX8 ^ lY8);
  3447. }
  3448. if (lX4 | lY4) {
  3449. if (lResult & 0x40000000) {
  3450. return (lResult ^ 0xC0000000 ^ lX8 ^ lY8);
  3451. } else {
  3452. return (lResult ^ 0x40000000 ^ lX8 ^ lY8);
  3453. }
  3454. } else {
  3455. return (lResult ^ lX8 ^ lY8);
  3456. }
  3457. };
  3458. var _F = function (x, y, z) {
  3459. return (x & y) | ((~x) & z);
  3460. };
  3461. var _G = function (x, y, z) {
  3462. return (x & z) | (y & (~z));
  3463. };
  3464. var _H = function (x, y, z) {
  3465. return (x ^ y ^ z);
  3466. };
  3467. var _I = function (x, y, z) {
  3468. return (y ^ (x | (~z)));
  3469. };
  3470. var _FF = function (a, b, c, d, x, s, ac) {
  3471. a = addUnsigned(a, addUnsigned(addUnsigned(_F(b, c, d), x), ac));
  3472. return addUnsigned(rotateLeft(a, s), b);
  3473. };
  3474. var _GG = function (a, b, c, d, x, s, ac) {
  3475. a = addUnsigned(a, addUnsigned(addUnsigned(_G(b, c, d), x), ac));
  3476. return addUnsigned(rotateLeft(a, s), b);
  3477. };
  3478. var _HH = function (a, b, c, d, x, s, ac) {
  3479. a = addUnsigned(a, addUnsigned(addUnsigned(_H(b, c, d), x), ac));
  3480. return addUnsigned(rotateLeft(a, s), b);
  3481. };
  3482. var _II = function (a, b, c, d, x, s, ac) {
  3483. a = addUnsigned(a, addUnsigned(addUnsigned(_I(b, c, d), x), ac));
  3484. return addUnsigned(rotateLeft(a, s), b);
  3485. };
  3486. var convertToWordArray = function (str) {
  3487. var lWordCount;
  3488. var lMessageLength = str.length;
  3489. var lNumberOfWords_temp1 = lMessageLength + 8;
  3490. var lNumberOfWords_temp2 = (lNumberOfWords_temp1 - (lNumberOfWords_temp1 % 64)) / 64;
  3491. var lNumberOfWords = (lNumberOfWords_temp2 + 1) * 16;
  3492. var lWordArray = new Array(lNumberOfWords - 1);
  3493. var lBytePosition = 0;
  3494. var lByteCount = 0;
  3495. while (lByteCount < lMessageLength) {
  3496. lWordCount = (lByteCount - (lByteCount % 4)) / 4;
  3497. lBytePosition = (lByteCount % 4) * 8;
  3498. lWordArray[lWordCount] = (lWordArray[lWordCount] | (str.charCodeAt(lByteCount) << lBytePosition));
  3499. lByteCount++;
  3500. }
  3501. lWordCount = (lByteCount - (lByteCount % 4)) / 4;
  3502. lBytePosition = (lByteCount % 4) * 8;
  3503. lWordArray[lWordCount] = lWordArray[lWordCount] | (0x80 << lBytePosition);
  3504. lWordArray[lNumberOfWords - 2] = lMessageLength << 3;
  3505. lWordArray[lNumberOfWords - 1] = lMessageLength >>> 29;
  3506. return lWordArray;
  3507. };
  3508. var wordToHex = function (lValue) {
  3509. var wordToHexValue = "",
  3510. wordToHexValue_temp = "",
  3511. lByte, lCount;
  3512. for (lCount = 0; lCount <= 3; lCount++) {
  3513. lByte = (lValue >>> (lCount * 8)) & 255;
  3514. wordToHexValue_temp = "0" + lByte.toString(16);
  3515. wordToHexValue = wordToHexValue + wordToHexValue_temp.substr(wordToHexValue_temp.length - 2, 2);
  3516. }
  3517. return wordToHexValue;
  3518. };
  3519. var x = [],
  3520. k, AA, BB, CC, DD, a, b, c, d, S11 = 7,
  3521. S12 = 12,
  3522. S13 = 17,
  3523. S14 = 22,
  3524. S21 = 5,
  3525. S22 = 9,
  3526. S23 = 14,
  3527. S24 = 20,
  3528. S31 = 4,
  3529. S32 = 11,
  3530. S33 = 16,
  3531. S34 = 23,
  3532. S41 = 6,
  3533. S42 = 10,
  3534. S43 = 15,
  3535. S44 = 21;
  3536. str = this.utf8_encode(str);
  3537. x = convertToWordArray(str);
  3538. a = 0x67452301;
  3539. b = 0xEFCDAB89;
  3540. c = 0x98BADCFE;
  3541. d = 0x10325476;
  3542. xl = x.length;
  3543. for (k = 0; k < xl; k += 16) {
  3544. AA = a;
  3545. BB = b;
  3546. CC = c;
  3547. DD = d;
  3548. a = _FF(a, b, c, d, x[k + 0], S11, 0xD76AA478);
  3549. d = _FF(d, a, b, c, x[k + 1], S12, 0xE8C7B756);
  3550. c = _FF(c, d, a, b, x[k + 2], S13, 0x242070DB);
  3551. b = _FF(b, c, d, a, x[k + 3], S14, 0xC1BDCEEE);
  3552. a = _FF(a, b, c, d, x[k + 4], S11, 0xF57C0FAF);
  3553. d = _FF(d, a, b, c, x[k + 5], S12, 0x4787C62A);
  3554. c = _FF(c, d, a, b, x[k + 6], S13, 0xA8304613);
  3555. b = _FF(b, c, d, a, x[k + 7], S14, 0xFD469501);
  3556. a = _FF(a, b, c, d, x[k + 8], S11, 0x698098D8);
  3557. d = _FF(d, a, b, c, x[k + 9], S12, 0x8B44F7AF);
  3558. c = _FF(c, d, a, b, x[k + 10], S13, 0xFFFF5BB1);
  3559. b = _FF(b, c, d, a, x[k + 11], S14, 0x895CD7BE);
  3560. a = _FF(a, b, c, d, x[k + 12], S11, 0x6B901122);
  3561. d = _FF(d, a, b, c, x[k + 13], S12, 0xFD987193);
  3562. c = _FF(c, d, a, b, x[k + 14], S13, 0xA679438E);
  3563. b = _FF(b, c, d, a, x[k + 15], S14, 0x49B40821);
  3564. a = _GG(a, b, c, d, x[k + 1], S21, 0xF61E2562);
  3565. d = _GG(d, a, b, c, x[k + 6], S22, 0xC040B340);
  3566. c = _GG(c, d, a, b, x[k + 11], S23, 0x265E5A51);
  3567. b = _GG(b, c, d, a, x[k + 0], S24, 0xE9B6C7AA);
  3568. a = _GG(a, b, c, d, x[k + 5], S21, 0xD62F105D);
  3569. d = _GG(d, a, b, c, x[k + 10], S22, 0x2441453);
  3570. c = _GG(c, d, a, b, x[k + 15], S23, 0xD8A1E681);
  3571. b = _GG(b, c, d, a, x[k + 4], S24, 0xE7D3FBC8);
  3572. a = _GG(a, b, c, d, x[k + 9], S21, 0x21E1CDE6);
  3573. d = _GG(d, a, b, c, x[k + 14], S22, 0xC33707D6);
  3574. c = _GG(c, d, a, b, x[k + 3], S23, 0xF4D50D87);
  3575. b = _GG(b, c, d, a, x[k + 8], S24, 0x455A14ED);
  3576. a = _GG(a, b, c, d, x[k + 13], S21, 0xA9E3E905);
  3577. d = _GG(d, a, b, c, x[k + 2], S22, 0xFCEFA3F8);
  3578. c = _GG(c, d, a, b, x[k + 7], S23, 0x676F02D9);
  3579. b = _GG(b, c, d, a, x[k + 12], S24, 0x8D2A4C8A);
  3580. a = _HH(a, b, c, d, x[k + 5], S31, 0xFFFA3942);
  3581. d = _HH(d, a, b, c, x[k + 8], S32, 0x8771F681);
  3582. c = _HH(c, d, a, b, x[k + 11], S33, 0x6D9D6122);
  3583. b = _HH(b, c, d, a, x[k + 14], S34, 0xFDE5380C);
  3584. a = _HH(a, b, c, d, x[k + 1], S31, 0xA4BEEA44);
  3585. d = _HH(d, a, b, c, x[k + 4], S32, 0x4BDECFA9);
  3586. c = _HH(c, d, a, b, x[k + 7], S33, 0xF6BB4B60);
  3587. b = _HH(b, c, d, a, x[k + 10], S34, 0xBEBFBC70);
  3588. a = _HH(a, b, c, d, x[k + 13], S31, 0x289B7EC6);
  3589. d = _HH(d, a, b, c, x[k + 0], S32, 0xEAA127FA);
  3590. c = _HH(c, d, a, b, x[k + 3], S33, 0xD4EF3085);
  3591. b = _HH(b, c, d, a, x[k + 6], S34, 0x4881D05);
  3592. a = _HH(a, b, c, d, x[k + 9], S31, 0xD9D4D039);
  3593. d = _HH(d, a, b, c, x[k + 12], S32, 0xE6DB99E5);
  3594. c = _HH(c, d, a, b, x[k + 15], S33, 0x1FA27CF8);
  3595. b = _HH(b, c, d, a, x[k + 2], S34, 0xC4AC5665);
  3596. a = _II(a, b, c, d, x[k + 0], S41, 0xF4292244);
  3597. d = _II(d, a, b, c, x[k + 7], S42, 0x432AFF97);
  3598. c = _II(c, d, a, b, x[k + 14], S43, 0xAB9423A7);
  3599. b = _II(b, c, d, a, x[k + 5], S44, 0xFC93A039);
  3600. a = _II(a, b, c, d, x[k + 12], S41, 0x655B59C3);
  3601. d = _II(d, a, b, c, x[k + 3], S42, 0x8F0CCC92);
  3602. c = _II(c, d, a, b, x[k + 10], S43, 0xFFEFF47D);
  3603. b = _II(b, c, d, a, x[k + 1], S44, 0x85845DD1);
  3604. a = _II(a, b, c, d, x[k + 8], S41, 0x6FA87E4F);
  3605. d = _II(d, a, b, c, x[k + 15], S42, 0xFE2CE6E0);
  3606. c = _II(c, d, a, b, x[k + 6], S43, 0xA3014314);
  3607. b = _II(b, c, d, a, x[k + 13], S44, 0x4E0811A1);
  3608. a = _II(a, b, c, d, x[k + 4], S41, 0xF7537E82);
  3609. d = _II(d, a, b, c, x[k + 11], S42, 0xBD3AF235);
  3610. c = _II(c, d, a, b, x[k + 2], S43, 0x2AD7D2BB);
  3611. b = _II(b, c, d, a, x[k + 9], S44, 0xEB86D391);
  3612. a = addUnsigned(a, AA);
  3613. b = addUnsigned(b, BB);
  3614. c = addUnsigned(c, CC);
  3615. d = addUnsigned(d, DD);
  3616. }
  3617. var temp = wordToHex(a) + wordToHex(b) + wordToHex(c) + wordToHex(d);
  3618. return temp.toLowerCase();
  3619. };
  3620. php.method_exists = function (obj, method) {
  3621. // Checks if the class method exists
  3622. //
  3623. // version: 1103.1210
  3624. // discuss at: http://phpjs.org/functions/method_exists
  3625. // + original by: Brett Zamir (http://brett-zamir.me)
  3626. // * example 1: \php.function class_a() {this.meth1 = function () {return true;}};
  3627. // * example 1: \php.var instance_a = new class_a();
  3628. // * example 1: \php.method_exists(instance_a, 'meth1');
  3629. // * returns 1: true
  3630. // * example 2: \php.function class_a() {this.meth1 = function () {return true;}};
  3631. // * example 2: \php.var instance_a = new class_a();
  3632. // * example 2: \php.method_exists(instance_a, 'meth2');
  3633. // * returns 2: false
  3634. if (typeof obj === 'string') {
  3635. return this.window[obj] && typeof this.window[obj][method] === 'function';
  3636. }
  3637. return typeof obj[method] === 'function';
  3638. };
  3639. php.microtime = function (get_as_float) {
  3640. // Returns either a string or a float containing the current time in seconds and microseconds
  3641. //
  3642. // version: 1103.1210
  3643. // discuss at: http://phpjs.org/functions/microtime
  3644. // + original by: Paulo Freitas
  3645. // * example 1: \php.timeStamp = microtime(true);
  3646. // * results 1: timeStamp > 1000000000 && timeStamp < 2000000000
  3647. var now = new Date().getTime() / 1000;
  3648. var s = parseInt(now, 10);
  3649. return (get_as_float) ? now : (Math.round((now - s) * 1000) / 1000) + ' ' + s;
  3650. };
  3651. php.min = function () {
  3652. // Return the lowest value in an array or a series of arguments
  3653. //
  3654. // version: 1103.1210
  3655. // discuss at: http://phpjs.org/functions/min
  3656. // + original by: Onno Marsman
  3657. // + revised by: Onno Marsman
  3658. // + tweaked by: Jack
  3659. // % note: Long code cause we're aiming for maximum PHP compatibility
  3660. // * example 1: \php.min(1, 3, 5, 6, 7);
  3661. // * returns 1: 1
  3662. // * example 2: \php.min([2, 4, 5]);
  3663. // * returns 2: 2
  3664. // * example 3: \php.min(0, 'hello');
  3665. // * returns 3: 0
  3666. // * example 4: \php.min('hello', 0);
  3667. // * returns 4: 'hello'
  3668. // * example 5: \php.min(-1, 'hello');
  3669. // * returns 5: -1
  3670. // * example 6: \php.min([2, 4, 8], [2, 5, 7]);
  3671. // * returns 6: [2, 4, 8]
  3672. var ar, retVal, i = 0,
  3673. n = 0;
  3674. var argv = arguments,
  3675. argc = argv.length;
  3676. var _obj2Array = function (obj) {
  3677. if (obj instanceof Array) {
  3678. return obj;
  3679. } else {
  3680. var ar = [];
  3681. for (var i in obj) {
  3682. ar.push(obj[i]);
  3683. }
  3684. return ar;
  3685. }
  3686. }; //function _obj2Array
  3687. var _compare = function (current, next) {
  3688. var i = 0,
  3689. n = 0,
  3690. tmp = 0;
  3691. var nl = 0,
  3692. cl = 0;
  3693. if (current === next) {
  3694. return 0;
  3695. } else if (typeof current == 'object') {
  3696. if (typeof next == 'object') {
  3697. current = _obj2Array(current);
  3698. next = _obj2Array(next);
  3699. cl = current.length;
  3700. nl = next.length;
  3701. if (nl > cl) {
  3702. return 1;
  3703. } else if (nl < cl) {
  3704. return -1;
  3705. } else {
  3706. for (i = 0, n = cl; i < n; ++i) {
  3707. tmp = _compare(current[i], next[i]);
  3708. if (tmp == 1) {
  3709. return 1;
  3710. } else if (tmp == -1) {
  3711. return -1;
  3712. }
  3713. }
  3714. return 0;
  3715. }
  3716. } else {
  3717. return -1;
  3718. }
  3719. } else if (typeof next == 'object') {
  3720. return 1;
  3721. } else if (isNaN(next) && !isNaN(current)) {
  3722. if (current == 0) {
  3723. return 0;
  3724. } else {
  3725. return (current < 0 ? 1 : -1);
  3726. }
  3727. } else if (isNaN(current) && !isNaN(next)) {
  3728. if (next == 0) {
  3729. return 0;
  3730. } else {
  3731. return (next > 0 ? 1 : -1);
  3732. }
  3733. } else {
  3734. if (next == current) {
  3735. return 0;
  3736. } else {
  3737. return (next > current ? 1 : -1);
  3738. }
  3739. }
  3740. }; //function _compare
  3741. if (argc === 0) {
  3742. throw new Error('At least one value should be passed to min()');
  3743. } else if (argc === 1) {
  3744. if (typeof argv[0] === 'object') {
  3745. ar = _obj2Array(argv[0]);
  3746. } else {
  3747. throw new Error('Wrong parameter count for min()');
  3748. }
  3749. if (ar.length === 0) {
  3750. throw new Error('Array must contain at least one element for min()');
  3751. }
  3752. } else {
  3753. ar = argv;
  3754. }
  3755. retVal = ar[0];
  3756. for (i = 1, n = ar.length; i < n; ++i) {
  3757. if (_compare(retVal, ar[i]) == -1) {
  3758. retVal = ar[i];
  3759. }
  3760. }
  3761. return retVal;
  3762. };
  3763. php.mktime = function () {
  3764. // Get UNIX timestamp for a date
  3765. //
  3766. // version: 1103.1210
  3767. // discuss at: http://phpjs.org/functions/mktime
  3768. // + original by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
  3769. // + improved by: baris ozdil
  3770. // + input by: gabriel paderni
  3771. // + improved by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
  3772. // + improved by: FGFEmperor
  3773. // + input by: Yannoo
  3774. // + bugfixed by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
  3775. // + input by: jakes
  3776. // + bugfixed by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
  3777. // + bugfixed by: Marc Palau
  3778. // + improved by: Brett Zamir (http://brett-zamir.me)
  3779. // + input by: 3D-GRAF
  3780. // + bugfixed by: Brett Zamir (http://brett-zamir.me)
  3781. // + input by: Chris
  3782. // + revised by: Theriault
  3783. // % note 1: The return values of the following examples are
  3784. // % note 1: received only if your system's timezone is UTC.
  3785. // * example 1: \php.mktime(14, 10, 2, 2, 1, 2008);
  3786. // * returns 1: 1201875002
  3787. // * example 2: \php.mktime(0, 0, 0, 0, 1, 2008);
  3788. // * returns 2: 1196467200
  3789. // * example 3: \php.make = mktime();
  3790. // * example 3: \php.td = new Date();
  3791. // * example 3: \php.real = Math.floor(td.getTime() / 1000);
  3792. // * example 3: \php.diff = (real - make);
  3793. // * results 3: diff < 5
  3794. // * example 4: \php.mktime(0, 0, 0, 13, 1, 1997)
  3795. // * returns 4: 883612800
  3796. // * example 5: \php.mktime(0, 0, 0, 1, 1, 1998)
  3797. // * returns 5: 883612800
  3798. // * example 6: \php.mktime(0, 0, 0, 1, 1, 98)
  3799. // * returns 6: 883612800
  3800. // * example 7: \php.mktime(23, 59, 59, 13, 0, 2010)
  3801. // * returns 7: 1293839999
  3802. // * example 8: \php.mktime(0, 0, -1, 1, 1, 1970)
  3803. // * returns 8: -1
  3804. var d = new Date(),
  3805. r = arguments,
  3806. i = 0,
  3807. e = ['Hours', 'Minutes', 'Seconds', 'Month', 'Date', 'FullYear'];
  3808. for (i = 0; i < e.length; i++) {
  3809. if (typeof r[i] === 'undefined') {
  3810. r[i] = d['get' + e[i]]();
  3811. r[i] += (i === 3); // +1 to fix JS months.
  3812. } else {
  3813. r[i] = parseInt(r[i], 10);
  3814. if (isNaN(r[i])) {
  3815. return false;
  3816. }
  3817. }
  3818. }
  3819. // Map years 0-69 to 2000-2069 and years 70-100 to 1970-2000.
  3820. r[5] += (r[5] >= 0 ? (r[5] <= 69 ? 2e3 : (r[5] <= 100 ? 1900 : 0)) : 0);
  3821. // Set year, month (-1 to fix JS months), and date.
  3822. // !This must come before the call to setHours!
  3823. d.setFullYear(r[5], r[3] - 1, r[4]);
  3824. // Set hours, minutes, and seconds.
  3825. d.setHours(r[0], r[1], r[2]);
  3826. // Divide milliseconds by 1000 to return seconds and drop decimal.
  3827. // Add 1 second if negative or it'll be off from PHP by 1 second.
  3828. return (d.getTime() / 1e3 >> 0) - (d.getTime() < 0);
  3829. };
  3830. php.natcasesort = function (inputArr) {
  3831. // Sort an array using case-insensitive natural sort
  3832. //
  3833. // version: 1103.1210
  3834. // discuss at: http://phpjs.org/functions/natcasesort
  3835. // + original by: Brett Zamir (http://brett-zamir.me)
  3836. // + improved by: Brett Zamir (http://brett-zamir.me)
  3837. // % note 1: This function deviates from PHP in returning a copy of the array instead
  3838. // % note 1: of acting by reference and returning true; this was necessary because
  3839. // % note 1: IE does not allow deleting and re-adding of properties without caching
  3840. // % note 1: of property position; you can set the ini of "phpjs.strictForIn" to true to
  3841. // % note 1: get the PHP behavior, but use this only if you are in an environment
  3842. // % note 1: such as Firefox extensions where for-in iteration order is fixed and true
  3843. // % note 1: property deletion is supported. Note that we intend to implement the PHP
  3844. // % note 1: behavior by default if IE ever does allow it; only gives shallow copy since
  3845. // % note 1: is by reference in PHP anyways
  3846. // % note 2: We cannot use numbers as keys and have them be reordered since they
  3847. // % note 2: adhere to numerical order in some implementations
  3848. // - depends on: strnatcasecmp
  3849. // * example 1: $array1 = {a:'IMG0.png', b:'img12.png', c:'img10.png', d:'img2.png', e:'img1.png', f:'IMG3.png'};
  3850. // * example 1: $array1 = natcasesort($array1);
  3851. // * returns 1: {a: 'IMG0.png', e: 'img1.png', d: 'img2.png', f: 'IMG3.png', c: 'img10.png', b: 'img12.png'}
  3852. var valArr = [],
  3853. keyArr = [],
  3854. k, i, ret, that = this,
  3855. strictForIn = false,
  3856. populateArr = {};
  3857. var bubbleSort = function (keyArr, inputArr) {
  3858. var i, j, tempValue, tempKeyVal;
  3859. for (i = inputArr.length - 2; i >= 0; i--) {
  3860. for (j = 0; j <= i; j++) {
  3861. ret = that.strnatcasecmp(inputArr[j + 1], inputArr[j]);
  3862. if (ret < 0) {
  3863. tempValue = inputArr[j];
  3864. inputArr[j] = inputArr[j + 1];
  3865. inputArr[j + 1] = tempValue;
  3866. tempKeyVal = keyArr[j];
  3867. keyArr[j] = keyArr[j + 1];
  3868. keyArr[j + 1] = tempKeyVal;
  3869. }
  3870. }
  3871. }
  3872. };
  3873. // BEGIN REDUNDANT
  3874. this.php_js = this.php_js || {};
  3875. this.php_js.ini = this.php_js.ini || {};
  3876. // END REDUNDANT
  3877. strictForIn = this.php_js.ini['phpjs.strictForIn'] && this.php_js.ini['phpjs.strictForIn'].local_value && this.php_js.ini['phpjs.strictForIn'].local_value !== 'off';
  3878. populateArr = strictForIn ? inputArr : populateArr;
  3879. // Get key and value arrays
  3880. for (k in inputArr) {
  3881. if (inputArr.hasOwnProperty(k)) {
  3882. valArr.push(inputArr[k]);
  3883. keyArr.push(k);
  3884. if (strictForIn) {
  3885. delete inputArr[k];
  3886. }
  3887. }
  3888. }
  3889. try {
  3890. // Sort our new temporary arrays
  3891. bubbleSort(keyArr, valArr);
  3892. } catch (e) {
  3893. return false;
  3894. }
  3895. // Repopulate the old array
  3896. for (i = 0; i < valArr.length; i++) {
  3897. populateArr[keyArr[i]] = valArr[i];
  3898. }
  3899. return strictForIn || populateArr;
  3900. };
  3901. php.natsort = function (inputArr) {
  3902. // Sort an array using natural sort
  3903. //
  3904. // version: 1103.1210
  3905. // discuss at: http://phpjs.org/functions/natsort
  3906. // + original by: Brett Zamir (http://brett-zamir.me)
  3907. // + improved by: Brett Zamir (http://brett-zamir.me)
  3908. // % note 1: This function deviates from PHP in returning a copy of the array instead
  3909. // % note 1: of acting by reference and returning true; this was necessary because
  3910. // % note 1: IE does not allow deleting and re-adding of properties without caching
  3911. // % note 1: of property position; you can set the ini of "phpjs.strictForIn" to true to
  3912. // % note 1: get the PHP behavior, but use this only if you are in an environment
  3913. // % note 1: such as Firefox extensions where for-in iteration order is fixed and true
  3914. // % note 1: property deletion is supported. Note that we intend to implement the PHP
  3915. // % note 1: behavior by default if IE ever does allow it; only gives shallow copy since
  3916. // % note 1: is by reference in PHP anyways
  3917. // - depends on: strnatcmp
  3918. // * example 1: $array1 = {a:"img12.png", b:"img10.png", c:"img2.png", d:"img1.png"};
  3919. // * example 1: $array1 = natsort($array1);
  3920. // * returns 1: {d: 'img1.png', c: 'img2.png', b: 'img10.png', a: 'img12.png'}
  3921. var valArr = [],
  3922. keyArr = [],
  3923. k, i, ret, that = this,
  3924. strictForIn = false,
  3925. populateArr = {};
  3926. var bubbleSort = function (keyArr, inputArr) {
  3927. var i, j, tempValue, tempKeyVal;
  3928. for (i = inputArr.length - 2; i >= 0; i--) {
  3929. for (j = 0; j <= i; j++) {
  3930. ret = that.strnatcmp(inputArr[j + 1], inputArr[j]);
  3931. if (ret < 0) {
  3932. tempValue = inputArr[j];
  3933. inputArr[j] = inputArr[j + 1];
  3934. inputArr[j + 1] = tempValue;
  3935. tempKeyVal = keyArr[j];
  3936. keyArr[j] = keyArr[j + 1];
  3937. keyArr[j + 1] = tempKeyVal;
  3938. }
  3939. }
  3940. }
  3941. };
  3942. // BEGIN REDUNDANT
  3943. this.php_js = this.php_js || {};
  3944. this.php_js.ini = this.php_js.ini || {};
  3945. // END REDUNDANT
  3946. strictForIn = this.php_js.ini['phpjs.strictForIn'] && this.php_js.ini['phpjs.strictForIn'].local_value && this.php_js.ini['phpjs.strictForIn'].local_value !== 'off';
  3947. populateArr = strictForIn ? inputArr : populateArr;
  3948. // Get key and value arrays
  3949. for (k in inputArr) {
  3950. if (inputArr.hasOwnProperty(k)) {
  3951. valArr.push(inputArr[k]);
  3952. keyArr.push(k);
  3953. if (strictForIn) {
  3954. delete inputArr[k];
  3955. }
  3956. }
  3957. }
  3958. try {
  3959. // Sort our new temporary arrays
  3960. bubbleSort(keyArr, valArr);
  3961. } catch (e) {
  3962. return false;
  3963. }
  3964. // Repopulate the old array
  3965. for (i = 0; i < valArr.length; i++) {
  3966. populateArr[keyArr[i]] = valArr[i];
  3967. }
  3968. return strictForIn || populateArr;
  3969. };
  3970. php.nl2br = function (str, is_xhtml) {
  3971. // Converts newlines to HTML line breaks
  3972. //
  3973. // version: 1103.1210
  3974. // discuss at: http://phpjs.org/functions/nl2br
  3975. // + original by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
  3976. // + improved by: Philip Peterson
  3977. // + improved by: Onno Marsman
  3978. // + improved by: Atli Þór
  3979. // + bugfixed by: Onno Marsman
  3980. // + input by: Brett Zamir (http://brett-zamir.me)
  3981. // + bugfixed by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
  3982. // + improved by: Brett Zamir (http://brett-zamir.me)
  3983. // + improved by: Maximusya
  3984. // * example 1: \php.nl2br('Kevin\nvan\nZonneveld');
  3985. // * returns 1: 'Kevin<br />\nvan<br />\nZonneveld'
  3986. // * example 2: \php.nl2br("\nOne\nTwo\n\nThree\n", false);
  3987. // * returns 2: '<br>\nOne<br>\nTwo<br>\n<br>\nThree<br>\n'
  3988. // * example 3: \php.nl2br("\nOne\nTwo\n\nThree\n", true);
  3989. // * returns 3: '<br />\nOne<br />\nTwo<br />\n<br />\nThree<br />\n'
  3990. var breakTag = (is_xhtml || typeof is_xhtml === 'undefined') ? '<br />' : '<br>';
  3991. return (str + '').replace(/([^>\r\n]?)(\r\n|\n\r|\r|\n)/g, '$1' + breakTag + '$2');
  3992. };
  3993. php.number_format = function (number, decimals, dec_point, thousands_sep) {
  3994. // Formats a number with grouped thousands
  3995. //
  3996. // version: 1103.1210
  3997. // discuss at: http://phpjs.org/functions/number_format
  3998. // + original by: Jonas Raoni Soares Silva (http://www.jsfromhell.com)
  3999. // + improved by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
  4000. // + bugfix by: Michael White (http://getsprink.com)
  4001. // + bugfix by: Benjamin Lupton
  4002. // + bugfix by: Allan Jensen (http://www.winternet.no)
  4003. // + revised by: Jonas Raoni Soares Silva (http://www.jsfromhell.com)
  4004. // + bugfix by: Howard Yeend
  4005. // + revised by: Luke Smith (http://lucassmith.name)
  4006. // + bugfix by: Diogo Resende
  4007. // + bugfix by: Rival
  4008. // + input by: Kheang Hok Chin (http://www.distantia.ca/)
  4009. // + improved by: davook
  4010. // + improved by: Brett Zamir (http://brett-zamir.me)
  4011. // + input by: Jay Klehr
  4012. // + improved by: Brett Zamir (http://brett-zamir.me)
  4013. // + input by: Amir Habibi (http://www.residence-mixte.com/)
  4014. // + bugfix by: Brett Zamir (http://brett-zamir.me)
  4015. // + improved by: Theriault
  4016. // + input by: Amirouche
  4017. // + improved by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
  4018. // * example 1: \php.number_format(1234.56);
  4019. // * returns 1: '1,235'
  4020. // * example 2: \php.number_format(1234.56, 2, ',', ' ');
  4021. // * returns 2: '1 234,56'
  4022. // * example 3: \php.number_format(1234.5678, 2, '.', '');
  4023. // * returns 3: '1234.57'
  4024. // * example 4: \php.number_format(67, 2, ',', '.');
  4025. // * returns 4: '67,00'
  4026. // * example 5: \php.number_format(1000);
  4027. // * returns 5: '1,000'
  4028. // * example 6: \php.number_format(67.311, 2);
  4029. // * returns 6: '67.31'
  4030. // * example 7: \php.number_format(1000.55, 1);
  4031. // * returns 7: '1,000.6'
  4032. // * example 8: \php.number_format(67000, 5, ',', '.');
  4033. // * returns 8: '67.000,00000'
  4034. // * example 9: \php.number_format(0.9, 0);
  4035. // * returns 9: '1'
  4036. // * example 10: \php.number_format('1.20', 2);
  4037. // * returns 10: '1.20'
  4038. // * example 11: \php.number_format('1.20', 4);
  4039. // * returns 11: '1.2000'
  4040. // * example 12: \php.number_format('1.2000', 3);
  4041. // * returns 12: '1.200'
  4042. // * example 13: \php.number_format('1 000,50', 2, '.', ' ');
  4043. // * returns 13: '100 050.00'
  4044. // Strip all characters but numerical ones.
  4045. number = (number + '').replace(/[^0-9+\-Ee.]/g, '');
  4046. var n = !isFinite(+number) ? 0 : +number,
  4047. prec = !isFinite(+decimals) ? 0 : Math.abs(decimals),
  4048. sep = (typeof thousands_sep === 'undefined') ? ',' : thousands_sep,
  4049. dec = (typeof dec_point === 'undefined') ? '.' : dec_point,
  4050. s = '',
  4051. toFixedFix = function (n, prec) {
  4052. var k = Math.pow(10, prec);
  4053. return '' + Math.round(n * k) / k;
  4054. };
  4055. // Fix for IE parseFloat(0.55).toFixed(0) = 0;
  4056. s = (prec ? toFixedFix(n, prec) : '' + Math.round(n)).split('.');
  4057. if (s[0].length > 3) {
  4058. s[0] = s[0].replace(/\B(?=(?:\d{3})+(?!\d))/g, sep);
  4059. }
  4060. if ((s[1] || '').length < prec) {
  4061. s[1] = s[1] || '';
  4062. s[1] += new Array(prec - s[1].length + 1).join('0');
  4063. }
  4064. return s.join(dec);
  4065. };
  4066. php.ord = function (string) {
  4067. // Returns the codepoint value of a character
  4068. //
  4069. // version: 1103.1210
  4070. // discuss at: http://phpjs.org/functions/ord
  4071. // + original by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
  4072. // + bugfixed by: Onno Marsman
  4073. // + improved by: Brett Zamir (http://brett-zamir.me)
  4074. // + input by: incidence
  4075. // * example 1: \php.ord('K');
  4076. // * returns 1: 75
  4077. // * example 2: \php.ord('\uD800\uDC00'); // surrogate pair to create a single Unicode character
  4078. // * returns 2: 65536
  4079. var str = string + '',
  4080. code = str.charCodeAt(0);
  4081. if (0xD800 <= code && code <= 0xDBFF) { // High surrogate (could change last hex to 0xDB7F to treat high private surrogates as single characters)
  4082. var hi = code;
  4083. if (str.length === 1) {
  4084. return code; // This is just a high surrogate with no following low surrogate, so we return its value;
  4085. // we could also throw an error as it is not a complete character, but someone may want to know
  4086. }
  4087. var low = str.charCodeAt(1);
  4088. return ((hi - 0xD800) * 0x400) + (low - 0xDC00) + 0x10000;
  4089. }
  4090. if (0xDC00 <= code && code <= 0xDFFF) { // Low surrogate
  4091. return code; // This is just a low surrogate with no preceding high surrogate, so we return its value;
  4092. // we could also throw an error as it is not a complete character, but someone may want to know
  4093. }
  4094. return code;
  4095. };
  4096. php.parse_str = function (str, array) {
  4097. // Parses GET/POST/COOKIE data and sets global variables
  4098. //
  4099. // version: 1103.1210
  4100. // discuss at: http://phpjs.org/functions/parse_str
  4101. // + original by: Cagri Ekin
  4102. // + improved by: Michael White (http://getsprink.com)
  4103. // + tweaked by: Jack
  4104. // + bugfixed by: Onno Marsman
  4105. // + reimplemented by: stag019
  4106. // + bugfixed by: Brett Zamir (http://brett-zamir.me)
  4107. // + bugfixed by: stag019
  4108. // - depends on: urldecode
  4109. // + input by: Dreamer
  4110. // + bugfixed by: Brett Zamir (http://brett-zamir.me)
  4111. // % note 1: When no argument is specified, will put variables in global scope.
  4112. // * example 1: \php.var arr = {};
  4113. // * example 1: \php.parse_str('first=foo&second=bar', arr);
  4114. // * results 1: arr == { first: 'foo', second: 'bar' }
  4115. // * example 2: \php.var arr = {};
  4116. // * example 2: \php.parse_str('str_a=Jack+and+Jill+didn%27t+see+the+well.', arr);
  4117. // * results 2: arr == { str_a: "Jack and Jill didn't see the well." }
  4118. var glue1 = '=',
  4119. glue2 = '&',
  4120. array2 = String(str).replace(/^&?([\s\S]*?)&?$/, '$1').split(glue2),
  4121. i, j, chr, tmp, key, value, bracket, keys, evalStr, that = this,
  4122. fixStr = function (str) {
  4123. return that.urldecode(str).replace(/([\\"'])/g, '\\$1').replace(/\n/g, '\\n').replace(/\r/g, '\\r');
  4124. };
  4125. if (!array) {
  4126. array = this.window;
  4127. }
  4128. for (i = 0; i < array2.length; i++) {
  4129. tmp = array2[i].split(glue1);
  4130. if (tmp.length < 2) {
  4131. tmp = [tmp, ''];
  4132. }
  4133. key = fixStr(tmp[0]);
  4134. value = fixStr(tmp[1]);
  4135. while (key.charAt(0) === ' ') {
  4136. key = key.substr(1);
  4137. }
  4138. if (key.indexOf('\0') !== -1) {
  4139. key = key.substr(0, key.indexOf('\0'));
  4140. }
  4141. if (key && key.charAt(0) !== '[') {
  4142. keys = [];
  4143. bracket = 0;
  4144. for (j = 0; j < key.length; j++) {
  4145. if (key.charAt(j) === '[' && !bracket) {
  4146. bracket = j + 1;
  4147. } else if (key.charAt(j) === ']') {
  4148. if (bracket) {
  4149. if (!keys.length) {
  4150. keys.push(key.substr(0, bracket - 1));
  4151. }
  4152. keys.push(key.substr(bracket, j - bracket));
  4153. bracket = 0;
  4154. if (key.charAt(j + 1) !== '[') {
  4155. break;
  4156. }
  4157. }
  4158. }
  4159. }
  4160. if (!keys.length) {
  4161. keys = [key];
  4162. }
  4163. for (j = 0; j < keys[0].length; j++) {
  4164. chr = keys[0].charAt(j);
  4165. if (chr === ' ' || chr === '.' || chr === '[') {
  4166. keys[0] = keys[0].substr(0, j) + '_' + keys[0].substr(j + 1);
  4167. }
  4168. if (chr === '[') {
  4169. break;
  4170. }
  4171. }
  4172. evalStr = 'array';
  4173. for (j = 0; j < keys.length; j++) {
  4174. key = keys[j];
  4175. if ((key !== '' && key !== ' ') || j === 0) {
  4176. key = "'" + key + "'";
  4177. } else {
  4178. key = eval(evalStr + '.push([]);') - 1;
  4179. }
  4180. evalStr += '[' + key + ']';
  4181. if (j !== keys.length - 1 && eval('typeof ' + evalStr) === 'undefined') {
  4182. eval(evalStr + ' = [];');
  4183. }
  4184. }
  4185. evalStr += " = '" + value + "';\n";
  4186. eval(evalStr);
  4187. }
  4188. }
  4189. };
  4190. php.parse_url = function (str, component) {
  4191. // Parse a URL and return its components
  4192. //
  4193. // version: 1103.1210
  4194. // discuss at: http://phpjs.org/functions/parse_url
  4195. // + original by: Steven Levithan (http://blog.stevenlevithan.com)
  4196. // + reimplemented by: Brett Zamir (http://brett-zamir.me)
  4197. // + input by: Lorenzo Pisani
  4198. // + input by: Tony
  4199. // + improved by: Brett Zamir (http://brett-zamir.me)
  4200. // % note: Based on http://stevenlevithan.com/demo/parseuri/js/assets/parseuri.js
  4201. // % note: blog post at http://blog.stevenlevithan.com/archives/parseuri
  4202. // % note: demo at http://stevenlevithan.com/demo/parseuri/js/assets/parseuri.js
  4203. // % note: Does not replace invalid characters with '_' as in PHP, nor does it return false with
  4204. // % note: a seriously malformed URL.
  4205. // % note: Besides function name, is essentially the same as parseUri as well as our allowing
  4206. // % note: an extra slash after the scheme/protocol (to allow file:/// as in PHP)
  4207. // * example 1: \php.parse_url('http://username:password@hostname/path?arg=value#anchor');
  4208. // * returns 1: {scheme: 'http', host: 'hostname', user: 'username', pass: 'password', path: '/path', query: 'arg=value', fragment: 'anchor'}
  4209. var key = ['source', 'scheme', 'authority', 'userInfo', 'user', 'pass', 'host', 'port',
  4210. 'relative', 'path', 'directory', 'file', 'query', 'fragment'],
  4211. ini = (this.php_js && this.php_js.ini) || {},
  4212. mode = (ini['phpjs.parse_url.mode'] &&
  4213. ini['phpjs.parse_url.mode'].local_value) || 'php',
  4214. parser = {
  4215. php: /^(?:([^:\/?#]+):)?(?:\/\/()(?:(?:()(?:([^:@]*):?([^:@]*))?@)?([^:\/?#]*)(?::(\d*))?))?()(?:(()(?:(?:[^?#\/]*\/)*)()(?:[^?#]*))(?:\?([^#]*))?(?:#(.*))?)/,
  4216. strict: /^(?:([^:\/?#]+):)?(?:\/\/((?:(([^:@]*):?([^:@]*))?@)?([^:\/?#]*)(?::(\d*))?))?((((?:[^?#\/]*\/)*)([^?#]*))(?:\?([^#]*))?(?:#(.*))?)/,
  4217. loose: /^(?:(?![^:@]+:[^:@\/]*@)([^:\/?#.]+):)?(?:\/\/\/?)?((?:(([^:@]*):?([^:@]*))?@)?([^:\/?#]*)(?::(\d*))?)(((\/(?:[^?#](?![^?#\/]*\.[^?#\/.]+(?:[?#]|$)))*\/?)?([^?#\/]*))(?:\?([^#]*))?(?:#(.*))?)/ // Added one optional slash to post-scheme to catch file:/// (should restrict this)
  4218. };
  4219. var m = parser[mode].exec(str),
  4220. uri = {},
  4221. i = 14;
  4222. while (i--) {
  4223. if (m[i]) {
  4224. uri[key[i]] = m[i];
  4225. }
  4226. }
  4227. if (component) {
  4228. return uri[component.replace('PHP_URL_', '').toLowerCase()];
  4229. }
  4230. if (mode !== 'php') {
  4231. var name = (ini['phpjs.parse_url.queryKey'] &&
  4232. ini['phpjs.parse_url.queryKey'].local_value) || 'queryKey';
  4233. parser = /(?:^|&)([^&=]*)=?([^&]*)/g;
  4234. uri[name] = {};
  4235. uri[key[12]].replace(parser, function ($0, $1, $2) {
  4236. if ($1) {uri[name][$1] = $2;}
  4237. });
  4238. }
  4239. delete uri.source;
  4240. return uri;
  4241. };
  4242. php.printf = function () {
  4243. // Output a formatted string
  4244. //
  4245. // version: 1103.1210
  4246. // discuss at: http://phpjs.org/functions/printf
  4247. // + original by: Ash Searle (http://hexmen.com/blog/)
  4248. // + improved by: Michael White (http://getsprink.com)
  4249. // + improved by: Brett Zamir (http://brett-zamir.me)
  4250. // - depends on: sprintf
  4251. // * example 1: \php.printf("%01.2f", 123.1);
  4252. // * returns 1: 6
  4253. var body, elmt, d = this.window.document;
  4254. var ret = '';
  4255. var HTMLNS = 'http://www.w3.org/1999/xhtml';
  4256. body = d.getElementsByTagNameNS ? (d.getElementsByTagNameNS(HTMLNS, 'body')[0] ? d.getElementsByTagNameNS(HTMLNS, 'body')[0] : d.documentElement.lastChild) : d.getElementsByTagName('body')[0];
  4257. if (!body) {
  4258. return false;
  4259. }
  4260. ret = this.sprintf.apply(this, arguments);
  4261. elmt = d.createTextNode(ret);
  4262. body.appendChild(elmt);
  4263. return ret.length;
  4264. };
  4265. php.property_exists = function (cls, prop) {
  4266. // Checks if the object or class has a property
  4267. //
  4268. // version: 1103.1210
  4269. // discuss at: http://phpjs.org/functions/property_exists
  4270. // + original by: Brett Zamir (http://brett-zamir.me)
  4271. // * example 1: \php.function class_a () {this.prop1 = 'one'};
  4272. // * example 1: \php.var instance_a = new class_a();
  4273. // * example 1: \php.property_exists(instance_a, 'prop1');
  4274. // * returns 1: true
  4275. // * example 2: \php.function class_a () {this.prop1 = 'one'};
  4276. // * example 2: \php.var instance_a = new class_a();
  4277. // * example 2: \php.property_exists(instance_a, 'prop2');
  4278. // * returns 2: false
  4279. cls = (typeof cls === 'string') ? this.window[cls] : cls;
  4280. if (typeof cls === 'function' && cls.toSource && cls.toSource().match(new RegExp('this\\.' + prop + '\\s'))) {
  4281. // Hackish and non-standard but can probably detect if setting
  4282. // the property (we don't want to test by instantiating as that
  4283. // may have side-effects)
  4284. return true;
  4285. }
  4286. return (cls[prop] !== undefined && typeof cls[prop] !== 'function') || (cls.prototype !== undefined && cls.prototype[prop] !== undefined && typeof cls.prototype[prop] !== 'function') || (cls.constructor && cls.constructor[prop] !== undefined && typeof cls.constructor[prop] !== 'function');
  4287. };
  4288. php.quotemeta = function (str) {
  4289. // Quotes meta characters
  4290. //
  4291. // version: 1103.1210
  4292. // discuss at: http://phpjs.org/functions/quotemeta
  4293. // + original by: Paulo Freitas
  4294. // * example 1: \php.quotemeta(". + * ? ^ ( $ )");
  4295. // * returns 1: '\. \+ \* \? \^ \( \$ \)'
  4296. return (str + '').replace(/([\.\\\+\*\?\[\^\]\$\(\)])/g, '\\$1');
  4297. };
  4298. php.rand = function (min, max) {
  4299. // Returns a random number
  4300. //
  4301. // version: 1103.1210
  4302. // discuss at: http://phpjs.org/functions/rand
  4303. // + original by: Leslie Hoare
  4304. // + bugfixed by: Onno Marsman
  4305. // % note 1: See the commented out code below for a version which will work with our experimental (though probably unnecessary) srand() function)
  4306. // * example 1: \php.rand(1, 1);
  4307. // * returns 1: 1
  4308. var argc = arguments.length;
  4309. if (argc === 0) {
  4310. min = 0;
  4311. max = 2147483647;
  4312. } else if (argc === 1) {
  4313. throw new Error('Warning: rand() expects exactly 2 parameters, 1 given');
  4314. }
  4315. return Math.floor(Math.random() * (max - min + 1)) + min;
  4316. /*
  4317. // See note above for an explanation of the following alternative code
  4318. // + reimplemented by: Brett Zamir (http://brett-zamir.me)
  4319. // - depends on: srand
  4320. // % note 1: This is a very possibly imperfect adaptation from the PHP source code
  4321. var rand_seed, ctx, PHP_RAND_MAX=2147483647; // 0x7fffffff
  4322. if (!this.php_js || this.php_js.rand_seed === undefined) {
  4323. this.srand();
  4324. }
  4325. rand_seed = this.php_js.rand_seed;
  4326. var argc = arguments.length;
  4327. if (argc === 1) {
  4328. throw new Error('Warning: rand() expects exactly 2 parameters, 1 given');
  4329. }
  4330. var do_rand = function (ctx) {
  4331. return ((ctx * 1103515245 + 12345) % (PHP_RAND_MAX + 1));
  4332. };
  4333. var php_rand = function (ctxArg) { // php_rand_r
  4334. this.php_js.rand_seed = do_rand(ctxArg);
  4335. return parseInt(this.php_js.rand_seed, 10);
  4336. };
  4337. var number = php_rand(rand_seed);
  4338. if (argc === 2) {
  4339. number = min + parseInt(parseFloat(parseFloat(max) - min + 1.0) * (number/(PHP_RAND_MAX + 1.0)), 10);
  4340. }
  4341. return number;
  4342. */
  4343. };
  4344. php.range = function (low, high, step) {
  4345. // Create an array containing the range of integers or characters from low to high (inclusive)
  4346. //
  4347. // version: 1103.1210
  4348. // discuss at: http://phpjs.org/functions/range
  4349. // + original by: Waldo Malqui Silva
  4350. // * example 1: \php.range ( 0, 12 );
  4351. // * returns 1: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12]
  4352. // * example 2: \php.range( 0, 100, 10 );
  4353. // * returns 2: [0, 10, 20, 30, 40, 50, 60, 70, 80, 90, 100]
  4354. // * example 3: \php.range( 'a', 'i' );
  4355. // * returns 3: ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i']
  4356. // * example 4: \php.range( 'c', 'a' );
  4357. // * returns 4: ['c', 'b', 'a']
  4358. var matrix = [];
  4359. var inival, endval, plus;
  4360. var walker = step || 1;
  4361. var chars = false;
  4362. if (!isNaN(low) && !isNaN(high)) {
  4363. inival = low;
  4364. endval = high;
  4365. } else if (isNaN(low) && isNaN(high)) {
  4366. chars = true;
  4367. inival = low.charCodeAt(0);
  4368. endval = high.charCodeAt(0);
  4369. } else {
  4370. inival = (isNaN(low) ? 0 : low);
  4371. endval = (isNaN(high) ? 0 : high);
  4372. }
  4373. plus = ((inival > endval) ? false : true);
  4374. if (plus) {
  4375. while (inival <= endval) {
  4376. matrix.push(((chars) ? String.fromCharCode(inival) : inival));
  4377. inival += walker;
  4378. }
  4379. } else {
  4380. while (inival >= endval) {
  4381. matrix.push(((chars) ? String.fromCharCode(inival) : inival));
  4382. inival -= walker;
  4383. }
  4384. }
  4385. return matrix;
  4386. };
  4387. php.reset = function (arr) {
  4388. // Set array argument's internal pointer to the first element and return it
  4389. //
  4390. // version: 1103.1210
  4391. // discuss at: http://phpjs.org/functions/reset
  4392. // + original by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
  4393. // + bugfixed by: Legaev Andrey
  4394. // + revised by: Brett Zamir (http://brett-zamir.me)
  4395. // % note 1: Uses global: php_js to store the array pointer
  4396. // * example 1: \php.reset({0: 'Kevin', 1: 'van', 2: 'Zonneveld'});
  4397. // * returns 1: 'Kevin'
  4398. // BEGIN REDUNDANT
  4399. this.php_js = this.php_js || {};
  4400. this.php_js.pointers = this.php_js.pointers || [];
  4401. var indexOf = function (value) {
  4402. for (var i = 0, length = this.length; i < length; i++) {
  4403. if (this[i] === value) {
  4404. return i;
  4405. }
  4406. }
  4407. return -1;
  4408. };
  4409. // END REDUNDANT
  4410. var pointers = this.php_js.pointers;
  4411. if (!pointers.indexOf) {
  4412. pointers.indexOf = indexOf;
  4413. }
  4414. if (pointers.indexOf(arr) === -1) {
  4415. pointers.push(arr, 0);
  4416. }
  4417. var arrpos = pointers.indexOf(arr);
  4418. if (!(arr instanceof Array)) {
  4419. for (var k in arr) {
  4420. if (pointers.indexOf(arr) === -1) {
  4421. pointers.push(arr, 0);
  4422. } else {
  4423. pointers[arrpos + 1] = 0;
  4424. }
  4425. return arr[k];
  4426. }
  4427. return false; // Empty
  4428. }
  4429. if (arr.length === 0) {
  4430. return false;
  4431. }
  4432. pointers[arrpos + 1] = 0;
  4433. return arr[pointers[arrpos + 1]];
  4434. };
  4435. php.round = function (value, precision, mode) {
  4436. // Returns the number rounded to specified precision
  4437. //
  4438. // version: 1103.1210
  4439. // discuss at: http://phpjs.org/functions/round
  4440. // + original by: Philip Peterson
  4441. // + revised by: Onno Marsman
  4442. // + input by: Greenseed
  4443. // + revised by: T.Wild
  4444. // + input by: meo
  4445. // + input by: William
  4446. // + bugfixed by: Brett Zamir (http://brett-zamir.me)
  4447. // + input by: Josep Sanz (http://www.ws3.es/)
  4448. // + revised by: Rafał Kukawski (http://blog.kukawski.pl/)
  4449. // % note 1: Great work. Ideas for improvement:
  4450. // % note 1: - code more compliant with developer guidelines
  4451. // % note 1: - for implementing PHP constant arguments look at
  4452. // % note 1: the pathinfo() function, it offers the greatest
  4453. // % note 1: flexibility & compatibility possible
  4454. // * example 1: \php.round(1241757, -3);
  4455. // * returns 1: 1242000
  4456. // * example 2: \php.round(3.6);
  4457. // * returns 2: 4
  4458. // * example 3: \php.round(2.835, 2);
  4459. // * returns 3: 2.84
  4460. // * example 4: \php.round(1.1749999999999, 2);
  4461. // * returns 4: 1.17
  4462. // * example 5: \php.round(58551.799999999996, 2);
  4463. // * returns 5: 58551.8
  4464. var m, f, isHalf, sgn; // helper variables
  4465. precision |= 0; // making sure precision is integer
  4466. m = Math.pow(10, precision);
  4467. value *= m;
  4468. sgn = (value > 0) | -(value < 0); // sign of the number
  4469. isHalf = value % 1 === 0.5 * sgn;
  4470. f = Math.floor(value);
  4471. if (isHalf) {
  4472. switch (mode) {
  4473. case 'PHP_ROUND_HALF_DOWN':
  4474. value = f + (sgn < 0); // rounds .5 toward zero
  4475. break;
  4476. case 'PHP_ROUND_HALF_EVEN':
  4477. value = f + (f % 2 * sgn); // rouds .5 towards the next even integer
  4478. break;
  4479. case 'PHP_ROUND_HALF_ODD':
  4480. value = f + !(f % 2); // rounds .5 towards the next odd integer
  4481. break;
  4482. default:
  4483. value = f + (sgn > 0); // rounds .5 away from zero
  4484. }
  4485. }
  4486. return (isHalf ? value : Math.round(value)) / m;
  4487. };
  4488. php.rsort = function (inputArr, sort_flags) {
  4489. // Sort an array in reverse order
  4490. //
  4491. // version: 1103.1210
  4492. // discuss at: http://phpjs.org/functions/rsort
  4493. // + original by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
  4494. // + revised by: Brett Zamir (http://brett-zamir.me)
  4495. // + improved by: Brett Zamir (http://brett-zamir.me)
  4496. // % note 1: SORT_STRING (as well as natsort and natcasesort) might also be
  4497. // % note 1: integrated into all of these functions by adapting the code at
  4498. // % note 1: http://sourcefrog.net/projects/natsort/natcompare.js
  4499. // % note 2: This function deviates from PHP in returning a copy of the array instead
  4500. // % note 2: of acting by reference and returning true; this was necessary because
  4501. // % note 2: IE does not allow deleting and re-adding of properties without caching
  4502. // % note 2: of property position; you can set the ini of "phpjs.strictForIn" to true to
  4503. // % note 2: get the PHP behavior, but use this only if you are in an environment
  4504. // % note 2: such as Firefox extensions where for-in iteration order is fixed and true
  4505. // % note 2: property deletion is supported. Note that we intend to implement the PHP
  4506. // % note 2: behavior by default if IE ever does allow it; only gives shallow copy since
  4507. // % note 2: is by reference in PHP anyways
  4508. // % note 3: Since JS objects' keys are always strings, and (the
  4509. // % note 3: default) SORT_REGULAR flag distinguishes by key type,
  4510. // % note 3: if the content is a numeric string, we treat the
  4511. // % note 3: "original type" as numeric.
  4512. // - depends on: i18n_loc_get_default
  4513. // * example 1: \php.rsort(['Kevin', 'van', 'Zonneveld']);
  4514. // * returns 1: ['van', 'Zonneveld', 'Kevin']
  4515. // * example 2: \php.ini_set('phpjs.strictForIn', true);
  4516. // * example 2: \php.fruits = {d: 'lemon', a: 'orange', b: 'banana', c: 'apple'};
  4517. // * example 2: \php.rsort(fruits);
  4518. // * results 2: fruits == {0: 'orange', 1: 'lemon', 2: 'banana', 3: 'apple'}
  4519. // * returns 2: true
  4520. var valArr = [],
  4521. k = '',
  4522. i = 0,
  4523. sorter = false,
  4524. that = this,
  4525. strictForIn = false,
  4526. populateArr = [];
  4527. switch (sort_flags) {
  4528. case 'SORT_STRING':
  4529. // compare items as strings
  4530. sorter = function (a, b) {
  4531. return that.strnatcmp(b, a);
  4532. };
  4533. break;
  4534. case 'SORT_LOCALE_STRING':
  4535. // compare items as strings, based on the current locale (set with i18n_loc_set_default() as of PHP6)
  4536. var loc = this.i18n_loc_get_default();
  4537. sorter = this.php_js.i18nLocales[loc].sorting;
  4538. break;
  4539. case 'SORT_NUMERIC':
  4540. // compare items numerically
  4541. sorter = function (a, b) {
  4542. return (b - a);
  4543. };
  4544. break;
  4545. case 'SORT_REGULAR':
  4546. // compare items normally (don't change types)
  4547. default:
  4548. sorter = function (b, a) {
  4549. var aFloat = parseFloat(a),
  4550. bFloat = parseFloat(b),
  4551. aNumeric = aFloat + '' === a,
  4552. bNumeric = bFloat + '' === b;
  4553. if (aNumeric && bNumeric) {
  4554. return aFloat > bFloat ? 1 : aFloat < bFloat ? -1 : 0;
  4555. } else if (aNumeric && !bNumeric) {
  4556. return 1;
  4557. } else if (!aNumeric && bNumeric) {
  4558. return -1;
  4559. }
  4560. return a > b ? 1 : a < b ? -1 : 0;
  4561. };
  4562. break;
  4563. }
  4564. // BEGIN REDUNDANT
  4565. this.php_js = this.php_js || {};
  4566. this.php_js.ini = this.php_js.ini || {};
  4567. // END REDUNDANT
  4568. strictForIn = this.php_js.ini['phpjs.strictForIn'] && this.php_js.ini['phpjs.strictForIn'].local_value && this.php_js.ini['phpjs.strictForIn'].local_value !== 'off';
  4569. populateArr = strictForIn ? inputArr : populateArr;
  4570. for (k in inputArr) { // Get key and value arrays
  4571. if (inputArr.hasOwnProperty(k)) {
  4572. valArr.push(inputArr[k]);
  4573. if (strictForIn) {
  4574. delete inputArr[k];
  4575. }
  4576. }
  4577. }
  4578. valArr.sort(sorter);
  4579. for (i = 0; i < valArr.length; i++) { // Repopulate the old array
  4580. populateArr[i] = valArr[i];
  4581. }
  4582. return strictForIn || populateArr;
  4583. };
  4584. php.setcookie = function (name, value, expires, path, domain, secure) {
  4585. // Send a cookie
  4586. //
  4587. // version: 1103.1210
  4588. // discuss at: http://phpjs.org/functions/setcookie
  4589. // + original by: Jonas Raoni Soares Silva (http://www.jsfromhell.com)
  4590. // + bugfixed by: Andreas
  4591. // + bugfixed by: Onno Marsman
  4592. // + improved by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
  4593. // - depends on: setrawcookie
  4594. // * example 1: \php.setcookie('author_name', 'Kevin van Zonneveld');
  4595. // * returns 1: true
  4596. return this.setrawcookie(name, encodeURIComponent(value), expires, path, domain, secure);
  4597. };
  4598. php.setrawcookie = function (name, value, expires, path, domain, secure) {
  4599. // Send a cookie with no url encoding of the value
  4600. //
  4601. // version: 1103.1210
  4602. // discuss at: http://phpjs.org/functions/setrawcookie
  4603. // + original by: Brett Zamir (http://brett-zamir.me)
  4604. // + improved by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
  4605. // + derived from: setcookie
  4606. // + input by: Michael
  4607. // + bugfixed by: Brett Zamir (http://brett-zamir.me)
  4608. // * example 1: \php.setcookie('author_name', 'Kevin van Zonneveld');
  4609. // * returns 1: true
  4610. if (typeof expires === 'string' && (/^\d+$/).test(expires)) {
  4611. expires = parseInt(expires, 10);
  4612. }
  4613. if (expires instanceof Date) {
  4614. expires = expires.toGMTString();
  4615. } else if (typeof(expires) === 'number') {
  4616. expires = (new Date(expires * 1e3)).toGMTString();
  4617. }
  4618. var r = [name + '=' + value],
  4619. s = {},
  4620. i = '';
  4621. s = {
  4622. expires: expires,
  4623. path: path,
  4624. domain: domain
  4625. };
  4626. for (i in s) {
  4627. if (s.hasOwnProperty(i)) { // Exclude items on Object.prototype
  4628. s[i] && r.push(i + '=' + s[i]);
  4629. }
  4630. }
  4631. return secure && r.push('secure'), this.window.document.cookie = r.join(";"), true;
  4632. };
  4633. php.sha1 = function (str) {
  4634. // Calculate the sha1 hash of a string
  4635. //
  4636. // version: 1103.1210
  4637. // discuss at: http://phpjs.org/functions/sha1
  4638. // + original by: Webtoolkit.info (http://www.webtoolkit.info/)
  4639. // + namespaced by: Michael White (http://getsprink.com)
  4640. // + input by: Brett Zamir (http://brett-zamir.me)
  4641. // + improved by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
  4642. // - depends on: utf8_encode
  4643. // * example 1: \php.sha1('Kevin van Zonneveld');
  4644. // * returns 1: '54916d2e62f65b3afa6e192e6a601cdbe5cb5897'
  4645. var rotate_left = function (n, s) {
  4646. var t4 = (n << s) | (n >>> (32 - s));
  4647. return t4;
  4648. };
  4649. /*var lsb_hex = function (val) { // Not in use; needed?
  4650. var str="";
  4651. var i;
  4652. var vh;
  4653. var vl;
  4654. for ( i=0; i<=6; i+=2 ) {
  4655. vh = (val>>>(i*4+4))&0x0f;
  4656. vl = (val>>>(i*4))&0x0f;
  4657. str += vh.toString(16) + vl.toString(16);
  4658. }
  4659. return str;
  4660. };*/
  4661. var cvt_hex = function (val) {
  4662. var str = "";
  4663. var i;
  4664. var v;
  4665. for (i = 7; i >= 0; i--) {
  4666. v = (val >>> (i * 4)) & 0x0f;
  4667. str += v.toString(16);
  4668. }
  4669. return str;
  4670. };
  4671. var blockstart;
  4672. var i, j;
  4673. var W = new Array(80);
  4674. var H0 = 0x67452301;
  4675. var H1 = 0xEFCDAB89;
  4676. var H2 = 0x98BADCFE;
  4677. var H3 = 0x10325476;
  4678. var H4 = 0xC3D2E1F0;
  4679. var A, B, C, D, E;
  4680. var temp;
  4681. str = this.utf8_encode(str);
  4682. var str_len = str.length;
  4683. var word_array = [];
  4684. for (i = 0; i < str_len - 3; i += 4) {
  4685. j = str.charCodeAt(i) << 24 | str.charCodeAt(i + 1) << 16 | str.charCodeAt(i + 2) << 8 | str.charCodeAt(i + 3);
  4686. word_array.push(j);
  4687. }
  4688. switch (str_len % 4) {
  4689. case 0:
  4690. i = 0x080000000;
  4691. break;
  4692. case 1:
  4693. i = str.charCodeAt(str_len - 1) << 24 | 0x0800000;
  4694. break;
  4695. case 2:
  4696. i = str.charCodeAt(str_len - 2) << 24 | str.charCodeAt(str_len - 1) << 16 | 0x08000;
  4697. break;
  4698. case 3:
  4699. i = str.charCodeAt(str_len - 3) << 24 | str.charCodeAt(str_len - 2) << 16 | str.charCodeAt(str_len - 1) << 8 | 0x80;
  4700. break;
  4701. }
  4702. word_array.push(i);
  4703. while ((word_array.length % 16) != 14) {
  4704. word_array.push(0);
  4705. }
  4706. word_array.push(str_len >>> 29);
  4707. word_array.push((str_len << 3) & 0x0ffffffff);
  4708. for (blockstart = 0; blockstart < word_array.length; blockstart += 16) {
  4709. for (i = 0; i < 16; i++) {
  4710. W[i] = word_array[blockstart + i];
  4711. }
  4712. for (i = 16; i <= 79; i++) {
  4713. W[i] = rotate_left(W[i - 3] ^ W[i - 8] ^ W[i - 14] ^ W[i - 16], 1);
  4714. }
  4715. A = H0;
  4716. B = H1;
  4717. C = H2;
  4718. D = H3;
  4719. E = H4;
  4720. for (i = 0; i <= 19; i++) {
  4721. temp = (rotate_left(A, 5) + ((B & C) | (~B & D)) + E + W[i] + 0x5A827999) & 0x0ffffffff;
  4722. E = D;
  4723. D = C;
  4724. C = rotate_left(B, 30);
  4725. B = A;
  4726. A = temp;
  4727. }
  4728. for (i = 20; i <= 39; i++) {
  4729. temp = (rotate_left(A, 5) + (B ^ C ^ D) + E + W[i] + 0x6ED9EBA1) & 0x0ffffffff;
  4730. E = D;
  4731. D = C;
  4732. C = rotate_left(B, 30);
  4733. B = A;
  4734. A = temp;
  4735. }
  4736. for (i = 40; i <= 59; i++) {
  4737. temp = (rotate_left(A, 5) + ((B & C) | (B & D) | (C & D)) + E + W[i] + 0x8F1BBCDC) & 0x0ffffffff;
  4738. E = D;
  4739. D = C;
  4740. C = rotate_left(B, 30);
  4741. B = A;
  4742. A = temp;
  4743. }
  4744. for (i = 60; i <= 79; i++) {
  4745. temp = (rotate_left(A, 5) + (B ^ C ^ D) + E + W[i] + 0xCA62C1D6) & 0x0ffffffff;
  4746. E = D;
  4747. D = C;
  4748. C = rotate_left(B, 30);
  4749. B = A;
  4750. A = temp;
  4751. }
  4752. H0 = (H0 + A) & 0x0ffffffff;
  4753. H1 = (H1 + B) & 0x0ffffffff;
  4754. H2 = (H2 + C) & 0x0ffffffff;
  4755. H3 = (H3 + D) & 0x0ffffffff;
  4756. H4 = (H4 + E) & 0x0ffffffff;
  4757. }
  4758. temp = cvt_hex(H0) + cvt_hex(H1) + cvt_hex(H2) + cvt_hex(H3) + cvt_hex(H4);
  4759. return temp.toLowerCase();
  4760. };
  4761. php.shuffle = function (inputArr) {
  4762. // Randomly shuffle the contents of an array
  4763. //
  4764. // version: 1103.1210
  4765. // discuss at: http://phpjs.org/functions/shuffle
  4766. // + original by: Jonas Raoni Soares Silva (http://www.jsfromhell.com)
  4767. // + revised by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
  4768. // + revised by: Brett Zamir (http://brett-zamir.me)
  4769. // + improved by: Brett Zamir (http://brett-zamir.me)
  4770. // % note 1: This function deviates from PHP in returning a copy of the array instead
  4771. // % note 1: of acting by reference and returning true; this was necessary because
  4772. // % note 1: IE does not allow deleting and re-adding of properties without caching
  4773. // % note 1: of property position; you can set the ini of "phpjs.strictForIn" to true to
  4774. // % note 1: get the PHP behavior, but use this only if you are in an environment
  4775. // % note 1: such as Firefox extensions where for-in iteration order is fixed and true
  4776. // % note 1: property deletion is supported. Note that we intend to implement the PHP
  4777. // % note 1: behavior by default if IE ever does allow it; only gives shallow copy since
  4778. // % note 1: is by reference in PHP anyways
  4779. // * example 1: \php.ini_set('phpjs.strictForIn', true);
  4780. // * example 1: \php.shuffle({5:'a', 2:'3', 3:'c', 4:5, 'q':5});
  4781. // * returns 1: {5:'a', 4:5, 'q':5, 3:'c', 2:'3'}
  4782. // * example 2: \php.ini_set('phpjs.strictForIn', true);
  4783. // * example 2: \php.var data = {5:'a', 2:'3', 3:'c', 4:5, 'q':5};
  4784. // * example 2: \php.shuffle(data);
  4785. // * results 2: {5:'a', 'q':5, 3:'c', 2:'3', 4:5}
  4786. // * returns 2: true
  4787. var valArr = [],
  4788. k = '',
  4789. i = 0,
  4790. strictForIn = false,
  4791. populateArr = [];
  4792. for (k in inputArr) { // Get key and value arrays
  4793. if (inputArr.hasOwnProperty(k)) {
  4794. valArr.push(inputArr[k]);
  4795. if (strictForIn) {
  4796. delete inputArr[k];
  4797. }
  4798. }
  4799. }
  4800. valArr.sort(function () {
  4801. return 0.5 - Math.random();
  4802. });
  4803. // BEGIN REDUNDANT
  4804. this.php_js = this.php_js || {};
  4805. this.php_js.ini = this.php_js.ini || {};
  4806. // END REDUNDANT
  4807. strictForIn = this.php_js.ini['phpjs.strictForIn'] && this.php_js.ini['phpjs.strictForIn'].local_value && this.php_js.ini['phpjs.strictForIn'].local_value !== 'off';
  4808. populateArr = strictForIn ? inputArr : populateArr;
  4809. for (i = 0; i < valArr.length; i++) { // Repopulate the old array
  4810. populateArr[i] = valArr[i];
  4811. }
  4812. return strictForIn || populateArr;
  4813. };
  4814. php.sizeof = function (mixed_var, mode) {
  4815. // !No description available for sizeof. @php.js developers: Please update the function summary text file.
  4816. //
  4817. // version: 1103.1210
  4818. // discuss at: http://phpjs.org/functions/sizeof
  4819. // + original by: Philip Peterson
  4820. // - depends on: count
  4821. // * example 1: \php.sizeof([[0,0],[0,-4]], 'COUNT_RECURSIVE');
  4822. // * returns 1: 6
  4823. // * example 2: \php.sizeof({'one' : [1,2,3,4,5]}, 'COUNT_RECURSIVE');
  4824. // * returns 2: 6
  4825. return this.count(mixed_var, mode);
  4826. };
  4827. php.sort = function (inputArr, sort_flags) {
  4828. // Sort an array
  4829. //
  4830. // version: 1103.1210
  4831. // discuss at: http://phpjs.org/functions/sort
  4832. // + original by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
  4833. // + revised by: Brett Zamir (http://brett-zamir.me)
  4834. // + improved by: Brett Zamir (http://brett-zamir.me)
  4835. // % note 1: SORT_STRING (as well as natsort and natcasesort) might also be
  4836. // % note 1: integrated into all of these functions by adapting the code at
  4837. // % note 1: http://sourcefrog.net/projects/natsort/natcompare.js
  4838. // % note 2: This function deviates from PHP in returning a copy of the array instead
  4839. // % note 2: of acting by reference and returning true; this was necessary because
  4840. // % note 2: IE does not allow deleting and re-adding of properties without caching
  4841. // % note 2: of property position; you can set the ini of "phpjs.strictForIn" to true to
  4842. // % note 2: get the PHP behavior, but use this only if you are in an environment
  4843. // % note 2: such as Firefox extensions where for-in iteration order is fixed and true
  4844. // % note 2: property deletion is supported. Note that we intend to implement the PHP
  4845. // % note 2: behavior by default if IE ever does allow it; only gives shallow copy since
  4846. // % note 2: is by reference in PHP anyways
  4847. // % note 3: Since JS objects' keys are always strings, and (the
  4848. // % note 3: default) SORT_REGULAR flag distinguishes by key type,
  4849. // % note 3: if the content is a numeric string, we treat the
  4850. // % note 3: "original type" as numeric.
  4851. // - depends on: i18n_loc_get_default
  4852. // * example 1: \php.sort(['Kevin', 'van', 'Zonneveld']);
  4853. // * returns 1: ['Kevin', 'Zonneveld', 'van']
  4854. // * example 2: \php.ini_set('phpjs.strictForIn', true);
  4855. // * example 2: \php.fruits = {d: 'lemon', a: 'orange', b: 'banana', c: 'apple'};
  4856. // * example 2: \php.sort(fruits);
  4857. // * results 2: fruits == {0: 'apple', 1: 'banana', 2: 'lemon', 3: 'orange'}
  4858. // * returns 2: true
  4859. var valArr = [],
  4860. keyArr = [],
  4861. k = '',
  4862. i = 0,
  4863. sorter = false,
  4864. that = this,
  4865. strictForIn = false,
  4866. populateArr = [];
  4867. switch (sort_flags) {
  4868. case 'SORT_STRING':
  4869. // compare items as strings
  4870. sorter = function (a, b) {
  4871. return that.strnatcmp(a, b);
  4872. };
  4873. break;
  4874. case 'SORT_LOCALE_STRING':
  4875. // compare items as strings, based on the current locale (set with i18n_loc_set_default() as of PHP6)
  4876. var loc = this.i18n_loc_get_default();
  4877. sorter = this.php_js.i18nLocales[loc].sorting;
  4878. break;
  4879. case 'SORT_NUMERIC':
  4880. // compare items numerically
  4881. sorter = function (a, b) {
  4882. return (a - b);
  4883. };
  4884. break;
  4885. case 'SORT_REGULAR':
  4886. // compare items normally (don't change types)
  4887. default:
  4888. sorter = function (a, b) {
  4889. var aFloat = parseFloat(a),
  4890. bFloat = parseFloat(b),
  4891. aNumeric = aFloat + '' === a,
  4892. bNumeric = bFloat + '' === b;
  4893. if (aNumeric && bNumeric) {
  4894. return aFloat > bFloat ? 1 : aFloat < bFloat ? -1 : 0;
  4895. } else if (aNumeric && !bNumeric) {
  4896. return 1;
  4897. } else if (!aNumeric && bNumeric) {
  4898. return -1;
  4899. }
  4900. return a > b ? 1 : a < b ? -1 : 0;
  4901. };
  4902. break;
  4903. }
  4904. // BEGIN REDUNDANT
  4905. this.php_js = this.php_js || {};
  4906. this.php_js.ini = this.php_js.ini || {};
  4907. // END REDUNDANT
  4908. strictForIn = this.php_js.ini['phpjs.strictForIn'] && this.php_js.ini['phpjs.strictForIn'].local_value && this.php_js.ini['phpjs.strictForIn'].local_value !== 'off';
  4909. populateArr = strictForIn ? inputArr : populateArr;
  4910. for (k in inputArr) { // Get key and value arrays
  4911. if (inputArr.hasOwnProperty(k)) {
  4912. valArr.push(inputArr[k]);
  4913. if (strictForIn) {
  4914. delete inputArr[k];
  4915. }
  4916. }
  4917. }
  4918. valArr.sort(sorter);
  4919. for (i = 0; i < valArr.length; i++) { // Repopulate the old array
  4920. populateArr[i] = valArr[i];
  4921. }
  4922. return strictForIn || populateArr;
  4923. };
  4924. php.sprintf = function () {
  4925. // Return a formatted string
  4926. //
  4927. // version: 1103.1210
  4928. // discuss at: http://phpjs.org/functions/sprintf
  4929. // + original by: Ash Searle (http://hexmen.com/blog/)
  4930. // + namespaced by: Michael White (http://getsprink.com)
  4931. // + tweaked by: Jack
  4932. // + improved by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
  4933. // + input by: Paulo Freitas
  4934. // + improved by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
  4935. // + input by: Brett Zamir (http://brett-zamir.me)
  4936. // + improved by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
  4937. // * example 1: \php.sprintf("%01.2f", 123.1);
  4938. // * returns 1: 123.10
  4939. // * example 2: \php.sprintf("[%10s]", 'monkey');
  4940. // * returns 2: '[ monkey]'
  4941. // * example 3: \php.sprintf("[%'#10s]", 'monkey');
  4942. // * returns 3: '[####monkey]'
  4943. var regex = /%%|%(\d+\$)?([-+\'#0 ]*)(\*\d+\$|\*|\d+)?(\.(\*\d+\$|\*|\d+))?([scboxXuidfegEG])/g;
  4944. var a = arguments,
  4945. i = 0,
  4946. format = a[i++];
  4947. // pad()
  4948. var pad = function (str, len, chr, leftJustify) {
  4949. if (!chr) {
  4950. chr = ' ';
  4951. }
  4952. var padding = (str.length >= len) ? '' : Array(1 + len - str.length >>> 0).join(chr);
  4953. return leftJustify ? str + padding : padding + str;
  4954. };
  4955. // justify()
  4956. var justify = function (value, prefix, leftJustify, minWidth, zeroPad, customPadChar) {
  4957. var diff = minWidth - value.length;
  4958. if (diff > 0) {
  4959. if (leftJustify || !zeroPad) {
  4960. value = pad(value, minWidth, customPadChar, leftJustify);
  4961. } else {
  4962. value = value.slice(0, prefix.length) + pad('', diff, '0', true) + value.slice(prefix.length);
  4963. }
  4964. }
  4965. return value;
  4966. };
  4967. // formatBaseX()
  4968. var formatBaseX = function (value, base, prefix, leftJustify, minWidth, precision, zeroPad) {
  4969. // Note: casts negative numbers to positive ones
  4970. var number = value >>> 0;
  4971. prefix = prefix && number && {
  4972. '2': '0b',
  4973. '8': '0',
  4974. '16': '0x'
  4975. }[base] || '';
  4976. value = prefix + pad(number.toString(base), precision || 0, '0', false);
  4977. return justify(value, prefix, leftJustify, minWidth, zeroPad);
  4978. };
  4979. // formatString()
  4980. var formatString = function (value, leftJustify, minWidth, precision, zeroPad, customPadChar) {
  4981. if (precision != null) {
  4982. value = value.slice(0, precision);
  4983. }
  4984. return justify(value, '', leftJustify, minWidth, zeroPad, customPadChar);
  4985. };
  4986. // doFormat()
  4987. var doFormat = function (substring, valueIndex, flags, minWidth, _, precision, type) {
  4988. var number;
  4989. var prefix;
  4990. var method;
  4991. var textTransform;
  4992. var value;
  4993. if (substring == '%%') {
  4994. return '%';
  4995. }
  4996. // parse flags
  4997. var leftJustify = false,
  4998. positivePrefix = '',
  4999. zeroPad = false,
  5000. prefixBaseX = false,
  5001. customPadChar = ' ';
  5002. var flagsl = flags.length;
  5003. for (var j = 0; flags && j < flagsl; j++) {
  5004. switch (flags.charAt(j)) {
  5005. case ' ':
  5006. positivePrefix = ' ';
  5007. break;
  5008. case '+':
  5009. positivePrefix = '+';
  5010. break;
  5011. case '-':
  5012. leftJustify = true;
  5013. break;
  5014. case "'":
  5015. customPadChar = flags.charAt(j + 1);
  5016. break;
  5017. case '0':
  5018. zeroPad = true;
  5019. break;
  5020. case '#':
  5021. prefixBaseX = true;
  5022. break;
  5023. }
  5024. }
  5025. // parameters may be null, undefined, empty-string or real valued
  5026. // we want to ignore null, undefined and empty-string values
  5027. if (!minWidth) {
  5028. minWidth = 0;
  5029. } else if (minWidth == '*') {
  5030. minWidth = +a[i++];
  5031. } else if (minWidth.charAt(0) == '*') {
  5032. minWidth = +a[minWidth.slice(1, -1)];
  5033. } else {
  5034. minWidth = +minWidth;
  5035. }
  5036. // Note: undocumented perl feature:
  5037. if (minWidth < 0) {
  5038. minWidth = -minWidth;
  5039. leftJustify = true;
  5040. }
  5041. if (!isFinite(minWidth)) {
  5042. throw new Error('sprintf: (minimum-)width must be finite');
  5043. }
  5044. if (!precision) {
  5045. precision = 'fFeE'.indexOf(type) > -1 ? 6 : (type == 'd') ? 0 : undefined;
  5046. } else if (precision == '*') {
  5047. precision = +a[i++];
  5048. } else if (precision.charAt(0) == '*') {
  5049. precision = +a[precision.slice(1, -1)];
  5050. } else {
  5051. precision = +precision;
  5052. }
  5053. // grab value using valueIndex if required?
  5054. value = valueIndex ? a[valueIndex.slice(0, -1)] : a[i++];
  5055. switch (type) {
  5056. case 's':
  5057. return formatString(String(value), leftJustify, minWidth, precision, zeroPad, customPadChar);
  5058. case 'c':
  5059. return formatString(String.fromCharCode(+value), leftJustify, minWidth, precision, zeroPad);
  5060. case 'b':
  5061. return formatBaseX(value, 2, prefixBaseX, leftJustify, minWidth, precision, zeroPad);
  5062. case 'o':
  5063. return formatBaseX(value, 8, prefixBaseX, leftJustify, minWidth, precision, zeroPad);
  5064. case 'x':
  5065. return formatBaseX(value, 16, prefixBaseX, leftJustify, minWidth, precision, zeroPad);
  5066. case 'X':
  5067. return formatBaseX(value, 16, prefixBaseX, leftJustify, minWidth, precision, zeroPad).toUpperCase();
  5068. case 'u':
  5069. return formatBaseX(value, 10, prefixBaseX, leftJustify, minWidth, precision, zeroPad);
  5070. case 'i':
  5071. case 'd':
  5072. number = (+value) | 0;
  5073. prefix = number < 0 ? '-' : positivePrefix;
  5074. value = prefix + pad(String(Math.abs(number)), precision, '0', false);
  5075. return justify(value, prefix, leftJustify, minWidth, zeroPad);
  5076. case 'e':
  5077. case 'E':
  5078. case 'f':
  5079. case 'F':
  5080. case 'g':
  5081. case 'G':
  5082. number = +value;
  5083. prefix = number < 0 ? '-' : positivePrefix;
  5084. method = ['toExponential', 'toFixed', 'toPrecision']['efg'.indexOf(type.toLowerCase())];
  5085. textTransform = ['toString', 'toUpperCase']['eEfFgG'.indexOf(type) % 2];
  5086. value = prefix + Math.abs(number)[method](precision);
  5087. return justify(value, prefix, leftJustify, minWidth, zeroPad)[textTransform]();
  5088. default:
  5089. return substring;
  5090. }
  5091. };
  5092. return format.replace(regex, doFormat);
  5093. };
  5094. php.str_ireplace = function (search, replace, subject) {
  5095. // Replaces all occurrences of search in haystack with replace / case-insensitive
  5096. //
  5097. // version: 1103.1210
  5098. // discuss at: http://phpjs.org/functions/str_ireplace
  5099. // + original by: Martijn Wieringa
  5100. // + input by: penutbutterjelly
  5101. // + improved by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
  5102. // + tweaked by: Jack
  5103. // + bugfixed by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
  5104. // + bugfixed by: Onno Marsman
  5105. // + input by: Brett Zamir (http://brett-zamir.me)
  5106. // + bugfixed by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
  5107. // + bugfixed by: Philipp Lenssen
  5108. // * example 1: \php.str_ireplace('l', 'l', 'HeLLo');
  5109. // * returns 1: 'Hello'
  5110. // * example 2: \php.str_ireplace('$', 'foo', '$bar');
  5111. // * returns 2: 'foobar'
  5112. var i, k = '';
  5113. var searchl = 0;
  5114. var reg;
  5115. var escapeRegex = function (s) {
  5116. return s.replace(/([\\\^\$*+\[\]?{}.=!:(|)])/g, '\\$1');
  5117. };
  5118. search += '';
  5119. searchl = search.length;
  5120. if (!(replace instanceof Array)) {
  5121. replace = [replace];
  5122. if (search instanceof Array) {
  5123. // If search is an array and replace is a string,
  5124. // then this replacement string is used for every value of search
  5125. while (searchl > replace.length) {
  5126. replace[replace.length] = replace[0];
  5127. }
  5128. }
  5129. }
  5130. if (!(search instanceof Array)) {
  5131. search = [search];
  5132. }
  5133. while (search.length > replace.length) {
  5134. // If replace has fewer values than search,
  5135. // then an empty string is used for the rest of replacement values
  5136. replace[replace.length] = '';
  5137. }
  5138. if (subject instanceof Array) {
  5139. // If subject is an array, then the search and replace is performed
  5140. // with every entry of subject , and the return value is an array as well.
  5141. for (k in subject) {
  5142. if (subject.hasOwnProperty(k)) {
  5143. subject[k] = str_ireplace(search, replace, subject[k]);
  5144. }
  5145. }
  5146. return subject;
  5147. }
  5148. searchl = search.length;
  5149. for (i = 0; i < searchl; i++) {
  5150. reg = new RegExp(escapeRegex(search[i]), 'gi');
  5151. subject = subject.replace(reg, replace[i]);
  5152. }
  5153. return subject;
  5154. };
  5155. php.str_pad = function (input, pad_length, pad_string, pad_type) {
  5156. // Returns input string padded on the left or right to specified length with pad_string
  5157. //
  5158. // version: 1103.1210
  5159. // discuss at: http://phpjs.org/functions/str_pad
  5160. // + original by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
  5161. // + namespaced by: Michael White (http://getsprink.com)
  5162. // + input by: Marco van Oort
  5163. // + bugfixed by: Brett Zamir (http://brett-zamir.me)
  5164. // * example 1: \php.str_pad('Kevin van Zonneveld', 30, '-=', 'STR_PAD_LEFT');
  5165. // * returns 1: '-=-=-=-=-=-Kevin van Zonneveld'
  5166. // * example 2: \php.str_pad('Kevin van Zonneveld', 30, '-', 'STR_PAD_BOTH');
  5167. // * returns 2: '------Kevin van Zonneveld-----'
  5168. var half = '',
  5169. pad_to_go;
  5170. var str_pad_repeater = function (s, len) {
  5171. var collect = '',
  5172. i;
  5173. while (collect.length < len) {
  5174. collect += s;
  5175. }
  5176. collect = collect.substr(0, len);
  5177. return collect;
  5178. };
  5179. input += '';
  5180. pad_string = pad_string !== undefined ? pad_string : ' ';
  5181. if (pad_type != 'STR_PAD_LEFT' && pad_type != 'STR_PAD_RIGHT' && pad_type != 'STR_PAD_BOTH') {
  5182. pad_type = 'STR_PAD_RIGHT';
  5183. }
  5184. if ((pad_to_go = pad_length - input.length) > 0) {
  5185. if (pad_type == 'STR_PAD_LEFT') {
  5186. input = str_pad_repeater(pad_string, pad_to_go) + input;
  5187. } else if (pad_type == 'STR_PAD_RIGHT') {
  5188. input = input + str_pad_repeater(pad_string, pad_to_go);
  5189. } else if (pad_type == 'STR_PAD_BOTH') {
  5190. half = str_pad_repeater(pad_string, Math.ceil(pad_to_go / 2));
  5191. input = half + input + half;
  5192. input = input.substr(0, pad_length);
  5193. }
  5194. }
  5195. return input;
  5196. };
  5197. php.str_repeat = function (input, multiplier) {
  5198. // Returns the input string repeat mult times
  5199. //
  5200. // version: 1103.1210
  5201. // discuss at: http://phpjs.org/functions/str_repeat
  5202. // + original by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
  5203. // + improved by: Jonas Raoni Soares Silva (http://www.jsfromhell.com)
  5204. // * example 1: \php.str_repeat('-=', 10);
  5205. // * returns 1: '-=-=-=-=-=-=-=-=-=-='
  5206. return new Array(multiplier + 1).join(input);
  5207. };
  5208. php.str_replace = function (search, replace, subject, count) {
  5209. // Replaces all occurrences of search in haystack with replace
  5210. //
  5211. // version: 1103.1210
  5212. // discuss at: http://phpjs.org/functions/str_replace
  5213. // + original by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
  5214. // + improved by: Gabriel Paderni
  5215. // + improved by: Philip Peterson
  5216. // + improved by: Simon Willison (http://simonwillison.net)
  5217. // + revised by: Jonas Raoni Soares Silva (http://www.jsfromhell.com)
  5218. // + bugfixed by: Anton Ongson
  5219. // + input by: Onno Marsman
  5220. // + improved by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
  5221. // + tweaked by: Onno Marsman
  5222. // + input by: Brett Zamir (http://brett-zamir.me)
  5223. // + bugfixed by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
  5224. // + input by: Oleg Eremeev
  5225. // + improved by: Brett Zamir (http://brett-zamir.me)
  5226. // + bugfixed by: Oleg Eremeev
  5227. // % note 1: The count parameter must be passed as a string in order
  5228. // % note 1: to find a global variable in which the result will be given
  5229. // * example 1: \php.str_replace(' ', '.', 'Kevin van Zonneveld');
  5230. // * returns 1: 'Kevin.van.Zonneveld'
  5231. // * example 2: \php.str_replace(['{name}', 'l'], ['hello', 'm'], '{name}, lars');
  5232. // * returns 2: 'hemmo, mars'
  5233. var i = 0,
  5234. j = 0,
  5235. temp = '',
  5236. repl = '',
  5237. sl = 0,
  5238. fl = 0,
  5239. f = [].concat(search),
  5240. r = [].concat(replace),
  5241. s = subject,
  5242. ra = r instanceof Array,
  5243. sa = s instanceof Array;
  5244. s = [].concat(s);
  5245. if (count) {
  5246. this.window[count] = 0;
  5247. }
  5248. for (i = 0, sl = s.length; i < sl; i++) {
  5249. if (s[i] === '') {
  5250. continue;
  5251. }
  5252. for (j = 0, fl = f.length; j < fl; j++) {
  5253. temp = s[i] + '';
  5254. repl = ra ? (r[j] !== undefined ? r[j] : '') : r[0];
  5255. s[i] = (temp).split(f[j]).join(repl);
  5256. if (count && s[i] !== temp) {
  5257. this.window[count] += (temp.length - s[i].length) / f[j].length;
  5258. }
  5259. }
  5260. }
  5261. return sa ? s : s[0];
  5262. };
  5263. php.str_word_count = function (str, format, charlist) {
  5264. // Counts the number of words inside a string. If format of 1 is specified, then the function will return an array containing all the words found inside the string. If format of 2 is specified, then the function will return an associated array where the position of the word is the key and the word itself is the value. For the purpose of this function, 'word' is defined as a locale dependent string containing alphabetic characters, which also may contain, but not start with "'" and "-" characters.
  5265. //
  5266. // version: 1103.1210
  5267. // discuss at: http://phpjs.org/functions/str_word_count
  5268. // + original by: Ole Vrijenhoek
  5269. // + bugfixed by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
  5270. // + bugfixed by: Brett Zamir (http://brett-zamir.me)
  5271. // + input by: Bug?
  5272. // + bugfixed by: Brett Zamir (http://brett-zamir.me)
  5273. // + improved by: Brett Zamir (http://brett-zamir.me)
  5274. // - depends on: ctype_alpha
  5275. // * example 1: \php.str_word_count("Hello fri3nd, you're\r\n looking good today!", 1);
  5276. // * returns 1: ['Hello', 'fri', 'nd', "you're", 'looking', 'good', 'today']
  5277. // * example 2: \php.str_word_count("Hello fri3nd, you're\r\n looking good today!", 2);
  5278. // * returns 2: {0: 'Hello', 6: 'fri', 10: 'nd', 14: "you're", 29: 'looking', 46: 'good', 51: 'today'}
  5279. // * example 3: \php.str_word_count("Hello fri3nd, you're\r\n looking good today!", 1, '\u00e0\u00e1\u00e3\u00e73');
  5280. // * returns 3: ['Hello', 'fri3nd', 'youre', 'looking', 'good', 'today']
  5281. var len = str.length,
  5282. cl = charlist && charlist.length,
  5283. chr = '',
  5284. tmpStr = '',
  5285. i = 0,
  5286. c = '',
  5287. wArr = [],
  5288. wC = 0,
  5289. assoc = {},
  5290. aC = 0,
  5291. reg = '',
  5292. match = false;
  5293. // BEGIN STATIC
  5294. var _preg_quote = function (str) {
  5295. return (str + '').replace(/([\\\.\+\*\?\[\^\]\$\(\)\{\}\=\!<>\|\:])/g, '\\$1');
  5296. },
  5297. _getWholeChar = function (str, i) { // Use for rare cases of non-BMP characters
  5298. var code = str.charCodeAt(i);
  5299. if (code < 0xD800 || code > 0xDFFF) {
  5300. return str.charAt(i);
  5301. }
  5302. if (0xD800 <= code && code <= 0xDBFF) { // High surrogate (could change last hex to 0xDB7F to treat high private surrogates as single characters)
  5303. if (str.length <= (i + 1)) {
  5304. throw 'High surrogate without following low surrogate';
  5305. }
  5306. var next = str.charCodeAt(i + 1);
  5307. if (0xDC00 > next || next > 0xDFFF) {
  5308. throw 'High surrogate without following low surrogate';
  5309. }
  5310. return str.charAt(i) + str.charAt(i + 1);
  5311. }
  5312. // Low surrogate (0xDC00 <= code && code <= 0xDFFF)
  5313. if (i === 0) {
  5314. throw 'Low surrogate without preceding high surrogate';
  5315. }
  5316. var prev = str.charCodeAt(i - 1);
  5317. if (0xD800 > prev || prev > 0xDBFF) { // (could change last hex to 0xDB7F to treat high private surrogates as single characters)
  5318. throw 'Low surrogate without preceding high surrogate';
  5319. }
  5320. return false; // We can pass over low surrogates now as the second component in a pair which we have already processed
  5321. };
  5322. // END STATIC
  5323. if (cl) {
  5324. reg = '^(' + _preg_quote(_getWholeChar(charlist, 0));
  5325. for (i = 1; i < cl; i++) {
  5326. if ((chr = _getWholeChar(charlist, i)) === false) {
  5327. continue;
  5328. }
  5329. reg += '|' + _preg_quote(chr);
  5330. }
  5331. reg += ')$';
  5332. reg = new RegExp(reg);
  5333. }
  5334. for (i = 0; i < len; i++) {
  5335. if ((c = _getWholeChar(str, i)) === false) {
  5336. continue;
  5337. }
  5338. match = this.ctype_alpha(c) || (reg && c.search(reg) !== -1) || ((i !== 0 && i !== len - 1) && c === '-') || // No hyphen at beginning or end unless allowed in charlist (or locale)
  5339. (i !== 0 && c === "'"); // No apostrophe at beginning unless allowed in charlist (or locale)
  5340. if (match) {
  5341. if (tmpStr === '' && format === 2) {
  5342. aC = i;
  5343. }
  5344. tmpStr = tmpStr + c;
  5345. }
  5346. if (i === len - 1 || !match && tmpStr !== '') {
  5347. if (format !== 2) {
  5348. wArr[wArr.length] = tmpStr;
  5349. } else {
  5350. assoc[aC] = tmpStr;
  5351. }
  5352. tmpStr = '';
  5353. wC++;
  5354. }
  5355. }
  5356. if (!format) {
  5357. return wC;
  5358. } else if (format === 1) {
  5359. return wArr;
  5360. } else if (format === 2) {
  5361. return assoc;
  5362. }
  5363. throw 'You have supplied an incorrect format';
  5364. };
  5365. php.strcasecmp = function (f_string1, f_string2) {
  5366. // Binary safe case-insensitive string comparison
  5367. //
  5368. // version: 1103.1210
  5369. // discuss at: http://phpjs.org/functions/strcasecmp
  5370. // + original by: Martijn Wieringa
  5371. // + bugfixed by: Onno Marsman
  5372. // * example 1: \php.strcasecmp('Hello', 'hello');
  5373. // * returns 1: 0
  5374. var string1 = (f_string1 + '').toLowerCase();
  5375. var string2 = (f_string2 + '').toLowerCase();
  5376. if (string1 > string2) {
  5377. return 1;
  5378. } else if (string1 == string2) {
  5379. return 0;
  5380. }
  5381. return -1;
  5382. };
  5383. php.strcmp = function (str1, str2) {
  5384. // Binary safe string comparison
  5385. //
  5386. // version: 1103.1210
  5387. // discuss at: http://phpjs.org/functions/strcmp
  5388. // + original by: Waldo Malqui Silva
  5389. // + input by: Steve Hilder
  5390. // + improved by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
  5391. // + revised by: gorthaur
  5392. // * example 1: \php.strcmp( 'waldo', 'owald' );
  5393. // * returns 1: 1
  5394. // * example 2: \php.strcmp( 'owald', 'waldo' );
  5395. // * returns 2: -1
  5396. return ((str1 == str2) ? 0 : ((str1 > str2) ? 1 : -1));
  5397. };
  5398. php.strcspn = function (str, mask, start, length) {
  5399. // Finds length of initial segment consisting entirely of characters not found in mask. If start or/and length is provide works like strcspn(substr($s,$start,$len),$bad_chars)
  5400. //
  5401. // version: 1103.1210
  5402. // discuss at: http://phpjs.org/functions/strcspn
  5403. // + original by: Brett Zamir (http://brett-zamir.me)
  5404. // * example 1: \php.strcspn('abcdefg123', '1234567890');
  5405. // * returns 1: 7
  5406. // * example 2: \php.strcspn('123abc', '1234567890');
  5407. // * returns 2: 3
  5408. start = start ? start : 0;
  5409. var count = (length && ((start + length) < str.length)) ? start + length : str.length;
  5410. strct: for (var i = start, lgth = 0; i < count; i++) {
  5411. for (var j = 0; j < mask.length; j++) {
  5412. if (str.charAt(i).indexOf(mask[j]) !== -1) {
  5413. continue strct;
  5414. }
  5415. }++lgth;
  5416. }
  5417. return lgth;
  5418. };
  5419. php.strip_tags = function (input, allowed) {
  5420. // Strips HTML and PHP tags from a string
  5421. //
  5422. // version: 1103.1210
  5423. // discuss at: http://phpjs.org/functions/strip_tags
  5424. // + original by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
  5425. // + improved by: Luke Godfrey
  5426. // + input by: Pul
  5427. // + bugfixed by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
  5428. // + bugfixed by: Onno Marsman
  5429. // + input by: Alex
  5430. // + bugfixed by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
  5431. // + input by: Marc Palau
  5432. // + improved by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
  5433. // + input by: Brett Zamir (http://brett-zamir.me)
  5434. // + bugfixed by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
  5435. // + bugfixed by: Eric Nagel
  5436. // + input by: Bobby Drake
  5437. // + bugfixed by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
  5438. // + bugfixed by: Tomasz Wesolowski
  5439. // + input by: Evertjan Garretsen
  5440. // + revised by: Rafał Kukawski (http://blog.kukawski.pl/)
  5441. // * example 1: \php.strip_tags('<p>Kevin</p> <br /><b>van</b> <i>Zonneveld</i>', '<i><b>');
  5442. // * returns 1: 'Kevin <b>van</b> <i>Zonneveld</i>'
  5443. // * example 2: \php.strip_tags('<p>Kevin <img src="someimage.png" onmouseover="someFunction()">van <i>Zonneveld</i></p>', '<p>');
  5444. // * returns 2: '<p>Kevin van Zonneveld</p>'
  5445. // * example 3: \php.strip_tags("<a href='http://kevin.vanzonneveld.net'>Kevin van Zonneveld</a>", "<a>");
  5446. // * returns 3: '<a href='http://kevin.vanzonneveld.net'>Kevin van Zonneveld</a>'
  5447. // * example 4: \php.strip_tags('1 < 5 5 > 1');
  5448. // * returns 4: '1 < 5 5 > 1'
  5449. // * example 5: \php.strip_tags('1 <br/> 1');
  5450. // * returns 5: '1 1'
  5451. // * example 6: \php.strip_tags('1 <br/> 1', '<br>');
  5452. // * returns 6: '1 1'
  5453. // * example 7: \php.strip_tags('1 <br/> 1', '<br><br/>');
  5454. // * returns 7: '1 <br/> 1'
  5455. allowed = (((allowed || "") + "").toLowerCase().match(/<[a-z][a-z0-9]*>/g) || []).join(''); // making sure the allowed arg is a string containing only tags in lowercase (<a><b><c>)
  5456. var tags = /<\/?([a-z][a-z0-9]*)\b[^>]*>/gi,
  5457. commentsAndPhpTags = /<!--[\s\S]*?-->|<\?(?:php)?[\s\S]*?\?>/gi;
  5458. return input.replace(commentsAndPhpTags, '').replace(tags, function ($0, $1) {
  5459. return allowed.indexOf('<' + $1.toLowerCase() + '>') > -1 ? $0 : '';
  5460. });
  5461. };
  5462. php.stripos = function (f_haystack, f_needle, f_offset) {
  5463. // Finds position of first occurrence of a string within another, case insensitive
  5464. //
  5465. // version: 1103.1210
  5466. // discuss at: http://phpjs.org/functions/stripos
  5467. // + original by: Martijn Wieringa
  5468. // + revised by: Onno Marsman
  5469. // * example 1: \php.stripos('ABC', 'a');
  5470. // * returns 1: 0
  5471. var haystack = (f_haystack + '').toLowerCase();
  5472. var needle = (f_needle + '').toLowerCase();
  5473. var index = 0;
  5474. if ((index = haystack.indexOf(needle, f_offset)) !== -1) {
  5475. return index;
  5476. }
  5477. return false;
  5478. };
  5479. php.stripslashes = function (str) {
  5480. // + original by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
  5481. // + improved by: Ates Goral (http://magnetiq.com)
  5482. // + fixed by: Mick@el
  5483. // + improved by: marrtins
  5484. // + bugfixed by: Onno Marsman
  5485. // + improved by: rezna
  5486. // + input by: Rick Waldron
  5487. // + reimplemented by: Brett Zamir (http://brett-zamir.me)
  5488. // + input by: Brant Messenger (http://www.brantmessenger.com/)
  5489. // + bugfixed by: Brett Zamir (http://brett-zamir.me)
  5490. // * example 1: \php.stripslashes('Kevin\'s code');
  5491. // * returns 1: "Kevin's code"
  5492. // * example 2: \php.stripslashes('Kevin\\\'s code');
  5493. // * returns 2: "Kevin\'s code"
  5494. return (str + '').replace(/\\(.?)/g, function (s, n1) {
  5495. switch (n1) {
  5496. case '\\':
  5497. return '\\';
  5498. case '0':
  5499. return '\u0000';
  5500. case '':
  5501. return '';
  5502. default:
  5503. return n1;
  5504. }
  5505. });
  5506. };
  5507. php.stristr = function (haystack, needle, bool) {
  5508. // Finds first occurrence of a string within another, case insensitive
  5509. //
  5510. // version: 1103.1210
  5511. // discuss at: http://phpjs.org/functions/stristr
  5512. // + original by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
  5513. // + bugfxied by: Onno Marsman
  5514. // * example 1: \php.stristr('Kevin van Zonneveld', 'Van');
  5515. // * returns 1: 'van Zonneveld'
  5516. // * example 2: \php.stristr('Kevin van Zonneveld', 'VAN', true);
  5517. // * returns 2: 'Kevin '
  5518. var pos = 0;
  5519. haystack += '';
  5520. pos = haystack.toLowerCase().indexOf((needle + '').toLowerCase());
  5521. if (pos == -1) {
  5522. return false;
  5523. } else {
  5524. if (bool) {
  5525. return haystack.substr(0, pos);
  5526. } else {
  5527. return haystack.slice(pos);
  5528. }
  5529. }
  5530. };
  5531. php.strlen = function (string) {
  5532. // Get string length
  5533. //
  5534. // version: 1103.1210
  5535. // discuss at: http://phpjs.org/functions/strlen
  5536. // + original by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
  5537. // + improved by: Sakimori
  5538. // + input by: Kirk Strobeck
  5539. // + improved by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
  5540. // + bugfixed by: Onno Marsman
  5541. // + revised by: Brett Zamir (http://brett-zamir.me)
  5542. // % note 1: May look like overkill, but in order to be truly faithful to handling all Unicode
  5543. // % note 1: characters and to this function in PHP which does not count the number of bytes
  5544. // % note 1: but counts the number of characters, something like this is really necessary.
  5545. // * example 1: \php.strlen('Kevin van Zonneveld');
  5546. // * returns 1: 19
  5547. // * example 2: \php.strlen('A\ud87e\udc04Z');
  5548. // * returns 2: 3
  5549. var str = string + '';
  5550. var i = 0,
  5551. chr = '',
  5552. lgth = 0;
  5553. if (!this.php_js || !this.php_js.ini || !this.php_js.ini['unicode.semantics'] || this.php_js.ini['unicode.semantics'].local_value.toLowerCase() !== 'on') {
  5554. return string.length;
  5555. }
  5556. var getWholeChar = function (str, i) {
  5557. var code = str.charCodeAt(i);
  5558. var next = '',
  5559. prev = '';
  5560. if (0xD800 <= code && code <= 0xDBFF) { // High surrogate (could change last hex to 0xDB7F to treat high private surrogates as single characters)
  5561. if (str.length <= (i + 1)) {
  5562. throw 'High surrogate without following low surrogate';
  5563. }
  5564. next = str.charCodeAt(i + 1);
  5565. if (0xDC00 > next || next > 0xDFFF) {
  5566. throw 'High surrogate without following low surrogate';
  5567. }
  5568. return str.charAt(i) + str.charAt(i + 1);
  5569. } else if (0xDC00 <= code && code <= 0xDFFF) { // Low surrogate
  5570. if (i === 0) {
  5571. throw 'Low surrogate without preceding high surrogate';
  5572. }
  5573. prev = str.charCodeAt(i - 1);
  5574. if (0xD800 > prev || prev > 0xDBFF) { //(could change last hex to 0xDB7F to treat high private surrogates as single characters)
  5575. throw 'Low surrogate without preceding high surrogate';
  5576. }
  5577. return false; // We can pass over low surrogates now as the second component in a pair which we have already processed
  5578. }
  5579. return str.charAt(i);
  5580. };
  5581. for (i = 0, lgth = 0; i < str.length; i++) {
  5582. if ((chr = getWholeChar(str, i)) === false) {
  5583. continue;
  5584. } // Adapt this line at the top of any loop, passing in the whole string and the current iteration and returning a variable to represent the individual character; purpose is to treat the first part of a surrogate pair as the whole character and then ignore the second part
  5585. lgth++;
  5586. }
  5587. return lgth;
  5588. };
  5589. php.strnatcasecmp = function (str1, str2) {
  5590. // Returns the result of case-insensitive string comparison using 'natural' algorithm
  5591. //
  5592. // version: 1103.1210
  5593. // discuss at: http://phpjs.org/functions/strnatcasecmp
  5594. // + original by: Martin Pool
  5595. // + reimplemented by: Pierre-Luc Paour
  5596. // + reimplemented by: Kristof Coomans (SCK-CEN (Belgian Nucleair Research Centre))
  5597. // + reimplemented by: Brett Zamir (http://brett-zamir.me)
  5598. // + bugfixed by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
  5599. // + input by: Devan Penner-Woelk
  5600. // + improved by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
  5601. // * example 1: \php.strnatcasecmp(10, 1);
  5602. // * returns 1: 1
  5603. // * example 1: \php.strnatcasecmp('1', '10');
  5604. // * returns 1: -1
  5605. var a = (str1 + '').toLowerCase();
  5606. var b = (str2 + '').toLowerCase();
  5607. var isWhitespaceChar = function (a) {
  5608. return a.charCodeAt(0) <= 32;
  5609. };
  5610. var isDigitChar = function (a) {
  5611. var charCode = a.charCodeAt(0);
  5612. return (charCode >= 48 && charCode <= 57);
  5613. };
  5614. var compareRight = function (a, b) {
  5615. var bias = 0;
  5616. var ia = 0;
  5617. var ib = 0;
  5618. var ca;
  5619. var cb;
  5620. // The longest run of digits wins. That aside, the greatest
  5621. // value wins, but we can't know that it will until we've scanned
  5622. // both numbers to know that they have the same magnitude, so we
  5623. // remember it in BIAS.
  5624. for (var cnt = 0; true; ia++, ib++) {
  5625. ca = a.charAt(ia);
  5626. cb = b.charAt(ib);
  5627. if (!isDigitChar(ca) && !isDigitChar(cb)) {
  5628. return bias;
  5629. } else if (!isDigitChar(ca)) {
  5630. return -1;
  5631. } else if (!isDigitChar(cb)) {
  5632. return 1;
  5633. } else if (ca < cb) {
  5634. if (bias === 0) {
  5635. bias = -1;
  5636. }
  5637. } else if (ca > cb) {
  5638. if (bias === 0) {
  5639. bias = 1;
  5640. }
  5641. } else if (ca === '0' && cb === '0') {
  5642. return bias;
  5643. }
  5644. }
  5645. };
  5646. var ia = 0,
  5647. ib = 0;
  5648. var nza = 0,
  5649. nzb = 0;
  5650. var ca, cb;
  5651. var result;
  5652. while (true) {
  5653. // only count the number of zeroes leading the last number compared
  5654. nza = nzb = 0;
  5655. ca = a.charAt(ia);
  5656. cb = b.charAt(ib);
  5657. // skip over leading spaces or zeros
  5658. while (isWhitespaceChar(ca) || ca === '0') {
  5659. if (ca === '0') {
  5660. nza++;
  5661. } else {
  5662. // only count consecutive zeroes
  5663. nza = 0;
  5664. }
  5665. ca = a.charAt(++ia);
  5666. }
  5667. while (isWhitespaceChar(cb) || cb === '0') {
  5668. if (cb === '0') {
  5669. nzb++;
  5670. } else {
  5671. // only count consecutive zeroes
  5672. nzb = 0;
  5673. }
  5674. cb = b.charAt(++ib);
  5675. }
  5676. // process run of digits
  5677. if (isDigitChar(ca) && isDigitChar(cb)) {
  5678. if ((result = compareRight(a.substring(ia), b.substring(ib))) !== 0) {
  5679. return result;
  5680. }
  5681. }
  5682. if (ca === '0' && cb === '0') {
  5683. // The strings compare the same. Perhaps the caller
  5684. // will want to call strcmp to break the tie.
  5685. return nza - nzb;
  5686. }
  5687. if (ca < cb) {
  5688. return -1;
  5689. } else if (ca > cb) {
  5690. return +1;
  5691. }
  5692. ++ia;
  5693. ++ib;
  5694. }
  5695. };
  5696. php.strnatcmp = function (f_string1, f_string2, f_version) {
  5697. // Returns the result of string comparison using 'natural' algorithm
  5698. //
  5699. // version: 1103.1210
  5700. // discuss at: http://phpjs.org/functions/strnatcmp
  5701. // + original by: Martijn Wieringa
  5702. // + namespaced by: Michael White (http://getsprink.com)
  5703. // + tweaked by: Jack
  5704. // + bugfixed by: Onno Marsman
  5705. // - depends on: strcmp
  5706. // % note: Added f_version argument against code guidelines, because it's so neat
  5707. // * example 1: \php.strnatcmp('Price 12.9', 'Price 12.15');
  5708. // * returns 1: 1
  5709. // * example 2: \php.strnatcmp('Price 12.09', 'Price 12.15');
  5710. // * returns 2: -1
  5711. // * example 3: \php.strnatcmp('Price 12.90', 'Price 12.15');
  5712. // * returns 3: 1
  5713. // * example 4: \php.strnatcmp('Version 12.9', 'Version 12.15', true);
  5714. // * returns 4: -6
  5715. // * example 5: \php.strnatcmp('Version 12.15', 'Version 12.9', true);
  5716. // * returns 5: 6
  5717. var i = 0;
  5718. if (f_version == undefined) {
  5719. f_version = false;
  5720. }
  5721. var __strnatcmp_split = function (f_string) {
  5722. var result = [];
  5723. var buffer = '';
  5724. var chr = '';
  5725. var i = 0,
  5726. f_stringl = 0;
  5727. var text = true;
  5728. f_stringl = f_string.length;
  5729. for (i = 0; i < f_stringl; i++) {
  5730. chr = f_string.substring(i, i + 1);
  5731. if (chr.match(/\d/)) {
  5732. if (text) {
  5733. if (buffer.length > 0) {
  5734. result[result.length] = buffer;
  5735. buffer = '';
  5736. }
  5737. text = false;
  5738. }
  5739. buffer += chr;
  5740. } else if ((text == false) && (chr == '.') && (i < (f_string.length - 1)) && (f_string.substring(i + 1, i + 2).match(/\d/))) {
  5741. result[result.length] = buffer;
  5742. buffer = '';
  5743. } else {
  5744. if (text == false) {
  5745. if (buffer.length > 0) {
  5746. result[result.length] = parseInt(buffer, 10);
  5747. buffer = '';
  5748. }
  5749. text = true;
  5750. }
  5751. buffer += chr;
  5752. }
  5753. }
  5754. if (buffer.length > 0) {
  5755. if (text) {
  5756. result[result.length] = buffer;
  5757. } else {
  5758. result[result.length] = parseInt(buffer, 10);
  5759. }
  5760. }
  5761. return result;
  5762. };
  5763. var array1 = __strnatcmp_split(f_string1 + '');
  5764. var array2 = __strnatcmp_split(f_string2 + '');
  5765. var len = array1.length;
  5766. var text = true;
  5767. var result = -1;
  5768. var r = 0;
  5769. if (len > array2.length) {
  5770. len = array2.length;
  5771. result = 1;
  5772. }
  5773. for (i = 0; i < len; i++) {
  5774. if (isNaN(array1[i])) {
  5775. if (isNaN(array2[i])) {
  5776. text = true;
  5777. if ((r = this.strcmp(array1[i], array2[i])) != 0) {
  5778. return r;
  5779. }
  5780. } else if (text) {
  5781. return 1;
  5782. } else {
  5783. return -1;
  5784. }
  5785. } else if (isNaN(array2[i])) {
  5786. if (text) {
  5787. return -1;
  5788. } else {
  5789. return 1;
  5790. }
  5791. } else {
  5792. if (text || f_version) {
  5793. if ((r = (array1[i] - array2[i])) != 0) {
  5794. return r;
  5795. }
  5796. } else {
  5797. if ((r = this.strcmp(array1[i].toString(), array2[i].toString())) != 0) {
  5798. return r;
  5799. }
  5800. }
  5801. text = false;
  5802. }
  5803. }
  5804. return result;
  5805. };
  5806. php.strncasecmp = function (argStr1, argStr2, len) {
  5807. // Binary safe string comparison
  5808. //
  5809. // version: 1103.1210
  5810. // discuss at: http://phpjs.org/functions/strncasecmp
  5811. // + original by: Saulo Vallory
  5812. // + input by: Nate
  5813. // + bugfixed by: Onno Marsman
  5814. // % note: Returns < 0 if str1 is less than str2 ; > 0 if str1 is greater than str2 , and 0 if they are equal.
  5815. // * example 1: \php.strncasecmp('Price 12.9', 'Price 12.15', 2);
  5816. // * returns 1: 0
  5817. // * example 2: \php.strncasecmp('Price 12.09', 'Price 12.15', 10);
  5818. // * returns 2: -1
  5819. // * example 3: \php.strncasecmp('Price 12.90', 'Price 12.15', 30);
  5820. // * returns 3: 8
  5821. // * example 4: \php.strncasecmp('Version 12.9', 'Version 12.15', 20);
  5822. // * returns 4: 8
  5823. // * example 5: \php.strncasecmp('Version 12.15', 'Version 12.9', 20);
  5824. // * returns 5: -8
  5825. var diff, i = 0;
  5826. var str1 = (argStr1 + '').toLowerCase().substr(0, len);
  5827. var str2 = (argStr2 + '').toLowerCase().substr(0, len);
  5828. if (str1.length !== str2.length) {
  5829. if (str1.length < str2.length) {
  5830. len = str1.length;
  5831. if (str2.substr(0, str1.length) == str1) {
  5832. return str1.length - str2.length; // return the difference of chars
  5833. }
  5834. } else {
  5835. len = str2.length;
  5836. // str1 is longer than str2
  5837. if (str1.substr(0, str2.length) == str2) {
  5838. return str1.length - str2.length; // return the difference of chars
  5839. }
  5840. }
  5841. } else {
  5842. // Avoids trying to get a char that does not exist
  5843. len = str1.length;
  5844. }
  5845. for (diff = 0, i = 0; i < len; i++) {
  5846. diff = str1.charCodeAt(i) - str2.charCodeAt(i);
  5847. if (diff !== 0) {
  5848. return diff;
  5849. }
  5850. }
  5851. return 0;
  5852. };
  5853. php.strncmp = function (str1, str2, lgth) {
  5854. // Binary safe string comparison
  5855. //
  5856. // version: 1103.1210
  5857. // discuss at: http://phpjs.org/functions/strncmp
  5858. // + original by: Waldo Malqui Silva
  5859. // + input by: Steve Hilder
  5860. // + improved by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
  5861. // + revised by: gorthaur
  5862. // + reimplemented by: Brett Zamir (http://brett-zamir.me)
  5863. // * example 1: \php.strncmp('aaa', 'aab', 2);
  5864. // * returns 1: 0
  5865. // * example 2: \php.strncmp('aaa', 'aab', 3 );
  5866. // * returns 2: -1
  5867. var s1 = (str1 + '').substr(0, lgth);
  5868. var s2 = (str2 + '').substr(0, lgth);
  5869. return ((s1 == s2) ? 0 : ((s1 > s2) ? 1 : -1));
  5870. };
  5871. php.strpos = function (haystack, needle, offset) {
  5872. // Finds position of first occurrence of a string within another
  5873. //
  5874. // version: 1103.1210
  5875. // discuss at: http://phpjs.org/functions/strpos
  5876. // + original by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
  5877. // + improved by: Onno Marsman
  5878. // + bugfixed by: Daniel Esteban
  5879. // + improved by: Brett Zamir (http://brett-zamir.me)
  5880. // * example 1: \php.strpos('Kevin van Zonneveld', 'e', 5);
  5881. // * returns 1: 14
  5882. var i = (haystack + '').indexOf(needle, (offset || 0));
  5883. return i === -1 ? false : i;
  5884. };
  5885. php.strtok = function (str, tokens) {
  5886. // Tokenize a string
  5887. //
  5888. // version: 1103.1210
  5889. // discuss at: http://phpjs.org/functions/strtok
  5890. // + original by: Brett Zamir (http://brett-zamir.me)
  5891. // % note 1: Use tab and newline as tokenizing characters as well
  5892. // * example 1: $string = "\t\t\t\nThis is\tan example\nstring\n";
  5893. // * example 1: $tok = strtok($string, " \n\t");
  5894. // * example 1: $b = '';
  5895. // * example 1: \php.while ($tok !== false) {$b += "Word="+$tok+"\n"; $tok = strtok(" \n\t");}
  5896. // * example 1: $b
  5897. // * returns 1: "Word=This\nWord=is\nWord=an\nWord=example\nWord=string\n"
  5898. // BEGIN REDUNDANT
  5899. this.php_js = this.php_js || {};
  5900. // END REDUNDANT
  5901. if (tokens === undefined) {
  5902. tokens = str;
  5903. str = this.php_js.strtokleftOver;
  5904. }
  5905. if (str.length === 0) {
  5906. return false;
  5907. }
  5908. if (tokens.indexOf(str.charAt(0)) !== -1) {
  5909. return this.strtok(str.substr(1), tokens);
  5910. }
  5911. for (var i = 0; i < str.length; i++) {
  5912. if (tokens.indexOf(str.charAt(i)) !== -1) {
  5913. break;
  5914. }
  5915. }
  5916. this.php_js.strtokleftOver = str.substr(i + 1);
  5917. return str.substring(0, i);
  5918. };
  5919. php.strtotime = function (str, now) {
  5920. // Convert string representation of date and time to a timestamp
  5921. //
  5922. // version: 1103.1210
  5923. // discuss at: http://phpjs.org/functions/strtotime
  5924. // + original by: Caio Ariede (http://caioariede.com)
  5925. // + improved by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
  5926. // + input by: David
  5927. // + improved by: Caio Ariede (http://caioariede.com)
  5928. // + improved by: Brett Zamir (http://brett-zamir.me)
  5929. // + bugfixed by: Wagner B. Soares
  5930. // + bugfixed by: Artur Tchernychev
  5931. // % note 1: Examples all have a fixed timestamp to prevent tests to fail because of variable time(zones)
  5932. // * example 1: \php.strtotime('+1 day', 1129633200);
  5933. // * returns 1: 1129719600
  5934. // * example 2: \php.strtotime('+1 week 2 days 4 hours 2 seconds', 1129633200);
  5935. // * returns 2: 1130425202
  5936. // * example 3: \php.strtotime('last month', 1129633200);
  5937. // * returns 3: 1127041200
  5938. // * example 4: \php.strtotime('2009-05-04 08:30:00');
  5939. // * returns 4: 1241418600
  5940. var i, match, s, strTmp = '',
  5941. parse = '';
  5942. strTmp = str;
  5943. strTmp = strTmp.replace(/\s{2,}|^\s|\s$/g, ' '); // unecessary spaces
  5944. strTmp = strTmp.replace(/[\t\r\n]/g, ''); // unecessary chars
  5945. if (strTmp == 'now') {
  5946. return (new Date()).getTime() / 1000; // Return seconds, not milli-seconds
  5947. } else if (!isNaN(parse = Date.parse(strTmp))) {
  5948. return (parse / 1000);
  5949. } else if (now) {
  5950. now = new Date(now * 1000); // Accept PHP-style seconds
  5951. } else {
  5952. now = new Date();
  5953. }
  5954. strTmp = strTmp.toLowerCase();
  5955. var __is = {
  5956. day: {
  5957. 'sun': 0,
  5958. 'mon': 1,
  5959. 'tue': 2,
  5960. 'wed': 3,
  5961. 'thu': 4,
  5962. 'fri': 5,
  5963. 'sat': 6
  5964. },
  5965. mon: {
  5966. 'jan': 0,
  5967. 'feb': 1,
  5968. 'mar': 2,
  5969. 'apr': 3,
  5970. 'may': 4,
  5971. 'jun': 5,
  5972. 'jul': 6,
  5973. 'aug': 7,
  5974. 'sep': 8,
  5975. 'oct': 9,
  5976. 'nov': 10,
  5977. 'dec': 11
  5978. }
  5979. };
  5980. var process = function (m) {
  5981. var ago = (m[2] && m[2] == 'ago');
  5982. var num = (num = m[0] == 'last' ? -1 : 1) * (ago ? -1 : 1);
  5983. switch (m[0]) {
  5984. case 'last':
  5985. case 'next':
  5986. switch (m[1].substring(0, 3)) {
  5987. case 'yea':
  5988. now.setFullYear(now.getFullYear() + num);
  5989. break;
  5990. case 'mon':
  5991. now.setMonth(now.getMonth() + num);
  5992. break;
  5993. case 'wee':
  5994. now.setDate(now.getDate() + (num * 7));
  5995. break;
  5996. case 'day':
  5997. now.setDate(now.getDate() + num);
  5998. break;
  5999. case 'hou':
  6000. now.setHours(now.getHours() + num);
  6001. break;
  6002. case 'min':
  6003. now.setMinutes(now.getMinutes() + num);
  6004. break;
  6005. case 'sec':
  6006. now.setSeconds(now.getSeconds() + num);
  6007. break;
  6008. default:
  6009. var day;
  6010. if (typeof(day = __is.day[m[1].substring(0, 3)]) != 'undefined') {
  6011. var diff = day - now.getDay();
  6012. if (diff == 0) {
  6013. diff = 7 * num;
  6014. } else if (diff > 0) {
  6015. if (m[0] == 'last') {
  6016. diff -= 7;
  6017. }
  6018. } else {
  6019. if (m[0] == 'next') {
  6020. diff += 7;
  6021. }
  6022. }
  6023. now.setDate(now.getDate() + diff);
  6024. }
  6025. }
  6026. break;
  6027. default:
  6028. if (/\d+/.test(m[0])) {
  6029. num *= parseInt(m[0], 10);
  6030. switch (m[1].substring(0, 3)) {
  6031. case 'yea':
  6032. now.setFullYear(now.getFullYear() + num);
  6033. break;
  6034. case 'mon':
  6035. now.setMonth(now.getMonth() + num);
  6036. break;
  6037. case 'wee':
  6038. now.setDate(now.getDate() + (num * 7));
  6039. break;
  6040. case 'day':
  6041. now.setDate(now.getDate() + num);
  6042. break;
  6043. case 'hou':
  6044. now.setHours(now.getHours() + num);
  6045. break;
  6046. case 'min':
  6047. now.setMinutes(now.getMinutes() + num);
  6048. break;
  6049. case 'sec':
  6050. now.setSeconds(now.getSeconds() + num);
  6051. break;
  6052. }
  6053. } else {
  6054. return false;
  6055. }
  6056. break;
  6057. }
  6058. return true;
  6059. };
  6060. match = strTmp.match(/^(\d{2,4}-\d{2}-\d{2})(?:\s(\d{1,2}:\d{2}(:\d{2})?)?(?:\.(\d+))?)?$/);
  6061. if (match != null) {
  6062. if (!match[2]) {
  6063. match[2] = '00:00:00';
  6064. } else if (!match[3]) {
  6065. match[2] += ':00';
  6066. }
  6067. s = match[1].split(/-/g);
  6068. for (i in __is.mon) {
  6069. if (__is.mon[i] == s[1] - 1) {
  6070. s[1] = i;
  6071. }
  6072. }
  6073. s[0] = parseInt(s[0], 10);
  6074. s[0] = (s[0] >= 0 && s[0] <= 69) ? '20' + (s[0] < 10 ? '0' + s[0] : s[0] + '') : (s[0] >= 70 && s[0] <= 99) ? '19' + s[0] : s[0] + '';
  6075. return parseInt(this.strtotime(s[2] + ' ' + s[1] + ' ' + s[0] + ' ' + match[2]) + (match[4] ? match[4] / 1000 : ''), 10);
  6076. }
  6077. var regex = '([+-]?\\d+\\s' + '(years?|months?|weeks?|days?|hours?|min|minutes?|sec|seconds?' + '|sun\\.?|sunday|mon\\.?|monday|tue\\.?|tuesday|wed\\.?|wednesday' + '|thu\\.?|thursday|fri\\.?|friday|sat\\.?|saturday)' + '|(last|next)\\s' + '(years?|months?|weeks?|days?|hours?|min|minutes?|sec|seconds?' + '|sun\\.?|sunday|mon\\.?|monday|tue\\.?|tuesday|wed\\.?|wednesday' + '|thu\\.?|thursday|fri\\.?|friday|sat\\.?|saturday))' + '(\\sago)?';
  6078. match = strTmp.match(new RegExp(regex, 'gi')); // Brett: seems should be case insensitive per docs, so added 'i'
  6079. if (match == null) {
  6080. return false;
  6081. }
  6082. for (i = 0; i < match.length; i++) {
  6083. if (!process(match[i].split(' '))) {
  6084. return false;
  6085. }
  6086. }
  6087. return (now.getTime() / 1000);
  6088. };
  6089. php.strrpos = function (haystack, needle, offset) {
  6090. // Finds position of last occurrence of a string within another string
  6091. //
  6092. // version: 1103.1210
  6093. // discuss at: http://phpjs.org/functions/strrpos
  6094. // + original by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
  6095. // + bugfixed by: Onno Marsman
  6096. // + input by: saulius
  6097. // + bugfixed by: Brett Zamir (http://brett-zamir.me)
  6098. // * example 1: strrpos('Kevin van Zonneveld', 'e');
  6099. // * returns 1: 16
  6100. // * example 2: strrpos('somepage.com', '.', false);
  6101. // * returns 2: 8
  6102. // * example 3: strrpos('baa', 'a', 3);
  6103. // * returns 3: false
  6104. // * example 4: strrpos('baa', 'a', 2);
  6105. // * returns 4: 2
  6106. var i = -1;
  6107. if (offset) {
  6108. i = (haystack + '').slice(offset).lastIndexOf(needle); // strrpos' offset indicates starting point of range till end,
  6109. // while lastIndexOf's optional 2nd argument indicates ending point of range from the beginning
  6110. if (i !== -1) {
  6111. i += offset;
  6112. }
  6113. } else {
  6114. i = (haystack + '').lastIndexOf(needle);
  6115. }
  6116. return i >= 0 ? i : false;
  6117. };
  6118. php.strtr = function (str, from, to) {
  6119. // Translates characters in str using given translation tables
  6120. //
  6121. // version: 1103.1210
  6122. // discuss at: http://phpjs.org/functions/strtr
  6123. // + original by: Brett Zamir (http://brett-zamir.me)
  6124. // + input by: uestla
  6125. // + bugfixed by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
  6126. // + input by: Alan C
  6127. // + bugfixed by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
  6128. // + input by: Taras Bogach
  6129. // + bugfixed by: Brett Zamir (http://brett-zamir.me)
  6130. // + input by: jpfle
  6131. // + bugfixed by: Brett Zamir (http://brett-zamir.me)
  6132. // - depends on: krsort
  6133. // - depends on: ini_set
  6134. // * example 1: $trans = {'hello' : 'hi', 'hi' : 'hello'};
  6135. // * example 1: \php.strtr('hi all, I said hello', $trans)
  6136. // * returns 1: 'hello all, I said hi'
  6137. // * example 2: \php.strtr('äaabaåccasdeöoo', 'äåö','aao');
  6138. // * returns 2: 'aaabaaccasdeooo'
  6139. // * example 3: \php.strtr('ääääääää', 'ä', 'a');
  6140. // * returns 3: 'aaaaaaaa'
  6141. // * example 4: \php.strtr('http', 'pthxyz','xyzpth');
  6142. // * returns 4: 'zyyx'
  6143. // * example 5: \php.strtr('zyyx', 'pthxyz','xyzpth');
  6144. // * returns 5: 'http'
  6145. // * example 6: \php.strtr('aa', {'a':1,'aa':2});
  6146. // * returns 6: '2'
  6147. var fr = '',
  6148. i = 0,
  6149. j = 0,
  6150. lenStr = 0,
  6151. lenFrom = 0,
  6152. tmpStrictForIn = false,
  6153. fromTypeStr = '',
  6154. toTypeStr = '',
  6155. istr = '';
  6156. var tmpFrom = [];
  6157. var tmpTo = [];
  6158. var ret = '';
  6159. var match = false;
  6160. // Received replace_pairs?
  6161. // Convert to normal from->to chars
  6162. if (typeof from === 'object') {
  6163. tmpStrictForIn = this.ini_set('phpjs.strictForIn', false); // Not thread-safe; temporarily set to true
  6164. from = this.krsort(from);
  6165. this.ini_set('phpjs.strictForIn', tmpStrictForIn);
  6166. for (fr in from) {
  6167. if (from.hasOwnProperty(fr)) {
  6168. tmpFrom.push(fr);
  6169. tmpTo.push(from[fr]);
  6170. }
  6171. }
  6172. from = tmpFrom;
  6173. to = tmpTo;
  6174. }
  6175. // Walk through subject and replace chars when needed
  6176. lenStr = str.length;
  6177. lenFrom = from.length;
  6178. fromTypeStr = typeof from === 'string';
  6179. toTypeStr = typeof to === 'string';
  6180. for (i = 0; i < lenStr; i++) {
  6181. match = false;
  6182. if (fromTypeStr) {
  6183. istr = str.charAt(i);
  6184. for (j = 0; j < lenFrom; j++) {
  6185. if (istr == from.charAt(j)) {
  6186. match = true;
  6187. break;
  6188. }
  6189. }
  6190. } else {
  6191. for (j = 0; j < lenFrom; j++) {
  6192. if (str.substr(i, from[j].length) == from[j]) {
  6193. match = true;
  6194. // Fast forward
  6195. i = (i + from[j].length) - 1;
  6196. break;
  6197. }
  6198. }
  6199. }
  6200. if (match) {
  6201. ret += toTypeStr ? to.charAt(j) : to[j];
  6202. } else {
  6203. ret += str.charAt(i);
  6204. }
  6205. }
  6206. return ret;
  6207. };
  6208. php.substr_compare = function (main_str, str, offset, length, case_insensitivity) {
  6209. // Binary safe optionally case insensitive comparison of 2 strings from an offset, up to length characters
  6210. //
  6211. // version: 1103.1210
  6212. // discuss at: http://phpjs.org/functions/substr_compare
  6213. // + original by: Brett Zamir (http://brett-zamir.me)
  6214. // + derived from: strcasecmp, strcmp
  6215. // * example 1: \php.substr_compare("abcde", "bc", 1, 2);
  6216. // * returns 1: 0
  6217. if (!offset && offset !== 0) {
  6218. throw 'Missing offset for substr_compare()';
  6219. }
  6220. if (offset < 0) {
  6221. offset = main_str.length + offset;
  6222. }
  6223. if (length && length > (main_str.length - offset)) {
  6224. return false;
  6225. }
  6226. length = length || main_str.length - offset;
  6227. main_str = main_str.substr(offset, length);
  6228. str = str.substr(0, length); // Should only compare up to the desired length
  6229. if (case_insensitivity) { // Works as strcasecmp
  6230. main_str = (main_str + '').toLowerCase();
  6231. str = (str + '').toLowerCase();
  6232. if (main_str == str) {
  6233. return 0;
  6234. }
  6235. return (main_str > str) ? 1 : -1;
  6236. }
  6237. // Works as strcmp
  6238. return ((main_str == str) ? 0 : ((main_str > str) ? 1 : -1));
  6239. };
  6240. php.substr_count = function (haystack, needle, offset, length) {
  6241. // Returns the number of times a substring occurs in the string
  6242. //
  6243. // version: 1103.1210
  6244. // discuss at: http://phpjs.org/functions/substr_count
  6245. // + original by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
  6246. // + bugfixed by: Onno Marsman
  6247. // * example 1: \php.substr_count('Kevin van Zonneveld', 'e');
  6248. // * returns 1: 3
  6249. // * example 2: \php.substr_count('Kevin van Zonneveld', 'K', 1);
  6250. // * returns 2: 0
  6251. // * example 3: \php.substr_count('Kevin van Zonneveld', 'Z', 0, 10);
  6252. // * returns 3: false
  6253. var pos = 0,
  6254. cnt = 0;
  6255. haystack += '';
  6256. needle += '';
  6257. if (isNaN(offset)) {
  6258. offset = 0;
  6259. }
  6260. if (isNaN(length)) {
  6261. length = 0;
  6262. }
  6263. offset--;
  6264. while ((offset = haystack.indexOf(needle, offset + 1)) != -1) {
  6265. if (length > 0 && (offset + needle.length) > length) {
  6266. return false;
  6267. } else {
  6268. cnt++;
  6269. }
  6270. }
  6271. return cnt;
  6272. };
  6273. php.substr_replace = function (str, replace, start, length) {
  6274. // Replaces part of a string with another string
  6275. //
  6276. // version: 1103.1210
  6277. // discuss at: http://phpjs.org/functions/substr_replace
  6278. // + original by: Brett Zamir (http://brett-zamir.me)
  6279. // * example 1: \php.substr_replace('ABCDEFGH:/MNRPQR/', 'bob', 0);
  6280. // * returns 1: 'bob'
  6281. // * example 2: $var = 'ABCDEFGH:/MNRPQR/';
  6282. // * example 2: \php.substr_replace($var, 'bob', 0, $var.length);
  6283. // * returns 2: 'bob'
  6284. // * example 3: \php.substr_replace('ABCDEFGH:/MNRPQR/', 'bob', 0, 0);
  6285. // * returns 3: 'bobABCDEFGH:/MNRPQR/'
  6286. // * example 4: \php.substr_replace('ABCDEFGH:/MNRPQR/', 'bob', 10, -1);
  6287. // * returns 4: 'ABCDEFGH:/bob/'
  6288. // * example 5: \php.substr_replace('ABCDEFGH:/MNRPQR/', 'bob', -7, -1);
  6289. // * returns 5: 'ABCDEFGH:/bob/'
  6290. // * example 6: 'substr_replace('ABCDEFGH:/MNRPQR/', '', 10, -1)'
  6291. // * returns 6: 'ABCDEFGH://'
  6292. if (start < 0) { // start position in str
  6293. start = start + str.length;
  6294. }
  6295. length = length !== undefined ? length : str.length;
  6296. if (length < 0) {
  6297. length = length + str.length - start;
  6298. }
  6299. return str.slice(0, start) + replace.substr(0, length) + replace.slice(length) + str.slice(start + length);
  6300. };
  6301. php.time = function () {
  6302. // Return current UNIX timestamp
  6303. //
  6304. // version: 1103.1210
  6305. // discuss at: http://phpjs.org/functions/time
  6306. // + original by: GeekFG (http://geekfg.blogspot.com)
  6307. // + improved by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
  6308. // + improved by: metjay
  6309. // + improved by: HKM
  6310. // * example 1: \php.timeStamp = time();
  6311. // * results 1: timeStamp > 1000000000 && timeStamp < 2000000000
  6312. return Math.floor(new Date().getTime() / 1000);
  6313. };
  6314. php.trim = function (str, charlist) {
  6315. // Strips whitespace from the beginning and end of a string
  6316. //
  6317. // version: 1103.1210
  6318. // discuss at: http://phpjs.org/functions/trim
  6319. // + original by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
  6320. // + improved by: mdsjack (http://www.mdsjack.bo.it)
  6321. // + improved by: Alexander Ermolaev (http://snippets.dzone.com/user/AlexanderErmolaev)
  6322. // + input by: Erkekjetter
  6323. // + improved by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
  6324. // + input by: DxGx
  6325. // + improved by: Steven Levithan (http://blog.stevenlevithan.com)
  6326. // + tweaked by: Jack
  6327. // + bugfixed by: Onno Marsman
  6328. // * example 1: \php.trim(' Kevin van Zonneveld ');
  6329. // * returns 1: 'Kevin van Zonneveld'
  6330. // * example 2: \php.trim('Hello World', 'Hdle');
  6331. // * returns 2: 'o Wor'
  6332. // * example 3: \php.trim(16, 1);
  6333. // * returns 3: 6
  6334. var whitespace, l = 0,
  6335. i = 0;
  6336. str += '';
  6337. if (!charlist) {
  6338. // default list
  6339. whitespace = " \n\r\t\f\x0b\xa0\u2000\u2001\u2002\u2003\u2004\u2005\u2006\u2007\u2008\u2009\u200a\u200b\u2028\u2029\u3000";
  6340. } else {
  6341. // preg_quote custom list
  6342. charlist += '';
  6343. whitespace = charlist.replace(/([\[\]\(\)\.\?\/\*\{\}\+\$\^\:])/g, '$1');
  6344. }
  6345. l = str.length;
  6346. for (i = 0; i < l; i++) {
  6347. if (whitespace.indexOf(str.charAt(i)) === -1) {
  6348. str = str.substring(i);
  6349. break;
  6350. }
  6351. }
  6352. l = str.length;
  6353. for (i = l - 1; i >= 0; i--) {
  6354. if (whitespace.indexOf(str.charAt(i)) === -1) {
  6355. str = str.substring(0, i + 1);
  6356. break;
  6357. }
  6358. }
  6359. return whitespace.indexOf(str.charAt(0)) === -1 ? str : '';
  6360. };
  6361. php.uasort = function (inputArr, sorter) {
  6362. // Sort an array with a user-defined comparison function and maintain index association
  6363. //
  6364. // version: 1103.1210
  6365. // discuss at: http://phpjs.org/functions/uasort
  6366. // + original by: Brett Zamir (http://brett-zamir.me)
  6367. // + improved by: Brett Zamir (http://brett-zamir.me)
  6368. // % note 1: This function deviates from PHP in returning a copy of the array instead
  6369. // % note 1: of acting by reference and returning true; this was necessary because
  6370. // % note 1: IE does not allow deleting and re-adding of properties without caching
  6371. // % note 1: of property position; you can set the ini of "phpjs.strictForIn" to true to
  6372. // % note 1: get the PHP behavior, but use this only if you are in an environment
  6373. // % note 1: such as Firefox extensions where for-in iteration order is fixed and true
  6374. // % note 1: property deletion is supported. Note that we intend to implement the PHP
  6375. // % note 1: behavior by default if IE ever does allow it; only gives shallow copy since
  6376. // % note 1: is by reference in PHP anyways
  6377. // * example 1: \php.fruits = {d: 'lemon', a: 'orange', b: 'banana', c: 'apple'};
  6378. // * example 1: \php.fruits = uasort(fruits, function (a, b) { if (a > b) {return 1;}if (a < b) {return -1;} return 0;});
  6379. // * results 1: fruits == {c: 'apple', b: 'banana', d: 'lemon', a: 'orange'}
  6380. var valArr = [],
  6381. keyArr = [],
  6382. tempKeyVal, tempValue, ret, k = '',
  6383. i = 0,
  6384. strictForIn = false,
  6385. populateArr = {};
  6386. if (typeof sorter === 'string') {
  6387. sorter = this[sorter];
  6388. } else if (sorter instanceof Array) {
  6389. sorter = this[sorter[0]][sorter[1]];
  6390. }
  6391. var sorterNew = function (keyArr, valArr) {
  6392. for (var i = valArr.length - 2; i >= 0; i--) {
  6393. for (var j = 0; j <= i; j++) {
  6394. ret = sorter(valArr[j + 1], valArr[j]);
  6395. if (ret < 0) {
  6396. tempValue = valArr[j];
  6397. valArr[j] = valArr[j + 1];
  6398. valArr[j + 1] = tempValue;
  6399. tempKeyVal = keyArr[j];
  6400. keyArr[j] = keyArr[j + 1];
  6401. keyArr[j + 1] = tempKeyVal;
  6402. }
  6403. }
  6404. }
  6405. };
  6406. // BEGIN REDUNDANT
  6407. this.php_js = this.php_js || {};
  6408. this.php_js.ini = this.php_js.ini || {};
  6409. // END REDUNDANT
  6410. strictForIn = this.php_js.ini['phpjs.strictForIn'] && this.php_js.ini['phpjs.strictForIn'].local_value && this.php_js.ini['phpjs.strictForIn'].local_value !== 'off';
  6411. populateArr = strictForIn ? inputArr : populateArr;
  6412. for (k in inputArr) { // Get key and value arrays
  6413. if (inputArr.hasOwnProperty(k)) {
  6414. valArr.push(inputArr[k]);
  6415. keyArr.push(k);
  6416. if (strictForIn) {
  6417. delete inputArr[k];
  6418. }
  6419. }
  6420. }
  6421. try {
  6422. sorterNew(keyArr, valArr); // Sort our new temporary arrays
  6423. } catch (e) {
  6424. return false;
  6425. }
  6426. for (i = 0; i < valArr.length; i++) { // Repopulate the old array
  6427. populateArr[keyArr[i]] = valArr[i];
  6428. }
  6429. return strictForIn || populateArr;
  6430. };
  6431. php.ucfirst = function (str) {
  6432. // Makes a string's first character uppercase
  6433. //
  6434. // version: 1103.1210
  6435. // discuss at: http://phpjs.org/functions/ucfirst
  6436. // + original by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
  6437. // + bugfixed by: Onno Marsman
  6438. // + improved by: Brett Zamir (http://brett-zamir.me)
  6439. // * example 1: \php.ucfirst('kevin van zonneveld');
  6440. // * returns 1: 'Kevin van zonneveld'
  6441. str += '';
  6442. var f = str.charAt(0).toUpperCase();
  6443. return f + str.substr(1);
  6444. };
  6445. php.ucwords = function (str) {
  6446. // Uppercase the first character of every word in a string
  6447. //
  6448. // version: 1103.1210
  6449. // discuss at: http://phpjs.org/functions/ucwords
  6450. // + original by: Jonas Raoni Soares Silva (http://www.jsfromhell.com)
  6451. // + improved by: Waldo Malqui Silva
  6452. // + bugfixed by: Onno Marsman
  6453. // + improved by: Robin
  6454. // + input by: James (http://www.james-bell.co.uk/)
  6455. // + improved by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
  6456. // * example 1: \php.ucwords('kevin van zonneveld');
  6457. // * returns 1: 'Kevin Van Zonneveld'
  6458. // * example 2: \php.ucwords('HELLO WORLD');
  6459. // * returns 2: 'HELLO WORLD'
  6460. return (str + '').replace(/^([a-z])|\s+([a-z])/g, function ($1) {
  6461. return $1.toUpperCase();
  6462. });
  6463. };
  6464. php.uksort = function (inputArr, sorter) {
  6465. // Sort an array by keys using a user-defined comparison function
  6466. //
  6467. // version: 1103.1210
  6468. // discuss at: http://phpjs.org/functions/uksort
  6469. // + original by: Brett Zamir (http://brett-zamir.me)
  6470. // + improved by: Brett Zamir (http://brett-zamir.me)
  6471. // % note 1: The examples are correct, this is a new way
  6472. // % note 2: This function deviates from PHP in returning a copy of the array instead
  6473. // % note 2: of acting by reference and returning true; this was necessary because
  6474. // % note 2: IE does not allow deleting and re-adding of properties without caching
  6475. // % note 2: of property position; you can set the ini of "phpjs.strictForIn" to true to
  6476. // % note 2: get the PHP behavior, but use this only if you are in an environment
  6477. // % note 2: such as Firefox extensions where for-in iteration order is fixed and true
  6478. // % note 2: property deletion is supported. Note that we intend to implement the PHP
  6479. // % note 2: behavior by default if IE ever does allow it; only gives shallow copy since
  6480. // % note 2: is by reference in PHP anyways
  6481. // * example 1: \php.data = {d: 'lemon', a: 'orange', b: 'banana', c: 'apple'};
  6482. // * example 1: \php.data = uksort(data, function (key1, key2){ return (key1 == key2 ? 0 : (key1 > key2 ? 1 : -1)); });
  6483. // * results 1: data == {a: 'orange', b: 'banana', c: 'apple', d: 'lemon'}
  6484. // * returns 1: true
  6485. var tmp_arr = {},
  6486. keys = [],
  6487. i = 0,
  6488. k = '',
  6489. strictForIn = false,
  6490. populateArr = {};
  6491. if (typeof sorter === 'string') {
  6492. sorter = this.window[sorter];
  6493. }
  6494. // Make a list of key names
  6495. for (k in inputArr) {
  6496. if (inputArr.hasOwnProperty(k)) {
  6497. keys.push(k);
  6498. }
  6499. }
  6500. // Sort key names
  6501. try {
  6502. if (sorter) {
  6503. keys.sort(sorter);
  6504. } else {
  6505. keys.sort();
  6506. }
  6507. } catch (e) {
  6508. return false;
  6509. }
  6510. // BEGIN REDUNDANT
  6511. this.php_js = this.php_js || {};
  6512. this.php_js.ini = this.php_js.ini || {};
  6513. // END REDUNDANT
  6514. strictForIn = this.php_js.ini['phpjs.strictForIn'] && this.php_js.ini['phpjs.strictForIn'].local_value && this.php_js.ini['phpjs.strictForIn'].local_value !== 'off';
  6515. populateArr = strictForIn ? inputArr : populateArr;
  6516. // Rebuild array with sorted key names
  6517. for (i = 0; i < keys.length; i++) {
  6518. k = keys[i];
  6519. tmp_arr[k] = inputArr[k];
  6520. if (strictForIn) {
  6521. delete inputArr[k];
  6522. }
  6523. }
  6524. for (i in tmp_arr) {
  6525. if (tmp_arr.hasOwnProperty(i)) {
  6526. populateArr[i] = tmp_arr[i];
  6527. }
  6528. }
  6529. return strictForIn || populateArr;
  6530. };
  6531. php.urldecode = function (str) {
  6532. // Decodes URL-encoded string
  6533. //
  6534. // version: 1103.1210
  6535. // discuss at: http://phpjs.org/functions/urldecode
  6536. // + original by: Philip Peterson
  6537. // + improved by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
  6538. // + input by: AJ
  6539. // + improved by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
  6540. // + improved by: Brett Zamir (http://brett-zamir.me)
  6541. // + input by: travc
  6542. // + input by: Brett Zamir (http://brett-zamir.me)
  6543. // + bugfixed by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
  6544. // + improved by: Lars Fischer
  6545. // + input by: Ratheous
  6546. // + improved by: Orlando
  6547. // + reimplemented by: Brett Zamir (http://brett-zamir.me)
  6548. // + bugfixed by: Rob
  6549. // + input by: e-mike
  6550. // + improved by: Brett Zamir (http://brett-zamir.me)
  6551. // % note 1: info on what encoding functions to use from: http://xkr.us/articles/javascript/encode-compare/
  6552. // % note 2: Please be aware that this function expects to decode from UTF-8 encoded strings, as found on
  6553. // % note 2: pages served as UTF-8
  6554. // * example 1: \php.urldecode('Kevin+van+Zonneveld%21');
  6555. // * returns 1: 'Kevin van Zonneveld!'
  6556. // * example 2: \php.urldecode('http%3A%2F%2Fkevin.vanzonneveld.net%2F');
  6557. // * returns 2: 'http://kevin.vanzonneveld.net/'
  6558. // * example 3: \php.urldecode('http%3A%2F%2Fwww.google.nl%2Fsearch%3Fq%3Dphp.js%26ie%3Dutf-8%26oe%3Dutf-8%26aq%3Dt%26rls%3Dcom.ubuntu%3Aen-US%3Aunofficial%26client%3Dfirefox-a');
  6559. // * returns 3: 'http://www.google.nl/search?q=php.js&ie=utf-8&oe=utf-8&aq=t&rls=com.ubuntu:en-US:unofficial&client=firefox-a'
  6560. return decodeURIComponent((str + '').replace(/\+/g, '%20'));
  6561. };
  6562. php.urlencode = function (str) {
  6563. // URL-encodes string
  6564. //
  6565. // version: 1103.1210
  6566. // discuss at: http://phpjs.org/functions/urlencode
  6567. // + original by: Philip Peterson
  6568. // + improved by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
  6569. // + input by: AJ
  6570. // + improved by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
  6571. // + improved by: Brett Zamir (http://brett-zamir.me)
  6572. // + bugfixed by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
  6573. // + input by: travc
  6574. // + input by: Brett Zamir (http://brett-zamir.me)
  6575. // + bugfixed by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
  6576. // + improved by: Lars Fischer
  6577. // + input by: Ratheous
  6578. // + reimplemented by: Brett Zamir (http://brett-zamir.me)
  6579. // + bugfixed by: Joris
  6580. // + reimplemented by: Brett Zamir (http://brett-zamir.me)
  6581. // % note 1: This reflects PHP 5.3/6.0+ behavior
  6582. // % note 2: Please be aware that this function expects to encode into UTF-8 encoded strings, as found on
  6583. // % note 2: pages served as UTF-8
  6584. // * example 1: \php.urlencode('Kevin van Zonneveld!');
  6585. // * returns 1: 'Kevin+van+Zonneveld%21'
  6586. // * example 2: \php.urlencode('http://kevin.vanzonneveld.net/');
  6587. // * returns 2: 'http%3A%2F%2Fkevin.vanzonneveld.net%2F'
  6588. // * example 3: \php.urlencode('http://www.google.nl/search?q=php.js&ie=utf-8&oe=utf-8&aq=t&rls=com.ubuntu:en-US:unofficial&client=firefox-a');
  6589. // * returns 3: 'http%3A%2F%2Fwww.google.nl%2Fsearch%3Fq%3Dphp.js%26ie%3Dutf-8%26oe%3Dutf-8%26aq%3Dt%26rls%3Dcom.ubuntu%3Aen-US%3Aunofficial%26client%3Dfirefox-a'
  6590. str = (str + '').toString();
  6591. // Tilde should be allowed unescaped in future versions of PHP (as reflected below), but if you want to reflect current
  6592. // PHP behavior, you would need to add ".replace(/~/g, '%7E');" to the following.
  6593. return encodeURIComponent(str).replace(/!/g, '%21').replace(/'/g, '%27').replace(/\(/g, '%28').
  6594. replace(/\)/g, '%29').replace(/\*/g, '%2A').replace(/%20/g, '+');
  6595. };
  6596. php.usort = function (inputArr, sorter) {
  6597. // Sort an array by values using a user-defined comparison function
  6598. //
  6599. // version: 1103.1210
  6600. // discuss at: http://phpjs.org/functions/usort
  6601. // + original by: Brett Zamir (http://brett-zamir.me)
  6602. // + improved by: Brett Zamir (http://brett-zamir.me)
  6603. // % note 1: This function deviates from PHP in returning a copy of the array instead
  6604. // % note 1: of acting by reference and returning true; this was necessary because
  6605. // % note 1: IE does not allow deleting and re-adding of properties without caching
  6606. // % note 1: of property position; you can set the ini of "phpjs.strictForIn" to true to
  6607. // % note 1: get the PHP behavior, but use this only if you are in an environment
  6608. // % note 1: such as Firefox extensions where for-in iteration order is fixed and true
  6609. // % note 1: property deletion is supported. Note that we intend to implement the PHP
  6610. // % note 1: behavior by default if IE ever does allow it; only gives shallow copy since
  6611. // % note 1: is by reference in PHP anyways
  6612. // * example 1: \php.stuff = {d: '3', a: '1', b: '11', c: '4'};
  6613. // * example 1: \php.stuff = usort(stuff, function (a, b) {return(a-b);});
  6614. // * results 1: stuff = {0: '1', 1: '3', 2: '4', 3: '11'};
  6615. var valArr = [],
  6616. k = '',
  6617. i = 0,
  6618. strictForIn = false,
  6619. populateArr = {};
  6620. if (typeof sorter === 'string') {
  6621. sorter = this[sorter];
  6622. } else if (sorter instanceof Array) {
  6623. sorter = this[sorter[0]][sorter[1]];
  6624. }
  6625. // BEGIN REDUNDANT
  6626. this.php_js = this.php_js || {};
  6627. this.php_js.ini = this.php_js.ini || {};
  6628. // END REDUNDANT
  6629. strictForIn = this.php_js.ini['phpjs.strictForIn'] && this.php_js.ini['phpjs.strictForIn'].local_value && this.php_js.ini['phpjs.strictForIn'].local_value !== 'off';
  6630. populateArr = strictForIn ? inputArr : populateArr;
  6631. for (k in inputArr) { // Get key and value arrays
  6632. if (inputArr.hasOwnProperty(k)) {
  6633. valArr.push(inputArr[k]);
  6634. if (strictForIn) {
  6635. delete inputArr[k];
  6636. }
  6637. }
  6638. }
  6639. try {
  6640. valArr.sort(sorter);
  6641. } catch (e) {
  6642. return false;
  6643. }
  6644. for (i = 0; i < valArr.length; i++) { // Repopulate the old array
  6645. populateArr[i] = valArr[i];
  6646. }
  6647. return strictForIn || populateArr;
  6648. };
  6649. php.utf8_decode = function (str_data) {
  6650. // Converts a UTF-8 encoded string to ISO-8859-1
  6651. //
  6652. // version: 1103.1210
  6653. // discuss at: http://phpjs.org/functions/utf8_decode
  6654. // + original by: Webtoolkit.info (http://www.webtoolkit.info/)
  6655. // + input by: Aman Gupta
  6656. // + improved by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
  6657. // + improved by: Norman "zEh" Fuchs
  6658. // + bugfixed by: hitwork
  6659. // + bugfixed by: Onno Marsman
  6660. // + input by: Brett Zamir (http://brett-zamir.me)
  6661. // + bugfixed by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
  6662. // * example 1: \php.utf8_decode('Kevin van Zonneveld');
  6663. // * returns 1: 'Kevin van Zonneveld'
  6664. var tmp_arr = [],
  6665. i = 0,
  6666. ac = 0,
  6667. c1 = 0,
  6668. c2 = 0,
  6669. c3 = 0;
  6670. str_data += '';
  6671. while (i < str_data.length) {
  6672. c1 = str_data.charCodeAt(i);
  6673. if (c1 < 128) {
  6674. tmp_arr[ac++] = String.fromCharCode(c1);
  6675. i++;
  6676. } else if (c1 > 191 && c1 < 224) {
  6677. c2 = str_data.charCodeAt(i + 1);
  6678. tmp_arr[ac++] = String.fromCharCode(((c1 & 31) << 6) | (c2 & 63));
  6679. i += 2;
  6680. } else {
  6681. c2 = str_data.charCodeAt(i + 1);
  6682. c3 = str_data.charCodeAt(i + 2);
  6683. tmp_arr[ac++] = String.fromCharCode(((c1 & 15) << 12) | ((c2 & 63) << 6) | (c3 & 63));
  6684. i += 3;
  6685. }
  6686. }
  6687. return tmp_arr.join('');
  6688. };
  6689. php.utf8_encode = function (argString) {
  6690. // Encodes an ISO-8859-1 string to UTF-8
  6691. //
  6692. // version: 1103.1210
  6693. // discuss at: http://phpjs.org/functions/utf8_encode
  6694. // + original by: Webtoolkit.info (http://www.webtoolkit.info/)
  6695. // + improved by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
  6696. // + improved by: sowberry
  6697. // + tweaked by: Jack
  6698. // + bugfixed by: Onno Marsman
  6699. // + improved by: Yves Sucaet
  6700. // + bugfixed by: Onno Marsman
  6701. // + bugfixed by: Ulrich
  6702. // * example 1: \php.utf8_encode('Kevin van Zonneveld');
  6703. // * returns 1: 'Kevin van Zonneveld'
  6704. var string = (argString + ''); // .replace(/\r\n/g, "\n").replace(/\r/g, "\n");
  6705. var utftext = "",
  6706. start, end, stringl = 0;
  6707. start = end = 0;
  6708. stringl = string.length;
  6709. for (var n = 0; n < stringl; n++) {
  6710. var c1 = string.charCodeAt(n);
  6711. var enc = null;
  6712. if (c1 < 128) {
  6713. end++;
  6714. } else if (c1 > 127 && c1 < 2048) {
  6715. enc = String.fromCharCode((c1 >> 6) | 192) + String.fromCharCode((c1 & 63) | 128);
  6716. } else {
  6717. enc = String.fromCharCode((c1 >> 12) | 224) + String.fromCharCode(((c1 >> 6) & 63) | 128) + String.fromCharCode((c1 & 63) | 128);
  6718. }
  6719. if (enc !== null) {
  6720. if (end > start) {
  6721. utftext += string.slice(start, end);
  6722. }
  6723. utftext += enc;
  6724. start = end = n + 1;
  6725. }
  6726. }
  6727. if (end > start) {
  6728. utftext += string.slice(start, stringl);
  6729. }
  6730. return utftext;
  6731. };