From 03bd1150af7f46b0f6ec1d2431deebb0bed0af73 Mon Sep 17 00:00:00 2001 From: Oliver Hamlet Date: Wed, 10 Feb 2016 20:50:24 +0000 Subject: [PATCH] Fix plugin item content not updating Fire an event whenever a Plugin object's relevant members are set, and handle the event to update the plugin item content if an item for the Plugin exists. --- src/gui/html/js/init.js | 1 + src/gui/html/js/plugin.js | 92 ++++++++++- src/tests/gui/html/js/test_plugin.js | 239 +++++++++++++++++++++++++++ 3 files changed, 327 insertions(+), 5 deletions(-) diff --git a/src/gui/html/js/init.js b/src/gui/html/js/init.js index 9f192a01..72a3eab1 100644 --- a/src/gui/html/js/init.js +++ b/src/gui/html/js/init.js @@ -99,6 +99,7 @@ document.addEventListener('loot-plugin-message-change', Plugin.onContentChange); document.addEventListener('loot-plugin-isdirty-change', Plugin.onIsDirtyChange); document.addEventListener('loot-plugin-card-content-change', Plugin.onContentChange); + document.addEventListener('loot-plugin-item-content-change', Plugin.onItemContentChange); /* Set up event handlers for game member variable changes. */ document.addEventListener('loot-game-folder-change', Game.onFolderChange); diff --git a/src/gui/html/js/plugin.js b/src/gui/html/js/plugin.js index 6d3102af..ed72bcd8 100644 --- a/src/gui/html/js/plugin.js +++ b/src/gui/html/js/plugin.js @@ -176,10 +176,10 @@ this.loadsArchive = obj.loadsArchive || false; this.masterlist = obj.masterlist; - this.userlist = obj.userlist; + this._userlist = obj.userlist; - this.priority = obj.priority || 0; - this.isPriorityGlobal = obj.isPriorityGlobal || false; + this._priority = obj.priority || 0; + this._isPriorityGlobal = obj.isPriorityGlobal || false; this._messages = obj.messages || []; this._tags = obj.tags || []; this._isDirty = obj.isDirty || false; @@ -187,7 +187,7 @@ /* UI state variables */ this.id = this.name.replace(/\s+/g, ''); this.isMenuOpen = false; - this.isEditorOpen = false; + this._isEditorOpen = false; this.isConflictFilterChecked = false; this.isSearchResult = false; } @@ -238,6 +238,18 @@ })); } + _dispatchItemContentChangeEvent() { + document.dispatchEvent(new CustomEvent('loot-plugin-item-content-change', { + detail: { + pluginId: this.id, + priority: this.priority, + isPriorityGlobal: this.isPriorityGlobal, + isEditorOpen: this.isEditorOpen, + hasUserEdits: this.hasUserEdits, + }, + })); + } + get messages() { return this._messages; } @@ -330,7 +342,55 @@ } get hasUserEdits() { - return this.userlist && Object.keys(this.userlist).length > 1; + return this.userlist !== undefined && Object.keys(this.userlist).length > 1; + } + + get userlist() { + return this._userlist; + } + + set userlist(userlist) { + if (!_.isEqual(this._userlist, userlist)) { + this._userlist = userlist; + + this._dispatchItemContentChangeEvent(); + } + } + + get priority() { + return this._priority; + } + + set priority(priority) { + if (this._priority !== priority) { + this._priority = priority; + + this._dispatchItemContentChangeEvent(); + } + } + + get isPriorityGlobal() { + return this._isPriorityGlobal; + } + + set isPriorityGlobal(isPriorityGlobal) { + if (this._isPriorityGlobal !== isPriorityGlobal) { + this._isPriorityGlobal = isPriorityGlobal; + + this._dispatchItemContentChangeEvent(); + } + } + + get isEditorOpen() { + return this._isEditorOpen; + } + + set isEditorOpen(isEditorOpen) { + if (this._isEditorOpen !== isEditorOpen) { + this._isEditorOpen = isEditorOpen; + + this._dispatchItemContentChangeEvent(); + } } getCardContent(filters) { @@ -358,5 +418,27 @@ card.updateContent(); } } + + static onItemContentChange(evt) { + const item = document.getElementById('cardsNav').querySelector(`[data-id="${evt.detail.pluginId}"]`); + if (item) { + item.setAttribute('priority', evt.detail.priority); + if (evt.detail.isPriorityGlobal) { + item.setAttribute('is-priority-global', ''); + } else { + item.removeAttribute('is-priority-global'); + } + if (evt.detail.isEditorOpen) { + item.setAttribute('is-editor-open', ''); + } else { + item.removeAttribute('is-editor-open'); + } + if (evt.detail.hasUserEdits) { + item.setAttribute('has-user-edits', ''); + } else { + item.removeAttribute('has-user-edits'); + } + } + } }; })); diff --git a/src/tests/gui/html/js/test_plugin.js b/src/tests/gui/html/js/test_plugin.js index 6c46a6c7..ddbbcdce 100644 --- a/src/tests/gui/html/js/test_plugin.js +++ b/src/tests/gui/html/js/test_plugin.js @@ -646,6 +646,245 @@ describe('Plugin', () => { }); }); + describe('#userlist', () => { + let handleEvent; + + afterEach(() => { + document.removeEventListener('loot-plugin-item-content-change', handleEvent); + }); + + it('getting value should return undefined if it has not been set in the constructor', () => { + const plugin = new loot.Plugin({ name: 'test' }); + + should(plugin.userlist).be.undefined(); + }); + + it('getting value should return the value that was set', () => { + const plugin = new loot.Plugin({ + name: 'test', + userlist: {}, + }); + + plugin.userlist.should.deepEqual({}); + }); + + it('setting value should store set value', () => { + const plugin = new loot.Plugin({ name: 'test' }); + + plugin.userlist = {}; + + plugin.userlist.should.deepEqual({}); + }); + + it('setting value to the current value should not fire an event', (done) => { + const plugin = new loot.Plugin({ name: 'test' }); + + handleEvent = () => { + done(new Error('Should not have fired an event')); + }; + + document.addEventListener('loot-plugin-item-content-change', handleEvent); + + plugin.userlist = plugin.userlist; + + setTimeout(done, 100); + }); + + it('setting value not equal to the current value should fire an event', (done) => { + const plugin = new loot.Plugin({ name: 'test' }); + + handleEvent = (evt) => { + evt.detail.pluginId.should.equal(plugin.id); + evt.detail.priority.should.equal(plugin.priority); + evt.detail.isPriorityGlobal.should.equal(plugin.isPriorityGlobal); + evt.detail.isEditorOpen.should.equal(plugin.isEditorOpen); + evt.detail.hasUserEdits.should.equal(plugin.hasUserEdits); + done(); + }; + + document.addEventListener('loot-plugin-item-content-change', handleEvent); + + plugin.userlist = { priority: 1 }; + }); + }); + + describe('#priority', () => { + let handleEvent; + + afterEach(() => { + document.removeEventListener('loot-plugin-item-content-change', handleEvent); + }); + + it('getting value should return 0 if it has not been set in the constructor', () => { + const plugin = new loot.Plugin({ name: 'test' }); + + plugin.priority.should.equal(0); + }); + + it('getting value should return the value that was set', () => { + const plugin = new loot.Plugin({ + name: 'test', + priority: 5, + }); + + plugin.priority.should.equal(5); + }); + + it('setting value should store set value', () => { + const plugin = new loot.Plugin({ name: 'test' }); + + plugin.priority = 5; + + plugin.priority.should.equal(5); + }); + + it('setting value to the current value should not fire an event', (done) => { + const plugin = new loot.Plugin({ name: 'test' }); + + handleEvent = () => { + done(new Error('Should not have fired an event')); + }; + + document.addEventListener('loot-plugin-item-content-change', handleEvent); + + plugin.priority = plugin.priority; + + setTimeout(done, 100); + }); + + it('setting value not equal to the current value should fire an event', (done) => { + const plugin = new loot.Plugin({ name: 'test' }); + + handleEvent = (evt) => { + evt.detail.pluginId.should.equal(plugin.id); + evt.detail.priority.should.equal(plugin.priority); + evt.detail.isPriorityGlobal.should.equal(plugin.isPriorityGlobal); + evt.detail.isEditorOpen.should.equal(plugin.isEditorOpen); + evt.detail.hasUserEdits.should.equal(plugin.hasUserEdits); + done(); + }; + + document.addEventListener('loot-plugin-item-content-change', handleEvent); + + plugin.priority = 5; + }); + }); + + describe('#isPriorityGlobal', () => { + let handleEvent; + + afterEach(() => { + document.removeEventListener('loot-plugin-item-content-change', handleEvent); + }); + + it('getting value should return false if it has not been set in the constructor', () => { + const plugin = new loot.Plugin({ name: 'test' }); + + plugin.isPriorityGlobal.should.be.false(); + }); + + it('getting value should return the value that was set', () => { + const plugin = new loot.Plugin({ + name: 'test', + isPriorityGlobal: true, + }); + + plugin.isPriorityGlobal.should.be.true(); + }); + + it('setting value should store set value', () => { + const plugin = new loot.Plugin({ name: 'test' }); + + plugin.isPriorityGlobal = true; + + plugin.isPriorityGlobal.should.be.true(); + }); + + it('setting value to the current value should not fire an event', (done) => { + const plugin = new loot.Plugin({ name: 'test' }); + + handleEvent = () => { + done(new Error('Should not have fired an event')); + }; + + document.addEventListener('loot-plugin-item-content-change', handleEvent); + + plugin.isPriorityGlobal = plugin.isPriorityGlobal; + + setTimeout(done, 100); + }); + + it('setting value not equal to the current value should fire an event', (done) => { + const plugin = new loot.Plugin({ name: 'test' }); + + handleEvent = (evt) => { + evt.detail.pluginId.should.equal(plugin.id); + evt.detail.priority.should.equal(plugin.priority); + evt.detail.isPriorityGlobal.should.equal(plugin.isPriorityGlobal); + evt.detail.isEditorOpen.should.equal(plugin.isEditorOpen); + evt.detail.hasUserEdits.should.equal(plugin.hasUserEdits); + done(); + }; + + document.addEventListener('loot-plugin-item-content-change', handleEvent); + + plugin.isPriorityGlobal = true; + }); + }); + + describe('#isEditorOpen', () => { + let handleEvent; + + afterEach(() => { + document.removeEventListener('loot-plugin-item-content-change', handleEvent); + }); + + it('getting value should return false if it has not been set in the constructor', () => { + const plugin = new loot.Plugin({ name: 'test' }); + + plugin.isEditorOpen.should.be.false(); + }); + + it('setting value should store set value', () => { + const plugin = new loot.Plugin({ name: 'test' }); + + plugin.isEditorOpen = true; + + plugin.isEditorOpen.should.be.true(); + }); + + it('setting value to the current value should not fire an event', (done) => { + const plugin = new loot.Plugin({ name: 'test' }); + + handleEvent = () => { + done(new Error('Should not have fired an event')); + }; + + document.addEventListener('loot-plugin-item-content-change', handleEvent); + + plugin.isEditorOpen = plugin.isEditorOpen; + + setTimeout(done, 100); + }); + + it('setting value not equal to the current value should fire an event', (done) => { + const plugin = new loot.Plugin({ name: 'test' }); + + handleEvent = (evt) => { + evt.detail.pluginId.should.equal(plugin.id); + evt.detail.priority.should.equal(plugin.priority); + evt.detail.isPriorityGlobal.should.equal(plugin.isPriorityGlobal); + evt.detail.isEditorOpen.should.equal(plugin.isEditorOpen); + evt.detail.hasUserEdits.should.equal(plugin.hasUserEdits); + done(); + }; + + document.addEventListener('loot-plugin-item-content-change', handleEvent); + + plugin.isEditorOpen = true; + }); + }); + describe('#getCardContent()', () => { let plugin; beforeEach(() => {