mirror of
https://github.com/google/blockly.git
synced 2026-01-09 10:00:09 +01:00
* refactor(xml): Move textToDom to core/utils/xml.ts This function being in core/xml.ts was the cause for the last remaining circular import in core/ (between variables.ts and xml.ts). Moving it to utils/xml.ts makes sense anyway, since there is nothing Blockly-specific about this function. Fixes #6817. * fix(closure): Reenable goog.declareModuleId multiple-call check Reenable an assertion which check to make sure that goog.declareModuleId is not called more than once in a module (and which also catches circular imports amongst ES modules, which are not detected by closure-make-deps). * chore(tests,demos): Augo-migrate use of textToDom Testing the migration file entry by auto-migrating all uses of Blockly.Xml.textToDom to Blockly.utils.xml.textToDom. * chore(blocks): Manually migrate remaining use of textToDom Update the one remaining call to textToDom (in blocks/lists.ts) to the function's new location - also removing the last use of the Blockly.Xml / core/xml.ts) module from this file. * docs(xml): Remove unneeded @alias per comments on PR #6818 * fix(imports): Remove unused import
149 lines
4.2 KiB
TypeScript
149 lines
4.2 KiB
TypeScript
/**
|
|
* @license
|
|
* Copyright 2018 Google LLC
|
|
* SPDX-License-Identifier: Apache-2.0
|
|
*/
|
|
|
|
/**
|
|
* XML element manipulation.
|
|
* These methods are not specific to Blockly, and could be factored out into
|
|
* a JavaScript framework such as Closure.
|
|
*
|
|
* @namespace Blockly.utils.xml
|
|
*/
|
|
import * as goog from '../../closure/goog/goog.js';
|
|
goog.declareModuleId('Blockly.utils.xml');
|
|
|
|
import * as deprecation from './deprecation.js';
|
|
|
|
|
|
/**
|
|
* Injected dependencies. By default these are just (and have the
|
|
* same types as) the corresponding DOM Window properties, but the
|
|
* Node.js wrapper for Blockly (see scripts/package/node/core.js)
|
|
* calls injectDependencies to supply implementations from the jsdom
|
|
* package instead.
|
|
*/
|
|
let {document, DOMParser, XMLSerializer} = globalThis;
|
|
|
|
/**
|
|
* Inject implementations of document, DOMParser and/or XMLSerializer
|
|
* to use instead of the default ones.
|
|
*
|
|
* Used by the Node.js wrapper for Blockly (see
|
|
* scripts/package/node/core.js) to supply implementations from the
|
|
* jsdom package instead.
|
|
*
|
|
* While they may be set individually, it is normally the case that
|
|
* all three will be sourced from the same JSDOM instance. They MUST
|
|
* at least come from the same copy of the jsdom package. (Typically
|
|
* this is hard to avoid satsifying this requirement, but it can be
|
|
* inadvertently violated by using webpack to build multiple bundles
|
|
* containing Blockly and jsdom, and then loading more than one into
|
|
* the same JavaScript runtime. See
|
|
* https://github.com/google/blockly-samples/pull/1452#issuecomment-1364442135
|
|
* for an example of how this happened.)
|
|
*
|
|
* @param dependencies Options object containing dependencies to set.
|
|
*/
|
|
export function injectDependencies(dependencies: {
|
|
document?: Document,
|
|
DOMParser?: typeof DOMParser,
|
|
XMLSerializer?: typeof XMLSerializer,
|
|
}) {
|
|
({
|
|
// Default to existing value if option not supplied.
|
|
document = document,
|
|
DOMParser = DOMParser,
|
|
XMLSerializer = XMLSerializer,
|
|
} = dependencies);
|
|
}
|
|
|
|
/**
|
|
* Namespace for Blockly's XML.
|
|
*/
|
|
export const NAME_SPACE = 'https://developers.google.com/blockly/xml';
|
|
|
|
/**
|
|
* Get the document object to use for XML serialization.
|
|
*
|
|
* @returns The document object.
|
|
* @deprecated No longer provided by Blockly.
|
|
*/
|
|
export function getDocument(): Document {
|
|
deprecation.warn('Blockly.utils.xml.getDocument', 'version 9', 'version 10');
|
|
return document;
|
|
}
|
|
|
|
/**
|
|
* Get the document object to use for XML serialization.
|
|
*
|
|
* @param xmlDocument The document object to use.
|
|
* @deprecated No longer provided by Blockly.
|
|
*/
|
|
export function setDocument(xmlDocument: Document) {
|
|
deprecation.warn('Blockly.utils.xml.setDocument', 'version 9', 'version 10');
|
|
document = xmlDocument;
|
|
}
|
|
|
|
/**
|
|
* Create DOM element for XML.
|
|
*
|
|
* @param tagName Name of DOM element.
|
|
* @returns New DOM element.
|
|
*/
|
|
export function createElement(tagName: string): Element {
|
|
return document.createElementNS(NAME_SPACE, tagName);
|
|
}
|
|
|
|
/**
|
|
* Create text element for XML.
|
|
*
|
|
* @param text Text content.
|
|
* @returns New DOM text node.
|
|
*/
|
|
export function createTextNode(text: string): Text {
|
|
return document.createTextNode(text);
|
|
}
|
|
|
|
/**
|
|
* Converts an XML string into a DOM structure.
|
|
*
|
|
* @param text An XML string.
|
|
* @returns A DOM object representing the singular child of the document
|
|
* element.
|
|
* @throws if the text doesn't parse.
|
|
*/
|
|
export function textToDom(text: string): Element {
|
|
const doc = textToDomDocument(text);
|
|
if (!doc || !doc.documentElement ||
|
|
doc.getElementsByTagName('parsererror').length) {
|
|
throw Error('textToDom was unable to parse: ' + text);
|
|
}
|
|
return doc.documentElement;
|
|
}
|
|
|
|
/**
|
|
* Converts an XML string into a DOM tree.
|
|
*
|
|
* @param text XML string.
|
|
* @returns The DOM document.
|
|
* @throws if XML doesn't parse.
|
|
*/
|
|
export function textToDomDocument(text: string): Document {
|
|
const oParser = new DOMParser();
|
|
return oParser.parseFromString(text, 'text/xml');
|
|
}
|
|
|
|
/**
|
|
* Converts a DOM structure into plain text.
|
|
* Currently the text format is fairly ugly: all one line with no whitespace.
|
|
*
|
|
* @param dom A tree of XML nodes.
|
|
* @returns Text representation.
|
|
*/
|
|
export function domToText(dom: Node): string {
|
|
const oSerializer = new XMLSerializer();
|
|
return oSerializer.serializeToString(dom);
|
|
}
|