build(aio): capture the h1 title and attach it to the document
The HTML post-processing now collects any h1 that is found in the renderedContent and attaches it to the doc via the `doc.vFile.title` property.
This commit is contained in:
parent
2f35392cd8
commit
4d5fa5c855
|
@ -107,6 +107,7 @@
|
||||||
"ts-node": "~2.0.0",
|
"ts-node": "~2.0.0",
|
||||||
"tslint": "~4.5.0",
|
"tslint": "~4.5.0",
|
||||||
"typescript": "2.2.0",
|
"typescript": "2.2.0",
|
||||||
|
"unist-util-filter": "^0.2.1",
|
||||||
"unist-util-source": "^1.0.1",
|
"unist-util-source": "^1.0.1",
|
||||||
"unist-util-visit": "^1.1.1",
|
"unist-util-visit": "^1.1.1",
|
||||||
"vrsource-tslint-rules": "^4.0.1",
|
"vrsource-tslint-rules": "^4.0.1",
|
||||||
|
|
|
@ -32,7 +32,7 @@ describe('addImageDimensions post-processor', () => {
|
||||||
processor.$process(docs);
|
processor.$process(docs);
|
||||||
expect(getImageDimensionsSpy).toHaveBeenCalledWith('base/path', 'a/b.jpg');
|
expect(getImageDimensionsSpy).toHaveBeenCalledWith('base/path', 'a/b.jpg');
|
||||||
expect(getImageDimensionsSpy).toHaveBeenCalledWith('base/path', 'c/d.png');
|
expect(getImageDimensionsSpy).toHaveBeenCalledWith('base/path', 'c/d.png');
|
||||||
expect(docs).toEqual([{
|
expect(docs).toEqual([jasmine.objectContaining({
|
||||||
docType: 'a',
|
docType: 'a',
|
||||||
renderedContent: `
|
renderedContent: `
|
||||||
<p>xxx</p>
|
<p>xxx</p>
|
||||||
|
@ -41,7 +41,7 @@ describe('addImageDimensions post-processor', () => {
|
||||||
<img src="c/d.png" width="30" height="40">
|
<img src="c/d.png" width="30" height="40">
|
||||||
<p>zzz</p>
|
<p>zzz</p>
|
||||||
`
|
`
|
||||||
}]);
|
})]);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should log a warning for images with no src attribute', () => {
|
it('should log a warning for images with no src attribute', () => {
|
||||||
|
@ -51,10 +51,10 @@ describe('addImageDimensions post-processor', () => {
|
||||||
}];
|
}];
|
||||||
processor.$process(docs);
|
processor.$process(docs);
|
||||||
expect(getImageDimensionsSpy).not.toHaveBeenCalled();
|
expect(getImageDimensionsSpy).not.toHaveBeenCalled();
|
||||||
expect(docs).toEqual([{
|
expect(docs).toEqual([jasmine.objectContaining({
|
||||||
docType: 'a',
|
docType: 'a',
|
||||||
renderedContent: '<img attr="value">'
|
renderedContent: '<img attr="value">'
|
||||||
}]);
|
})]);
|
||||||
expect(log.warn).toHaveBeenCalled();
|
expect(log.warn).toHaveBeenCalled();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -70,10 +70,10 @@ describe('addImageDimensions post-processor', () => {
|
||||||
}];
|
}];
|
||||||
processor.$process(docs);
|
processor.$process(docs);
|
||||||
expect(getImageDimensionsSpy).toHaveBeenCalled();
|
expect(getImageDimensionsSpy).toHaveBeenCalled();
|
||||||
expect(docs).toEqual([{
|
expect(docs).toEqual([jasmine.objectContaining({
|
||||||
docType: 'a',
|
docType: 'a',
|
||||||
renderedContent: '<img src="missing">'
|
renderedContent: '<img src="missing">'
|
||||||
}]);
|
})]);
|
||||||
expect(log.warn).toHaveBeenCalled();
|
expect(log.warn).toHaveBeenCalled();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -88,14 +88,14 @@ describe('addImageDimensions post-processor', () => {
|
||||||
}];
|
}];
|
||||||
processor.$process(docs);
|
processor.$process(docs);
|
||||||
expect(getImageDimensionsSpy).not.toHaveBeenCalled();
|
expect(getImageDimensionsSpy).not.toHaveBeenCalled();
|
||||||
expect(docs).toEqual([{
|
expect(docs).toEqual([jasmine.objectContaining({
|
||||||
docType: 'a',
|
docType: 'a',
|
||||||
renderedContent: `
|
renderedContent: `
|
||||||
<img src="a/b.jpg" width="10">
|
<img src="a/b.jpg" width="10">
|
||||||
<img src="c/d.jpg" height="10">
|
<img src="c/d.jpg" height="10">
|
||||||
<img src="e/f.jpg" width="10" height="10">
|
<img src="e/f.jpg" width="10" height="10">
|
||||||
`
|
`
|
||||||
}]);
|
})]);
|
||||||
});
|
});
|
||||||
|
|
||||||
function mockGetImageDimensions() {
|
function mockGetImageDimensions() {
|
||||||
|
|
|
@ -1,6 +1,8 @@
|
||||||
const visit = require('unist-util-visit');
|
const visit = require('unist-util-visit');
|
||||||
const is = require('hast-util-is-element');
|
const is = require('hast-util-is-element');
|
||||||
const source = require('unist-util-source');
|
const source = require('unist-util-source');
|
||||||
|
const toString = require('hast-util-to-string');
|
||||||
|
const filter = require('unist-util-filter');
|
||||||
|
|
||||||
module.exports = function h1CheckerPostProcessor() {
|
module.exports = function h1CheckerPostProcessor() {
|
||||||
return (ast, file) => {
|
return (ast, file) => {
|
||||||
|
@ -8,11 +10,23 @@ module.exports = function h1CheckerPostProcessor() {
|
||||||
visit(ast, node => {
|
visit(ast, node => {
|
||||||
if (is(node, 'h1')) {
|
if (is(node, 'h1')) {
|
||||||
h1s.push(node);
|
h1s.push(node);
|
||||||
|
file.title = getText(node);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
if (h1s.length > 1) {
|
if (h1s.length > 1) {
|
||||||
const h1Src = h1s.map(node => source(node, file)).join(', ');
|
const h1Src = h1s.map(node => source(node, file)).join(', ');
|
||||||
file.fail(`More than one h1 found [${h1Src}]`);
|
file.fail(`More than one h1 found [${h1Src}]`);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
function getText(h1) {
|
||||||
|
// Remove the aria-hidden anchor from the h1 node
|
||||||
|
const cleaned = filter(h1, node => !(
|
||||||
|
is(node, 'a') && node.properties &&
|
||||||
|
(node.properties.ariaHidden === 'true' || node.properties['aria-hidden'] === 'true')
|
||||||
|
));
|
||||||
|
|
||||||
|
return toString(cleaned);
|
||||||
|
}
|
|
@ -46,4 +46,27 @@ describe('h1Checker postprocessor', () => {
|
||||||
};
|
};
|
||||||
expect(() => processor.$process([doc])).not.toThrow();
|
expect(() => processor.$process([doc])).not.toThrow();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('should attach the h1 text to the vFile', () => {
|
||||||
|
const doc = {
|
||||||
|
docType: 'a',
|
||||||
|
renderedContent: '<h1>Heading 1</h1>'
|
||||||
|
};
|
||||||
|
processor.$process([doc]);
|
||||||
|
expect(doc.vFile.title).toEqual('Heading 1');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should clean aria-hidden anchors from h1 text added to the vFile', () => {
|
||||||
|
const doc = {
|
||||||
|
docType: 'a',
|
||||||
|
renderedContent:
|
||||||
|
'<h1 class="no-toc" id="what-is-angular">' +
|
||||||
|
'<a title="Link to this heading" class="header-link" aria-hidden="true" href="docs#what-is-angular">' +
|
||||||
|
'<i class="material-icons">link</i>' +
|
||||||
|
'</a>What is Angular?' +
|
||||||
|
'</h1>'
|
||||||
|
};
|
||||||
|
processor.$process([doc]);
|
||||||
|
expect(doc.vFile.title).toEqual('What is Angular?');
|
||||||
|
});
|
||||||
});
|
});
|
|
@ -39,6 +39,7 @@ module.exports = function postProcessHtml(log, createDocMessage) {
|
||||||
vFile.messages.forEach(m => {
|
vFile.messages.forEach(m => {
|
||||||
log.warn(createDocMessage(m.message, doc));
|
log.warn(createDocMessage(m.message, doc));
|
||||||
});
|
});
|
||||||
|
doc.vFile = vFile;
|
||||||
} catch(e) {
|
} catch(e) {
|
||||||
throw new Error(createDocMessage(e.message, doc));
|
throw new Error(createDocMessage(e.message, doc));
|
||||||
}
|
}
|
||||||
|
|
|
@ -2705,6 +2705,10 @@ flat-cache@^1.2.1:
|
||||||
graceful-fs "^4.1.2"
|
graceful-fs "^4.1.2"
|
||||||
write "^0.2.1"
|
write "^0.2.1"
|
||||||
|
|
||||||
|
flatmap@0.0.3:
|
||||||
|
version "0.0.3"
|
||||||
|
resolved "https://registry.yarnpkg.com/flatmap/-/flatmap-0.0.3.tgz#1f18a4d938152d495965f9c958d923ab2dd669b4"
|
||||||
|
|
||||||
flatten@^1.0.2:
|
flatten@^1.0.2:
|
||||||
version "1.0.2"
|
version "1.0.2"
|
||||||
resolved "https://registry.yarnpkg.com/flatten/-/flatten-1.0.2.tgz#dae46a9d78fbe25292258cc1e780a41d95c03782"
|
resolved "https://registry.yarnpkg.com/flatten/-/flatten-1.0.2.tgz#dae46a9d78fbe25292258cc1e780a41d95c03782"
|
||||||
|
@ -7256,10 +7260,21 @@ unist-builder@^1.0.1:
|
||||||
dependencies:
|
dependencies:
|
||||||
object-assign "^4.1.0"
|
object-assign "^4.1.0"
|
||||||
|
|
||||||
|
unist-util-filter@^0.2.1:
|
||||||
|
version "0.2.1"
|
||||||
|
resolved "https://registry.yarnpkg.com/unist-util-filter/-/unist-util-filter-0.2.1.tgz#e2f7876828903a6a9308e362051f86b14f35b545"
|
||||||
|
dependencies:
|
||||||
|
flatmap "0.0.3"
|
||||||
|
unist-util-is "^1.0.0"
|
||||||
|
|
||||||
unist-util-generated@^1.1.0:
|
unist-util-generated@^1.1.0:
|
||||||
version "1.1.0"
|
version "1.1.0"
|
||||||
resolved "https://registry.yarnpkg.com/unist-util-generated/-/unist-util-generated-1.1.0.tgz#8c95657ff12b32eaffe0731fbb37da6995fae01b"
|
resolved "https://registry.yarnpkg.com/unist-util-generated/-/unist-util-generated-1.1.0.tgz#8c95657ff12b32eaffe0731fbb37da6995fae01b"
|
||||||
|
|
||||||
|
unist-util-is@^1.0.0:
|
||||||
|
version "1.0.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/unist-util-is/-/unist-util-is-1.0.0.tgz#4c7b3c5c0f6aa963640056fe4af7b5fcfdbb8ef0"
|
||||||
|
|
||||||
unist-util-is@^2.0.0:
|
unist-util-is@^2.0.0:
|
||||||
version "2.0.0"
|
version "2.0.0"
|
||||||
resolved "https://registry.yarnpkg.com/unist-util-is/-/unist-util-is-2.0.0.tgz#e536472c4f78739e164d0859fc3201b97cf46e7c"
|
resolved "https://registry.yarnpkg.com/unist-util-is/-/unist-util-is-2.0.0.tgz#e536472c4f78739e164d0859fc3201b97cf46e7c"
|
||||||
|
|
Loading…
Reference in New Issue