From b18740a89a46d2e24fef64b7fe8c1b4bdcf65962 Mon Sep 17 00:00:00 2001 From: Romain Deltour Date: Sun, 29 Oct 2017 01:56:05 +0200 Subject: [PATCH] feat(rules): report data on fallback mechanisms with no a11y support Report the following Package properties in the `properties` section: - `hasBindings` will report the presence of a `bindings` element in the Package Doc - `hasManifestFallbacks` will report the presence of any manifest fallback Report the following Content Doc elements in the `data` sections: - `epub:trigger` elements in the `data['epub-triggers']` array - `epub:switch` elements in the `data['epub-switches']` array Closes #76 --- src/checker/checker-epub.js | 10 +++- src/epub/epub-parse.js | 3 ++ src/scripts/ace-extraction.js | 34 ++++++++++++- src/scripts/ace-extraction.test.js | 40 +++++++++++++++ tests/__tests__/report_json.test.js | 49 ++++++++++++++++--- .../data/feat-bindings/EPUB/content_001.xhtml | 10 ++++ tests/data/feat-bindings/EPUB/nav.xhtml | 12 +++++ tests/data/feat-bindings/EPUB/package.opf | 26 ++++++++++ .../data/feat-bindings/META-INF/container.xml | 6 +++ tests/data/feat-bindings/mimetype | 1 + .../feat-epub-switch/EPUB/content_001.xhtml | 17 +++++++ tests/data/feat-epub-switch/EPUB/nav.xhtml | 12 +++++ tests/data/feat-epub-switch/EPUB/package.opf | 23 +++++++++ .../feat-epub-switch/META-INF/container.xml | 6 +++ tests/data/feat-epub-switch/mimetype | 1 + .../feat-epub-trigger/EPUB/content_001.xhtml | 13 +++++ tests/data/feat-epub-trigger/EPUB/nav.xhtml | 12 +++++ tests/data/feat-epub-trigger/EPUB/package.opf | 23 +++++++++ .../feat-epub-trigger/META-INF/container.xml | 6 +++ tests/data/feat-epub-trigger/mimetype | 1 + .../EPUB/content_001.xhtml | 9 ++++ .../EPUB/docbook_001.xml | 9 ++++ .../feat-manifest-fallbacks/EPUB/nav.xhtml | 12 +++++ .../feat-manifest-fallbacks/EPUB/package.opf | 25 ++++++++++ .../META-INF/container.xml | 6 +++ tests/data/feat-manifest-fallbacks/mimetype | 1 + 26 files changed, 357 insertions(+), 10 deletions(-) create mode 100644 tests/data/feat-bindings/EPUB/content_001.xhtml create mode 100644 tests/data/feat-bindings/EPUB/nav.xhtml create mode 100644 tests/data/feat-bindings/EPUB/package.opf create mode 100644 tests/data/feat-bindings/META-INF/container.xml create mode 100644 tests/data/feat-bindings/mimetype create mode 100644 tests/data/feat-epub-switch/EPUB/content_001.xhtml create mode 100644 tests/data/feat-epub-switch/EPUB/nav.xhtml create mode 100644 tests/data/feat-epub-switch/EPUB/package.opf create mode 100644 tests/data/feat-epub-switch/META-INF/container.xml create mode 100644 tests/data/feat-epub-switch/mimetype create mode 100644 tests/data/feat-epub-trigger/EPUB/content_001.xhtml create mode 100644 tests/data/feat-epub-trigger/EPUB/nav.xhtml create mode 100644 tests/data/feat-epub-trigger/EPUB/package.opf create mode 100644 tests/data/feat-epub-trigger/META-INF/container.xml create mode 100644 tests/data/feat-epub-trigger/mimetype create mode 100644 tests/data/feat-manifest-fallbacks/EPUB/content_001.xhtml create mode 100644 tests/data/feat-manifest-fallbacks/EPUB/docbook_001.xml create mode 100644 tests/data/feat-manifest-fallbacks/EPUB/nav.xhtml create mode 100644 tests/data/feat-manifest-fallbacks/EPUB/package.opf create mode 100644 tests/data/feat-manifest-fallbacks/META-INF/container.xml create mode 100644 tests/data/feat-manifest-fallbacks/mimetype diff --git a/src/checker/checker-epub.js b/src/checker/checker-epub.js index 87a3b2f1..7a75181f 100644 --- a/src/checker/checker-epub.js +++ b/src/checker/checker-epub.js @@ -105,8 +105,16 @@ function check(epub, report) { checkPageSource(assertion, epub); report.addAssertions(assertion.build()); -// Report the Nav Doc + + // Report the Nav Doc report.addEPUBNav(epub.navDoc); + + // Report package properties + report.addProperties({ + hasManifestFallbacks: epub.hasManifestFallbacks, + hasBindings: epub.hasBindings, + }); + return Promise.resolve(); } diff --git a/src/epub/epub-parse.js b/src/epub/epub-parse.js index 9e48da46..5ed153eb 100644 --- a/src/epub/epub-parse.js +++ b/src/epub/epub-parse.js @@ -136,6 +136,9 @@ EpubParser.prototype.parseData = function(packageDocPath, epubDir) { const navDocFullPath = path.join(path.dirname(packageDocPath), navDocPath); this.navDoc = parseNavDoc(navDocFullPath, epubDir); } + + this.hasBindings = select('//opf:bindings', doc).length > 0; + this.hasManifestFallbacks = select('//opf:item[@fallback]', doc).length > 0; }; EpubParser.prototype.parseContentDocTitle = function(filepath) { diff --git a/src/scripts/ace-extraction.js b/src/scripts/ace-extraction.js index 9ea99878..8857f08c 100644 --- a/src/scripts/ace-extraction.js +++ b/src/scripts/ace-extraction.js @@ -17,9 +17,11 @@ ace.createReport = function(report) { reportData('audios', ace.getAudios()); reportData('canvases', ace.getCanvases()); reportData('embeds', ace.getEmbeds()); + reportData('epub-triggers', ace.getEPUBTriggers()); + reportData('epub-switches', ace.getEPUBSwitches()); reportData('iframes', ace.getIframes()); reportData('maps', ace.getMaps()); - reportData('scripts`', ace.getScripts()); + reportData('scripts', ace.getScripts()); reportData('videos', ace.getVideos()); report.properties = report.properties || {}; report.properties.hasFormElements = ace.hasFormElements(); @@ -90,6 +92,36 @@ ace.getEmbeds = function() { return embeds; } +ace.getEPUBSwitches = function() { + let switchElems = document.querySelectorAll('*|switch'); + let switches = []; + switchElems.forEach(function(elem) { + if (elem.namespaceURI === 'http://www.idpf.org/2007/ops') { + let obj = { + cfi: window.daisy.epub.createCFI(elem), + } + if (elem.hasAttribute('id')) obj.id = elem.getAttribute('id'); + switches.push(obj); + } + }); + return switches; +} + +ace.getEPUBTriggers = function() { + let triggerElems = document.querySelectorAll('*|trigger'); + let triggers = []; + triggerElems.forEach(function(elem) { + if (elem.namespaceURI === 'http://www.idpf.org/2007/ops') { + let obj = { + cfi: window.daisy.epub.createCFI(elem), + } + if (elem.hasAttribute('id')) obj.id = elem.getAttribute('id'); + triggers.push(obj); + } + }); + return triggers; +} + ace.getHTMLOutline = function() { return HTML5Outline(document.body).asHTML(); } diff --git a/src/scripts/ace-extraction.test.js b/src/scripts/ace-extraction.test.js index beb16a9c..6898f707 100644 --- a/src/scripts/ace-extraction.test.js +++ b/src/scripts/ace-extraction.test.js @@ -147,6 +147,46 @@ describe('extracting embeds', () => { }); }); +describe('extracting epub:switch', () => { + test('switch with id', async () => { + const results = await run('getEPUBSwitches', ''); + expect(results.length).toBe(1); + expect(results[0].html).toBeUndefined(); + expect(results[0].id).toEqual('foo'); + }); + + test('embed with no id', async () => { + const results = await run('getEPUBSwitches', ''); + expect(results.length).toBe(1); + expect(results[0].id).toBeUndefined(); + }); + + test('switch in other namespace', async () => { + const results = await run('getEPUBSwitches', ''); + expect(results.length).toBe(0); + }); +}); + +describe('extracting epub:trigger', () => { + test('trigger with id', async () => { + const results = await run('getEPUBTriggers', ''); + expect(results.length).toBe(1); + expect(results[0].html).toBeUndefined(); + expect(results[0].id).toEqual('foo'); + }); + + test('embed with no id', async () => { + const results = await run('getEPUBTriggers', ''); + expect(results.length).toBe(1); + expect(results[0].id).toBeUndefined(); + }); + + test('trigger in other namespace', async () => { + const results = await run('getEPUBTriggers', ''); + expect(results.length).toBe(0); + }); +}); + describe('extracting headings', () => { test('simple h1', async () => { const results = await run('getHeadings', '

