the-riddle
clone your own copy | download snapshot

Snapshots | iceberg

Inside this repository

flow.js
application/javascript

Download raw (3.2 KB)

;(function () {
  // Ensure same names for function swheteher we have webkit's native
  // implementation or throught polyfill
  if ((!document.getNamedFlows) && document.webkitGetNamedFlows) {
    document.getNamedFlows = document.webkitGetNamedFlows;
  }
  
  if (!document.getNamedFlow) {
    document.getNamedFlow = function (name) {
      return document.getNamedFlows(name).namedItem(name);
    }
  }

  'use strict';
  window.fitFlow = function (flow, template, container, isPageTest) {

    // Global parameters
    var batchSize = 50;

    function getStartPage () {
      var selector = "body#" + document.body.id + " #pages",
          stylesheets = document.styleSheets;

      for (var s=0; s < stylesheets.length; s++) {
        var rules = stylesheets[s].cssRules;

        for (var r=0; r < rules.length;r++) {
          if (rules[r].selectorText == selector) {
            return parseInt(/\d+/.exec(rules[r].style.counterReset)[0]);
          }
        }
      }
    }
  
    function makeEvent(name) {
      var e = document.createEvent("Event");
      e.initEvent(name, false, true);
      return e;
    }

    function getPageForRegion (node) {
      while(!isPageTest(node)) {
        node = node.parentNode;
      }

      return node;
    }

    function addPagesIfNecessary () {
      var page,
          num = document.querySelectorAll('.paper').length + getStartPage(),
          regions = flow.getRegions();
    
      if ((document.querySelectorAll('.paper').length) < 1 || regions[regions.length-1].webkitRegionOverset == 'overset') {
        console.log('adding pages');
        for (var i=0;i<batchSize;i++) {
          num++;
          page = template.cloneNode(true);
          page.setAttribute('data-page', num);
          page.setAttribute('id', 'page-' + num);
          container.appendChild(page);
        };
      } else {
        flow.dispatchEvent(makeEvent("regionlayoutextendingcomplete"));
      }
    }

    function tighten () {
      // Remove event listeners to avoid bug in webkit where it left one page too many
      flow.removeEventListener("webkitregionoversetchange", addPagesIfNecessary);
      flow.removeEventListener("regionoversetchange", addPagesIfNecessary);

      console.log('Tightning');

      if (flow.firstEmptyRegionIndex > 0) {
        var regions = flow.getRegions(),
            lastPageWithContent = getPageForRegion(regions[(flow.firstEmptyRegionIndex - 1)]);

        while (lastPageWithContent.nextSibling) {
          lastPageWithContent.parentNode.removeChild(lastPageWithContent.nextSibling);
        }

        window.requestAnimationFrame(function () {
          console.log(flow.firstEmptyRegionIndex);
          flow.dispatchEvent(makeEvent("regionlayoutfittingcomplete"));
          flow.dispatchEvent(makeEvent("regionlayoutcomplete"));
          
        });
      }
    }

    flow.dispatchEvent(makeEvent("regionlayoutstart"));
    
    flow.addEventListener("webkitregionoversetchange", addPagesIfNecessary, false);
    flow.addEventListener("regionoversetchange", addPagesIfNecessary, false);
    flow.addEventListener("regionlayoutextendingcomplete", tighten, false);

    if (flow.overset == true) {  
      addPagesIfNecessary();
    } else {
      console.log('flow already fitting?');
    }
  };
})(window, document);