diff --git a/ghost/admin/.template-lintrc.js b/ghost/admin/.template-lintrc.js
index 6fdd9bc177..d4646221a0 100644
--- a/ghost/admin/.template-lintrc.js
+++ b/ghost/admin/.template-lintrc.js
@@ -3,7 +3,7 @@ module.exports = {
rules: {
'no-forbidden-elements': ['meta', 'html', 'script'],
- 'no-implicit-this': {allow: ['noop', 'now', 'site-icon-style', 'accent-color-background']},
+ 'no-implicit-this': {allow: ['noop', 'now', 'site-icon-style']},
'no-inline-styles': false,
'no-duplicate-landmark-elements': false,
'no-pointer-down-event-binding': false,
diff --git a/ghost/admin/app/components/editor/modals/re-authenticate.hbs b/ghost/admin/app/components/editor/modals/re-authenticate.hbs
index 1da8ce1031..6024aca235 100644
--- a/ghost/admin/app/components/editor/modals/re-authenticate.hbs
+++ b/ghost/admin/app/components/editor/modals/re-authenticate.hbs
@@ -27,7 +27,7 @@
@showSuccess={{false}}
@task={{this.reauthenticateTask}}
@class="login gh-btn gh-btn-login gh-btn-block gh-btn-icon"
- style={{accent-color-background}}
+ @useAccentColor={{true}}
/>
{{#if this.authenticationError}}
diff --git a/ghost/admin/app/components/gh-task-button.js b/ghost/admin/app/components/gh-task-button.js
index 873c360366..a08ef711b9 100644
--- a/ghost/admin/app/components/gh-task-button.js
+++ b/ghost/admin/app/components/gh-task-button.js
@@ -1,6 +1,8 @@
import Component from '@ember/component';
import config from 'ghost-admin/config/environment';
import {action, computed} from '@ember/object';
+import {htmlSafe} from '@ember/template';
+import {inject} from 'ghost-admin/decorators/inject';
import {isBlank} from '@ember/utils';
import {reads} from '@ember/object/computed';
import {task, timeout} from 'ember-concurrency';
@@ -25,7 +27,7 @@ const GhTaskButton = Component.extend({
'isSuccessClass',
'isFailureClass'
],
- attributeBindings: ['disabled', 'form', 'type', 'tabindex', 'data-test-button'],
+ attributeBindings: ['disabled', 'form', 'type', 'tabindex', 'data-test-button', 'style'],
task: null,
taskArgs: undefined,
@@ -49,6 +51,8 @@ const GhTaskButton = Component.extend({
// Allowed actions
action: () => {},
+ config: inject(),
+
runningText: reads('buttonText'),
// hasRun is needed so that a newly rendered button does not show the last
@@ -113,6 +117,13 @@ const GhTaskButton = Component.extend({
return !this.isRunning && !this.isSuccess && !this.isFailure;
}),
+ style: computed('useAccentColor', 'isFailure', function () {
+ if (this.useAccentColor && !this.isFailure) {
+ return htmlSafe(`background-color: ${this.config.accent_color}`);
+ }
+ return null;
+ }),
+
init() {
this._super(...arguments);
this._initialPerformCount = this.get('task.performCount');
diff --git a/ghost/admin/app/helpers/accent-color-background.js b/ghost/admin/app/helpers/accent-color-background.js
deleted file mode 100644
index 3590ddf9ec..0000000000
--- a/ghost/admin/app/helpers/accent-color-background.js
+++ /dev/null
@@ -1,12 +0,0 @@
-import Helper from '@ember/component/helper';
-import {htmlSafe} from '@ember/template';
-import {inject} from 'ghost-admin/decorators/inject';
-
-export default class AccentColorBackgroundHelper extends Helper {
- @inject config;
-
- compute() {
- const color = this.config.accent_color;
- return htmlSafe(`background: ${color};`);
- }
-}
diff --git a/ghost/admin/app/templates/signin.hbs b/ghost/admin/app/templates/signin.hbs
index 2a3d5e2741..6e4b1f0371 100644
--- a/ghost/admin/app/templates/signin.hbs
+++ b/ghost/admin/app/templates/signin.hbs
@@ -69,7 +69,7 @@
@showSuccess={{false}}
@class="login gh-btn gh-btn-login gh-btn-block gh-btn-icon"
@type="submit"
- style={{accent-color-background}}
+ @useAccentColor={{true}}
data-test-button="sign-in" />
diff --git a/ghost/admin/app/templates/signup.hbs b/ghost/admin/app/templates/signup.hbs
index c6996c8922..7d7797bfac 100644
--- a/ghost/admin/app/templates/signup.hbs
+++ b/ghost/admin/app/templates/signup.hbs
@@ -75,10 +75,10 @@
@task={{this.signupTask}}
@defaultClick={{true}}
@showSuccess={{false}}
+ @useAccentColor={{true}}
type="submit"
form="signup"
class="gh-btn gh-btn-signup gh-btn-block gh-btn-icon"
- style={{accent-color-background}}
data-test-button="signup"
/>
diff --git a/ghost/admin/tests/integration/components/gh-task-button-test.js b/ghost/admin/tests/integration/components/gh-task-button-test.js
index b967e9006e..0687a4c0ef 100644
--- a/ghost/admin/tests/integration/components/gh-task-button-test.js
+++ b/ghost/admin/tests/integration/components/gh-task-button-test.js
@@ -3,13 +3,17 @@ import {click, find, render, settled, waitFor} from '@ember/test-helpers';
import {defineProperty} from '@ember/object';
import {describe, it} from 'mocha';
import {expect} from 'chai';
-import {run} from '@ember/runloop';
import {setupRenderingTest} from 'ember-mocha';
import {task, timeout} from 'ember-concurrency';
describe('Integration: Component: gh-task-button', function () {
setupRenderingTest();
+ beforeEach(function () {
+ const config = this.owner.lookup('config:main');
+ config.accent_color = '#123456';
+ });
+
it('renders', async function () {
// sets button text using positional param
await render(hbs``);
@@ -47,7 +51,6 @@ describe('Integration: Component: gh-task-button', function () {
this.myTask.perform();
await waitFor('button svg', {timeout: 50});
- await settled();
});
it('shows running text when passed whilst running', async function () {
@@ -61,8 +64,6 @@ describe('Integration: Component: gh-task-button', function () {
await waitFor('button svg', {timeout: 50});
expect(find('button')).to.contain.text('Running');
-
- await settled();
});
it('appears disabled whilst running', async function () {
@@ -83,7 +84,7 @@ describe('Integration: Component: gh-task-button', function () {
it('shows success on success', async function () {
defineProperty(this, 'myTask', task(function* () {
- yield timeout(50);
+ yield timeout(1);
return true;
}));
@@ -97,7 +98,7 @@ describe('Integration: Component: gh-task-button', function () {
it('assigns specified success class on success', async function () {
defineProperty(this, 'myTask', task(function* () {
- yield timeout(50);
+ yield timeout(1);
return true;
}));
@@ -113,7 +114,7 @@ describe('Integration: Component: gh-task-button', function () {
it('shows failure when task errors', async function () {
defineProperty(this, 'myTask', task(function* () {
try {
- yield timeout(50);
+ yield timeout(1);
throw new ReferenceError('test error');
} catch (error) {
// noop, prevent mocha triggering unhandled error assert
@@ -126,13 +127,11 @@ describe('Integration: Component: gh-task-button', function () {
await waitFor('button.is-failed');
expect(find('button')).to.contain.text('Retry');
-
- await settled();
});
it('shows failure on falsy response', async function () {
defineProperty(this, 'myTask', task(function* () {
- yield timeout(50);
+ yield timeout(1);
return false;
}));
@@ -142,13 +141,11 @@ describe('Integration: Component: gh-task-button', function () {
await waitFor('button.gh-btn-red', {timeout: 50});
expect(find('button')).to.contain.text('Retry');
-
- await settled();
});
it('shows idle on canceled response', async function () {
defineProperty(this, 'myTask', task(function* () {
- yield timeout(50);
+ yield timeout(1);
return 'canceled';
}));
@@ -156,13 +153,11 @@ describe('Integration: Component: gh-task-button', function () {
this.myTask.perform();
await waitFor('[data-test-task-button-state="idle"]', {timeout: 50});
-
- await settled();
});
it('assigns specified failure class on failure', async function () {
defineProperty(this, 'myTask', task(function* () {
- yield timeout(50);
+ yield timeout(1);
return false;
}));
@@ -174,15 +169,13 @@ describe('Integration: Component: gh-task-button', function () {
expect(find('button')).to.not.have.class('gh-btn-red');
expect(find('button')).to.contain.text('Retry');
-
- await settled();
});
it('performs task on click', async function () {
let taskCount = 0;
defineProperty(this, 'myTask', task(function* () {
- yield timeout(50);
+ yield timeout(1);
taskCount = taskCount + 1;
}));
@@ -192,33 +185,37 @@ describe('Integration: Component: gh-task-button', function () {
expect(taskCount, 'taskCount').to.equal(1);
});
- it.skip('keeps button size when showing spinner', async function () {
+ it('@useAccentColor=true adds style attr', async function () {
defineProperty(this, 'myTask', task(function* () {
- yield timeout(50);
+ yield timeout(1);
}));
- await render(hbs``);
- let width = find('button').clientWidth;
- let height = find('button').clientHeight;
- expect(find('button')).to.not.have.attr('style');
+ await render(hbs``);
- this.myTask.perform();
+ expect(find('button')).to.have.attr('style', 'background-color: #123456');
+ });
- run.later(this, function () {
- // we can't test exact width/height because Chrome/Firefox use different rounding methods
- // expect(find('button')).to.have.attr('style', `width: ${width}px; height: ${height}px;`);
+ it('@useAccentColor=true removes style attr when in failure state', async function () {
+ defineProperty(this, 'myTask', task(function* () {
+ yield timeout(1);
+ return false;
+ }));
- let [widthInt] = width.toString().split('.');
- let [heightInt] = height.toString().split('.');
+ await render(hbs``);
+ await click('button');
+ await waitFor('button.gh-btn-red', {timeout: 50});
- expect(find('button')).to.have.attr('style', `width: ${widthInt}`);
- expect(find('button')).to.have.attr('style', `height: ${heightInt}`);
- }, 20);
+ expect(find('button')).to.contain.text('Retry');
+ expect(find('button')).not.to.have.attr('style');
+ });
- run.later(this, function () {
- expect(find('button').getAttribute('style')).to.be.empty;
- }, 100);
+ it('@useAccentColor=false does not add style attr', async function () {
+ defineProperty(this, 'myTask', task(function* () {
+ yield timeout(1);
+ }));
- await settled();
+ await render(hbs``);
+
+ expect(find('button')).not.to.have.attr('style');
});
});