protoblast
Advanced tools
Comparing version 0.7.12 to 0.7.13
@@ -0,1 +1,12 @@ | ||
## 0.7.13 (2021-09-12) | ||
* Allow custom blocks in `String#tokenizeHTML()` to drop their delimiters from the output | ||
* Add line_start & line_end to String.tokenizeHTML() output | ||
* Add line_start & line_end to Function.tokenize() output | ||
* Add `Blast.isFirefox` boolean property | ||
* Add `Error.parseStack()` method | ||
* `String#slug()` will now also replace underscores | ||
* Add `String#reverse()` method, which works with astral characters | ||
* Also add `StringBuilder#reverse()` and `StringBuilder#banish()` methods | ||
## 0.7.12 (2021-08-10) | ||
@@ -2,0 +13,0 @@ |
@@ -225,2 +225,88 @@ const ERROR = Symbol('error'); | ||
const V8_NAMED_LINE = /at (.*?) \((.*?):(\d*):(\d*)\)/, | ||
V8_ANON_LINE = /at (.*?):(\d*):(\d*)/, | ||
FX_LINE = /(.*?)@(.*):(\d*):(\d*)/, | ||
UNKNOWN = 'unknown'; | ||
/** | ||
* Parse an error's stacktrace | ||
* | ||
* @author Jelle De Loecker <jelle@elevenways.be> | ||
* @since 0.7.13 | ||
* @version 0.7.13 | ||
* | ||
* @param {Error|string} error | ||
* | ||
* @return {Array<Object>} | ||
*/ | ||
Blast.defineStatic('Error', function parseStack(error) { | ||
if (!error) { | ||
return {}; | ||
} | ||
let stack, | ||
is_v8; | ||
if (typeof error == 'string') { | ||
stack = error; | ||
} else { | ||
stack = error.stack || ''; | ||
} | ||
// Turn the stack string into an array | ||
let result = [], | ||
lines = stack.split('\n'), | ||
entry, | ||
temp, | ||
line, | ||
i; | ||
if (stack.indexOf('\n at ') > -1) { | ||
is_v8 = true; | ||
i = 1; | ||
} else { | ||
i = 0; | ||
} | ||
for (; i < lines.length; i++) { | ||
line = lines[i]; | ||
if (is_v8) { | ||
if (line.indexOf('(') > -1) { | ||
temp = V8_NAMED_LINE.exec(line); | ||
} else { | ||
temp = V8_ANON_LINE.exec(line); | ||
if (temp) { | ||
temp.splice(1, 0, 'anonymous'); | ||
} | ||
} | ||
} else { | ||
// It's probably firefox | ||
temp = FX_LINE.exec(line); | ||
if (temp && !temp[1]) { | ||
temp[1] = 'anonymous'; | ||
} | ||
} | ||
if (!temp) { | ||
temp = ['', UNKNOWN, UNKNOWN, UNKNOWN, UNKNOWN]; | ||
} | ||
result.push({ | ||
// Chrome includes the instance name (Instance.method), | ||
// firefox does not | ||
name : temp[1], | ||
path : temp[2], | ||
file : temp[2].split(/\/|\\/g).pop(), | ||
line : +temp[3], | ||
char : +temp[4], | ||
}); | ||
} | ||
return result; | ||
}); | ||
Blast.Classes.EvalError = EvalError; | ||
@@ -227,0 +313,0 @@ Blast.Classes.RangeError = RangeError; |
@@ -257,3 +257,3 @@ var tokenMatches, | ||
* @since 0.1.2 | ||
* @version 0.7.0 | ||
* @version 0.7.13 | ||
* | ||
@@ -268,3 +268,4 @@ * @param {String} sourceCode | ||
var tokens = [], | ||
let line_nr = 0, | ||
tokens = [], | ||
obj, | ||
@@ -315,2 +316,4 @@ i; | ||
value : tokens[i], | ||
line_start : line_nr, | ||
line_end : 0, | ||
}; | ||
@@ -365,5 +368,9 @@ | ||
if (obj.type != 'whitespace') { | ||
if (obj.type == 'whitespace') { | ||
line_nr += Bound.String.count(obj.value, '\n'); | ||
} else { | ||
prev = obj; | ||
} | ||
obj.line_end = line_nr; | ||
} | ||
@@ -370,0 +377,0 @@ |
@@ -238,2 +238,3 @@ module.exports = function BlastInitLoader(modifyPrototype) { | ||
Blast.isChrome = ua.family == 'chrome'; | ||
Blast.isFirefox = ua.family == 'firefox'; | ||
} | ||
@@ -240,0 +241,0 @@ } |
@@ -528,3 +528,3 @@ module.exports = function serverFunctions(Blast, extras) { | ||
* | ||
* @return {Pledge} | ||
* @return {Pledge<string>} | ||
*/ | ||
@@ -829,3 +829,3 @@ Blast.mkdirp = function mkdirp(path, options, callback) { | ||
* | ||
* @return {Pledge} | ||
* @return {Pledge<string>} | ||
*/ | ||
@@ -832,0 +832,0 @@ Blast.createTempDir = function createTempDir(options, callback) { |
@@ -0,1 +1,2 @@ | ||
const Str = Bound.String; | ||
let astral_rx = /\ud83c[\udffb-\udfff](?=\ud83c[\udffb-\udfff])|(?:[^\ud800-\udfff][\u0300-\u036f\ufe20-\ufe23\u20d0-\u20f0]?|[\u0300-\u036f\ufe20-\ufe23\u20d0-\u20f0]|(?:\ud83c[\udde6-\uddff]){2}|[\ud800-\udbff][\udc00-\udfff]|[\ud800-\udfff])[\ufe0e\ufe0f]?(?:[\u0300-\u036f\ufe20-\ufe23\u20d0-\u20f0]|\ud83c[\udffb-\udfff])?(?:\u200d(?:[^\ud800-\udfff]|(?:\ud83c[\udde6-\uddff]){2}|[\ud800-\udbff][\udc00-\udfff])[\ufe0e\ufe0f]?(?:[\u0300-\u036f\ufe20-\ufe23\u20d0-\u20f0]|\ud83c[\udffb-\udfff])?)*/g; | ||
@@ -66,3 +67,3 @@ let hashLengths = { | ||
if (separator == null) { | ||
let tokens = Bound.String.tokenizeHTML(value, {state: Blast.HTML_TOKENIZER_STATES.TAG_CONTENT}), | ||
let tokens = Str.tokenizeHTML(value, {state: Blast.HTML_TOKENIZER_STATES.TAG_CONTENT}), | ||
token; | ||
@@ -209,3 +210,3 @@ | ||
Blast.defineStatic('String', 'decodeCookies', function decodeCookies(value) { | ||
return Bound.String.decodeAttributes(value, /; */); | ||
return Str.decodeAttributes(value, /; */); | ||
}); | ||
@@ -422,3 +423,3 @@ | ||
// Make sure it's 4 characters long | ||
temp = Bound.String.multiply('0', 4-temp.length) + temp; | ||
temp = Str.multiply('0', 4-temp.length) + temp; | ||
@@ -660,3 +661,3 @@ result += '\\u' + temp.toUpperCase(); | ||
* @since 0.6.5 | ||
* @version 0.7.3 | ||
* @version 0.7.13 | ||
* | ||
@@ -677,2 +678,3 @@ * @param {String source | ||
last_tag = '', | ||
line_nr = 0, | ||
block_indexes_arr, | ||
@@ -686,3 +688,5 @@ ordered_blocks, | ||
block, | ||
piece, | ||
open, | ||
temp, | ||
char, | ||
@@ -694,2 +698,47 @@ end, | ||
function pushResult(token) { | ||
token.line_start = line_nr; | ||
result.push(token); | ||
line_nr += Str.count(token.value, '\n'); | ||
token.line_end = line_nr; | ||
} | ||
let skip_empty_custom_tokens = false; | ||
if (options && options.skip_empty_custom_tokens) { | ||
skip_empty_custom_tokens = true; | ||
} | ||
function createToken(type, value) { | ||
if (current) { | ||
// When working with custom blocks, empty tokens can be made | ||
// We don't want these | ||
// For now, skipping these is optional for backwards compatibility | ||
// reasons, for 0.8 & up it should be the default behaviour | ||
if (!skip_empty_custom_tokens || current.value !== '') { | ||
pushResult(current); | ||
} | ||
} | ||
if (type === null) { | ||
current = null; | ||
} else { | ||
if (value == null) { | ||
value = ''; | ||
} | ||
current = { | ||
type : type, | ||
line_start : 0, | ||
line_end : 0, | ||
value : value, | ||
}; | ||
} | ||
return current; | ||
} | ||
if (options) { | ||
@@ -732,3 +781,3 @@ | ||
key = block.name; | ||
open = Bound.String.allIndexesOf(source, block.open); | ||
open = Str.allIndexesOf(source, block.open); | ||
@@ -804,17 +853,27 @@ if (open.length) { | ||
result.push({ | ||
type : key, | ||
value : source.slice(i, end) | ||
}); | ||
piece = source.slice(i, end); | ||
if (block.strip_delimiter) { | ||
piece = piece.slice(block.open.length); | ||
// End delimiters can be optional | ||
if (piece.slice(-block.close.length) == block.close) { | ||
piece = piece.slice(0, -block.close.length); | ||
} | ||
} | ||
// Remember the current token type | ||
if (current) { | ||
temp = current.type; | ||
} else { | ||
temp = null; | ||
} | ||
createToken(key, piece); | ||
if (state === STATE.ATTR_VAL) { | ||
state = STATE.TAG_CONTENT; | ||
current = null; | ||
createToken(null); | ||
} else if (current) { | ||
current = { | ||
type : current.type, | ||
value : '' | ||
}; | ||
result.push(current); | ||
createToken(temp); | ||
} | ||
@@ -828,8 +887,3 @@ | ||
if (!current) { | ||
current = { | ||
type : 'text', | ||
value : '' | ||
}; | ||
result.push(current); | ||
createToken('text'); | ||
} | ||
@@ -855,3 +909,3 @@ | ||
current.value += '-->'; | ||
current = null; | ||
createToken(null); | ||
i += 2; | ||
@@ -876,39 +930,14 @@ state = STATE.PLAINTEXT; | ||
state = STATE.TAG_CONTENT; | ||
current = null; | ||
createToken(null); | ||
} else if (char == '"') { | ||
state = STATE.STRING_D; | ||
result.push({ | ||
type : 'string_open', | ||
value : char | ||
}); | ||
current = { | ||
type : 'string', | ||
value : '' | ||
}; | ||
result.push(current); | ||
createToken('string_open', char); | ||
createToken('string'); | ||
} else if (char == "'") { | ||
state = STATE.STRING_S; | ||
result.push({ | ||
type : 'string_open', | ||
value : char | ||
}); | ||
current = { | ||
type : 'string', | ||
value : '' | ||
}; | ||
result.push(current); | ||
createToken('string_open', char); | ||
createToken('string'); | ||
} else { | ||
state = STATE.ATTR_IDENT; | ||
current = { | ||
type : 'identifier', | ||
value : char | ||
}; | ||
result.push(current); | ||
createToken('identifier', char); | ||
} | ||
@@ -926,8 +955,4 @@ | ||
if (char === '"') { | ||
result.push({ | ||
type : 'string_close', | ||
value : char | ||
}); | ||
current = null; | ||
createToken('string_close', char); | ||
createToken(null); | ||
state = STATE.TAG_CONTENT; | ||
@@ -949,8 +974,4 @@ continue; | ||
if (char === "'") { | ||
result.push({ | ||
type : 'string_close', | ||
value : char | ||
}); | ||
current = null; | ||
createToken('string_close', char); | ||
createToken(null); | ||
state = STATE.TAG_CONTENT; | ||
@@ -970,3 +991,3 @@ continue; | ||
state = STATE.TAG_CONTENT; | ||
current = null; | ||
createToken(null); | ||
i--; | ||
@@ -985,4 +1006,3 @@ } else { | ||
state = STATE.COMMENT; | ||
current = {type: 'comment', value: char}; | ||
result.push(current); | ||
createToken('comment', char); | ||
tag_buffer = ''; | ||
@@ -994,7 +1014,8 @@ continue; | ||
tag_buffer += char; | ||
result.push({type: 'open_bracket', value: '<'}); | ||
createToken('open_bracket', '<'); | ||
if (source.substr(i, 2) == '</') { | ||
char = source[++i]; | ||
result.push({type: 'forward_slash', value: '/'}); | ||
createToken('forward_slash', '/'); | ||
closing = true; | ||
@@ -1005,12 +1026,7 @@ } else { | ||
current = null; | ||
createToken(null); | ||
last_tag = ''; | ||
} else { | ||
if (!current) { | ||
current = { | ||
type : 'text', | ||
value : '' | ||
}; | ||
result.push(current); | ||
createToken('text'); | ||
} | ||
@@ -1047,3 +1063,3 @@ | ||
state = STATE.PLAINTEXT; | ||
current = null; | ||
createToken(null); | ||
} | ||
@@ -1064,8 +1080,3 @@ | ||
if (!current || current.type != 'whitespace') { | ||
current = { | ||
type : 'whitespace', | ||
value : char | ||
}; | ||
result.push(current); | ||
createToken('whitespace', char); | ||
if (state === STATE.TAG_NAME) { | ||
@@ -1084,3 +1095,3 @@ state = STATE.TAG_CONTENT; | ||
result.push({type: 'close_bracket', value: '>'}); | ||
createToken('close_bracket', '>'); | ||
tag_buffer = ''; | ||
@@ -1094,3 +1105,3 @@ | ||
current = null; | ||
createToken(null); | ||
} else if (char == '<') { | ||
@@ -1105,7 +1116,7 @@ depth++; | ||
if (depth && source[i + 1] != '>') { | ||
result.push({type: 'close_bracket', value: '>'}); | ||
createToken('close_bracket', '>'); | ||
tag_buffer = ''; | ||
i -= 2; | ||
depth--; | ||
current = null; | ||
createToken(null); | ||
@@ -1123,3 +1134,3 @@ if (!closing && last_tag.toLowerCase() == 'script') { | ||
if (char == '/') { | ||
result.push({type: 'forward_slash', value: '/'}); | ||
createToken('forward_slash', '/'); | ||
continue; | ||
@@ -1129,8 +1140,4 @@ } | ||
state = STATE.ATTR_NAME; | ||
current = { | ||
type : 'attribute', | ||
value : char | ||
}; | ||
result.push(current); | ||
createToken('attribute', char); | ||
} | ||
@@ -1149,4 +1156,3 @@ | ||
if (char == '=') { | ||
current = {type: 'equals', value: '='}; | ||
result.push(current); | ||
createToken('equals', '='); | ||
state = STATE.ATTR_VAL; | ||
@@ -1165,10 +1171,8 @@ continue; | ||
state = STATE.COMMENT; | ||
current = {type: 'comment', value: char}; | ||
createToken('comment', char); | ||
} else { | ||
state = STATE.TAG_NAME; | ||
last_tag = char; | ||
current = {type: 'tag_name', value: char}; | ||
createToken('tag_name', char); | ||
} | ||
result.push(current); | ||
} else { | ||
@@ -1179,2 +1183,7 @@ tag_buffer += char; | ||
// Don't forget the last token | ||
if (current) { | ||
pushResult(current); | ||
} | ||
return result; | ||
@@ -1239,3 +1248,3 @@ }); | ||
// Tokenize the input | ||
tokens = Bound.String.tokenizeHTML(this); | ||
tokens = Str.tokenizeHTML(this); | ||
@@ -1294,5 +1303,5 @@ for (i = 0; i < tokens.length; i++) { | ||
* | ||
* @author Jelle De Loecker <jelle@develry.be> | ||
* @author Jelle De Loecker <jelle@elevenways.be> | ||
* @since 0.1.3 | ||
* @version 0.7.0 | ||
* @version 0.7.13 | ||
* | ||
@@ -1321,3 +1330,3 @@ * @return {String} The sluggifier string | ||
// Replace spaces and placeholders with the separator | ||
result = result.replace(/ +|=+/g, separator); | ||
result = result.replace(/\s+|=+|_+/g, separator); | ||
@@ -1436,3 +1445,3 @@ // Truncate repeats of the separator | ||
e_len, | ||
len = Bound.String.countCharacters(this); | ||
len = Str.countCharacters(this); | ||
@@ -1449,6 +1458,6 @@ if (len <= length) { | ||
e_len = Bound.String.countCharacters(ellipsis); | ||
e_len = Str.countCharacters(ellipsis); | ||
// Get the simple cut | ||
simpleCut = Bound.String.substrCharacters(this, 0, length - e_len); | ||
simpleCut = Str.substrCharacters(this, 0, length - e_len); | ||
@@ -1483,3 +1492,3 @@ if (typeof word === 'undefined' || word) { | ||
var tokens = Bound.String.tokenizeHTML(this), | ||
var tokens = Str.tokenizeHTML(this), | ||
token, | ||
@@ -1507,6 +1516,6 @@ count = 0, | ||
count += Bound.String.countCharacters(token.value); | ||
count += Str.countCharacters(token.value); | ||
if (count > length) { | ||
temp += Bound.String.truncate(token.value, count - length, word, ellipsis); | ||
temp += Str.truncate(token.value, count - length, word, ellipsis); | ||
break; | ||
@@ -1520,3 +1529,3 @@ } | ||
// Now fix the html | ||
return Bound.String.fixHTML(temp); | ||
return Str.fixHTML(temp); | ||
}); | ||
@@ -1646,3 +1655,3 @@ | ||
if (word == null || word === '') { | ||
return Bound.String.countCharacters(this); | ||
return Str.countCharacters(this); | ||
} | ||
@@ -1814,3 +1823,3 @@ | ||
// Append the postfix if it isn't present yet | ||
if (!Bound.String.endsWith(str, postfixString)) str += postfixString; | ||
if (!Str.endsWith(str, postfixString)) str += postfixString; | ||
@@ -1884,3 +1893,3 @@ return str; | ||
Blast.definePrototype('String', function isObjectId() { | ||
return this.length == 24 && Bound.String.isHex(this); | ||
return this.length == 24 && Str.isHex(this); | ||
}); | ||
@@ -1901,3 +1910,3 @@ | ||
var isHex = Bound.String.isHex(this); | ||
var isHex = Str.isHex(this); | ||
@@ -2068,3 +2077,3 @@ if (!hashType) { | ||
if (values && typeof values == 'object') { | ||
params = Bound.String.placeholders(this); | ||
params = Str.placeholders(this); | ||
@@ -2564,3 +2573,3 @@ for (i = 0; i < params.length; i++) { | ||
if (Bound.String.isEmptyWhitespace(this)) { | ||
if (Str.isEmptyWhitespace(this)) { | ||
return true; | ||
@@ -2570,4 +2579,4 @@ } | ||
if (~this.indexOf('<') && ~this.indexOf('>')) { | ||
str = Bound.String.stripTags(this); | ||
return Bound.String.isEmptyWhitespace(str); | ||
str = Str.stripTags(this); | ||
return Str.isEmptyWhitespace(str); | ||
} | ||
@@ -2632,3 +2641,3 @@ | ||
var str_len = Bound.String.countCharacters(this), | ||
var str_len = Str.countCharacters(this), | ||
match, | ||
@@ -2752,2 +2761,15 @@ end; | ||
return lines.join('\n'); | ||
}); | ||
/** | ||
* Reverse a string | ||
* | ||
* @author Jelle De Loecker <jelle@elevenways.be> | ||
* @since 0.7.13 | ||
* @version 0.7.13 | ||
* | ||
* @return {string} | ||
*/ | ||
Blast.definePrototype('String', function reverse() { | ||
return Str.splitCharacters(this).reverse().join(''); | ||
}); |
@@ -0,1 +1,3 @@ | ||
const Str = Bound.String; | ||
/** | ||
@@ -6,5 +8,5 @@ * The StringBuilder class | ||
* @since 0.7.0 | ||
* @version 0.7.0 | ||
* @version 0.7.13 | ||
* | ||
* @param {String} str | ||
* @param {string} str | ||
*/ | ||
@@ -18,2 +20,5 @@ var SB = Fn.inherits(null, 'Develry', function StringBuilder(str) { | ||
} | ||
// Strings can be moved into limbo instead of being deleted | ||
this.limbo = ''; | ||
}); | ||
@@ -28,3 +33,3 @@ | ||
* | ||
* @type {Number} | ||
* @type {number} | ||
*/ | ||
@@ -40,3 +45,3 @@ SB.setProperty(function length() { | ||
* @since 0.7.0 | ||
* @version 0.7.0 | ||
* @version 0.7.13 | ||
* | ||
@@ -49,2 +54,3 @@ * @return {StringBuilder} | ||
result.buffer = this.buffer; | ||
result.limbo = this.limbo; | ||
@@ -61,3 +67,3 @@ return result; | ||
* | ||
* @param {String} str | ||
* @param {string} str | ||
*/ | ||
@@ -94,3 +100,3 @@ SB.setMethod(function append(str) { | ||
* | ||
* @param {String} str | ||
* @param {string} str | ||
*/ | ||
@@ -112,4 +118,6 @@ SB.setMethod(function prepend(str) { | ||
* | ||
* @param {Number} start | ||
* @param {Number} end | ||
* @param {number} start | ||
* @param {number} end | ||
* | ||
* @return {StringBuilder} | ||
*/ | ||
@@ -132,3 +140,5 @@ SB.setMethod('delete', function _delete(start, end) { | ||
* | ||
* @param {Number} index | ||
* @param {number} index | ||
* | ||
* @return {string} | ||
*/ | ||
@@ -147,4 +157,6 @@ SB.setMethod(function charAt(index) { | ||
* | ||
* @param {Number} start | ||
* @param {Number} end | ||
* @param {number} start | ||
* @param {number} end | ||
* | ||
* @return {string} | ||
*/ | ||
@@ -165,2 +177,44 @@ SB.setMethod(function cut(start, end) { | ||
/** | ||
* Move a piece of the string to limbo | ||
* | ||
* @author Jelle De Loecker <jelle@elevenways.be> | ||
* @since 0.7.13 | ||
* @version 0.7.13 | ||
* | ||
* @param {number} start | ||
* @param {number} end | ||
* | ||
* @return {string} | ||
*/ | ||
SB.setMethod(function banish(start, end) { | ||
let result = this.cut(start, end); | ||
if (result !== '') { | ||
this.limbo += result; | ||
} | ||
return result; | ||
}); | ||
/** | ||
* Reverse the string we're working with | ||
* | ||
* @author Jelle De Loecker <jelle@elevenways.be> | ||
* @since 0.7.13 | ||
* @version 0.7.13 | ||
* | ||
* @return {StringBuilder} | ||
*/ | ||
SB.setMethod(function reverse() { | ||
this.buffer = Str.reverse(this.buffer); | ||
if (this.limbo) { | ||
this.limbo = Str.reverse(this.limbo); | ||
} | ||
return this; | ||
}); | ||
/** | ||
* Get the total string | ||
@@ -172,3 +226,3 @@ * | ||
* | ||
* @return {String} | ||
* @return {string} | ||
*/ | ||
@@ -175,0 +229,0 @@ SB.setMethod(function toString() { |
{ | ||
"name": "protoblast", | ||
"description": "Native object expansion library", | ||
"version": "0.7.12", | ||
"version": "0.7.13", | ||
"author": "Jelle De Loecker <jelle@elevenways.be>", | ||
@@ -6,0 +6,0 @@ "keywords": [ |
733709
30446