From 9f75a1d9d91324d7092ec7a18a9d9ac3c136256e Mon Sep 17 00:00:00 2001 From: Romain Deltour Date: Mon, 12 Dec 2022 22:28:02 +0100 Subject: [PATCH] feat: update viewport meta element requirements This commit implements the post-CR changes on the requirements for the viewport meta element used to define the ICB in fixed-layout documents. Viewport syntax: - properties can now have several values - the `ViewportMeta` object now return a list of string values when looking up values for a name. ICB definition checks: - only the first `viewport` `meta` element of fixed-layout documents is checked - new `HTM-059` error is reported when `height` or `width` dimensions are specified more than once - new `HTM-060a` usage is reported for any subsequent `viewport` `meta` element found in fixed-layout documents - new `HTM-060b` usage is reported fo any `viewport` `meta` element found in reflowable documents Fix #1401, Fix #1449 --- .../epubcheck/messages/DefaultSeverities.java | 3 + .../adobe/epubcheck/messages/MessageId.java | 3 + .../com/adobe/epubcheck/ops/OPSHandler30.java | 66 ++++++++++------ .../util/microsyntax/ViewportMeta.java | 79 +++++++++++-------- .../messages/MessageBundle.properties | 5 +- .../util/microsyntax/ViewportSteps.java | 12 ++- .../EPUB/content_001.xhtml | 3 +- .../EPUB/nav.xhtml | 0 .../EPUB/package.opf | 0 .../META-INF/container.xml | 0 .../mimetype | 0 .../EPUB/content_001.xhtml | 2 +- .../EPUB/content_001.xhtml | 14 ++++ .../EPUB/nav.xhtml | 14 ++++ .../EPUB/package.opf | 17 ++++ .../META-INF/container.xml | 6 ++ .../mimetype | 1 + .../EPUB/content_001.xhtml | 15 ++++ .../EPUB/nav.xhtml | 14 ++++ .../EPUB/package.opf | 17 ++++ .../META-INF/container.xml | 6 ++ .../mimetype | 1 + .../EPUB/content_001.xhtml | 2 +- .../EPUB/content_001.xhtml | 12 +++ .../EPUB/nav.xhtml | 14 ++++ .../EPUB/package.opf | 17 ++++ .../META-INF/container.xml | 6 ++ .../mimetype | 1 + .../EPUB/content_001.xhtml | 12 +++ .../EPUB/nav.xhtml | 14 ++++ .../EPUB/package.opf | 16 ++++ .../META-INF/container.xml | 6 ++ .../mimetype | 1 + .../resources/epub3/08-layout/layout.feature | 55 +++++++++---- .../viewport-syntax.feature | 75 ++++++++++-------- 35 files changed, 396 insertions(+), 113 deletions(-) rename src/test/resources/epub3/08-layout/files/{content-fxl-xhtml-viewport-multiple-valid => content-fxl-xhtml-viewport-duplicate-width-height-error}/EPUB/content_001.xhtml (65%) rename src/test/resources/epub3/08-layout/files/{content-fxl-xhtml-viewport-multiple-valid => content-fxl-xhtml-viewport-duplicate-width-height-error}/EPUB/nav.xhtml (100%) rename src/test/resources/epub3/08-layout/files/{content-fxl-xhtml-viewport-multiple-valid => content-fxl-xhtml-viewport-duplicate-width-height-error}/EPUB/package.opf (100%) rename src/test/resources/epub3/08-layout/files/{content-fxl-xhtml-viewport-multiple-valid => content-fxl-xhtml-viewport-duplicate-width-height-error}/META-INF/container.xml (100%) rename src/test/resources/epub3/08-layout/files/{content-fxl-xhtml-viewport-multiple-valid => content-fxl-xhtml-viewport-duplicate-width-height-error}/mimetype (100%) create mode 100644 src/test/resources/epub3/08-layout/files/content-fxl-xhtml-viewport-icb-missing-in-first-meta-error/EPUB/content_001.xhtml create mode 100644 src/test/resources/epub3/08-layout/files/content-fxl-xhtml-viewport-icb-missing-in-first-meta-error/EPUB/nav.xhtml create mode 100644 src/test/resources/epub3/08-layout/files/content-fxl-xhtml-viewport-icb-missing-in-first-meta-error/EPUB/package.opf create mode 100644 src/test/resources/epub3/08-layout/files/content-fxl-xhtml-viewport-icb-missing-in-first-meta-error/META-INF/container.xml create mode 100644 src/test/resources/epub3/08-layout/files/content-fxl-xhtml-viewport-icb-missing-in-first-meta-error/mimetype create mode 100644 src/test/resources/epub3/08-layout/files/content-fxl-xhtml-viewport-multiple-usage-valid/EPUB/content_001.xhtml create mode 100644 src/test/resources/epub3/08-layout/files/content-fxl-xhtml-viewport-multiple-usage-valid/EPUB/nav.xhtml create mode 100644 src/test/resources/epub3/08-layout/files/content-fxl-xhtml-viewport-multiple-usage-valid/EPUB/package.opf create mode 100644 src/test/resources/epub3/08-layout/files/content-fxl-xhtml-viewport-multiple-usage-valid/META-INF/container.xml create mode 100644 src/test/resources/epub3/08-layout/files/content-fxl-xhtml-viewport-multiple-usage-valid/mimetype create mode 100644 src/test/resources/epub3/08-layout/files/content-fxl-xhtml-viewport-width-missing-error/EPUB/content_001.xhtml create mode 100644 src/test/resources/epub3/08-layout/files/content-fxl-xhtml-viewport-width-missing-error/EPUB/nav.xhtml create mode 100644 src/test/resources/epub3/08-layout/files/content-fxl-xhtml-viewport-width-missing-error/EPUB/package.opf create mode 100644 src/test/resources/epub3/08-layout/files/content-fxl-xhtml-viewport-width-missing-error/META-INF/container.xml create mode 100644 src/test/resources/epub3/08-layout/files/content-fxl-xhtml-viewport-width-missing-error/mimetype create mode 100644 src/test/resources/epub3/08-layout/files/content-reflow-xhtml-viewport-height-missing-valid/EPUB/content_001.xhtml create mode 100644 src/test/resources/epub3/08-layout/files/content-reflow-xhtml-viewport-height-missing-valid/EPUB/nav.xhtml create mode 100644 src/test/resources/epub3/08-layout/files/content-reflow-xhtml-viewport-height-missing-valid/EPUB/package.opf create mode 100644 src/test/resources/epub3/08-layout/files/content-reflow-xhtml-viewport-height-missing-valid/META-INF/container.xml create mode 100644 src/test/resources/epub3/08-layout/files/content-reflow-xhtml-viewport-height-missing-valid/mimetype diff --git a/src/main/java/com/adobe/epubcheck/messages/DefaultSeverities.java b/src/main/java/com/adobe/epubcheck/messages/DefaultSeverities.java index ceb019866..792578953 100644 --- a/src/main/java/com/adobe/epubcheck/messages/DefaultSeverities.java +++ b/src/main/java/com/adobe/epubcheck/messages/DefaultSeverities.java @@ -142,6 +142,9 @@ private void initialize() severities.put(MessageId.HTM_056, Severity.ERROR); severities.put(MessageId.HTM_057, Severity.ERROR); severities.put(MessageId.HTM_058, Severity.ERROR); + severities.put(MessageId.HTM_059, Severity.ERROR); + severities.put(MessageId.HTM_060a, Severity.USAGE); + severities.put(MessageId.HTM_060b, Severity.USAGE); // Media severities.put(MessageId.MED_001, Severity.SUPPRESSED); diff --git a/src/main/java/com/adobe/epubcheck/messages/MessageId.java b/src/main/java/com/adobe/epubcheck/messages/MessageId.java index 8c35915d1..b74f13168 100644 --- a/src/main/java/com/adobe/epubcheck/messages/MessageId.java +++ b/src/main/java/com/adobe/epubcheck/messages/MessageId.java @@ -136,6 +136,9 @@ public enum MessageId implements Comparable HTM_056("HTM_056"), HTM_057("HTM_057"), HTM_058("HTM_058"), + HTM_059("HTM_059"), + HTM_060a("HTM_060a"), + HTM_060b("HTM_060b"), // Messages associated with media (images, audio and video) MED_001("MED-001"), diff --git a/src/main/java/com/adobe/epubcheck/ops/OPSHandler30.java b/src/main/java/com/adobe/epubcheck/ops/OPSHandler30.java index 9c4a964e9..cb558beb2 100644 --- a/src/main/java/com/adobe/epubcheck/ops/OPSHandler30.java +++ b/src/main/java/com/adobe/epubcheck/ops/OPSHandler30.java @@ -1,5 +1,6 @@ package com.adobe.epubcheck.ops; +import java.util.Arrays; import java.util.Collections; import java.util.EnumSet; import java.util.HashMap; @@ -10,6 +11,7 @@ import java.util.Map; import java.util.Set; import java.util.TreeSet; +import java.util.stream.Collectors; import org.w3c.epubcheck.constants.MIMEType; import org.w3c.epubcheck.core.references.Reference; @@ -763,17 +765,14 @@ protected void processMeta() String name = e.getAttribute("name"); if ("viewport".equals(Strings.nullToEmpty(name).trim())) { - // Mark the viewport as seen - // (used when checking the existence of viewport metadata) - hasViewport = true; - // For a fixed-layout documents: - if (context.opfItem.isPresent() && context.opfItem.get().isFixedLayout()) + String content = e.getAttribute("content"); + // For fixed-layout documents, check the first viewport meta element + if (!hasViewport && context.opfItem.isPresent() && context.opfItem.get().isFixedLayout()) { - String contentAttribute = e.getAttribute("content"); - + hasViewport = true; // parse viewport metadata List syntaxErrors = new LinkedList<>(); - ViewportMeta viewport = ViewportMeta.parse(contentAttribute, + ViewportMeta viewport = ViewportMeta.parse(content, new ViewportMeta.ErrorHandler() { @Override @@ -785,31 +784,46 @@ public void error(ParseError error, int position) if (!syntaxErrors.isEmpty()) { // report any syntax error - report.message(MessageId.HTM_047, location(), contentAttribute); + report.message(MessageId.HTM_047, location(), content); } else { - // check that viewport metadata has a valid width value - if (!viewport.hasProperty("width")) - { - report.message(MessageId.HTM_056, location(), "width"); - } - else if (!ViewportMeta.isValidWidth(viewport.getValue("width"))) + for (String property : Arrays.asList("width", "height")) { - report.message(MessageId.HTM_057, location(), "width"); + // check that viewport metadata has a valid width value + if (!viewport.hasProperty(property)) + { + report.message(MessageId.HTM_056, location(), property); + } + else + { + List values = viewport.getValues(property); + if (values.size() > 1) + { + report.message(MessageId.HTM_059, location(), property, + values.stream().map(v -> '"' + v + '"').collect(Collectors.joining(", "))); + } + if (!ViewportMeta.isValidProperty(property, values.get(0))) + { + report.message(MessageId.HTM_057, location(), property); + } + } } - // check that viewport metadata has a valid height value - if (!viewport.hasProperty("height")) - { - report.message(MessageId.HTM_056, location(), "height"); - } - else if (!ViewportMeta.isValidHeight(viewport.getValue("height"))) - { - report.message(MessageId.HTM_057, location(), "height"); - } } - + } + else + { + // Report ignored secondary viewport meta in fixed-layout documents + if (context.opfItem.isPresent() && context.opfItem.get().isFixedLayout()) + { + report.message(MessageId.HTM_060a, location(), content); + } + // Report ignored viewport meta in reflowable documents + else + { + report.message(MessageId.HTM_060b, location(), content); + } } } } diff --git a/src/main/java/org/w3c/epubcheck/util/microsyntax/ViewportMeta.java b/src/main/java/org/w3c/epubcheck/util/microsyntax/ViewportMeta.java index 3120cd460..2e20feb5a 100644 --- a/src/main/java/org/w3c/epubcheck/util/microsyntax/ViewportMeta.java +++ b/src/main/java/org/w3c/epubcheck/util/microsyntax/ViewportMeta.java @@ -3,11 +3,12 @@ import static org.w3c.epubcheck.util.infra.InfraUtil.isASCIIWhitespace; import java.nio.CharBuffer; -import java.util.Map; +import java.util.List; import java.util.regex.Pattern; import com.google.common.base.Preconditions; -import com.google.common.collect.ImmutableMap; +import com.google.common.collect.ImmutableListMultimap; +import com.google.common.collect.ListMultimap; public class ViewportMeta { @@ -19,16 +20,18 @@ public static ViewportMeta parse(String string, ErrorHandler errorHandler) return new Parser(errorHandler).parse(string); } - public static boolean isValidHeight(String height) + public static boolean isValidProperty(String name, String value) { - Preconditions.checkArgument(height != null); - return VIEWPORT_HEIGHT_REGEX.matcher(height).matches(); - } - - public static boolean isValidWidth(String width) - { - Preconditions.checkArgument(width != null); - return VIEWPORT_WIDTH_REGEX.matcher(width).matches(); + Preconditions.checkNotNull(value); + switch (Preconditions.checkNotNull(name)) + { + case "width": + return VIEWPORT_WIDTH_REGEX.matcher(value).matches(); + case "height": + return VIEWPORT_HEIGHT_REGEX.matcher(value).matches(); + default: + return true; + } } public static enum ParseError @@ -51,7 +54,8 @@ public interface ErrorHandler private final static class Builder { - public ImmutableMap.Builder properties = ImmutableMap.builder(); + public ImmutableListMultimap.Builder properties = ImmutableListMultimap + .builder(); public ViewportMeta build() { @@ -123,25 +127,13 @@ public ViewportMeta parse(CharSequence string) } else if (c == '=' || isASCIIWhitespace(c)) { - if (name.length() == 0) - { - error(ParseError.NAME_EMPTY, input.position()); - return builder.build(); - } state = State.ASSIGN; consume = false; } else if (c == ',' || c == ';') { - if (name.length() == 0) - { - error(ParseError.LEADING_SEPARATOR, input.position()); - } - else - { - error(ParseError.VALUE_EMPTY, input.position()); - } - return builder.build(); + state = State.SEPARATOR; + consume = false; } else { @@ -149,7 +141,12 @@ else if (c == '=' || isASCIIWhitespace(c)) } break; case ASSIGN: - if (isASCIIWhitespace(c)) + if (name.length()==0) { + // assign state but no name was found + error(ParseError.NAME_EMPTY, input.position()); + return builder.build(); + } + else if (isASCIIWhitespace(c)) { // skip whitespace } @@ -157,6 +154,11 @@ else if (c == '=') { state = State.VALUE; } + else if (c == ',' || c == ';') + { + state = State.SEPARATOR; + consume = false; + } else { // no '=' was matched (i.e. no value is set) @@ -200,6 +202,11 @@ else if (c == '=') consume = false; } case SEPARATOR: + if (name.length() == 0) + { + error(ParseError.LEADING_SEPARATOR, input.position()); + return builder.build(); + } if (c == ',' || c == ';' || isASCIIWhitespace(c)) { // skip repeating separators @@ -215,13 +222,12 @@ else if (c == '=') break; } } - if (value.length() != 0) - { - builder.withProperty(name.toString(), value.toString()); - } - else if (name.length() != 0) + // finalize, report if unexpected final state + if (state == State.VALUE && value.length() == 0) { error(ParseError.VALUE_EMPTY, input.position()); + } else { + builder.withProperty(name.toString(), value.toString()); } if (state == State.SEPARATOR) { @@ -231,7 +237,7 @@ else if (name.length() != 0) } } - private final Map properties; + private final ImmutableListMultimap properties; private ViewportMeta(Builder builder) { @@ -243,9 +249,14 @@ public boolean hasProperty(String name) return properties.containsKey(name); } - public String getValue(String name) + public List getValues(String name) { return properties.get(name); } + public ListMultimap asMultimap() + { + return properties; + } + } diff --git a/src/main/resources/com/adobe/epubcheck/messages/MessageBundle.properties b/src/main/resources/com/adobe/epubcheck/messages/MessageBundle.properties index ec9336ba8..27fe95bd9 100644 --- a/src/main/resources/com/adobe/epubcheck/messages/MessageBundle.properties +++ b/src/main/resources/com/adobe/epubcheck/messages/MessageBundle.properties @@ -60,7 +60,10 @@ HTM_054=Custom attribute namespace ("%1$s") must not include the string "%2$s" i HTM_055=The "%1$s" element should not be used (discouraged construct) HTM_056=Viewport metadata has no "%1$s" dimension (both "width" and "height" properties are required) HTM_057=Viewport "%1$s" value must be a positive number or the keyword "device-%1$s" -HTM_058=HTML documents must be encoded in UTF-8, but UTF-16 was detected. +HTM_058=HTML documents must be encoded in UTF-8, but UTF-16 was detected. +HTM_059=Viewport "%1$s" property must not be defined more than once, but found values [%2$s]. +HTM_060a=EPUB reading systems must ignore secondary viewport meta elements in fixed-layout documents; viewport declaration "%1$s" will be ignored. +HTM_060b=EPUB reading systems must ignore viewport meta elements in reflowable documents; viewport declaration "%1$s" will be ignored. #media MED_003=Picture "img" elements must reference core media type resources, but found resource "%1$s" of type "%2$s". diff --git a/src/test/java/org/w3c/epubcheck/util/microsyntax/ViewportSteps.java b/src/test/java/org/w3c/epubcheck/util/microsyntax/ViewportSteps.java index 625473bfb..792b88b92 100644 --- a/src/test/java/org/w3c/epubcheck/util/microsyntax/ViewportSteps.java +++ b/src/test/java/org/w3c/epubcheck/util/microsyntax/ViewportSteps.java @@ -2,6 +2,7 @@ import static org.hamcrest.MatcherAssert.assertThat; import static org.hamcrest.Matchers.contains; +import static org.hamcrest.Matchers.equalTo; import static org.hamcrest.Matchers.empty; import static org.hamcrest.Matchers.is; @@ -12,6 +13,7 @@ import org.w3c.epubcheck.util.microsyntax.ViewportMeta.ParseError; import com.google.common.collect.ImmutableList; +import com.google.common.collect.ImmutableListMultimap; import io.cucumber.java.ParameterType; import io.cucumber.java.en.Then; @@ -20,6 +22,8 @@ public class ViewportSteps { + private ViewportMeta viewport; + public static final class TestErrorHandler implements ErrorHandler { public final List errors = new LinkedList<>(); @@ -58,7 +62,7 @@ public ParseError error(String error) @When("parsing viewport {string}") public void parseViewport(String content) { - ViewportMeta.parse(content, handler); + viewport = ViewportMeta.parse(content, handler); } @Then("no error is returned") @@ -67,6 +71,12 @@ public void assertValid() assertThat("Unexpected errors", handler.errors(), is(empty())); } + @Then("the parsed viewport equals {multimap}") + public void assertResult(ImmutableListMultimap multimap) + { + assertThat(viewport.asMultimap(), is(equalTo(multimap))); + } + @Then("error {error} is returned") public void assertError(ParseError error) { diff --git a/src/test/resources/epub3/08-layout/files/content-fxl-xhtml-viewport-multiple-valid/EPUB/content_001.xhtml b/src/test/resources/epub3/08-layout/files/content-fxl-xhtml-viewport-duplicate-width-height-error/EPUB/content_001.xhtml similarity index 65% rename from src/test/resources/epub3/08-layout/files/content-fxl-xhtml-viewport-multiple-valid/EPUB/content_001.xhtml rename to src/test/resources/epub3/08-layout/files/content-fxl-xhtml-viewport-duplicate-width-height-error/EPUB/content_001.xhtml index cc9ac31b9..c228724ce 100644 --- a/src/test/resources/epub3/08-layout/files/content-fxl-xhtml-viewport-multiple-valid/EPUB/content_001.xhtml +++ b/src/test/resources/epub3/08-layout/files/content-fxl-xhtml-viewport-duplicate-width-height-error/EPUB/content_001.xhtml @@ -2,8 +2,7 @@ - - + Minimal EPUB diff --git a/src/test/resources/epub3/08-layout/files/content-fxl-xhtml-viewport-multiple-valid/EPUB/nav.xhtml b/src/test/resources/epub3/08-layout/files/content-fxl-xhtml-viewport-duplicate-width-height-error/EPUB/nav.xhtml similarity index 100% rename from src/test/resources/epub3/08-layout/files/content-fxl-xhtml-viewport-multiple-valid/EPUB/nav.xhtml rename to src/test/resources/epub3/08-layout/files/content-fxl-xhtml-viewport-duplicate-width-height-error/EPUB/nav.xhtml diff --git a/src/test/resources/epub3/08-layout/files/content-fxl-xhtml-viewport-multiple-valid/EPUB/package.opf b/src/test/resources/epub3/08-layout/files/content-fxl-xhtml-viewport-duplicate-width-height-error/EPUB/package.opf similarity index 100% rename from src/test/resources/epub3/08-layout/files/content-fxl-xhtml-viewport-multiple-valid/EPUB/package.opf rename to src/test/resources/epub3/08-layout/files/content-fxl-xhtml-viewport-duplicate-width-height-error/EPUB/package.opf diff --git a/src/test/resources/epub3/08-layout/files/content-fxl-xhtml-viewport-multiple-valid/META-INF/container.xml b/src/test/resources/epub3/08-layout/files/content-fxl-xhtml-viewport-duplicate-width-height-error/META-INF/container.xml similarity index 100% rename from src/test/resources/epub3/08-layout/files/content-fxl-xhtml-viewport-multiple-valid/META-INF/container.xml rename to src/test/resources/epub3/08-layout/files/content-fxl-xhtml-viewport-duplicate-width-height-error/META-INF/container.xml diff --git a/src/test/resources/epub3/08-layout/files/content-fxl-xhtml-viewport-multiple-valid/mimetype b/src/test/resources/epub3/08-layout/files/content-fxl-xhtml-viewport-duplicate-width-height-error/mimetype similarity index 100% rename from src/test/resources/epub3/08-layout/files/content-fxl-xhtml-viewport-multiple-valid/mimetype rename to src/test/resources/epub3/08-layout/files/content-fxl-xhtml-viewport-duplicate-width-height-error/mimetype diff --git a/src/test/resources/epub3/08-layout/files/content-fxl-xhtml-viewport-height-empty-error/EPUB/content_001.xhtml b/src/test/resources/epub3/08-layout/files/content-fxl-xhtml-viewport-height-empty-error/EPUB/content_001.xhtml index a820d396e..edce0cc30 100644 --- a/src/test/resources/epub3/08-layout/files/content-fxl-xhtml-viewport-height-empty-error/EPUB/content_001.xhtml +++ b/src/test/resources/epub3/08-layout/files/content-fxl-xhtml-viewport-height-empty-error/EPUB/content_001.xhtml @@ -2,7 +2,7 @@ - + Minimal EPUB diff --git a/src/test/resources/epub3/08-layout/files/content-fxl-xhtml-viewport-icb-missing-in-first-meta-error/EPUB/content_001.xhtml b/src/test/resources/epub3/08-layout/files/content-fxl-xhtml-viewport-icb-missing-in-first-meta-error/EPUB/content_001.xhtml new file mode 100644 index 000000000..5d0b34c3c --- /dev/null +++ b/src/test/resources/epub3/08-layout/files/content-fxl-xhtml-viewport-icb-missing-in-first-meta-error/EPUB/content_001.xhtml @@ -0,0 +1,14 @@ + + + + + + + + Minimal EPUB + + +

