UNPKG

@qooxdoo/framework

Version:

The JS Framework for Coders

141 lines (114 loc) 4.51 kB
/* ************************************************************************ qooxdoo - the new era of web development http://qooxdoo.org Copyright: 2004-2008 1&1 Internet AG, Germany, http://www.1und1.de License: MIT: https://opensource.org/licenses/MIT See the LICENSE file in the project's top-level directory for details. Authors: * Sebastian Werner (wpbasti) * Adrian Olaru (adrianolaru) ====================================================================== This class contains code based on the following work: * Cross-Browser Split http://blog.stevenlevithan.com/archives/cross-browser-split Version 1.0.1 Copyright: (c) 2006-2007, Steven Levithan <http://stevenlevithan.com> License: MIT: http://www.opensource.org/licenses/mit-license.php Authors: * Steven Levithan ************************************************************************ */ /** * Implements an ECMA-compliant, uniform cross-browser split method */ qx.Bootstrap.define("qx.util.StringSplit", { statics : { /** * ECMA-compliant, uniform cross-browser split method * * @param str {String} Incoming string to split * @param separator {RegExp} Specifies the character to use for separating the string. * The separator is treated as a string or a regular expression. If separator is * omitted, the array returned contains one element consisting of the entire string. * @param limit {Integer?} Integer specifying a limit on the number of splits to be found. * @return {String[]} split string */ split : function (str, separator, limit) { // if `separator` is not a regex, use the native `split` if (Object.prototype.toString.call(separator) !== "[object RegExp]") { return String.prototype.split.call(str, separator, limit); } var output = [], lastLastIndex = 0, flags = (separator.ignoreCase ? "i" : "") + (separator.multiline ? "m" : "") + (separator.sticky ? "y" : ""), separator = RegExp(separator.source, flags + "g"), // make `global` and avoid `lastIndex` issues by working with a copy separator2, match, lastIndex, lastLength, compliantExecNpcg = /()??/.exec("")[1] === undefined; // NPCG: nonparticipating capturing group str = str + ""; // type conversion if (!compliantExecNpcg) { separator2 = RegExp("^" + separator.source + "$(?!\\s)", flags); // doesn't need /g or /y, but they don't hurt } /* behavior for `limit`: if it's... - `undefined`: no limit. - `NaN` or zero: return an empty array. - a positive number: use `Math.floor(limit)`. - a negative number: no limit. - other: type-convert, then use the above rules. */ if (limit === undefined || +limit < 0) { limit = Infinity; } else { limit = Math.floor(+limit); if (!limit) { return []; } } while (match = separator.exec(str)) { lastIndex = match.index + match[0].length; // `separator.lastIndex` is not reliable cross-browser if (lastIndex > lastLastIndex) { output.push(str.slice(lastLastIndex, match.index)); // fix browsers whose `exec` methods don't consistently return `undefined` for nonparticipating capturing groups if (!compliantExecNpcg && match.length > 1) { match[0].replace(separator2, function () { for (var i = 1; i < arguments.length - 2; i++) { if (arguments[i] === undefined) { match[i] = undefined; } } }); } if (match.length > 1 && match.index < str.length) { Array.prototype.push.apply(output, match.slice(1)); } lastLength = match[0].length; lastLastIndex = lastIndex; if (output.length >= limit) { break; } } if (separator.lastIndex === match.index) { separator.lastIndex++; // avoid an infinite loop } } if (lastLastIndex === str.length) { if (lastLength || !separator.test("")) { output.push(""); } } else { output.push(str.slice(lastLastIndex)); } return output.length > limit ? output.slice(0, limit) : output; } } });