Skip to content
This repository has been archived by the owner on Feb 15, 2024. It is now read-only.

Commit

Permalink
migrated to cheerio
Browse files Browse the repository at this point in the history
  • Loading branch information
Öner Zafer committed Jun 29, 2019
1 parent a9a3757 commit 4ef5c7a
Show file tree
Hide file tree
Showing 16 changed files with 182 additions and 211 deletions.
26 changes: 10 additions & 16 deletions lib/extend.js
Original file line number Diff line number Diff line change
@@ -1,28 +1,22 @@
const utils = require('./utils');

module.exports = (dom, extendingAppManifest) => {
const doc = dom.window.document;
const _$ = doc.querySelector.bind(doc);
const _$$ = doc.querySelectorAll.bind(doc);
utils.injectBundleIntoDom(dom, extendingAppManifest.bundle);
_$('[export]').setAttribute('export', extendingAppManifest.appName);
Array.from(_$$('[resource]')).forEach(e =>
e.setAttribute('resource', 'resource')
);
Array.from(_$$('script:not([resource]),style:not([resource]),link:not([resource])')).forEach(e =>
e.parentElement.removeChild(e)
);
module.exports = ($, extendingAppManifest) => {
utils.injectBundleIntoDom($, extendingAppManifest.bundle);
$('[export]').attr('export', extendingAppManifest.appName);

$('script:not([resource]),style:not([resource]),link:not([resource])').remove();

if (extendingAppManifest.overrides && extendingAppManifest.overrides.length) {
extendingAppManifest.overrides.forEach(override => {
const elem = _$(`${override.tag}[public="${override.target}"]`);
const selector = `${override.tag}[public="${override.target}"]`;
const $elem = $(selector);
let content = override.content;
const superTagPattern = /(<super\s*\/>)|(<super>.*<\/\s*super>)/g;
if (superTagPattern.test(content)) {
content = content.replace(superTagPattern, elem.innerHTML);
content = content.replace(superTagPattern, $elem.html());
}
const tagName = override.target && override.target !== '' ? override.target : override.tag;
utils.replaceElement(dom, elem, tagName, content);
utils.replaceElement($, selector, tagName, content);
});
}
return dom;
};
26 changes: 10 additions & 16 deletions lib/import.js
Original file line number Diff line number Diff line change
@@ -1,27 +1,21 @@
const utils = require('./utils');

module.exports = (dom, importedApps = {}) => {
module.exports = ($, importedApps = {}) => {
const injected = [];
const doc = dom.window.document;
const _$$ = doc.querySelectorAll.bind(doc);
Array.from(_$$('head [import]')).forEach(elem =>
elem.parentNode.removeChild(elem)
);
Array.from(_$$('fragment')).forEach(elem => {
const appName = utils.getAttr(elem, 'name');

$('head [import]').remove();

$('fragment').each((index, elem) => {
const appName = $(elem).attr('name');
if (importedApps[appName] && importedApps[appName].content) {
// inject content
utils.replaceElement(dom, elem, appName, importedApps[appName].content);
if (injected.indexOf(appName) === -1) {
utils.injectBundleIntoDom(dom, importedApps[appName].bundle);
utils.replaceElement($, elem, appName, importedApps[appName].content);
if (!injected.includes(appName)) {
utils.injectBundleIntoDom($, importedApps[appName].bundle);
injected.push(appName);
}
} else {
elem.parentNode.removeChild(elem);
$(elem).remove(elem);
}
});
Array.from(_$$('[resource]')).forEach(e =>
e.setAttribute('resource', 'resource')
);
return dom;
};
52 changes: 27 additions & 25 deletions lib/manifest.js
Original file line number Diff line number Diff line change
@@ -1,38 +1,40 @@
const utils = require('./utils');
const JSDOM = require('JSDOM').JSDOM;

module.exports = html => {
if (!html || typeof html !== 'string') {
return;
}
const dom = utils.parse(html);
const _$ = dom.window.document.querySelector.bind(dom.window.document);
const _$$ = dom.window.document.querySelectorAll.bind(dom.window.document);
const manifest = utils.cleanObject({
appName: utils.getAttr(_$('head meta[export]'), 'export'),
baseUrl: utils.getAttr(_$('head meta[public-url]'), 'public-url'),
extending: utils.getAttr(_$('head meta[export]'), 'extends') || undefined,
alias: utils.getAttr(_$('head meta[export-as]'), 'export-as') || undefined,
type: utils.getAttr(_$('head meta[of-type]'), 'of-type') || 'page',
uses: Array.from(_$$('head meta[import]')).map(elem =>
utils.getAttr(elem, 'import')
),
bundle: Array.from(_$$('[resource]')).map(elem =>
utils.cleanObject(utils.toBundleItem(elem))
),
overrides: Array.from(_$$('[override]')).map(elem =>
utils.cleanObject(utils.toOverrideItem(elem))
),
publics: Array.from(_$$('[public]')).map(
elem => utils.getAttr(elem, 'public') || elem.tagName
),
content: utils.toContent(new JSDOM(dom.serialize())) || '',
const $ = utils.parse(html);

const manifest = {
appName: $('head meta[export]').attr('export'),
baseUrl: $('head meta[public-url]').attr('public-url'),
extending: $('head meta[extends]').attr('extends'),
alias: $('head meta[export-as]').attr('export-as'),
type: $('head meta[of-type]').attr('of-type') || 'page',
uses: [],
bundle: [],
overrides: [],
publics: [],
content: utils.toContent(utils.parse(utils.serialize($))) || '',
raw: utils.minify(html),
});
};

$('meta[import]').each((index, elem) => {
manifest.uses.push($(elem).attr('import'))});
$('[resource]').each((index, elem) =>
manifest.bundle.push(utils.toBundleItem($, elem))
);
$('[override]').each((index, elem) =>
manifest.overrides.push(utils.toOverrideItem($, elem))
);
$('[public]').each((index, elem) =>
manifest.publics.push($(elem).attr('public') || elem.name)
);

if (!manifest.appName) {
throw new Error('<meta export> is not available');
}

return manifest;
return utils.cleanObject(manifest);
};
26 changes: 17 additions & 9 deletions lib/mfhtml.js
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ class MFHTML {
const manifest = generateManifest(html);
this.graph[manifest.appName] = manifest;
} catch (e) {
throw new Error('Not able to generate manifest for given html');
throw new Error(e);
}
} else {
throw new Error('mfhml.register requires an html');
Expand All @@ -39,26 +39,30 @@ class MFHTML {
/**
* Searches and retrieves the app by name and returns the generated html
* @param {string} appName
* @param {null | string} baseUrl
* @param scriptToInject
*/
get(appName, baseUrl = null) {
get(appName, scriptToInject) {
const foundAppManifest = this.getManifest(appName);
const appBaseUrl = baseUrl || foundAppManifest.baseUrl;
let appDom = UrlFix(utils.parse(foundAppManifest.raw), appBaseUrl);
const appBaseUrl = foundAppManifest.baseUrl || '';
let appDom = utils.parse(foundAppManifest.raw);
UrlFix(appDom, appBaseUrl);
if (foundAppManifest.extending) {
if (this.getAppNames().includes(foundAppManifest.extending)) {
const superDom = utils.parse(this.get(foundAppManifest.extending));
foundAppManifest.bundle = foundAppManifest.bundle.map(bundle => ({
...bundle,
path: bundle.path ? utils.combineUrl(appBaseUrl, bundle.path) : bundle.path,
path: bundle.path
? utils.combineUrl(appBaseUrl, bundle.path)
: bundle.path,
}));
appDom = Extend(superDom, foundAppManifest);
Extend(superDom, foundAppManifest);
appDom = superDom;
} else {
throw new Error(`undefined super '${foundAppManifest.extending}'`);
}
}
if (foundAppManifest.uses && foundAppManifest.uses.length) {
appDom = Import(
Import(
appDom,
foundAppManifest.uses.reduce((importedAppManifest, importedAppName) => {
if (this.getAppNames().includes(importedAppName)) {
Expand All @@ -72,7 +76,11 @@ class MFHTML {
}, {})
);
}
return utils.serialize(utils.cleanPrivates(appDom));
utils.cleanPrivates(appDom);
if (scriptToInject) {
utils.injectScript(appDom, scriptToInject);
}
return utils.serialize(appDom);
}

/**
Expand Down
11 changes: 5 additions & 6 deletions lib/url-fixer.js
Original file line number Diff line number Diff line change
Expand Up @@ -37,19 +37,18 @@ const ElementsWithUrlSelectors = {
*/

// will ignore inline styles
module.exports = (dom, baseUri) => {
module.exports = ($, baseUri) => {
if (baseUri) {
_$$ = dom.window.document.querySelectorAll.bind(dom.window.document);
Object.keys(ElementsWithUrlSelectors).forEach(attr => {
const tags = ElementsWithUrlSelectors[attr];
const selector = tags.map(tag => `${tag}[${attr}]`).join(', ');
Array.from(_$$(selector)).forEach(elem => {
const attrValue = elem.getAttribute(attr);
$(selector).each((index, elem) => {
const $elem = $(elem);
const attrValue = $elem.attr(attr);
if (attrValue && /https?:\/\//g.test(attrValue) !== true) {
elem.setAttribute(attr, utils.combineUrl(baseUri, attrValue));
$elem.attr(attr, utils.combineUrl(baseUri, attrValue));
}
});
});
}
return dom;
};
Loading

0 comments on commit 4ef5c7a

Please sign in to comment.