Loomings

+

Call me Ishmael.

+ + diff --git a/src/test/resources/epub3/08-layout/files/content-fxl-xhtml-viewport-icb-missing-in-first-meta-error/EPUB/nav.xhtml b/src/test/resources/epub3/08-layout/files/content-fxl-xhtml-viewport-icb-missing-in-first-meta-error/EPUB/nav.xhtml new file mode 100644 index 000000000..240745e63 --- /dev/null +++ b/src/test/resources/epub3/08-layout/files/content-fxl-xhtml-viewport-icb-missing-in-first-meta-error/EPUB/nav.xhtml @@ -0,0 +1,14 @@ + + + + + Minimal Nav + + + + + diff --git a/src/test/resources/epub3/08-layout/files/content-fxl-xhtml-viewport-icb-missing-in-first-meta-error/EPUB/package.opf b/src/test/resources/epub3/08-layout/files/content-fxl-xhtml-viewport-icb-missing-in-first-meta-error/EPUB/package.opf new file mode 100644 index 000000000..d16a30d60 --- /dev/null +++ b/src/test/resources/epub3/08-layout/files/content-fxl-xhtml-viewport-icb-missing-in-first-meta-error/EPUB/package.opf @@ -0,0 +1,17 @@ + + + + Minimal EPUB 3.0 + en + NOID + 2017-06-14T00:00:01Z + pre-paginated + + + + + + + + + \ No newline at end of file diff --git a/src/test/resources/epub3/08-layout/files/content-fxl-xhtml-viewport-icb-missing-in-first-meta-error/META-INF/container.xml b/src/test/resources/epub3/08-layout/files/content-fxl-xhtml-viewport-icb-missing-in-first-meta-error/META-INF/container.xml new file mode 100644 index 000000000..318782179 --- /dev/null +++ b/src/test/resources/epub3/08-layout/files/content-fxl-xhtml-viewport-icb-missing-in-first-meta-error/META-INF/container.xml @@ -0,0 +1,6 @@ + + + + + + diff --git a/src/test/resources/epub3/08-layout/files/content-fxl-xhtml-viewport-icb-missing-in-first-meta-error/mimetype b/src/test/resources/epub3/08-layout/files/content-fxl-xhtml-viewport-icb-missing-in-first-meta-error/mimetype new file mode 100644 index 000000000..57ef03f24 --- /dev/null +++ b/src/test/resources/epub3/08-layout/files/content-fxl-xhtml-viewport-icb-missing-in-first-meta-error/mimetype @@ -0,0 +1 @@ +application/epub+zip \ No newline at end of file diff --git a/src/test/resources/epub3/08-layout/files/content-fxl-xhtml-viewport-multiple-usage-valid/EPUB/content_001.xhtml b/src/test/resources/epub3/08-layout/files/content-fxl-xhtml-viewport-multiple-usage-valid/EPUB/content_001.xhtml new file mode 100644 index 000000000..90272e58f --- /dev/null +++ b/src/test/resources/epub3/08-layout/files/content-fxl-xhtml-viewport-multiple-usage-valid/EPUB/content_001.xhtml @@ -0,0 +1,15 @@ + + + + + + + + + Minimal EPUB + + +

