diff --git a/bower.json b/bower.json
index 13d1fbcb..0ffbc93b 100644
--- a/bower.json
+++ b/bower.json
@@ -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"
}
}
diff --git a/src/gui/html/index.html b/src/gui/html/index.html
index 57560ec4..0a1957ab 100644
--- a/src/gui/html/index.html
+++ b/src/gui/html/index.html
@@ -448,6 +448,7 @@
+
diff --git a/src/gui/html/js/init.js b/src/gui/html/js/init.js
index 4f72d5a7..9f192a01 100644
--- a/src/gui/html/js/init.js
+++ b/src/gui/html/js/init.js
@@ -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);
diff --git a/src/gui/html/js/plugin.js b/src/gui/html/js/plugin.js
index 5a37d8c2..78fb2ec5 100644
--- a/src/gui/html/js/plugin.js
+++ b/src/gui/html/js/plugin.js
@@ -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();
+ }
+ }
};
}));
diff --git a/src/tests/gui/html/js/test.html b/src/tests/gui/html/js/test.html
index 44de2886..11efd275 100644
--- a/src/tests/gui/html/js/test.html
+++ b/src/tests/gui/html/js/test.html
@@ -9,6 +9,7 @@
+
diff --git a/src/tests/gui/html/js/test_plugin.js b/src/tests/gui/html/js/test_plugin.js
index 928d391e..76093c92 100644
--- a/src/tests/gui/html/js/test_plugin.js
+++ b/src/tests/gui/html/js/test_plugin.js
@@ -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(() => {