Class: Deadweight

Inherits:
Object
  • Object
show all
Defined in:
lib/deadweight.rb,
lib/deadweight/cli.rb,
lib/deadweight/hijack.rb,
lib/deadweight/rake_task.rb,
lib/deadweight/hijack/rails.rb,
lib/deadweight/rack/capturing_middleware.rb

Defined Under Namespace

Modules: Hijack, Rack Classes: CLI, FetchError, RakeTask

Instance Attribute Summary (collapse)

Instance Method Summary (collapse)

Constructor Details

- (Deadweight) initialize

Returns a new instance of Deadweight



19
20
21
22
23
24
25
26
27
28
# File 'lib/deadweight.rb', line 19

def initialize
  @root = 'http://localhost:3000'
  @stylesheets = []
  @pages = []
  @rules = ""
  @ignore_selectors = []
  @mechanize = false
  @log_file = STDERR
  yield self and run if block_given?
end

Instance Attribute Details

- (Object) ignore_selectors

Returns the value of attribute ignore_selectors



16
17
18
# File 'lib/deadweight.rb', line 16

def ignore_selectors
  @ignore_selectors
end

- (Object) log_file

Returns the value of attribute log_file



16
17
18
# File 'lib/deadweight.rb', line 16

def log_file
  @log_file
end

- (Object) mechanize

Returns the value of attribute mechanize



16
17
18
# File 'lib/deadweight.rb', line 16

def mechanize
  @mechanize
end

- (Object) pages

Returns the value of attribute pages



16
17
18
# File 'lib/deadweight.rb', line 16

def pages
  @pages
end

- (Object) parsed_rules (readonly)

Returns the value of attribute parsed_rules



17
18
19
# File 'lib/deadweight.rb', line 17

def parsed_rules
  @parsed_rules
end

- (Object) root

Returns the value of attribute root



16
17
18
# File 'lib/deadweight.rb', line 16

def root
  @root
end

- (Object) rules

Returns the value of attribute rules



16
17
18
# File 'lib/deadweight.rb', line 16

def rules
  @rules
end

- (Object) stylesheets

Returns the value of attribute stylesheets



16
17
18
# File 'lib/deadweight.rb', line 16

def stylesheets
  @stylesheets
end

- (Object) unused_selectors (readonly)

Returns the value of attribute unused_selectors



17
18
19
# File 'lib/deadweight.rb', line 17

def unused_selectors
  @unused_selectors
end

Instance Method Details

- (Object) add_css!(css)



47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
# File 'lib/deadweight.rb', line 47

def add_css!(css)
  parser = CssParser::Parser.new
  parser.add_block!(css)

  selector_count = 0

  parser.each_selector do |selector, declarations, specificity|
    next if @unused_selectors.include?(selector)
    next if selector =~ @ignore_selectors
    next if has_pseudo_classes(selector) and @unused_selectors.include?(strip(selector))

    @unused_selectors << selector
    @parsed_rules[selector] = declarations

    selector_count += 1
  end

  selector_count
end

- (Object) agent

Returns the Mechanize instance, if mechanize is set to true.



137
138
139
# File 'lib/deadweight.rb', line 137

def agent
  @agent ||= initialize_agent
end

- (Object) analyze(html)



30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
# File 'lib/deadweight.rb', line 30

def analyze(html)
  doc = Nokogiri::HTML(html)

  @unused_selectors.collect do |selector, declarations|
    # We test against the selector stripped of any pseudo classes,
    # but we report on the selector with its pseudo classes.
    stripped_selector = strip(selector)

    next if stripped_selector.empty?

    if doc.search(stripped_selector).any?
      log.puts("  #{selector.green}")
      selector
    end
  end
end

- (Object) dump(output)



126
127
128
# File 'lib/deadweight.rb', line 126

def dump(output)
  output.puts(@unused_selectors)
end

- (Object) fetch(path)

Fetch a path, using Mechanize if mechanize is set to true.



142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
# File 'lib/deadweight.rb', line 142

def fetch(path)
  log.puts(path)

  loc = root + path

  if @mechanize
    loc = "file://#{File.expand_path(loc)}" unless loc =~ %r{^\w+://}

    begin
      page = agent.get(loc)
    rescue Mechanize::ResponseCodeError => e
      raise FetchError.new("#{loc} returned a response code of #{e.response_code}")
    end

    log.puts("#{loc} redirected to #{page.uri}".red) unless page.uri.to_s == loc

    page.body
  else
    begin
      open(loc).read
    rescue Errno::ENOENT
      raise FetchError.new("#{loc} was not found")
    rescue OpenURI::HTTPError => e
      raise FetchError.new("retrieving #{loc} raised an HTTP error: #{e.message}")
    end
  end
end

- (Object) process!(html)



130
131
132
133
134
# File 'lib/deadweight.rb', line 130

def process!(html)
  analyze(html).each do |selector|
    @unused_selectors.delete(selector)
  end
end

- (Object) report



85
86
87
88
89
# File 'lib/deadweight.rb', line 85

def report
  log.puts
  log.puts "found #{@unused_selectors.size} unused selectors out of #{@total_selectors} total".yellow
  log.puts
end

- (Object) reset!



67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
# File 'lib/deadweight.rb', line 67

def reset!
  @parsed_rules     = {}
  @unused_selectors = []

  @stylesheets.each do |path|
    new_selector_count = add_css!(fetch(path))
    log.puts("  found #{new_selector_count} selectors".yellow)
  end

  if @rules and !@rules.empty?
    new_selector_count = add_css!(@rules)
    log.puts
    log.puts("Added #{new_selector_count} extra selectors".yellow)
  end

  @total_selectors = @unused_selectors.size
end

- (Object) run

Find all unused CSS selectors and return them as an array.



92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
# File 'lib/deadweight.rb', line 92

def run
  reset!

  pages.each do |page|
    log.puts

    if page.respond_to?(:read)
      html = page.read
    elsif page.respond_to?(:call)
      result = instance_eval(&page)

      html = case result
             when String
               result
             else
               @agent.page.body
             end
    else
      begin
        html = fetch(page)
      rescue FetchError => e
        log.puts(e.message.red)
        next
      end
    end

    process!(html)
  end

  report

  @unused_selectors
end