DEV: Update Ember to 6.6.0 (#34460)

This upgrade does not include any breaking changes for Discourse
themes/plugins. Two of the three deprecations in Ember 6 (array
prototype extensions, component-template resolution) have already been
polyfilled in Discourse. The third (action helper/modifier) is
polyfilled in this commit.

Performance testing shows a 2-3% improvement in Discourse rendering
time, thanks to upstream performance fixes in the glimmer-vm since the
regressions in the Ember 5.x series.

---------

Co-authored-by: David Taylor <david@taylorhq.com>
This commit is contained in:
Jarek Radosz
2025-08-27 16:48:40 +01:00
committed by GitHub
co-authored by David Taylor
parent 2daf45e5e5
commit 06f841da08
24 changed files with 808 additions and 528 deletions
-1
View File
@@ -181,7 +181,6 @@ jobs:
run: rm -rf public/uploads && cp -r tmp/app-cache/uploads public/uploads
- name: Create and migrate database
if: steps.app-cache.outputs.cache-hit != 'true'
env:
LOAD_PLUGINS: ${{ (matrix.target == 'plugins' || matrix.target == 'chat') && '1' || '0' }}
run: |
+2 -2
View File
@@ -23,7 +23,7 @@
"devDependencies": {
"@ember/optional-features": "^2.2.0",
"@embroider/test-setup": "^4.0.0",
"@glimmer/component": "^1.1.2",
"@glimmer/component": "^2.0.0",
"@types/jquery": "^3.5.33",
"@types/qunit": "^2.19.13",
"@types/rsvp": "^4.0.9",
@@ -35,7 +35,7 @@
"ember-disable-prototype-extensions": "^1.1.3",
"ember-load-initializers": "^3.0.1",
"ember-resolver": "^13.1.1",
"ember-source": "~5.12.0",
"ember-source": "~6.6.0",
"ember-source-channel-url": "^3.0.0",
"loader.js": "^4.7.0",
"webpack": "^5.101.3"
@@ -8,6 +8,7 @@ const fs = require("fs");
const concat = require("broccoli-concat");
const DiscoursePluginColocatedTemplateProcessor = require("./colocated-template-compiler");
const EmberApp = require("ember-cli/lib/broccoli/ember-app");
const transformActionSyntax = require("./transform-action-syntax");
function fixLegacyExtensions(tree) {
return new Funnel(tree, {
@@ -103,6 +104,28 @@ module.exports = {
},
},
setupPreprocessorRegistry(type, registry) {
if (type === "self") {
const plugin = this._buildActionPlugin();
plugin.parallelBabel = {
requireFile: __filename,
buildUsing: "_buildActionPlugin",
params: {},
};
registry.add("htmlbars-ast-plugin", plugin);
}
},
_buildActionPlugin() {
return {
name: "transform-action-syntax",
plugin: transformActionSyntax,
baseDir: transformActionSyntax.baseDir,
cacheKey: transformActionSyntax.cacheKey,
};
},
pluginInfos() {
const root = path.resolve("../../../../plugins");
const pluginDirectories = fs
@@ -0,0 +1,67 @@
// backported from https://github.com/emberjs/ember.js/blob/v5.12.0/packages/ember-template-compiler/lib/plugins/transform-action-syntax.ts
/**
A Glimmer2 AST transformation that replaces all instances of
```handlebars
<button {{action 'foo'}}>
<button onblur={{action 'foo'}}>
<button onblur={{action (action 'foo') 'bar'}}>
```
with
```handlebars
<button {{action this 'foo'}}>
<button onblur={{action this 'foo'}}>
<button onblur={{action this (action this 'foo') 'bar'}}>
```
@private
@class TransformActionSyntax
*/
function transformActionSyntax({ syntax }) {
let { builders: b } = syntax;
return {
name: "transform-action-syntax",
visitor: {
ElementModifierStatement(node) {
if (isAction(node)) {
insertThisAsFirstParam(node, b);
}
},
MustacheStatement(node) {
if (isAction(node)) {
insertThisAsFirstParam(node, b);
}
},
SubExpression(node) {
if (isAction(node)) {
insertThisAsFirstParam(node, b);
}
},
},
};
}
transformActionSyntax.baseDir = () => __dirname;
transformActionSyntax.cacheKey = () => "transform-action-syntax";
module.exports = transformActionSyntax;
function isPath(node) {
return node.type === "PathExpression";
}
function isAction(node) {
return isPath(node.path) && node.path.original === "d-action";
}
function insertThisAsFirstParam(node, builders) {
node.params.unshift(builders.path("this"));
}
@@ -22,7 +22,7 @@
"devDependencies": {
"@ember/optional-features": "^2.2.0",
"@embroider/test-setup": "^4.0.0",
"@glimmer/component": "^1.1.2",
"@glimmer/component": "^2.0.0",
"@glimmer/syntax": "0.93.1",
"broccoli-asset-rev": "^3.0.0",
"ember-cli": "~6.6.0",
@@ -32,7 +32,7 @@
"ember-disable-prototype-extensions": "^1.1.3",
"ember-load-initializers": "^3.0.1",
"ember-resolver": "^13.1.1",
"ember-source": "~5.12.0",
"ember-source": "~6.6.0",
"ember-source-channel-url": "^3.0.0",
"loader.js": "^4.7.0",
"webpack": "^5.101.3"
+1 -1
View File
@@ -38,7 +38,7 @@ async function loadThemeFromModulePreload(link) {
// eslint-disable-next-line no-console
console.error(
`Failed to load theme ${link.dataset.themeId} from ${link.href}`,
error
String(error)
);
fireThemeErrorEvent({ themeId: link.dataset.themeId, error });
}
@@ -5,6 +5,10 @@ const DEPRECATION_WORKFLOW = [
handler: "silence",
matchId: "discourse.decorate-widget.hamburger-widget-links",
},
{
handler: "silence",
matchId: "deprecate-import-meta-from-ember",
},
];
export default DEPRECATION_WORKFLOW;
@@ -0,0 +1,118 @@
import { setInternalHelperManager } from "@glimmer/manager";
import {
createUnboundRef,
isInvokableRef,
updateRef,
valueForRef,
} from "@glimmer/reference";
import { get } from "@ember/-internals/metal";
import { flaggedInstrument } from "@ember/instrumentation";
import { join } from "@ember/runloop";
import deprecated from "discourse/lib/deprecated";
function NOOP(args) {
return args;
}
function makeArgsProcessor(valuePathRef, actionArgsRef) {
let mergeArgs;
if (actionArgsRef.length > 0) {
mergeArgs = (args) => {
return actionArgsRef.map(valueForRef).concat(args);
};
}
let readValue;
if (valuePathRef) {
readValue = (args) => {
let valuePath = valueForRef(valuePathRef);
if (valuePath && args.length > 0) {
args[0] = get(args[0], valuePath);
}
return args;
};
}
if (mergeArgs && readValue) {
return (args) => {
return readValue(mergeArgs(args));
};
} else {
return mergeArgs || readValue || NOOP;
}
}
function makeClosureAction(context, target, action, processArgs) {
let self;
let fn;
if (typeof action === "string") {
self = target;
let value = target.actions?.[action];
fn = value;
} else if (typeof action === "function") {
self = context;
fn = action;
}
return (...args) => {
let payload = { target: self, args, label: "@glimmer/closure-action" };
return flaggedInstrument("interaction.ember-action", payload, () => {
return join(self, fn, ...processArgs(args));
});
};
}
function makeDynamicClosureAction(context, targetRef, actionRef, processArgs) {
const action = valueForRef(actionRef);
return (...args) => {
return makeClosureAction(
context,
valueForRef(targetRef),
action,
processArgs
)(...args);
};
}
function invokeRef(value) {
updateRef(this, value);
}
// a port of ember's builtin action helper
export default setInternalHelperManager(({ named, positional }) => {
deprecated(
`Usage of the \`(action)\` helper is deprecated. Migrate to native functions and function invocation.`,
{
id: "discourse.template-action",
url: "https://deprecations.emberjs.com/id/template-action",
}
);
let [context, action, ...restArgs] = positional;
let target = "target" in named ? named["target"] : context;
let processArgs = makeArgsProcessor(
("value" in named && named["value"]) || false,
restArgs
);
let fn;
if (isInvokableRef(action)) {
fn = makeClosureAction(action, action, invokeRef, processArgs);
} else {
fn = makeDynamicClosureAction(
valueForRef(context),
target,
action,
processArgs
);
}
return createUnboundRef(fn, "(result of an `action` helper)");
}, {});
@@ -1,4 +1,5 @@
import { modifier } from "ember-modifier";
import deprecated from "./deprecated";
/**
* Creates a replacement for Ember's built-in `action` modifier that uses
@@ -15,6 +16,14 @@ export const actionModifier = modifier(
[context, callback, ...args],
{ on, bubbles, preventDefault, allowedKeys }
) => {
deprecated(
`Usage of the \`{{action}}\` modifier is deprecated. Migrate to native functions and function invocation.`,
{
id: "discourse.template-action",
url: "https://deprecations.emberjs.com/id/template-action",
}
);
const handler = (event) => {
let fn;
if (typeof callback === "string") {
@@ -80,7 +80,7 @@
"@embroider/router": "^2.1.8",
"@embroider/webpack": "^4.1.0",
"@floating-ui/dom": "^1.7.4",
"@glimmer/component": "^1.1.2",
"@glimmer/component": "^2.0.0",
"@glimmer/tracking": "^1.1.2",
"@popperjs/core": "^2.11.8",
"@swc/core": "^1.13.5",
@@ -123,7 +123,7 @@
"ember-load-initializers": "^3.0.1",
"ember-modifier": "^4.2.2",
"ember-qunit": "^9.0.3",
"ember-source": "~5.12.0",
"ember-source": "~6.6.0",
"ember-template-imports": "^4.3.0",
"ember-test-selectors": "^7.1.0",
"float-kit": "workspace:1.0.0",
@@ -123,7 +123,12 @@ module("Integration | Component | plugin-outlet", function (hooks) {
});
test("Renders a template into the outlet", async function (assert) {
await render(hbs`<PluginOutlet @name="test-name" />`);
await withSilencedDeprecationsAsync(
"discourse.template-action",
async () => {
await render(hbs`<PluginOutlet @name="test-name" />`);
}
);
assert
.dom(".hello-username")
@@ -389,12 +394,17 @@ module("Integration | Component | plugin-outlet", function (hooks) {
test("Reevaluates shouldRender for argument changes", async function (assert) {
this.set("shouldDisplay", false);
await render(hbs`
<PluginOutlet
@name="test-name"
@outletArgs={{lazyHash shouldDisplay=this.shouldDisplay}}
/>
`);
await withSilencedDeprecationsAsync(
"discourse.template-action",
async () => {
await render(hbs`
<PluginOutlet
@name="test-name"
@outletArgs={{lazyHash shouldDisplay=this.shouldDisplay}}
/>
`);
}
);
assert
.dom(".conditional-render")
.doesNotExist("doesn't render conditional outlet");
@@ -405,7 +415,12 @@ module("Integration | Component | plugin-outlet", function (hooks) {
});
test("Reevaluates shouldRender for other autotracked changes", async function (assert) {
await render(hbs`<PluginOutlet @name="test-name" />`);
await withSilencedDeprecationsAsync(
"discourse.template-action",
async () => {
await render(hbs`<PluginOutlet @name="test-name" />`);
}
);
assert
.dom(".conditional-render")
.doesNotExist("doesn't render conditional outlet");
@@ -416,7 +431,12 @@ module("Integration | Component | plugin-outlet", function (hooks) {
});
test("shouldRender receives an owner argument", async function (assert) {
await render(hbs`<PluginOutlet @name="test-name" />`);
await withSilencedDeprecationsAsync(
"discourse.template-action",
async () => {
await render(hbs`<PluginOutlet @name="test-name" />`);
}
);
assert
.dom(".conditional-render")
.doesNotExist("doesn't render conditional outlet");
@@ -428,12 +448,17 @@ module("Integration | Component | plugin-outlet", function (hooks) {
test("Other outlets are not re-rendered", async function (assert) {
this.set("shouldDisplay", false);
await render(hbs`
<PluginOutlet
@name="test-name"
@outletArgs={{lazyHash shouldDisplay=this.shouldDisplay}}
/>
`);
await withSilencedDeprecationsAsync(
"discourse.template-action",
async () => {
await render(hbs`
<PluginOutlet
@name="test-name"
@outletArgs={{lazyHash shouldDisplay=this.shouldDisplay}}
/>
`);
}
);
find(".hello-username").someUniqueProperty = true;
@@ -462,15 +487,20 @@ module("Integration | Component | plugin-outlet", function (hooks) {
});
test("deprecated parameters with default message", async function (assert) {
await render(
<template>
<PluginOutlet
@name="test-name"
@deprecatedArgs={{lazyHash
shouldDisplay=(deprecatedOutletArgument value=true)
}}
/>
</template>
await withSilencedDeprecationsAsync(
"discourse.template-action",
async () => {
await render(
<template>
<PluginOutlet
@name="test-name"
@deprecatedArgs={{lazyHash
shouldDisplay=(deprecatedOutletArgument value=true)
}}
/>
</template>
);
}
);
// deprecated argument still works
@@ -490,21 +520,26 @@ module("Integration | Component | plugin-outlet", function (hooks) {
});
test("deprecated parameters with custom deprecation data", async function (assert) {
await render(
<template>
<PluginOutlet
@name="test-name"
@deprecatedArgs={{lazyHash
shouldDisplay=(deprecatedOutletArgument
value=true
message="The 'shouldDisplay' is deprecated on this test"
id="discourse.plugin-connector.deprecated-arg.test"
since="3.3.0.beta4-dev"
dropFrom="3.4.0"
)
}}
/>
</template>
await withSilencedDeprecationsAsync(
"discourse.template-action",
async () => {
await render(
<template>
<PluginOutlet
@name="test-name"
@deprecatedArgs={{lazyHash
shouldDisplay=(deprecatedOutletArgument
value=true
message="The 'shouldDisplay' is deprecated on this test"
id="discourse.plugin-connector.deprecated-arg.test"
since="3.3.0.beta4-dev"
dropFrom="3.4.0"
)
}}
/>
</template>
);
}
);
// deprecated argument still works
@@ -553,18 +588,23 @@ module("Integration | Component | plugin-outlet", function (hooks) {
},
};
await render(
<template>
<PluginOutlet
@name="test-name"
@deprecatedArgs={{lazyHash
shouldDisplay=(deprecatedOutletArgument
value=deprecatedData.display
silence="discourse.deprecation-that-should-not-be-logged"
)
}}
/>
</template>
await withSilencedDeprecationsAsync(
"discourse.template-action",
async () => {
await render(
<template>
<PluginOutlet
@name="test-name"
@deprecatedArgs={{lazyHash
shouldDisplay=(deprecatedOutletArgument
value=deprecatedData.display
silence="discourse.deprecation-that-should-not-be-logged"
)
}}
/>
</template>
);
}
);
// deprecated argument still works
@@ -594,16 +634,21 @@ module("Integration | Component | plugin-outlet", function (hooks) {
});
test("unused arguments", async function (assert) {
await render(
<template>
<PluginOutlet
@name="test-name"
@outletArgs={{lazyHash shouldDisplay=true}}
@deprecatedArgs={{lazyHash
argNotUsed=(deprecatedOutletArgument value=true)
}}
/>
</template>
await withSilencedDeprecationsAsync(
"discourse.template-action",
async () => {
await render(
<template>
<PluginOutlet
@name="test-name"
@outletArgs={{lazyHash shouldDisplay=true}}
@deprecatedArgs={{lazyHash
argNotUsed=(deprecatedOutletArgument value=true)
}}
/>
</template>
);
}
);
// deprecated argument still works
@@ -5,6 +5,7 @@ import { click, doubleClick, render } from "@ember/test-helpers";
import { hbs } from "ember-cli-htmlbars";
import { setupRenderingTest } from "ember-qunit";
import { module, test } from "qunit";
import { withSilencedDeprecationsAsync } from "discourse/lib/deprecated";
module("Unit | Lib | ember-action-modifier", function (hooks) {
setupRenderingTest(hooks);
@@ -17,9 +18,14 @@ module("Unit | Lib | ember-action-modifier", function (hooks) {
childClicked: undefined,
});
await render(hbs`
<button id="childButton" {{action this.onChildClick}} />
`);
await withSilencedDeprecationsAsync(
"discourse.template-action",
async () => {
await render(hbs`
<button id="childButton" {{action this.onChildClick}} />
`);
}
);
await click("#childButton");
@@ -34,9 +40,14 @@ module("Unit | Lib | ember-action-modifier", function (hooks) {
childClicked: undefined,
});
await render(hbs`
<button id="childButton" {{action 'onChildClick'}} />
`);
await withSilencedDeprecationsAsync(
"discourse.template-action",
async () => {
await render(hbs`
<button id="childButton" {{action 'onChildClick'}} />
`);
}
);
await click("#childButton");
@@ -51,9 +62,14 @@ module("Unit | Lib | ember-action-modifier", function (hooks) {
childClicked: undefined,
});
await render(hbs`
await withSilencedDeprecationsAsync(
"discourse.template-action",
async () => {
await render(hbs`
<button id="childButton" {{action 'onChildClick'}} />
`);
}
);
await click("#childButton", { ctrlKey: true });
@@ -68,9 +84,14 @@ module("Unit | Lib | ember-action-modifier", function (hooks) {
dblClicked: undefined,
});
await render(hbs`
await withSilencedDeprecationsAsync(
"discourse.template-action",
async () => {
await render(hbs`
<button id="childButton" {{action this.onDblClick on='dblclick'}} />
`);
}
);
await doubleClick("#childButton");
@@ -146,9 +167,14 @@ module("Unit | Lib | ember-action-modifier", function (hooks) {
oneClicked: undefined,
});
await render(hbs`
await withSilencedDeprecationsAsync(
"discourse.template-action",
async () => {
await render(hbs`
<ExampleClassicButton @onDoSomething={{this.onOneClick}} />
`);
}
);
assert.strictEqual(this.oneClicked, undefined);
@@ -172,9 +198,14 @@ module("Unit | Lib | ember-action-modifier", function (hooks) {
oneClicked: undefined,
});
await render(hbs`
<ExampleClassicButtonWithActions @onDoSomething={{this.onOneClick}} />
`);
await withSilencedDeprecationsAsync(
"discourse.template-action",
async () => {
await render(hbs`
<ExampleClassicButtonWithActions @onDoSomething={{this.onOneClick}} />
`);
}
);
assert.strictEqual(this.oneClicked, undefined);
@@ -7,6 +7,7 @@ import { click, render } from "@ember/test-helpers";
import { hbs } from "ember-cli-htmlbars";
import { setupRenderingTest } from "ember-qunit";
import { module, test } from "qunit";
import { withSilencedDeprecationsAsync } from "discourse/lib/deprecated";
// Configure test-local Classic and Glimmer components that
// will be immune from upgrades to actual Discourse components.
@@ -210,11 +211,16 @@ module("Unit | Lib | ember-events", function (hooks) {
childClicked: undefined,
});
await render(hbs`
<ExampleClassicButton id="parentButton" @onClick={{this.onParentClick}}>
<button id="childButton" {{action this.onChildClick}} />
</ExampleClassicButton>
`);
await withSilencedDeprecationsAsync(
"discourse.template-action",
async () => {
await render(hbs`
<ExampleClassicButton id="parentButton" @onClick={{this.onParentClick}}>
<button id="childButton" {{action this.onChildClick}} />
</ExampleClassicButton>
`);
}
);
await click("#childButton");
@@ -232,11 +238,16 @@ module("Unit | Lib | ember-events", function (hooks) {
childClicked: undefined,
});
await render(hbs`
<ExampleClassicButton id="parentButton" @onClick={{this.onParentClick}}>
<button id="childButton" {{action this.onChildClick bubbles=false}} />
</ExampleClassicButton>
`);
await withSilencedDeprecationsAsync(
"discourse.template-action",
async () => {
await render(hbs`
<ExampleClassicButton id="parentButton" @onClick={{this.onParentClick}}>
<button id="childButton" {{action this.onChildClick bubbles=false}} />
</ExampleClassicButton>
`);
}
);
await click("#childButton");
@@ -256,11 +267,16 @@ module("Unit | Lib | ember-events", function (hooks) {
childClicked: undefined,
});
await render(hbs`
<ExampleGlimmerButton id="parentButton" @onClick={{this.onParentClick}}>
<button id="childButton" {{action this.onChildClick}} />
</ExampleGlimmerButton>
`);
await withSilencedDeprecationsAsync(
"discourse.template-action",
async () => {
await render(hbs`
<ExampleGlimmerButton id="parentButton" @onClick={{this.onParentClick}}>
<button id="childButton" {{action this.onChildClick}} />
</ExampleGlimmerButton>
`);
}
);
await click("#childButton");
@@ -278,11 +294,16 @@ module("Unit | Lib | ember-events", function (hooks) {
childClicked: undefined,
});
await render(hbs`
<ExampleGlimmerButton id="parentButton" @onClick={{this.onParentClick}}>
<button id="childButton" {{action this.onChildClick bubbles=false}} />
</ExampleGlimmerButton>
`);
await withSilencedDeprecationsAsync(
"discourse.template-action",
async () => {
await render(hbs`
<ExampleGlimmerButton id="parentButton" @onClick={{this.onParentClick}}>
<button id="childButton" {{action this.onChildClick bubbles=false}} />
</ExampleGlimmerButton>
`);
}
);
await click("#childButton");
@@ -27,7 +27,7 @@
"devDependencies": {
"@ember/optional-features": "^2.2.0",
"@embroider/test-setup": "^4.0.0",
"@glimmer/component": "^1.1.2",
"@glimmer/component": "^2.0.0",
"@types/jquery": "^3.5.33",
"@types/qunit": "^2.19.13",
"@types/rsvp": "^4.0.9",
@@ -39,7 +39,7 @@
"ember-disable-prototype-extensions": "^1.1.3",
"ember-load-initializers": "^3.0.1",
"ember-resolver": "^13.1.1",
"ember-source": "~5.12.0",
"ember-source": "~6.6.0",
"ember-source-channel-url": "^3.0.0",
"loader.js": "^4.7.0",
"webpack": "^5.101.3"
@@ -24,7 +24,7 @@
"devDependencies": {
"@ember/optional-features": "^2.2.0",
"@embroider/test-setup": "^4.0.0",
"@glimmer/component": "^1.1.2",
"@glimmer/component": "^2.0.0",
"@types/jquery": "^3.5.33",
"@types/qunit": "^2.19.13",
"@types/rsvp": "^4.0.9",
@@ -36,7 +36,7 @@
"ember-disable-prototype-extensions": "^1.1.3",
"ember-load-initializers": "^3.0.1",
"ember-resolver": "^13.1.1",
"ember-source": "~5.12.0",
"ember-source": "~6.6.0",
"ember-source-channel-url": "^3.0.0",
"loader.js": "^4.7.0",
"webpack": "^5.101.3"
@@ -30,7 +30,7 @@
"devDependencies": {
"@ember/optional-features": "^2.2.0",
"@embroider/test-setup": "^4.0.0",
"@glimmer/component": "^1.1.2",
"@glimmer/component": "^2.0.0",
"@types/jquery": "^3.5.33",
"@types/qunit": "^2.19.13",
"@types/rsvp": "^4.0.9",
@@ -42,7 +42,7 @@
"ember-disable-prototype-extensions": "^1.1.3",
"ember-load-initializers": "^3.0.1",
"ember-resolver": "^13.1.1",
"ember-source": "~5.12.0",
"ember-source": "~6.6.0",
"ember-source-channel-url": "^3.0.0",
"loader.js": "^4.7.0",
"webpack": "^5.101.3"
@@ -23,9 +23,10 @@
"core-js": "^3.45.1",
"decorator-transforms": "^2.3.0",
"discourse": "workspace:0.0.0",
"discourse-plugins": "workspace:1.0.0",
"discourse-widget-hbs": "workspace:1.0.0",
"ember-cli-htmlbars": "^6.3.0",
"ember-source": "~5.12.0",
"ember-source": "~6.6.0",
"ember-this-fallback": "^0.4.0",
"fastestsmallesttextencoderdecoder": "^1.0.22",
"magic-string": "^0.30.18",
@@ -4,13 +4,14 @@ import { babel, getBabelOutputPlugin } from "@rollup/plugin-babel";
import HTMLBarsInlinePrecompile from "babel-plugin-ember-template-compilation";
import DecoratorTransforms from "decorator-transforms";
import colocatedBabelPlugin from "ember-cli-htmlbars/lib/colocated-babel-plugin";
import { precompile } from "ember-source/dist/ember-template-compiler";
import EmberThisFallback from "ember-this-fallback";
import { memfs } from "memfs";
import transformActionSyntax from "discourse-plugins/transform-action-syntax";
import { WidgetHbsCompiler } from "discourse-widget-hbs/lib/widget-hbs-compiler";
import { browsers } from "../discourse/config/targets";
import AddThemeGlobals from "./add-theme-globals";
import BabelReplaceImports from "./babel-replace-imports";
import { precompile } from "./node_modules/ember-source/dist/ember-template-compiler";
import discourseColocation from "./rollup-plugins/discourse-colocation";
import discourseExtensionSearch from "./rollup-plugins/discourse-extension-search";
import discourseExternalLoader from "./rollup-plugins/discourse-external-loader";
@@ -72,6 +73,7 @@ globalThis.rollup = function (modules, opts) {
isTheme: true,
}).plugin,
buildEmberTemplateManipulatorPlugin(opts.themeId),
transformActionSyntax,
],
},
],
+4 -1
View File
@@ -71,7 +71,7 @@
"virtual-dom@2.1.1": "patches/virtual-dom@2.1.1.patch",
"licensee@11.1.1": "patches/licensee@11.1.1.patch",
"@ember-compat/tracked-built-ins@0.9.1": "patches/@ember-compat__tracked-built-ins@0.9.1.patch",
"ember-source@5.12.0": "patches/ember-source@5.12.0.patch"
"ember-source@6.6.0": "patches/ember-source@6.6.0.patch"
},
"peerDependencyRules": {
"allowedVersions": {
@@ -83,6 +83,9 @@
"ignoreMissing": [
"webpack"
]
},
"overrides": {
"@ember/test-waiters": "4.1.1"
}
}
}
-66
View File
@@ -1,66 +0,0 @@
diff --git a/dist/ember-template-compiler.js b/dist/ember-template-compiler.js
index 01999af0c4c125af3c713318db7eb85fa492f72d..edadab049d4e5959b4d33ddcbe59bcaec9641e61 100644
--- a/dist/ember-template-compiler.js
+++ b/dist/ember-template-compiler.js
@@ -9485,10 +9485,20 @@ var define, require;
return Object.defineProperty(node, "escaped", {
enumerable: !1,
get() {
- return deprecate$1("The escaped property on mustache nodes is deprecated, use trusting instead"), !this.trusting;
+ // when upgrading Ember check if this patch is still necessary
+ // Ember 5.12 still shipped with the template-compiler generating a ton of warnings but the fix is already commited
+ // to glimmervm/syntax
+ // See https://github.com/glimmerjs/glimmer-vm/commit/02313376f21a606841b00a7789fd6128a1b292af
+ // return deprecate$1("The escaped property on mustache nodes is deprecated, use trusting instead"), !this.trusting;
+ return !this.trusting;
},
set(value) {
- deprecate$1("The escaped property on mustache nodes is deprecated, use trusting instead"), this.trusting = !value;
+ // when upgrading Ember check if this patch is still necessary
+ // Ember 5.12 still shipped with the template-compiler generating a ton of warnings but the fix is already commited
+ // to glimmervm/syntax
+ // See https://github.com/glimmerjs/glimmer-vm/commit/02313376f21a606841b00a7789fd6128a1b292af
+ // deprecate$1("The escaped property on mustache nodes is deprecated, use trusting instead"), this.trusting = !value;
+ this.trusting = !value;
}
}), node;
}({
diff --git a/dist/packages/@ember/-internals/deprecations/index.js b/dist/packages/@ember/-internals/deprecations/index.js
index a6390a7c14f78c4876f97695e057231c1c7ecef0..f62f2d4efbdbf3fb01cd9d1235ac5dc0967a8756 100644
--- a/dist/packages/@ember/-internals/deprecations/index.js
+++ b/dist/packages/@ember/-internals/deprecations/index.js
@@ -142,7 +142,7 @@ function deprecateUntil(message, deprecation) {
if (deprecation.isRemoved) {
throw new Error(`The API deprecated by ${options.id} was removed in ember-source ${options.until}. The message was: ${message}. Please see ${options.url} for more details.`);
}
- (isDevelopingApp() && !(deprecation.test) && deprecate(message, deprecation.test, options));
+ (true && !(deprecation.test) && deprecate(message, deprecation.test, options));
}
const {
EXTEND_PROTOTYPES
diff --git a/dist/packages/@ember/debug/lib/deprecate.js b/dist/packages/@ember/debug/lib/deprecate.js
index bd48673cc5a4416b492daded7e1ca4ff5b1a8d8d..9cf7b80e7308dd4b34b5d6a980294de43ce21bd5 100644
--- a/dist/packages/@ember/debug/lib/deprecate.js
+++ b/dist/packages/@ember/debug/lib/deprecate.js
@@ -50,7 +50,7 @@ let missingOptionsDeprecation;
let missingOptionsIdDeprecation;
let missingOptionDeprecation = () => '';
let deprecate = () => {};
-if (isDevelopingApp()) {
+if (true) {
registerHandler = function registerHandler(handler) {
registerHandler$1('deprecate', handler);
};
diff --git a/dist/packages/@ember/debug/lib/handlers.js b/dist/packages/@ember/debug/lib/handlers.js
index cd68afe479229ed77b4e4c93759aa90913cdc49c..6e7d71bbeb28f18259fa8afb48ef78279f25c531 100644
--- a/dist/packages/@ember/debug/lib/handlers.js
+++ b/dist/packages/@ember/debug/lib/handlers.js
@@ -3,7 +3,7 @@ import { isDevelopingApp } from '@embroider/macros';
let HANDLERS = {};
let registerHandler = function registerHandler(_type, _callback) {};
let invoke = () => {};
-if (isDevelopingApp()) {
+if (true) {
registerHandler = function registerHandler(type, callback) {
let nextHandler = HANDLERS[type] || (() => {});
HANDLERS[type] = (message, options) => {
+39
View File
@@ -0,0 +1,39 @@
diff --git a/dist/packages/@ember/-internals/deprecations/index.js b/dist/packages/@ember/-internals/deprecations/index.js
index 894cd5c5e28db30f8798ee828b8364c94d488964..bffb6b1c0d22d3611f8e85414c0f34f0e416e4f4 100644
--- a/dist/packages/@ember/-internals/deprecations/index.js
+++ b/dist/packages/@ember/-internals/deprecations/index.js
@@ -123,7 +123,7 @@ function deprecateUntil(message, deprecation) {
if (deprecation.isRemoved) {
throw new Error(`The API deprecated by ${options.id} was removed in ember-source ${options.until}. The message was: ${message}. Please see ${options.url} for more details.`);
}
- (isDevelopingApp() && !(deprecation.test) && deprecate(message, deprecation.test, options));
+ (true && !(deprecation.test) && deprecate(message, deprecation.test, options));
}
const {
EXTEND_PROTOTYPES
diff --git a/dist/packages/@ember/debug/lib/deprecate.js b/dist/packages/@ember/debug/lib/deprecate.js
index 2a40f7cca607ab80beb267d79243fc30f16c92a1..9c15e205f3fb1661b8f1ae397c2338c42a3cc601 100644
--- a/dist/packages/@ember/debug/lib/deprecate.js
+++ b/dist/packages/@ember/debug/lib/deprecate.js
@@ -50,7 +50,7 @@ let missingOptionsDeprecation;
let missingOptionsIdDeprecation;
let missingOptionDeprecation = () => '';
let deprecate = () => {};
-if (isDevelopingApp()) {
+if (true) {
registerHandler = function registerHandler(handler) {
registerHandler$1('deprecate', handler);
};
diff --git a/dist/packages/@ember/debug/lib/handlers.js b/dist/packages/@ember/debug/lib/handlers.js
index cd68afe479229ed77b4e4c93759aa90913cdc49c..6e7d71bbeb28f18259fa8afb48ef78279f25c531 100644
--- a/dist/packages/@ember/debug/lib/handlers.js
+++ b/dist/packages/@ember/debug/lib/handlers.js
@@ -3,7 +3,7 @@ import { isDevelopingApp } from '@embroider/macros';
let HANDLERS = {};
let registerHandler = function registerHandler(_type, _callback) {};
let invoke = () => {};
-if (isDevelopingApp()) {
+if (true) {
registerHandler = function registerHandler(type, callback) {
let nextHandler = HANDLERS[type] || (() => {});
HANDLERS[type] = (message, options) => {
@@ -0,0 +1,66 @@
// eslint-disable-next-line ember/no-classic-components
import Component from "@ember/component";
import { action } from "@ember/object";
import { click, render } from "@ember/test-helpers";
import { hbs } from "ember-cli-htmlbars";
import { module, test } from "qunit";
import { withSilencedDeprecationsAsync } from "discourse/lib/deprecated";
import { setupRenderingTest } from "discourse/tests/helpers/component-test";
class FooString extends Component {
layout = hbs`<button {{on "click" (action "bar" 123)}}>test</button>`;
@action
bar(value) {
this.callback(value);
}
}
class FooReference extends Component {
layout = hbs`<button {{on "click" (action this.bar)}}>test</button>`;
@action
bar() {
this.callback();
}
}
// This is a core test but has to be in a plugin since the transform
// (that injects `this` into actions' params) is applied only to
// themes and plugins
module("Integration | Helper | action", function (hooks) {
setupRenderingTest(hooks);
test("string argument", async function (assert) {
this.registry.register("component:foo", FooString);
this.callback = (value) => {
assert.step("called");
assert.strictEqual(value, 123);
};
await withSilencedDeprecationsAsync(
"discourse.template-action",
async () => {
await render(hbs`<Foo @callback={{this.callback}} />`);
}
);
await click("button");
assert.verifySteps(["called"]);
});
test("reference argument", async function (assert) {
this.registry.register("component:foo", FooReference);
this.callback = () => assert.step("called");
await withSilencedDeprecationsAsync(
"discourse.template-action",
async () => {
await render(hbs`<Foo @callback={{this.callback}} />`);
}
);
await click("button");
assert.verifySteps(["called"]);
});
});
+204 -352
View File
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,66 @@
// eslint-disable-next-line ember/no-classic-components
import Component from "@ember/component";
import { action } from "@ember/object";
import { click, render } from "@ember/test-helpers";
import { hbs } from "ember-cli-htmlbars";
import { module, test } from "qunit";
import { withSilencedDeprecationsAsync } from "discourse/lib/deprecated";
import { setupRenderingTest } from "discourse/tests/helpers/component-test";
class FooString extends Component {
layout = hbs`<button {{on "click" (action "bar" 123)}}>test</button>`;
@action
bar(value) {
this.callback(value);
}
}
class FooReference extends Component {
layout = hbs`<button {{on "click" (action this.bar)}}>test</button>`;
@action
bar() {
this.callback();
}
}
// This is a core test but has to be in a theme since the transform
// (that injects `this` into actions' params) is applied only to
// themes and plugins
module("Integration | Helper | action", function (hooks) {
setupRenderingTest(hooks);
test("string argument", async function (assert) {
this.registry.register("component:foo", FooString);
this.callback = (value) => {
assert.step("called");
assert.strictEqual(value, 123);
};
await withSilencedDeprecationsAsync(
"discourse.template-action",
async () => {
await render(hbs`<Foo @callback={{this.callback}} />`);
}
);
await click("button");
assert.verifySteps(["called"]);
});
test("reference argument", async function (assert) {
this.registry.register("component:foo", FooReference);
this.callback = () => assert.step("called");
await withSilencedDeprecationsAsync(
"discourse.template-action",
async () => {
await render(hbs`<Foo @callback={{this.callback}} />`);
}
);
await click("button");
assert.verifySteps(["called"]);
});
});