Split loot JS global code into new file.

This commit is contained in:
Oliver Hamlet
2015-01-15 10:45:47 +00:00
parent 9bed71edb4
commit b2278aba86
2 changed files with 315 additions and 313 deletions
+309
View File
@@ -0,0 +1,309 @@
var loot = {
installedGames: [],
settings: {},
game: {
folder: '',
globalMessages: [],
masterlist: {},
plugins: [],
/* Call whenever game is changed or game menu / game table are rewritten. */
updateSelectedGame: function() {
document.getElementById('gameMenu').value = this.folder;
/* Also disable deletion of the game's row in the settings dialog. */
var table = document.getElementById('gameTable');
for (var i = 0; i < table.tBodies[0].rows.length; ++i) {
if (table.tBodies[0].rows[i].getElementsByClassName('folder').length > 0) {
if (table.tBodies[0].rows[i].getElementsByClassName('folder')[0].value == this.folder) {
table.setReadOnly(table.tBodies[0].rows[i], ['delete']);
} else {
table.setReadOnly(table.tBodies[0].rows[i], ['delete'], false);
}
}
}
},
/* Call whenever game is changed. */
updateRedatePluginsButtonState: function() {
/* Also enable/disable the redate plugins option. */
var index = undefined;
for (var i = 0; i < loot.settings.games.length; ++i) {
if (loot.settings.games[i].folder == this.folder) {
index = i;
break;
}
}
var redateButton = document.getElementById('redatePluginsButton');
if (index != undefined && loot.settings.games[index].type == 'Skyrim') {
redateButton.removeAttribute('disabled');
} else {
redateButton.setAttribute('disabled', true);
}
},
pluginsObserver: function(changes) {
changes.forEach(function(change){
/* Need to handle plugin addition and removal.
Update plugin and message counts. */
var totalChange = 0;
var warnChange = 0;
var errorChange = 0;
var activeChange = 0;
var dirtyChange = 0;
if (change.addedCount > 0) {
/* Addition */
for (var i = change.index; i < change.index + change.addedCount; ++i) {
if (change.object[i].isActive) {
++activeChange;
}
if (change.object[i].isDirty) {
++dirtyChange;
}
if (change.object[i].messages) {
totalChange += change.object[i].messages.length;
change.object[i].messages.forEach(function(message) {
if (message.type == 'warn') {
++warnChange;
} else if (message.type == 'error') {
++errorChange;
}
});
}
}
}
if (change.removed.length > 0) {
/* Removal */
change.removed.forEach(function(plugin){
if (plugin.isActive) {
--activeChange;
}
if (plugin.isDirty) {
--dirtyChange;
}
if (plugin.messages) {
totalChange -= plugin.messages.length;
plugin.messages.forEach(function(message) {
if (message.type == 'warn') {
--warnChange;
} else if (message.type == 'error') {
--errorChange;
}
});
}
});
}
document.getElementById('filterTotalMessageNo').textContent = parseInt(document.getElementById('filterTotalMessageNo').textContent, 10) + totalChange;
document.getElementById('totalMessageNo').textContent = document.getElementById('filterTotalMessageNo').textContent;
document.getElementById('totalWarningNo').textContent = parseInt(document.getElementById('totalWarningNo').textContent, 10) + warnReduction;
document.getElementById('totalErrorNo').textContent = parseInt(document.getElementById('totalErrorNo').textContent, 10) + errorReduction;
document.getElementById('filterTotalPluginNo').textContent = parseInt(document.getElementById('filterTotalPluginNo').textContent, 10) + change.addedCount - change.removed.length;
document.getElementById('totalPluginNo').textContent = document.getElementById('filterTotalPluginNo').textContent;
document.getElementById('activePluginNo').textContent = parseInt(document.getElementById('activePluginNo').textContent, 10) + activeReduction;
document.getElementById('dirtyPluginNo').textContent = parseInt(document.getElementById('dirtyPluginNo').textContent, 10) + dirtyReduction;
});
}
},
/* Call whenever installedGames is changed or game menu is rewritten. */
updateEnabledGames: function() {
/* Update the disabled games in the game menu. */
var gameMenuItems = document.getElementById('gameMenu').children;
for (var i = 0; i < gameMenuItems.length; ++i) {
if (this.installedGames.indexOf(gameMenuItems[i].getAttribute('value')) == -1) {
gameMenuItems[i].setAttribute('disabled', true);
gameMenuItems[i].removeEventListener('click', changeGame, false);
} else {
gameMenuItems[i].removeAttribute('disabled');
gameMenuItems[i].addEventListener('click', changeGame, false);
}
}
},
/* Call whenever settings are changed. */
updateSettingsUI: function() {
var gameSelect = document.getElementById('defaultGameSelect');
var gameMenu = document.getElementById('gameMenu');
var gameTable = document.getElementById('gameTable');
/* First make sure game listing elements don't have any existing entries. */
while (gameSelect.children.length > 1) {
gameSelect.removeChild(gameSelect.lastElementChild);
}
while (gameMenu.firstElementChild) {
gameMenu.firstElementChild.removeEventListener('click', changeGame, false);
gameMenu.removeChild(gameMenu.firstElementChild);
}
gameTable.clear();
/* Now fill with new values. */
this.settings.games.forEach(function(game){
var menuItem = document.createElement('paper-item');
menuItem.setAttribute('value', game.folder);
menuItem.setAttribute('noink', '');
menuItem.textContent = game.name;
gameMenu.appendChild(menuItem);
gameSelect.appendChild(menuItem.cloneNode(true));
var row = gameTable.addRow(game);
gameTable.setReadOnly(row, ['name','folder','type']);
});
gameSelect.value = this.settings.game;
document.getElementById('languageSelect').value = this.settings.language;
document.getElementById('enableDebugLogging').checked = this.settings.enableDebugLogging;
document.getElementById('updateMasterlist').checked = this.settings.updateMasterlist;
this.updateEnabledGames();
this.game.updateSelectedGame();
},
/* Observer for loot members. */
observer: function(changes) {
changes.forEach(function(change){
if (change.name == 'installedGames') {
change.object.updateEnabledGames();
} else if (change.name == 'settings') {
change.object.updateSettingsUI();
}
});
},
/* Observer for loot.game members. */
gameObserver: function(changes) {
changes.forEach(function(change){
if (change.name == 'folder') {
change.object.updateSelectedGame();
change.object.updateRedatePluginsButtonState();
} else if (change.name == 'masterlist') {
if (change.object[change.name] && change.object[change.name].revision) {
document.getElementById('masterlistRevision').textContent = change.object[change.name].revision;
} else {
document.getElementById('masterlistRevision').textContent = l10n.jed.translate("N/A").fetch();
}
if (change.object[change.name] && change.object[change.name].date) {
document.getElementById('masterlistDate').textContent = change.object[change.name].date;
} else {
document.getElementById('masterlistDate').textContent = l10n.jed.translate("N/A").fetch();
}
} else if (change.name == 'globalMessages') {
/* For the messages, they don't have a JS 'class' so need to everything
here. Count up the global message types that exist, then remove them
and add the new ones, counting their types, then update the message
counts. I tried using an observer for this, but it wouldn't fire for
some reason. */
var oldTotal = change.oldValue.length;
var newTotal = 0;
var oldWarn = 0;
var newWarn = 0;
var oldErr = 0;
var newErr = 0;
/* Count up old warnings and errors. */
change.oldValue.forEach(function(message){
if (message.type == 'warn') {
++oldWarn;
} else if (message.type == 'error') {
++oldErr;
}
});
/* Remove old messages from UI. */
var generalMessagesList = document.getElementById('summary').getElementsByTagName('ul')[0];
while (generalMessagesList.firstElementChild) {
generalMessagesList.removeChild(generalMessagesList.firstElementChild);
}
/* Add new messages. */
if (change.object[change.name]) {
newTotal = change.object[change.name].length;
change.object[change.name].forEach(function(message){
var li = document.createElement('li');
li.className = message.type;
/* Use the Marked library for Markdown formatting support. */
li.innerHTML = marked(message.content[0].str);
generalMessagesList.appendChild(li);
if (li.className == 'warn') {
++newWarn;
} else if (li.className == 'error') {
++newErr;
}
});
}
/* Update message counts in UI. */
document.getElementById('filterTotalMessageNo').textContent = parseInt(document.getElementById('filterTotalMessageNo').textContent, 10) + newTotal - oldTotal;
document.getElementById('totalMessageNo').textContent = document.getElementById('filterTotalMessageNo').textContent;
document.getElementById('totalWarningNo').textContent = parseInt(document.getElementById('totalWarningNo').textContent, 10) + newWarn - oldWarn;
document.getElementById('totalErrorNo').textContent = parseInt(document.getElementById('totalErrorNo').textContent, 10) + newErr - oldErr;
} else if (change.name == 'plugins') {
/* Update plugin and message counts. Unlike for global messages
it's not worth calculating the count differences, just count
from zero. */
var totalMessageNo = 0;
var warnMessageNo = 0;
var errorMessageNo = 0;
var activePluginNo = 0;
var dirtyPluginNo = 0;
if (change.object.globalMessages) {
totalMessageNo = change.object.globalMessages.length;
change.object.globalMessages.forEach(function(message){
if (message.type == 'warn') {
++warnMessageNo;
} else if (message.type == 'error') {
++errorMessageNo;
}
});
}
change.object[change.name].forEach(function(plugin) {
if (plugin.isActive) {
++activePluginNo;
}
if (plugin.isDirty) {
++dirtyPluginNo;
}
if (plugin.messages) {
totalMessageNo += plugin.messages.length;
plugin.messages.forEach(function(message) {
if (message.type == 'warn') {
++warnMessageNo;
} else if (message.type == 'error') {
++errorMessageNo;
}
});
}
});
document.getElementById('filterTotalMessageNo').textContent = totalMessageNo;
document.getElementById('totalMessageNo').textContent = totalMessageNo;
document.getElementById('totalWarningNo').textContent = warnMessageNo;
document.getElementById('totalErrorNo').textContent = errorMessageNo;
document.getElementById('filterTotalPluginNo').textContent = change.object[change.name].length;
document.getElementById('totalPluginNo').textContent = change.object[change.name].length;
document.getElementById('activePluginNo').textContent = activePluginNo;
document.getElementById('dirtyPluginNo').textContent = dirtyPluginNo;
/* Register a new array observer. */
Array.observe(change.object[change.name], change.object.pluginsObserver);
}
});
},
/* Returns a cefQuery as a Promise. */
query: function(request) {
return new Promise(function(resolve, reject) {
window.cefQuery({
request: request,
persistent: false,
onSuccess: resolve,
onFailure: function(errorCode, errorMessage) {
reject(Error('Error code: ' + errorCode + '; ' + errorMessage))
}
});
});
}
};
+6 -313
View File
@@ -24,318 +24,6 @@
'use strict';
var marked;
var l10n;
var loot = {
installedGames: [],
settings: {},
game: {
folder: '',
globalMessages: [],
masterlist: {},
plugins: [],
/* Call whenever game is changed or game menu / game table are rewritten. */
updateSelectedGame: function() {
document.getElementById('gameMenu').value = this.folder;
/* Also disable deletion of the game's row in the settings dialog. */
var table = document.getElementById('gameTable');
for (var i = 0; i < table.tBodies[0].rows.length; ++i) {
if (table.tBodies[0].rows[i].getElementsByClassName('folder').length > 0) {
if (table.tBodies[0].rows[i].getElementsByClassName('folder')[0].value == this.folder) {
table.setReadOnly(table.tBodies[0].rows[i], ['delete']);
} else {
table.setReadOnly(table.tBodies[0].rows[i], ['delete'], false);
}
}
}
},
/* Call whenever game is changed. */
updateRedatePluginsButtonState: function() {
/* Also enable/disable the redate plugins option. */
var index = undefined;
for (var i = 0; i < loot.settings.games.length; ++i) {
if (loot.settings.games[i].folder == this.folder) {
index = i;
break;
}
}
var redateButton = document.getElementById('redatePluginsButton');
if (index != undefined && loot.settings.games[index].type == 'Skyrim') {
redateButton.removeAttribute('disabled');
} else {
redateButton.setAttribute('disabled', true);
}
},
pluginsObserver: function(changes) {
changes.forEach(function(change){
/* Need to handle plugin addition and removal.
Update plugin and message counts. */
var totalChange = 0;
var warnChange = 0;
var errorChange = 0;
var activeChange = 0;
var dirtyChange = 0;
if (change.addedCount > 0) {
/* Addition */
for (var i = change.index; i < change.index + change.addedCount; ++i) {
if (change.object[i].isActive) {
++activeChange;
}
if (change.object[i].isDirty) {
++dirtyChange;
}
if (change.object[i].messages) {
totalChange += change.object[i].messages.length;
change.object[i].messages.forEach(function(message) {
if (message.type == 'warn') {
++warnChange;
} else if (message.type == 'error') {
++errorChange;
}
});
}
}
}
if (change.removed.length > 0) {
/* Removal */
change.removed.forEach(function(plugin){
if (plugin.isActive) {
--activeChange;
}
if (plugin.isDirty) {
--dirtyChange;
}
if (plugin.messages) {
totalChange -= plugin.messages.length;
plugin.messages.forEach(function(message) {
if (message.type == 'warn') {
--warnChange;
} else if (message.type == 'error') {
--errorChange;
}
});
}
});
}
document.getElementById('filterTotalMessageNo').textContent = parseInt(document.getElementById('filterTotalMessageNo').textContent, 10) + totalChange;
document.getElementById('totalMessageNo').textContent = document.getElementById('filterTotalMessageNo').textContent;
document.getElementById('totalWarningNo').textContent = parseInt(document.getElementById('totalWarningNo').textContent, 10) + warnReduction;
document.getElementById('totalErrorNo').textContent = parseInt(document.getElementById('totalErrorNo').textContent, 10) + errorReduction;
document.getElementById('filterTotalPluginNo').textContent = parseInt(document.getElementById('filterTotalPluginNo').textContent, 10) + change.addedCount - change.removed.length;
document.getElementById('totalPluginNo').textContent = document.getElementById('filterTotalPluginNo').textContent;
document.getElementById('activePluginNo').textContent = parseInt(document.getElementById('activePluginNo').textContent, 10) + activeReduction;
document.getElementById('dirtyPluginNo').textContent = parseInt(document.getElementById('dirtyPluginNo').textContent, 10) + dirtyReduction;
});
}
},
/* Call whenever installedGames is changed or game menu is rewritten. */
updateEnabledGames: function() {
/* Update the disabled games in the game menu. */
var gameMenuItems = document.getElementById('gameMenu').children;
for (var i = 0; i < gameMenuItems.length; ++i) {
if (this.installedGames.indexOf(gameMenuItems[i].getAttribute('value')) == -1) {
gameMenuItems[i].setAttribute('disabled', true);
gameMenuItems[i].removeEventListener('click', changeGame, false);
} else {
gameMenuItems[i].removeAttribute('disabled');
gameMenuItems[i].addEventListener('click', changeGame, false);
}
}
},
/* Call whenever settings are changed. */
updateSettingsUI: function() {
var gameSelect = document.getElementById('defaultGameSelect');
var gameMenu = document.getElementById('gameMenu');
var gameTable = document.getElementById('gameTable');
/* First make sure game listing elements don't have any existing entries. */
while (gameSelect.children.length > 1) {
gameSelect.removeChild(gameSelect.lastElementChild);
}
while (gameMenu.firstElementChild) {
gameMenu.firstElementChild.removeEventListener('click', changeGame, false);
gameMenu.removeChild(gameMenu.firstElementChild);
}
gameTable.clear();
/* Now fill with new values. */
this.settings.games.forEach(function(game){
var menuItem = document.createElement('paper-item');
menuItem.setAttribute('value', game.folder);
menuItem.setAttribute('noink', '');
menuItem.textContent = game.name;
gameMenu.appendChild(menuItem);
gameSelect.appendChild(menuItem.cloneNode(true));
var row = gameTable.addRow(game);
gameTable.setReadOnly(row, ['name','folder','type']);
});
gameSelect.value = this.settings.game;
document.getElementById('languageSelect').value = this.settings.language;
document.getElementById('enableDebugLogging').checked = this.settings.enableDebugLogging;
document.getElementById('updateMasterlist').checked = this.settings.updateMasterlist;
this.updateEnabledGames();
this.game.updateSelectedGame();
},
/* Observer for loot members. */
observer: function(changes) {
changes.forEach(function(change){
if (change.name == 'installedGames') {
change.object.updateEnabledGames();
} else if (change.name == 'settings') {
change.object.updateSettingsUI();
}
});
},
/* Observer for loot.game members. */
gameObserver: function(changes) {
changes.forEach(function(change){
if (change.name == 'folder') {
change.object.updateSelectedGame();
change.object.updateRedatePluginsButtonState();
} else if (change.name == 'masterlist') {
if (change.object[change.name] && change.object[change.name].revision) {
document.getElementById('masterlistRevision').textContent = change.object[change.name].revision;
} else {
document.getElementById('masterlistRevision').textContent = l10n.jed.translate("N/A").fetch();
}
if (change.object[change.name] && change.object[change.name].date) {
document.getElementById('masterlistDate').textContent = change.object[change.name].date;
} else {
document.getElementById('masterlistDate').textContent = l10n.jed.translate("N/A").fetch();
}
} else if (change.name == 'globalMessages') {
/* For the messages, they don't have a JS 'class' so need to everything
here. Count up the global message types that exist, then remove them
and add the new ones, counting their types, then update the message
counts. I tried using an observer for this, but it wouldn't fire for
some reason. */
var oldTotal = change.oldValue.length;
var newTotal = 0;
var oldWarn = 0;
var newWarn = 0;
var oldErr = 0;
var newErr = 0;
/* Count up old warnings and errors. */
change.oldValue.forEach(function(message){
if (message.type == 'warn') {
++oldWarn;
} else if (message.type == 'error') {
++oldErr;
}
});
/* Remove old messages from UI. */
var generalMessagesList = document.getElementById('summary').getElementsByTagName('ul')[0];
while (generalMessagesList.firstElementChild) {
generalMessagesList.removeChild(generalMessagesList.firstElementChild);
}
/* Add new messages. */
if (change.object[change.name]) {
newTotal = change.object[change.name].length;
change.object[change.name].forEach(function(message){
var li = document.createElement('li');
li.className = message.type;
/* Use the Marked library for Markdown formatting support. */
li.innerHTML = marked(message.content[0].str);
generalMessagesList.appendChild(li);
if (li.className == 'warn') {
++newWarn;
} else if (li.className == 'error') {
++newErr;
}
});
}
/* Update message counts in UI. */
document.getElementById('filterTotalMessageNo').textContent = parseInt(document.getElementById('filterTotalMessageNo').textContent, 10) + newTotal - oldTotal;
document.getElementById('totalMessageNo').textContent = document.getElementById('filterTotalMessageNo').textContent;
document.getElementById('totalWarningNo').textContent = parseInt(document.getElementById('totalWarningNo').textContent, 10) + newWarn - oldWarn;
document.getElementById('totalErrorNo').textContent = parseInt(document.getElementById('totalErrorNo').textContent, 10) + newErr - oldErr;
} else if (change.name == 'plugins') {
/* Update plugin and message counts. Unlike for global messages
it's not worth calculating the count differences, just count
from zero. */
var totalMessageNo = 0;
var warnMessageNo = 0;
var errorMessageNo = 0;
var activePluginNo = 0;
var dirtyPluginNo = 0;
if (change.object.globalMessages) {
totalMessageNo = change.object.globalMessages.length;
change.object.globalMessages.forEach(function(message){
if (message.type == 'warn') {
++warnMessageNo;
} else if (message.type == 'error') {
++errorMessageNo;
}
});
}
change.object[change.name].forEach(function(plugin) {
if (plugin.isActive) {
++activePluginNo;
}
if (plugin.isDirty) {
++dirtyPluginNo;
}
if (plugin.messages) {
totalMessageNo += plugin.messages.length;
plugin.messages.forEach(function(message) {
if (message.type == 'warn') {
++warnMessageNo;
} else if (message.type == 'error') {
++errorMessageNo;
}
});
}
});
document.getElementById('filterTotalMessageNo').textContent = totalMessageNo;
document.getElementById('totalMessageNo').textContent = totalMessageNo;
document.getElementById('totalWarningNo').textContent = warnMessageNo;
document.getElementById('totalErrorNo').textContent = errorMessageNo;
document.getElementById('filterTotalPluginNo').textContent = change.object[change.name].length;
document.getElementById('totalPluginNo').textContent = change.object[change.name].length;
document.getElementById('activePluginNo').textContent = activePluginNo;
document.getElementById('dirtyPluginNo').textContent = dirtyPluginNo;
/* Register a new array observer. */
Array.observe(change.object[change.name], change.object.pluginsObserver);
}
});
},
/* Returns a cefQuery as a Promise. */
query: function(request) {
return new Promise(function(resolve, reject) {
window.cefQuery({
request: request,
persistent: false,
onSuccess: resolve,
onFailure: function(errorCode, errorMessage) {
reject(Error('Error code: ' + errorCode + '; ' + errorMessage))
}
});
});
}
};
Object.observe(loot, loot.observer);
/* Register game object observer. */
Object.observe(loot.game, loot.gameObserver);
function processCefError(err) {
/* Error.stack seems to be Chromium-specific. It gives a lot more useful
@@ -1282,7 +970,12 @@ window.addEventListener('polymer-ready', function(e) {
/* Set the plugin list's scroll target to its parent. */
document.getElementById('main').lastElementChild.scrollTarget = document.getElementById('main');
require(['bower_components/marked/lib/marked', 'js/l10n', 'js/plugin', 'js/filters'], function(markedResponse, l10nResponse) {
require(['bower_components/marked/lib/marked', 'js/l10n', 'js/plugin', 'js/loot', 'js/filters'], function(markedResponse, l10nResponse) {
/* Register object observers. */
Object.observe(loot, loot.observer);
Object.observe(loot.game, loot.gameObserver);
marked = markedResponse;
l10n = l10nResponse;
/* Make sure settings are what I want. */