title 1

'); diff --git a/tests/__tests__/report_json.test.js b/tests/__tests__/report_json.test.js index b4af5e97..eba6af27 100644 --- a/tests/__tests__/report_json.test.js +++ b/tests/__tests__/report_json.test.js @@ -63,12 +63,21 @@ describe('check properties', () => { test('defaults', async () => { const report = await ace(path.join(__dirname, '../data/base-epub-30')); expect(report.properties).toMatchObject({ + hasBindings: false, + hasManifestFallbacks: false, hasMathML: false, hasPageBreaks: false, hasFormElements: false, }); }); + test('with bindings element', async () => { + const report = await ace(path.join(__dirname, '../data/feat-bindings')); + expect(report.properties).toMatchObject({ + hasBindings: true, + }); + }); + test('with form elements', async () => { const report = await ace(path.join(__dirname, '../data/feat-forms')); expect(report.properties).toMatchObject({ @@ -76,6 +85,13 @@ describe('check properties', () => { }); }); + test('with manifest fallbacks', async () => { + const report = await ace(path.join(__dirname, '../data/feat-manifest-fallbacks')); + expect(report.properties).toMatchObject({ + hasManifestFallbacks: true, + }); + }); + test('with mathml', async () => { const report = await ace(path.join(__dirname, '../data/feat-mathml')); expect(report.properties).toMatchObject({ @@ -97,20 +113,34 @@ describe('check data', () => { expect(report.data).toEqual({}); }); - test('extract images', async () => { - const report = await ace(path.join(__dirname, '../data/feat-image')); + test('extract audios', async () => { + const report = await ace(path.join(__dirname, '../data/feat-audio')); expect(report.data).toMatchObject({ - images: [{ - src: 'EPUB/image_001.jpg', + audios: [{ + src: 'EPUB/audio_001.mp3', }], }); }); - test('extract audios', async () => { - const report = await ace(path.join(__dirname, '../data/feat-audio')); + test('extract epub:switch elements', async () => { + const report = await ace(path.join(__dirname, '../data/feat-epub-switch')); expect(report.data).toMatchObject({ - audios: [{ - src: 'EPUB/audio_001.mp3', + 'epub-switches': [{}], + }); + }); + + test('extract epub:trigger elements', async () => { + const report = await ace(path.join(__dirname, '../data/feat-epub-trigger')); + expect(report.data).toMatchObject({ + 'epub-triggers': [{}], + }); + }); + + test('extract images', async () => { + const report = await ace(path.join(__dirname, '../data/feat-image')); + expect(report.data).toMatchObject({ + images: [{ + src: 'EPUB/image_001.jpg', }], }); }); @@ -132,4 +162,7 @@ describe('check data', () => { }], }); }); + + //FIXME extract switch + //FIXME extract trigger }); diff --git a/tests/data/feat-bindings/EPUB/content_001.xhtml b/tests/data/feat-bindings/EPUB/content_001.xhtml new file mode 100644 index 00000000..1dbc3b5a --- /dev/null +++ b/tests/data/feat-bindings/EPUB/content_001.xhtml @@ -0,0 +1,10 @@ + + +Minimal EPUB + + + +

