From 612284cef31cb9f068e0d36d01306d355a065ced Mon Sep 17 00:00:00 2001 From: Robin Ward Date: Tue, 5 May 2020 12:15:03 -0400 Subject: [PATCH] DEV: Remove `Discourse.RAW_TEMPLATES` (#9630) We were sharing `Discourse` both as an application object and a namespace which complicated things for Ember CLI. This patch moves raw templates into `__DISCOURSE_RAW_TEMPLATES` and adds a couple helper methods to create/remove them. --- app/assets/javascripts/app-boot.js | 5 +++ .../addon/lib/raw-templates.js | 38 +++++++++++++++++++ app/assets/javascripts/discourse/app/app.js | 1 - .../app/components/badge-selector.js | 2 +- .../app/components/composer-editor.js | 2 +- .../discourse/app/components/d-editor.js | 2 +- .../discourse/app/components/emoji-picker.js | 2 +- .../app/components/group-selector.js | 2 +- .../app/components/topic-list-item.js | 2 +- .../discourse/app/components/user-selector.js | 2 +- .../javascripts/discourse/app/helpers/raw.js | 2 +- .../discourse/app/lib/plugin-connectors.js | 13 +------ .../discourse/app/lib/raw-templates.js | 17 --------- .../javascripts/discourse/app/lib/search.js | 2 +- app/models/theme_field.rb | 2 +- config/application.rb | 2 +- lib/theme_javascript_compiler.rb | 6 +-- spec/lib/theme_javascript_compiler_spec.rb | 8 ++-- spec/models/theme_field_spec.rb | 6 +-- .../acceptance/raw-plugin-outlet-test.js | 12 ++++-- 20 files changed, 75 insertions(+), 53 deletions(-) create mode 100644 app/assets/javascripts/discourse-common/addon/lib/raw-templates.js delete mode 100644 app/assets/javascripts/discourse/app/lib/raw-templates.js diff --git a/app/assets/javascripts/app-boot.js b/app/assets/javascripts/app-boot.js index d744e7f649..0fd7a5ea97 100644 --- a/app/assets/javascripts/app-boot.js +++ b/app/assets/javascripts/app-boot.js @@ -6,6 +6,11 @@ } let Discourse = requirejs("discourse/app").default; + // required for our template compiler + window.__DISCOURSE_RAW_TEMPLATES = requirejs( + "discourse-common/lib/raw-templates" + ).__DISCOURSE_RAW_TEMPLATES; + // ensure Discourse is added as a global window.Discourse = Discourse; })(); diff --git a/app/assets/javascripts/discourse-common/addon/lib/raw-templates.js b/app/assets/javascripts/discourse-common/addon/lib/raw-templates.js new file mode 100644 index 0000000000..2aa14dbf0d --- /dev/null +++ b/app/assets/javascripts/discourse-common/addon/lib/raw-templates.js @@ -0,0 +1,38 @@ +import { getResolverOption } from "discourse-common/resolver"; + +export const __DISCOURSE_RAW_TEMPLATES = {}; + +export function addRawTemplate(name, template) { + __DISCOURSE_RAW_TEMPLATES[name] = template; +} + +export function removeRawTemplate(name) { + delete __DISCOURSE_RAW_TEMPLATES[name]; +} + +export function findRawTemplate(name) { + if (getResolverOption("mobileView")) { + return ( + __DISCOURSE_RAW_TEMPLATES[`javascripts/mobile/${name}`] || + __DISCOURSE_RAW_TEMPLATES[`javascripts/${name}`] || + __DISCOURSE_RAW_TEMPLATES[`mobile/${name}`] || + __DISCOURSE_RAW_TEMPLATES[name] + ); + } + + return ( + __DISCOURSE_RAW_TEMPLATES[`javascripts/${name}`] || + __DISCOURSE_RAW_TEMPLATES[name] + ); +} + +export function buildRawConnectorCache(findOutlets) { + let result = {}; + findOutlets(__DISCOURSE_RAW_TEMPLATES, (outletName, resource) => { + result[outletName] = result[outletName] || []; + result[outletName].push({ + template: __DISCOURSE_RAW_TEMPLATES[resource] + }); + }); + return result; +} diff --git a/app/assets/javascripts/discourse/app/app.js b/app/assets/javascripts/discourse/app/app.js index 8080da1af6..62c4cfdf90 100644 --- a/app/assets/javascripts/discourse/app/app.js +++ b/app/assets/javascripts/discourse/app/app.js @@ -10,7 +10,6 @@ const _pluginCallbacks = []; const Discourse = Application.extend(FocusEvent, { rootElement: "#main", _docTitle: document.title, - RAW_TEMPLATES: {}, __widget_helpers: {}, customEvents: { paste: "paste" diff --git a/app/assets/javascripts/discourse/app/components/badge-selector.js b/app/assets/javascripts/discourse/app/components/badge-selector.js index 0f5c22941b..47cf4dbd10 100644 --- a/app/assets/javascripts/discourse/app/components/badge-selector.js +++ b/app/assets/javascripts/discourse/app/components/badge-selector.js @@ -3,7 +3,7 @@ import discourseComputed, { on, observes } from "discourse-common/utils/decorators"; -import { findRawTemplate } from "discourse/lib/raw-templates"; +import { findRawTemplate } from "discourse-common/lib/raw-templates"; const { makeArray } = Ember; export default Component.extend({ diff --git a/app/assets/javascripts/discourse/app/components/composer-editor.js b/app/assets/javascripts/discourse/app/components/composer-editor.js index a71902ed52..7d89caa070 100644 --- a/app/assets/javascripts/discourse/app/components/composer-editor.js +++ b/app/assets/javascripts/discourse/app/components/composer-editor.js @@ -22,7 +22,7 @@ import { load, LOADING_ONEBOX_CSS_CLASS } from "pretty-text/oneboxer"; import { applyInlineOneboxes } from "pretty-text/inline-oneboxer"; import { ajax } from "discourse/lib/ajax"; import EmberObject from "@ember/object"; -import { findRawTemplate } from "discourse/lib/raw-templates"; +import { findRawTemplate } from "discourse-common/lib/raw-templates"; import { iconHTML } from "discourse-common/lib/icon-library"; import { tinyAvatar, diff --git a/app/assets/javascripts/discourse/app/components/d-editor.js b/app/assets/javascripts/discourse/app/components/d-editor.js index faeeb11c77..d1a64b4c0f 100644 --- a/app/assets/javascripts/discourse/app/components/d-editor.js +++ b/app/assets/javascripts/discourse/app/components/d-editor.js @@ -10,7 +10,7 @@ import { categoryHashtagTriggerRule } from "discourse/lib/category-hashtags"; import { search as searchCategoryTag } from "discourse/lib/category-tag-search"; import { cookAsync } from "discourse/lib/text"; import { getRegister } from "discourse-common/lib/get-owner"; -import { findRawTemplate } from "discourse/lib/raw-templates"; +import { findRawTemplate } from "discourse-common/lib/raw-templates"; import { siteDir } from "discourse/lib/text-direction"; import { determinePostReplaceSelection, diff --git a/app/assets/javascripts/discourse/app/components/emoji-picker.js b/app/assets/javascripts/discourse/app/components/emoji-picker.js index e088f9c409..86fa8fcec9 100644 --- a/app/assets/javascripts/discourse/app/components/emoji-picker.js +++ b/app/assets/javascripts/discourse/app/components/emoji-picker.js @@ -2,7 +2,7 @@ import { inject as service } from "@ember/service"; import { throttle, debounce, schedule } from "@ember/runloop"; import Component from "@ember/component"; import { on, observes } from "discourse-common/utils/decorators"; -import { findRawTemplate } from "discourse/lib/raw-templates"; +import { findRawTemplate } from "discourse-common/lib/raw-templates"; import { emojiUrlFor } from "discourse/lib/text"; import { extendedEmojiList, diff --git a/app/assets/javascripts/discourse/app/components/group-selector.js b/app/assets/javascripts/discourse/app/components/group-selector.js index 3fe2e505f8..a743cde69f 100644 --- a/app/assets/javascripts/discourse/app/components/group-selector.js +++ b/app/assets/javascripts/discourse/app/components/group-selector.js @@ -4,7 +4,7 @@ import discourseComputed, { on, observes } from "discourse-common/utils/decorators"; -import { findRawTemplate } from "discourse/lib/raw-templates"; +import { findRawTemplate } from "discourse-common/lib/raw-templates"; export default Component.extend({ @discourseComputed("placeholderKey") diff --git a/app/assets/javascripts/discourse/app/components/topic-list-item.js b/app/assets/javascripts/discourse/app/components/topic-list-item.js index 0746ed95f6..2460dc8fc9 100644 --- a/app/assets/javascripts/discourse/app/components/topic-list-item.js +++ b/app/assets/javascripts/discourse/app/components/topic-list-item.js @@ -3,7 +3,7 @@ import { alias } from "@ember/object/computed"; import Component from "@ember/component"; import { schedule } from "@ember/runloop"; import DiscourseURL from "discourse/lib/url"; -import { findRawTemplate } from "discourse/lib/raw-templates"; +import { findRawTemplate } from "discourse-common/lib/raw-templates"; import { wantsNewWindow } from "discourse/lib/intercept-click"; import { on } from "@ember/object/evented"; diff --git a/app/assets/javascripts/discourse/app/components/user-selector.js b/app/assets/javascripts/discourse/app/components/user-selector.js index d362c60e62..a340b27f18 100644 --- a/app/assets/javascripts/discourse/app/components/user-selector.js +++ b/app/assets/javascripts/discourse/app/components/user-selector.js @@ -2,7 +2,7 @@ import { isEmpty } from "@ember/utils"; import { on, observes } from "discourse-common/utils/decorators"; import TextField from "discourse/components/text-field"; import userSearch from "discourse/lib/user-search"; -import { findRawTemplate } from "discourse/lib/raw-templates"; +import { findRawTemplate } from "discourse-common/lib/raw-templates"; export default TextField.extend({ autocorrect: false, diff --git a/app/assets/javascripts/discourse/app/helpers/raw.js b/app/assets/javascripts/discourse/app/helpers/raw.js index 0a764a1dee..fe0d43c88b 100644 --- a/app/assets/javascripts/discourse/app/helpers/raw.js +++ b/app/assets/javascripts/discourse/app/helpers/raw.js @@ -1,5 +1,5 @@ import { registerUnbound } from "discourse-common/lib/helpers"; -import { findRawTemplate } from "discourse/lib/raw-templates"; +import { findRawTemplate } from "discourse-common/lib/raw-templates"; import { htmlSafe } from "@ember/template"; import { setOwner } from "@ember/application"; diff --git a/app/assets/javascripts/discourse/app/lib/plugin-connectors.js b/app/assets/javascripts/discourse/app/lib/plugin-connectors.js index 8bf830be89..65aa1ce2f9 100644 --- a/app/assets/javascripts/discourse/app/lib/plugin-connectors.js +++ b/app/assets/javascripts/discourse/app/lib/plugin-connectors.js @@ -1,5 +1,6 @@ import Site from "discourse/models/site"; import deprecated from "discourse-common/lib/deprecated"; +import { buildRawConnectorCache } from "discourse-common/lib/raw-templates"; let _connectorCache; let _rawConnectorCache; @@ -82,16 +83,6 @@ function buildConnectorCache() { }); } -function buildRawConnectorCache() { - _rawConnectorCache = {}; - findOutlets(Discourse.RAW_TEMPLATES, (outletName, resource) => { - _rawConnectorCache[outletName] = _rawConnectorCache[outletName] || []; - _rawConnectorCache[outletName].push({ - template: Discourse.RAW_TEMPLATES[resource] - }); - }); -} - export function connectorsFor(outletName) { if (!_connectorCache) { buildConnectorCache(); @@ -107,7 +98,7 @@ export function renderedConnectorsFor(outletName, args, context) { export function rawConnectorsFor(outletName) { if (!_rawConnectorCache) { - buildRawConnectorCache(); + _rawConnectorCache = buildRawConnectorCache(findOutlets); } return _rawConnectorCache[outletName] || []; } diff --git a/app/assets/javascripts/discourse/app/lib/raw-templates.js b/app/assets/javascripts/discourse/app/lib/raw-templates.js deleted file mode 100644 index 3dffd81870..0000000000 --- a/app/assets/javascripts/discourse/app/lib/raw-templates.js +++ /dev/null @@ -1,17 +0,0 @@ -import { getResolverOption } from "discourse-common/resolver"; - -export function findRawTemplate(name) { - if (getResolverOption("mobileView")) { - return ( - Discourse.RAW_TEMPLATES[`javascripts/mobile/${name}`] || - Discourse.RAW_TEMPLATES[`javascripts/${name}`] || - Discourse.RAW_TEMPLATES[`mobile/${name}`] || - Discourse.RAW_TEMPLATES[name] - ); - } - - return ( - Discourse.RAW_TEMPLATES[`javascripts/${name}`] || - Discourse.RAW_TEMPLATES[name] - ); -} diff --git a/app/assets/javascripts/discourse/app/lib/search.js b/app/assets/javascripts/discourse/app/lib/search.js index f057425bc5..fb0dd3c493 100644 --- a/app/assets/javascripts/discourse/app/lib/search.js +++ b/app/assets/javascripts/discourse/app/lib/search.js @@ -1,7 +1,7 @@ import { isEmpty } from "@ember/utils"; import EmberObject from "@ember/object"; import { ajax } from "discourse/lib/ajax"; -import { findRawTemplate } from "discourse/lib/raw-templates"; +import { findRawTemplate } from "discourse-common/lib/raw-templates"; import Category from "discourse/models/category"; import { search as searchCategoryTag } from "discourse/lib/category-tag-search"; import userSearch from "discourse/lib/user-search"; diff --git a/app/models/theme_field.rb b/app/models/theme_field.rb index a9f98ce407..c2e8d06a72 100644 --- a/app/models/theme_field.rb +++ b/app/models/theme_field.rb @@ -60,7 +60,7 @@ class ThemeField < ActiveRecord::Base validates :name, format: { with: /\A[a-z_][a-z0-9_-]*\z/i }, if: Proc.new { |field| ThemeField.theme_var_type_ids.include?(field.type_id) } - BASE_COMPILER_VERSION = 15 + BASE_COMPILER_VERSION = 16 DEPENDENT_CONSTANTS = [ BASE_COMPILER_VERSION, Ember::VERSION, diff --git a/config/application.rb b/config/application.rb index 0145ddbe7a..3b9d4da7db 100644 --- a/config/application.rb +++ b/config/application.rb @@ -245,7 +245,7 @@ module Discourse # Our templates shouldn't start with 'discourse/app/templates' config.handlebars.templates_root = 'discourse/app/templates' - config.handlebars.raw_template_namespace = "Discourse.RAW_TEMPLATES" + config.handlebars.raw_template_namespace = "__DISCOURSE_RAW_TEMPLATES" Sprockets.register_mime_type 'text/x-handlebars', extensions: ['.hbr'] Sprockets.register_transformer 'text/x-handlebars', 'application/javascript', Ember::Handlebars::Template diff --git a/lib/theme_javascript_compiler.rb b/lib/theme_javascript_compiler.rb index 988a96ad9e..17bebf1b22 100644 --- a/lib/theme_javascript_compiler.rb +++ b/lib/theme_javascript_compiler.rb @@ -195,9 +195,9 @@ class ThemeJavascriptCompiler compiled = RawTemplatePrecompiler.new(@theme_id).compile(hbs_template) @content << <<~JS (function() { - if ('Discourse' in window) { - Discourse.RAW_TEMPLATES[#{raw_template_name(name)}] = requirejs('discourse-common/lib/raw-handlebars').template(#{compiled}); - } + const addRawTemplate = requirejs('discourse-common/lib/raw-templates').addRawTemplate; + const template = requirejs('discourse-common/lib/raw-handlebars').template(#{compiled}); + addRawTemplate(#{raw_template_name(name)}, template); })(); JS rescue Barber::PrecompilerError => e diff --git a/spec/lib/theme_javascript_compiler_spec.rb b/spec/lib/theme_javascript_compiler_spec.rb index ca0c9cd046..e82bb64597 100644 --- a/spec/lib/theme_javascript_compiler_spec.rb +++ b/spec/lib/theme_javascript_compiler_spec.rb @@ -112,19 +112,19 @@ describe ThemeJavascriptCompiler do describe "#append_raw_template" do let(:compiler) { ThemeJavascriptCompiler.new(1, 'marks') } - it 'adds the correct template to "Discourse.RAW_TEMPLATES"' do + it 'uses the correct template paths' do template = "

hello

" name = "/path/to/templates1" compiler.append_raw_template("#{name}.raw", template) - expect(compiler.content.to_s).to include("Discourse.RAW_TEMPLATES[\"#{name}\"]") + expect(compiler.content.to_s).to include("addRawTemplate(\"#{name}\"") name = "/path/to/templates2" compiler.append_raw_template("#{name}.hbr", template) - expect(compiler.content.to_s).to include("Discourse.RAW_TEMPLATES[\"#{name}\"]") + expect(compiler.content.to_s).to include("addRawTemplate(\"#{name}\"") name = "/path/to/templates3" compiler.append_raw_template("#{name}.hbs", template) - expect(compiler.content.to_s).to include("Discourse.RAW_TEMPLATES[\"#{name}.hbs\"]") + expect(compiler.content.to_s).to include("addRawTemplate(\"#{name}.hbs\"") end end end diff --git a/spec/models/theme_field_spec.rb b/spec/models/theme_field_spec.rb index 306b3aeec3..570a861d7a 100644 --- a/spec/models/theme_field_spec.rb +++ b/spec/models/theme_field_spec.rb @@ -196,14 +196,14 @@ HTML 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('Discourse.RAW_TEMPLATES["discovery"]') - expect(hbr_field.reload.value_baked).to include('Discourse.RAW_TEMPLATES["other_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["discovery"]') - expect(theme.javascript_cache.content).to include('Discourse.RAW_TEMPLATES["discovery"]') + expect(theme.javascript_cache.content).to include('addRawTemplate("discovery"') 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 =") diff --git a/test/javascripts/acceptance/raw-plugin-outlet-test.js b/test/javascripts/acceptance/raw-plugin-outlet-test.js index 8f104ce37b..a5a81208ce 100644 --- a/test/javascripts/acceptance/raw-plugin-outlet-test.js +++ b/test/javascripts/acceptance/raw-plugin-outlet-test.js @@ -1,17 +1,23 @@ import { acceptance } from "helpers/qunit-helpers"; import compile from "handlebars-compiler"; +import { + addRawTemplate, + removeRawTemplate +} from "discourse-common/lib/raw-templates"; const CONNECTOR = "javascripts/raw-test/connectors/topic-list-before-status/lala"; + acceptance("Raw Plugin Outlet", { beforeEach() { - Discourse.RAW_TEMPLATES[CONNECTOR] = compile( - `{{context.topic.id}}` + addRawTemplate( + CONNECTOR, + compile(`{{context.topic.id}}`) ); }, afterEach() { - delete Discourse.RAW_TEMPLATES[CONNECTOR]; + removeRawTemplate(CONNECTOR); } });