Skip to content

Revisiting Color in Markup #2054

@perlygatekeeper

Description

@perlygatekeeper

Changes to the sanitize (step 2):

color_transformer = lambda do |env|
  node = env[:node]
  
  # Only process element nodes with a style attribute
  return unless node.type == Nokogiri::XML::Node::ELEMENT_NODE
  return unless node['style']

  # Parse each declaration
  allowed_declarations = node['style'].split(';').filter_map do |declaration|
    property, value = declaration.split(':').map(&:strip)
    next unless property == 'color'

    # Allow only:
    # - Named colors: red, blue, darkslategray, etc. OR NOT?
    # - Hex colors: #fff, #ff6600
    # - RGB: rgb(0, 128, 255)
    # - HSL: hsl(120, 100%, 50%)
    valid_color = value.match?(
      /\A(
        \#([0-9a-fA-F]{3}|[0-9a-fA-F]{6})        | # hex
        rgb\(\s*\d{1,3}\s*,\s*\d{1,3}\s*,\s*\d{1,3}\s*\)  | # rgb()
        hsl\(\s*\d{1,3}\s*,\s*\d{1,3}%\s*,\s*\d{1,3}%\s*\) | # hsl()
        [a-zA-Z]{2,50}                              # named color
      )\z/x
    )

    "color: #{value}" if valid_color
  end

  if allowed_declarations&.any?
    node['style'] = allowed_declarations.join('; ')
  else
    node.remove_attribute('style')
  end
end

--- THEN ADD THIS TO THE SANITIZE CONFIG ---

config = {
  elements: ['p', 'span', 'em', 'strong'],
  attributes: {
    :all => ['style']
  },
  css: {
    properties: ['color']
  },
  transformers: [color_transformer]
}

Sanitize.fragment(html, config)

Originally posted by @perlygatekeeper in #1440

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions