Update a plugin's card when its content changes

Add new events fired when changing the CRC or tags, and update the card
content if they or the plugin's messages change. Use Lodash's isEquals()
to test for deep object equality.
This commit is contained in:
Oliver Hamlet
2016-03-05 11:49:26 +00:00
parent c13cd8b859
commit 632cf1b30a
6 changed files with 188 additions and 19 deletions
+2 -1
View File
@@ -31,6 +31,7 @@
"paper-tooltip": "PolymerElements/paper-tooltip#^1.0.0",
"Jed": "SlexAxton/Jed#a9d03e1bbca9211a8b29a93a298a7ee9ddb353f0",
"jed-gettext-parser": "^1.0.0",
"marked": "^0.3.2"
"marked": "^0.3.2",
"lodash": "^4.3.0"
}
}
+1
View File
@@ -448,6 +448,7 @@
<script src="../../../bower_components/marked/lib/marked.js"></script>
<script src="../../../bower_components/Jed/jed.js"></script>
<script src="../../../bower_components/jed-gettext-parser/jedGettextParser.js"></script>
<script src="../../../bower_components/lodash/dist/lodash.core.min.js"></script>
<script src="js/dialog.js"></script>
<script src="js/dom.js"></script>
<script src="js/events.js"></script>
+3 -1
View File
@@ -94,9 +94,11 @@
document.getElementById('cardsNav').addEventListener('click', onSidebarClick);
document.getElementById('cardsNav').addEventListener('dblclick', onSidebarClick);
/* Set up handler for plugin message and dirty info changes. */
/* Set up handler for plugin data changes. */
document.addEventListener('loot-plugin-message-change', Plugin.onMessageChange);
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);
/* Set up event handlers for game member variable changes. */
document.addEventListener('loot-game-folder-change', Game.onFolderChange);
+51 -9
View File
@@ -25,13 +25,13 @@
(function exportModule(root, factory) {
if (typeof define === 'function' && define.amd) {
// AMD. Register as an anonymous module.
define([], factory);
define(['bower_components/lodash/dist/lodash.core.min'], factory);
} else {
// Browser globals
root.loot = root.loot || {};
root.loot.Plugin = factory();
root.loot.Plugin = factory(root._);
}
}(this, () => {
}(this, (_) => {
/* Messages, tags, CRCs and version strings can all be hidden by filters.
Use getters with no setters for member variables as data should not be
written to objects of this class. */
@@ -168,7 +168,7 @@
constructor(obj) {
/* Plugin data */
this.name = obj.name;
this.crc = obj.crc || 0;
this._crc = obj.crc || 0;
this.version = obj.version || '';
this.isActive = obj.isActive || false;
this.isEmpty = obj.isEmpty || false;
@@ -181,7 +181,7 @@
this.priority = obj.priority || 0;
this.isPriorityGlobal = obj.isPriorityGlobal || false;
this._messages = obj.messages || [];
this.tags = obj.tags;
this._tags = obj.tags;
this._isDirty = obj.isDirty || false;
/* UI state variables */
@@ -240,6 +240,12 @@
return this.priority.toString();
}
_dispatchCardContentChangeEvent() {
document.dispatchEvent(new CustomEvent('loot-plugin-card-content-change', {
detail: { pluginId: this.id },
}));
}
get messages() {
return this._messages;
}
@@ -273,17 +279,21 @@
}
});
if (newTotal !== oldTotal || newWarns !== oldWarns || newErrs !== oldErrs) {
if (newTotal !== oldTotal
|| newWarns !== oldWarns
|| newErrs !== oldErrs
|| !_.isEqual(this._messages, messages)) {
this._messages = messages;
document.dispatchEvent(new CustomEvent('loot-plugin-message-change', {
detail: {
pluginId: this.id,
totalDiff: newTotal - oldTotal,
warningDiff: newWarns - oldWarns,
errorDiff: newErrs - oldErrs,
},
}));
}
this._messages = messages;
}
get isDirty() {
@@ -293,14 +303,38 @@
set isDirty(dirty) {
/* Update dirty counts. */
if (dirty !== this._isDirty) {
this._isDirty = dirty;
document.dispatchEvent(new CustomEvent('loot-plugin-isdirty-change', {
detail: {
isDirty: dirty,
},
}));
}
}
this._isDirty = dirty;
get crc() {
return this._crc;
}
set crc(crc) {
if (this._crc !== crc) {
this._crc = crc;
this._dispatchCardContentChangeEvent();
}
}
get tags() {
return this._tags;
}
set tags(tags) {
if (!_.isEqual(this._tags, tags)) {
this._tags = tags;
this._dispatchCardContentChangeEvent();
}
}
get hasUserEdits() {
@@ -317,6 +351,7 @@
document.getElementById('totalWarningNo').textContent = parseInt(document.getElementById('totalWarningNo').textContent, 10) + evt.detail.warningDiff;
document.getElementById('totalErrorNo').textContent = parseInt(document.getElementById('totalErrorNo').textContent, 10) + evt.detail.errorDiff;
}
static onIsDirtyChange(evt) {
if (evt.detail.isDirty) {
document.getElementById('dirtyPluginNo').textContent = parseInt(document.getElementById('dirtyPluginNo').textContent, 10) + 1;
@@ -324,5 +359,12 @@
document.getElementById('dirtyPluginNo').textContent = parseInt(document.getElementById('dirtyPluginNo').textContent, 10) - 1;
}
}
static onContentChange(evt) {
const card = document.getElementById(evt.detail.pluginId);
if (card) {
card.updateContent();
}
}
};
}));
+1
View File
@@ -9,6 +9,7 @@
<script src="../../../../../bower_components/Jed/jed.js"></script>
<script src="../../../../../bower_components/jed-gettext-parser/jedGettextParser.js"></script>
<script src="../../../../../bower_components/lodash/dist/lodash.core.min.js"></script>
<script>mocha.setup('bdd')</script>
<script src="../../../../gui/html/js/filters.js"></script>
+130 -8
View File
@@ -357,7 +357,7 @@ describe('Plugin', () => {
}];
const plugin = new loot.Plugin({
name: 'test',
messages: messages,
messages,
});
plugin.messages.should.be.deepEqual(messages);
@@ -378,7 +378,7 @@ describe('Plugin', () => {
plugin.messages.should.be.deepEqual(messages);
});
it('setting messages should not fire an event if no message counts were changed', (done) => {
it('setting messages should not fire an event if no messages were changed', (done) => {
const plugin = new loot.Plugin({
name: 'test',
messages: [{
@@ -386,10 +386,6 @@ describe('Plugin', () => {
content: 'test message',
}],
});
const messages = [{
type: 'say',
content: 'another test message',
}];
handleEvent = () => {
done(new Error('Should not have fired an event'));
@@ -397,12 +393,12 @@ describe('Plugin', () => {
document.addEventListener('loot-plugin-message-change', handleEvent);
plugin.messages = messages;
plugin.messages = plugin.messages;
setTimeout(done, 100);
});
it('setting messages should fire an event if message counts were changed', (done) => {
it('setting messages should fire an event if the messages were changed', (done) => {
const plugin = new loot.Plugin({
name: 'test',
messages: [],
@@ -413,6 +409,7 @@ describe('Plugin', () => {
}];
handleEvent = (evt) => {
evt.detail.pluginId.should.equal(plugin.id);
evt.detail.totalDiff.should.equal(1);
evt.detail.warningDiff.should.equal(0);
evt.detail.errorDiff.should.equal(1);
@@ -483,6 +480,131 @@ describe('Plugin', () => {
});
});
describe('#crc', () => {
let handleEvent;
afterEach(() => {
document.removeEventListener('loot-plugin-card-content-change', handleEvent);
});
it('getting value should return 0 if crc has not been set in the constructor', () => {
const plugin = new loot.Plugin({ name: 'test' });
plugin.isDirty.should.be.false();
});
it('getting value should return 0xDEADBEEF if it was set in the constructor', () => {
const plugin = new loot.Plugin({
name: 'test',
crc: 0xDEADBEEF,
});
plugin.crc.should.equal(0xDEADBEEF);
});
it('setting value should store set value', () => {
const plugin = new loot.Plugin({ name: 'test' });
plugin.crc = 0xDEADBEEF;
plugin.crc.should.equal(0xDEADBEEF);
});
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-card-content-change', handleEvent);
plugin.crc = plugin.crc;
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);
done();
};
document.addEventListener('loot-plugin-card-content-change', handleEvent);
plugin.crc = 0xDEADBEEF;
});
});
describe('#tags', () => {
let handleEvent;
afterEach(() => {
document.removeEventListener('loot-plugin-card-content-change', handleEvent);
});
it('getting value should return an empty array if tags have not been set in the constructor', () => {
const plugin = new loot.Plugin({ name: 'test' });
plugin.tags.length.should.equal(0);
});
it('getting value should return any tags that are set', () => {
const tags = [{
name: 'Delev',
}];
const plugin = new loot.Plugin({
name: 'test',
tags,
});
plugin.tags.should.deepEqual(tags);
});
it('setting value should store set value', () => {
const plugin = new loot.Plugin({ name: 'test' });
const tags = [{
name: 'Delev',
}];
plugin.tags = tags;
plugin.tags.should.deepEqual(tags);
});
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-card-content-change', handleEvent);
plugin.tags = plugin.tags;
setTimeout(done, 100);
});
it('setting value not equal to the current value should fire an event', (done) => {
const plugin = new loot.Plugin({ name: 'test' });
const tags = [{
name: 'Delev',
}];
handleEvent = (evt) => {
evt.detail.pluginId.should.equal(plugin.id);
done();
};
document.addEventListener('loot-plugin-card-content-change', handleEvent);
plugin.tags = tags;
});
});
describe('#getCardContent()', () => {
let plugin;
beforeEach(() => {