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

Commit

Permalink
Add post processors
Browse files Browse the repository at this point in the history
  • Loading branch information
jaredlockhart committed Aug 25, 2016
1 parent c3efd6c commit 9b6c2d4
Show file tree
Hide file tree
Showing 2 changed files with 44 additions and 7 deletions.
41 changes: 36 additions & 5 deletions parser.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,17 @@
const urlparse = require('url');
const {dom, rule, ruleset} = require('fathom-web');

function buildRuleset(name, rules) {
function makeUrlAbsolute(base, relative) {
const relativeParsed = urlparse.parse(relative);

if (relativeParsed.host === null) {
return urlparse.resolve(base, relative);
}

return relative;
}

function buildRuleset(name, rules, processors) {
const reversedRules = Array.from(rules).reverse();
const builtRuleset = ruleset(...reversedRules.map(([query, handler], order) => rule(
dom(query),
Expand All @@ -11,11 +22,19 @@ function buildRuleset(name, rules) {
}]
)));

return doc => {
return (doc, context) => {
const kb = builtRuleset.score(doc);
const maxNode = kb.max(name);

if (maxNode) {
const value = maxNode.flavors.get(name);
let value = maxNode.flavors.get(name);

if (processors) {
processors.forEach(processor => {
value = processor(value, context);
});
}

if (value) {
return value.trim();
}
Expand All @@ -41,6 +60,9 @@ const metadataRules = {
['link[rel="Shortcut Icon"]', node => node.element.getAttribute('href')],
['link[rel="mask-icon"]', node => node.element.getAttribute('href')],
],
processors: [
(icon_url, context) => makeUrlAbsolute(context.url, icon_url)
]
},

image_url: {
Expand All @@ -51,6 +73,9 @@ const metadataRules = {
['meta[property="twitter:image"]', node => node.element.getAttribute('content')],
['meta[name="thumbnail"]', node => node.element.getAttribute('content')],
],
processors: [
(image_url, context) => makeUrlAbsolute(context.url, image_url)
],
},

keywords: {
Expand Down Expand Up @@ -82,15 +107,21 @@ const metadataRules = {
},
};

function getMetadata(doc, rules) {
function getMetadata(doc, rules, url) {
const metadata = {};
const ruleSet = rules || metadataRules;

const context = {};

if (url) {
context.url = url;
}

Object.keys(ruleSet).map(metadataKey => {
const metadataRule = ruleSet[metadataKey];

if(Array.isArray(metadataRule.rules)) {
metadata[metadataKey] = buildRuleset(metadataKey, metadataRule.rules)(doc);
metadata[metadataKey] = buildRuleset(metadataKey, metadataRule.rules, metadataRule.processors)(doc, context);
} else {
metadata[metadataKey] = getMetadata(doc, metadataRule);
}
Expand Down
10 changes: 8 additions & 2 deletions tests/metadataRules.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,10 @@ function ruleTest(testName, testRule, expected, testTag) {
it(`finds ${testName}`, () => {
const html = buildHTML(testTag);
const doc = stringToDom(html);
const rule = buildRuleset(testName, testRule.rules);
const found = rule(doc);
const rule = buildRuleset(testName, testRule.rules, testRule.processors);
const found = rule(doc, {
url: 'http://www.example.com/'
});
assert.equal(found, expected, `Unable to find ${testName} in ${html}`);
});
}
Expand Down Expand Up @@ -52,6 +54,7 @@ describe('Canonical URL Rule Tests', function() {

describe('Icon Rule Tests', function() {
const pageIcon = 'http://www.example.com/favicon.ico';
const relativeIcon = '/favicon.ico';

const ruleTests = [
['apple-touch-icon', `<link rel="apple-touch-icon" href="${pageIcon}" />`],
Expand All @@ -61,6 +64,7 @@ describe('Icon Rule Tests', function() {
['shortcut icon', `<link rel="shortcut icon" href="${pageIcon}" />`],
['Shortcut Icon', `<link rel="Shortcut Icon" href="${pageIcon}" />`],
['mask-icon', `<link rel="mask-icon" href="${pageIcon}" />`],
['relative icon', `<link rel="icon" href="${relativeIcon}" />`],
];

ruleTests.map(([testName, testTag]) => ruleTest(testName, metadataRules.icon_url, pageIcon, testTag));
Expand All @@ -69,13 +73,15 @@ describe('Icon Rule Tests', function() {

describe('Image Rule Tests', function() {
const pageImage = 'http://www.example.com/image.png';
const relativeImage = '/image.png';

const ruleTests = [
['og:image', `<meta property="og:image" content="${pageImage}" />`],
['og:image:url', `<meta property="og:image:url" content="${pageImage}" /> `],
['og:image:secure_url', `<meta property="og:image:secure_url" content="${pageImage}" /> `],
['twitter:image', `<meta property="twitter:image" content="${pageImage}" />`],
['thumbnail', `<meta name="thumbnail" content="${pageImage}" />`],
['relative image', `<meta name="thumbnail" content="${relativeImage}" />`],
];

ruleTests.map(([testName, testTag]) => ruleTest(testName, metadataRules.image_url, pageImage, testTag));
Expand Down

0 comments on commit 9b6c2d4

Please sign in to comment.