munderover.ts 7.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236
  1. /*************************************************************
  2. *
  3. * Copyright (c) 2017-2022 The MathJax Consortium
  4. *
  5. * Licensed under the Apache License, Version 2.0 (the "License");
  6. * you may not use this file except in compliance with the License.
  7. * You may obtain a copy of the License at
  8. *
  9. * http://www.apache.org/licenses/LICENSE-2.0
  10. *
  11. * Unless required by applicable law or agreed to in writing, software
  12. * distributed under the License is distributed on an "AS IS" BASIS,
  13. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  14. * See the License for the specific language governing permissions and
  15. * limitations under the License.
  16. */
  17. /**
  18. * @fileoverview Implements the CHTMLmunderover wrapper for the MmlMunderover object
  19. * and the special cases CHTMLmunder and CHTMLmsup
  20. *
  21. * @author dpvc@mathjax.org (Davide Cervone)
  22. */
  23. import {CHTMLWrapper, Constructor} from '../Wrapper.js';
  24. import {CHTMLmsubsup, CHTMLmsub, CHTMLmsup} from './msubsup.js';
  25. import {CommonMunderMixin} from '../../common/Wrappers/munderover.js';
  26. import {CommonMoverMixin} from '../../common/Wrappers/munderover.js';
  27. import {CommonMunderoverMixin} from '../../common/Wrappers/munderover.js';
  28. import {MmlMunderover, MmlMunder, MmlMover} from '../../../core/MmlTree/MmlNodes/munderover.js';
  29. import {StyleList} from '../../../util/StyleList.js';
  30. /*****************************************************************/
  31. /**
  32. * The CHTMLmunder wrapper for the MmlMunder object
  33. *
  34. * @template N The HTMLElement node class
  35. * @template T The Text node class
  36. * @template D The Document class
  37. */
  38. // @ts-ignore
  39. export class CHTMLmunder<N, T, D> extends
  40. CommonMunderMixin<CHTMLWrapper<any, any, any>, Constructor<CHTMLmsub<any, any, any>>>(CHTMLmsub) {
  41. /**
  42. * The munder wrapper
  43. */
  44. public static kind = MmlMunder.prototype.kind;
  45. /**
  46. * @override
  47. */
  48. public static styles: StyleList = {
  49. 'mjx-over': {
  50. 'text-align': 'left'
  51. },
  52. 'mjx-munder:not([limits="false"])': {
  53. display: 'inline-table',
  54. },
  55. 'mjx-munder > mjx-row': {
  56. 'text-align': 'left'
  57. },
  58. 'mjx-under': {
  59. 'padding-bottom': '.1em' // big_op_spacing5
  60. }
  61. };
  62. /**
  63. * @override
  64. */
  65. public toCHTML(parent: N) {
  66. if (this.hasMovableLimits()) {
  67. super.toCHTML(parent);
  68. this.adaptor.setAttribute(this.chtml, 'limits', 'false');
  69. return;
  70. }
  71. this.chtml = this.standardCHTMLnode(parent);
  72. const base = this.adaptor.append(
  73. this.adaptor.append(this.chtml, this.html('mjx-row')) as N,
  74. this.html('mjx-base')
  75. ) as N;
  76. const under = this.adaptor.append(
  77. this.adaptor.append(this.chtml, this.html('mjx-row')) as N,
  78. this.html('mjx-under')
  79. ) as N;
  80. this.baseChild.toCHTML(base);
  81. this.scriptChild.toCHTML(under);
  82. const basebox = this.baseChild.getOuterBBox();
  83. const underbox = this.scriptChild.getOuterBBox();
  84. const k = this.getUnderKV(basebox, underbox)[0];
  85. const delta = (this.isLineBelow ? 0 : this.getDelta(true));
  86. this.adaptor.setStyle(under, 'paddingTop', this.em(k));
  87. this.setDeltaW([base, under], this.getDeltaW([basebox, underbox], [0, -delta]));
  88. this.adjustUnderDepth(under, underbox);
  89. }
  90. }
  91. /*****************************************************************/
  92. /**
  93. * The CHTMLmover wrapper for the MmlMover object
  94. *
  95. * @template N The HTMLElement node class
  96. * @template T The Text node class
  97. * @template D The Document class
  98. */
  99. // @ts-ignore
  100. export class CHTMLmover<N, T, D> extends
  101. CommonMoverMixin<CHTMLWrapper<any, any, any>, Constructor<CHTMLmsup<any, any, any>>>(CHTMLmsup) {
  102. /**
  103. * The mover wrapper
  104. */
  105. public static kind = MmlMover.prototype.kind;
  106. /**
  107. * @override
  108. */
  109. public static styles: StyleList = {
  110. 'mjx-mover:not([limits="false"])': {
  111. 'padding-top': '.1em' // big_op_spacing5
  112. },
  113. 'mjx-mover:not([limits="false"]) > *': {
  114. display: 'block',
  115. 'text-align': 'left'
  116. }
  117. };
  118. /**
  119. * @override
  120. */
  121. public toCHTML(parent: N) {
  122. if (this.hasMovableLimits()) {
  123. super.toCHTML(parent);
  124. this.adaptor.setAttribute(this.chtml, 'limits', 'false');
  125. return;
  126. }
  127. this.chtml = this.standardCHTMLnode(parent);
  128. const over = this.adaptor.append(this.chtml, this.html('mjx-over')) as N;
  129. const base = this.adaptor.append(this.chtml, this.html('mjx-base')) as N;
  130. this.scriptChild.toCHTML(over);
  131. this.baseChild.toCHTML(base);
  132. const overbox = this.scriptChild.getOuterBBox();
  133. const basebox = this.baseChild.getOuterBBox();
  134. this.adjustBaseHeight(base, basebox);
  135. const k = this.getOverKU(basebox, overbox)[0];
  136. const delta = (this.isLineAbove ? 0 : this.getDelta());
  137. this.adaptor.setStyle(over, 'paddingBottom', this.em(k));
  138. this.setDeltaW([base, over], this.getDeltaW([basebox, overbox], [0, delta]));
  139. this.adjustOverDepth(over, overbox);
  140. }
  141. }
  142. /*****************************************************************/
  143. /*
  144. * The CHTMLmunderover wrapper for the MmlMunderover object
  145. *
  146. * @template N The HTMLElement node class
  147. * @template T The Text node class
  148. * @template D The Document class
  149. */
  150. // @ts-ignore
  151. export class CHTMLmunderover<N, T, D> extends
  152. CommonMunderoverMixin<CHTMLWrapper<any, any, any>, Constructor<CHTMLmsubsup<any, any, any>>>(CHTMLmsubsup) {
  153. /**
  154. * The munderover wrapper
  155. */
  156. public static kind = MmlMunderover.prototype.kind;
  157. /**
  158. * @override
  159. */
  160. public static styles: StyleList = {
  161. 'mjx-munderover:not([limits="false"])': {
  162. 'padding-top': '.1em' // big_op_spacing5
  163. },
  164. 'mjx-munderover:not([limits="false"]) > *': {
  165. display: 'block'
  166. },
  167. };
  168. /**
  169. * @override
  170. */
  171. public toCHTML(parent: N) {
  172. if (this.hasMovableLimits()) {
  173. super.toCHTML(parent);
  174. this.adaptor.setAttribute(this.chtml, 'limits', 'false');
  175. return;
  176. }
  177. this.chtml = this.standardCHTMLnode(parent);
  178. const over = this.adaptor.append(this.chtml, this.html('mjx-over')) as N;
  179. const table = this.adaptor.append(
  180. this.adaptor.append(this.chtml, this.html('mjx-box')) as N,
  181. this.html('mjx-munder')
  182. ) as N;
  183. const base = this.adaptor.append(
  184. this.adaptor.append(table, this.html('mjx-row')) as N,
  185. this.html('mjx-base')
  186. ) as N;
  187. const under = this.adaptor.append(
  188. this.adaptor.append(table, this.html('mjx-row')) as N,
  189. this.html('mjx-under')
  190. ) as N;
  191. this.overChild.toCHTML(over);
  192. this.baseChild.toCHTML(base);
  193. this.underChild.toCHTML(under);
  194. const overbox = this.overChild.getOuterBBox();
  195. const basebox = this.baseChild.getOuterBBox();
  196. const underbox = this.underChild.getOuterBBox();
  197. this.adjustBaseHeight(base, basebox);
  198. const ok = this.getOverKU(basebox, overbox)[0];
  199. const uk = this.getUnderKV(basebox, underbox)[0];
  200. const delta = this.getDelta();
  201. this.adaptor.setStyle(over, 'paddingBottom', this.em(ok));
  202. this.adaptor.setStyle(under, 'paddingTop', this.em(uk));
  203. this.setDeltaW([base, under, over],
  204. this.getDeltaW([basebox, underbox, overbox],
  205. [0, this.isLineBelow ? 0 : -delta, this.isLineAbove ? 0 : delta]));
  206. this.adjustOverDepth(over, overbox);
  207. this.adjustUnderDepth(under, underbox);
  208. }
  209. /**
  210. * Make sure styles get output when called from munderover with movable limits
  211. *
  212. * @override
  213. */
  214. public markUsed() {
  215. super.markUsed();
  216. this.jax.wrapperUsage.add(CHTMLmsubsup.kind);
  217. }
  218. }