At some point in time, you may want to add your own Javascript libraries to perform certain functionality, such as rendering Mathematical formulae (e.g. KaTeX) or displaying a fancy tooltip (e.g. Tippy). Since Kotobee Author transparently provides you with access to the internal files of the ebook project (via the File Manager) you may import any JS library you need. If you have already tried and followed the library's corresponding instructions, it's possible that it may not have worked from the first time. That is because it's important to understand how the Kotobee Reader works, and how it deals with such external Javascript libraries. There are some gotchas that you need to be very well-aware of.



Kotobee's parsing


When any 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 in 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 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. Hence 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.