diff --git a/app/assets/javascripts/discourse/ember-cli-build.js b/app/assets/javascripts/discourse/ember-cli-build.js index 64c40558089..e6a01988ad4 100644 --- a/app/assets/javascripts/discourse/ember-cli-build.js +++ b/app/assets/javascripts/discourse/ember-cli-build.js @@ -110,6 +110,11 @@ module.exports = function (defaults) { }); app.import(discourseRoot + "/app/assets/javascripts/polyfills.js"); + app.import( + discourseRoot + + "/app/assets/javascripts/discourse/public/assets/scripts/module-shims.js" + ); + const mergedTree = mergeTrees([ discourseScss(`${discourseRoot}/app/assets/stylesheets`, "testem.scss"), createI18nTree(discourseRoot, vendorJs), diff --git a/app/assets/javascripts/discourse/lib/rfc176-shims/.npmrc b/app/assets/javascripts/discourse/lib/rfc176-shims/.npmrc new file mode 100644 index 00000000000..c42da845b44 --- /dev/null +++ b/app/assets/javascripts/discourse/lib/rfc176-shims/.npmrc @@ -0,0 +1 @@ +engine-strict = true diff --git a/app/assets/javascripts/discourse/lib/rfc176-shims/index.js b/app/assets/javascripts/discourse/lib/rfc176-shims/index.js new file mode 100644 index 00000000000..df26adac628 --- /dev/null +++ b/app/assets/javascripts/discourse/lib/rfc176-shims/index.js @@ -0,0 +1,57 @@ +"use strict"; + +// In core, babel-plugin-ember-modules-api-polyfill takes care of re-writing the new module +// syntax to the legacy Ember globals. For themes and plugins, we need to manually set up +// the modules. +// +// Eventually, Ember RFC176 will be implemented, and we can drop these shims. + +const RFC176Data = require("ember-rfc176-data"); + +module.exports = { + name: require("./package").name, + + isDevelopingAddon() { + return true; + }, + + contentFor: function (type) { + if (type !== "vendor-suffix") { + return; + } + + const modules = {}; + + for (const entry of RFC176Data) { + // Entries look like: + // { + // global: 'Ember.expandProperties', + // module: '@ember/object/computed', + // export: 'expandProperties', + // deprecated: false + // }, + + if (entry.deprecated) { + continue; + } + + let m = modules[entry.module]; + if (!m) { + m = modules[entry.module] = []; + } + + m.push(entry); + } + + let output = ""; + for (const moduleName of Object.keys(modules)) { + const exports = modules[moduleName]; + const rawExports = exports + .map((e) => `${e.export}:${e.global}`) + .join(","); + output += `define("${moduleName}", () => {return {${rawExports}}});\n`; + } + + return output; + }, +}; diff --git a/app/assets/javascripts/discourse/lib/rfc176-shims/package.json b/app/assets/javascripts/discourse/lib/rfc176-shims/package.json new file mode 100644 index 00000000000..60bf829f39c --- /dev/null +++ b/app/assets/javascripts/discourse/lib/rfc176-shims/package.json @@ -0,0 +1,6 @@ +{ + "name": "rfc176-shims", + "keywords": [ + "ember-addon" + ] +} diff --git a/app/assets/javascripts/discourse/package.json b/app/assets/javascripts/discourse/package.json index e743a6586f1..013f5cedba9 100644 --- a/app/assets/javascripts/discourse/package.json +++ b/app/assets/javascripts/discourse/package.json @@ -49,6 +49,7 @@ "ember-load-initializers": "^2.1.1", "ember-maybe-import-regenerator": "^0.1.6", "ember-qunit": "^5.1.2", + "ember-rfc176-data": "^0.3.17", "ember-source": "~3.15.0", "ember-test-selectors": "^6.0.0", "eslint": "^7.27.0", @@ -79,7 +80,8 @@ }, "ember-addon": { "paths": [ - "lib/bootstrap-json" + "lib/bootstrap-json", + "lib/rfc176-shims" ] }, "devDependencies": { diff --git a/app/assets/javascripts/discourse/public/assets/scripts/discourse-boot.js b/app/assets/javascripts/discourse/public/assets/scripts/discourse-boot.js index a1fe1ebd489..1bc1786c8db 100644 --- a/app/assets/javascripts/discourse/public/assets/scripts/discourse-boot.js +++ b/app/assets/javascripts/discourse/public/assets/scripts/discourse-boot.js @@ -2,157 +2,6 @@ if (window.unsupportedBrowser) { throw "Unsupported browser detected"; } - // TODO: These are needed to load plugins because @ember has its own loader. - // We should find a nicer way to do this. - const EMBER_MODULES = { - "@ember/application": { - default: Ember.Application, - setOwner: Ember.setOwner, - getOwner: Ember.getOwner, - }, - "@ember/array": { - default: Ember.Array, - A: Ember.A, - isArray: Ember.isArray, - }, - "@ember/array/proxy": { - default: Ember.ArrayProxy, - }, - "@ember/component": { - default: Ember.Component, - }, - "@ember/component/helper": { - default: Ember.Helper, - }, - "@ember/component/text-field": { - default: Ember.TextField, - }, - "@ember/component/text-area": { - default: Ember.TextArea, - }, - "@ember/controller": { - default: Ember.Controller, - inject: Ember.inject.controller, - }, - "@ember/debug": { - warn: Ember.warn, - }, - "@ember/error": { - default: Ember.error, - }, - "@ember/object": { - action: Ember._action, - default: Ember.Object, - get: Ember.get, - getProperties: Ember.getProperties, - set: Ember.set, - setProperties: Ember.setProperties, - computed: Ember.computed, - defineProperty: Ember.defineProperty, - }, - "@ember/object/computed": { - alias: Ember.computed.alias, - and: Ember.computed.and, - bool: Ember.computed.bool, - collect: Ember.computed.collect, - deprecatingAlias: Ember.computed.deprecatingAlias, - empty: Ember.computed.empty, - equal: Ember.computed.equal, - filter: Ember.computed.filter, - filterBy: Ember.computed.filterBy, - gt: Ember.computed.gt, - gte: Ember.computed.gte, - intersect: Ember.computed.intersect, - lt: Ember.computed.lt, - lte: Ember.computed.lte, - map: Ember.computed.map, - mapBy: Ember.computed.mapBy, - match: Ember.computed.match, - max: Ember.computed.max, - min: Ember.computed.min, - none: Ember.computed.none, - not: Ember.computed.not, - notEmpty: Ember.computed.notEmpty, - oneWay: Ember.computed.oneWay, - or: Ember.computed.or, - readOnly: Ember.computed.readOnly, - reads: Ember.computed.reads, - setDiff: Ember.computed.setDiff, - sort: Ember.computed.sort, - sum: Ember.computed.sum, - union: Ember.computed.union, - uniq: Ember.computed.uniq, - uniqBy: Ember.computed.uniqBy, - }, - "@ember/object/internals": { - guidFor: Ember.guidFor, - }, - "@ember/object/mixin": { default: Ember.Mixin }, - "@ember/object/proxy": { default: Ember.ObjectProxy }, - "@ember/object/promise-proxy-mixin": { default: Ember.PromiseProxyMixin }, - "@ember/object/evented": { - default: Ember.Evented, - on: Ember.on, - }, - "@ember/routing/route": { default: Ember.Route }, - "@ember/routing/router": { default: Ember.Router }, - "@ember/runloop": { - bind: Ember.run.bind, - cancel: Ember.run.cancel, - debounce: Ember.testing ? Ember.run : Ember.run.debounce, - later: Ember.run.later, - next: Ember.run.next, - once: Ember.run.once, - run: Ember.run, - schedule: Ember.run.schedule, - scheduleOnce: Ember.run.scheduleOnce, - throttle: Ember.run.throttle, - }, - "@ember/service": { - default: Ember.Service, - inject: Ember.inject.service, - }, - "@ember/string": { - w: Ember.String.w, - dasherize: Ember.String.dasherize, - decamelize: Ember.String.decamelize, - camelize: Ember.String.camelize, - classify: Ember.String.classify, - underscore: Ember.String.underscore, - capitalize: Ember.String.capitalize, - }, - "@ember/template": { - htmlSafe: Ember.String.htmlSafe, - }, - "@ember/utils": { - isBlank: Ember.isBlank, - isEmpty: Ember.isEmpty, - isNone: Ember.isNone, - isPresent: Ember.isPresent, - }, - jquery: { default: $ }, - rsvp: { - asap: Ember.RSVP.asap, - all: Ember.RSVP.all, - allSettled: Ember.RSVP.allSettled, - race: Ember.RSVP.race, - hash: Ember.RSVP.hash, - hashSettled: Ember.RSVP.hashSettled, - rethrow: Ember.RSVP.rethrow, - defer: Ember.RSVP.defer, - denodeify: Ember.RSVP.denodeify, - resolve: Ember.RSVP.resolve, - reject: Ember.RSVP.reject, - map: Ember.RSVP.map, - filter: Ember.RSVP.filter, - default: Ember.RSVP, - Promise: Ember.RSVP.Promise, - EventTarget: Ember.RSVP.EventTarget, - }, - }; - Object.keys(EMBER_MODULES).forEach((mod) => { - define(mod, () => EMBER_MODULES[mod]); - }); // TODO: Remove this and have resolver find the templates const prefix = "discourse/templates/"; @@ -166,15 +15,6 @@ } }); - define("I18n", ["exports"], function (exports) { - return I18n; - }); - - define("htmlbars-inline-precompile", ["exports"], function (exports) { - exports.default = function tag(strings) { - return Ember.Handlebars.compile(strings[0]); - }; - }); window.__widget_helpers = require("discourse-widget-hbs/helpers").default; // TODO: Eliminate this global diff --git a/app/assets/javascripts/discourse/public/assets/scripts/module-shims.js b/app/assets/javascripts/discourse/public/assets/scripts/module-shims.js new file mode 100644 index 00000000000..cab696c0126 --- /dev/null +++ b/app/assets/javascripts/discourse/public/assets/scripts/module-shims.js @@ -0,0 +1,9 @@ +define("I18n", ["exports"], function (exports) { + return I18n; +}); + +define("htmlbars-inline-precompile", ["exports"], function (exports) { + exports.default = function tag(strings) { + return Ember.Handlebars.compile(strings[0]); + }; +});