diff --git a/app/assets/javascripts/discourse-common/addon/utils/handle-descriptor.js b/app/assets/javascripts/discourse-common/addon/utils/handle-descriptor.js
index d871e454eb..f53354a413 100644
--- a/app/assets/javascripts/discourse-common/addon/utils/handle-descriptor.js
+++ b/app/assets/javascripts/discourse-common/addon/utils/handle-descriptor.js
@@ -1,37 +1,48 @@
-import { computed, get } from "@ember/object";
+import EmberObject, { computed, get } from "@ember/object";
import extractValue from "./extract-value";
export default function handleDescriptor(target, key, desc, params = []) {
- return {
- enumerable: desc.enumerable,
- configurable: desc.configurable,
- writeable: desc.writeable,
- initializer() {
- let computedDescriptor;
+ const val = extractValue(desc);
- if (desc.writable) {
- let val = extractValue(desc);
- if (typeof val === "object") {
- let value = {};
- if (val.get) {
- value.get = callUserSuppliedGet(params, val.get);
+ if (typeof val === "function" && target instanceof EmberObject) {
+ // We're in a native class, so convert the method to a getter first
+ desc.writable = false;
+ desc.initializer = undefined;
+ desc.value = undefined;
+ desc.get = callUserSuppliedGet(params, val);
+
+ return computed(target, key, desc);
+ } else {
+ return {
+ enumerable: desc.enumerable,
+ configurable: desc.configurable,
+ writable: desc.writable,
+ initializer() {
+ let computedDescriptor;
+
+ if (desc.writable) {
+ if (typeof val === "object") {
+ let value = {};
+ if (val.get) {
+ value.get = callUserSuppliedGet(params, val.get);
+ }
+ if (val.set) {
+ value.set = callUserSuppliedSet(params, val.set);
+ }
+ computedDescriptor = value;
+ } else {
+ computedDescriptor = callUserSuppliedGet(params, val);
}
- if (val.set) {
- value.set = callUserSuppliedSet(params, val.set);
- }
- computedDescriptor = value;
} else {
- computedDescriptor = callUserSuppliedGet(params, val);
+ throw new Error(
+ "ember-computed-decorators does not support using getters and setters"
+ );
}
- } else {
- throw new Error(
- "ember-computed-decorators does not support using getters and setters"
- );
- }
- return computed.apply(null, params.concat(computedDescriptor));
- },
- };
+ return computed.apply(null, params.concat(computedDescriptor));
+ },
+ };
+ }
}
function niceAttr(attr) {
diff --git a/app/assets/javascripts/discourse/tests/unit/utils/decorators-test.js b/app/assets/javascripts/discourse/tests/unit/utils/decorators-test.js
index c0b7c960ab..d9df7ce3e1 100644
--- a/app/assets/javascripts/discourse/tests/unit/utils/decorators-test.js
+++ b/app/assets/javascripts/discourse/tests/unit/utils/decorators-test.js
@@ -1,5 +1,7 @@
import Component from "@ember/component";
-import { afterRender } from "discourse-common/utils/decorators";
+import discourseComputed, {
+ afterRender,
+} from "discourse-common/utils/decorators";
import componentTest, {
setupRenderingTest,
} from "discourse/tests/helpers/component-test";
@@ -29,7 +31,16 @@ const fooComponent = Component.extend({
},
});
-discourseModule("utils:decorators", function (hooks) {
+class NativeComponent extends Component {
+ name = "";
+
+ @discourseComputed("name")
+ text(name) {
+ return `hello, ${name}`;
+ }
+}
+
+discourseModule("Unit | Utils | decorators", function (hooks) {
setupRenderingTest(hooks);
componentTest("afterRender", {
@@ -50,4 +61,26 @@ discourseModule("utils:decorators", function (hooks) {
assert.strictEqual(this.baz, 1);
},
});
+
+ componentTest("discourseComputed works in native classes", {
+ template: hbs``,
+
+ beforeEach() {
+ Ember.TEMPLATES[
+ "components/native-component"
+ ] = hbs`{{this.text}}`;
+ this.registry.register("component:native-component", NativeComponent);
+ },
+
+ afterEach() {
+ delete Ember.TEMPLATES["components/native-component"];
+ },
+
+ test(assert) {
+ assert.strictEqual(
+ document.querySelector(".native-component").textContent,
+ "hello, Jarek"
+ );
+ },
+ });
});