diff --git a/ts/adaptors/HTMLAdaptor.ts b/ts/adaptors/HTMLAdaptor.ts
index 97b2b05c3..565c213ae 100644
--- a/ts/adaptors/HTMLAdaptor.ts
+++ b/ts/adaptors/HTMLAdaptor.ts
@@ -74,6 +74,7 @@ export interface MinHTMLElement {
/* tslint:disable:jsdoc-require */
getElementsByTagName(name: string): N[] | HTMLCollectionOf;
getElementsByTagNameNS(ns: string, name: string): N[] | HTMLCollectionOf;
+ contains(child: N | T): boolean;
appendChild(child: N | T): N | T | Node;
removeChild(child: N | T): N | T | Node;
replaceChild(nnode: N | T, onode: N | T): N | T | Node;
@@ -254,6 +255,13 @@ AbstractDOMAdaptor implements MinHTMLAdaptor {
return containers;
}
+ /**
+ * @override
+ */
+ public contains(container: N, node: N | T) {
+ return container.contains(node);
+ }
+
/**
* @override
*/
diff --git a/ts/adaptors/liteAdaptor.ts b/ts/adaptors/liteAdaptor.ts
index 9fa7bc594..0332027fe 100644
--- a/ts/adaptors/liteAdaptor.ts
+++ b/ts/adaptors/liteAdaptor.ts
@@ -235,6 +235,16 @@ export class LiteAdaptor extends AbstractDOMAdaptor= 0) {
onode.parent.children[i] = nnode;
+ nnode.parent = onode.parent;
+ onode.parent = null;
}
return onode;
}
diff --git a/ts/components/startup.ts b/ts/components/startup.ts
index 79a9d82b8..a9b2699ba 100644
--- a/ts/components/startup.ts
+++ b/ts/components/startup.ts
@@ -327,19 +327,26 @@ export namespace Startup {
* TypeseClear() clears all the MathItems from the document.
*/
export function makeTypesetMethods() {
- MathJax.typeset = (elements: any = null) => {
+ MathJax.typeset = (elements: any[] = null) => {
document.options.elements = elements;
document.reset();
document.render();
};
- MathJax.typesetPromise = (elements: any = null) => {
+ MathJax.typesetPromise = (elements: any[] = null) => {
document.options.elements = elements;
document.reset();
return mathjax.handleRetriesFor(() => {
document.render();
});
};
- MathJax.typesetClear = () => document.clear();
+ MathJax.typesetClear = (elements: any[] = null) => {
+ if (elements) {
+ document.reset();
+ document.clearMathItemsWithin(elements);
+ } else {
+ document.clear();
+ }
+ };
}
/**
diff --git a/ts/core/DOMAdaptor.ts b/ts/core/DOMAdaptor.ts
index 6ad61d77a..09eac9d97 100644
--- a/ts/core/DOMAdaptor.ts
+++ b/ts/core/DOMAdaptor.ts
@@ -114,6 +114,15 @@ export interface DOMAdaptor {
*/
getElements(nodes: (string | N | N[])[], document: D): N[];
+ /**
+ * Determine if a container node contains a given node is somewhere in its DOM tree
+ *
+ * @param {N} container The container to search
+ * @param {N|T} node The node to look for
+ * @return {boolean} True if the node is in the container's DOM tree
+ */
+ contains(container: N, node: N | T): boolean;
+
/**
* @param {N|T} node The HTML node whose parent is to be obtained
* @return {N} The parent node of the given one
@@ -431,6 +440,11 @@ export abstract class AbstractDOMAdaptor implements DOMAdaptor
*/
public abstract getElements(nodes: (string | N | N[])[], document: D): N[];
+ /**
+ * @override
+ */
+ public abstract contains(container: N, node: N | T): boolean;
+
/**
* @override
*/
diff --git a/ts/core/MathDocument.ts b/ts/core/MathDocument.ts
index d9e882b5e..da5a88a30 100644
--- a/ts/core/MathDocument.ts
+++ b/ts/core/MathDocument.ts
@@ -230,6 +230,15 @@ export class RenderList extends PrioritizedList> {
}
+/*****************************************************************/
+/**
+ * The ways of specifying a container (a selector string, an actual node,
+ * or an array of those (e.g., the result of document.getElementsByTagName())
+ *
+ * @template N The HTMLElement node class
+ */
+export type ContainerList = string | N | (string | N | N[])[];
+
/*****************************************************************/
/**
* The MathDocument interface
@@ -428,6 +437,24 @@ export interface MathDocument {
*/
concat(list: MathList): MathDocument;
+ /**
+ * Clear the typeset MathItems that are within the given container
+ * from the document's MathList. (E.g., when the content of the
+ * container has been updated and you want to remove the
+ * associated MathItems)
+ *
+ * @param {ContainerList} elements The container DOM elements whose math items are to be removed
+ */
+ clearMathItemsWithin(containers: ContainerList): void;
+
+ /**
+ * Get the typeset MathItems that are within a given container.
+ *
+ * @param {ContainerList} elements The container DOM elements whose math items are to be found
+ * @return {MathItem[]} The list of MathItems within that container
+ */
+ getMathItemsWithin(elements: ContainerList): MathItem[];
+
}
/*****************************************************************/
@@ -857,6 +884,35 @@ export abstract class AbstractMathDocument implements MathDocument) {
+ this.math.remove(...this.getMathItemsWithin(containers));
+ }
+
+ /**
+ * @override
+ */
+ public getMathItemsWithin(elements: ContainerList) {
+ if (!Array.isArray(elements)) {
+ elements = [elements];
+ }
+ const adaptor = this.adaptor;
+ const items = [] as MathItem[];
+ const containers = adaptor.getElements(elements, this.document);
+ ITEMS:
+ for (const item of this.math) {
+ for (const container of containers) {
+ if (item.start.node && adaptor.contains(container, item.start.node)) {
+ items.push(item);
+ continue ITEMS;
+ }
+ }
+ }
+ return items;
+ }
+
}
/**
diff --git a/ts/util/LinkedList.ts b/ts/util/LinkedList.ts
index c5600887d..856e84256 100644
--- a/ts/util/LinkedList.ts
+++ b/ts/util/LinkedList.ts
@@ -26,7 +26,7 @@
* A symbol used to mark the special node used to indicate
* the start and end of the list.
*/
-const END = Symbol();
+export const END = Symbol();
/**
* Shorthand type for the functions used to sort the data items
@@ -190,6 +190,28 @@ export class LinkedList {
return item.data as DataClass;
}
+ /**
+ * Remove items from the list
+ *
+ * @param {DataClass[]} items The items to remove
+ */
+ public remove(...items: DataClass[]) {
+ const map = new Map();
+ for (const item of items) {
+ map.set(item, true);
+ }
+ let item = this.list.next;
+ while (item.data !== END) {
+ const next = item.next;
+ if (map.has(item.data as DataClass)) {
+ item.prev.next = item.next;
+ item.next.prev = item.prev;
+ item.next = item.prev = null;
+ }
+ item = next;
+ }
+ }
+
/**
* Empty the list
*