blob: 4b492df0b82b20f86699fd5ebcbf6c1bab237c37 [file] [log] [blame]
/*!
* Copyright 2018 The Fuchsia Authors. All rights reserved.
* Use of this source code is governed by a BSD-style license that can be
* found in the LICENSE file.
*/
import { EntityExtractor, Entity } from "./entity";
import { toArray } from "./util";
const jsonLdType = 'application/ld+json';
export class JsonLdExtractor implements EntityExtractor {
extract(document: HTMLDocument): Entity[] {
const entities: Entity[] = [];
for (var script of toArray(document.querySelectorAll("script[type='application/ld+json']"))) {
var value;
try {
value = JSON.parse(script.textContent!);
} catch (e) {
continue;
}
if (value instanceof Array) {
entities.push(...value);
} else {
entities.push(value);
}
}
return entities;
}
private isJsonLdRelated(node: Node): boolean {
if (node.nodeType != Node.ELEMENT_NODE) {
if (node.parentNode) {
return this.isJsonLdRelated(node.parentNode);
} else {
return false;
}
}
return node instanceof HTMLScriptElement && node.type === jsonLdType;
}
entitiesChanged(records: MutationRecord[]): boolean {
for (const record of records) {
if (record.type === "childList") {
for (const node of toArray(record.addedNodes)) {
if (this.isJsonLdRelated(node)) {
return true;
}
}
for (const node of toArray(record.removedNodes)) {
if (this.isJsonLdRelated(node)) {
return true;
}
}
} else if (record.type === "attributes") {
if (record.target instanceof HTMLScriptElement) {
if (record.target.type === jsonLdType || record.oldValue === jsonLdType) {
return true;
}
}
} else if (record.type === "characterData") {
return this.isJsonLdRelated(record.target);
}
}
return false;
}
}