From 627ef54efea9235791cc02524aef1ae494555d84 Mon Sep 17 00:00:00 2001 From: Robin Ward Date: Fri, 26 Feb 2016 14:26:29 -0500 Subject: [PATCH] New PluginAPI for widget settings --- .../discourse/lib/plugin-api.js.es6 | 14 ++++- .../javascripts/discourse/widgets/post.js.es6 | 6 +- .../discourse/widgets/widget.js.es6 | 13 ++++ test/javascripts/widgets/widget-test.js.es6 | 63 +++++++++++++++++-- 4 files changed, 88 insertions(+), 8 deletions(-) diff --git a/app/assets/javascripts/discourse/lib/plugin-api.js.es6 b/app/assets/javascripts/discourse/lib/plugin-api.js.es6 index 1e74ae397..10c8f4a99 100644 --- a/app/assets/javascripts/discourse/lib/plugin-api.js.es6 +++ b/app/assets/javascripts/discourse/lib/plugin-api.js.es6 @@ -5,7 +5,7 @@ import { addButton } from 'discourse/widgets/post-menu'; import { includeAttributes } from 'discourse/lib/transform-post'; import { addToolbarCallback } from 'discourse/components/d-editor'; import { addWidgetCleanCallback } from 'discourse/components/mount-widget'; -import { decorateWidget } from 'discourse/widgets/widget'; +import { decorateWidget, changeSetting } from 'discourse/widgets/widget'; import { onPageChange } from 'discourse/lib/page-tracker'; class PluginApi { @@ -241,6 +241,18 @@ class PluginApi { onPageChange(fn); } + /** + * Changes a setting associated with a widget. For example, if + * you wanted small avatars in the post stream: + * + * ```javascript + * api.changeWidgetSetting('post-avatar', 'size', 'small'); + * ``` + * + **/ + changeWidgetSetting(widgetName, settingName, newValue) { + changeSetting(widgetName, settingName, newValue); + } } let _pluginv01; diff --git a/app/assets/javascripts/discourse/widgets/post.js.es6 b/app/assets/javascripts/discourse/widgets/post.js.es6 index 8da490a50..cc3e67a92 100644 --- a/app/assets/javascripts/discourse/widgets/post.js.es6 +++ b/app/assets/javascripts/discourse/widgets/post.js.es6 @@ -77,12 +77,16 @@ createWidget('reply-to-tab', { createWidget('post-avatar', { tagName: 'div.topic-avatar', + settings: { + size: 'large' + }, + html(attrs) { let body; if (!attrs.user_id) { body = h('i', { className: 'fa fa-trash-o deleted-user-avatar' }); } else { - body = avatarFor.call(this, 'large', { + body = avatarFor.call(this, this.settings.size, { template: attrs.avatar_template, username: attrs.username, url: attrs.usernameUrl, diff --git a/app/assets/javascripts/discourse/widgets/widget.js.es6 b/app/assets/javascripts/discourse/widgets/widget.js.es6 index ec470c0fe..47f56cdfe 100644 --- a/app/assets/javascripts/discourse/widgets/widget.js.es6 +++ b/app/assets/javascripts/discourse/widgets/widget.js.es6 @@ -37,6 +37,12 @@ export function applyDecorators(widget, type, attrs, state) { return []; } +const _customSettings = {}; +export function changeSetting(widgetName, settingName, newValue) { + _customSettings[widgetName] = _customSettings[widgetName] || {}; + _customSettings[widgetName][settingName] = newValue; +} + function drawWidget(builder, attrs, state) { const properties = {}; @@ -113,6 +119,13 @@ export default class Widget { this.currentUser = container.lookup('current-user:main'); this.store = container.lookup('store:main'); this.appEvents = container.lookup('app-events:main'); + + if (this.name) { + const custom = _customSettings[this.name]; + if (custom) { + Object.keys(custom).forEach(k => this.settings[k] = custom[k]); + } + } } defaultState() { diff --git a/test/javascripts/widgets/widget-test.js.es6 b/test/javascripts/widgets/widget-test.js.es6 index 64ed5b7d4..5680516f6 100644 --- a/test/javascripts/widgets/widget-test.js.es6 +++ b/test/javascripts/widgets/widget-test.js.es6 @@ -1,5 +1,6 @@ import { moduleForWidget, widgetTest } from 'helpers/widget-test'; -import { decorateWidget, createWidget } from 'discourse/widgets/widget'; +import { createWidget } from 'discourse/widgets/widget'; +import { withPluginApi } from 'discourse/lib/plugin-api'; moduleForWidget('base'); @@ -177,12 +178,14 @@ widgetTest('widget decorating', { }, }); - decorateWidget('decorate-test:before', dec => { - return dec.h('b', 'before'); - }); + withPluginApi('0.1', api => { + api.decorateWidget('decorate-test:before', dec => { + return dec.h('b', 'before'); + }); - decorateWidget('decorate-test:after', dec => { - return dec.h('i', 'after'); + api.decorateWidget('decorate-test:after', dec => { + return dec.h('i', 'after'); + }); }); }, @@ -192,3 +195,51 @@ widgetTest('widget decorating', { assert.equal(this.$('.decorate i').text(), 'after'); } }); + +widgetTest('widget settings', { + template: `{{mount-widget widget="settings-test"}}`, + + setup() { + createWidget('settings-test', { + tagName: 'div.settings', + + settings: { + age: 36 + }, + + html() { + return `age is ${this.settings.age}`; + }, + }); + }, + + test(assert) { + assert.equal(this.$('.settings').text(), 'age is 36'); + } +}); + +widgetTest('override settings', { + template: `{{mount-widget widget="ov-settings-test"}}`, + + setup() { + createWidget('ov-settings-test', { + tagName: 'div.settings', + + settings: { + age: 36 + }, + + html() { + return `age is ${this.settings.age}`; + }, + }); + + withPluginApi('0.1', api => { + api.changeWidgetSetting('ov-settings-test', 'age', 37); + }); + }, + + test(assert) { + assert.equal(this.$('.settings').text(), 'age is 37'); + } +});