Skip to content

Commit 6a58b8e

Browse files
committed
feat: better check media overlays styling properties
- report schema error RSC-005 when the 'media:active-class' or 'media:playback-active-class' properties are declared more than once. - report schema error RSC-005 when the 'media:active-class' or 'media:playback-active-class' properties define more than once class names. - report new usage CSS-029 when a CSS selector is found referring to the widely-used '-epub-media-overlay-active' or '-epub-media-overlay- playing' class names but no 'media:active-class' or 'media:playback- active-class' properties were declared in the package document. - report new error CSS-030 when the 'media:active-class' or 'media:playback-active-class' properties are declared but no CSS is found in a content document with media overlays. - added various test scenarios for the checks described above. Closs #1218.
1 parent 01a7758 commit 6a58b8e

File tree

54 files changed

+581
-5
lines changed

Some content is hidden

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

54 files changed

+581
-5
lines changed

src/main/java/com/adobe/epubcheck/css/CSSHandler.java

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,9 @@
99
import org.idpf.epubcheck.util.css.CssContentHandler;
1010
import org.idpf.epubcheck.util.css.CssErrorHandler;
1111
import org.idpf.epubcheck.util.css.CssExceptions.CssException;
12+
import org.idpf.epubcheck.util.css.CssGrammar;
1213
import org.idpf.epubcheck.util.css.CssGrammar.CssAtRule;
14+
import org.idpf.epubcheck.util.css.CssGrammar.CssComposedConstruct;
1315
import org.idpf.epubcheck.util.css.CssGrammar.CssConstruct;
1416
import org.idpf.epubcheck.util.css.CssGrammar.CssDeclaration;
1517
import org.idpf.epubcheck.util.css.CssGrammar.CssSelector;
@@ -201,6 +203,43 @@ public void endAtRule(String name)
201203
@Override
202204
public void selectors(List<CssSelector> selectors)
203205
{
206+
for (CssSelector selector : selectors)
207+
{
208+
if (!context.featureReport.hasFeature(FeatureEnum.MEDIA_OVERLAYS_ACTIVE_CLASS)
209+
&& findClassName(selector, ".-epub-media-overlay-active"))
210+
{
211+
report.message(MessageId.CSS_029,
212+
getCorrectedEPUBLocation(selector.getLocation().getLine(),
213+
selector.getLocation().getColumn(), selector.toCssString()),
214+
"-epub-media-overlay-active", "media:active-class");
215+
}
216+
if (!context.featureReport.hasFeature(FeatureEnum.MEDIA_OVERLAYS_PLAYBACK_ACTIVE_CLASS)
217+
&& findClassName(selector, ".-epub-media-overlay-playing"))
218+
{
219+
report.message(MessageId.CSS_029,
220+
getCorrectedEPUBLocation(selector.getLocation().getLine(),
221+
selector.getLocation().getColumn(), selector.toCssString()),
222+
"-epub-media-overlay-playing", "media:playback-active-class");
223+
}
224+
}
225+
}
226+
227+
private boolean findClassName(CssConstruct construct, String name)
228+
{
229+
if (construct.getType() == CssGrammar.CssConstruct.Type.CLASSNAME
230+
&& name.equals(construct.toCssString()))
231+
{
232+
return true;
233+
234+
}
235+
else if (construct instanceof CssComposedConstruct)
236+
{
237+
for (CssConstruct component : ((CssComposedConstruct) construct).getComponents())
238+
{
239+
if (findClassName(component, name)) return true;
240+
}
241+
}
242+
return false;
204243
}
205244

206245
@Override

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

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -91,6 +91,8 @@ private void initialize()
9191
severities.put(MessageId.CSS_024, Severity.SUPPRESSED);
9292
severities.put(MessageId.CSS_025, Severity.SUPPRESSED);
9393
severities.put(MessageId.CSS_028, Severity.USAGE);
94+
severities.put(MessageId.CSS_029, Severity.USAGE);
95+
severities.put(MessageId.CSS_030, Severity.ERROR);
9496

9597
// HTML
9698
severities.put(MessageId.HTM_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
@@ -85,6 +85,8 @@ public enum MessageId implements Comparable<MessageId>
8585
CSS_024("CSS-024"),
8686
CSS_025("CSS-025"),
8787
CSS_028("CSS-028"),
88+
CSS_029("CSS-029"),
89+
CSS_030("CSS-030"),
8890

8991
// Messages relating to xhtml markup
9092
HTM_001("HTM-001"),

src/main/java/com/adobe/epubcheck/opf/OPFHandler30.java

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -566,6 +566,24 @@ private void processMeta()
566566
{
567567
metadataBuilders.peekFirst().meta(e.getAttribute("id"), prop.get(),
568568
(String) e.getPrivateData(), e.getAttribute("refines"));
569+
570+
// Primary metadata checks
571+
if (metadataBuilders.size() == 1)
572+
{
573+
switch (prop.get().getPrefixedName())
574+
{
575+
case "media:active-class":
576+
context.featureReport.report(FeatureEnum.MEDIA_OVERLAYS_ACTIVE_CLASS, location(),
577+
e.getPrivateData().toString());
578+
break;
579+
case "media:playback-active-class":
580+
context.featureReport.report(FeatureEnum.MEDIA_OVERLAYS_PLAYBACK_ACTIVE_CLASS, location(),
581+
e.getPrivateData().toString());
582+
break;
583+
default:
584+
break;
585+
}
586+
}
569587
}
570588

571589
// just parse the scheme for vocab errors

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

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,7 @@ public class OPSHandler extends XMLHandler
5151
protected boolean hasTh = false;
5252
protected boolean hasThead = false;
5353
protected boolean hasCaption = false;
54+
protected boolean hasCSS = false;
5455
protected boolean epubTypeInUse = false;
5556
protected StringBuilder textNode;
5657
protected Stack<EPUBLocation> elementLocationStack = new Stack<EPUBLocation>();
@@ -94,10 +95,13 @@ protected void checkLink()
9495
XMLElement e = currentElement();
9596
URL href = checkURL(e.getAttribute("href"));
9697
String rel = e.getAttribute("rel");
97-
if (xrefChecker.isPresent() && href != null && rel != null
98+
if (href != null && rel != null
9899
&& rel.toLowerCase(Locale.ROOT).contains("stylesheet"))
99100
{
100-
xrefChecker.get().registerReference(href, XRefChecker.Type.STYLESHEET, location());
101+
this.hasCSS = true;
102+
if (xrefChecker.isPresent()) {
103+
xrefChecker.get().registerReference(href, XRefChecker.Type.STYLESHEET, location());
104+
}
101105
}
102106
}
103107

@@ -365,6 +369,7 @@ public void endElement()
365369
String style = textNode.toString();
366370
if (style.length() > 0)
367371
{
372+
this.hasCSS = true;
368373
new CSSChecker(context, style, currentLocation.getLine(), false).check();
369374
}
370375
textNode = null;

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

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -815,6 +815,7 @@ public void endElement()
815815
String name = e.getName();
816816
if (openElements == 0 && (name.equals("html") || name.equals("svg")))
817817
{
818+
checkOverlaysStyles();
818819
checkProperties();
819820
}
820821
else if (name.equals("object"))
@@ -902,6 +903,17 @@ protected void checkFallback(String elementType)
902903
}
903904
}
904905

