diff --git a/Gemfile b/Gemfile index ad5e1e4..d6f655e 100644 --- a/Gemfile +++ b/Gemfile @@ -4,3 +4,4 @@ gemspec gem "minitest", ">= 5" gem "rake" +gem "nokogiri" diff --git a/lib/chartkick/helper.rb b/lib/chartkick/helper.rb index 9f16bec..493cefe 100644 --- a/lib/chartkick/helper.rb +++ b/lib/chartkick/helper.rb @@ -34,6 +34,26 @@ def timeline(data_source, **options) private + # It removes style tag from html and replaced with class name with same property to work with CSP + def inline_styles_replace_with_class(html, element_id) + docs = Nokogiri::HTML.fragment(html) + style_attrs = docs.css('div')[0]["style"] + docs.css('*').remove_attr('style') + + div_element = docs.css('div') + chart_class_name = "#{div_element.first["id"].to_s}-styles" + class_element = div_element.first["class"].to_s + if class_element.empty? + class_element = "#{chart_class_name}" + else + class_element += " #{chart_class_name}" + end + + docs.css('div')[0]["id"] = element_id + html = docs.to_html(save_with: Nokogiri::XML::Node::SaveOptions::AS_XML) + [html, style_attrs, chart_class_name] + end + # don't break out options since need to merge with default options def chartkick_chart(klass, data_source, **options) options = Chartkick::Utils.deep_merge(Chartkick.options, options) @@ -74,6 +94,8 @@ def chartkick_chart(klass, data_source, **options) loading: options[:loading] || "Loading..." } + option_element_id = html_vars[:id] + [:height, :width].each do |k| # limit to alphanumeric and % for simplicity # this prevents things like calc() but safety is the priority @@ -90,6 +112,9 @@ def chartkick_chart(klass, data_source, **options) html = (options.delete(:html) || %(