www

Unnamed repository; edit this file 'description' to name the repository.
Log | Files | Refs | README | LICENSE

menclose.js (15341B)


      1 /* -*- Mode: Javascript; indent-tabs-mode:nil; js-indent-level: 2 -*- */
      2 /* vim: set ts=2 et sw=2 tw=80: */
      3 
      4 /*************************************************************
      5  *
      6  *  MathJax/jax/output/HTML-CSS/autoload/menclose.js
      7  *  
      8  *  Implements the HTML-CSS output for <menclose> elements.
      9  *
     10  *  ---------------------------------------------------------------------
     11  *  
     12  *  Copyright (c) 2010-2015 The MathJax Consortium
     13  * 
     14  *  Licensed under the Apache License, Version 2.0 (the "License");
     15  *  you may not use this file except in compliance with the License.
     16  *  You may obtain a copy of the License at
     17  * 
     18  *      http://www.apache.org/licenses/LICENSE-2.0
     19  * 
     20  *  Unless required by applicable law or agreed to in writing, software
     21  *  distributed under the License is distributed on an "AS IS" BASIS,
     22  *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     23  *  See the License for the specific language governing permissions and
     24  *  limitations under the License.
     25  */
     26 
     27 MathJax.Hub.Register.StartupHook("HTML-CSS Jax Ready",function () {
     28   var VERSION = "2.6.0";
     29   var MML = MathJax.ElementJax.mml,
     30       HTMLCSS = MathJax.OutputJax["HTML-CSS"];
     31   
     32   var SVGNS = "http://www.w3.org/2000/svg";
     33   var VMLNS = "urn:schemas-microsoft-com:vml";
     34   var vmlns = "mjxvml";
     35 
     36   MML.menclose.Augment({
     37     toHTML: function (span) {
     38       var values = this.getValues("notation","thickness","padding","mathcolor","color");
     39       if (values.color && !this.mathcolor) {values.mathcolor = values.color}
     40       if (values.thickness == null) {values.thickness = ".075em"}
     41       if (values.padding == null)   {values.padding   = ".2em"}
     42       span = this.HTMLcreateSpan(span);
     43       var mu = this.HTMLgetMu(span), scale = this.HTMLgetScale();
     44       var p = HTMLCSS.length2em(values.padding,mu,1/HTMLCSS.em) * scale;   // padding for enclosure
     45       var t = HTMLCSS.length2em(values.thickness,mu,1/HTMLCSS.em) * scale; // thickness of lines
     46       t = Math.max(1/HTMLCSS.em,t); // see issue #414
     47       var SOLID = HTMLCSS.Em(t)+" solid";
     48 
     49       var stack = HTMLCSS.createStack(span);
     50       var base = HTMLCSS.createBox(stack);
     51       this.HTMLmeasureChild(0,base);
     52       var H = base.bbox.h+p+t, D = base.bbox.d+p+t, W = base.bbox.w+2*(p+t);
     53       var frame = HTMLCSS.createFrame(stack,H+D,0,W,t,"none");
     54       frame.id = "MathJax-frame-"+this.spanID;
     55       HTMLCSS.addBox(stack,frame); stack.insertBefore(frame,base); // move base to above background
     56       var T = 0, B = 0, R = 0, L = 0, dx = 0, dy = 0; var svg, vml;
     57       var w, h, r;
     58       if (!values.mathcolor) {values.mathcolor = "black"} else {span.style.color = values.mathcolor}
     59 
     60       // perform some reduction e.g. eliminate duplicate notations.
     61       var nl = MathJax.Hub.SplitList(values.notation), notation = {};
     62       for (var i = 0, m = nl.length; i < m; i++) notation[nl[i]] = true;
     63       if (notation[MML.NOTATION.UPDIAGONALARROW]) notation[MML.NOTATION.UPDIAGONALSTRIKE] = false;
     64 
     65       var line;
     66       for (var n in notation) {
     67         if (!notation.hasOwnProperty(n) || !notation[n]) continue;
     68         switch (n) {
     69          case MML.NOTATION.BOX:
     70            frame.style.border = SOLID; if (!HTMLCSS.msieBorderWidthBug) {T = B = L = R = t}
     71            break;
     72 
     73           case MML.NOTATION.ROUNDEDBOX:
     74             if (HTMLCSS.useVML) {
     75               if (!vml) {vml = this.HTMLvml(stack,H,D,W,t,values.mathcolor)}
     76               // roundrect.arcsize can't be set in IE8 standards mode, so use a path
     77               r = Math.floor(1000*Math.min(W,H+D)-2*t);
     78               w = Math.floor(4000*(W-2*t)), h = Math.floor(4000*(H+D-2*t));
     79               this.HTMLvmlElement(vml,"shape",{
     80                 style: {width:this.HTMLpx(W-2*t),height:this.HTMLpx(H+D-2*t),
     81                         left:this.HTMLpx(t,.5),top:this.HTMLpx(t,.5)},
     82                 path: "m "+r+",0 qx 0,"+r+" l 0,"+(h-r)+" qy "+r+","+h+" "+
     83                       "l "+(w-r)+","+h+" qx "+w+","+(h-r)+" l "+w+","+r+" qy "+(w-r)+",0 x e",
     84                 coordsize: w+","+h
     85               });
     86             } else {
     87               if (!svg) {svg = this.HTMLsvg(stack,H,D,W,t,values.mathcolor)}
     88               this.HTMLsvgElement(svg.firstChild,"rect",{
     89                 x:1, y:1, width:this.HTMLpx(W-t)-1,
     90                 height:this.HTMLpx(H+D-t)-1, rx:this.HTMLpx(Math.min(H+D,W)/4)
     91               });
     92             }
     93             break;
     94             
     95           case MML.NOTATION.CIRCLE:
     96             if (HTMLCSS.useVML) {
     97               if (!vml) {vml = this.HTMLvml(stack,H,D,W,t,values.mathcolor)}
     98               this.HTMLvmlElement(vml,"oval",{
     99                 style: {width:this.HTMLpx(W-2*t),height:this.HTMLpx(H+D-2*t),
    100                         left:this.HTMLpx(t,.5),top:this.HTMLpx(t,.5)}
    101               });
    102             } else {
    103               if (!svg) {svg = this.HTMLsvg(stack,H,D,W,t,values.mathcolor)}
    104               this.HTMLsvgElement(svg.firstChild,"ellipse",{
    105                 rx:this.HTMLpx(W/2-t), ry:this.HTMLpx((H+D)/2-t),
    106                 cx:this.HTMLpx(W/2), cy:this.HTMLpx((H+D)/2)
    107               });
    108             }
    109             break;
    110 
    111           case MML.NOTATION.LEFT:
    112             frame.style.borderLeft = SOLID; if (!HTMLCSS.msieBorderWidthBug) {L = t}
    113             break;
    114             
    115           case MML.NOTATION.ACTUARIAL:
    116             frame.style.borderTop = SOLID; if (!HTMLCSS.msieBorderWidthBug) {T = t; frame.bbox.w += p-t}
    117           case MML.NOTATION.RIGHT:
    118             frame.style.borderRight = SOLID; if (!HTMLCSS.msieBorderWidthBug) {R = t}
    119             break;
    120 
    121           case MML.NOTATION.VERTICALSTRIKE:
    122             line = HTMLCSS.createRule(stack,H+D-t/2,0,t);
    123             HTMLCSS.addBox(stack,line); HTMLCSS.placeBox(line,p+t+base.bbox.w/2,-D,true);
    124             break;
    125             
    126           case MML.NOTATION.TOP:
    127             frame.style.borderTop = SOLID; if (!HTMLCSS.msieBorderWidthBug) {T = t}
    128             break;
    129             
    130           case MML.NOTATION.BOTTOM:
    131             frame.style.borderBottom = SOLID; if (!HTMLCSS.msieBorderWidthBug) {B = t}
    132             break;
    133             
    134           case MML.NOTATION.HORIZONTALSTRIKE:
    135             line = HTMLCSS.createRule(stack,t,0,W-t/2);
    136             HTMLCSS.addBox(stack,line); HTMLCSS.placeBox(line,0,(H+D)/2-D,true);
    137             break;
    138 
    139           case MML.NOTATION.UPDIAGONALSTRIKE:
    140             if (HTMLCSS.useVML) {
    141               if (!vml) {vml = this.HTMLvml(stack,H,D,W,t,values.mathcolor)}
    142               line = this.HTMLvmlElement(vml,"line",{from: "0,"+this.HTMLpx(H+D-t), to: this.HTMLpx(W)+",0"});
    143             } else {
    144               if (!svg) {svg = this.HTMLsvg(stack,H,D,W,t,values.mathcolor)}
    145               this.HTMLsvgElement(svg.firstChild,"line",{
    146                 x1:1, y1:this.HTMLpx(H+D-t), x2:this.HTMLpx(W-t), y2:this.HTMLpx(t)
    147               });
    148             }
    149             break;
    150 
    151           case MML.NOTATION.UPDIAGONALARROW:
    152             if (HTMLCSS.useVML) {
    153               if (!vml) {vml = this.HTMLvml(stack,H,D,W,t,values.mathcolor)}
    154               line = this.HTMLvmlElement(vml,"line",{from: "0,"+this.HTMLpx(H+D-t), to: this.HTMLpx(W)+","+this.HTMLpx(t)});
    155               this.HTMLvmlElement(line,"stroke",{endarrow:"classic"});
    156             } else {
    157               if (!svg) {svg = this.HTMLsvg(stack,H,D,W,t,values.mathcolor)}
    158               var l = Math.sqrt(W*W + (H+D)*(H+D)), f = 1/l * 10*this.scale/HTMLCSS.em * t/.075;
    159               w = W * f; h = (H+D) * f; var x = W - t/2, y = t/2;
    160               if (y+h-.4*w < 0) {y = .4*w-h}
    161               this.HTMLsvgElement(svg.firstChild,"line",{
    162                 x1:1, y1:this.HTMLpx(H+D-t), x2:this.HTMLpx(x-.7*w), y2:this.HTMLpx(y+.7*h)
    163               });
    164               this.HTMLsvgElement(svg.firstChild,"polygon",{
    165                 points: this.HTMLpx(x)+","+this.HTMLpx(y)+" "
    166                        +this.HTMLpx(x-w-.4*h)+","+this.HTMLpx(y+h-.4*w)+" "
    167                        +this.HTMLpx(x-.7*w)+","+this.HTMLpx(y+.7*h)+" "
    168                        +this.HTMLpx(x-w+.4*h)+","+this.HTMLpx(y+h+.4*w)+" "
    169                        +this.HTMLpx(x)+","+this.HTMLpx(y),
    170                  fill:values.mathcolor, stroke:"none"
    171               });
    172             }
    173             break;
    174 
    175           case MML.NOTATION.DOWNDIAGONALSTRIKE:
    176             if (HTMLCSS.useVML) {
    177               if (!vml) {vml = this.HTMLvml(stack,H,D,W,t,values.mathcolor)}
    178               this.HTMLvmlElement(vml,"line",{from: "0,0", to: this.HTMLpx(W)+","+this.HTMLpx(H+D-t)});
    179             } else {
    180               if (!svg) {svg = this.HTMLsvg(stack,H,D,W,t,values.mathcolor)}
    181               this.HTMLsvgElement(svg.firstChild,"line",{
    182                 x1:1, y1:this.HTMLpx(t), x2:this.HTMLpx(W-t), y2:this.HTMLpx(H+D-t)
    183               });
    184             }
    185             break;
    186             
    187           case MML.NOTATION.PHASORANGLE:
    188             W -= 2*p; p = (H+D)/2; W += p;
    189             if (HTMLCSS.useVML) {
    190               if (!vml) {vml = this.HTMLvml(stack,H,D,W,t,values.mathcolor)}
    191               this.HTMLvmlElement(vml,"shape",{
    192                 style: {width:this.HTMLpx(W), height:this.HTMLpx(H+D)},
    193                 path: "m "+this.HTMLpt(p+t/2,t/2)+
    194                       " l "+this.HTMLpt(t/2,H+D-t)+" "+this.HTMLpt(W-t/2,H+D-t)+" e",
    195                 coordsize: this.HTMLpt(W,H+D)
    196               });
    197               
    198             } else {
    199               if (!svg) {svg = this.HTMLsvg(stack,H,D,W,t,values.mathcolor)}
    200               this.HTMLsvgElement(svg.firstChild,"path",{
    201                 d: "M "+this.HTMLpx(p)+",1" +
    202                    "L 1,"+this.HTMLpx(H+D-t)+" L "+this.HTMLpx(W)+","+this.HTMLpx(H+D-t)
    203               });
    204               HTMLCSS.placeBox(svg.parentNode,0,-D,true);
    205             }
    206             break;
    207 
    208           case MML.NOTATION.MADRUWB:
    209             frame.style.borderBottom = SOLID;
    210             frame.style.borderRight = SOLID; if (!HTMLCSS.msieBorderWidthBug) {B = R = t}
    211             break;
    212 
    213           case MML.NOTATION.RADICAL:
    214             if (HTMLCSS.useVML) {
    215               if (!vml) {vml = this.HTMLvml(stack,H,D,W,t,values.mathcolor)}
    216               this.HTMLvmlElement(vml,"shape",{
    217                 style: {width:this.HTMLpx(W), height:this.HTMLpx(H+D)},
    218                 path: "m "+this.HTMLpt(t/2,.6*(H+D))+" l "+this.HTMLpt(p,H+D-t)+" "+
    219                            this.HTMLpt(2*p,t/2)+" "+this.HTMLpt(W,t/2)+" e",
    220                 coordsize: this.HTMLpt(W,H+D)
    221               });
    222               dx = p;
    223             } else {
    224               if (!svg) {svg = this.HTMLsvg(stack,H,D,W,t,values.mathcolor)}
    225               this.HTMLsvgElement(svg.firstChild,"path",{
    226                 d: "M 1,"+this.HTMLpx(.6*(H+D)) +
    227                   " L "+this.HTMLpx(p)+","+this.HTMLpx(H+D) +
    228                   " L "+this.HTMLpx(2*p)+",1 L "+this.HTMLpx(W)+",1"
    229               });
    230               HTMLCSS.placeBox(svg.parentNode,0,p/2-D,true);
    231               dx = p; dy = t;
    232             }
    233             break;
    234             
    235           case MML.NOTATION.LONGDIV:
    236             if (HTMLCSS.useVML) {
    237               if (!vml) {vml = this.HTMLvml(stack,H,D,W,t,values.mathcolor)}
    238               this.HTMLvmlElement(vml,"line",{from: "0,"+this.HTMLpx(t/2), to: this.HTMLpx(W-t)+","+this.HTMLpx(t/2)});
    239               this.HTMLvmlElement(vml,"arc",{
    240                 style: {width:this.HTMLpx(2*p),height:this.HTMLpx(H+D-2*t),
    241                         left:this.HTMLpx(-p),top:this.HTMLpx(t)},
    242                 startangle:"10", endangle:"170"
    243               });
    244               dx = p;
    245             } else {
    246               if (!svg) {svg = this.HTMLsvg(stack,H,D,W,t,values.mathcolor)}
    247               this.HTMLsvgElement(svg.firstChild,"path",{
    248                 d: "M "+this.HTMLpx(W)+",1 L 1,1 "+
    249                    "a"+this.HTMLpx(p)+","+this.HTMLpx((H+D)/2-t)+" 0 0,1 1,"+this.HTMLpx(H+D-2*t)
    250               });
    251               HTMLCSS.placeBox(svg.parentNode,0,t-D,true);
    252               dx = p; dy = t;
    253             }
    254             break;
    255         }
    256       }
    257       frame.style.width = HTMLCSS.Em(W-L-R); frame.style.height = HTMLCSS.Em(H+D-T-B);
    258       HTMLCSS.placeBox(frame,0,dy-D,true);
    259       HTMLCSS.placeBox(base,dx+p+t,0);
    260       this.HTMLhandleSpace(span);
    261       this.HTMLhandleColor(span);
    262       return span;
    263     },
    264     
    265     HTMLpx: function (n) {return (n*HTMLCSS.em)},
    266     HTMLpt: function (x,y) {return Math.floor(1000*x)+','+Math.floor(1000*y)},
    267     
    268     HTMLhandleColor: function (span) {
    269       var frame = document.getElementById("MathJax-frame-"+this.spanID);
    270       if (frame) {
    271         // mathcolor is handled in toHTML above
    272         var values = this.getValues("mathbackground","background");
    273         if (this.style && span.style.backgroundColor) {
    274           values.mathbackground = span.style.backgroundColor;
    275           span.style.backgroundColor = "";
    276         }
    277         if (values.background && !this.mathbackground) {values.mathbackground = values.background}
    278         if (values.mathbackground && values.mathbackground !== MML.COLOR.TRANSPARENT)
    279           {frame.style.backgroundColor = values.mathbackground}
    280       } else {this.SUPER(arguments).HTMLhandleColor.call(this,span)}
    281     },
    282     
    283     HTMLsvg: function (stack,H,D,W,t,color) {
    284       var svg = document.createElementNS(SVGNS,"svg");
    285       if (svg.style) {svg.style.width = HTMLCSS.Em(W); svg.style.height = HTMLCSS.Em(H+D)}
    286       var scale = HTMLCSS.createBox(stack); scale.appendChild(svg);
    287       HTMLCSS.placeBox(scale,0,-D,true);
    288       this.HTMLsvgElement(svg,"g",{fill:"none", stroke:color, "stroke-width":t*HTMLCSS.em});
    289       return svg;
    290     },
    291     HTMLsvgElement: function (svg,type,def) {
    292       var obj = document.createElementNS(SVGNS,type); obj.isMathJax = true;
    293       if (def) {for (var id in def) {if (def.hasOwnProperty(id)) {obj.setAttributeNS(null,id,def[id].toString())}}}
    294       svg.appendChild(obj);
    295       return obj;
    296     },
    297     HTMLvml: function (stack,H,D,W,t,color) {
    298       var vml = HTMLCSS.createFrame(stack,H+D,0,W,0,"none");
    299       HTMLCSS.addBox(stack,vml); HTMLCSS.placeBox(vml,0,-D,true);
    300       this.constructor.VMLcolor = color; this.constructor.VMLthickness = this.HTMLpx(t);
    301       return vml;
    302     },
    303     HTMLvmlElement: function (vml,type,def) {
    304       var obj = HTMLCSS.addElement(vml,vmlns+":"+type,{isMathJax:true});
    305       obj.style.position = "absolute"; obj.style.left = obj.style.top = 0;
    306       MathJax.Hub.Insert(obj,def); // IE8 needs to do this after obj is added to the page
    307       if (!def.fillcolor) {obj.fillcolor = "none"}
    308       if (!def.strokecolor) {obj.strokecolor = this.constructor.VMLcolor}
    309       if (!def.strokeweight) {obj.strokeweight =this.constructor.VMLthickness}
    310       return obj;
    311     }
    312   });
    313   
    314   MathJax.Hub.Browser.Select({
    315     MSIE: function (browser) {
    316       //
    317       //  IE8 and below doesn't have SVG, so use VML
    318       //
    319       if ((document.documentMode||0) < 9) {
    320         MML.menclose.Augment({HTMLpx: function (n,d) {return (n*HTMLCSS.em+(d||0))+"px"}});
    321         HTMLCSS.useVML = true;
    322         if (!document.namespaces[vmlns]) {
    323           if (document.documentMode && document.documentMode === 8) {
    324             document.namespaces.add(vmlns,VMLNS,"#default#VML");
    325           } else {
    326             document.namespaces.add(vmlns,VMLNS);
    327             document.createStyleSheet().addRule(vmlns+"\\: *","{behavior: url(#default#VML)}");
    328           }
    329         }
    330       }
    331     }
    332   });
    333 
    334   
    335   MathJax.Hub.Startup.signal.Post("HTML-CSS menclose Ready");
    336   MathJax.Ajax.loadComplete(HTMLCSS.autoloadDir+"/menclose.js");
    337   
    338 });
    339