Socket
Socket
Sign inDemoInstall

protoblast

Package Overview
Dependencies
Maintainers
1
Versions
102
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

protoblast - npm Package Compare versions

Comparing version 0.6.2 to 0.6.3

18

CHANGELOG.md

@@ -0,1 +1,18 @@

## 0.6.3 (2018-12-06)
* Add `RURL#usedBaseProperty(name)` to find out if a property came from the base location
* You can now use `Date#startOf(unit)` to set dacesecond & decaminute
* `Function.series` will now pass the value from the previous task to the next
* Add `LazyPledge` class, which will only call on the executor once `then` has been called
* Forward Pledge progress reports to other pledges
* Add `Blast.isWebview` to detect when it's running in a webview
* Use `requestIdleCallback` as a `setImmediate` implementation in the browser
* Make `Informer#emit()` exit early when no listeners are found
* Rewrite setImmediate polyfill
* Add `Date#timestamp` getter
* Add `flag` parameter to `Object.path(flag, obj, path)`
* Add `Blast.PATH_AGGREGATE` flag
* Add flag support to `Array#sortByPath()`
* Rewrite `String#stripTags()`, based on Eric Norris implementation
## 0.6.2 (2018-11-09)

@@ -127,2 +144,3 @@

* Removed `Blast.setTimeout`
* Pass the `seen` object to `Blast.alikeSymbol` methods

@@ -129,0 +147,0 @@ ## 0.5.0 (2018-02-17)

36

lib/array.js

