$30 off During Our Annual Pro Sale. View Details »

アクセシビリティチェックを自動化するためのmarkuplintのロードマップ

 アクセシビリティチェックを自動化するためのmarkuplintのロードマップ

Accessibility Step Vol.01

Yusuke Hirao

August 10, 2018
Tweet

More Decks by Yusuke Hirao

Other Decks in Programming

Transcript

  1. ΞΫηγϏϦςΟνΣοΫΛࣗಈԽ͢ΔͨΊͷ
    NBSLVQMJOUͷϩʔυϚοϓ
    "DDFTTJCJMJUZ4UFQ7PM

    View Slide

  2. ©2018 Yusuke Hirao
    ࣗݾ঺հ
    ฏඌ༏యʢͻΒ͓Ώ͏ͯΜʣ
    גࣜձࣾσΟʔθϩ
    ϑϩϯτΤϯυΤϯδχΞ
    #-0(IUUQTOPUFNVZVTVLFIJSBP
    Yusuke Hirao
    @cloud10designs

    View Slide

  3. ©2018 Yusuke Hirao
    ΞΫηγϏϦςΟνΣοΫΛࣗಈԽ͢ΔͨΊͷ
    NBSLVQMJOUͷϩʔυϚοϓ

    View Slide

  4. ©2018 Yusuke Hirao
    ࠓ೔͸ͪΐͬͱϑϩϯτدΓͷ
    ٕज़Ϊδϡπͨ͠࿩Ͱ͢

    View Slide

  5. ©2018 Yusuke Hirao
    NBSLVQMJOU͝ଘ஌ͷํ✋

    View Slide

  6. ©2018 Yusuke Hirao
    &4-JOUɾTUZMFMJOU͝ଘ஌ͷํ✋

    View Slide

  7. ©2018 Yusuke Hirao
    -JOUFSͱ͸
    қ͘͠આ໌͢Δͱ
    ίʔυΛղੳͯ͠ɺ
    ϧʔϧʹଇͬͯͳ͍෦෼Λࢦఠ͢ΔπʔϧͰ͢ɻ

    View Slide

  8. ©2018 Yusuke Hirao
    )5.-ͷ-JOUFS
    Φʔϓϯιʔε/PEFKT੡)5.--JOUFS

    View Slide

  9. ©2018 Yusuke Hirao
    )5.-ͷ-JOUFS
    ͖͔͚ͬ
    IUUQTTQFBLFSEFDLDPNZVTVLFIJSBPLPEPSFCJZVOBOUFTJUFSBSFSVLBUV

    View Slide

  10. ©2018 Yusuke Hirao
    )5.-ͷ-JOUFS
    ͓͔͛͞·Ͱ4UBS௒͑·ͨ͠

    View Slide

  11. ©2018 Yusuke Hirao
    ։ൃ్্ ݱࡏW

    ʹ΋ؔΘΒͣ
    ஫໨͍͍ͨͩͯຊ౰ʹخ͍͠Ͱ͢

    View Slide

  12. ©2018 Yusuke Hirao
    ͱ͍͏Θ͚Ͱ
    ϩʔυϚοϓ ࠓޙͷ։ൃ༧ఆ
    ͷ͸ͳ͠

    View Slide

  13. ©2018 Yusuke Hirao
    ΞδΣϯμ
    ࠓ೔࿩͢͜ͱ

    ࠓɺͲ͏͍͏ར༻Λ͍ͯ͠Δͷ͔
    ࠓޙɺͲ͏͍͏ར༻Λ͍͔ͨ͠ɾͯ͠΄͍͔͠
    ΞΫηγϏϦςΟνΣοΫͷࣗಈԽʹ͍ͭͯ

    View Slide

  14. ©2018 Yusuke Hirao
    ίʔυ඼࣭νΣοΫ
    ࣾ಺πʔϧͱͯ͠
    ίϚϯυʢλʔϛφϧʣ͔Β
    ΋͘͠͸
    HVMQλεΫ͔Β
    ࠷ۙ—fixΦϓγϣϯ࣮૷͠·ͨ͠
    ࠓɺͲΜͳར༻Λ͍ͯ͠Δͷ͔

    View Slide

  15. ©2018 Yusuke Hirao
    ΤσΟλʔͷػೳͱͯ͠
    7JTVBM4UVEJP$PEF
    "UPN
    7JN
    ʹϓϥάΠϯ͕ఏڙ͞Ε͍ͯΔ
    ࠓɺͲΜͳར༻Λ͍ͯ͠Δͷ͔

    View Slide

  16. ©2018 Yusuke Hirao
    νΣοΫ͍ͯ͠Δ͜ͱ
    ϑΥʔϚοτɾίʔυελΠϧ
    Πϯσϯτ
    εϖʔεɾվߦҐஔ
    ໋໊نଇ
    όϦσʔγϣϯ
    γϯλοΫε
    ن֨
    ඇਪ঑ɾΞϯνύλʔϯ
    ࠓɺͲΜͳར༻Λ͍ͯ͠Δͷ͔

    View Slide

  17. ©2018 Yusuke Hirao
    ΞδΣϯμ
    ࠓ೔࿩͢͜ͱ

    ࠓɺͲ͏͍͏ར༻Λ͍ͯ͠Δͷ͔
    ࠓޙɺͲ͏͍͏ར༻Λ͍͔ͨ͠ɾͯ͠΄͍͔͠
    ΞΫηγϏϦςΟνΣοΫͷࣗಈԽʹ͍ͭͯ

    View Slide

  18. ©2018 Yusuke Hirao
    ࠓޙɺͲ͏͍͏ར༻Λ͍͔ͨ͠ɾͯ͠΄͍͔͠
    NBSLVQMJOUͷϩʔυϚοϓ
    ೥݄WBMQIBΞϧϑΝ൛ύϒϦογϡ
    ೥݄Wਖ਼ࣜ൛ύϒϦογϡ
    ⾣೿ੜπʔϧల։ͷͨΊͷ"1*࣮૷
    ⾣ϓϥάΠϯɾΧελϜϧʔϧͷ"1*࣮૷
    ⾣ΠϯσϯτϑΥʔϚοτɾίʔυελΠϧΛ౷Ұ͢ΔϏϧτΠϯϧʔϧ࣮૷
    ⾣ཁૉɾଐੑνΣοΫ͕࠷௿ݶՄೳͳϏϧτΠϯϧʔϧ࣮૷
    ⾣7JTVBM4UVEJP$PEF֦ுWਖ਼ࣜ൛ύϒϦογϡ
    ೥݄WϚΠφʔόʔδϣϯΞοϓ
    ⾣)5.--JWJOHTUBOEBSEͷόϦσʔγϣϯ͕Ͱ͖ΔϏϧτΠϯϧʔϧ௥Ճ
    ⾣8$8"*"3*"ͷόϦσʔγϣϯ͕Ͱ͖ΔϏϧτΠϯϧʔϧ௥Ճ
    ⾣ϒϥ΢β༻Ϟδϡʔϧ։ൃ
    ೥݄पลϓϥάΠϯ։ൃ
    ⾣)5.-JO+4ʢ5FNQMBUFMJUFSBMʣରԠϓϥάΠϯ
    ⾣QVHରԠϓϥάΠϯ
    ⾣QIQରԠϓϥάΠϯ

    View Slide

  19. ©2018 Yusuke Hirao
    ࠓޙɺͲ͏͍͏ར༻Λ͍͔ͨ͠ɾͯ͠΄͍͔͠
    NBSLVQMJOUͷϩʔυϚοϓ
    ೥݄WBMQIBΞϧϑΝ൛ύϒϦογϡ
    ೥݄Wਖ਼ࣜ൛ύϒϦογϡ
    ⾣೿ੜπʔϧల։ͷͨΊͷ"1*࣮૷
    ⾣ϓϥάΠϯɾΧελϜϧʔϧͷ"1*࣮૷
    ⾣ΠϯσϯτϑΥʔϚοτɾίʔυελΠϧΛ౷Ұ͢ΔϏϧτΠϯϧʔϧ࣮૷
    ⾣ཁૉɾଐੑνΣοΫ͕࠷௿ݶՄೳͳϏϧτΠϯϧʔϧ࣮૷
    ⾣7JTVBM4UVEJP$PEF֦ுWਖ਼ࣜ൛ύϒϦογϡ
    ೥݄WϚΠφʔόʔδϣϯΞοϓ
    ⾣)5.--JWJOHTUBOEBSEͷόϦσʔγϣϯ͕Ͱ͖ΔϏϧτΠϯϧʔϧ௥Ճ
    ⾣8$8"*"3*"ͷόϦσʔγϣϯ͕Ͱ͖ΔϏϧτΠϯϧʔϧ௥Ճ
    ⾣ϒϥ΢β༻Ϟδϡʔϧ։ൃ
    ೥݄पลϓϥάΠϯ։ൃ
    ⾣)5.-JO+4ʢ5FNQMBUFMJUFSBMʣରԠϓϥάΠϯ
    ⾣QVHରԠϓϥάΠϯ
    ⾣QIQରԠϓϥάΠϯ

    View Slide

  20. ©2018 Yusuke Hirao
    ࠓޙɺͲ͏͍͏ར༻Λ͍͔ͨ͠ɾͯ͠΄͍͔͠
    ೿ੜπʔϧల։ͷͨΊͷ"1*࣮૷
    ೿ੜπʔϧ͕࡞ΕΔ࢓૊Έʹ͍ͭͯཁ๬͕͋ͬͨ

    View Slide

  21. ©2018 Yusuke Hirao
    ࠓޙɺͲ͏͍͏ར༻Λ͍͔ͨ͠ɾͯ͠΄͍͔͠
    ೿ੜπʔϧల։ͷͨΊͷ"1*࣮૷
    ೿ੜπʔϧ੍࡞ʹऔΓֻ͔ͬͯ͘Ε͍ͯΔํʑ͕͍Δ

    View Slide

  22. ©2018 Yusuke Hirao
    ࠓޙɺͲ͏͍͏ར༻Λ͍͔ͨ͠ɾͯ͠΄͍͔͠
    ೿ੜπʔϧల։ͷͨΊͷ"1*࣮૷
    ೿ੜπʔϧͷͨΊͷ"1*ఏڙ ࣮૷த

    !// ॊೈͰඪ४ͳAPIΛఏڙ͢ΔຊՈ
    import * as markuplint from 'markuplint';
    !// ࣮ߦ؀ڥΛ໰Θͳ͍Universal JavaScriptͰར༻Ͱ͖ΔAPI
    import { MLCore } from '@markuplint/ml-core';
    ˞@textlint/kernelʹӨڹΛड͚͍ͯ·͢ɻ

    View Slide

  23. ©2018 Yusuke Hirao
    ࠓޙɺͲ͏͍͏ར༻Λ͍͔ͨ͠ɾͯ͠΄͍͔͠
    ϑϩϯτΤϯυΤϯδχΞʹ
    ؾܰʹ
    ϛχϚϜʹ
    ΞυϗοΫʹ
    ར༻ͯ͠΄͍͠
    ͳͷͰϥΠηϯε΋.*5Ͱ͢

    View Slide

  24. ©2018 Yusuke Hirao
    ࠓޙɺͲ͏͍͏ར༻Λ͍͔ͨ͠ɾͯ͠΄͍͔͠
    NBSLVQMJOUͷϩʔυϚοϓ
    ೥݄WBMQIBΞϧϑΝ൛ύϒϦογϡ
    ೥݄Wਖ਼ࣜ൛ύϒϦογϡ
    ⾣೿ੜπʔϧల։ͷͨΊͷ/PEFKT"1*࣮૷
    ⾣ϓϥάΠϯɾΧελϜϧʔϧͷ"1*࣮૷
    ⾣ΠϯσϯτϑΥʔϚοτɾίʔυελΠϧΛ౷Ұ͢ΔϏϧτΠϯϧʔϧ࣮૷
    ⾣ཁૉɾଐੑνΣοΫ͕࠷௿ݶՄೳͳϏϧτΠϯϧʔϧ࣮૷
    ⾣7JTVBM4UVEJP$PEF֦ுWਖ਼ࣜ൛ύϒϦογϡ
    ೥݄WϚΠφʔόʔδϣϯΞοϓ
    ⾣)5.--JWJOHTUBOEBSEͷόϦσʔγϣϯ͕Ͱ͖ΔϏϧτΠϯϧʔϧ௥Ճ
    ⾣8$8"*"3*"ͷόϦσʔγϣϯ͕Ͱ͖ΔϏϧτΠϯϧʔϧ௥Ճ
    ⾣ϒϥ΢β༻Ϟδϡʔϧ։ൃ
    ೥݄पลϓϥάΠϯ։ൃ
    ⾣)5.-JO+4ʢ5FNQMBUFMJUFSBMʣରԠϓϥάΠϯ
    ⾣QVHରԠϓϥάΠϯ
    ⾣QIQରԠϓϥάΠϯ

    View Slide

  25. ©2018 Yusuke Hirao
    ࠓޙɺͲ͏͍͏ར༻Λ͍͔ͨ͠ɾͯ͠΄͍͔͠
    8$8"*"3*"ͷόϦσʔγϣϯ
    SPMFଐੑ
    BSJBଐੑ
    ࢦఆཁૉͷଥ౰ੑ
    ଐੑ஋ͷنఆ஋ɾλΠϙνΣοΫ
    aria-***byଐੑͳͲͱ#idͷ੔߹ੑ
    aria-labelͷ্ॻ͖໰୊νΣοΫ
    ͳͲ

    View Slide

  26. ©2018 Yusuke Hirao
    ࠓޙɺͲ͏͍͏ར༻Λ͍͔ͨ͠ɾͯ͠΄͍͔͠
    8$8"*"3*"ͷόϦσʔγϣϯ
    SPMFଐੑ
    BSJBଐੑ
    ࢦఆཁૉͷଥ౰ੑ
    ଐੑ஋ͷنఆ஋ɾλΠϙνΣοΫ
    aria-***byଐੑͳͲͱ#idͷ੔߹ੑ
    aria-labelͷ্ॻ͖໰୊νΣοΫ
    ͳͲ
    ਓ͕ؒνΣοΫ͢Δͷʹݶք͕͋Δ΍ͭ

    View Slide

  27. ©2018 Yusuke Hirao
    ΞδΣϯμ
    ࠓ೔࿩͢͜ͱ

    ࠓɺͲ͏͍͏ར༻Λ͍ͯ͠Δͷ͔
    ࠓޙɺͲ͏͍͏ར༻Λ͍͔ͨ͠ɾͯ͠΄͍͔͠
    ΞΫηγϏϦςΟνΣοΫͷࣗಈԽʹ͍ͭͯ

    View Slide

  28. ©2018 Yusuke Hirao
    Έͳ͞ΜŊ΋ͪΖΜςετॻ͍ͯ·͢ΑͶʁ
    ʢ౜ಥͳἤΓʣ

    View Slide

  29. ©2018 Yusuke Hirao
    ΞΫηγϏϦςΟνΣοΫͷࣗಈԽ
    ΋͏ͻͱͭར༻͍ͨ͠γʔϯ
    ίϯϙʔωϯτςετ

    ΞΫηγϏϦςΟ 8"*"3*"
    νΣοΫ

    ࣗಈςετπʔϧ

    View Slide

  30. ©2018 Yusuke Hirao
    ΞΫηγϏϦςΟνΣοΫͷࣗಈԽ
    ίϯϙʔωϯτςετ
    7VFKTͷྫ
    import { render } from '@vue/server-test-utils';
    import Foo from './Foo.vue';
    describe('Foo', () !=> {
    it('renders a div', () !=> {
    const wrapper = render(Foo);
    expect(wrapper.text()).toContain('!');
    });
    });
    Ҿ༻IUUQTWVFUFTUVUJMTWVFKTPSHKBBQJSFOEFS

    View Slide

  31. ©2018 Yusuke Hirao
    ΞΫηγϏϦςΟνΣοΫͷࣗಈԽ
    ίϯϙʔωϯτςετʹ8"*"3*"νΣοΫΛಋೖ
    NBSLVQMJOU͸)5.-ͷஅย %PDVNFOU'SBHNFOU
    Λѻ͑Δ
    import { render } from '@vue/server-test-utils';
    import * as markuplint from 'markuplint';
    import Foo from './Foo.vue';
    describe('Foo', () !=> {
    it('renders a div', () !=> {
    const wrapper = render(Foo, { propsData: { pressed: true } });
    expect(
    markuplint.verify({
    sourceCodes: wrapper.html(),
    reportType: 'exception',
    }),
    ).toBe(true);
    });
    });
    ࢀߟIUUQTWVFUFTUVUJMTWVFKTPSHKBBQJSFOEFS

    View Slide

  32. ©2018 Yusuke Hirao
    ΞΫηγϏϦςΟνΣοΫͷࣗಈԽ
    ίϯϙʔωϯτςετʹ8"*"3*"νΣοΫΛಋೖ
    NBSLVQMJOU͸)5.-ͷஅย %PDVNFOU'SBHNFOU
    Λѻ͑Δ
    ࢀߟIUUQTWVFUFTUVUJMTWVFKTPSHKBBQJSFOEFS
    import { render } from '@vue/server-test-utils';
    import * as markuplint from 'markuplint';
    import Foo from './Foo.vue';
    describe('Foo', () !=> {
    it('renders a div', () !=> {
    const wrapper = render(Foo, { propsData: { pressed: true } });
    expect(
    markuplint.verify({
    sourceCodes: wrapper.html(),
    reportType: 'exception',
    }),
    ).toBe(true);
    });
    });
    ීวతͳଐੑ஋ςετ͸·ͱΊͯ୲͏

    View Slide

  33. ©2018 Yusuke Hirao
    ΞΫηγϏϦςΟνΣοΫͷࣗಈԽ
    ίʔσΟϯά
    ίϯϙʔωϯτ
    ςετ
    ϦϯτνΣοΫ
    git push
    ϦϙδτϦ
    post-receive
    $*αʔόʔ
    ϔουϨε
    ϒϥ΢βʔ
    test —watch
    lint —watch
    ίϯϙʔωϯτ
    ςετ

    View Slide

  34. ©2018 Yusuke Hirao
    ͱ͜ΖͰ
    NBSLVQMJOU͸ΞΫηγϏϦςΟνΣοΧʔͳͷ͔

    View Slide

  35. ©2018 Yusuke Hirao
    ΞΫηγϏϦςΟνΣοΫͷࣗಈԽ
    NBSLVQMJOU͸ΞΫηγϏϦςΟνΣοΧʔͳͷ͔
    νΣοΧʔͱ໊৐Δͱ͜Ζ·Ͱػೳ࣮૷͢Δͭ΋Γ͸ͳ͍Ͱ͢ɻ
    ͋͘·ͰNBSLVQMJOU͸ϚʔΫΞοϓϥϯήʔδ༻ͷϦϯλʔͰ͢ɻ
    ͳͷͰɺཁૉ΍ଐੑΛνΣοΫ͢Δ্Ͱid ΍for΍altɺ
    ͦͯ͠8"*"3*"΋ର৅ʹ͍ͯ͠Δ͚ͩͰ͢ɻ
    άϥϑΟΧϧͳ෦෼΍$44࣮૷ʹٴͿͱ͜Ζ·Ͱ͸αϙʔτ͠·ͤΜ͠ɺͰ͖·ͤΜɻ
    NBSLVQMJOUΛར༻ͯ͠ΞΫηγϏϦςΟνΣοΧʔΛ
    ։ൃ͍ͯͨͩ͘͠ͷ͸΍Ϳ͔͞Ͱ͸ͳ͍Ͱ͢

    View Slide

  36. ©2018 Yusuke Hirao
    ΞΫηγϏϦςΟνΣοΫͷࣗಈԽ
    ஫໨͍ͯ͠ΔΞΫηγϏϦςΟνΣοΧʔ
    "ZD
    8FC্ͰΞΫηγϏϦςΟνΣοΫ͕
    Ͱ͖ΔαʔϏεπʔϧɻ
    .*5ϥΠηϯεͷΦʔϓϯιʔεͰ
    1)1Ͱॻ͔Ε͍ͯΔͷͰ
    $.4ͳͲʹ૊ΈࠐΈՄೳɻ
    8PSE1SFTTϓϥάΠϯ͕഑෍͞Ε͍ͯ·͢ɻ
    CBTFS$.4ϓϥάΠϯ΋΄͍͠ʜ

    View Slide

  37. ©2018 Yusuke Hirao
    ·ͱΊ

    View Slide

  38. ©2018 Yusuke Hirao
    ·ͱΊ
    ؾܰʹɺϛχϚϜʹɺΞυϗοΫʹར༻ͯ͠΄͍͠
    ίϯϙʔωϯτςετʹ΋࢖͑Δ
    ࣗಈςετπʔϧʹ૊ΈࠐΉͷ͕Φεεϝ
    ΞΫηγϏϦςΟνΣοΫ͸͋͘·Ͱཁૉɾଐੑ͕ର৅

    View Slide

  39. ΞΫηγϏϦςΟνΣοΫΛࣗಈԽ͢ΔͨΊͷ
    NBSLVQMJOUͷϩʔυϚοϓ
    "DDFTTJCJMJUZ4UFQ7PM

    View Slide