Loomings

+

Call me Ishmael.

+ + diff --git a/src/test/resources/epub3/08-layout/files/content-fxl-xhtml-viewport-multiple-usage-valid/EPUB/nav.xhtml b/src/test/resources/epub3/08-layout/files/content-fxl-xhtml-viewport-multiple-usage-valid/EPUB/nav.xhtml new file mode 100644 index 000000000..240745e63 --- /dev/null +++ b/src/test/resources/epub3/08-layout/files/content-fxl-xhtml-viewport-multiple-usage-valid/EPUB/nav.xhtml @@ -0,0 +1,14 @@ + + + + + Minimal Nav + + + + + diff --git a/src/test/resources/epub3/08-layout/files/content-fxl-xhtml-viewport-multiple-usage-valid/EPUB/package.opf b/src/test/resources/epub3/08-layout/files/content-fxl-xhtml-viewport-multiple-usage-valid/EPUB/package.opf new file mode 100644 index 000000000..d16a30d60 --- /dev/null +++ b/src/test/resources/epub3/08-layout/files/content-fxl-xhtml-viewport-multiple-usage-valid/EPUB/package.opf @@ -0,0 +1,17 @@ + + + + Minimal EPUB 3.0 + en + NOID + 2017-06-14T00:00:01Z + pre-paginated + + + + + + + + + \ No newline at end of file diff --git a/src/test/resources/epub3/08-layout/files/content-fxl-xhtml-viewport-multiple-usage-valid/META-INF/container.xml b/src/test/resources/epub3/08-layout/files/content-fxl-xhtml-viewport-multiple-usage-valid/META-INF/container.xml new file mode 100644 index 000000000..318782179 --- /dev/null +++ b/src/test/resources/epub3/08-layout/files/content-fxl-xhtml-viewport-multiple-usage-valid/META-INF/container.xml @@ -0,0 +1,6 @@ + + + + + + diff --git a/src/test/resources/epub3/08-layout/files/content-fxl-xhtml-viewport-multiple-usage-valid/mimetype b/src/test/resources/epub3/08-layout/files/content-fxl-xhtml-viewport-multiple-usage-valid/mimetype new file mode 100644 index 000000000..57ef03f24 --- /dev/null +++ b/src/test/resources/epub3/08-layout/files/content-fxl-xhtml-viewport-multiple-usage-valid/mimetype @@ -0,0 +1 @@ +application/epub+zip \ No newline at end of file diff --git a/src/test/resources/epub3/08-layout/files/content-fxl-xhtml-viewport-syntax-invalid-error/EPUB/content_001.xhtml b/src/test/resources/epub3/08-layout/files/content-fxl-xhtml-viewport-syntax-invalid-error/EPUB/content_001.xhtml index ff331a5db..e76b87c7f 100644 --- a/src/test/resources/epub3/08-layout/files/content-fxl-xhtml-viewport-syntax-invalid-error/EPUB/content_001.xhtml +++ b/src/test/resources/epub3/08-layout/files/content-fxl-xhtml-viewport-syntax-invalid-error/EPUB/content_001.xhtml @@ -2,7 +2,7 @@ - + Minimal EPUB diff --git a/src/test/resources/epub3/08-layout/files/content-fxl-xhtml-viewport-width-missing-error/EPUB/content_001.xhtml b/src/test/resources/epub3/08-layout/files/content-fxl-xhtml-viewport-width-missing-error/EPUB/content_001.xhtml new file mode 100644 index 000000000..e2a95261c --- /dev/null +++ b/src/test/resources/epub3/08-layout/files/content-fxl-xhtml-viewport-width-missing-error/EPUB/content_001.xhtml @@ -0,0 +1,12 @@ + + + + + + Minimal EPUB + + +

Loomings

+

Call me Ishmael.

+ + diff --git a/src/test/resources/epub3/08-layout/files/content-fxl-xhtml-viewport-width-missing-error/EPUB/nav.xhtml b/src/test/resources/epub3/08-layout/files/content-fxl-xhtml-viewport-width-missing-error/EPUB/nav.xhtml new file mode 100644 index 000000000..240745e63 --- /dev/null +++ b/src/test/resources/epub3/08-layout/files/content-fxl-xhtml-viewport-width-missing-error/EPUB/nav.xhtml @@ -0,0 +1,14 @@ + + + + + Minimal Nav + + + + + diff --git a/src/test/resources/epub3/08-layout/files/content-fxl-xhtml-viewport-width-missing-error/EPUB/package.opf b/src/test/resources/epub3/08-layout/files/content-fxl-xhtml-viewport-width-missing-error/EPUB/package.opf new file mode 100644 index 000000000..d16a30d60 --- /dev/null +++ b/src/test/resources/epub3/08-layout/files/content-fxl-xhtml-viewport-width-missing-error/EPUB/package.opf @@ -0,0 +1,17 @@ + + + + Minimal EPUB 3.0 + en + NOID + 2017-06-14T00:00:01Z + pre-paginated + + + + + + + + + \ No newline at end of file diff --git a/src/test/resources/epub3/08-layout/files/content-fxl-xhtml-viewport-width-missing-error/META-INF/container.xml b/src/test/resources/epub3/08-layout/files/content-fxl-xhtml-viewport-width-missing-error/META-INF/container.xml new file mode 100644 index 000000000..318782179 --- /dev/null +++ b/src/test/resources/epub3/08-layout/files/content-fxl-xhtml-viewport-width-missing-error/META-INF/container.xml @@ -0,0 +1,6 @@ + + + + + + diff --git a/src/test/resources/epub3/08-layout/files/content-fxl-xhtml-viewport-width-missing-error/mimetype b/src/test/resources/epub3/08-layout/files/content-fxl-xhtml-viewport-width-missing-error/mimetype new file mode 100644 index 000000000..57ef03f24 --- /dev/null +++ b/src/test/resources/epub3/08-layout/files/content-fxl-xhtml-viewport-width-missing-error/mimetype @@ -0,0 +1 @@ +application/epub+zip \ No newline at end of file diff --git a/src/test/resources/epub3/08-layout/files/content-reflow-xhtml-viewport-height-missing-valid/EPUB/content_001.xhtml b/src/test/resources/epub3/08-layout/files/content-reflow-xhtml-viewport-height-missing-valid/EPUB/content_001.xhtml new file mode 100644 index 000000000..8bcb4abde --- /dev/null +++ b/src/test/resources/epub3/08-layout/files/content-reflow-xhtml-viewport-height-missing-valid/EPUB/content_001.xhtml @@ -0,0 +1,12 @@ + + + + + + Minimal EPUB + + +

Loomings

+

Call me Ishmael.

+ + diff --git a/src/test/resources/epub3/08-layout/files/content-reflow-xhtml-viewport-height-missing-valid/EPUB/nav.xhtml b/src/test/resources/epub3/08-layout/files/content-reflow-xhtml-viewport-height-missing-valid/EPUB/nav.xhtml new file mode 100644 index 000000000..240745e63 --- /dev/null +++ b/src/test/resources/epub3/08-layout/files/content-reflow-xhtml-viewport-height-missing-valid/EPUB/nav.xhtml @@ -0,0 +1,14 @@ + + + + + Minimal Nav + + + + + diff --git a/src/test/resources/epub3/08-layout/files/content-reflow-xhtml-viewport-height-missing-valid/EPUB/package.opf b/src/test/resources/epub3/08-layout/files/content-reflow-xhtml-viewport-height-missing-valid/EPUB/package.opf new file mode 100644 index 000000000..0d1eec6e9 --- /dev/null +++ b/src/test/resources/epub3/08-layout/files/content-reflow-xhtml-viewport-height-missing-valid/EPUB/package.opf @@ -0,0 +1,16 @@ + + + + Minimal EPUB 3.0 + en + NOID + 2017-06-14T00:00:01Z + + + + + + + + + \ No newline at end of file diff --git a/src/test/resources/epub3/08-layout/files/content-reflow-xhtml-viewport-height-missing-valid/META-INF/container.xml b/src/test/resources/epub3/08-layout/files/content-reflow-xhtml-viewport-height-missing-valid/META-INF/container.xml new file mode 100644 index 000000000..318782179 --- /dev/null +++ b/src/test/resources/epub3/08-layout/files/content-reflow-xhtml-viewport-height-missing-valid/META-INF/container.xml @@ -0,0 +1,6 @@ + + + + + + diff --git a/src/test/resources/epub3/08-layout/files/content-reflow-xhtml-viewport-height-missing-valid/mimetype b/src/test/resources/epub3/08-layout/files/content-reflow-xhtml-viewport-height-missing-valid/mimetype new file mode 100644 index 000000000..57ef03f24 --- /dev/null +++ b/src/test/resources/epub3/08-layout/files/content-reflow-xhtml-viewport-height-missing-valid/mimetype @@ -0,0 +1 @@ +application/epub+zip \ No newline at end of file diff --git a/src/test/resources/epub3/08-layout/layout.feature b/src/test/resources/epub3/08-layout/layout.feature index b51d2c9f3..ee1a5cfb1 100644 --- a/src/test/resources/epub3/08-layout/layout.feature +++ b/src/test/resources/epub3/08-layout/layout.feature @@ -207,6 +207,8 @@ Feature: EPUB 3 — Layout Rendering Control #### 8.2.2.6 Content document dimensions + ##### Expressing the ICB in XHTML + @spec @xref:sec-fxl-content-dimensions Scenario: Verify a fixed-layout XHTML document with a valid viewport When checking EPUB 'content-fxl-xhtml-viewport-valid' @@ -222,11 +224,6 @@ Feature: EPUB 3 — Layout Rendering Control When checking EPUB 'content-fxl-xhtml-viewport-keywords-valid' Then no errors or warnings are reported - @spec @xref:sec-fxl-content-dimensions - Scenario: Verify a fixed-layout XHTML document with multiple viewport meta tags - When checking EPUB 'content-fxl-xhtml-viewport-multiple-valid' - Then no errors or warnings are reported - @spec @xref:sec-fxl-content-dimensions Scenario: Report a fixed-layout XHTML document with no viewport When checking EPUB 'content-fxl-xhtml-viewport-missing-error' @@ -240,9 +237,9 @@ Feature: EPUB 3 — Layout Rendering Control And no other errors or warnings are reported @spec @xref:sec-fxl-content-dimensions - Scenario: Report a fixed-layout XHTML document with a viewport using units - When checking EPUB 'content-fxl-xhtml-viewport-units-invalid-error' - Then error HTM-057 is reported 2 times + Scenario: Report a single fixed-layout XHTML document with an invalid viewport in a reflowable publication + When checking EPUB 'content-fxl-item-xhtml-viewport-invalid-error' + Then error HTM-047 is reported And no other errors or warnings are reported @spec @xref:sec-fxl-content-dimensions @@ -252,17 +249,47 @@ Feature: EPUB 3 — Layout Rendering Control And no other errors or warnings are reported @spec @xref:sec-fxl-content-dimensions - Scenario: Report a fixed-layout XHTML document with a viewport missing the height value + Scenario: Report a fixed-layout XHTML document with a viewport with no width + When checking EPUB 'content-fxl-xhtml-viewport-width-missing-error' + Then error HTM-056 is reported + And no other errors or warnings are reported + + @spec @xref:sec-fxl-content-dimensions + Scenario: Report a fixed-layout XHTML document with a viewport with an empty height value When checking EPUB 'content-fxl-xhtml-viewport-height-empty-error' - Then error HTM-047 is reported + Then error HTM-057 is reported And no other errors or warnings are reported @spec @xref:sec-fxl-content-dimensions - Scenario: Report a single fixed-layout XHTML document with an invalid viewport in a reflowable publication - When checking EPUB 'content-fxl-item-xhtml-viewport-invalid-error' - Then error HTM-047 is reported + Scenario: Report a fixed-layout XHTML document with a viewport using units + When checking EPUB 'content-fxl-xhtml-viewport-units-invalid-error' + Then error HTM-057 is reported 2 times And no other errors or warnings are reported - + + @spec @xref:sec-fxl-content-dimensions + Scenario: Report a fixed-layout XHTML document with duplicate width/height in a single viewport meta tag + When checking EPUB 'content-fxl-xhtml-viewport-duplicate-width-height-error' + Then error HTM-059 is reported 2 times (1 for width, 1 for height) + And no other errors or warnings are reported + + @spec @xref:sec-fxl-content-dimensions + Scenario: Do not check more than one viewport meta tag in a fixed-layout document (but report as usage) + Given the reporting level is set to usage + When checking EPUB 'content-fxl-xhtml-viewport-multiple-usage-valid' + Then usage HTM-060a is reported 2 times + But no other usages are reported + And no errors or warnings are reported + + @spec @xref:sec-fxl-content-dimensions + Scenario: Do not check viewport metadata in reflowable content documents (but report as usage) + Given the reporting level is set to usage + When checking EPUB 'content-reflow-xhtml-viewport-height-missing-valid' + Then usage HTM-060b is reported + But no other usages are reported + And no errors or warnings are reported + + ##### Expressing the ICB in SVG + Scenario: Verify that the initial containing block rules are not checked on embedded svg elements When checking EPUB 'content-fxl-svg-no-viewbox-on-inner-svg-valid' Then no errors or warnings are reported diff --git a/src/test/resources/epub3/F-viewport-meta-tag/viewport-syntax.feature b/src/test/resources/epub3/F-viewport-meta-tag/viewport-syntax.feature index 1eb7c7c65..ef6474c89 100644 --- a/src/test/resources/epub3/F-viewport-meta-tag/viewport-syntax.feature +++ b/src/test/resources/epub3/F-viewport-meta-tag/viewport-syntax.feature @@ -3,47 +3,56 @@ Feature: Viewport meta tag syntax Tests the parser for the viewport meta tag syntax as defined in EPUB 3.3: https://www.w3.org/TR/epub-33/#app-viewport-meta-syntax - + Scenario Outline: parsing valid viewport values When parsing viewport Then no error is returned + And the parsed viewport equals Scenarios: - | viewport | - | "width=1200, height=600" | - | "p1=value" | - | " p1 = value " | - | " p1 = value " | - | "p1 = value" | - | "p1=value,p2=value" | - | "p1=value;p2=value" | - | "p1=value,,,p2=value" | - | "p1=value;;;p2=value" | - | "p1=value p2=value" | - | "p1=value, ;p2=value" | - | "p1=value,p2=value,p3=value" | + | viewport | result | + | "width=1200, height=600" | "width=1200;height=600" | + # single values + | "p1=v1" | "p1=v1" | + | " p1 = v1 " | "p1=v1" | + | " p1 = v1 " | "p1=v1" | + | "p1 = v1" | "p1=v1" | + # separators + | "p1=v1,p2=v2" | "p1=v1;p2=v2" | + | "p1=v1;p2=v2" | "p1=v1;p2=v2" | + | "p1=v1,,,p2=v2" | "p1=v1;p2=v2" | + | "p1=v1;;;p2=v2" | "p1=v1;p2=v2" | + | "p1=v1 p2=v2" | "p1=v1;p2=v2" | + | "p1=v1, ;p2=v2" | "p1=v1;p2=v2" | + | "p1=v1,p2=v2,p3=v3" | "p1=v1;p2=v2;p3=v3" | + # value-less names + | "p1" | "p1=" | + | "p1 " | "p1=" | + | "p1,p2=v2" | "p1=;p2=v2" | + | "p1 ,p2=v2" | "p1=;p2=v2" | + | "p1=v1,p2" | "p1=v1;p2=" | + | "p1=v1 p2" | "p1=v1;p2=" | + # multiple values + | "p1=v1a,p1=v1b" | "p1=v1a,v1b" | + | "p1=v1a,p2=v2,p1=v1b" | "p1=v1a,v1b;p2=v2" | Scenario Outline: parsing invalid viewport values When parsing viewport Then error is returned Scenarios: - | viewport | error | - | "" | NULL_OR_EMPTY | - | "p1==value" | ASSIGN_UNEXPECTED | - | "p1=value=value" | ASSIGN_UNEXPECTED | - | "p1" | VALUE_EMPTY | - | "p1 value" | VALUE_EMPTY | - | "p1=value value" | VALUE_EMPTY | - | "p1,p2=value" | VALUE_EMPTY | - | "p1=value,p2" | VALUE_EMPTY | - | "p1=" | VALUE_EMPTY | - | "p1= " | VALUE_EMPTY | - | "p1=value,p2=" | VALUE_EMPTY | - | "=value" | NAME_EMPTY | - | "p1=value,=value" | NAME_EMPTY | - | "p1=value, =value" | NAME_EMPTY | - | ",p1=value" | LEADING_SEPARATOR | - | ";p1=value" | LEADING_SEPARATOR | - | "p1=value," | TRAILING_SEPARATOR | - | "p1=value;" | TRAILING_SEPARATOR | + | viewport | error | + | "" | NULL_OR_EMPTY | + | "p1==v1" | ASSIGN_UNEXPECTED | + | "p1=v1=v" | ASSIGN_UNEXPECTED | + | "p1 v1" | VALUE_EMPTY | + | "p1=" | VALUE_EMPTY | + | "p1= " | VALUE_EMPTY | + | "p1=v1,p2=" | VALUE_EMPTY | + | "=value" | NAME_EMPTY | + | "p1=v1,=v" | NAME_EMPTY | + | "p1=v1, =v" | NAME_EMPTY | + | ",p1=v1" | LEADING_SEPARATOR | + | ";p1=v1" | LEADING_SEPARATOR | + | "p1=v1," | TRAILING_SEPARATOR | + | "p1=v1;" | TRAILING_SEPARATOR |