| 50 | } |
| 51 | |
| 52 | class StructuredData extends Rule { |
| 53 | documentation(context) { |
| 54 | return { |
| 55 | description: "Validates JSON-LD according to schema.org" |
| 56 | }; |
| 57 | } |
| 58 | |
| 59 | setup() { |
| 60 | let start = -1; |
| 61 | |
| 62 | this.on('tag:open', event => { |
| 63 | if (event.target.nodeName === 'script') { |
| 64 | start = event.target.location.offset; |
| 65 | } |
| 66 | }); |
| 67 | |
| 68 | this.on('tag:close', async event => { |
| 69 | const tag = event.previous; |
| 70 | if (event.target.nodeName === 'script' && tag.hasAttribute('type') && tag.getAttribute('type').value === 'application/ld+json') { |
| 71 | const startIdx = data.indexOf('>', start) + 1; |
| 72 | const endIdx = event.target.location.offset - 1; // omit the opening tag angled bracket |
| 73 | const content = data.substring(startIdx, endIdx); |
| 74 | try { |
| 75 | JSON.parse(content); |
| 76 | } catch (err) { |
| 77 | this.report(tag, `Unable to parse JSON-LD as JSON: ${err}`); |
| 78 | } |
| 79 | } |
| 80 | }); |
| 81 | } |
| 82 | } |
| 83 | |
| 84 | let data; |
| 85 |
nothing calls this directly
no outgoing calls
no test coverage detected