Learn how to add your own Javascript libraries to Kotobee Author.


Adding your own Javascript libraries can help perform certain functions, such as rendering Mathematical formulae (e.g. KaTeX) or displaying a fancy tooltip (e.g. Tippy). Since Kotobee Author provides you with access to the internal files of the ebook project (via the File Manager), you may import any JS library you need. 


It's important to understand how the Kotobee Reader works, and how it deals with such external Javascript libraries. Though sometimes it's possible to follow the library's corresponding instructions for them to fail the first time around. There are some gotchas you should know about.

Kotobee's parsing

When an ebook is opened, Kotobee's Reader dissects the content and splits each word into its own HTML span tag. That is done in order to provide text-selection at the word level. If you are entering some special code inside a tag that is to be rendered by a library (as is the case with KaTeX for rendering a formula), by the time the library finds the text, it will not understand it. That is because it will have already been parsed and divided into separate pieces (assuming there are spaces) by the reader.


The solution is to add the class "parsed" to a tag that does not need parsing. As an example with a KaTeX formula, assume the following code:


<p>\[\int_1^\pi \sin x \mathrm{d} x\]</p>


The default behavior is that it will be parsed into the following:


<p>
  <span>\[\int_1^\pi </span>
  <span>\sin </span>
  <span>x </span>
  <span>\mathrm{d} </span>
  <span>x\]</span>
</p>


To avoid this and have the entire content attached together as one piece, simply add the class "parsed" as follows:


<p class="parsed">\[\int_1^\pi \sin x \mathrm{d} x\]</p>

Waiting for the DOM

The standard way of dealing with Javascript libraries that require rendering HTML in the DOM is to wait for the DOM to load and become ready. This is done in several ways, such as:


document.addEventListener("DOMContentLoaded", ready);


or


window.addEventListener("onload", ready);


Although this is the correct way to initiate executing any Javascript in your page, this causes an issue in Kotobee. Basically, the DOM in Kotobee is loaded just once for the entire app. Hence these events will be triggered just once. Whenever a chapter is loaded that relies on these DOM-ready events, they will never be triggered. Thus, the binding Javascript will never be executed. The way around this is to execute functions directly without wrapping them in such listeners. 


In the case of KaTeX, instead of having the Javascript code as such:


<script>
document.addEventListener("DOMContentLoaded", function() {
        renderMathInElement(document.body,
          {
              delimiters: [
                  {left: "$", right: "$", display: true},
                  {left: "\\[", right: "\\]", display: true},
                  {left: "$", right: "$", display: false},
                  {left: "\\(", right: "\\)", display: false}
              ]
          }                               
); 
</script>


It will become:


<script>
        renderMathInElement(document.body,
          {
              delimiters: [
                  {left: "$", right: "$", display: true},
                  {left: "\\[", right: "\\]", display: true},
                  {left: "$", right: "$", display: false},
                  {left: "\\(", right: "\\)", display: false}
              ]
          }                               
</script>


If you are planning to use the ebook on various readers including Kotobee Reader, then you may do a simple check to find out whether it is being run on Kotobee Reader with the following Javascript:


if(typeof isKotobee != "undefined")


In the near future, we will be applying smarter ways to automatically bypass DOM-ready events, without you having to enter any custom code.