FIX: only extract script tags with certain types (#6553)

`script` tags with custom types (e.g. `text/template`) are not executed
by the browser, and should not be extracted into an external theme
JavaScript
This commit is contained in:
Kyle Zhao 2018-11-01 16:01:46 -04:00 committed by GitHub
parent 2feadcdafb
commit f9b36820ef
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 51 additions and 4 deletions

View File

@ -123,9 +123,10 @@ COMPILED
end
doc.css('script').each do |node|
next if node['src'].present?
next unless inline_javascript?(node)
javascript_cache.content << "(function() { #{node.inner_html} })();"
javascript_cache.content << node.inner_html
javascript_cache.content << "\n"
node.remove
end
@ -253,6 +254,24 @@ COMPILED
MessageBus.publish "/header-change/#{theme.id}", self.value if theme && self.name == "header"
MessageBus.publish "/footer-change/#{theme.id}", self.value if theme && self.name == "footer"
end
private
JAVASCRIPT_TYPES = %w(
text/javascript
application/javascript
application/ecmascript
)
def inline_javascript?(node)
if node['src'].present?
false
elsif node['type'].present?
JAVASCRIPT_TYPES.include?(node['type'].downcase)
else
true
end
end
end
# == Schema Information

View File

@ -37,9 +37,18 @@ describe ThemeField do
<script type="text/discourse-plugin" version="0.8">
var a = "inline discourse plugin";
</script>
<script type="text/template" data-template="custom-template">
<div>custom script type</div>
</script>
<script>
var b = "inline raw script";
</script>
<script type="texT/jAvasCripT">
var c = "text/javascript";
</script>
<script type="application/javascript">
var d = "application/javascript";
</script>
<script src="/external-script.js"></script>
HTML
@ -47,8 +56,27 @@ describe ThemeField do
expect(theme_field.value_baked).to include("<script src=\"#{theme_field.javascript_cache.url}\"></script>")
expect(theme_field.value_baked).to include("external-script.js")
expect(theme_field.javascript_cache.content).to include('inline discourse plugin')
expect(theme_field.javascript_cache.content).to include('inline raw script')
expect(theme_field.value_baked).to include('<script type="text/template"')
expect(theme_field.javascript_cache.content).to include('a = "inline discourse plugin"')
expect(theme_field.javascript_cache.content).to include('b = "inline raw script"')
expect(theme_field.javascript_cache.content).to include('c = "text/javascript"')
expect(theme_field.javascript_cache.content).to include('d = "application/javascript"')
end
it 'adds newlines between the extracted javascripts' do
html = <<~HTML
<script>var a = 10</script>
<script>var b = 10</script>
HTML
extracted = <<~JavaScript
var a = 10
var b = 10
JavaScript
theme_field = ThemeField.create!(theme_id: 1, target_id: 0, name: "header", value: html)
expect(theme_field.javascript_cache.content).to eq(extracted)
end
it "correctly extracts and generates errors for transpiled js" do