Loomings

+

Call me Ishmael.

+ + diff --git a/tests/data/feat-bindings/EPUB/nav.xhtml b/tests/data/feat-bindings/EPUB/nav.xhtml new file mode 100644 index 00000000..1d538c19 --- /dev/null +++ b/tests/data/feat-bindings/EPUB/nav.xhtml @@ -0,0 +1,12 @@ + + +Minimal Nav + + + + + diff --git a/tests/data/feat-bindings/EPUB/package.opf b/tests/data/feat-bindings/EPUB/package.opf new file mode 100644 index 00000000..e3d2b7b8 --- /dev/null +++ b/tests/data/feat-bindings/EPUB/package.opf @@ -0,0 +1,26 @@ + + + + Minimal EPUB 3.0 + en + NOID + 2017-01-01T00:00:01Z + structuralNavigation + everything OK! + noFlashingHazard + noSoundHazard + noMotionSimulationHazard + textual + textual + + + + + + + + + + + + diff --git a/tests/data/feat-bindings/META-INF/container.xml b/tests/data/feat-bindings/META-INF/container.xml new file mode 100644 index 00000000..2cf00654 --- /dev/null +++ b/tests/data/feat-bindings/META-INF/container.xml @@ -0,0 +1,6 @@ + + + + + + diff --git a/tests/data/feat-bindings/mimetype b/tests/data/feat-bindings/mimetype new file mode 100644 index 00000000..57ef03f2 --- /dev/null +++ b/tests/data/feat-bindings/mimetype @@ -0,0 +1 @@ +application/epub+zip \ No newline at end of file diff --git a/tests/data/feat-epub-switch/EPUB/content_001.xhtml b/tests/data/feat-epub-switch/EPUB/content_001.xhtml new file mode 100644 index 00000000..cd501eee --- /dev/null +++ b/tests/data/feat-epub-switch/EPUB/content_001.xhtml @@ -0,0 +1,17 @@ + + +Minimal EPUB + + +

