Class: ThemeCheck::AssetSizeCSS

Inherits:
LiquidCheck show all
Includes:
RegexHelpers
Defined in:
lib/theme_check/checks/asset_size_css.rb

Defined Under Namespace

Classes: Link

Constant Summary collapse

%r{
  <link
    (?=[^>]+?rel=['"]?stylesheet['"]?)    # Make sure rel=stylesheet is in the link with lookahead
    [^>]+                                 # any non closing tag character
    href=                                 # href attribute start
    (?<href>#{QUOTED_LIQUID_ATTRIBUTE})   # href attribute value (may contain liquid)
    [^>]*                                 # any non closing character till the end
  >
}omix
STYLESHEET_TAG =
%r{
  #{Liquid::VariableStart}          # VariableStart
  (?:(?!#{Liquid::VariableEnd}).)*? # anything that isn't followed by a VariableEnd
  \|\s*asset_url\s*                 # | asset_url
  \|\s*stylesheet_tag\s*            # | stylesheet_tag
  #{Liquid::VariableEnd}            # VariableEnd
}omix

Constants inherited from LiquidCheck

LiquidCheck::ATTR, LiquidCheck::HTML_ATTRIBUTE, LiquidCheck::HTML_ATTRIBUTES, LiquidCheck::QUOTED_LIQUID_ATTRIBUTE, LiquidCheck::START_OR_END_QUOTE, LiquidCheck::TAG, LiquidCheck::VARIABLE

Constants inherited from Check

Check::CATEGORIES, Check::SEVERITIES

Instance Attribute Summary collapse

Attributes inherited from Check

#offenses, #options, #theme

Instance Method Summary collapse

Methods included from RegexHelpers

#matches

Methods inherited from LiquidCheck

#add_offense

Methods included from ChecksTracking

#inherited

Methods included from ParsingHelpers

#outside_of_strings

Methods inherited from Check

all, can_disable, #can_disable?, categories, #categories, category, #code_name, #doc, doc, docs_url, #ignore!, #ignored?, #severity, severity, #to_s, #unignore!

Methods included from JsonHelpers

#format_json_parse_error

Constructor Details

#initialize(threshold_in_bytes: 100_000) ⇒ AssetSizeCSS

Returns a new instance of AssetSizeCSS.



30
31
32
# File 'lib/theme_check/checks/asset_size_css.rb', line 30

def initialize(threshold_in_bytes: 100_000)
  @threshold_in_bytes = threshold_in_bytes
end

Instance Attribute Details

#threshold_in_bytesObject (readonly)

Returns the value of attribute threshold_in_bytes.



28
29
30
# File 'lib/theme_check/checks/asset_size_css.rb', line 28

def threshold_in_bytes
  @threshold_in_bytes
end

Instance Method Details

#href_to_file_size(href) ⇒ Object



74
75
76
77
78
79
80
81
82
83
84
85
86
87
# File 'lib/theme_check/checks/asset_size_css.rb', line 74

def href_to_file_size(href)
  # asset_url (+ optional stylesheet_tag) variables
  if href =~ /^#{VARIABLE}$/o && href =~ /asset_url/ && href =~ Liquid::QuotedString
    asset_id = Regexp.last_match(0).gsub(START_OR_END_QUOTE, "")
    asset = @theme.assets.find { |a| a.name.end_with?("/" + asset_id) }
    return if asset.nil?
    asset.gzipped_size

  # remote URLs
  elsif href =~ %r{^(https?:)?//}
    asset = RemoteAssetFile.from_src(href)
    asset.gzipped_size
  end
end

#on_document(node) ⇒ Object



34
35
36
37
38
# File 'lib/theme_check/checks/asset_size_css.rb', line 34

def on_document(node)
  @node = node
  @source = node.template.source
  record_offenses
end

#record_offensesObject



40
41
42
43
44
45
46
47
48
49
50
51
52
# File 'lib/theme_check/checks/asset_size_css.rb', line 40

def record_offenses
  stylesheets(@source).each do |stylesheet|
    file_size = href_to_file_size(stylesheet.href)
    next if file_size.nil?
    next if file_size <= threshold_in_bytes
    add_offense(
      "CSS on every page load exceding compressed size threshold (#{threshold_in_bytes} Bytes).",
      node: @node,
      markup: stylesheet.href,
      line_number: @source[0...stylesheet.index].count("\n") + 1
    )
  end
end

#stylesheets(source) ⇒ Object



54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
# File 'lib/theme_check/checks/asset_size_css.rb', line 54

def stylesheets(source)
  stylesheet_links = matches(source, LINK_TAG_HREF)
    .map do |m|
      Link.new(
        m[:href].gsub(START_OR_END_QUOTE, ""),
        m.begin(:href),
      )
    end

  stylesheet_tags = matches(source, STYLESHEET_TAG)
    .map do |m|
      Link.new(
        m[0],
        m.begin(0),
      )
    end

  stylesheet_links + stylesheet_tags
end