stuff
This commit is contained in:
parent
bc92231240
commit
b8225c639e
11904 changed files with 1472749 additions and 133 deletions
241
node_modules/mathjax-full/ts/ui/menu/MJContextMenu.ts
generated
vendored
Normal file
241
node_modules/mathjax-full/ts/ui/menu/MJContextMenu.ts
generated
vendored
Normal file
|
|
@ -0,0 +1,241 @@
|
|||
/*************************************************************
|
||||
*
|
||||
* Copyright (c) 2019-2022 The MathJax Consortium
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @fileoverview Implements a subclass of ContextMenu specific to MathJax
|
||||
*
|
||||
* @author dpvc@mathjax.org (Davide Cervone)
|
||||
*/
|
||||
|
||||
import {MathItem} from '../../core/MathItem.js';
|
||||
import {MmlNode} from '../../core/MmlTree/MmlNode.js';
|
||||
import {SelectableInfo} from './SelectableInfo.js';
|
||||
|
||||
import {ContextMenu} from 'mj-context-menu/js/context_menu.js';
|
||||
import {SubMenu} from 'mj-context-menu/js/sub_menu.js';
|
||||
import {Submenu} from 'mj-context-menu/js/item_submenu.js';
|
||||
import {Menu} from 'mj-context-menu/js/menu.js';
|
||||
import {Item} from 'mj-context-menu/js/item.js';
|
||||
|
||||
/*==========================================================================*/
|
||||
|
||||
/**
|
||||
* The subclass of ContextMenu that handles the needs of the MathJax
|
||||
* contextual menu (in particular, tying it to a MathItem).
|
||||
*/
|
||||
export class MJContextMenu extends ContextMenu {
|
||||
|
||||
/**
|
||||
* Static map to hold methods for re-computing dynamic submenus.
|
||||
* @type {Map<string, (menu: MJContextMenu, sub: Submenu)}
|
||||
*/
|
||||
public static DynamicSubmenus: Map<string,
|
||||
(menu: MJContextMenu, sub: Submenu) =>
|
||||
SubMenu> = new Map();
|
||||
|
||||
/**
|
||||
* The MathItem that has posted the menu
|
||||
*/
|
||||
public mathItem: MathItem<HTMLElement, Text, Document> = null;
|
||||
|
||||
/**
|
||||
* The annotation selected in the Annotation submenu (neede for the info box to be able to show it)
|
||||
*/
|
||||
public annotation: string = '';
|
||||
|
||||
/**
|
||||
* The info box for showing annotations (created by the Menu object that contains this MJContextMenu)
|
||||
*/
|
||||
public showAnnotation: SelectableInfo;
|
||||
|
||||
/**
|
||||
* The function to copy the selected annotation (set by the containing Menu item)
|
||||
*/
|
||||
public copyAnnotation: () => void;
|
||||
|
||||
/**
|
||||
* The annotation types to look for in a MathItem
|
||||
*/
|
||||
public annotationTypes: {[type: string]: string[]} = {};
|
||||
|
||||
/*======================================================================*/
|
||||
|
||||
/**
|
||||
* Before posting the menu, set the name for the ShowAs and CopyToClipboard menus,
|
||||
* enable/disable the semantics check item, and get the annotations for the MathItem
|
||||
*
|
||||
* @override
|
||||
*/
|
||||
public post(x?: any, y?: number) {
|
||||
if (this.mathItem) {
|
||||
if (y !== undefined) {
|
||||
// FIXME: handle error output jax
|
||||
const input = this.mathItem.inputJax.name;
|
||||
const original = this.findID('Show', 'Original');
|
||||
original.content = (input === 'MathML' ? 'Original MathML' : input + ' Commands');
|
||||
const clipboard = this.findID('Copy', 'Original');
|
||||
clipboard.content = original.content;
|
||||
const semantics = this.findID('Settings', 'semantics');
|
||||
input === 'MathML' ? semantics.disable() : semantics.enable();
|
||||
this.getAnnotationMenu();
|
||||
this.dynamicSubmenus();
|
||||
}
|
||||
super.post(x, y);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Clear the stored MathItem when the menu is removed
|
||||
*
|
||||
* @override
|
||||
*/
|
||||
public unpost() {
|
||||
super.unpost();
|
||||
this.mathItem = null;
|
||||
}
|
||||
|
||||
/*======================================================================*/
|
||||
|
||||
/**
|
||||
* Find an item in the menu (recursively descending into submenus, if needed)
|
||||
*
|
||||
* @param {string[]} names The menu IDs to look for
|
||||
* @returns {Item} The menu item (or null if not found)
|
||||
*/
|
||||
public findID(...names: string[]) {
|
||||
let menu = this as Menu;
|
||||
let item = null as Item;
|
||||
for (const name of names) {
|
||||
if (menu) {
|
||||
item = menu.find(name);
|
||||
menu = (item instanceof Submenu ? item.submenu : null);
|
||||
} else {
|
||||
item = null;
|
||||
}
|
||||
}
|
||||
return item;
|
||||
}
|
||||
|
||||
/*======================================================================*/
|
||||
|
||||
/**
|
||||
* Look up the annotations in the MathItem and set the ShowAs and CopyToClipboard menus
|
||||
*/
|
||||
protected getAnnotationMenu() {
|
||||
const annotations = this.getAnnotations(this.getSemanticNode());
|
||||
this.createAnnotationMenu('Show', annotations, () => this.showAnnotation.post());
|
||||
this.createAnnotationMenu('Copy', annotations, () => this.copyAnnotation());
|
||||
}
|
||||
|
||||
/**
|
||||
* Find the top-most semantics element that encloses the contents of the expression (if any)
|
||||
*
|
||||
* @returns {MmlNode | null} The semantics node that was found (or null)
|
||||
*/
|
||||
protected getSemanticNode(): MmlNode | null {
|
||||
let node: MmlNode = this.mathItem.root;
|
||||
while (node && !node.isKind('semantics')) {
|
||||
if (node.isToken || node.childNodes.length !== 1) return null;
|
||||
node = node.childNodes[0] as MmlNode;
|
||||
}
|
||||
return node;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {MmlNode} node The semantics node whose annotations are to be obtained
|
||||
* @returns {[string, string][]} Array of [type, text] where the type is the annotation type
|
||||
* and text is the content of the annotation of that type
|
||||
*/
|
||||
protected getAnnotations(node: MmlNode): [string, string][] {
|
||||
const annotations = [] as [string, string][];
|
||||
if (!node) return annotations;
|
||||
for (const child of node.childNodes as MmlNode[]) {
|
||||
if (child.isKind('annotation')) {
|
||||
const match = this.annotationMatch(child);
|
||||
if (match) {
|
||||
const value = child.childNodes.reduce((text, chars) => text + chars.toString(), '');
|
||||
annotations.push([match, value]);
|
||||
}
|
||||
}
|
||||
}
|
||||
return annotations;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {MmlNode} child The annotation node to check if its encoding is one of the displayable ones
|
||||
* @returns {string | null} The annotation type if it does, or null if it doesn't
|
||||
*/
|
||||
protected annotationMatch(child: MmlNode): string | null {
|
||||
const encoding = child.attributes.get('encoding') as string;
|
||||
for (const type of Object.keys(this.annotationTypes)) {
|
||||
if (this.annotationTypes[type].indexOf(encoding) >= 0) {
|
||||
return type;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a submenu from the available annotations and attach it to the proper menu item
|
||||
*
|
||||
* @param {string} id The id of the menu to attach to (Show or Copy)
|
||||
* @param {[string, string][]} annotations The annotations to use for the submenu
|
||||
* @param {() => void} action The action to perform when the annotation is selected
|
||||
*/
|
||||
protected createAnnotationMenu(id: string, annotations: [string, string][], action: () => void) {
|
||||
const menu = this.findID(id, 'Annotation') as Submenu;
|
||||
menu.submenu = this.factory.get('subMenu')(this.factory, {
|
||||
items: annotations.map(([type, value]) => {
|
||||
return {
|
||||
type: 'command',
|
||||
id: type,
|
||||
content: type,
|
||||
action: () => {
|
||||
this.annotation = value;
|
||||
action();
|
||||
}
|
||||
};
|
||||
}),
|
||||
id: 'annotations'
|
||||
}, menu);
|
||||
if (annotations.length) {
|
||||
menu.enable();
|
||||
} else {
|
||||
menu.disable();
|
||||
}
|
||||
}
|
||||
|
||||
/*======================================================================*/
|
||||
|
||||
/**
|
||||
* Renews the dynamic submenus.
|
||||
*/
|
||||
public dynamicSubmenus() {
|
||||
for (const [id, method] of MJContextMenu.DynamicSubmenus) {
|
||||
const menu = this.find(id) as Submenu;
|
||||
if (!menu) continue;
|
||||
const sub = method(this, menu);
|
||||
menu.submenu = sub;
|
||||
if (sub.items.length) {
|
||||
menu.enable();
|
||||
} else {
|
||||
menu.disable();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
1177
node_modules/mathjax-full/ts/ui/menu/Menu.ts
generated
vendored
Normal file
1177
node_modules/mathjax-full/ts/ui/menu/Menu.ts
generated
vendored
Normal file
File diff suppressed because it is too large
Load diff
284
node_modules/mathjax-full/ts/ui/menu/MenuHandler.ts
generated
vendored
Normal file
284
node_modules/mathjax-full/ts/ui/menu/MenuHandler.ts
generated
vendored
Normal file
|
|
@ -0,0 +1,284 @@
|
|||
/*************************************************************
|
||||
*
|
||||
* Copyright (c) 2019-2022 The MathJax Consortium
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @fileoverview Mixin that adds a context-menu to MathJax output
|
||||
*
|
||||
* @author dpvc@mathjax.org (Davide Cervone)
|
||||
*/
|
||||
|
||||
import {mathjax} from '../../mathjax.js';
|
||||
|
||||
import {STATE, newState} from '../../core/MathItem.js';
|
||||
import {MathDocumentConstructor} from '../../core/MathDocument.js';
|
||||
import {Handler} from '../../core/Handler.js';
|
||||
import {ComplexityMathDocument, ComplexityMathItem} from '../../a11y/complexity.js';
|
||||
import {ExplorerMathDocument, ExplorerMathItem} from '../../a11y/explorer.js';
|
||||
import {AssistiveMmlMathDocument, AssistiveMmlMathItem} from '../../a11y/assistive-mml.js';
|
||||
import {expandable} from '../../util/Options.js';
|
||||
|
||||
import {Menu} from './Menu.js';
|
||||
|
||||
/*==========================================================================*/
|
||||
|
||||
/**
|
||||
* Generic constructor for Mixins
|
||||
*/
|
||||
export type Constructor<T> = new(...args: any[]) => T;
|
||||
|
||||
/**
|
||||
* Constructor for base MathItem for MenuMathItem
|
||||
*/
|
||||
export type A11yMathItemConstructor = {
|
||||
new(...args: any[]): ComplexityMathItem<HTMLElement, Text, Document> &
|
||||
ExplorerMathItem & AssistiveMmlMathItem<HTMLElement, Text, Document>;
|
||||
};
|
||||
|
||||
/**
|
||||
* Constructor for base document for MenuMathDocument
|
||||
*/
|
||||
export type A11yDocumentConstructor =
|
||||
MathDocumentConstructor<ComplexityMathDocument<HTMLElement, Text, Document> &
|
||||
ExplorerMathDocument & AssistiveMmlMathDocument<HTMLElement, Text, Document>>;
|
||||
|
||||
/*==========================================================================*/
|
||||
|
||||
/**
|
||||
* Add STATE value for menus being added (after TYPESET and before INSERTED)
|
||||
*/
|
||||
newState('CONTEXT_MENU', 170);
|
||||
|
||||
/**
|
||||
* The new function for MathItem that adds the context menu
|
||||
*/
|
||||
export interface MenuMathItem extends ComplexityMathItem<HTMLElement, Text, Document> {
|
||||
|
||||
/**
|
||||
* @param {MenuMathDocument} document The document where the menu is being added
|
||||
* @param {boolean} force True if menu should be added even if enableMenu is false
|
||||
*/
|
||||
addMenu(document: MenuMathDocument, force?: boolean): void;
|
||||
|
||||
/**
|
||||
* @param {MenuMathDocument} document The document to check for if anything is being loaded
|
||||
*/
|
||||
checkLoading(document: MenuMathDocument): void;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* The mixin for adding context menus to MathItems
|
||||
*
|
||||
* @param {B} BaseMathItem The MathItem class to be extended
|
||||
* @return {MathMathItem} The extended MathItem class
|
||||
*
|
||||
* @template B The MathItem class to extend
|
||||
*/
|
||||
export function MenuMathItemMixin<B extends A11yMathItemConstructor>(
|
||||
BaseMathItem: B
|
||||
): Constructor<MenuMathItem> & B {
|
||||
|
||||
return class extends BaseMathItem {
|
||||
|
||||
/**
|
||||
* @param {MenuMathDocument} document The document where the menu is being added
|
||||
* @param {boolean} force True if menu should be added even if enableMenu is false
|
||||
*/
|
||||
public addMenu(document: MenuMathDocument, force: boolean = false) {
|
||||
if (this.state() >= STATE.CONTEXT_MENU) return;
|
||||
if (!this.isEscaped && (document.options.enableMenu || force)) {
|
||||
document.menu.addMenu(this);
|
||||
}
|
||||
this.state(STATE.CONTEXT_MENU);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {MenuMathDocument} document The document to check for if anything is being loaded
|
||||
*/
|
||||
public checkLoading(document: MenuMathDocument) {
|
||||
document.checkLoading();
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
/*==========================================================================*/
|
||||
|
||||
/**
|
||||
* The properties needed in the MathDocument for context menus
|
||||
*/
|
||||
export interface MenuMathDocument extends ComplexityMathDocument<HTMLElement, Text, Document> {
|
||||
|
||||
/**
|
||||
* The menu associated with this document
|
||||
*/
|
||||
menu: Menu;
|
||||
|
||||
/**
|
||||
* Add context menus to the MathItems in the MathDocument
|
||||
*
|
||||
* @return {MenuMathDocument} The MathDocument (so calls can be chained)
|
||||
*/
|
||||
addMenu(): MenuMathDocument;
|
||||
|
||||
/**
|
||||
* Checks if there are files being loaded by the menu, and restarts the typesetting if so
|
||||
*
|
||||
* @return {MenuMathDocument} The MathDocument (so calls can be chained)
|
||||
*/
|
||||
checkLoading(): MenuMathDocument;
|
||||
}
|
||||
|
||||
/**
|
||||
* The mixin for adding context menus to MathDocuments
|
||||
*
|
||||
* @param {B} BaseDocument The MathDocument class to be extended
|
||||
* @return {MenuMathDocument} The extended MathDocument class
|
||||
*
|
||||
* @template B The MathDocument class to extend
|
||||
*/
|
||||
export function MenuMathDocumentMixin<B extends A11yDocumentConstructor>(
|
||||
BaseDocument: B
|
||||
): Constructor<MenuMathDocument> & B {
|
||||
|
||||
return class extends BaseDocument {
|
||||
|
||||
/**
|
||||
* @override
|
||||
*/
|
||||
public static OPTIONS = {
|
||||
//
|
||||
// These options are from the a11y extensions, which may not be loaded
|
||||
// initially, and so would cause "undefined option" error messages
|
||||
// if a user tries to configure them. So we include them here.
|
||||
// They are overridden by the options from the extensions when
|
||||
// those are loaded (via ...BaseDocument.OPTIONS).
|
||||
//
|
||||
enableEnrichment: true,
|
||||
enableComplexity: true,
|
||||
enableExplorer: true,
|
||||
enrichSpeech: 'none',
|
||||
enrichError: (_doc: MenuMathDocument, _math: MenuMathItem, err: Error) =>
|
||||
console.warn('Enrichment Error:', err),
|
||||
...BaseDocument.OPTIONS,
|
||||
MenuClass: Menu,
|
||||
menuOptions: Menu.OPTIONS,
|
||||
enableMenu: true,
|
||||
sre: (BaseDocument.OPTIONS.sre || expandable({})),
|
||||
a11y: (BaseDocument.OPTIONS.a11y || expandable({})),
|
||||
renderActions: expandable({
|
||||
...BaseDocument.OPTIONS.renderActions,
|
||||
addMenu: [STATE.CONTEXT_MENU],
|
||||
checkLoading: [STATE.UNPROCESSED + 1]
|
||||
})
|
||||
};
|
||||
|
||||
/**
|
||||
* The menu associated with this document
|
||||
*/
|
||||
public menu: Menu;
|
||||
|
||||
/**
|
||||
* Extend the MathItem class used for this MathDocument
|
||||
*
|
||||
* @override
|
||||
* @constructor
|
||||
*/
|
||||
constructor(...args: any[]) {
|
||||
super(...args);
|
||||
this.menu = new this.options.MenuClass(this, this.options.menuOptions);
|
||||
const ProcessBits = (this.constructor as typeof BaseDocument).ProcessBits;
|
||||
if (!ProcessBits.has('context-menu')) {
|
||||
ProcessBits.allocate('context-menu');
|
||||
}
|
||||
this.options.MathItem = MenuMathItemMixin<A11yMathItemConstructor>(this.options.MathItem);
|
||||
}
|
||||
|
||||
/**
|
||||
* Add context menus to the MathItems in the MathDocument
|
||||
*
|
||||
* @return {MenuMathDocument} The MathDocument (so calls can be chained)
|
||||
*/
|
||||
public addMenu(): MenuMathDocument {
|
||||
if (!this.processed.isSet('context-menu')) {
|
||||
for (const math of this.math) {
|
||||
(math as MenuMathItem).addMenu(this);
|
||||
}
|
||||
this.processed.set('context-menu');
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if there are files being loaded by the menu, and restarts the typesetting if so
|
||||
*
|
||||
* @return {MenuMathDocument} The MathDocument (so calls can be chained)
|
||||
*/
|
||||
public checkLoading(): MenuMathDocument {
|
||||
if (this.menu.isLoading) {
|
||||
mathjax.retryAfter(this.menu.loadingPromise.catch((err) => console.log(err)));
|
||||
}
|
||||
const settings = this.menu.settings;
|
||||
if (settings.collapsible) {
|
||||
this.options.enableComplexity = true;
|
||||
this.menu.checkComponent('a11y/complexity');
|
||||
}
|
||||
if (settings.explorer) {
|
||||
this.options.enableEnrichment = true;
|
||||
this.options.enableExplorer = true;
|
||||
this.menu.checkComponent('a11y/explorer');
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @override
|
||||
*/
|
||||
public state(state: number, restore: boolean = false) {
|
||||
super.state(state, restore);
|
||||
if (state < STATE.CONTEXT_MENU) {
|
||||
this.processed.clear('context-menu');
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @override
|
||||
*/
|
||||
public updateDocument() {
|
||||
super.updateDocument();
|
||||
(this.menu.menu.store as any).sort();
|
||||
return this;
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
/*==========================================================================*/
|
||||
|
||||
/**
|
||||
* Add context-menu support to a Handler instance
|
||||
*
|
||||
* @param {Handler} handler The Handler instance to enhance
|
||||
* @return {Handler} The handler that was modified (for purposes of chaining extensions)
|
||||
*/
|
||||
export function MenuHandler(handler: Handler<HTMLElement, Text, Document>): Handler<HTMLElement, Text, Document> {
|
||||
handler.documentClass = MenuMathDocumentMixin<A11yDocumentConstructor>(handler.documentClass as any);
|
||||
return handler;
|
||||
}
|
||||
100
node_modules/mathjax-full/ts/ui/menu/MmlVisitor.ts
generated
vendored
Normal file
100
node_modules/mathjax-full/ts/ui/menu/MmlVisitor.ts
generated
vendored
Normal file
|
|
@ -0,0 +1,100 @@
|
|||
/*************************************************************
|
||||
*
|
||||
* Copyright (c) 2019-2022 The MathJax Consortium
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @fileoverview A visitor to serialize MathML taking menu settings into account
|
||||
*
|
||||
* @author dpvc@mathjax.org (Davide Cervone)
|
||||
*/
|
||||
|
||||
import {MathItem} from '../../core/MathItem.js';
|
||||
import {MmlNode} from '../../core/MmlTree/MmlNode.js';
|
||||
import {SerializedMmlVisitor} from '../../core/MmlTree/SerializedMmlVisitor.js';
|
||||
import {OptionList, userOptions} from '../../util/Options.js';
|
||||
|
||||
/*==========================================================================*/
|
||||
|
||||
/**
|
||||
* The visitor to serialize MathML
|
||||
*
|
||||
* @template N The HTMLElement node class
|
||||
* @template T The Text node class
|
||||
* @template D The Document class
|
||||
*/
|
||||
export class MmlVisitor<N, T, D> extends SerializedMmlVisitor {
|
||||
|
||||
/**
|
||||
* The options controlling the serialization
|
||||
*/
|
||||
public options: OptionList = {
|
||||
texHints: true, // True means include classes for TeXAtom elements
|
||||
semantics: false, // True means include original form as annotation in a semantics element
|
||||
};
|
||||
|
||||
/**
|
||||
* The MathItem currently being processed
|
||||
*/
|
||||
public mathItem: MathItem<N, T, D> = null;
|
||||
|
||||
/**
|
||||
* @param {MmlNode} node The internal MathML node to serialize
|
||||
* @param {MathItem} math The MathItem for this node
|
||||
* @param {OptionList} options The options controlling the processing
|
||||
* @override
|
||||
*/
|
||||
public visitTree(node: MmlNode, math: MathItem<N, T, D> = null, options: OptionList = {}) {
|
||||
this.mathItem = math;
|
||||
userOptions(this.options, options);
|
||||
return this.visitNode(node, '');
|
||||
}
|
||||
|
||||
/**
|
||||
* @override
|
||||
*/
|
||||
public visitTeXAtomNode(node: MmlNode, space: string) {
|
||||
if (this.options.texHints) {
|
||||
return super.visitTeXAtomNode(node, space);
|
||||
}
|
||||
if (node.childNodes[0] && node.childNodes[0].childNodes.length === 1) {
|
||||
return this.visitNode(node.childNodes[0], space);
|
||||
}
|
||||
return space + '<mrow' + this.getAttributes(node) + '>\n'
|
||||
+ this.childNodeMml(node, space + ' ', '\n')
|
||||
+ space + '</mrow>';
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {MmlNode} node The math node to visit
|
||||
* @param {string} space The number of spaces to use for indentation
|
||||
* @returns {string} The serialized math element
|
||||
*/
|
||||
public visitMathNode(node: MmlNode, space: string): string {
|
||||
if (!this.options.semantics || this.mathItem.inputJax.name !== 'TeX') {
|
||||
return super.visitDefault(node, space);
|
||||
}
|
||||
const addRow = node.childNodes.length && node.childNodes[0].childNodes.length > 1;
|
||||
return space + '<math' + this.getAttributes(node) + '>\n'
|
||||
+ space + ' <semantics>\n'
|
||||
+ (addRow ? space + ' <mrow>\n' : '')
|
||||
+ this.childNodeMml(node, space + (addRow ? ' ' : ' '), '\n')
|
||||
+ (addRow ? space + ' </mrow>\n' : '')
|
||||
+ space + ' <annotation encoding="application/x-tex">' + this.mathItem.math + '</annotation>\n'
|
||||
+ space + ' </semantics>\n'
|
||||
+ space + '</math>';
|
||||
}
|
||||
|
||||
}
|
||||
82
node_modules/mathjax-full/ts/ui/menu/SelectableInfo.ts
generated
vendored
Normal file
82
node_modules/mathjax-full/ts/ui/menu/SelectableInfo.ts
generated
vendored
Normal file
|
|
@ -0,0 +1,82 @@
|
|||
/*************************************************************
|
||||
*
|
||||
* Copyright (c) 2019-2022 The MathJax Consortium
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @fileoverview An info box that allows text selection and has copy-to-clipboard functions
|
||||
*
|
||||
* @author dpvc@mathjax.org (Davide Cervone)
|
||||
*/
|
||||
|
||||
import {Info} from 'mj-context-menu/js/info.js';
|
||||
import {HtmlClasses} from 'mj-context-menu/js/html_classes.js';
|
||||
|
||||
/*==========================================================================*/
|
||||
|
||||
/**
|
||||
* The SelectableInfo class definition
|
||||
*/
|
||||
export class SelectableInfo extends Info {
|
||||
|
||||
/**
|
||||
* Add a keypress event to handle "select all" so that only
|
||||
* the info-box's text is selected (not the whole page)
|
||||
*
|
||||
* @override
|
||||
*/
|
||||
public addEvents(element: HTMLElement) {
|
||||
element.addEventListener('keypress', (event: KeyboardEvent) => {
|
||||
if (event.key === 'a' && (event.ctrlKey || event.metaKey)) {
|
||||
this.selectAll();
|
||||
this.stop(event);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Select all the main text of the info box
|
||||
*/
|
||||
public selectAll() {
|
||||
const selection = document.getSelection();
|
||||
selection.selectAllChildren(this.html.querySelector('pre'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Implement the copy-to-clipboard action
|
||||
*/
|
||||
public copyToClipboard() {
|
||||
this.selectAll();
|
||||
try {
|
||||
document.execCommand('copy');
|
||||
} catch (err) {
|
||||
alert('Can\'t copy to clipboard: ' + err.message);
|
||||
}
|
||||
document.getSelection().removeAllRanges();
|
||||
}
|
||||
|
||||
/**
|
||||
* Attach the copy-to-clipboard action to its button
|
||||
*/
|
||||
public generateHtml() {
|
||||
super.generateHtml();
|
||||
const footer = this.html.querySelector('span.' + HtmlClasses['INFOSIGNATURE']);
|
||||
const button = footer.appendChild(document.createElement('input'));
|
||||
button.type = 'button';
|
||||
button.value = 'Copy to Clipboard';
|
||||
button.addEventListener('click', (_event: MouseEvent) => this.copyToClipboard());
|
||||
}
|
||||
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue