Sha256: 19079e33e346b0cc5196eb722908bf16b92640adeb417952ca5a68e93f54c92b

Contents?: true

Size: 1.68 KB

Versions: 1

Compression:

Stored size: 1.68 KB

Contents

begin
  require 'md5'
rescue LoadError
  require 'digest/md5'
end

class Rack::PageSpeed::Filters::CombineJavaScripts < Rack::PageSpeed::Filter
  requires_store
  name      'combine_javascripts'
  priority  2
  
  def execute! document
    nodes = document.css('script[src]')
    return false unless nodes.count > 0
    groups = group_siblings topmost_of_sequence(nodes)
    groups.each do |group|
      save group
      merged = merge group, document
      group.first.before merged
      group.map { |node| node.remove }
    end
  end

  private
  def save nodes
    contents = nodes.map { |node| file_for(node).read rescue "" }.join(';')
    nodes_id = unique_id nodes
    @options[:store]["#{nodes_id}.js"] = contents
  end
  
  def merge nodes, document
    nodes_id = unique_id nodes
    node = Nokogiri::XML::Node.new 'script', document
    node['src'] = "/rack-pagespeed-#{nodes_id}.js"
    node
  end
  
  def local_script? node
    node.name == 'script' and file_for(node)
  end
  
  def topmost_of_sequence nodes
    result = []
    nodes.each do |node|
      _previous, _next = node.previous_sibling, node.next_sibling
      if _previous && local_script?(_previous) &&
        (!_next || !file_for(_next))
        result << node
      end
    end
    result
  end

  def unique_id nodes
    Digest::MD5.hexdigest nodes.map { |node| file = file_for node; file.mtime.to_i.to_s + file.read }.join
  end
  
  def group_siblings nodes
    nodes.inject([]) do |result, node|
      group, current = [], node
      group << node
      while previous = current.previous_sibling and local_script?(previous)
        current = previous
        group.unshift current
      end
      result << group
    end
  end
end

Version data entries

1 entries across 1 versions & 1 rubygems

Version Path
rack-pagespeed-1.0.2 lib/rack/pagespeed/filters/combine_javascripts.rb