Loomings

+

Call me Ishmael.

+ + + + + +
+
+
+ + diff --git a/tests/data/feat-epub-switch/EPUB/nav.xhtml b/tests/data/feat-epub-switch/EPUB/nav.xhtml new file mode 100644 index 00000000..1d538c19 --- /dev/null +++ b/tests/data/feat-epub-switch/EPUB/nav.xhtml @@ -0,0 +1,12 @@ + + +Minimal Nav + + + + + diff --git a/tests/data/feat-epub-switch/EPUB/package.opf b/tests/data/feat-epub-switch/EPUB/package.opf new file mode 100644 index 00000000..85501065 --- /dev/null +++ b/tests/data/feat-epub-switch/EPUB/package.opf @@ -0,0 +1,23 @@ + + + + Minimal EPUB 3.0 + en + NOID + 2017-01-01T00:00:01Z + structuralNavigation + everything OK! + noFlashingHazard + noSoundHazard + noMotionSimulationHazard + textual + textual + + + + + + + + + diff --git a/tests/data/feat-epub-switch/META-INF/container.xml b/tests/data/feat-epub-switch/META-INF/container.xml new file mode 100644 index 00000000..2cf00654 --- /dev/null +++ b/tests/data/feat-epub-switch/META-INF/container.xml @@ -0,0 +1,6 @@ + + + + + + diff --git a/tests/data/feat-epub-switch/mimetype b/tests/data/feat-epub-switch/mimetype new file mode 100644 index 00000000..57ef03f2 --- /dev/null +++ b/tests/data/feat-epub-switch/mimetype @@ -0,0 +1 @@ +application/epub+zip \ No newline at end of file diff --git a/tests/data/feat-epub-trigger/EPUB/content_001.xhtml b/tests/data/feat-epub-trigger/EPUB/content_001.xhtml new file mode 100644 index 00000000..79adea79 --- /dev/null +++ b/tests/data/feat-epub-trigger/EPUB/content_001.xhtml @@ -0,0 +1,13 @@ + + +Minimal EPUB + + + +

Loomings

+

Call me Ishmael.

