Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
23 changes: 23 additions & 0 deletions pkg/manifest/a11y.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ type A11y struct {
AccessModesSufficient [][]A11yPrimaryAccessMode `json:"accessModeSufficient,omitempty"` // A list of single or combined accessModes that are sufficient to understand all the intellectual content of a resource.
Features []A11yFeature `json:"feature,omitempty"` // Content features of the resource, such as accessible media, alternatives and supported enhancements for accessibility.
Hazards []A11yHazard `json:"hazard,omitempty"` // A characteristic of the described resource that is physiologically dangerous to some users.
Exemptions []A11yExemption `json:"exemption,omitempty"` // Justifications for non-conformance based on exemptions in a given jurisdiction.
}

// NewA11y creates a new empty A11y.
Expand All @@ -29,6 +30,7 @@ func NewA11y() A11y {
AccessModesSufficient: [][]A11yPrimaryAccessMode{},
Features: []A11yFeature{},
Hazards: []A11yHazard{},
Exemptions: []A11yExemption{},
}
}

Expand Down Expand Up @@ -130,6 +132,12 @@ func A11yFromJSON(rawJSON map[string]interface{}) (*A11y, error) {
}
a.Hazards = A11yHazardsFromStrings(hazards)

examptions, err := parseSliceOrString(rawJSON["exemption"], true)
if err != nil {
return nil, errors.Wrap(err, "failed unmarshalling 'exemption'")
}
a.Exemptions = A11yExemptionsFromStrings(examptions)

return a, nil
}

Expand Down Expand Up @@ -433,6 +441,21 @@ func A11yHazardsFromStrings(strings []string) []A11yHazard {
})
}

// A11yExemption is a justification for non-conformance based on an exemption in a given jurisdiction.
type A11yExemption string

const (
A11yExemptionEAASisproportionateBurden A11yExemption = "eaa-disproportionate-burden"
A11yExemptionEAAFundamentalAlteration A11yExemption = "eaa-fundamental-alteration"
A11yExemptionEAAMicroenterprise A11yExemption = "eaa-microenterprise"
)

func A11yExemptionsFromStrings(strings []string) []A11yExemption {
return fromStrings(strings, func(str string) A11yExemption {
return A11yExemption(str)
})
}

