Code coverage report for lib/handlers/live-reload.js

Statements: 22.22% (10 / 45)      Branches: 7.14% (1 / 14)      Functions: 16.67% (1 / 6)      Lines: 22.22% (10 / 45)      Ignored: none     

All files » lib/handlers/ » live-reload.js
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 1151   1             1         1 3 3                                     1                                                                 1                               1                                 1                          
module.exports = handleLiveReload
 
var responsify = require('response-stream')
  , inject = require('script-injector')
  , through = require('through')
  , watchr = require('watchr')
  , path = require('path')
  , fs = require('fs')
 
var liveReloadCode = fs.readFileSync(
    path.join(__dirname, '..', 'frontend-js', 'live-reload.js')
  , 'utf8'
)
 
function handleLiveReload(opts, io, nextHandler) {
  Eif(!opts.live) {
    return nextHandler
  }
 
  var lastUpdate = Date.now()
    , pending = []
 
  watchr.watch({
      path: opts.cwd
    , listener: onupdate
    , ignoreHiddenFiles: true
    , ignorePatterns: true
  })
 
  opts = opts.live
  opts.rate = +opts.rate || 1000
  opts.rate = Math.max(100, Math.min(opts.rate, 1000))
 
  return handle
 
  function handle(server, req, resp, parsed) {
    if(parsed.pathname === '/-/live-reload') {
      resp.writeHead(200, {'content-type': 'application/json'})
 
      pending.push(function ontimeout() {
        resp.end(JSON.stringify({
            lastUpdate: lastUpdate
        }))
        pending.splice(pending.indexOf(ontimeout), 1)
      })
 
      return setTimeout(pending[pending.length - 1], 60000)
 
    }
 
    // script-injector expects to be able to wrap & execute
    // the incoming code itself. so, we're wrapping it prior
    // to handing it over.
    var liveReloadInjection =   'function live() { (' + liveReloadCode + ')' +
          '(' + lastUpdate + ',' + opts.rate + ') }'
      , injector = inject(liveReloadInjection)
      , lazyResponse
      , piped
 
    lazyResponse = responsify(through())
    injector.pipe(resp)
 
    lazyResponse
      .on('setHeader', setHeaderListener)
      .on('writeHead', writeHeadListener)
 
    return nextHandler(server, req, lazyResponse, parsed)
 
    function setHeaderListener(args, prevent) {
      var isCType = args[0].toLowerCase() === 'content-type'
        , isHTML = args[1].toLowerCase() === 'text/html'
 
      if(isCType) {
        if(isHTML) {
          lazyResponse.pipe(injector)
        } else {
          lazyResponse.pipe(resp)
        }
 
        lazyResponse.removeListener('setHeader', setHeaderListener)
        lazyResponse.removeListener('writeHead', writeHeadListener)
      }
    }
 
    function writeHeadListener(args, prevent) {
      var hasCType = 'content-type' in args[1]
        , isHTML
 
      isHTML = args[1]['content-type'] === 'text/html'
 
      if(hasCType && isHTML) {
        lazyResponse.pipe(injector)
      } else {
        lazyResponse.pipe(resp)
      }
 
      lazyResponse.removeListener('setHeader', setHeaderListener)
      lazyResponse.removeListener('writeHead', writeHeadListener)
    }
  }
 
  function onupdate() {
    lastUpdate = Date.now()
 
    // remove all functions from pending before
    // calling them so we don't have 'em constantly
    // indexOf-ing for themselves for no purpose.
    var queued = pending.splice(0, pending.length)
 
    for(var i = 0, len = queued.length; i < len; ++i) {
      queued[i]()
    }
  }
}