diff --git a/app/assets/javascripts/discourse/app/helpers/theme-helpers.js b/app/assets/javascripts/discourse/app/helpers/theme-helpers.js
index 477b89b1b06..989877554f1 100644
--- a/app/assets/javascripts/discourse/app/helpers/theme-helpers.js
+++ b/app/assets/javascripts/discourse/app/helpers/theme-helpers.js
@@ -1,7 +1,6 @@
-import { registerUnbound } from "discourse-common/lib/helpers";
+import { helperContext, registerUnbound } from "discourse-common/lib/helpers";
import I18n from "I18n";
import deprecated from "discourse-common/lib/deprecated";
-import { getSetting as getThemeSetting } from "discourse/lib/theme-settings-store";
registerUnbound("theme-i18n", (themeId, key, params) => {
return I18n.t(`theme_translations.${themeId}.${key}`, params);
@@ -19,6 +18,5 @@ registerUnbound("theme-setting", (themeId, key, hash) => {
{ since: "v2.2.0.beta8", dropFrom: "v2.3.0" }
);
}
-
- return getThemeSetting(themeId, key);
+ return helperContext().themeSettings.getSetting(themeId, key);
});
diff --git a/app/assets/javascripts/discourse/app/initializers/auto-load-modules.js b/app/assets/javascripts/discourse/app/initializers/auto-load-modules.js
index fa2ca51902a..b985d85c372 100644
--- a/app/assets/javascripts/discourse/app/initializers/auto-load-modules.js
+++ b/app/assets/javascripts/discourse/app/initializers/auto-load-modules.js
@@ -19,6 +19,7 @@ export function autoLoadModules(container, registry) {
let context = {
siteSettings: container.lookup("site-settings:main"),
+ themeSettings: container.lookup("service:theme-settings"),
keyValueStore: container.lookup("key-value-store:main"),
capabilities: container.lookup("capabilities:main"),
currentUser: container.lookup("current-user:main"),
diff --git a/app/assets/javascripts/discourse/app/lib/theme-settings-store.js b/app/assets/javascripts/discourse/app/lib/theme-settings-store.js
deleted file mode 100644
index 6503d6b932c..00000000000
--- a/app/assets/javascripts/discourse/app/lib/theme-settings-store.js
+++ /dev/null
@@ -1,47 +0,0 @@
-import { get } from "@ember/object";
-
-const originalSettings = {};
-const settings = {};
-
-export function registerSettings(
- themeId,
- settingsObject,
- { force = false } = {}
-) {
- if (settings[themeId] && !force) {
- return;
- }
- originalSettings[themeId] = Object.assign({}, settingsObject);
- const s = {};
- Object.keys(settingsObject).forEach((key) => {
- Object.defineProperty(s, key, {
- enumerable: true,
- get() {
- return settingsObject[key];
- },
- set(newVal) {
- settingsObject[key] = newVal;
- },
- });
- });
- settings[themeId] = s;
-}
-
-export function getSetting(themeId, settingKey) {
- if (settings[themeId]) {
- return get(settings[themeId], settingKey);
- }
- return null;
-}
-
-export function getObjectForTheme(themeId) {
- return settings[themeId];
-}
-
-export function resetSettings() {
- Object.keys(originalSettings).forEach((themeId) => {
- Object.keys(originalSettings[themeId]).forEach((key) => {
- settings[themeId][key] = originalSettings[themeId][key];
- });
- });
-}
diff --git a/app/assets/javascripts/discourse/app/services/theme-settings.js b/app/assets/javascripts/discourse/app/services/theme-settings.js
new file mode 100644
index 00000000000..3a1afbdf223
--- /dev/null
+++ b/app/assets/javascripts/discourse/app/services/theme-settings.js
@@ -0,0 +1,26 @@
+import Service from "@ember/service";
+import { get } from "@ember/object";
+
+export default Service.extend({
+ settings: null,
+
+ init() {
+ this._super(...arguments);
+ this._settings = {};
+ },
+
+ registerSettings(themeId, settingsObject) {
+ this._settings[themeId] = settingsObject;
+ },
+
+ getSetting(themeId, settingsKey) {
+ if (this._settings[themeId]) {
+ return get(this._settings[themeId], settingsKey);
+ }
+ return null;
+ },
+
+ getObjectForTheme(themeId) {
+ return this._settings[themeId];
+ },
+});
diff --git a/app/assets/javascripts/discourse/tests/setup-tests.js b/app/assets/javascripts/discourse/tests/setup-tests.js
index df1c06c3939..066d4ff314f 100644
--- a/app/assets/javascripts/discourse/tests/setup-tests.js
+++ b/app/assets/javascripts/discourse/tests/setup-tests.js
@@ -17,7 +17,6 @@ import { setupS3CDN, setupURL } from "discourse-common/lib/get-url";
import Application from "../app";
import MessageBus from "message-bus-client";
import PreloadStore from "discourse/lib/preload-store";
-import { resetSettings as resetThemeSettings } from "discourse/lib/theme-settings-store";
import QUnit from "qunit";
import { ScrollingDOMMethods } from "discourse/mixins/scrolling";
import Session from "discourse/models/session";
@@ -155,7 +154,6 @@ function setupTestsCommon(application, container, config) {
QUnit.testStart(function (ctx) {
bootbox.$body = $("#ember-testing");
let settings = resetSettings();
- resetThemeSettings();
if (config) {
// Ember CLI testing environment
@@ -253,8 +251,6 @@ function setupTestsCommon(application, container, config) {
let pluginPath = getUrlParameter("qunit_single_plugin")
? "/" + getUrlParameter("qunit_single_plugin") + "/"
: "/plugins/";
- let themeOnly = getUrlParameter("theme_name") || getUrlParameter("theme_url");
-
if (getUrlParameter("qunit_disable_auto_start") === "1") {
QUnit.config.autostart = false;
}
@@ -263,20 +259,8 @@ function setupTestsCommon(application, container, config) {
let isTest = /\-test/.test(entry);
let regex = new RegExp(pluginPath);
let isPlugin = regex.test(entry);
- let isTheme = /^discourse\/theme\-\d+\/.+/.test(entry);
- if (!isTest) {
- return;
- }
-
- if (themeOnly) {
- if (isTheme) {
- require(entry, null, null, true);
- }
- return;
- }
-
- if (!skipCore || isPlugin) {
+ if (isTest && (!skipCore || isPlugin)) {
require(entry, null, null, true);
}
});
diff --git a/app/assets/javascripts/discourse/tests/test_helper.js b/app/assets/javascripts/discourse/tests/test_helper.js
index affd1b36ee0..595e95ecaaf 100644
--- a/app/assets/javascripts/discourse/tests/test_helper.js
+++ b/app/assets/javascripts/discourse/tests/test_helper.js
@@ -41,3 +41,13 @@
//= require setup-tests
//= require test-shims
//= require jquery.magnific-popup.min.js
+
+document.write(
+ '
'
+);
+document.write(
+ ""
+);
+
+let setupTestsLegacy = require("discourse/tests/setup-tests").setupTestsLegacy;
+setupTestsLegacy(window.Discourse);
diff --git a/app/assets/javascripts/discourse/tests/test_starter.js b/app/assets/javascripts/discourse/tests/test_starter.js
deleted file mode 100644
index 77b69af2a10..00000000000
--- a/app/assets/javascripts/discourse/tests/test_starter.js
+++ /dev/null
@@ -1,11 +0,0 @@
-// discourse-skip-module
-
-document.write(
- ''
-);
-document.write(
- ""
-);
-
-let setupTestsLegacy = require("discourse/tests/setup-tests").setupTestsLegacy;
-setupTestsLegacy(window.Discourse);
diff --git a/app/controllers/qunit_controller.rb b/app/controllers/qunit_controller.rb
index 5e71847d801..f042d0a634d 100644
--- a/app/controllers/qunit_controller.rb
+++ b/app/controllers/qunit_controller.rb
@@ -1,26 +1,11 @@
# frozen_string_literal: true
class QunitController < ApplicationController
- skip_before_action *%i{
- check_xhr
- preload_json
- redirect_to_login_if_required
- }
+ skip_before_action :check_xhr, :preload_json, :redirect_to_login_if_required
layout false
# only used in test / dev
def index
raise Discourse::InvalidAccess.new if Rails.env.production?
- if (theme_name = params[:theme_name]).present?
- theme = Theme.find_by(name: theme_name)
- raise Discourse::NotFound if theme.blank?
- elsif (theme_url = params[:theme_url]).present?
- theme = RemoteTheme.find_by(remote_url: theme_url)
- raise Discourse::NotFound if theme.blank?
- end
- if theme.present?
- request.env[:resolved_theme_ids] = [theme.id]
- request.env[:skip_theme_ids_transformation] = true
- end
end
end
diff --git a/app/controllers/theme_javascripts_controller.rb b/app/controllers/theme_javascripts_controller.rb
index e28d0ed58f5..25dfd6567db 100644
--- a/app/controllers/theme_javascripts_controller.rb
+++ b/app/controllers/theme_javascripts_controller.rb
@@ -8,7 +8,7 @@ class ThemeJavascriptsController < ApplicationController
:preload_json,
:redirect_to_login_if_required,
:verify_authenticity_token,
- only: [:show, :show_tests]
+ only: [:show]
)
before_action :is_asset_path, :no_cookies, :apply_cdn_headers, only: [:show]
@@ -34,29 +34,6 @@ class ThemeJavascriptsController < ApplicationController
send_file(cache_file, disposition: :inline)
end
- def show_tests
- raise Discourse::NotFound if Rails.env.production?
-
- theme_id = params.require(:theme_id)
- theme = Theme.find(theme_id)
- content = ThemeField
- .where(
- theme_id: theme_id,
- target_id: Theme.targets[:tests_js]
- )
- .each(&:ensure_baked!)
- .map(&:value_baked)
- .join("\n")
-
- ThemeJavascriptCompiler.force_default_settings(content, theme)
-
- response.headers["Content-Length"] = content.size.to_s
- response.headers["Last-Modified"] = Time.zone.now.httpdate
- immutable_for(1.second)
-
- send_data content, filename: "js-tests-theme-#{theme_id}.js", disposition: :inline
- end
-
private
def query
diff --git a/app/helpers/application_helper.rb b/app/helpers/application_helper.rb
index 0e53e2788bd..b27b889c5be 100644
--- a/app/helpers/application_helper.rb
+++ b/app/helpers/application_helper.rb
@@ -453,30 +453,15 @@ module ApplicationHelper
end
def theme_lookup(name)
- Theme.lookup_field(
- theme_ids,
- mobile_view? ? :mobile : :desktop,
- name,
- skip_transformation: request.env[:skip_theme_ids_transformation].present?
- )
+ Theme.lookup_field(theme_ids, mobile_view? ? :mobile : :desktop, name)
end
def theme_translations_lookup
- Theme.lookup_field(
- theme_ids,
- :translations,
- I18n.locale,
- skip_transformation: request.env[:skip_theme_ids_transformation].present?
- )
+ Theme.lookup_field(theme_ids, :translations, I18n.locale)
end
def theme_js_lookup
- Theme.lookup_field(
- theme_ids,
- :extra_js,
- nil,
- skip_transformation: request.env[:skip_theme_ids_transformation].present?
- )
+ Theme.lookup_field(theme_ids, :extra_js, nil)
end
def discourse_stylesheet_link_tag(name, opts = {})
diff --git a/app/helpers/qunit_helper.rb b/app/helpers/qunit_helper.rb
deleted file mode 100644
index bf7955a6d93..00000000000
--- a/app/helpers/qunit_helper.rb
+++ /dev/null
@@ -1,24 +0,0 @@
-# frozen_string_literal: true
-
-module QunitHelper
- def theme_tests
- theme_ids = request.env[:resolved_theme_ids]
- return "" if theme_ids.blank?
-
- skip_transformation = request.env[:skip_theme_ids_transformation]
- query = ThemeField
- .joins(:theme)
- .where(
- target_id: Theme.targets[:tests_js],
- theme_id: skip_transformation ? theme_ids : Theme.transform_ids(theme_ids)
- )
- .pluck(:theme_id)
- .uniq
- .map do |theme_id|
- src = "#{GlobalSetting.cdn_url}#{Discourse.base_path}/theme-javascripts/tests/#{theme_id}.js"
- ""
- end
- .join("\n")
- .html_safe
- end
-end
diff --git a/app/models/theme.rb b/app/models/theme.rb
index ef935774fa1..94972fb2b15 100644
--- a/app/models/theme.rb
+++ b/app/models/theme.rb
@@ -128,7 +128,7 @@ class Theme < ActiveRecord::Base
SvgSprite.expire_cache
end
- BASE_COMPILER_VERSION = 46
+ BASE_COMPILER_VERSION = 17
def self.compiler_version
get_set_cache "compiler_version" do
dependencies = [
@@ -262,11 +262,11 @@ class Theme < ActiveRecord::Base
end
end
- def self.lookup_field(theme_ids, target, field, skip_transformation: false)
+ def self.lookup_field(theme_ids, target, field)
return if theme_ids.blank?
theme_ids = [theme_ids] unless Array === theme_ids
- theme_ids = transform_ids(theme_ids) if !skip_transformation
+ theme_ids = transform_ids(theme_ids)
cache_key = "#{theme_ids.join(",")}:#{target}:#{field}:#{Theme.compiler_version}"
lookup = @cache[cache_key]
return lookup.html_safe if lookup
@@ -297,7 +297,7 @@ class Theme < ActiveRecord::Base
end
def self.targets
- @targets ||= Enum.new(common: 0, desktop: 1, mobile: 2, settings: 3, translations: 4, extra_scss: 5, extra_js: 6, tests_js: 7)
+ @targets ||= Enum.new(common: 0, desktop: 1, mobile: 2, settings: 3, translations: 4, extra_scss: 5, extra_js: 6)
end
def self.lookup_target(target_id)
diff --git a/app/models/theme_field.rb b/app/models/theme_field.rb
index 038b9acfd9d..673386b791b 100644
--- a/app/models/theme_field.rb
+++ b/app/models/theme_field.rb
@@ -94,38 +94,10 @@ class ThemeField < ActiveRecord::Base
node.remove
end
- doc.css('script[type="text/discourse-plugin"]').each_with_index do |node, index|
- version = node['version']
- next if version.blank?
-
- initializer_name = "theme-field" +
- "-#{self.id}" +
- "-#{Theme.targets[self.target_id]}" +
- "-#{ThemeField.types[self.type_id]}" +
- "-script-#{index + 1}"
+ doc.css('script[type="text/discourse-plugin"]').each do |node|
+ next unless node['version'].present?
begin
- js = <<~JS
- import { withPluginApi } from "discourse/lib/plugin-api";
- import { rescueThemeError } from "discourse/lib/utilities";
-
- const __theme_name__ = #{self.theme.name.to_s.inspect};
- export default {
- name: #{initializer_name.inspect},
- after: "inject-objects",
-
- initialize() {
- withPluginApi(#{version.inspect}, (api) => {
- try {
- #{node.inner_html}
- } catch(err) {
- rescueThemeError(__theme_name__, err, api);
- }
- });
- }
- };
- JS
-
- js_compiler.append_module(js, "discourse/initializers/#{initializer_name}", include_variables: true)
+ js_compiler.append_plugin_script(node.inner_html, node['version'])
rescue ThemeJavascriptCompiler::CompileError => ex
errors << ex.message
end
@@ -160,7 +132,7 @@ class ThemeField < ActiveRecord::Base
begin
case extension
when "js.es6", "js"
- js_compiler.append_module(content, filename, include_variables: true)
+ js_compiler.append_module(content, filename)
when "hbs"
js_compiler.append_ember_template(filename.sub("discourse/templates/", ""), content)
when "hbr", "raw.hbs"
@@ -313,10 +285,6 @@ class ThemeField < ActiveRecord::Base
Theme.targets[self.target_id] == :extra_js
end
- def js_tests_field?
- Theme.targets[self.target_id] == :tests_js
- end
-
def basic_scss_field?
ThemeField.basic_targets.include?(Theme.targets[self.target_id].to_s) &&
ThemeField.scss_fields.include?(self.name)
@@ -347,7 +315,7 @@ class ThemeField < ActiveRecord::Base
self.error = nil unless self.error.present?
self.compiler_version = Theme.compiler_version
DB.after_commit { CSP::Extension.clear_theme_extensions_cache! }
- elsif extra_js_field? || js_tests_field?
+ elsif extra_js_field?
self.value_baked, self.error = process_extra_js(self.value)
self.error = nil unless self.error.present?
self.compiler_version = Theme.compiler_version
@@ -454,7 +422,7 @@ class ThemeField < ActiveRecord::Base
hash = {}
OPTIONS.each do |option|
plural = :"#{option}s"
- hash[option] = @allowed_values[plural][0] if @allowed_values[plural]&.length == 1
+ hash[option] = @allowed_values[plural][0] if @allowed_values[plural] && @allowed_values[plural].length == 1
hash[option] = match[option] if hash[option].nil?
end
hash
@@ -489,9 +457,6 @@ class ThemeField < ActiveRecord::Base
ThemeFileMatcher.new(regex: /^javascripts\/(?.+)$/,
targets: :extra_js, names: nil, types: :js,
canonical: -> (h) { "javascripts/#{h[:name]}" }),
- ThemeFileMatcher.new(regex: /^test\/(?.+)$/,
- targets: :tests_js, names: nil, types: :js,
- canonical: -> (h) { "test/#{h[:name]}" }),
ThemeFileMatcher.new(regex: /^settings\.ya?ml$/,
names: "yaml", types: :yaml, targets: :settings,
canonical: -> (h) { "settings.yml" }),
diff --git a/app/views/qunit/index.html.erb b/app/views/qunit/index.html.erb
index a8b57ce32b8..9b116c83dd5 100644
--- a/app/views/qunit/index.html.erb
+++ b/app/views/qunit/index.html.erb
@@ -5,11 +5,6 @@
<%= discourse_color_scheme_stylesheets %>
<%= stylesheet_link_tag "test_helper" %>
<%= javascript_include_tag "test_helper" %>
- <%= theme_tests %>
- <%= theme_translations_lookup %>
- <%= theme_js_lookup %>
- <%= theme_lookup("head_tag") %>
- <%= javascript_include_tag "test_starter" %>
<%= csrf_meta_tags %>
diff --git a/config/routes.rb b/config/routes.rb
index 3f5e4d644d1..9b1c0454936 100644
--- a/config/routes.rb
+++ b/config/routes.rb
@@ -527,7 +527,6 @@ Discourse::Application.routes.draw do
get "stylesheets/:name.css" => "stylesheets#show", constraints: { name: /[-a-z0-9_]+/ }
get "color-scheme-stylesheet/:id(/:theme_id)" => "stylesheets#color_scheme", constraints: { format: :json }
get "theme-javascripts/:digest.js" => "theme_javascripts#show", constraints: { digest: /\h{40}/ }
- get "theme-javascripts/tests/:theme_id.js" => "theme_javascripts#show_tests"
post "uploads/lookup-metadata" => "uploads#metadata"
post "uploads" => "uploads#create"
diff --git a/lib/tasks/qunit.rake b/lib/tasks/qunit.rake
index 1cb656993eb..405e932cc64 100644
--- a/lib/tasks/qunit.rake
+++ b/lib/tasks/qunit.rake
@@ -61,7 +61,7 @@ task "qunit:test", [:timeout, :qunit_path] do |_, args|
cmd = "node #{test_path}/run-qunit.js http://localhost:#{port}#{qunit_path}"
options = { seed: (ENV["QUNIT_SEED"] || Random.new.seed), hidepassed: 1 }
- %w{module filter qunit_skip_core qunit_single_plugin theme_name theme_url}.each do |arg|
+ %w{module filter qunit_skip_core qunit_single_plugin}.each do |arg|
options[arg] = ENV[arg.upcase] if ENV[arg.upcase].present?
end
diff --git a/lib/tasks/themes.rake b/lib/tasks/themes.rake
index e2912ec0577..05674767466 100644
--- a/lib/tasks/themes.rake
+++ b/lib/tasks/themes.rake
@@ -96,24 +96,3 @@ task "themes:audit" => :environment do
puts repo
end
end
-
-desc "Run QUnit tests of a theme/component"
-task "themes:qunit", :theme_name_or_url do |t, args|
- name_or_url = args[:theme_name_or_url]
- if name_or_url.blank?
- raise "A theme name or URL must be provided."
- end
- if name_or_url =~ /^(url|name)=(.+)/
- cmd = "THEME_#{Regexp.last_match(1).upcase}=#{Regexp.last_match(2)} "
- cmd += `which rake`.strip + " qunit:test"
- sh cmd
- else
- raise <<~MSG
- Cannot parse passed argument #{name_or_url.inspect}.
- Usage:
- `bundle exec rake themes:unit[url=]`
- OR
- `bundle exec rake themes:unit[name=]`
- MSG
- end
-end
diff --git a/lib/theme_javascript_compiler.rb b/lib/theme_javascript_compiler.rb
index 6fb33e7126f..17bebf1b229 100644
--- a/lib/theme_javascript_compiler.rb
+++ b/lib/theme_javascript_compiler.rb
@@ -151,18 +151,6 @@ class ThemeJavascriptCompiler
class CompileError < StandardError
end
- def self.force_default_settings(content, theme)
- settings_hash = {}
- theme.settings.each do |setting|
- settings_hash[setting.name] = setting.default
- end
- content.prepend <<~JS
- (function() {
- require("discourse/lib/theme-settings-store").registerSettings(#{theme.id}, #{settings_hash.to_json}, { force: true });
- })();
- JS
- end
-
attr_accessor :content
def initialize(theme_id, theme_name)
@@ -174,8 +162,10 @@ class ThemeJavascriptCompiler
def prepend_settings(settings_hash)
@content.prepend <<~JS
(function() {
- if ('require' in window) {
- require("discourse/lib/theme-settings-store").registerSettings(#{@theme_id}, #{settings_hash.to_json});
+ if ('Discourse' in window && Discourse.__container__) {
+ Discourse.__container__
+ .lookup("service:theme-settings")
+ .registerSettings(#{@theme_id}, #{settings_hash.to_json});
}
})();
JS
@@ -183,14 +173,8 @@ class ThemeJavascriptCompiler
# TODO Error handling for handlebars templates
def append_ember_template(name, hbs_template)
- if !name.start_with?("javascripts/")
- prefix = "javascripts"
- prefix += "/" if !name.start_with?("/")
- name = prefix + name
- end
name = name.inspect
compiled = EmberTemplatePrecompiler.new(@theme_id).compile(hbs_template)
- # the `'Ember' in window` check is needed for no_ember pages
content << <<~JS
(function() {
if ('Ember' in window) {
@@ -220,19 +204,18 @@ class ThemeJavascriptCompiler
raise CompileError.new e.instance_variable_get(:@error) # e.message contains the entire template, which could be very long
end
+ def append_plugin_script(script, api_version)
+ @content << transpile(script, api_version)
+ end
+
def append_raw_script(script)
@content << script + "\n"
end
def append_module(script, name, include_variables: true)
- name = "discourse/theme-#{@theme_id}/#{name.gsub(/^discourse\//, '')}"
- script = "#{theme_settings}#{script}" if include_variables
+ script = "#{theme_variables}#{script}" if include_variables
transpiler = DiscourseJsProcessor::Transpiler.new
- @content << <<~JS
- if ('define' in window) {
- #{transpiler.perform(script, "", name).strip}
- }
- JS
+ @content << transpiler.perform(script, "", name)
rescue MiniRacer::RuntimeError => ex
raise CompileError.new ex.message
end
@@ -243,9 +226,11 @@ class ThemeJavascriptCompiler
private
- def theme_settings
+ def theme_variables
<<~JS
- const settings = require("discourse/lib/theme-settings-store")
+ const __theme_name__ = "#{@theme_name.gsub('"', "\\\"")}";
+ const settings = Discourse.__container__
+ .lookup("service:theme-settings")
.getObjectForTheme(#{@theme_id});
const themePrefix = (key) => `theme_translations.#{@theme_id}.${key}`;
JS
@@ -256,8 +241,7 @@ class ThemeJavascriptCompiler
wrapped = <<~PLUGIN_API_JS
(function() {
if ('Discourse' in window && typeof Discourse._registerPluginCode === 'function') {
- const __theme_name__ = #{@theme_name.to_s.inspect};
- #{theme_settings}
+ #{theme_variables}
Discourse._registerPluginCode('#{version}', api => {
try {
#{es6_source}
diff --git a/spec/lib/theme_javascript_compiler_spec.rb b/spec/lib/theme_javascript_compiler_spec.rb
index e15adc5ee05..e82bb645977 100644
--- a/spec/lib/theme_javascript_compiler_spec.rb
+++ b/spec/lib/theme_javascript_compiler_spec.rb
@@ -127,18 +127,4 @@ describe ThemeJavascriptCompiler do
expect(compiler.content.to_s).to include("addRawTemplate(\"#{name}.hbs\"")
end
end
-
- describe "#append_ember_template" do
- let(:compiler) { ThemeJavascriptCompiler.new(1, 'marks') }
- it 'prepends `javascripts/` to template name if it is not prepended' do
- compiler.append_ember_template("/connectors/blah-1", "{{var}}")
- expect(compiler.content.to_s).to include('Ember.TEMPLATES["javascripts/connectors/blah-1"]')
-
- compiler.append_ember_template("connectors/blah-2", "{{var}}")
- expect(compiler.content.to_s).to include('Ember.TEMPLATES["javascripts/connectors/blah-2"]')
-
- compiler.append_ember_template("javascripts/connectors/blah-3", "{{var}}")
- expect(compiler.content.to_s).to include('Ember.TEMPLATES["javascripts/connectors/blah-3"]')
- end
- end
end
diff --git a/spec/models/remote_theme_spec.rb b/spec/models/remote_theme_spec.rb
index 6511842e4fa..9bb82c9d5cb 100644
--- a/spec/models/remote_theme_spec.rb
+++ b/spec/models/remote_theme_spec.rb
@@ -40,7 +40,6 @@ describe RemoteTheme do
"stylesheets/file.scss" => ".class1{color:red}",
"stylesheets/empty.scss" => "",
"javascripts/discourse/controllers/test.js.es6" => "console.log('test');",
- "test/acceptance/theme-test.js" => "assert.ok(true);",
"common/header.html" => "I AM HEADER",
"common/random.html" => "I AM SILLY",
"common/embedded.scss" => "EMBED",
@@ -75,7 +74,7 @@ describe RemoteTheme do
expect(@theme.theme_modifier_set.serialize_topic_excerpts).to eq(true)
- expect(@theme.theme_fields.length).to eq(11)
+ expect(@theme.theme_fields.length).to eq(10)
mapped = Hash[*@theme.theme_fields.map { |f| ["#{f.target_id}-#{f.name}", f.value] }.flatten]
@@ -89,9 +88,8 @@ describe RemoteTheme do
expect(mapped["3-yaml"]).to eq("boolean_setting: true")
expect(mapped["4-en"]).to eq("sometranslations")
- expect(mapped["7-acceptance/theme-test.js"]).to eq("assert.ok(true);")
- expect(mapped.length).to eq(11)
+ expect(mapped.length).to eq(10)
expect(@theme.settings.length).to eq(1)
expect(@theme.settings.first.value).to eq(true)
diff --git a/spec/models/theme_field_spec.rb b/spec/models/theme_field_spec.rb
index b57a87d98fb..20e00e06940 100644
--- a/spec/models/theme_field_spec.rb
+++ b/spec/models/theme_field_spec.rb
@@ -192,22 +192,34 @@ HTML
unknown_field = theme.set_field(target: :extra_js, name: "discourse/controllers/discovery.blah", value: "this wont work")
theme.save!
- js_field.reload
- expect(js_field.value_baked).to include("if ('define' in window) {")
- expect(js_field.value_baked).to include("define(\"discourse/theme-#{theme.id}/controllers/discovery\"")
- expect(js_field.value_baked).to include("console.log('hello from .js.es6');")
+ expected_js = <<~JS
+ define("discourse/controllers/discovery", ["discourse/lib/ajax"], function (_ajax) {
+ "use strict";
- expect(hbs_field.reload.value_baked).to include('Ember.TEMPLATES["javascripts/discovery"]')
+ var __theme_name__ = "#{theme.name}";
+
+ var settings = Discourse.__container__.lookup("service:theme-settings").getObjectForTheme(#{theme.id});
+
+ var themePrefix = function themePrefix(key) {
+ return "theme_translations.#{theme.id}.".concat(key);
+ };
+
+ console.log('hello from .js.es6');
+ });
+ JS
+ expect(js_field.reload.value_baked).to eq(expected_js.strip)
+
+ expect(hbs_field.reload.value_baked).to include('Ember.TEMPLATES["discovery"]')
expect(raw_hbs_field.reload.value_baked).to include('addRawTemplate("discovery"')
expect(hbr_field.reload.value_baked).to include('addRawTemplate("other_discovery"')
expect(unknown_field.reload.value_baked).to eq("")
expect(unknown_field.reload.error).to eq(I18n.t("themes.compile_error.unrecognized_extension", extension: "blah"))
# All together
- expect(theme.javascript_cache.content).to include('Ember.TEMPLATES["javascripts/discovery"]')
+ expect(theme.javascript_cache.content).to include('Ember.TEMPLATES["discovery"]')
expect(theme.javascript_cache.content).to include('addRawTemplate("discovery"')
- expect(theme.javascript_cache.content).to include("define(\"discourse/theme-#{theme.id}/controllers/discovery\"")
- expect(theme.javascript_cache.content).to include("define(\"discourse/theme-#{theme.id}/controllers/discovery-2\"")
+ expect(theme.javascript_cache.content).to include('define("discourse/controllers/discovery"')
+ expect(theme.javascript_cache.content).to include('define("discourse/controllers/discovery-2"')
expect(theme.javascript_cache.content).to include("var settings =")
end
diff --git a/spec/models/theme_spec.rb b/spec/models/theme_spec.rb
index 7ae6a04caae..ef359c139a3 100644
--- a/spec/models/theme_spec.rb
+++ b/spec/models/theme_spec.rb
@@ -276,7 +276,7 @@ HTML
def transpile(html)
f = ThemeField.create!(target_id: Theme.targets[:mobile], theme_id: 1, name: "after_header", value: html)
f.ensure_baked!
- [f.value_baked, f.javascript_cache, f]
+ [f.value_baked, f.javascript_cache]
end
it "transpiles ES6 code" do
@@ -286,21 +286,10 @@ HTML
HTML
- baked, javascript_cache, field = transpile(html)
+ baked, javascript_cache = transpile(html)
expect(baked).to include(javascript_cache.url)
-
- expect(javascript_cache.content).to include("if ('define' in window) {")
- expect(javascript_cache.content).to include(
- "define(\"discourse/theme-#{field.theme_id}/initializers/theme-field-#{field.id}-mobile-html-script-1\""
- )
- expect(javascript_cache.content).to include(
- "settings = require(\"discourse/lib/theme-settings-store\").getObjectForTheme(#{field.theme_id});"
- )
- expect(javascript_cache.content).to include("name: \"theme-field-#{field.id}-mobile-html-script-1\",")
- expect(javascript_cache.content).to include("after: \"inject-objects\",")
- expect(javascript_cache.content).to include("(0, _pluginApi.withPluginApi)(\"0.1\", function (api) {")
- expect(javascript_cache.content).to include("var x = 1;")
- expect(javascript_cache.content).to include("(0, _utilities.rescueThemeError)(__theme_name__, err, api);")
+ expect(javascript_cache.content).to include('var x = 1;')
+ expect(javascript_cache.content).to include("_registerPluginCode('0.1'")
end
it "wraps constants calls in a readOnlyError function" do
@@ -380,32 +369,83 @@ HTML
theme_field = theme.set_field(target: :common, name: :after_header, value: '')
theme.save!
+ transpiled = <<~HTML
+ (function() {
+ if ('Discourse' in window && Discourse.__container__) {
+ Discourse.__container__
+ .lookup("service:theme-settings")
+ .registerSettings(#{theme.id}, {"name":"bob"});
+ }
+ })();
+ (function () {
+ if ('Discourse' in window && typeof Discourse._registerPluginCode === 'function') {
+ var __theme_name__ = "awesome theme\\\"";
+
+ var settings = Discourse.__container__.lookup("service:theme-settings").getObjectForTheme(#{theme.id});
+
+ var themePrefix = function themePrefix(key) {
+ return "theme_translations.#{theme.id}.".concat(key);
+ };
+
+ Discourse._registerPluginCode('1.0', function (api) {
+ try {
+ alert(settings.name);
+
+ var a = function a() {};
+ } catch (err) {
+ var rescue = require("discourse/lib/utilities").rescueThemeError;
+
+ rescue(__theme_name__, err, api);
+ }
+ });
+ }
+ })();
+ HTML
+
theme_field.reload
expect(Theme.lookup_field(theme.id, :desktop, :after_header)).to include(theme_field.javascript_cache.url)
- expect(theme_field.javascript_cache.content).to include("if ('require' in window) {")
- expect(theme_field.javascript_cache.content).to include(
- "require(\"discourse/lib/theme-settings-store\").registerSettings(#{theme_field.theme.id}, {\"name\":\"bob\"});"
- )
- expect(theme_field.javascript_cache.content).to include("if ('define' in window) {")
- expect(theme_field.javascript_cache.content).to include(
- "define(\"discourse/theme-#{theme_field.theme.id}/initializers/theme-field-#{theme_field.id}-common-html-script-1\","
- )
- expect(theme_field.javascript_cache.content).to include("var __theme_name__ = \"awesome theme\\\"\";")
- expect(theme_field.javascript_cache.content).to include("name: \"theme-field-#{theme_field.id}-common-html-script-1\",")
- expect(theme_field.javascript_cache.content).to include("after: \"inject-objects\",")
- expect(theme_field.javascript_cache.content).to include("(0, _pluginApi.withPluginApi)(\"1.0\", function (api)")
- expect(theme_field.javascript_cache.content).to include("alert(settings.name)")
- expect(theme_field.javascript_cache.content).to include("var a = function a() {}")
+ expect(theme_field.javascript_cache.content).to eq(transpiled.strip)
setting = theme.settings.find { |s| s.name == :name }
setting.value = 'bill'
theme.save!
+ transpiled = <<~HTML
+ (function() {
+ if ('Discourse' in window && Discourse.__container__) {
+ Discourse.__container__
+ .lookup("service:theme-settings")
+ .registerSettings(#{theme.id}, {"name":"bill"});
+ }
+ })();
+ (function () {
+ if ('Discourse' in window && typeof Discourse._registerPluginCode === 'function') {
+ var __theme_name__ = "awesome theme\\\"";
+
+ var settings = Discourse.__container__.lookup("service:theme-settings").getObjectForTheme(#{theme.id});
+
+ var themePrefix = function themePrefix(key) {
+ return "theme_translations.#{theme.id}.".concat(key);
+ };
+
+ Discourse._registerPluginCode('1.0', function (api) {
+ try {
+ alert(settings.name);
+
+ var a = function a() {};
+ } catch (err) {
+ var rescue = require("discourse/lib/utilities").rescueThemeError;
+
+ rescue(__theme_name__, err, api);
+ }
+ });
+ }
+ })();
+ HTML
+
theme_field.reload
- expect(theme_field.javascript_cache.content).to include(
- "require(\"discourse/lib/theme-settings-store\").registerSettings(#{theme_field.theme.id}, {\"name\":\"bill\"});"
- )
expect(Theme.lookup_field(theme.id, :desktop, :after_header)).to include(theme_field.javascript_cache.url)
+ expect(theme_field.javascript_cache.content).to eq(transpiled.strip)
end
it 'is empty when the settings are invalid' do
diff --git a/spec/requests/qunit_controller_spec.rb b/spec/requests/qunit_controller_spec.rb
deleted file mode 100644
index b0a9535dc2c..00000000000
--- a/spec/requests/qunit_controller_spec.rb
+++ /dev/null
@@ -1,76 +0,0 @@
-# frozen_string_literal: true
-
-require 'rails_helper'
-
-describe QunitController do
- let(:theme) { Fabricate(:theme, name: 'main-theme') }
- let(:component) { Fabricate(:theme, component: true, name: 'enabled-component') }
- let(:disabled_component) { Fabricate(:theme, component: true, enabled: false, name: 'disabled-component') }
-
- before do
- Theme.destroy_all
- theme.set_default!
- component.add_relative_theme!(:parent, theme)
- disabled_component.add_relative_theme!(:parent, theme)
- [theme, component, disabled_component].each do |t|
- t.set_field(
- target: :extra_js,
- type: :js,
- name: "discourse/initializers/my-#{t.id}-initializer.js",
- value: "console.log(#{t.id});"
- )
- t.set_field(
- target: :tests_js,
- type: :js,
- name: "acceptance/some-test-#{t.id}.js",
- value: "assert.ok(#{t.id});"
- )
- t.save!
- end
- end
-
- context "when no theme is specified" do
- it "includes tests of enabled theme + components" do
- get '/qunit'
- js_urls = JavascriptCache.where(theme_id: [theme.id, component.id]).map(&:url)
- expect(js_urls.size).to eq(2)
- js_urls.each do |url|
- expect(response.body).to include(url)
- end
- [theme, component].each do |t|
- expect(response.body).to include("/theme-javascripts/tests/#{t.id}.js")
- end
-
- js_urls = JavascriptCache.where(theme_id: disabled_component).map(&:url)
- expect(js_urls.size).to eq(1)
- js_urls.each do |url|
- expect(response.body).not_to include(url)
- end
- expect(response.body).not_to include("/theme-javascripts/tests/#{disabled_component.id}.js")
- end
- end
-
- context "when a theme is specified" do
- it "includes tests of the specified theme only" do
- [theme, disabled_component].each do |t|
- get "/qunit?theme_name=#{t.name}"
- js_urls = JavascriptCache.where(theme_id: t.id).map(&:url)
- expect(js_urls.size).to eq(1)
- js_urls.each do |url|
- expect(response.body).to include(url)
- end
- expect(response.body).to include("/theme-javascripts/tests/#{t.id}.js")
-
- excluded = Theme.pluck(:id) - [t.id]
- js_urls = JavascriptCache.where(theme_id: excluded).map(&:url)
- expect(js_urls.size).to eq(2)
- js_urls.each do |url|
- expect(response.body).not_to include(url)
- end
- excluded.each do |id|
- expect(response.body).not_to include("/theme-javascripts/tests/#{id}.js")
- end
- end
- end
- end
-end
diff --git a/spec/requests/theme_javascripts_controller_spec.rb b/spec/requests/theme_javascripts_controller_spec.rb
index b63d9efbbd2..6c05efd4e57 100644
--- a/spec/requests/theme_javascripts_controller_spec.rb
+++ b/spec/requests/theme_javascripts_controller_spec.rb
@@ -54,24 +54,4 @@ describe ThemeJavascriptsController do
end
end
end
-
- describe "#show_tests" do
- context "theme settings" do
- let(:component) { Fabricate(:theme, component: true, name: 'enabled-component') }
-
- it "forces default values" do
- ThemeField.create!(
- theme: component,
- target_id: Theme.targets[:settings],
- name: "yaml",
- value: "num_setting: 5"
- )
- component.reload
- component.update_setting(:num_setting, 643)
-
- get "/theme-javascripts/tests/#{component.id}.js"
- expect(response.body).to include("require(\"discourse/lib/theme-settings-store\").registerSettings(#{component.id}, {\"num_setting\":5}, { force: true });")
- end
- end
- end
end