func fromStrings[T any](strings []string, transform func(string) T) []T {
res := make([]T, 0, len(strings))
for _, s := range strings {
Expand Down
14 changes: 12 additions & 2 deletions pkg/manifest/a11y_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,8 @@ func TestA11yUnmarshalFullJSON(t *testing.T) {
"accessMode": ["auditory", "chartOnVisual"],
"accessModeSufficient": [["visual", "tactile"]],
"feature": ["readingOrder", "alternativeText"],
"hazard": ["flashing", "motionSimulation"]
"hazard": ["flashing", "motionSimulation"],
"exemption": ["eaa-fundamental-alteration", "eaa-microenterprise"]
}`), &m))
assert.Equal(t, A11y{
ConformsTo: []A11yProfile{
Expand Down Expand Up @@ -57,6 +58,10 @@ func TestA11yUnmarshalFullJSON(t *testing.T) {
A11yHazardFlashing,
A11yHazardMotionSimulation,
},
Exemptions: []A11yExemption{
A11yExemptionEAAFundamentalAlteration,
A11yExemptionEAAMicroenterprise,
},
}, m, "unmarshalled JSON object should be equal to A11y object")
}

Expand Down Expand Up @@ -101,6 +106,7 @@ func TestA11yMarshalMinimalJSON(t *testing.T) {
AccessModesSufficient: [][]A11yPrimaryAccessMode{},
Features: []A11yFeature{},
Hazards: []A11yHazard{},
Exemptions: []A11yExemption{},
}
data, err := json.Marshal(m)
assert.NoError(t, err)
Expand Down Expand Up @@ -139,12 +145,16 @@ func TestA11yMarshalFullJSON(t *testing.T) {
A11yHazardFlashing,
A11yHazardMotionSimulation,
},
Exemptions: []A11yExemption{
A11yExemptionEAAFundamentalAlteration,
A11yExemptionEAAMicroenterprise,
},
}
data, err := json.Marshal(m)
assert.NoError(t, err)
assert.Equal(
t,
data,
[]byte(`{"conformsTo":["http://www.idpf.org/epub/a11y/accessibility-20170105.html#wcag-a","https://profile2"],"certification":{"certifiedBy":"company1","credential":"credential1","report":"https://report1"},"summary":"Summary","accessMode":["auditory","chartOnVisual"],"accessModeSufficient":[["auditory"],["visual","tactile"],["visual"]],"feature":["readingOrder","alternativeText"],"hazard":["flashing","motionSimulation"]}`),
[]byte(`{"conformsTo":["http://www.idpf.org/epub/a11y/accessibility-20170105.html#wcag-a","https://profile2"],"certification":{"certifiedBy":"company1","credential":"credential1","report":"https://report1"},"summary":"Summary","accessMode":["auditory","chartOnVisual"],"accessModeSufficient":[["auditory"],["visual","tactile"],["visual"]],"feature":["readingOrder","alternativeText"],"hazard":["flashing","motionSimulation"],"exemption":["eaa-fundamental-alteration","eaa-microenterprise"]}`),
)
}
10 changes: 10 additions & 0 deletions pkg/parser/epub/metadata.go
Original file line number Diff line number Diff line change
Expand Up @@ -646,6 +646,7 @@ func (m PubMetadataAdapter) Accessibility() *manifest.A11y {
a11y.AccessModesSufficient = m.a11yAccessModesSufficient()
a11y.Features = m.a11yFeatures()
a11y.Hazards = m.a11yHazards()
a11y.Exemptions = m.a11yExemptions()

if a11y.IsEmpty() {
return nil
Expand Down Expand Up @@ -785,6 +786,15 @@ func (m PubMetadataAdapter) a11yHazards() []manifest.A11yHazard {
return hazards
}

func (m PubMetadataAdapter) a11yExemptions() []manifest.A11yExemption {
values := m.Values(VocabularyA11Y + "exemption")
hazards := make([]manifest.A11yExemption, len(values))
for i, v := range values {
hazards[i] = manifest.A11yExemption(v)
}
return hazards
}

func (m *PubMetadataAdapter) seedBelongsToData() {
if m._belongsToSeeded {
return
Expand Down
2 changes: 2 additions & 0 deletions pkg/parser/epub/metadata_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -323,6 +323,7 @@ func TestMetadataEPUB2Accessibility(t *testing.T) {
}
e.Features = []manifest.A11yFeature{manifest.A11yFeatureStructuralNavigation, manifest.A11yFeatureAlternativeText}
e.Hazards = []manifest.A11yHazard{manifest.A11yHazardMotionSimulation, manifest.A11yHazardNoSoundHazard}
e.Exemptions = []manifest.A11yExemption{manifest.A11yExemptionEAAMicroenterprise, manifest.A11yExemptionEAAFundamentalAlteration}
assert.Equal(t, &e, m.Accessibility)
assert.Nil(t, m.OtherMetadata["accessibility"])
}
Expand All @@ -345,6 +346,7 @@ func TestMetadataEPUB3Accessibility(t *testing.T) {
}
e.Features = []manifest.A11yFeature{manifest.A11yFeatureStructuralNavigation, manifest.A11yFeatureAlternativeText}
e.Hazards = []manifest.A11yHazard{manifest.A11yHazardMotionSimulation, manifest.A11yHazardNoSoundHazard}
e.Exemptions = []manifest.A11yExemption{manifest.A11yExemptionEAAMicroenterprise, manifest.A11yExemptionEAAFundamentalAlteration}
assert.Equal(t, &e, m.Accessibility)
assert.Nil(t, m.OtherMetadata["accessibility"])
}
Expand Down
3 changes: 3 additions & 0 deletions pkg/parser/epub/testdata/package/accessibility-epub2.opf
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,9 @@
<meta name="a11y:certifiedBy" content="Accessibility Testers Group"/>
<meta name="a11y:certifierCredential" content="DAISY OK"/>
<meta name="a11y:certifierReport" content="https://example.com/a11y-report/"/>

<meta property="a11y:exemption">eaa-microenterprise</meta>
<meta property="a11y:exemption">eaa-fundamental-alteration</meta>
</metadata>
<manifest>
<item id="titlepage" href="titlepage.xhtml"/>
Expand Down
3 changes: 3 additions & 0 deletions pkg/parser/epub/testdata/package/accessibility-epub3.opf
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,9 @@
<link rel="a11y:certifierReport" refines="#certifier2" href="https://example.com/fakereport"/>
<link rel="a11y:certifierReport" refines="#certifier" href="https://example.com/a11y-report/"/>

<meta property="a11y:exemption">eaa-microenterprise</meta>
<meta property="a11y:exemption">eaa-fundamental-alteration</meta>

</metadata>
<manifest>
<item id="titlepage" href="titlepage.xhtml"/>
Expand Down