Skip to content
Han Wei edited this page Jun 11, 2012 · 16 revisions

The master branch is currently v0.2 of MathQuill. Its architecture has proven limiting, and we dream of v0.3 featuring a completely overhauled architecture that will address all the flaws of the v0.2 architecture. But before designing how this new, perfect architecture will work, we kinda ought to figure out how the current architecture works (and how it doesn't).

Overview:

  • math is represented by a tree structure of JS objects with pointers to each other, analogous to the HTML DOM
    • each node in tree is associated with an HTML element
    • e.g. for some math represented in LaTeX by x + \frac{ 1 }{ 2 }, the math tree looks like
  root math block [0]
    /      |      \
 x [1]   + [2]   \frac [3]
                 /       \
          numerator     denominator
          block [4]      block [6]
              |              |
            1 [5]          2 [7]

where bracketed numbers indicate associated HTML elements in the HTML tree, which looks like

[0] <span class="mathquill-editable mathquill-rendered-math">
      <span class="textarea">
        <textarea></textarea>
      </span>
  [1] <var>x</var>
  [2] <span class="binary-operator">+</span>
  [3] <span class="fraction">
    [4] <span class="numerator">
      [5] <span>1</span>
        </span>
    [6] <span class="denominator">
      [7] <span>2</span>
        </span>
        <span style="display:inline-block;width:0">&nbsp;</span>
      </span>
      <span class="cursor">&zwj;</span>
    </span>
  • the cursor's methods manipulate the math and HTML trees
    • they also notify each affected math node, which can further manipulate the HTML tree as necessary to render the math correctly
  • to input or edit math, or render LaTeX math, call the cursor's methods
    • typical of keyboard events like backspace or text input

Code paths start 2 ways:

  • initial load
    • classes declared, LatexCmds and CharCmds populated
    • document ready handler registered in publicapi.js that, upon firing, finds all .mathquill-editable, .mathquill-textbox, and .mathquill-embedded-latex elements and renders them accordingly
      • calls createRoot with flags for editable and textbox
      • createRoot in rootelements.js
        • saves the current contents of the span to be MathQuill-ified (ready to be reverted)
        • creates cursor and textarea (and textarea span)
        • renders the current contents of the span as LaTeX math
        • binds mouse, keyboard, clipboard event handlers
  • events
    • terminology:
      • events fire on HTML elements in the HTML DOM
      • we trigger (fake) events on math nodes in the math DOM
      • we bind/unbind event handlers to/from nodes
      • we attach/detach nodes to/from trees
    • overview:
      • focus, blur, keyboard, and clipboard event handlers have to be bound to the textarea
        • keyboard events trigger normalized fake keyboard events to bubble in the math DOM
      • mouse event handlers are bound to every node in the tree the mouse is on, e.g. the <var>x</var>
        • mousedown is the only permanently bound handler, it binds mousemove/up handlers, and the mouseup handler unbinds them again
      • for static math, there is no typing, cutting, pasting, focusing, blurring, or clicking to place the cursor, only dragging to select and copying. For copying the selection, we need a textarea to fill with the selection and select, but we don't want it to be focusable by, say, tabbing to it, so we keep around a detached hidden textarea that we temporarily attach to the DOM while there is a selection and detach when we're done with it (see Mouse Events). This textarea has just one event handler, the same copy event handler that editables have (see Keyboard and Clipboard Events)
    • focus and blur events
      • for static math, their textareas are focused when attached on mousedown and if there's no selection on mouseup, detached. If the user dragged and selected something, when the user goes to do something else and the selection should clear, the blur event fires, so all we need is a blur handler that clears the fake selection and detaches the textarea
      • for editable math,
        • the focus/blur handlers on the root span set focus/blur on the textarea, so that calling .focus()/.blur() on the root span of the editable will make it happen on the textarea
          • this means that the focus/blur handlers on the textarea have to stopPropagation() to prevent an infinite loop. Unfortunately, this is also blocking focusin/out events from bubbling
            • to fix this, in v0.3, there will be an external API to set focus/blur, no handlers on the root span, and no stopPropagation() calls on focus/blur
    • see also: Keyboard and Clipboard Events, Mouse Events

Clone this wiki locally