+
+
+ + diff --git a/tests/data/feat-epub-trigger/EPUB/nav.xhtml b/tests/data/feat-epub-trigger/EPUB/nav.xhtml new file mode 100644 index 00000000..1d538c19 --- /dev/null +++ b/tests/data/feat-epub-trigger/EPUB/nav.xhtml @@ -0,0 +1,12 @@ + + +Minimal Nav + + + + + diff --git a/tests/data/feat-epub-trigger/EPUB/package.opf b/tests/data/feat-epub-trigger/EPUB/package.opf new file mode 100644 index 00000000..17cf544e --- /dev/null +++ b/tests/data/feat-epub-trigger/EPUB/package.opf @@ -0,0 +1,23 @@ + + + + Minimal EPUB 3.0 + en + NOID + 2017-01-01T00:00:01Z + structuralNavigation + everything OK! + noFlashingHazard + noSoundHazard + noMotionSimulationHazard + textual + textual + + + + + + + + + diff --git a/tests/data/feat-epub-trigger/META-INF/container.xml b/tests/data/feat-epub-trigger/META-INF/container.xml new file mode 100644 index 00000000..2cf00654 --- /dev/null +++ b/tests/data/feat-epub-trigger/META-INF/container.xml @@ -0,0 +1,6 @@ + + + + + + diff --git a/tests/data/feat-epub-trigger/mimetype b/tests/data/feat-epub-trigger/mimetype new file mode 100644 index 00000000..57ef03f2 --- /dev/null +++ b/tests/data/feat-epub-trigger/mimetype @@ -0,0 +1 @@ +application/epub+zip \ No newline at end of file diff --git a/tests/data/feat-manifest-fallbacks/EPUB/content_001.xhtml b/tests/data/feat-manifest-fallbacks/EPUB/content_001.xhtml new file mode 100644 index 00000000..c55a9e8b --- /dev/null +++ b/tests/data/feat-manifest-fallbacks/EPUB/content_001.xhtml @@ -0,0 +1,9 @@ + + +Minimal EPUB + + +

Loomings

+

Call me Ishmael.

+ + diff --git a/tests/data/feat-manifest-fallbacks/EPUB/docbook_001.xml b/tests/data/feat-manifest-fallbacks/EPUB/docbook_001.xml new file mode 100644 index 00000000..c55a9e8b --- /dev/null +++ b/tests/data/feat-manifest-fallbacks/EPUB/docbook_001.xml @@ -0,0 +1,9 @@ + + +Minimal EPUB + + +

Loomings

+

Call me Ishmael.

+ + diff --git a/tests/data/feat-manifest-fallbacks/EPUB/nav.xhtml b/tests/data/feat-manifest-fallbacks/EPUB/nav.xhtml new file mode 100644 index 00000000..1d538c19 --- /dev/null +++ b/tests/data/feat-manifest-fallbacks/EPUB/nav.xhtml @@ -0,0 +1,12 @@ + + +Minimal Nav + + + + + diff --git a/tests/data/feat-manifest-fallbacks/EPUB/package.opf b/tests/data/feat-manifest-fallbacks/EPUB/package.opf new file mode 100644 index 00000000..7d2871d1 --- /dev/null +++ b/tests/data/feat-manifest-fallbacks/EPUB/package.opf @@ -0,0 +1,25 @@ + + + + Minimal EPUB 3.0 + en + NOID + 2017-01-01T00:00:01Z + structuralNavigation + everything OK! + noFlashingHazard + noSoundHazard + noMotionSimulationHazard + textual + textual + + + + + + + + + + + diff --git a/tests/data/feat-manifest-fallbacks/META-INF/container.xml b/tests/data/feat-manifest-fallbacks/META-INF/container.xml new file mode 100644 index 00000000..2cf00654 --- /dev/null +++ b/tests/data/feat-manifest-fallbacks/META-INF/container.xml @@ -0,0 +1,6 @@ + + + + + + diff --git a/tests/data/feat-manifest-fallbacks/mimetype b/tests/data/feat-manifest-fallbacks/mimetype new file mode 100644 index 00000000..57ef03f2 --- /dev/null +++ b/tests/data/feat-manifest-fallbacks/mimetype @@ -0,0 +1 @@ +application/epub+zip \ No newline at end of file