class MagLove::Middleware::LiveReload

Attributes

app[R]
current_template[R]
options[R]

Public Class Methods

new(app, options = {}) click to toggle source
# File lib/maglove/middleware/live_reload.rb, line 8
def initialize(app, options = {})
  @app = app
  @options = options
  @theme = options[:theme]
  @templates = options[:templates]
end

Public Instance Methods

call(env) click to toggle source
# File lib/maglove/middleware/live_reload.rb, line 15
def call(env)
  if env["PATH_INFO"] == @options[:mount]
    request = Rack::Request.new(env)
    @ws = Faye::WebSocket.new(request.env, [], {})
    @ws.onmessage = lambda do |event|
      message = JSON.parse(event.data)
      command = message["command"]
      handle_command(command, message)
    end
    @ws.onclose = ->(event) { clear_watcher! if @watcher }
    @ws.rack_response
  else
    @app.call(env)
  end
end
clear_watcher!() click to toggle source
# File lib/maglove/middleware/live_reload.rb, line 31
def clear_watcher!
  @ws = nil
  @watcher.stop
  @thread.join
  @watcher = nil
  @thread = nil
end
handle_command(command, data = {}) click to toggle source
# File lib/maglove/middleware/live_reload.rb, line 44
def handle_command(command, data = {})
  if command == "init"
    send_command("init", { templates: @templates })
  elsif command == "watch"
    @current_template = data["template"]
    watch
  end
end
send_command(command, data = {}) click to toggle source
# File lib/maglove/middleware/live_reload.rb, line 39
def send_command(command, data = {})
  data[:command] = command
  @ws.send(JSON.dump(data)) if @ws
end
watch() click to toggle source
# File lib/maglove/middleware/live_reload.rb, line 53
def watch
  base_version = Maglove.theme.base_version
  patterns = [
    "src/themes/#{@theme}/**/*.{haml,html,coffee,js,less,scss,css,yml}",
    "src/themes/#{@theme}/images/**/*.{jpg,jpeg,gif,png,svg}",
    "src/base/#{base_version}/**/*.{coffee,js,less,scss,css}",
    "src/base/#{base_version}/images/**/*.{jpg,jpeg,gif,png,svg}"
  ]
  @watcher = FileWatcher.new(patterns.map(&:to_s))
  @thread = Thread.new(@watcher) do |fw|
    fw.watch do |filename, event|
      if Workspace.dir(Dir.pwd).file(filename).exists? and event != :delete
        if filename =~ %r{^src/base/#{base_version}/.*\.coffee}
          path = "theme.coffee"
        elsif filename =~ %r{^src/base/#{base_version}/.*\.js}
          path = "theme.coffee"
        elsif filename =~ %r{^src/base/#{base_version}/.*\.less}
          path = "theme.less"
        elsif filename =~ %r{^src/base/#{base_version}/.*\.scss}
          path = "theme.scss"
        elsif filename =~ %r{^src/themes/#{@theme}/.*\.less}
          path = "theme.less"
        elsif filename =~ %r{^src/themes/#{@theme}/.*\.scss}
          path = "theme.scss"
        elsif filename =~ %r{^src/themes/#{@theme}/.*\.coffee}
          path = "theme.coffee"
        elsif filename =~ %r{^src/themes/#{@theme}/.*\.js}
          path = "theme.js"
        elsif filename =~ %r{^src/themes/#{@theme}/blocks/.*\.haml}
          path = "templates/#{current_template}.haml"
        else
          path = filename.gsub("src/themes/#{@theme}/", '')
        end
        asset = MagLove::Asset::Theme.new(path, { base: false })
        if asset.write!
          puts "▸ #{path} updated"
          case asset.output_type
          when "html"
            template = path.match(%r{templates/(.*)\.haml})[1]
            send_command("html", { template: template, contents: asset.contents })
          when "css"
            send_command("css", { contents: asset.contents })
          when "js"
            send_command("js", { contents: asset.contents })
          end
        end
      end
    end
  end
end