yog-bigpipe
Advanced tools
Comparing version 0.1.0 to 0.2.0
@@ -26,3 +26,5 @@ var BigPipe = require('./lib/bigpipe.js'); | ||
// res.locals 肯定是一个对象,不信可以去查看 express/middleware/init | ||
res.locals.isQuickingMode = bigpipe.isQuickingMode(); | ||
res.locals.isQuicklingMode = bigpipe.isQuicklingMode(); | ||
// 拼写兼容 | ||
res.locals.isQuickingMode = res.locals.isQuicklingMode; | ||
@@ -29,0 +31,0 @@ res.on('finish', destroy); |
@@ -17,2 +17,3 @@ var Pagelet = require('./pagelet.js'); | ||
this.quicklings = []; | ||
this.parentQuicklings = []; | ||
@@ -65,14 +66,21 @@ this.on('pagelet:after', this._onPageletDone); | ||
BigPipe.prototype.addQuicklingPagelets = function (pagelets) { | ||
var arr = this.quicklings; | ||
arr && arr.push.apply(arr, pagelets); | ||
var me = this; | ||
pagelets.forEach(function (id) { | ||
var pageletIDSplit = id.split('@'); | ||
var pageletID = pageletIDSplit.shift() | ||
me.quicklings.push(pageletID); | ||
me.parentQuicklings.push.apply(me.parentQuicklings, pageletIDSplit); | ||
}); | ||
}; | ||
// 判断是否是 quickling 模式。 | ||
BigPipe.prototype.isQuickingMode = function () { | ||
BigPipe.prototype.isQuicklingMode = function () { | ||
return !!(this.quicklings && this.quicklings.length); | ||
}; | ||
// 拼写兼容 | ||
BigPipe.prototype.isQuickingMode = BigPipe.prototype.isQuicklingMode; | ||
// 添加 pagelet. | ||
BigPipe.prototype.addPagelet = function (obj) { | ||
// 已经晚了了,不处理。 | ||
@@ -87,25 +95,37 @@ if (this.state === status.fulfilled) { | ||
// todo 如果某个 quickling widget 里面再包含一个非 quickling 的 pagelet, 则不会渲染。 | ||
// 应该需要渲染才对。 | ||
// 注意: 如果 quickling 的 widget 藏在某些异步 widget 里面,岂不是找不到? | ||
if (!this.isQuickingMode() && obj.mode !== mode.pipeline && obj.mode !== mode.async) { | ||
if (!this.isQuicklingMode() && obj.mode !== mode.pipeline && obj.mode !== mode.async) { | ||
// 非 quickling 请求,只接收 pipeline 和 async 模式的 pagelet. | ||
return false; | ||
} | ||
else if (this.isQuickingMode()) { | ||
var parent = obj; | ||
else if (this.isQuicklingMode() && !~this.quicklings.indexOf(obj.id)) { | ||
// 以下几种情况均需要继续执行 | ||
// 1. 被声明为父Pagelet | ||
// 2. 先祖Pagelet被请求了 | ||
// 找到最近的一个 quickling 父亲节点。 | ||
while (parent && parent.parentId) { | ||
if (parent.mode === mode.quickling) { | ||
break; | ||
if (!~this.parentQuicklings.indexOf(obj.id)) { | ||
var parent, founded; | ||
// 如果没有被声明为父Pagelet,则检查是否属于先祖Pagelet被请求了的情况 | ||
// 如果是lazy模式,则不寻找先祖Pagelet | ||
if (obj.lazy) { | ||
return false; | ||
} | ||
parent = this.map[parent.parentId]; | ||
// 支持嵌套pagelet时,一次性返回所有pagelet | ||
parent = obj; | ||
founded = false; | ||
// 如果指定的pagelet不在quicklings列表中,检查先祖节点,查看先祖节点是否在列表中,如果在则加载 | ||
// 以此实现Pagelet A contain Pagelet B时,会用一个请求同时返回A与B | ||
while (parent && parent.parentId) { | ||
parent = this.map[parent.parentId]; | ||
if (parent.mode === mode.quickling && !!~this.quicklings.indexOf(parent.id)) { | ||
founded = true; | ||
// 插入为需要输出的Pagelet | ||
this.quicklings.push(obj.id); | ||
break; | ||
} | ||
} | ||
if (!founded) { | ||
return false; | ||
} | ||
} | ||
if (parent.mode !== mode.quickling || !~this.quicklings.indexOf(parent.id)) { | ||
return false; | ||
} | ||
} | ||
@@ -211,3 +231,5 @@ | ||
var content = this.format(pagelet); | ||
content && this.push(content); | ||
if (!this.isQuicklingMode() || !!~this.quicklings.indexOf(pagelet.id)) { | ||
content && this.push(content); | ||
} | ||
this._markPageletRendered(pagelet); | ||
@@ -218,3 +240,3 @@ }; | ||
var tpl = this.options.tpl; | ||
var type = this.isQuickingMode() ? 'quickling' : '_default'; | ||
var type = this.isQuicklingMode() ? 'quickling' : '_default'; | ||
var json = pagelet.toJson(); | ||
@@ -221,0 +243,0 @@ var obj = {}; |
{ | ||
"name": "yog-bigpipe", | ||
"version": "0.1.0", | ||
"version": "0.2.0", | ||
"description": "An express.js middleware for fis widget pipline output.", | ||
@@ -5,0 +5,0 @@ "main": "index.js", |
@@ -1,126 +0,289 @@ | ||
(function() { | ||
var Util = (function() { | ||
var d = document; | ||
var head = d.getElementsByTagName('head')[0]; | ||
(function (root) { | ||
// BigPipe 依赖的各种处理器 | ||
// 可以通过此部分换成 [lazyrender](https://github.com/rgrove/lazyload/), | ||
// 以达到更好的 js 并发下载性能。 | ||
// get broswer info | ||
var browser = (function() { | ||
var ua = navigator.userAgent.toLowerCase(); | ||
var match = /(webkit)[ \/]([\w.]+)/.exec(ua) || | ||
/(opera)(?:.*version)?[ \/]([\w.]+)/.exec(ua) || | ||
/(msie) ([\w.]+)/.exec(ua) || !/compatible/.test(ua) && /(mozilla)(?:.*? rv:([\w.]+))?/.exec(ua) || | ||
[]; | ||
return match[1]; | ||
})(); | ||
var d = document; | ||
var head = d.getElementsByTagName('head')[0]; | ||
var loadedRes = {}; | ||
var loadingRes = {}; | ||
var loadJs = function(url, cb) { | ||
var script = d.createElement('script'); | ||
var loaded = false; | ||
var wrap = function() { | ||
if (loaded) { | ||
// get broswer info | ||
var browser = (function () { | ||
var ua = navigator.userAgent.toLowerCase(); | ||
var match = /(webkit)[ \/]([\w.]+)/.exec(ua) || | ||
/(opera)(?:.*version)?[ \/]([\w.]+)/.exec(ua) || | ||
/(msie) ([\w.]+)/.exec(ua) || !/compatible/.test(ua) && /(mozilla)(?:.*? rv:([\w.]+))?/.exec(ua) || | ||
[]; | ||
return match[1]; | ||
})(); | ||
// load Js and excute it. | ||
// 加载 JS 并执行它。 | ||
function loadJs(url, ignoreDuplicate, cb) { | ||
if (ignoreDuplicate && loadedRes[url]) { | ||
cb && cb(); | ||
return; | ||
} | ||
if (ignoreDuplicate && loadingRes[url]) { | ||
loadingRes[url].push(cb); | ||
return; | ||
} | ||
loadingRes[url] = loadingRes[url] || []; | ||
var script = d.createElement('script'); | ||
var loaded = false; | ||
var wrap = function () { | ||
if (loaded) { | ||
return; | ||
} | ||
loaded = true; | ||
loadedRes[url] = true; | ||
if (ignoreDuplicate) { | ||
for (var i = 0; i < loadingRes[url].length; i++) { | ||
loadingRes[url][i] && loadingRes[url][i](); | ||
} | ||
loadingRes[url] = null; | ||
} | ||
cb && cb(); | ||
}; | ||
script.setAttribute('src', url); | ||
script.setAttribute('type', 'text/javascript'); | ||
script.onload = script.onerror = wrap; | ||
script.onreadystatechange = wrap; | ||
head.appendChild(script); | ||
} | ||
// load css and apply it. | ||
// 加载 css, 并应用该样式。 | ||
function loadCss(url, ignoreDuplicate, cb) { | ||
if (ignoreDuplicate && loadedRes[url]) { | ||
cb && cb(); | ||
return; | ||
} | ||
if (ignoreDuplicate && loadingRes[url]) { | ||
loadingRes[url].push(cb); | ||
return; | ||
} | ||
loadingRes[url] = loadingRes[url] || []; | ||
var link = d.createElement('link'); | ||
link.type = 'text/css'; | ||
link.rel = 'stylesheet'; | ||
link.href = url; | ||
if (browser === 'msie') { | ||
link.onreadystatechange = function () { | ||
/loaded|complete/.test(link.readyState) && cb(); | ||
} | ||
} | ||
else if (browser === 'opera') { | ||
link.onload = cb; | ||
} | ||
else { | ||
// FF, Safari, Chrome | ||
(function () { | ||
try { | ||
link.sheet.cssRule; | ||
} | ||
catch (e) { | ||
setTimeout(arguments.callee, 20); | ||
return; | ||
} | ||
loadedRes[url] = true; | ||
if (ignoreDuplicate) { | ||
for (var i = 0; i < loadingRes[url].length; i++) { | ||
loadingRes[url][i] && loadingRes[url][i](); | ||
} | ||
loadingRes[url] = null; | ||
} | ||
cb(); | ||
})(); | ||
} | ||
loaded = true; | ||
cb && cb(); | ||
}; | ||
head.appendChild(link); | ||
} | ||
script.setAttribute('src', url); | ||
script.setAttribute('type', 'text/javascript'); | ||
script.onload = wrap; | ||
script.onreadystatechange = wrap; | ||
head.appendChild(script); | ||
}; | ||
var loadCss = function(url, cb) { | ||
var link = d.createElement('link'); | ||
link.type = 'text/css'; | ||
link.rel = 'stylesheet'; | ||
link.href = url; | ||
// eval js code. | ||
// 直接执行 js 代码。 | ||
function globalEval(code) { | ||
var script; | ||
if (browser === 'msie') { | ||
link.onreadystatechange = function() { | ||
/loaded|complete/.test(link.readyState) && cb(); | ||
} | ||
} else if (browser == 'opera') { | ||
link.onload = cb; | ||
} else { | ||
//FF, Safari, Chrome | ||
(function() { | ||
try { | ||
link.sheet.cssRule; | ||
} catch (e) { | ||
setTimeout(arguments.callee, 20); | ||
return; | ||
}; | ||
cb(); | ||
})(); | ||
code = code.replace(/^\s+/, '').replace(/\s+$/, ''); | ||
if (code) { | ||
if (code.indexOf('use strict') === 1) { | ||
script = document.createElement('script'); | ||
script.text = code; | ||
head.appendChild(script).parentNode.removeChild(script); | ||
} | ||
else { | ||
eval(code); | ||
} | ||
} | ||
} | ||
head.appendChild(link); | ||
}; | ||
// append style cod to dom. | ||
// 直接应用样式代码到页面。 | ||
function appendStyle(code) { | ||
var dom = document.createElement('style'); | ||
dom.innerHTML = code; | ||
head.appendChild(dom); | ||
} | ||
var appendStyle = function(code) { | ||
var dom = document.createElement('style'); | ||
dom.innerHTML = code; | ||
head.appendChild(dom); | ||
// ajax 请求,简单实现,可以修改成使用 jQuery.ajax 如果已经依赖了的话。 | ||
function ajax(url, cb, data) { | ||
var xhr = new(window.XMLHttpRequest || ActiveXObject)('Microsoft.XMLHTTP'); | ||
xhr.onreadystatechange = function () { | ||
if (this.readyState == 4) { | ||
cb(this.responseText); | ||
} | ||
}; | ||
xhr.open(data ? 'POST' : 'GET', url + '&t=' + (new Date()).getTime(), true); | ||
var globalEval = function(code) { | ||
var script; | ||
if (data) { | ||
xhr.setRequestHeader('Content-type', 'application/x-www-form-urlencoded'); | ||
} | ||
xhr.setRequestHeader('X-Requested-With', 'XMLHttpRequest'); | ||
xhr.send(data); | ||
} | ||
code = code.replace(/^\s+/, '').replace(/\s+$/, ''); | ||
if (code) { | ||
if (code.indexOf('use strict') === 1) { | ||
script = document.createElement('script'); | ||
script.text = code; | ||
head.appendChild(script).parentNode.removeChild(script); | ||
} else { | ||
eval(code); | ||
// 可以换成 jQuery.extend | ||
function mixin(a, b) { | ||
if (a && b) { | ||
for (var k in b) { | ||
if (b.hasOwnProperty(k)) { | ||
a[k] = b[k]; | ||
} | ||
} | ||
}; | ||
} | ||
return a; | ||
} | ||
var ajax = function(url, cb, data) { | ||
var xhr = new (window.XMLHttpRequest || ActiveXObject)('Microsoft.XMLHTTP'); | ||
var Util = { | ||
loadJs: loadJs, | ||
loadCss: loadCss, | ||
appendStyle: appendStyle, | ||
globalEval: globalEval, | ||
ajax: ajax, | ||
mixin: mixin | ||
}; | ||
xhr.onreadystatechange = function() { | ||
if (this.readyState == 4) { | ||
cb(this.responseText); | ||
} | ||
// expose it. | ||
root.BigPipeUtil = Util; | ||
})(this); | ||
(function (root) { | ||
// Event | ||
var Util = root.BigPipeUtil, | ||
slice = [].slice, | ||
protos; | ||
protos = { | ||
on: function (name, callback) { | ||
var me = this, | ||
set, handler; | ||
set = this._events || (this._events = []); | ||
set.push({ | ||
e: name, | ||
cb: callback, | ||
id: set.length, | ||
ctx: this | ||
}); | ||
return this; | ||
}, | ||
once: function (name, callback) { | ||
var me = this, | ||
once; | ||
once = function () { | ||
me.off(name, once); | ||
return callback.apply(me, arguments); | ||
}; | ||
xhr.open(data?'POST':'GET', url + '&t=' + ~~(Math.random() * 1e6), true); | ||
if (data) { | ||
xhr.setRequestHeader('Content-type', 'application/x-www-form-urlencoded'); | ||
once._cb = callback; | ||
return me.on(name, once); | ||
}, | ||
off: function (name, cb) { | ||
var events = this._events; | ||
if (!name && !cb) { | ||
this._events = []; | ||
return this; | ||
} | ||
xhr.setRequestHeader('X-Requested-With', 'XMLHttpRequest'); | ||
xhr.send(data); | ||
}; | ||
var mixin = function(a, b) { | ||
if (a && b) { | ||
for (var k in b) { | ||
if (b.hasOwnProperty(k)) { | ||
a[k] = b[k]; | ||
} | ||
} | ||
each(findHandlers(events, name, cb), function (item) { | ||
delete events[item.id]; | ||
}); | ||
return this; | ||
}, | ||
trigger: function (type) { | ||
var args, events, allEvents; | ||
if (!this._events || !type) { | ||
return this; | ||
} | ||
return a; | ||
}; | ||
return { | ||
loadCss: loadCss, | ||
loadJs: loadJs, | ||
appendStyle: appendStyle, | ||
globalEval: globalEval, | ||
ajax: ajax, | ||
mixin: mixin | ||
}; | ||
})(); | ||
args = slice.call(arguments, 1); | ||
events = findHandlers(this._events, type); | ||
return triggerHanders(events, args); | ||
} | ||
}; | ||
// 根据条件过滤出事件handlers. | ||
function findHandlers(arr, name, callback) { | ||
var ret = []; | ||
var BigPipe = function() { | ||
each(arr, function (handler) { | ||
if (handler && | ||
(!name || handler.e === name) && | ||
(!callback || handler.cb === callback || handler.cb._cb === callback)) { | ||
ret.push(handler); | ||
} | ||
}); | ||
return ret; | ||
} | ||
function each(arr, iterator) { | ||
for (var i = 0, len = arr.length, item; i < len; i++) { | ||
item = arr[i]; | ||
iterator.call(item, item, i); | ||
} | ||
} | ||
function triggerHanders(events, args) { | ||
var i = -1, | ||
len = events.length, | ||
handler; | ||
while (++i < len) { | ||
handler = events[i]; | ||
if (handler.cb.apply(handler.ctx, args) === false) { | ||
break; | ||
} | ||
} | ||
} | ||
root.BigPipeEvent = Util.mixin({ | ||
mixto: function (obj) { | ||
return Util.mixin(obj, protos); | ||
} | ||
}, protos); | ||
})(this); | ||
(function (root) { | ||
var Util = root.BigPipeUtil; | ||
var Event = root.BigPipeEvent; | ||
var BigPipe = function () { | ||
// The order of render pagelet. | ||
@@ -146,3 +309,3 @@ // - load css | ||
var loadCss = function() { | ||
var loadCss = function () { | ||
// load css | ||
@@ -152,17 +315,18 @@ if (data.css && data.css.length) { | ||
for (var i = 0, len = remaining; i < len; i++) { | ||
Util.loadCss(data.css[i], function() { | ||
Util.loadCss(data.css[i], BigPipe.ignoreDuplicate, function () { | ||
--remaining || insertDom(); | ||
}); | ||
} | ||
} else { | ||
} | ||
else { | ||
insertDom(); | ||
} | ||
} | ||
}; | ||
var insertDom = function() { | ||
var i, len, dom, node, text, scriptText; | ||
var insertDom = function () { | ||
var i, len, dom, node, text, scriptText, temp; | ||
// insert style code | ||
if(data.styles && data.styles.length) { | ||
for(i = 0, len = data.styles.length; i < len; i++) { | ||
if (data.styles && data.styles.length) { | ||
for (i = 0, len = data.styles.length; i < len; i++) { | ||
Util.appendStyle(data.styles[i]); | ||
@@ -173,21 +337,32 @@ } | ||
dom = data.container && typeof data.container === 'string' ? | ||
document.getElementById(data.container) : | ||
(data.container || document.getElementById(data.id)); | ||
document.getElementById(data.container) : | ||
(data.container || document.getElementById(data.id)); | ||
dom.innerHTML = data.html; | ||
if (data.extend) { | ||
temp = document.createElement('div'); | ||
temp.innerHTML = data.html; | ||
while (temp.firstChild) { | ||
dom.appendChild(temp.firstChild); | ||
} | ||
} | ||
else { | ||
dom.innerHTML = data.html; | ||
} | ||
setTimeout(function () { | ||
onDomInserted(data); | ||
}, 0); | ||
}; | ||
onDomInserted(); | ||
} | ||
var loadJs = function() { | ||
var loadJs = function (callback) { | ||
var len = data.js && data.js.length; | ||
var remaining = len, i; | ||
var remaining = len, | ||
i; | ||
// exec data.scripts | ||
var next = function() { | ||
var next = function () { | ||
var i, len; | ||
// eval scripts. | ||
if(data.scripts && data.scripts.length) { | ||
for(i = 0, len = data.scripts.length; i < len; i++) { | ||
if (data.scripts && data.scripts.length) { | ||
for (i = 0, len = data.scripts.length; i < len; i++) { | ||
Util.globalEval(data.scripts[i]); | ||
@@ -197,3 +372,3 @@ } | ||
data.done && data.done(data.id); | ||
callback && callback(data); | ||
}; | ||
@@ -208,7 +383,7 @@ | ||
for (i = 0; i < len; i++) { | ||
Util.loadJs(data.js[i], next && function() { | ||
Util.loadJs(data.js[i], BigPipe.ignoreDuplicate, next && function () { | ||
--remaining || next(); | ||
}); | ||
} | ||
} | ||
}; | ||
@@ -221,6 +396,9 @@ return { | ||
var d = document, | ||
config = {}, | ||
count = 0, | ||
pagelets = []; /* registered pagelets */ | ||
var count = 0, | ||
pagelets = [], | ||
/* registered pagelets */ | ||
currentPagelet = null, | ||
currReqID = null, | ||
cache = {}, | ||
globalBigPipeLoadIndex = 0; | ||
@@ -233,15 +411,24 @@ return { | ||
// - after async load quickling pagelet. | ||
onPageletArrive: function(obj) { | ||
config[obj.id] && (obj = Util.mixin(obj, config[obj.id])); | ||
onPageletArrive: function (obj) { | ||
currReqID = obj.reqID; | ||
// console.log('arrive', obj.id); | ||
this.trigger('pageletarrive', obj); | ||
var pagelet = PageLet(obj, function() { | ||
var pagelet = PageLet(obj, function () { | ||
// console.log('dom ready', obj.id); | ||
var item; | ||
count--; | ||
// enforce js executed after dom inserted. | ||
if (!--count) { | ||
if (count === 0) { | ||
while ((item = pagelets.shift())) { | ||
item.loadJs(); | ||
BigPipe.trigger('pageletinsert', pagelet, item.pageletData); | ||
// console.log('pagelet exec js', item.pageletData.id); | ||
item.loadJs(function () { | ||
// console.log('pagelet exec done', item.pageletData.id); | ||
BigPipe.trigger('pageletdone', pagelet, item.pageletData); | ||
}); | ||
} | ||
} | ||
}); | ||
pagelet.pageletData = obj; | ||
pagelets.push(pagelet); | ||
@@ -276,7 +463,10 @@ count++; | ||
// specified document node. | ||
// - cb done callback. | ||
load: function(pagelets) { | ||
// - extend | ||
load: function (pagelets) { | ||
var args = []; | ||
var currentPageUrl = location.href; | ||
var obj, i, id, cb, remaining, search, url, param; | ||
var containers = {}; | ||
var pageletRequestID = globalBigPipeLoadIndex++; | ||
var obj, i, id, cb, remaining = 0, | ||
search, url, param, container; | ||
@@ -293,8 +483,9 @@ // convert arguments. | ||
pagelets: pagelets | ||
} | ||
} else { | ||
}; | ||
} | ||
else { | ||
obj = typeof pagelets === 'string' ? { | ||
pagelets: pagelets | ||
}: pagelets; | ||
pagelets = obj.pagelets; | ||
} : pagelets; | ||
pagelets = obj.pagelet || obj.pagelets; | ||
typeof pagelets === 'string' && | ||
@@ -304,32 +495,66 @@ (pagelets = pagelets.split(/\s*,\s*/)); | ||
remaining = pagelets.length; | ||
cb = obj.cb && function(pageletId) { | ||
delete config[pageletId]; | ||
--remaining || obj.cb(); | ||
}; | ||
for(i = remaining - 1; i >= 0; i--) { | ||
for (i = pagelets.length - 1; i >= 0; i--) { | ||
id = pagelets[i]; | ||
args.push('pagelets[]=' + id); | ||
config[id] = { | ||
container: obj.container && obj.container[id] || | ||
obj.container, | ||
done: cb | ||
container = obj.container && obj.container[id] || obj.container; | ||
containers[id] = container; | ||
} | ||
args.push('reqID=' + pageletRequestID); | ||
function onPageArrive(data) { | ||
// !data.reqID 用于兼容老版本未返回reqID的情况 | ||
if (data.reqID === undefined || data.reqID === pageletRequestID) { | ||
var id = data.id; | ||
// console.log('req', data.reqID, 'pagelet', data.id, 'arrive'); | ||
remaining++; | ||
containers[id] && (data.container = containers[id]); | ||
data.extend = obj.extend; | ||
} | ||
} | ||
param = obj.param ? '&' + obj.param : ''; | ||
search = location.search; | ||
search = search ? (search + '&') : '?'; | ||
url = search + args.join('&') + param; | ||
BigPipe.on('pageletarrive', onPageArrive); | ||
obj.search && args.push(obj.search); | ||
if (obj.url) { | ||
url = obj.url + (obj.url.indexOf('?') === -1 ? '?' : '&') + args.join('&'); | ||
} | ||
else { | ||
url = (location.search ? location.search + '&' : '?') + args.join('&'); | ||
} | ||
BigPipe.on('pageletdone', function (pagelet, res) { | ||
// !res.reqID 用于兼容老版本未返回reqID的情况 | ||
if (res.reqID === undefined || res.reqID === pageletRequestID) { | ||
remaining--; | ||
// console.log('req', res.reqID, 'pagelet', res.id, 'done'); | ||
if (remaining === 0) { | ||
// console.log('req', res.reqID, 'done'); | ||
BigPipe.off('pageletdone', arguments.callee); | ||
BigPipe.off('pageletarrive', onPageArrive); | ||
obj.cb && obj.cb(); | ||
} | ||
} | ||
}); | ||
Util.ajax(url, function(res) { | ||
// console.log('req', pageletRequestID, url, 'start'); | ||
// if the page url has been moved. | ||
if(currentPageUrl !== location.href) { | ||
return; | ||
} | ||
Util.globalEval(res); | ||
}); | ||
if (cache[obj.cacheID]) { | ||
var requestCache = cache[obj.cacheID]; | ||
// 同步requestID | ||
pageletRequestID = requestCache.reqID; | ||
Util.globalEval(requestCache.content); | ||
} | ||
else { | ||
Util.ajax(url, function (res) { | ||
// if the page url has been moved. | ||
if (currentPageUrl !== location.href) { | ||
return; | ||
} | ||
Util.globalEval(res); | ||
if (obj.cacheID) { | ||
cache[obj.cacheID] = { | ||
content: res, | ||
reqID: currReqID | ||
}; | ||
} | ||
}); | ||
} | ||
} | ||
@@ -339,3 +564,5 @@ }; | ||
Event.mixto(BigPipe); | ||
BigPipe.ignoreDuplicate = true; | ||
window.BigPipe = BigPipe; | ||
})(); | ||
})(this); |
New author
Supply chain riskA new npm collaborator published a version of the package for the first time. New collaborators are usually benign additions to a project, but do indicate a change to the security surface area of a package.
Found 1 instance in 1 package
37362
969
0