@@ -765,2 +765,5 @@ module.exports = function BlastArray(Blast, Collection, Bound, Obj) {

// Sort type symbols
Blast.arrayPath = Symbol('array_path');
/**

@@ -772,4 +775,5 @@ * Sort by given paths.

* @since 0.1.5
* @version 0.4.1
* @version 0.6.3
*
* @param {Symbol} _flag Use certain sort flag?
* @param {Number} _order Sort order: 1 for ascending, -1 for descending

@@ -780,12 +784,18 @@ * @param {String} _paths One path, an array of paths, of multiple arguments

*/
Blast.definePrototype('Array', function sortByPath(_order, _paths) {
Blast.definePrototype('Array', function sortByPath(_flag, _order, _paths) {
var paths,
path,
flag,
len,
i;
i = 0;
paths = [];
for (i = 0; i < arguments.length; i++) {
if (typeof _flag == 'symbol') {
flag = _flag;
i = 1;
}
for (; i < arguments.length; i++) {
if (Array.isArray(arguments[i])) {

@@ -817,5 +827,19 @@ paths = paths.concat(arguments[i]);

alpha = Obj.path(a, path);
beta = Obj.path(b, path);
if (flag) {
alpha = Obj.path(flag, a, path);
beta = Obj.path(flag, b, path);
if (Array.isArray(alpha)) {
alpha = alpha[alpha.length - 1];
}
if (Array.isArray(beta)) {
beta = beta[beta.length - 1];
}
} else {
alpha = Obj.path(a, path);
beta = Obj.path(b, path);
}
if (alpha < beta) {

@@ -822,0 +846,0 @@ return 0 - ord;

@@ -308,2 +308,15 @@ module.exports = function BlastDate(Blast, Collection, Bound, Obj) {

/**
* Timestamp getter
*
* @author Jelle De Loecker <jelle@develry.be>
* @since 0.6.3
* @version 0.6.3
*
* @return {String}
*/
Blast.definePrototype('Date', function timestamp() {
return +this;
}, 'get');
/**
* Calculate the bytesize of a date

@@ -624,3 +637,3 @@ *

* @since 0.1.4
* @version 0.1.4
* @version 0.6.3
*

@@ -637,2 +650,29 @@ * @param {String} unit year, quarter, month, week, day, ...

// Set start of a tenfold?
if (unit.slice(0, 4) == 'deca') {
unit = unit.slice(4);
switch (unit) {
case 'minute':
case 'second':
break;
default:
throw new Error('Unable to set tenfold of "' + unit + '"');
}
// Get the unit amount
temp = ms_units[unit] * 10;
if (!temp) {
throw new Error('Unable to find time unit "' + unit + '"');
}
temp = (~~(this / temp)) * temp;
this.setTime(temp);
return this;
}
switch (unit) {

@@ -639,0 +679,0 @@ case 'year':

6

lib/function_decorators.js

@@ -31,3 +31,3 @@ module.exports = function BlastDecorators(Blast, Collection) {

// Overwrite the value
descriptor.value = (function() {
descriptor.value = (function memoizeMethod() {

@@ -76,3 +76,3 @@ var callback,

if (result && result.then) {
result.then(function done(value) {
result.then(function donePromise(value) {
callback.apply(null, value);

@@ -83,3 +83,3 @@ });

} else {
return Blast.nextTick(function() {
return Blast.nextTick(function done() {
callback.apply(null, result);

@@ -86,0 +86,0 @@ });

@@ -97,3 +97,3 @@ module.exports = function BlastFunctionFlow(Blast, Collection, Bound) {

* @since 0.1.2
* @version 0.5.2
* @version 0.6.3
*

@@ -258,4 +258,5 @@ * @param {Boolean} _forceAsync Force asynchronous behaviour [TRUE]

if (typeof tasks[next] == 'function') {
tasks[next](nextHandler);
tasks[next](nextHandler, result);
} else {
pledge._addProgressPledge(tasks[next]);
Blast.Classes.Pledge.prototype.handleCallback.call(tasks[next], nextHandler);

@@ -302,3 +303,3 @@ }

* @since 0.1.2
* @version 0.5.9
* @version 0.6.3
*/

@@ -518,3 +519,4 @@ Blast.defineStatic('Function', function parallel(_forceAsync, _limit, _tasks, _callback) {

// Go over every tasks
tasks.every(function everyTask(fnc, index) {
for (let index = 0; index < tasks.length; index++) {
let fnc = tasks[index];

@@ -536,2 +538,3 @@ running++;

} else {
pledge._addProgressPledge(fnc);
Blast.Classes.Pledge.prototype.handleCallback.call(fnc, nextHandler);

@@ -553,8 +556,6 @@ }

if (setLimit && running >= limit) {
return false;
break;
}
}
return true;
});
stillStarting = false;

@@ -561,0 +562,0 @@

@@ -995,3 +995,3 @@ module.exports = function BlastInformer(Blast, Collection) {

* @since 0.1.3
* @version 0.1.9
* @version 0.6.3
*

@@ -1039,7 +1039,9 @@ * @param {String|Object} type

cb = null;
} else if (listeners.length < 3 && !this.forward_targets) {
}
if (listeners.length < 3 && !this.forward_targets) {
// The first 2 items are the type & filter object,
// if only those are present, no listeners were found
if (cb != null) {
Blast.setImmediate(function noListenersFound() {
Blast.nextTick(function noListenersFound() {
cb();

@@ -1072,12 +1074,15 @@ });

listeners.forEach(function eachListener(list, index) {
for (let index = 0; index < listeners.length; index++) {
var listener,
// Skip the first 2 items
if (index < 2) {
continue;
}
let listener,
context,
config,
octx;
octx,
list = listeners[index];
// Skip the first 2 items
if (index < 2) return;
listener = list[0];

@@ -1148,3 +1153,3 @@ octx = context = list[2];

};
});
}

@@ -1159,3 +1164,3 @@ // Run the functions (but do it immediately, `series` should use

// Throw the error when no callback is given
if (err) Blast.setImmediate(function throwError() {
if (err) Blast.nextTick(function throwError() {
throw err;

@@ -1162,0 +1167,0 @@ });

@@ -24,2 +24,3 @@ module.exports = function BlastInitLoader(modifyPrototype) {

key,
ua,
i;

@@ -42,2 +43,8 @@

// Is it running in a webview?
Blast.isWebview = false;
// Is it running on iOS?
Blast.isiOS = false;
// If it's a browser, is it IE?

@@ -64,7 +71,22 @@ Blast.isIE = false;

if (window.navigator && window.navigator.userAgent) {
Blast.isIE = (window.navigator.userAgent.indexOf('MSIE') > -1 || window.navigator.userAgent.indexOf('Trident/') > -1);
ua = window.navigator.userAgent;
Blast.isIE = (ua.indexOf('MSIE') > -1 || ua.indexOf('Trident/') > -1);
if (!Blast.isIE) {
Blast.isEdge = window.navigator.userAgent.indexOf('Edge/') > -1;
Blast.isEdge = ua.indexOf('Edge/') > -1;
}
if (!Blast.isEdge) {
Blast.isiOS = /iphone|ipod|ipad/i.test(ua);
if (Blast.isiOS) {
// If safari is not part of the useragent string, it's a webview
Blast.isWebview = !/safari/i.test(ua);
} else {
Blast.isWebview = ua.indexOf('; wv)') > -1;
}
Blast.isChrome = /Chrome/.test(ua);
}
}

@@ -506,3 +528,3 @@ } else if (typeof self !== 'undefined' && self.constructor && self.constructor.name == 'DedicatedWorkerGlobalScope') {

* @since 0.1.0
* @version 0.6.2
* @version 0.6.3
*

@@ -523,7 +545,14 @@ * @param {Object} target The object to add the property to

if (typeof name == 'function') {
length += 1;
shim = value;
value = type;
type = name;
name = type.name;
if (typeof type == 'string') {
length = 4;
value = name;
name = value.name;
} else {
length += 1;
shim = value;
value = type;
type = name;
name = type.name;
}
}

@@ -530,0 +559,0 @@

@@ -585,2 +585,5 @@ module.exports = function BlastObject(Blast, Collection, Bound, Obj) {

// Aggregate array results
Blast.PATH_AGGREGATE = Symbol('PATH_AGGREGATE');
/**

@@ -591,19 +594,36 @@ * Get the value of the given property path

* @since 0.0.1
* @version 0.1.9
* @version 0.6.3
*
* @param {Symbol} flag
* @param {Object} obj
* @param {String} pathString The dot notation path
* @param {String} path_string The dot notation path
*
* @return {Mixed}
*/
Blast.defineStatic('Object', function path(obj, pathString) {
Blast.defineStatic('Object', function path(_flag, _obj, _path_string) {
var pieces,
var path_string,
pieces,
piece,
here,
flag,
skip = 0,
obj,
len,
i;
if (typeof pathString !== 'string') {
if (Array.isArray(pathString)) {
pieces = pathString;
if (typeof _flag == 'symbol') {
skip = 1;
flag = _flag;
obj = _obj;
path_string = _path_string;
} else {
path_string = _obj;
obj = _flag;
flag = null;
}
if (typeof path_string !== 'string') {
if (Array.isArray(path_string)) {
pieces = path_string;
} else {

@@ -614,8 +634,8 @@ return;

len = arguments.length;
if (len == 2) {
pieces = arguments[1].split('.');
if (len == (2 + skip)) {
pieces = path_string.split('.');
} else {
pieces = new Array(len-1);
pieces = new Array(len - (1 + skip));
for (i = 1; i < len; i++) {
for (i = 1 + skip; i < len; i++) {
pieces[i-1] = arguments[i]

@@ -628,7 +648,32 @@ }

// Go over every piece in the path
for (i = 0; i < pieces.length; i++) {
if (here != null) {
here = here[pieces[i]];
if (flag == Blast.PATH_AGGREGATE) {
for (i = 0; i < pieces.length; i++) {
piece = pieces[i];
if (here != null) {
if (Array.isArray(here)) {
let arr = here,
j;
here = [];
for (j = 0; j < arr.length; j++) {
if (arr[j] != null && arr[j][piece] != null) {
here.push(arr[j][piece]);
}
}
} else {
here = here[piece];
}
}
}
} else {
// Go over every piece in the path
for (i = 0; i < pieces.length; i++) {
piece = pieces[i];
if (here != null) {
here = here[piece];
}
}
}

@@ -1574,8 +1619,15 @@

if (!seen) {
seen = {
objects : [],
ids : []
};
}
if (typeof a[Blast.alikeSymbol] == 'function') {
return a[Blast.alikeSymbol](b);
return a[Blast.alikeSymbol](b, seen);
}
if (typeof b[Blast.alikeSymbol] == 'function') {
return b[Blast.alikeSymbol](a);
return b[Blast.alikeSymbol](a, seen);
}

@@ -1602,9 +1654,2 @@

if (!seen) {
seen = {
objects : [],
ids : []
};
}
for (key in a) {

@@ -1611,0 +1656,0 @@

@@ -341,3 +341,3 @@ module.exports = function BlastPledge(Blast, Collection) {

* @since 0.5.2
* @version 0.5.2
* @version 0.6.3
*/

@@ -348,7 +348,11 @@ Pledge.setMethod(function calculateProgressParts() {

// Calculate how much is already finished
amount = this.progress_parts_finished / this.progress_parts;
if (this.state == PENDING) {
// Calculate how much is already finished
amount = this.progress_parts_finished / this.progress_parts;
// And multiply it to get a nice percentage number
amount = ~~(amount * 100);
// And multiply it to get a nice percentage number
amount = ~~(amount * 100);
} else {
amount = 100;
}

@@ -359,2 +363,35 @@ this.reportProgress(amount);

/**
* Add progress pledge
*
* @author Jelle De Loecker <jelle@develry.be>
* @since 0.6.3
* @version 0.6.3
*
* @param {Pledge} pledge
*/
Pledge.setMethod(function _addProgressPledge(pledge) {
if (!Pledge.isPledge(pledge)) {
return false;
}
this.addProgressPart(pledge.progress_parts);
this.reportProgressPart(pledge.progress_parts_finished);
let that = this,
other_addProgressPart = pledge.addProgressPart,
other_reportProgressPart = pledge.reportProgressPart;
pledge.addProgressPart = function addProgressPart(parts) {
that.addProgressPart(parts);
other_addProgressPart.call(this, parts);
};
pledge.reportProgressPart = function reportProgressPart(parts) {
that.reportProgressPart(parts);
other_reportProgressPart.call(this, parts);
};
});
/**
* Resolve with the given value

@@ -384,3 +421,3 @@ *

* @since 0.4.0
* @version 0.5.6
* @version 0.6.3
*/

@@ -392,2 +429,5 @@ Pledge.setMethod(function _doResolve(value) {

if (value && value.then) {
this._addProgressPledge(value);
return value.then(function onFulfilledResolve(value) {

@@ -410,2 +450,4 @@ that.resolve(value);

}
this.calculateProgressParts();
});

@@ -635,3 +677,39 @@

/**
* The LazyPledge Class
*
* @author Jelle De Loecker <jelle@develry.be>
* @since 0.6.3
* @version 0.6.3
*
* @param {Function} executor
*/
var Lazy = Collection.Function.inherits('Pledge', function LazyPledge(executor) {
this.executor = executor;
});
/**
* Then
*
* @author Jelle De Loecker <jelle@develry.be>
* @since 0.6.3
* @version 0.6.3
*
* @return {Pledge}
*/
Lazy.setMethod(function then(on_fulfilled, on_rejected) {
var result = then.super.call(this, on_fulfilled, on_rejected);
if (typeof this.executor != 'function') {
this.reject(new Error('No valid executor has been given'));
} else {
this._startExecutor();
}
return result;
});
Blast.defineClass('Pledge', Pledge);
Blast.defineClass('LazyPledge', Lazy);
};

@@ -664,3 +664,3 @@ module.exports = function BlastURL(Blast, Collection, Bound, Obj) {

* @since 0.5.7
* @version 0.5.7
* @version 0.6.3
*

@@ -670,3 +670,7 @@ * @return {RURL}

RURL.setStatic(function unDry(obj) {
return new RURL(obj);
var result = new RURL(obj);
result._data.from_base = obj.from_base;
return result;
});

@@ -1205,2 +1209,20 @@

/**
* Which properties were gotten from the base?
*
* @author Jelle De Loecker <jelle@develry.be>
* @since 0.6.3
* @version 0.6.3
*
* @type {Array}
*/
RURL.setProperty(function from_base() {
if (!this._data.from_base) {
this._data.from_base = [];
}
return this._data.from_base;
});
/**
* Return an object for json-drying this object

@@ -1224,3 +1246,3 @@ *

* @since 0.5.7
* @version 0.5.7
* @version 0.6.3
*

@@ -1231,11 +1253,12 @@ * @return {Object}

return {
protocol : this.protocol,
username : this.username,
password : this.password,
hostname : this.hostname,
port : this.port,
pathname : this.pathname,
search : this.search,
hash : this.hash,
slashes : this.slashes
protocol : this.protocol,
username : this.username,
password : this.password,
hostname : this.hostname,
port : this.port,
pathname : this.pathname,
search : this.search,
hash : this.hash,
slashes : this.slashes,
from_base : this.from_base
};

@@ -1424,3 +1447,10 @@ });

// Store the protocol
data.protocol = extracted.protocol || (location && location.protocol) || '';
if (extracted.protocol) {
data.protocol = extracted.protocol;
} else if (location && location.protocol) {
data.protocol = location.protocol;
this.from_base.push('protocol');
} else {
data.protocol = '';
}

@@ -1467,3 +1497,10 @@ // Store the slashes

data[key] = data[key] || (relative && rule[3] ? location && location[key] || '' : '');
if (data[key]) {
data[key] = data[key];
} else if (relative && rule[3] && location && location[key]) {
data[key] = location[key];
this.from_base.push(key);
} else {
data[key] = '';
}

@@ -1644,2 +1681,22 @@ // Lowercase hostname, host & protocol

/**
* Did the wanted property come from the base location?
*
* @author Jelle De Loecker <jelle@develry.be>
* @since 0.6.3
* @version 0.6.3
*
* @param {String} name
*
* @return {Boolean}
*/
RURL.setMethod(function usedBaseProperty(name) {
if (!this.from_base.length) {
return false;
}
return this.from_base.indexOf(name) > -1;
});
// Make it a global class

@@ -1646,0 +1703,0 @@ Blast.defineClass('RURL', RURL);

@@ -1,21 +0,1 @@

// Copyright (c) 2012 Barnesandnoble.com, llc, Donavon West, and Domenic Denicola
// Permission is hereby granted, free of charge, to any person obtaining
// a copy of this software and associated documentation files (the
// "Software"), to deal in the Software without restriction, including
// without limitation the rights to use, copy, modify, merge, publish,
// distribute, sublicense, and/or sell copies of the Software, and to
// permit persons to whom the Software is furnished to do so, subject to
// the following conditions:
// The above copyright notice and this permission notice shall be
// included in all copies or substantial portions of the Software.
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
module.exports = function BlastImmediate(Blast, Collection) {

@@ -26,46 +6,188 @@

var global = Blast.Globals,
realSetImmediate,
timeout_counter = 0,
idle_counter = 0,
last_idle = 0,
realNextTick,
timeouts = {},
idles = {},
resolved;
realClearImmediate = global.clearImmediate || global.msClearImmediate,
realSetImmediate = global.setImmediate || global.msSetImmediate,
realNextTick = global.nextTick,
handles = {};
if (global.nextTick) {
realNextTick = global.nextTick;
} else if (global.process && global.process.nextTick) {
realNextTick = global.process.nextTick;
} else if (typeof Promise !== 'undefined' && Promise.resolve) {
resolved = Promise.resolve();
realNextTick = function nextTick(callback) {
resolved.then(callback);
// Ensure a nextTick implementation
if (!realNextTick) {
if (global.process && global.process.nextTick) {
realNextTick = global.process.nextTick;
} else if (typeof Promise !== 'undefined' && Promise.resolve) {
let resolved = Promise.resolve();
realNextTick = function nextTick(callback) {
resolved.then(callback);
};
} else if (typeof Image !== 'undefined') {
realNextTick = function nextTick(callback) {
var img = new Image;
img.onerror = callback;
img.src = 'data:image/png,' + Math.random();
};
} else {
realNextTick = function nextTick(callback) {
return setTimeout(callback, 0);
};
}
}
function canUsePostMessage() {
// The test against `importScripts` prevents this implementation from
// being installed inside a web worker, where `global.postMessage` means
// something completely different and can't be used for this purpose.
// Don't use on chrome either, because it's causes some GC issues
if (!Blast.isChrome && global.postMessage && !global.importScripts) {
var is_async = true,
old_onmessage = global.onmessage;
global.onmessage = function() {
is_async = false;
};
global.postMessage('', '*');
global.onmessage = old_onmessage;
return is_async;
}
};
// Ensure a setImmediate implementation
if (!realSetImmediate) {
let addSchedule;
realSetImmediate = function setImmediate(fnc) {
var handle,
args;
if (arguments.length > 1) {
let original_fnc = fnc,
i;
args = [];
for (i = 1; i < arguments.length; i++) {
args.push(arguments[i]);
}
fnc = function callFunction() {
original_fnc.apply(null, args);
};
}
handle = Blast.storeHandle('immediate', fnc);
addSchedule(handle);
return handle;
};
} else if (typeof Image !== 'undefined') {
realNextTick = function nextTick(callback) {
var img = new Image;
img.onerror = callback;
img.src = 'data:image/png,' + Math.random();
realClearImmediate = function clearImmediate(handle) {
return Blast.clearHandle('immediate', handle);
};
} else {
realNextTick = function nextTick(callback) {
return setTimeout(callback, 0);
};
if (global.MessageChannel) {
let channel = new global.MessageChannel();
channel.port1.onmessage = function immediateMC(e) {
Blast.runHandle('immediate', +e.data);
};
addSchedule = function addSchedule(handle) {
channel.port2.postMessage(handle);
};
} else if (canUsePostMessage()) {
let prefix = 'setImmediate$' + Math.random() + '$';
global.addEventListener('message', function immediatePM(e) {
if (e.source === global && typeof e.data == 'string' && e.data.indexOf(prefix) == 0) {
Blast.runHandle('immediate', +e.data.slice(prefix.length));
}
}, false);
addSchedule = function addSchedule(handle) {
global.postMessage(prefix + handle, '*');
};
} else {
addSchedule = function addSchedule(handle) {
setTimeout(function immediateST() {
Blast.runHandle('immediate', handle);
}, 0);
};
}
}
/**
* Clear a blast timeout
* Clear a blast handle
*
* @author Jelle De Loecker <jelle@develry.be>
* @since 0.2.1
* @version 0.2.1
* @since 0.6.3
* @version 0.6.3
*
* @param {String} type The type of handle
* @param {Number} id The id to clear
*/
Blast.clearTimeout = function clearTimeout(id) {
delete timeouts[id];
Blast.clearHandle = function clearHandle(type, id) {
if (!handles[type]) {
return false;
}
return handles[type].delete(id);
};
/**
* Store something and return a handle
*
* @author Jelle De Loecker <jelle@develry.be>
* @since 0.6.3
* @version 0.6.3
*
* @param {String} type The type of handle
* @param {Mixed} data The data to store
*
* @return {Number}
*/
Blast.storeHandle = function storeHandle(type, data) {
var id;
if (!handles[type]) {
handles[type] = new Map();
handles[type].count = 0;
}
id = handles[type].count++;
handles[type].set(id, data);
return id;
};
/**
* Run the given handle
*
* @author Jelle De Loecker <jelle@develry.be>
* @since 0.6.3
* @version 0.6.3
*
* @param {String} type The type of handle
* @param {Number} id The handle id
*
* @return {Number}
*/
Blast.runHandle = function runHandle(type, id) {
if (!handles[type]) {
return false;
}
let fnc = handles[type].get(id);
try {
fnc();
} finally {
handles[type].delete(id);
}
};
/**
* Perform task at the given timestamp

@@ -99,185 +221,2 @@ *

if (global.setImmediate) {
realSetImmediate = global.setImmediate.bind(global);
var clearImmediate = global.clearImmediate.bind(global);
} else {
var nextHandle = 1; // Spec says greater than zero
var tasksByHandle = {};
var currentlyRunningATask = false;
var doc = global.document;
var installReadyStateChangeImplementation,
installMessageChannelImplementation,
installPostMessageImplementation,
installSetTimeoutImplementation,
installNextTickImplementation,
addFromSetImmediateArguments,
canUsePostMessage,
partiallyApplied,
clearImmediate,
runIfPresent;
addFromSetImmediateArguments = function addFromSetImmediateArguments(args) {
tasksByHandle[nextHandle] = partiallyApplied.apply(undefined, args);
return nextHandle++;
};
// This function accepts the same arguments as setImmediate, but
// returns a function that requires no arguments.
partiallyApplied = function partiallyApplied(handler) {
var args,
i;
// Keep function optimized by not leaking the `arguments` object
args = new Array(arguments.length-1);
for (i = 0; i < args.length; i++) args[i] = arguments[i+1];
return function doHandler() {
if (typeof handler === "function") {
handler.apply(undefined, args);
} else {
(new Function("" + handler))();
}
};
};
runIfPresent = function runIfPresent(handle) {
// From the spec: "Wait until any invocations of this algorithm started before this one have completed."
// So if we're currently running a task, we'll need to delay this invocation.
if (currentlyRunningATask) {
// Delay by doing a setTimeout. setImmediate was tried instead, but in Firefox 7 it generated a
// "too much recursion" error.
setTimeout(partiallyApplied(runIfPresent, handle), 0);
} else {
var task = tasksByHandle[handle];
if (task) {
currentlyRunningATask = true;
try {
task();
} finally {
clearImmediate(handle);
currentlyRunningATask = false;
}
}
}
};
clearImmediate = function clearImmediate(handle) {
delete tasksByHandle[handle];
};
installNextTickImplementation = function installNextTickImplementation() {
realSetImmediate = function setImmediateNexttick() {
var handle = addFromSetImmediateArguments(arguments);
process.nextTick(partiallyApplied(runIfPresent, handle));
return handle;
};
};
canUsePostMessage = function canUsePostMessage() {
// The test against `importScripts` prevents this implementation from being installed inside a web worker,
// where `global.postMessage` means something completely different and can't be used for this purpose.
if (global.postMessage && !global.importScripts) {
var postMessageIsAsynchronous = true;
var oldOnMessage = global.onmessage;
global.onmessage = function() {
postMessageIsAsynchronous = false;
};
global.postMessage("", "*");
global.onmessage = oldOnMessage;
return postMessageIsAsynchronous;
}
};
installPostMessageImplementation = function installPostMessageImplementation() {
// Installs an event handler on `global` for the `message` event: see
// * https://developer.mozilla.org/en/DOM/window.postMessage
// * http://www.whatwg.org/specs/web-apps/current-work/multipage/comms.html#crossDocumentMessages
var messagePrefix = 'setImmediate$' + Math.random() + '$';
var onGlobalMessage = function(event) {
if (event.source === global &&
typeof event.data === "string" &&
event.data.indexOf(messagePrefix) === 0) {
runIfPresent(+event.data.slice(messagePrefix.length));
}
};
if (global.addEventListener) {
global.addEventListener("message", onGlobalMessage, false);
} else {
global.attachEvent("onmessage", onGlobalMessage);
}
realSetImmediate = function setImmediatePostmessage() {
var handle = addFromSetImmediateArguments(arguments);
global.postMessage(messagePrefix + handle, "*");
return handle;
};
};
installMessageChannelImplementation = function installMessageChannelImplementation() {
var channel = new MessageChannel();
channel.port1.onmessage = function onmessage(event) {
var handle = event.data;
runIfPresent(handle);
};
realSetImmediate = function setImmediateMessageChannel() {
var handle = addFromSetImmediateArguments(arguments);
channel.port2.postMessage(handle);
return handle;
};
}
installReadyStateChangeImplementation = function installReadyStateChangeImplementation() {
var html = doc.documentElement;
realSetImmediate = function setImmediateStatechange() {
var handle = addFromSetImmediateArguments(arguments);
// Create a <script> element; its readystatechange event will be fired asynchronously once it is inserted
// into the document. Do so, thus queuing up the task. Remember to clean up once it's been called.
var script = doc.createElement("script");
script.onreadystatechange = function onreadystatechange() {
runIfPresent(handle);
script.onreadystatechange = null;
html.removeChild(script);
script = null;
};
html.appendChild(script);
return handle;
};
};
installSetTimeoutImplementation = function installSetTimeoutImplementation() {
realSetImmediate = function setImmediateTimeout() {
var handle = addFromSetImmediateArguments(arguments);
setTimeout(partiallyApplied(runIfPresent, handle), 0);
return handle;
};
};
// Don't get fooled by e.g. browserify environments.
if ({}.toString.call(global.process) === "[object process]") {
// For Node.js before 0.9
installNextTickImplementation();
} else if (canUsePostMessage()) {
// For non-IE10 modern browsers
installPostMessageImplementation();
} else if (global.MessageChannel) {
// For web workers, where supported
installMessageChannelImplementation();
} else if (doc && "onreadystatechange" in doc.createElement("script")) {
// For IE 6–8
installReadyStateChangeImplementation();
} else {
// For older browsers
installSetTimeoutImplementation();
}
}
/**

@@ -288,3 +227,3 @@ * A nextTick that can set the context

* @since 0.5.1
* @version 0.5.1
* @version 0.6.3
*

@@ -296,14 +235,19 @@ * @param {Function} task

var args = [],
i;
if (arguments.length > 1) {
if (arguments.length > 2) {
let args = [],
i;
for (i = 2; i < arguments.length; i++) {
args.push(arguments[i]);
}
return realNextTick.call(global, function doTickTaskWithArgs() {
task.apply(context, args);
});
} else {
return realNextTick.call(global, function doTickTask() {
task();
});
}
return realNextTick.call(global, function doTask() {
task.apply(context, args);
});
};

@@ -343,3 +287,3 @@

Blast.defineGlobal('clearImmediate', clearImmediate);
Blast.defineGlobal('clearImmediate', realClearImmediate);

@@ -346,0 +290,0 @@ if (Blast.Globals.requestIdleCallback) {

@@ -576,13 +576,199 @@ module.exports = function BlastString(Blast, Collection, Bound, Obj) {

const NORMALIZE_TAG_REGEX = /<\/?([^\s\/>]+)/,
STATE_PLAINTEXT = Symbol('plaintext'),
STATE_HTML = Symbol('html'),
STATE_COMMENT = Symbol('comment');
Blast.REPLACE_BR_NEWLINE = Symbol('REPLACE_BR_NEWLINE');
/**
* Get the tag name
*
* @author Jelle De Loecker <jelle@develry.be>
* @since 0.6.3
* @version 0.6.3
*
* @param {String} tag_buffer
*
* @return {String} The lowercase tag name
*/
function getNormalizedTag(tag_buffer) {
var match = NORMALIZE_TAG_REGEX.exec(tag_buffer);
return match ? match[1].toLowerCase() : null;
}
/**
* Remove HTML tags from the string
*
* @author Jelle De Loecker <jelle@develry.be>
* @author Eric Norris
* @since 0.1.2
* @version 0.1.2
* @version 0.6.3
*
* @param {Array} allowed_tags
* @param {Symbol|String} tag_replacement
*
* @return {String} The string without any tags
*/
Blast.definePrototype('String', function stripTags() {
return String.prototype.replace.call(this, /(<([^>]+)>)/ig, '');
Blast.definePrototype('String', function stripTags(allowed_tags, tag_replacement) {
var in_quote_char = '',
tag_buffer = '',
allowed,
output = '',
length = this.length,
depth = 0,
state = STATE_PLAINTEXT,
char,
tag,
map,
i;
if (allowed_tags == null) {
allowed_tags = Blast.REPLACE_BR_NEWLINE;
}
if (allowed_tags) {
if (allowed_tags === Blast.REPLACE_BR_NEWLINE) {
allowed_tags = null;
map = new Map();
map.set('br', '\n');
} else {
let type = typeof allowed_tags;
if (type === 'object') {
if (Array.isArray(allowed_tags)) {
map = new Map();
for (i = 0; i < allowed_tags.length; i++) {
map.set(allowed_tags[i], true);
}
} else {
map = new Map(Object.entries(allowed_tags));
}
} else if (type === 'string') {
map = new Map();
map.set(allowed_tags, true);
}
}
}
tag_replacement = tag_replacement || '';
for (i = 0; i < length; i++) {
char = this[i];
if (state === STATE_PLAINTEXT) {
if (char == '<') {
state = STATE_HTML;
tag_buffer += char;
} else {
output += char;
}
continue;
}
if (state === STATE_COMMENT) {
if (char == '>') {
if (tag_buffer.slice(-2) == '--') {
// Close the comment
state = STATE_PLAINTEXT;
}
tag_buffer = '';
} else {
tag_buffer += char;
}
continue;
}
// Now we're in STATE_HTML
switch (char) {
case '<':
// Ignore '<' if inside a quote
if (in_quote_char) {
break;
}
// We're seeing a nested '<'
depth++;
break;
case '>':
// Ignore '>' if inside a quote
if (in_quote_char) {
break;
}
// Something like '<<>>' is happening
if (depth) {
depth--;
break;
}
// This is closing the tag in tag_buffer
in_quote_char = '';
state = STATE_PLAINTEXT;
tag_buffer += '>';
if (map) {
tag = getNormalizedTag(tag_buffer);
allowed = map.get(tag);
// If allowed is explicitly true, it's allowed
if (allowed === true) {
output += tag_buffer;
} else if (allowed) {
output += allowed;
} else {
output += tag_replacement;
}
} else {
output += tag_replacement;
}
tag_buffer = '';
break;
case '"':
case '\'':
// Catch single and double quotes
if (char === in_quote_char) {
in_quote_char = '';
} else {
in_quote_char = in_quote_char || char;
}
tag_buffer += char;
break;
case '-':
if (tag_buffer === '<!-') {
state = STATE_COMMENT;
}
tag_buffer += char;
break;
case ' ':
case '\n':
if (tag_buffer === '<') {
state = STATE_PLAINTEXT;
output += '< ';
tag_buffer = '';
break;
}
tag_buffer += char;
break;
default:
tag_buffer += char;
break;
}
}
return output;
});

@@ -589,0 +775,0 @@

{
"name": "protoblast",
"description": "Native object expansion library",
"version": "0.6.2",
"version": "0.6.3",
"author": "Jelle De Loecker <jelle@develry.be>",

@@ -15,3 +15,3 @@ "keywords": [

"dependencies": {
"json-dry" : "~1.0.8"
"json-dry" : "~1.0.9"
},

@@ -18,0 +18,0 @@ "repository": "skerit/protoblast",

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc