Skip to content

Commit 01a7758

Browse files
committed
feat: check the formal viewport meta tag syntax
- `HTM-047` is now reported for invalid `viewport` values - new `HTM-056` is reported when a `viewport` value has no `width` or `height` - new `HTM-057` is reported when a viewport width or height value is invalid (i.e. not a positive number or a well-known kewyword) Also: - the `isASCIIWhitespace` static utility method is extraced to a public `InfraUtil` class in a new `org.w3c.epubcheck.util.infra` package - the viewport parser is tested as a standalone class in its own feature file. However, for easier lookup, this file is however located in the `epub3/F-viewport-meta-tag` directory, as if it was a functional test. - several additional functional tests are added to the `epub3/08-layout` directory, for viewport metadata checks. Fixes #1214, fixes #1347
1 parent 39f97a4 commit 01a7758

File tree

55 files changed

+901
-23
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

55 files changed

+901
-23
lines changed

src/main/java/com/adobe/epubcheck/messages/DefaultSeverities.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -137,6 +137,8 @@ private void initialize()
137137
severities.put(MessageId.HTM_053, Severity.INFO);
138138
severities.put(MessageId.HTM_054, Severity.ERROR);
139139
severities.put(MessageId.HTM_055, Severity.WARNING);
140+
severities.put(MessageId.HTM_056, Severity.ERROR);
141+
severities.put(MessageId.HTM_057, Severity.ERROR);
140142

141143
// Media
142144
severities.put(MessageId.MED_001, Severity.ERROR);

src/main/java/com/adobe/epubcheck/messages/MessageId.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -131,6 +131,8 @@ public enum MessageId implements Comparable<MessageId>
131131
HTM_053("HTM_053"),
132132
HTM_054("HTM_054"),
133133
HTM_055("HTM_055"),
134+
HTM_056("HTM_056"),
135+
HTM_057("HTM_057"),
134136

135137
// Messages associated with media (images, audio and video)
136138
MED_001("MED-001"),

src/main/java/com/adobe/epubcheck/ops/OPSHandler30.java

Lines changed: 46 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
import java.util.Collections;
44
import java.util.EnumSet;
55
import java.util.HashSet;
6+
import java.util.LinkedList;
67
import java.util.List;
78
import java.util.Locale;
89
import java.util.Map;
@@ -11,6 +12,9 @@
1112
import java.util.regex.Matcher;
1213
import java.util.regex.Pattern;
1314

15+
import org.w3c.epubcheck.util.microsyntax.ViewportMeta;
16+
import org.w3c.epubcheck.util.microsyntax.ViewportMeta.ParseError;
17+
1418
import com.adobe.epubcheck.api.EPUBLocation;
1519
import com.adobe.epubcheck.api.EPUBProfile;
1620
import com.adobe.epubcheck.messages.MessageId;
@@ -701,19 +705,55 @@ protected void processMeta()
701705
if (EpubConstants.HtmlNamespaceUri.equals(e.getNamespace()))
702706
{
703707
String name = e.getAttribute("name");
704-
if ("viewport".equals(name))
708+
if ("viewport".equals(Strings.nullToEmpty(name).trim()))
705709
{
710+
// Mark the viewport as seen
711+
// (used when checking the existence of viewport metadata)
706712
hasViewport = true;
707-
// For a fixed-layout document:
708-
// check that the vieport declares both height and width
713+
// For a fixed-layout documents:
709714
if (context.opfItem.isPresent() && context.opfItem.get().isFixedLayout())
710715
{
711716
String contentAttribute = e.getAttribute("content");
712-
if (contentAttribute == null || !contentAttribute.contains("width=")
713-
|| !contentAttribute.contains("height="))
717+
718+
// parse viewport metadata
719+
List<ViewportMeta.ParseError> syntaxErrors = new LinkedList<>();
720+
ViewportMeta viewport = ViewportMeta.parse(contentAttribute,
721+
new ViewportMeta.ErrorHandler()
722+
{
723+
@Override
724+
public void error(ParseError error, int position)
725+
{
726+
syntaxErrors.add(error);
727+
}
728+
});
729+
if (!syntaxErrors.isEmpty())
730+
{
731+
// report any syntax error
732+
report.message(MessageId.HTM_047, location(), contentAttribute);
733+
}
734+
else
714735
{
715-
report.message(MessageId.HTM_047, location());
736+
// check that viewport metadata has a valid width value
737+
if (!viewport.hasProperty("width"))
738+
{
739+
report.message(MessageId.HTM_056, location(), "width");
740+
}
741+
else if (!ViewportMeta.isValidWidth(viewport.getValue("width")))
742+
{
743+
report.message(MessageId.HTM_057, location(), "width");
744+
}
745+
746+
// check that viewport metadata has a valid height value
747+
if (!viewport.hasProperty("height"))
748+
{
749+
report.message(MessageId.HTM_056, location(), "height");
750+
}
751+
else if (!ViewportMeta.isValidHeight(viewport.getValue("height")))
752+
{
753+
report.message(MessageId.HTM_057, location(), "height");
754+
}
716755
}
756+
717757
}
718758
}
719759
}

src/main/java/com/adobe/epubcheck/util/SourceSet.java

Lines changed: 5 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,14 @@
11
package com.adobe.epubcheck.util;
22

3+
import static org.w3c.epubcheck.util.infra.InfraUtil.isASCIIWhitespace;
4+
35
import java.nio.CharBuffer;
46
import java.util.LinkedList;
57
import java.util.List;
68
import java.util.regex.Pattern;
79

10+
import org.w3c.epubcheck.util.infra.InfraUtil;
11+
812
import com.google.common.base.Function;
913
import com.google.common.base.Optional;
1014
import com.google.common.base.Preconditions;
@@ -162,7 +166,7 @@ public SourceSet parse(CharSequence srcset)
162166
{
163167
case SPLIT:
164168
assert (url.length() == 0);
165-
if (isASCIIWhitespace(c))
169+
if (InfraUtil.isASCIIWhitespace(c))
166170
{
167171
// skip whitespace
168172
}
@@ -271,15 +275,6 @@ else if (c == '(')
271275
return builder.build();
272276
}
273277

274-
/**
275-
* if a character is https://infra.spec.whatwg.org/#ascii-whitespace U+0009 TAB,
276-
* U+000A LF, U+000C FF, U+000D CR, or U+0020 SPACE.
277-
*/
278-
private static boolean isASCIIWhitespace(char c)
279-
{
280-
return c == ' ' || c == '\t' || c == '\f' || c == '\n' || c == '\r';
281-
}
282-
283278
/**
284279
* Remove trailing commas and return the count of commas removed
285280
*/
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
package org.w3c.epubcheck.util.infra;
2+
3+
public final class InfraUtil
4+
{
5+
6+
private InfraUtil()
7+
{
8+
// static utility class
9+
}
10+
11+
/**
12+
* if a character is https://infra.spec.whatwg.org/#ascii-whitespace U+0009
13+
* TAB, U+000A LF, U+000C FF, U+000D CR, or U+0020 SPACE.
14+
*/
15+
public static boolean isASCIIWhitespace(char c)
16+
{
17+
return c == ' ' || c == '\t' || c == '\f' || c == '\n' || c == '\r';
18+
}
19+
}

0 commit comments

Comments
 (0)