import through from 'through';
import tokenize from 'html-tokenize';
import pipe from 'multipipe';
var createExtractCritical = function createExtractCritical(cache) {
return function (html) {
// parse out ids from html
// reconstruct css/rules/cache to pass
var RGX = new RegExp(cache.key + "-([a-zA-Z0-9-_]+)", 'gm');
var o = {
html: html,
ids: [],
css: ''
};
var match;
var ids = {};
while ((match = RGX.exec(html)) !== null) {
// $FlowFixMe
if (ids[match[1]] === undefined) {
// $FlowFixMe
ids[match[1]] = true;
}
}
o.ids = Object.keys(cache.inserted).filter(function (id) {
if ((ids[id] !== undefined || cache.registered[cache.key + "-" + id] === undefined) && cache.inserted[id] !== true) {
o.css += cache.inserted[id];
return true;
}
});
return o;
};
};
var createExtractCriticalToChunks = function createExtractCriticalToChunks(cache) {
return function (html) {
// parse out ids from html
// reconstruct css/rules/cache to pass
var RGX = new RegExp(cache.key + "-([a-zA-Z0-9-_]+)", 'gm');
var o = {
html: html,
styles: []
};
var match;
var ids = {};
while ((match = RGX.exec(html)) !== null) {
// $FlowFixMe
if (ids[match[1]] === undefined) {
// $FlowFixMe
ids[match[1]] = true;
}
}
var regularCssIds = [];
var regularCss = '';
Object.keys(cache.inserted).forEach(function (id) {
if ((ids[id] !== undefined || cache.registered[cache.key + "-" + id] === undefined) && cache.inserted[id] !== true) {
if (cache.registered[cache.key + "-" + id]) {
// regular css can be added in one style tag
regularCssIds.push(id); // $FlowFixMe
regularCss += cache.inserted[id];
} else {
// each global styles require a new entry so it can be independently flushed
o.styles.push({
key: cache.key + "-global",
ids: [id],
css: cache.inserted[id]
});
}
}
}); // make sure that regular css is added after the global styles
o.styles.push({
key: cache.key,
ids: regularCssIds,
css: regularCss
});
return o;
};
};
function generateStyleTag(cssKey, ids, styles, nonceString) {
return "";
}
var createRenderStylesToString = function createRenderStylesToString(cache, nonceString) {
return function (html) {
var inserted = cache.inserted,
cssKey = cache.key,
registered = cache.registered;
var regex = new RegExp("<|" + cssKey + "-([a-zA-Z0-9-_]+)", 'gm');
var seen = {};
var result = '';
var globalIds = '';
var globalStyles = '';
for (var id in inserted) {
// eslint-disable-next-line no-prototype-builtins
if (inserted.hasOwnProperty(id)) {
var style = inserted[id];
var key = cssKey + "-" + id;
if (style !== true && registered[key] === undefined) {
globalStyles += style;
globalIds += " " + id;
}
}
}
if (globalStyles !== '') {
result = generateStyleTag(cssKey, globalIds.substring(1), globalStyles, nonceString);
}
var ids = '';
var styles = '';
var lastInsertionPoint = 0;
var match;
while ((match = regex.exec(html)) !== null) {
// $FlowFixMe
if (match[0] === '<') {
if (ids !== '') {
result += generateStyleTag(cssKey, ids.substring(1), styles, nonceString);
ids = '';
styles = '';
} // $FlowFixMe
result += html.substring(lastInsertionPoint, match.index); // $FlowFixMe
lastInsertionPoint = match.index;
continue;
} // $FlowFixMe
var _id = match[1];
var _style = inserted[_id];
if (_style === true || _style === undefined || seen[_id]) {
continue;
}
seen[_id] = true;
styles += _style;
ids += " " + _id;
}
result += html.substring(lastInsertionPoint);
return result;
};
};
var createRenderStylesToNodeStream = function createRenderStylesToNodeStream(cache, nonceString) {
return function () {
var insed = {};
var tokenStream = tokenize();
var inlineStream = through(function write(thing) {
var type = thing[0],
data = thing[1];
if (type === 'open') {
var css = '';
var ids = {};
var match;
var fragment = data.toString();
var regex = new RegExp(cache.key + "-([a-zA-Z0-9-_]+)", 'gm');
while ((match = regex.exec(fragment)) !== null) {
if (match !== null && insed[match[1]] === undefined) {
ids[match[1]] = true;
}
}
Object.keys(cache.inserted).forEach(function (id) {
if (cache.inserted[id] !== true && insed[id] === undefined && (ids[id] === true || cache.registered[cache.key + "-" + id] === undefined && (ids[id] = true))) {
insed[id] = true; // $FlowFixMe flow thinks emotion.caches.inserted[id] can be true even though it's checked earlier
css += cache.inserted[id];
}
});
if (css !== '') {
this.queue("");
}
}
this.queue(data);
}, function end() {
this.queue(null);
});
return pipe(tokenStream, inlineStream);
};
};
var createConstructStyleTagsFromChunks = function createConstructStyleTagsFromChunks(cache, nonceString) {
return function (criticalData) {
var styleTagsString = '';
criticalData.styles.forEach(function (item) {
styleTagsString += generateStyleTag(item.key, item.ids.join(' '), item.css, nonceString);
});
return styleTagsString;
};
};
function createEmotionServer (cache) {
if (cache.compat !== true) {
// is this good? should we do this automatically?
// this is only for when using the new apis (not emotion or create-emotion)
cache.compat = true;
}
var nonceString = cache.nonce !== undefined ? " nonce=\"" + cache.nonce + "\"" : '';
return {
extractCritical: createExtractCritical(cache),
extractCriticalToChunks: createExtractCriticalToChunks(cache),
renderStylesToString: createRenderStylesToString(cache, nonceString),
renderStylesToNodeStream: createRenderStylesToNodeStream(cache, nonceString),
constructStyleTagsFromChunks: createConstructStyleTagsFromChunks(cache, nonceString)
};
}
export { createEmotionServer as default };