906+
protected void checkOverlaysStyles()
907+
{
908+
if (context.opfItem.isPresent() && context.opfItem.get().getMediaOverlay() != null
909+
&& (context.featureReport.hasFeature(FeatureEnum.MEDIA_OVERLAYS_ACTIVE_CLASS)
910+
|| context.featureReport.hasFeature(FeatureEnum.MEDIA_OVERLAYS_PLAYBACK_ACTIVE_CLASS))
911+
&& !this.hasCSS)
912+
{
913+
report.message(MessageId.CSS_030, location());
914+
}
915+
}
916+
905917
protected void checkProperties()
906918
{
907919
if (!context.container.isPresent()) // single file validation

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

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,8 @@ public enum FeatureEnum
6464
LOI("list of illustrations"),
6565
LOT("list of tables"),
6666
LOV("list of videos"),
67+
MEDIA_OVERLAYS_ACTIVE_CLASS("media:active-class"),
68+
MEDIA_OVERLAYS_PLAYBACK_ACTIVE_CLASS("media:playback-active-class"),
6769
MODIFIED_DATE("modification date"),
6870
NAVIGATION_ORDER("navigation order"),
6971
PAGE_BREAK("epub:page-break"),

src/main/java/org/idpf/epubcheck/util/css/CssGrammar.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -130,7 +130,7 @@ public enum Type
130130
/**
131131
* A CssConstruct that is composed by a single token.
132132
*/
133-
static abstract class CssAtomicConstruct extends CssConstruct
133+
public static abstract class CssAtomicConstruct extends CssConstruct
134134
{
135135
final String value;
136136

@@ -434,7 +434,7 @@ public String toString()
434434
* A CssConstruct that is composed a list of atomic and/or composed CssConstructs,
435435
* and optionally a name.
436436
*/
437-
static abstract class CssComposedConstruct extends CssConstruct
437+
public static abstract class CssComposedConstruct extends CssConstruct
438438
{
439439
final List<CssConstruct> components;
440440
final Optional<String> name;

src/main/resources/com/adobe/epubcheck/messages/MessageBundle.properties

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,8 @@ CSS_024_SUG=Remove unused CSS selectors.
6767
CSS_025=CSS class Selector could not be found.
6868
CSS_025_SUG=Check for typos or define a class selector to document the use of the class.
6969
CSS_028=Use of Font-face declaration.
70+
CSS_029=Found CSS class name "%1$s" but no "%2$s" property was declared in the package document.
71+
CSS_030=The package document declares media overlays styling class names but no CSS was found in the content document.
7072

7173
#HTM - XHTML related messages
7274
HTM_001=Any publication resource that is an XML-based media type must be a valid XML 1.0 document. XML version found: %1$s.

src/main/resources/com/adobe/epubcheck/schema/30/package-30.sch

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -417,14 +417,24 @@
417417
</pattern>
418418

419419
<pattern id="opf.media.overlay.metadata.active-class">
420+
<rule context="opf:package/opf:metadata">
421+
<assert test="count(opf:meta[normalize-space(@property)='media:active-class']) le 1">The 'active-class' property must not occur more than one time in the package
422+
metadata.</assert>
423+
</rule>
420424
<rule context="opf:meta[normalize-space(@property)='media:active-class']">
421425
<report test="@refines"> @refines must not be used with the media:active-class property</report>
426+
<report test="contains(normalize-space(.),' ')">the 'active-class' property must define a single class name</report>
422427
</rule>
423428
</pattern>
424429

425430
<pattern id="opf.media.overlay.metadata.playback-active-class">
431+
<rule context="opf:package/opf:metadata">
432+
<assert test="count(opf:meta[normalize-space(@property)='media:playback-active-class']) le 1">The 'playback-active-class' property must not occur more than one time in the package
433+
metadata.</assert>
434+
</rule>
426435
<rule context="opf:meta[normalize-space(@property)='media:playback-active-class']">
427436
<report test="@refines"> @refines must not be used with the media:playback-active-class property</report>
437+
<report test="contains(normalize-space(.),' ')">the 'playback-active-class' property must define a single class name</report>
428438
</rule>
429439
</pattern>
430440

0 commit comments

Comments
 (0)