From b2278aba86aeb14aff505d12dde8683f66a1b08e Mon Sep 17 00:00:00 2001 From: Oliver Hamlet Date: Thu, 15 Jan 2015 10:45:47 +0000 Subject: [PATCH 1/7] Split `loot` JS global code into new file. --- resources/report/js/loot.js | 309 ++++++++++++++++++++++++++++++++ resources/report/js/script.js | 319 +--------------------------------- 2 files changed, 315 insertions(+), 313 deletions(-) create mode 100644 resources/report/js/loot.js diff --git a/resources/report/js/loot.js b/resources/report/js/loot.js new file mode 100644 index 00000000..830d0b59 --- /dev/null +++ b/resources/report/js/loot.js @@ -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)) + } + }); + }); + } +}; diff --git a/resources/report/js/script.js b/resources/report/js/script.js index c3992c40..9e2bd73a 100644 --- a/resources/report/js/script.js +++ b/resources/report/js/script.js @@ -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. */ From 1c0f1f0dc08bc5ebde81da7d97198355e9c8d0d6 Mon Sep 17 00:00:00 2001 From: Oliver Hamlet Date: Thu, 15 Jan 2015 10:58:44 +0000 Subject: [PATCH 2/7] Refactored event handling JS. --- resources/report/js/events.js | 590 ++++++++++++++++++++++++++++++++++ resources/report/js/script.js | 589 +-------------------------------- 2 files changed, 591 insertions(+), 588 deletions(-) create mode 100644 resources/report/js/events.js diff --git a/resources/report/js/events.js b/resources/report/js/events.js new file mode 100644 index 00000000..38ff3836 --- /dev/null +++ b/resources/report/js/events.js @@ -0,0 +1,590 @@ +function openLogLocation(evt) { + loot.query('openLogLocation').catch(processCefError); +} +function changeGame(evt) { + /* Check that the selected game isn't the current one. */ + if (evt.target.className.indexOf('core-selected') != -1) { + return; + } + + /* Send off a CEF query with the folder name of the new game. */ + showProgress(l10n.jed.translate('Loading game data...').fetch()); + var request = JSON.stringify({ + name: 'changeGame', + args: [ + evt.currentTarget.getAttribute('value') + ] + }); + loot.query(request).then(function(result){ + /* Filters should be re-applied on game change, except the conflicts + filter. Don't need to deactivate the others beforehand. Strictly not + deactivating the conflicts filter either, just resetting it's value. + */ + document.body.removeAttribute('data-conflicts'); + + /* Clear the UI of all existing game-specific data. Also + clear the card and li variables for each plugin object. */ + var globalMessages = document.getElementById('summary').getElementsByTagName('ul')[0]; + while (globalMessages.firstElementChild) { + globalMessages.removeChild(globalMessages.firstElementChild); + } + + /* Parse the data sent from C++. */ + try { + var gameInfo = JSON.parse(result, jsonToPlugin); + loot.game.folder = gameInfo.folder; + loot.game.masterlist = gameInfo.masterlist; + loot.game.globalMessages = gameInfo.globalMessages; + loot.game.plugins = gameInfo.plugins; + + /* Reset virtual list positions. */ + document.getElementById('cardsNav').scrollToItem(0); + document.getElementById('main').lastElementChild.scrollToItem(0); + + /* Now update virtual lists. */ + setFilteredUIData(); + } catch (e) { + console.log(e); + console.log('changeGame response: ' + result); + } + + closeProgressDialog(); + }).catch(processCefError); +} +function openReadme(evt) { + loot.query('openReadme').catch(processCefError); +} +/* Masterlist update process, minus progress dialog. */ +function updateMasterlistNoProgress() { + return loot.query('updateMasterlist').then(JSON.parse).then(function(result){ + if (result) { + /* Update JS variables. */ + loot.game.masterlist = result.masterlist; + loot.game.globalMessages = result.globalMessages; + + result.plugins.forEach(function(plugin){ + for (var i = 0; i < loot.game.plugins.length; ++i) { + if (loot.game.plugins[i].name == plugin.name) { + loot.game.plugins[i].isDirty = plugin.isDirty; + loot.game.plugins[i].isGlobalPriority = plugin.isGlobalPriority; + loot.game.plugins[i].masterlist = plugin.masterlist; + loot.game.plugins[i].messages = plugin.messages; + loot.game.plugins[i].modPriority = plugin.modPriority; + loot.game.plugins[i].tags = plugin.tags; + break; + } + } + }); + /* Hack to stop cards overlapping. */ + document.getElementById('main').lastElementChild.updateSize(); + + toast(l10n.jed.translate('Masterlist updated to revision %s.').fetch(loot.game.masterlist.revision)); + } else { + toast(l10n.jed.translate('No masterlist update was necessary.').fetch()); + } + }).catch(processCefError); +} +function updateMasterlist(evt) { + showProgress(l10n.jed.translate('Updating masterlist...').fetch()); + updateMasterlistNoProgress().then(function(result){ + closeProgressDialog(); + }).catch(processCefError); +} +function sortPlugins(evt) { + var mlistUpdate; + if (loot.settings.updateMasterlist) { + mlistUpdate = updateMasterlistNoProgress(); + } else { + mlistUpdate = new Promise(function(resolve, reject){ + resolve(''); + }); + } + mlistUpdate.then(function(){ + showProgress(l10n.jed.translate('Sorting plugins...').fetch()); + loot.query('sortPlugins').then(JSON.parse).then(function(result){ + if (result) { + loot.game.oldLoadOrder = loot.game.plugins; + loot.game.loadOrder = []; + result.forEach(function(plugin){ + var found = false; + for (var i = 0; i < loot.game.plugins.length; ++i) { + if (loot.game.plugins[i].name == plugin.name) { + loot.game.plugins[i].crc = plugin.crc; + loot.game.plugins[i].isEmpty = plugin.isEmpty; + + loot.game.plugins[i].messages = plugin.messages; + loot.game.plugins[i].tags = plugin.tags; + loot.game.plugins[i].isDirty = plugin.isDirty; + + loot.game.loadOrder.push(loot.game.plugins[i]); + + found = true; + break; + } + } + if (!found) { + loot.game.plugins[i].push(new Plugin(plugin)); + loot.game.loadOrder.push(loot.game.plugins[i]); + } + }); + + if (loot.settings.neverTellMeTheOdds) { + /* Array shuffler from */ + for(var j, x, i = loot.game.loadOrder.length; i; j = Math.floor(Math.random() * i), x = loadOrder[--i], loot.game.loadOrder[i] = loot.game.loadOrder[j], loot.game.loadOrder[j] = x); + } + + /* Now update the UI for the new order. */ + loot.game.plugins = loot.game.loadOrder; + setFilteredUIData(); + + /* Now hide the masterlist update buttons, and display the accept and + cancel sort buttons. */ + hideElement(document.getElementById('updateMasterlistButton')); + hideElement(document.getElementById('sortButton')); + showElement(document.getElementById('applySortButton')); + showElement(document.getElementById('cancelSortButton')); + + /* Disable changing game. */ + document.getElementById('gameMenu').setAttribute('disabled', ''); + closeProgressDialog(); + } + }).catch(processCefError); + }).catch(processCefError); +} +function applySort(evt) { + var loadOrder = []; + loot.game.plugins.forEach(function(plugin){ + loadOrder.push(plugin.name); + }); + var request = JSON.stringify({ + name: 'applySort', + args: [ + loadOrder + ] + }); + return loot.query(request).then(function(result){ + /* Remove old load order storage. */ + delete loot.game.loadOrder; + delete loot.game.oldLoadOrder; + + /* Now show the masterlist update buttons, and hide the accept and + cancel sort buttons. */ + showElement(document.getElementById('updateMasterlistButton')); + showElement(document.getElementById('sortButton')); + hideElement(document.getElementById('applySortButton')); + hideElement(document.getElementById('cancelSortButton')); + + /* Enable changing game. */ + document.getElementById('gameMenu').removeAttribute('disabled'); + }).catch(processCefError); +} +function cancelSort(evt) { + return loot.query('cancelSort').then(function(){ + /* Sort UI elements again according to stored old load order. */ + loot.game.plugins = loot.game.oldLoadOrder; + setFilteredUIData(); + delete loot.game.loadOrder; + delete loot.game.oldLoadOrder; + + /* Now show the masterlist update buttons, and hide the accept and + cancel sort buttons. */ + showElement(document.getElementById('updateMasterlistButton')); + showElement(document.getElementById('sortButton')); + hideElement(document.getElementById('applySortButton')); + hideElement(document.getElementById('cancelSortButton')); + + /* Enable changing game. */ + document.getElementById('gameMenu').removeAttribute('disabled'); + }).catch(processCefError); +} +function redatePlugins(evt) { + if (evt.target.hasAttribute('disabled')) { + return; + } + + showMessageDialog(l10n.jed.translate('Redate Plugins?').fetch(), l10n.jed.translate('This feature is provided so that modders using the Creation Kit may set the load order it uses. A side-effect is that any subscribed Steam Workshop mods will be re-downloaded by Steam. Do you wish to continue?').fetch(), l10n.jed.translate('Redate').fetch(), function(result){ + if (result) { + loot.query('redatePlugins').then(function(response){ + toast('Plugins were successfully redated.'); + }).catch(processCefError); + } + }); +} +function clearAllMetadata(evt) { + showMessageDialog('', l10n.jed.translate('Are you sure you want to clear all existing user-added metadata from all plugins?').fetch(), l10n.jed.translate('Clear').fetch(), function(result){ + if (result) { + loot.query('clearAllMetadata').then(JSON.parse).then(function(result){ + if (result) { + /* Need to empty the UI-side user metadata. */ + result.forEach(function(plugin){ + for (var i = 0; i < loot.game.plugins.length; ++i) { + if (loot.game.plugins[i].name == plugin.name) { + loot.game.plugins[i].userlist = undefined; + + loot.game.plugins[i].modPriority = plugin.modPriority; + loot.game.plugins[i].isGlobalPriority = plugin.isGlobalPriority; + loot.game.plugins[i].messages = plugin.messages; + loot.game.plugins[i].tags = plugin.tags; + loot.game.plugins[i].isDirty = plugin.isDirty; + + break; + } + } + }); + + toast(l10n.jed.translate('All user-added metadata has been cleared.').fetch()); + } + }).catch(processCefError); + } + }); +} +function copyContent(evt) { + var messages = []; + var plugins = []; + + if (loot.game) { + if (loot.game.globalMessages) { + loot.game.globalMessages.forEach(function(message){ + var m = {}; + messages.push({ + type: message.type, + content: message.content[0].str + }); + }); + } + if (loot.game.plugins) { + loot.game.plugins.forEach(function(plugin){ + plugins.push({ + name: plugin.name, + crc: plugin.crc, + version: plugin.version, + isActive: plugin.isActive, + isEmpty: plugin.isEmpty, + loadsBSA: plugin.loadsBSA, + + modPriority: plugin.modPriority, + isGlobalPriority: plugin.isGlobalPriority, + messages: plugin.messages, + tags: plugin.tags, + isDirty: plugin.isDirty + }); + }); + } + } else { + var message = document.getElementById('summary').getElementsByTagName('ul')[0].firstElementChild; + if (message) { + messages.push({ + type: 'error', + content: message.textContent + }); + } + } + + var request = JSON.stringify({ + name: 'copyContent', + args: [{ + messages: messages, + plugins: plugins + }] + }); + + loot.query(request).then(function(){ + toast(l10n.jed.translate("LOOT's content has been copied to the clipboard.").fetch()); + }).catch(processCefError); +} +function switchSidebarTab(evt) { + if (evt.detail.isSelected) { + document.getElementById(evt.target.selected).parentElement.selected = evt.target.selected; + } +} + +function showAboutDialog(evt) { + document.getElementById('about').showModal(); +} +function closeSettingsDialog(evt) { + if (evt.target.classList.contains('accept')) { + if (!areSettingsValid()) { + return; + } + + /* Update the JS variable values. */ + var settings = { + enableDebugLogging: document.getElementById('enableDebugLogging').checked, + game: document.getElementById('defaultGameSelect').value, + games: document.getElementById('gameTable').getRowsData(false), + language: document.getElementById('languageSelect').value, + lastGame: loot.settings.lastGame, + updateMasterlist: document.getElementById('updateMasterlist').checked, + filters: loot.settings.filters, + }; + + /* Send the settings back to the C++ side. */ + var request = JSON.stringify({ + name: 'closeSettings', + args: [ + settings + ] + }); + loot.query(request).then(function(result){ + + try { + loot.installedGames = JSON.parse(result); + } catch (e) { + console.log(e); + console.log('getInstalledGames response: ' + results[1]); + } + + loot.settings = settings; + }).catch(processCefError); + } else { + /* Re-apply the existing settings to the settings dialog elements. */ + loot.updateSettingsUI(); + } + evt.target.parentElement.close(); +} + +function showSettingsDialog(evt) { + document.getElementById('settingsDialog').showModal(); +} +function focusSearch(evt) { + if (evt.ctrlKey && evt.keyCode == 70) { //'f' + document.getElementById('searchBox').focus(); + } +} +function handleEditorOpen(evt) { + /* Set up drag 'n' drop event handlers. */ + var elements = document.getElementById('cardsNav').getElementsByTagName('loot-plugin-item'); + for (var i = 0; i < elements.length; ++i) { + elements[i].draggable = true; + elements[i].addEventListener('dragstart', elements[i].handleDragStart, false); + } + + /* Now show editor. */ + evt.target.classList.toggle('flip'); + + /* Enable priority hover in plugins list and enable header + buttons if this is the only editor instance. */ + var numEditors = 0; + if (document.body.hasAttribute('data-editors')) { + numEditors = parseInt(document.body.getAttribute('data-editors'), 10); + } + ++numEditors; + + if (numEditors == 1) { + /* Set the edit mode toggle attribute. */ + document.getElementById('cardsNav').setAttribute('data-editModeToggle', ''); + /* Disable the toolbar elements. */ + document.getElementById('wipeUserlistButton').setAttribute('disabled', ''); + document.getElementById('copyContentButton').setAttribute('disabled', ''); + document.getElementById('refreshContentButton').setAttribute('disabled', ''); + document.getElementById('settingsButton').setAttribute('disabled', ''); + document.getElementById('gameMenu').setAttribute('disabled', ''); + document.getElementById('updateMasterlistButton').setAttribute('disabled', ''); + document.getElementById('sortButton').setAttribute('disabled', ''); + } + document.body.setAttribute('data-editors', numEditors); + document.getElementById('cardsNav').updateSize(); + + return loot.query('editorOpened').catch(processCefError); +} +function handleEditorClose(evt) { + /* evt.detail is true if the apply button was pressed. */ + if (evt.detail) { + /* Need to record the editor control values and work out what's + changed, and update any UI elements necessary. Offload the + majority of the work to the C++ side of things. */ + + var edits = evt.target.readFromEditor(evt.target.data); + + var request = JSON.stringify({ + name: 'editorClosed', + args: [ + edits + ] + }); + loot.query(request).then(JSON.parse).then(function(result){ + if (result) { + evt.target.data.modPriority = result.modPriority; + evt.target.data.isGlobalPriority = result.isGlobalPriority; + evt.target.data.messages = result.messages; + evt.target.data.tags = result.tags; + evt.target.data.isDirty = result.isDirty; + + evt.target.data.userlist = edits.userlist; + delete evt.target.data.editor; + } + }).catch(processCefError); + } else { + /* Don't need to record changes, but still need to notify C++ side that + the editor has been closed. */ + loot.query('editorClosed').catch(processCefError); + } + + /* Now hide editor. */ + evt.target.classList.toggle('flip'); + + /* Remove drag 'n' drop event handlers. */ + var elements = document.getElementById('cardsNav').getElementsByTagName('loot-plugin-item'); + for (var i = 0; i < elements.length; ++i) { + elements[i].removeAttribute('draggable'); + elements[i].removeEventListener('dragstart', elements[i].handleDragStart, false); + } + + /* Disable priority hover in plugins list and enable header + buttons if this is the only editor instance. */ + var numEditors = parseInt(document.body.getAttribute('data-editors'), 10); + --numEditors; + + if (numEditors == 0) { + document.body.removeAttribute('data-editors'); + /* Set the edit mode toggle attribute. */ + document.getElementById('cardsNav').setAttribute('data-editModeToggle', ''); + /* Re-enable toolbar elements. */ + document.getElementById('wipeUserlistButton').removeAttribute('disabled'); + document.getElementById('copyContentButton').removeAttribute('disabled'); + document.getElementById('refreshContentButton').removeAttribute('disabled'); + document.getElementById('settingsButton').removeAttribute('disabled'); + document.getElementById('gameMenu').removeAttribute('disabled'); + document.getElementById('updateMasterlistButton').removeAttribute('disabled'); + document.getElementById('sortButton').removeAttribute('disabled'); + } else { + document.body.setAttribute('data-editors', numEditors); + } + document.getElementById('cardsNav').updateSize(); +} +function handleConflictsFilter(evt) { + /* evt.detail is true if the filter has been activated. */ + if (evt.detail) { + /* Un-highlight any existing filter plugin. */ + var cards = document.getElementById('main').getElementsByTagName('loot-plugin-card'); + for (var i = 0; i < cards.length; ++i) { + cards[i].classList.toggle('highlight', false); + if (cards[i] != evt.target) { + cards[i].deactivateConflictFilter(); + } + } + evt.target.classList.toggle('highlight', true); + document.body.setAttribute('data-conflicts', evt.target.getName()); + } else { + evt.target.classList.toggle('highlight', false); + document.body.removeAttribute('data-conflicts'); + } + setFilteredUIData(evt); +} +function handleCopyMetadata(evt) { + /* evt.detail is the name of the plugin. */ + var request = JSON.stringify({ + name: 'copyMetadata', + args: [ + evt.target.getName(), + ] + }); + + loot.query(request).then(function(){ + toast(l10n.jed.translate('The metadata for "%s" has been copied to the clipboard.').fetch(evt.target.getName())); + }).catch(processCefError); +} +function handleClearMetadata(evt) { + showMessageDialog('', l10n.jed.translate('Are you sure you want to clear all existing user-added metadata from "%s"?').fetch(evt.target.getName()), l10n.jed.translate('Clear').fetch(), function(result){ + if (result) { + var request = JSON.stringify({ + name: 'clearPluginMetadata', + args: [ + evt.target.getName() + ] + }); + + loot.query(request).then(JSON.parse).then(function(result){ + if (result) { + /* Need to empty the UI-side user metadata. */ + for (var i = 0; i < loot.game.plugins.length; ++i) { + if (loot.game.plugins[i].id == evt.target.id) { + loot.game.plugins[i].userlist = undefined; + + loot.game.plugins[i].modPriority = result.modPriority; + loot.game.plugins[i].isGlobalPriority = result.isGlobalPriority; + loot.game.plugins[i].messages = result.messages; + loot.game.plugins[i].tags = result.tags; + loot.game.plugins[i].isDirty = result.isDirty; + + break; + } + } + toast(l10n.jed.translate('The user-added metadata for "%s" has been cleared.').fetch(evt.target.getName())); + } + }).catch(processCefError); + } + }); +} +function handleSidebarClick(evt) { + if (evt.target.hasAttribute('data-index')) { + document.getElementById('main').lastElementChild.scrollToItem(evt.target.getAttribute('data-index')); + + if (evt.type == 'dblclick') { + var card = document.getElementById(evt.target.getAttribute('data-id')); + if (!card.classList.contains('flip')) { + document.getElementById(evt.target.getAttribute('data-id')).onShowEditor(); + } + } + } +} +function handleQuit(evt) { + if (!document.getElementById('applySortButton').classList.contains('hidden')) { + handleUnappliedChangesClose(l10n.jed.translate('sorted load order').fetch()); + } else if (document.body.hasAttribute('data-editors')) { + handleUnappliedChangesClose(l10n.jed.translate('metadata edits').fetch()); + } else { + window.close(); + } +} +function jumpToGeneralInfo(evt) { + window.location.hash = ''; + document.getElementById('main').scrollTop = 0; +} +function setupEventHandlers() { + /*Set up handlers for filters.*/ + document.getElementById('hideVersionNumbers').addEventListener('change', toggleDisplayCSS, false); + document.getElementById('hideCRCs').addEventListener('change', toggleDisplayCSS, false); + document.getElementById('hideBashTags').addEventListener('change', toggleDisplayCSS, false); + document.getElementById('hideNotes').addEventListener('change', setFilteredUIData, false); + document.getElementById('hideDoNotCleanMessages').addEventListener('change', setFilteredUIData, false); + document.getElementById('hideInactivePlugins').addEventListener('change', setFilteredUIData, false); + document.getElementById('hideAllPluginMessages').addEventListener('change', setFilteredUIData, false); + document.getElementById('hideMessagelessPlugins').addEventListener('change', setFilteredUIData, false); + document.body.addEventListener('loot-filter-conflicts', handleConflictsFilter, false); + + /* Set up event handlers for content filter. */ + document.getElementById('searchBox').addEventListener('change', setFilteredUIData, false); + window.addEventListener('keyup', focusSearch, false); + + /* Set up handlers for buttons. */ + document.getElementById('redatePluginsButton').addEventListener('click', redatePlugins, false); + document.getElementById('openLogButton').addEventListener('click', openLogLocation, false); + document.getElementById('wipeUserlistButton').addEventListener('click', clearAllMetadata, false); + document.getElementById('copyContentButton').addEventListener('click', copyContent, false); + document.getElementById('refreshContentButton').addEventListener('click', onContentRefresh, false); + document.getElementById('settingsButton').addEventListener('click', showSettingsDialog, false); + document.getElementById('helpButton').addEventListener('click', openReadme, false); + document.getElementById('aboutButton').addEventListener('click', showAboutDialog, false); + document.getElementById('quitButton').addEventListener('click', handleQuit, false); + document.getElementById('updateMasterlistButton').addEventListener('click', updateMasterlist, false); + document.getElementById('sortButton').addEventListener('click', sortPlugins, false); + document.getElementById('applySortButton').addEventListener('click', applySort, false); + document.getElementById('cancelSortButton').addEventListener('click', cancelSort, false); + document.getElementById('sidebarTabs').addEventListener('core-select', switchSidebarTab, false); + document.getElementById('jumpToGeneralInfo').addEventListener('click', jumpToGeneralInfo, false); + + /* Set up event handlers for settings dialog. */ + var settings = document.getElementById('settingsDialog'); + settings.getElementsByClassName('accept')[0].addEventListener('click', closeSettingsDialog, false); + settings.getElementsByClassName('cancel')[0].addEventListener('click', closeSettingsDialog, false); + + /* Set up handler for opening and closing editors. */ + document.body.addEventListener('loot-editor-open', handleEditorOpen, false); + document.body.addEventListener('loot-editor-close', handleEditorClose, false); + document.body.addEventListener('loot-copy-metadata', handleCopyMetadata, false); + document.body.addEventListener('loot-clear-metadata', handleClearMetadata, false); + + document.getElementById('cardsNav').addEventListener('click', handleSidebarClick, false); + document.getElementById('cardsNav').addEventListener('dblclick', handleSidebarClick, false); +} \ No newline at end of file diff --git a/resources/report/js/script.js b/resources/report/js/script.js index 9e2bd73a..7c9a1e45 100644 --- a/resources/report/js/script.js +++ b/resources/report/js/script.js @@ -113,98 +113,7 @@ function showMessageBox(title, text) { dialog.showModal(title, text); document.body.appendChild(dialog); } -function openLogLocation(evt) { - loot.query('openLogLocation').catch(processCefError); -} -function changeGame(evt) { - /* Check that the selected game isn't the current one. */ - if (evt.target.className.indexOf('core-selected') != -1) { - return; - } - /* Send off a CEF query with the folder name of the new game. */ - showProgress(l10n.jed.translate('Loading game data...').fetch()); - var request = JSON.stringify({ - name: 'changeGame', - args: [ - evt.currentTarget.getAttribute('value') - ] - }); - loot.query(request).then(function(result){ - /* Filters should be re-applied on game change, except the conflicts - filter. Don't need to deactivate the others beforehand. Strictly not - deactivating the conflicts filter either, just resetting it's value. - */ - document.body.removeAttribute('data-conflicts'); - - /* Clear the UI of all existing game-specific data. Also - clear the card and li variables for each plugin object. */ - var globalMessages = document.getElementById('summary').getElementsByTagName('ul')[0]; - while (globalMessages.firstElementChild) { - globalMessages.removeChild(globalMessages.firstElementChild); - } - - /* Parse the data sent from C++. */ - try { - var gameInfo = JSON.parse(result, jsonToPlugin); - loot.game.folder = gameInfo.folder; - loot.game.masterlist = gameInfo.masterlist; - loot.game.globalMessages = gameInfo.globalMessages; - loot.game.plugins = gameInfo.plugins; - - /* Reset virtual list positions. */ - document.getElementById('cardsNav').scrollToItem(0); - document.getElementById('main').lastElementChild.scrollToItem(0); - - /* Now update virtual lists. */ - setFilteredUIData(); - } catch (e) { - console.log(e); - console.log('changeGame response: ' + result); - } - - closeProgressDialog(); - }).catch(processCefError); -} -function openReadme(evt) { - loot.query('openReadme').catch(processCefError); -} -/* Masterlist update process, minus progress dialog. */ -function updateMasterlistNoProgress() { - return loot.query('updateMasterlist').then(JSON.parse).then(function(result){ - if (result) { - /* Update JS variables. */ - loot.game.masterlist = result.masterlist; - loot.game.globalMessages = result.globalMessages; - - result.plugins.forEach(function(plugin){ - for (var i = 0; i < loot.game.plugins.length; ++i) { - if (loot.game.plugins[i].name == plugin.name) { - loot.game.plugins[i].isDirty = plugin.isDirty; - loot.game.plugins[i].isGlobalPriority = plugin.isGlobalPriority; - loot.game.plugins[i].masterlist = plugin.masterlist; - loot.game.plugins[i].messages = plugin.messages; - loot.game.plugins[i].modPriority = plugin.modPriority; - loot.game.plugins[i].tags = plugin.tags; - break; - } - } - }); - /* Hack to stop cards overlapping. */ - document.getElementById('main').lastElementChild.updateSize(); - - toast(l10n.jed.translate('Masterlist updated to revision %s.').fetch(loot.game.masterlist.revision)); - } else { - toast(l10n.jed.translate('No masterlist update was necessary.').fetch()); - } - }).catch(processCefError); -} -function updateMasterlist(evt) { - showProgress(l10n.jed.translate('Updating masterlist...').fetch()); - updateMasterlistNoProgress().then(function(result){ - closeProgressDialog(); - }).catch(processCefError); -} function showProgress(message) { var progressDialog = document.getElementById('progressDialog'); if (message) { @@ -220,208 +129,6 @@ function closeProgressDialog() { progressDialog.close(); } } -function sortPlugins(evt) { - var mlistUpdate; - if (loot.settings.updateMasterlist) { - mlistUpdate = updateMasterlistNoProgress(); - } else { - mlistUpdate = new Promise(function(resolve, reject){ - resolve(''); - }); - } - mlistUpdate.then(function(){ - showProgress(l10n.jed.translate('Sorting plugins...').fetch()); - loot.query('sortPlugins').then(JSON.parse).then(function(result){ - if (result) { - loot.game.oldLoadOrder = loot.game.plugins; - loot.game.loadOrder = []; - result.forEach(function(plugin){ - var found = false; - for (var i = 0; i < loot.game.plugins.length; ++i) { - if (loot.game.plugins[i].name == plugin.name) { - loot.game.plugins[i].crc = plugin.crc; - loot.game.plugins[i].isEmpty = plugin.isEmpty; - - loot.game.plugins[i].messages = plugin.messages; - loot.game.plugins[i].tags = plugin.tags; - loot.game.plugins[i].isDirty = plugin.isDirty; - - loot.game.loadOrder.push(loot.game.plugins[i]); - - found = true; - break; - } - } - if (!found) { - loot.game.plugins[i].push(new Plugin(plugin)); - loot.game.loadOrder.push(loot.game.plugins[i]); - } - }); - - if (loot.settings.neverTellMeTheOdds) { - /* Array shuffler from */ - for(var j, x, i = loot.game.loadOrder.length; i; j = Math.floor(Math.random() * i), x = loadOrder[--i], loot.game.loadOrder[i] = loot.game.loadOrder[j], loot.game.loadOrder[j] = x); - } - - /* Now update the UI for the new order. */ - loot.game.plugins = loot.game.loadOrder; - setFilteredUIData(); - - /* Now hide the masterlist update buttons, and display the accept and - cancel sort buttons. */ - hideElement(document.getElementById('updateMasterlistButton')); - hideElement(document.getElementById('sortButton')); - showElement(document.getElementById('applySortButton')); - showElement(document.getElementById('cancelSortButton')); - - /* Disable changing game. */ - document.getElementById('gameMenu').setAttribute('disabled', ''); - closeProgressDialog(); - } - }).catch(processCefError); - }).catch(processCefError); -} -function applySort(evt) { - var loadOrder = []; - loot.game.plugins.forEach(function(plugin){ - loadOrder.push(plugin.name); - }); - var request = JSON.stringify({ - name: 'applySort', - args: [ - loadOrder - ] - }); - return loot.query(request).then(function(result){ - /* Remove old load order storage. */ - delete loot.game.loadOrder; - delete loot.game.oldLoadOrder; - - /* Now show the masterlist update buttons, and hide the accept and - cancel sort buttons. */ - showElement(document.getElementById('updateMasterlistButton')); - showElement(document.getElementById('sortButton')); - hideElement(document.getElementById('applySortButton')); - hideElement(document.getElementById('cancelSortButton')); - - /* Enable changing game. */ - document.getElementById('gameMenu').removeAttribute('disabled'); - }).catch(processCefError); -} -function cancelSort(evt) { - return loot.query('cancelSort').then(function(){ - /* Sort UI elements again according to stored old load order. */ - loot.game.plugins = loot.game.oldLoadOrder; - setFilteredUIData(); - delete loot.game.loadOrder; - delete loot.game.oldLoadOrder; - - /* Now show the masterlist update buttons, and hide the accept and - cancel sort buttons. */ - showElement(document.getElementById('updateMasterlistButton')); - showElement(document.getElementById('sortButton')); - hideElement(document.getElementById('applySortButton')); - hideElement(document.getElementById('cancelSortButton')); - - /* Enable changing game. */ - document.getElementById('gameMenu').removeAttribute('disabled'); - }).catch(processCefError); -} -function redatePlugins(evt) { - if (evt.target.hasAttribute('disabled')) { - return; - } - - showMessageDialog(l10n.jed.translate('Redate Plugins?').fetch(), l10n.jed.translate('This feature is provided so that modders using the Creation Kit may set the load order it uses. A side-effect is that any subscribed Steam Workshop mods will be re-downloaded by Steam. Do you wish to continue?').fetch(), l10n.jed.translate('Redate').fetch(), function(result){ - if (result) { - loot.query('redatePlugins').then(function(response){ - toast('Plugins were successfully redated.'); - }).catch(processCefError); - } - }); -} -function clearAllMetadata(evt) { - showMessageDialog('', l10n.jed.translate('Are you sure you want to clear all existing user-added metadata from all plugins?').fetch(), l10n.jed.translate('Clear').fetch(), function(result){ - if (result) { - loot.query('clearAllMetadata').then(JSON.parse).then(function(result){ - if (result) { - /* Need to empty the UI-side user metadata. */ - result.forEach(function(plugin){ - for (var i = 0; i < loot.game.plugins.length; ++i) { - if (loot.game.plugins[i].name == plugin.name) { - loot.game.plugins[i].userlist = undefined; - - loot.game.plugins[i].modPriority = plugin.modPriority; - loot.game.plugins[i].isGlobalPriority = plugin.isGlobalPriority; - loot.game.plugins[i].messages = plugin.messages; - loot.game.plugins[i].tags = plugin.tags; - loot.game.plugins[i].isDirty = plugin.isDirty; - - break; - } - } - }); - - toast(l10n.jed.translate('All user-added metadata has been cleared.').fetch()); - } - }).catch(processCefError); - } - }); -} -function copyContent(evt) { - var messages = []; - var plugins = []; - - if (loot.game) { - if (loot.game.globalMessages) { - loot.game.globalMessages.forEach(function(message){ - var m = {}; - messages.push({ - type: message.type, - content: message.content[0].str - }); - }); - } - if (loot.game.plugins) { - loot.game.plugins.forEach(function(plugin){ - plugins.push({ - name: plugin.name, - crc: plugin.crc, - version: plugin.version, - isActive: plugin.isActive, - isEmpty: plugin.isEmpty, - loadsBSA: plugin.loadsBSA, - - modPriority: plugin.modPriority, - isGlobalPriority: plugin.isGlobalPriority, - messages: plugin.messages, - tags: plugin.tags, - isDirty: plugin.isDirty - }); - }); - } - } else { - var message = document.getElementById('summary').getElementsByTagName('ul')[0].firstElementChild; - if (message) { - messages.push({ - type: 'error', - content: message.textContent - }); - } - } - - var request = JSON.stringify({ - name: 'copyContent', - args: [{ - messages: messages, - plugins: plugins - }] - }); - - loot.query(request).then(function(){ - toast(l10n.jed.translate("LOOT's content has been copied to the clipboard.").fetch()); - }).catch(processCefError); -} function areSettingsValid() { /* Validate inputs individually. */ var inputs = document.getElementById('settingsDialog').getElementsByTagName('input'); @@ -433,65 +140,7 @@ function areSettingsValid() { } return true; } -function switchSidebarTab(evt) { - if (evt.detail.isSelected) { - document.getElementById(evt.target.selected).parentElement.selected = evt.target.selected; - } -} -function showAboutDialog(evt) { - document.getElementById('about').showModal(); -} -function closeSettingsDialog(evt) { - if (evt.target.classList.contains('accept')) { - if (!areSettingsValid()) { - return; - } - - /* Update the JS variable values. */ - var settings = { - enableDebugLogging: document.getElementById('enableDebugLogging').checked, - game: document.getElementById('defaultGameSelect').value, - games: document.getElementById('gameTable').getRowsData(false), - language: document.getElementById('languageSelect').value, - lastGame: loot.settings.lastGame, - updateMasterlist: document.getElementById('updateMasterlist').checked, - filters: loot.settings.filters, - }; - - /* Send the settings back to the C++ side. */ - var request = JSON.stringify({ - name: 'closeSettings', - args: [ - settings - ] - }); - loot.query(request).then(function(result){ - - try { - loot.installedGames = JSON.parse(result); - } catch (e) { - console.log(e); - console.log('getInstalledGames response: ' + results[1]); - } - - loot.settings = settings; - }).catch(processCefError); - } else { - /* Re-apply the existing settings to the settings dialog elements. */ - loot.updateSettingsUI(); - } - evt.target.parentElement.close(); -} - -function showSettingsDialog(evt) { - document.getElementById('settingsDialog').showModal(); -} -function focusSearch(evt) { - if (evt.ctrlKey && evt.keyCode == 70) { //'f' - document.getElementById('searchBox').focus(); - } -} function handleUnappliedChangesClose(change) { showMessageDialog('', l10n.jed.translate('You have not yet applied or cancelled your %s. Are you sure you want to quit?').fetch(change), l10n.jed.translate('Quit').fetch(), function(result){ if (result) { @@ -512,243 +161,7 @@ function handleUnappliedChangesClose(change) { } }); } -function handleEditorOpen(evt) { - /* Set up drag 'n' drop event handlers. */ - var elements = document.getElementById('cardsNav').getElementsByTagName('loot-plugin-item'); - for (var i = 0; i < elements.length; ++i) { - elements[i].draggable = true; - elements[i].addEventListener('dragstart', elements[i].handleDragStart, false); - } - /* Now show editor. */ - evt.target.classList.toggle('flip'); - - /* Enable priority hover in plugins list and enable header - buttons if this is the only editor instance. */ - var numEditors = 0; - if (document.body.hasAttribute('data-editors')) { - numEditors = parseInt(document.body.getAttribute('data-editors'), 10); - } - ++numEditors; - - if (numEditors == 1) { - /* Set the edit mode toggle attribute. */ - document.getElementById('cardsNav').setAttribute('data-editModeToggle', ''); - /* Disable the toolbar elements. */ - document.getElementById('wipeUserlistButton').setAttribute('disabled', ''); - document.getElementById('copyContentButton').setAttribute('disabled', ''); - document.getElementById('refreshContentButton').setAttribute('disabled', ''); - document.getElementById('settingsButton').setAttribute('disabled', ''); - document.getElementById('gameMenu').setAttribute('disabled', ''); - document.getElementById('updateMasterlistButton').setAttribute('disabled', ''); - document.getElementById('sortButton').setAttribute('disabled', ''); - } - document.body.setAttribute('data-editors', numEditors); - document.getElementById('cardsNav').updateSize(); - - return loot.query('editorOpened').catch(processCefError); -} -function handleEditorClose(evt) { - /* evt.detail is true if the apply button was pressed. */ - if (evt.detail) { - /* Need to record the editor control values and work out what's - changed, and update any UI elements necessary. Offload the - majority of the work to the C++ side of things. */ - - var edits = evt.target.readFromEditor(evt.target.data); - - var request = JSON.stringify({ - name: 'editorClosed', - args: [ - edits - ] - }); - loot.query(request).then(JSON.parse).then(function(result){ - if (result) { - evt.target.data.modPriority = result.modPriority; - evt.target.data.isGlobalPriority = result.isGlobalPriority; - evt.target.data.messages = result.messages; - evt.target.data.tags = result.tags; - evt.target.data.isDirty = result.isDirty; - - evt.target.data.userlist = edits.userlist; - delete evt.target.data.editor; - } - }).catch(processCefError); - } else { - /* Don't need to record changes, but still need to notify C++ side that - the editor has been closed. */ - loot.query('editorClosed').catch(processCefError); - } - - /* Now hide editor. */ - evt.target.classList.toggle('flip'); - - /* Remove drag 'n' drop event handlers. */ - var elements = document.getElementById('cardsNav').getElementsByTagName('loot-plugin-item'); - for (var i = 0; i < elements.length; ++i) { - elements[i].removeAttribute('draggable'); - elements[i].removeEventListener('dragstart', elements[i].handleDragStart, false); - } - - /* Disable priority hover in plugins list and enable header - buttons if this is the only editor instance. */ - var numEditors = parseInt(document.body.getAttribute('data-editors'), 10); - --numEditors; - - if (numEditors == 0) { - document.body.removeAttribute('data-editors'); - /* Set the edit mode toggle attribute. */ - document.getElementById('cardsNav').setAttribute('data-editModeToggle', ''); - /* Re-enable toolbar elements. */ - document.getElementById('wipeUserlistButton').removeAttribute('disabled'); - document.getElementById('copyContentButton').removeAttribute('disabled'); - document.getElementById('refreshContentButton').removeAttribute('disabled'); - document.getElementById('settingsButton').removeAttribute('disabled'); - document.getElementById('gameMenu').removeAttribute('disabled'); - document.getElementById('updateMasterlistButton').removeAttribute('disabled'); - document.getElementById('sortButton').removeAttribute('disabled'); - } else { - document.body.setAttribute('data-editors', numEditors); - } - document.getElementById('cardsNav').updateSize(); -} -function handleConflictsFilter(evt) { - /* evt.detail is true if the filter has been activated. */ - if (evt.detail) { - /* Un-highlight any existing filter plugin. */ - var cards = document.getElementById('main').getElementsByTagName('loot-plugin-card'); - for (var i = 0; i < cards.length; ++i) { - cards[i].classList.toggle('highlight', false); - if (cards[i] != evt.target) { - cards[i].deactivateConflictFilter(); - } - } - evt.target.classList.toggle('highlight', true); - document.body.setAttribute('data-conflicts', evt.target.getName()); - } else { - evt.target.classList.toggle('highlight', false); - document.body.removeAttribute('data-conflicts'); - } - setFilteredUIData(evt); -} -function handleCopyMetadata(evt) { - /* evt.detail is the name of the plugin. */ - var request = JSON.stringify({ - name: 'copyMetadata', - args: [ - evt.target.getName(), - ] - }); - - loot.query(request).then(function(){ - toast(l10n.jed.translate('The metadata for "%s" has been copied to the clipboard.').fetch(evt.target.getName())); - }).catch(processCefError); -} -function handleClearMetadata(evt) { - showMessageDialog('', l10n.jed.translate('Are you sure you want to clear all existing user-added metadata from "%s"?').fetch(evt.target.getName()), l10n.jed.translate('Clear').fetch(), function(result){ - if (result) { - var request = JSON.stringify({ - name: 'clearPluginMetadata', - args: [ - evt.target.getName() - ] - }); - - loot.query(request).then(JSON.parse).then(function(result){ - if (result) { - /* Need to empty the UI-side user metadata. */ - for (var i = 0; i < loot.game.plugins.length; ++i) { - if (loot.game.plugins[i].id == evt.target.id) { - loot.game.plugins[i].userlist = undefined; - - loot.game.plugins[i].modPriority = result.modPriority; - loot.game.plugins[i].isGlobalPriority = result.isGlobalPriority; - loot.game.plugins[i].messages = result.messages; - loot.game.plugins[i].tags = result.tags; - loot.game.plugins[i].isDirty = result.isDirty; - - break; - } - } - toast(l10n.jed.translate('The user-added metadata for "%s" has been cleared.').fetch(evt.target.getName())); - } - }).catch(processCefError); - } - }); -} -function handleSidebarClick(evt) { - if (evt.target.hasAttribute('data-index')) { - document.getElementById('main').lastElementChild.scrollToItem(evt.target.getAttribute('data-index')); - - if (evt.type == 'dblclick') { - var card = document.getElementById(evt.target.getAttribute('data-id')); - if (!card.classList.contains('flip')) { - document.getElementById(evt.target.getAttribute('data-id')).onShowEditor(); - } - } - } -} -function handleQuit(evt) { - if (!document.getElementById('applySortButton').classList.contains('hidden')) { - handleUnappliedChangesClose(l10n.jed.translate('sorted load order').fetch()); - } else if (document.body.hasAttribute('data-editors')) { - handleUnappliedChangesClose(l10n.jed.translate('metadata edits').fetch()); - } else { - window.close(); - } -} -function jumpToGeneralInfo(evt) { - window.location.hash = ''; - document.getElementById('main').scrollTop = 0; -} -function setupEventHandlers() { - /*Set up handlers for filters.*/ - document.getElementById('hideVersionNumbers').addEventListener('change', toggleDisplayCSS, false); - document.getElementById('hideCRCs').addEventListener('change', toggleDisplayCSS, false); - document.getElementById('hideBashTags').addEventListener('change', toggleDisplayCSS, false); - document.getElementById('hideNotes').addEventListener('change', setFilteredUIData, false); - document.getElementById('hideDoNotCleanMessages').addEventListener('change', setFilteredUIData, false); - document.getElementById('hideInactivePlugins').addEventListener('change', setFilteredUIData, false); - document.getElementById('hideAllPluginMessages').addEventListener('change', setFilteredUIData, false); - document.getElementById('hideMessagelessPlugins').addEventListener('change', setFilteredUIData, false); - document.body.addEventListener('loot-filter-conflicts', handleConflictsFilter, false); - - /* Set up event handlers for content filter. */ - document.getElementById('searchBox').addEventListener('change', setFilteredUIData, false); - window.addEventListener('keyup', focusSearch, false); - - /* Set up handlers for buttons. */ - document.getElementById('redatePluginsButton').addEventListener('click', redatePlugins, false); - document.getElementById('openLogButton').addEventListener('click', openLogLocation, false); - document.getElementById('wipeUserlistButton').addEventListener('click', clearAllMetadata, false); - document.getElementById('copyContentButton').addEventListener('click', copyContent, false); - document.getElementById('refreshContentButton').addEventListener('click', onContentRefresh, false); - document.getElementById('settingsButton').addEventListener('click', showSettingsDialog, false); - document.getElementById('helpButton').addEventListener('click', openReadme, false); - document.getElementById('aboutButton').addEventListener('click', showAboutDialog, false); - document.getElementById('quitButton').addEventListener('click', handleQuit, false); - document.getElementById('updateMasterlistButton').addEventListener('click', updateMasterlist, false); - document.getElementById('sortButton').addEventListener('click', sortPlugins, false); - document.getElementById('applySortButton').addEventListener('click', applySort, false); - document.getElementById('cancelSortButton').addEventListener('click', cancelSort, false); - document.getElementById('sidebarTabs').addEventListener('core-select', switchSidebarTab, false); - document.getElementById('jumpToGeneralInfo').addEventListener('click', jumpToGeneralInfo, false); - - /* Set up event handlers for settings dialog. */ - var settings = document.getElementById('settingsDialog'); - settings.getElementsByClassName('accept')[0].addEventListener('click', closeSettingsDialog, false); - settings.getElementsByClassName('cancel')[0].addEventListener('click', closeSettingsDialog, false); - - /* Set up handler for opening and closing editors. */ - document.body.addEventListener('loot-editor-open', handleEditorOpen, false); - document.body.addEventListener('loot-editor-close', handleEditorClose, false); - document.body.addEventListener('loot-copy-metadata', handleCopyMetadata, false); - document.body.addEventListener('loot-clear-metadata', handleClearMetadata, false); - - document.getElementById('cardsNav').addEventListener('click', handleSidebarClick, false); - document.getElementById('cardsNav').addEventListener('dblclick', handleSidebarClick, false); -} function initVars() { loot.query('getVersion').then(function(result){ try { @@ -970,7 +383,7 @@ 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/loot', 'js/filters'], function(markedResponse, l10nResponse) { + require(['bower_components/marked/lib/marked', 'js/l10n', 'js/plugin', 'js/loot', 'js/filters', 'js/events.js'], function(markedResponse, l10nResponse) { /* Register object observers. */ Object.observe(loot, loot.observer); From 84731e1f7200c29482317d296f86f72720c7f536 Mon Sep 17 00:00:00 2001 From: Oliver Hamlet Date: Thu, 15 Jan 2015 10:59:18 +0000 Subject: [PATCH 3/7] Move filter-related JS function into filters.js --- resources/report/js/filters.js | 45 ++++++++++++++++++++++++++++++++++ resources/report/js/script.js | 44 --------------------------------- 2 files changed, 45 insertions(+), 44 deletions(-) diff --git a/resources/report/js/filters.js b/resources/report/js/filters.js index f605f4ac..8b9a756c 100644 --- a/resources/report/js/filters.js +++ b/resources/report/js/filters.js @@ -146,6 +146,51 @@ var filters = { }, }; +function getConflictingPluginsFromFilter() { + var conflictsPlugin = document.body.getAttribute('data-conflicts'); + if (conflictsPlugin) { + /* Now get conflicts for the plugin. */ + var request = JSON.stringify({ + name: 'getConflictingPlugins', + args: [ + conflictsPlugin + ] + }); + + showProgress(l10n.jed.translate('Checking if plugins have been loaded...').fetch()); + + return loot.query(request).then(JSON.parse).then(function(result){ + if (result) { + /* Filter everything but the plugin itself if there are no + conflicts. */ + var conflicts = [ conflictsPlugin ]; + for (var key in result) { + if (result[key].conflicts) { + conflicts.push(key); + } + for (var i = 0; i < loot.game.plugins.length; ++i) { + if (loot.game.plugins[i].name == key) { + loot.game.plugins[i].crc = result[key].crc; + loot.game.plugins[i].isEmpty = result[key].isEmpty; + + loot.game.plugins[i].messages = result[key].messages; + loot.game.plugins[i].tags = result[key].tags; + loot.game.plugins[i].isDirty = result[key].isDirty; + break; + } + } + } + closeProgressDialog(); + return conflicts; + } + closeProgressDialog(); + return [ conflictsPlugin ]; + }).catch(processCefError); + } + + return Promise.resolve([]); +} + function setFilteredUIData(evt) { /* The conflict filter, if enabled, executes C++ code, so needs to be handled using a promise, so the rest of the function should wait until diff --git a/resources/report/js/script.js b/resources/report/js/script.js index 7c9a1e45..c687991a 100644 --- a/resources/report/js/script.js +++ b/resources/report/js/script.js @@ -57,50 +57,6 @@ function toast(text) { toast.text = text; toast.show(); } -function getConflictingPluginsFromFilter() { - var conflictsPlugin = document.body.getAttribute('data-conflicts'); - if (conflictsPlugin) { - /* Now get conflicts for the plugin. */ - var request = JSON.stringify({ - name: 'getConflictingPlugins', - args: [ - conflictsPlugin - ] - }); - - showProgress(l10n.jed.translate('Checking if plugins have been loaded...').fetch()); - - return loot.query(request).then(JSON.parse).then(function(result){ - if (result) { - /* Filter everything but the plugin itself if there are no - conflicts. */ - var conflicts = [ conflictsPlugin ]; - for (var key in result) { - if (result[key].conflicts) { - conflicts.push(key); - } - for (var i = 0; i < loot.game.plugins.length; ++i) { - if (loot.game.plugins[i].name == key) { - loot.game.plugins[i].crc = result[key].crc; - loot.game.plugins[i].isEmpty = result[key].isEmpty; - - loot.game.plugins[i].messages = result[key].messages; - loot.game.plugins[i].tags = result[key].tags; - loot.game.plugins[i].isDirty = result[key].isDirty; - break; - } - } - } - closeProgressDialog(); - return conflicts; - } - closeProgressDialog(); - return [ conflictsPlugin ]; - }).catch(processCefError); - } - - return Promise.resolve([]); -} function showMessageDialog(title, text, positiveText, closeCallback) { var dialog = document.createElement('loot-message-dialog'); dialog.setButtonText(positiveText, l10n.jed.translate('Cancel').fetch()); From 62ec80a77158450db0a4826127d73caffd8f6ff4 Mon Sep 17 00:00:00 2001 From: Oliver Hamlet Date: Thu, 15 Jan 2015 11:07:34 +0000 Subject: [PATCH 4/7] Some more JS refactoring. Moved a couple more event-related functions into events.js, moved all helper functions into helpers.js, and renamed script.js to init.js. --- resources/report/js/events.js | 78 ++++++++++ resources/report/js/helpers.js | 81 +++++++++++ resources/report/js/{script.js => init.js} | 162 +-------------------- resources/report/report.html | 2 +- 4 files changed, 161 insertions(+), 162 deletions(-) create mode 100644 resources/report/js/helpers.js rename resources/report/js/{script.js => init.js} (57%) diff --git a/resources/report/js/events.js b/resources/report/js/events.js index 38ff3836..6cae4031 100644 --- a/resources/report/js/events.js +++ b/resources/report/js/events.js @@ -301,6 +301,17 @@ function switchSidebarTab(evt) { function showAboutDialog(evt) { document.getElementById('about').showModal(); } +function areSettingsValid() { + /* Validate inputs individually. */ + var inputs = document.getElementById('settingsDialog').getElementsByTagName('input'); + for (var i = 0; i < inputs.length; ++i) { + if (!inputs[i].checkValidity()) { + return false; + console.log(inputs[i]); + } + } + return true; +} function closeSettingsDialog(evt) { if (evt.target.classList.contains('accept')) { if (!areSettingsValid()) { @@ -541,6 +552,73 @@ function jumpToGeneralInfo(evt) { window.location.hash = ''; document.getElementById('main').scrollTop = 0; } +function onContentRefresh(evt) { + /* Send a query for updated load order and plugin header info. */ + showProgress(l10n.jed.translate('Refreshing data...').fetch()); + loot.query('getGameData').then(function(result){ + /* Parse the data sent from C++. */ + try { + /* We don't want the plugin info creating cards, so don't convert + to plugin objects. */ + var gameInfo = JSON.parse(result); + } catch (e) { + console.log(e); + console.log('getGameData response: ' + result); + } + + /* Now overwrite plugin data with the newly sent data. Also update + card and li vars as they were unset when the game was switched + from before. */ + var pluginNames = []; + gameInfo.plugins.forEach(function(plugin){ + var foundPlugin = false; + for (var i = 0; i < loot.game.plugins.length; ++i) { + if (loot.game.plugins[i].name == plugin.name) { + + loot.game.plugins[i].isActive = plugin.isActive; + loot.game.plugins[i].isEmpty = plugin.isEmpty; + loot.game.plugins[i].loadsBSA = plugin.loadsBSA; + loot.game.plugins[i].crc = plugin.crc; + loot.game.plugins[i].version = plugin.version; + + loot.game.plugins[i].modPriority = plugin.modPriority; + loot.game.plugins[i].isGlobalPriority = plugin.isGlobalPriority; + loot.game.plugins[i].messages = plugin.messages; + loot.game.plugins[i].tags = plugin.tags; + loot.game.plugins[i].isDirty = plugin.isDirty; + + foundPlugin = true; + break; + } + } + if (!foundPlugin) { + /* A new plugin. */ + loot.game.plugins.push(new Plugin(plugin)); + } + pluginNames.push(plugin.name); + }); + for (var i = 0; i < loot.game.plugins.length;) { + var foundPlugin = false; + for (var j = 0; j < pluginNames.length; ++j) { + if (loot.game.plugins[i].name == pluginNames[j]) { + foundPlugin = true; + break; + } + } + if (!foundPlugin) { + /* Remove plugin. */ + loot.game.plugins.splice(i, 1); + } else { + ++i; + } + } + + /* Reapply filters. */ + setFilteredUIData(); + + closeProgressDialog(); + }).catch(processCefError); +} function setupEventHandlers() { /*Set up handlers for filters.*/ document.getElementById('hideVersionNumbers').addEventListener('change', toggleDisplayCSS, false); diff --git a/resources/report/js/helpers.js b/resources/report/js/helpers.js new file mode 100644 index 00000000..fd419402 --- /dev/null +++ b/resources/report/js/helpers.js @@ -0,0 +1,81 @@ +function processCefError(err) { + /* Error.stack seems to be Chromium-specific. It gives a lot more useful + info than just the error message. Also, this can be used to catch any + promise errors, not just CEF errors. */ + console.log(err.stack); + closeProgressDialog(); + showMessageBox(l10n.jed.translate('Error').fetch(), err.message); +} + +function showElement(element) { + if (element != null) { + element.classList.toggle('hidden', false); + } +} +function hideElement(element) { + if (element != null) { + element.classList.toggle('hidden', true); + } +} +function toggleDisplayCSS(evt) { + var attr = 'data-hide-' + evt.target.getAttribute('data-class'); + if (evt.target.checked) { + document.getElementById('main').setAttribute(attr, true); + } else { + document.getElementById('main').removeAttribute(attr); + } +} +function toast(text) { + var toast = document.getElementById('toast'); + toast.text = text; + toast.show(); +} +function showMessageDialog(title, text, positiveText, closeCallback) { + var dialog = document.createElement('loot-message-dialog'); + dialog.setButtonText(positiveText, l10n.jed.translate('Cancel').fetch()); + dialog.showModal(title, text, closeCallback); + document.body.appendChild(dialog); +} +function showMessageBox(title, text) { + var dialog = document.createElement('loot-message-dialog'); + dialog.setButtonText(l10n.jed.translate('OK').fetch()); + dialog.showModal(title, text); + document.body.appendChild(dialog); +} + +function showProgress(message) { + var progressDialog = document.getElementById('progressDialog'); + if (message) { + progressDialog.getElementsByTagName('p')[0].textContent = message; + } + if (!progressDialog.opened) { + progressDialog.showModal(); + } +} +function closeProgressDialog() { + var progressDialog = document.getElementById('progressDialog'); + if (progressDialog.opened) { + progressDialog.close(); + } +} +function handleUnappliedChangesClose(change) { + showMessageDialog('', l10n.jed.translate('You have not yet applied or cancelled your %s. Are you sure you want to quit?').fetch(change), l10n.jed.translate('Quit').fetch(), function(result){ + if (result) { + /* Cancel any sorting and close any editors. Cheat by sending a + cancelSort query for as many times as necessary. */ + var queries = []; + var numQueries = 0; + if (!document.getElementById('applySortButton').classList.contains('hidden')) { + numQueries += 1; + } + numQueries += document.body.getAttribute('data-editors'); + for (var i = 0; i < numQueries; ++i) { + queries.push(loot.query('cancelSort')); + } + Promise.all(queries).then(function(){ + window.close(); + }).catch(processCefError); + } + }); +} + diff --git a/resources/report/js/script.js b/resources/report/js/init.js similarity index 57% rename from resources/report/js/script.js rename to resources/report/js/init.js index c687991a..3047bb65 100644 --- a/resources/report/js/script.js +++ b/resources/report/js/init.js @@ -25,99 +25,6 @@ var marked; var l10n; -function processCefError(err) { - /* Error.stack seems to be Chromium-specific. It gives a lot more useful - info than just the error message. Also, this can be used to catch any - promise errors, not just CEF errors. */ - console.log(err.stack); - closeProgressDialog(); - showMessageBox(l10n.jed.translate('Error').fetch(), err.message); -} - -function showElement(element) { - if (element != null) { - element.classList.toggle('hidden', false); - } -} -function hideElement(element) { - if (element != null) { - element.classList.toggle('hidden', true); - } -} -function toggleDisplayCSS(evt) { - var attr = 'data-hide-' + evt.target.getAttribute('data-class'); - if (evt.target.checked) { - document.getElementById('main').setAttribute(attr, true); - } else { - document.getElementById('main').removeAttribute(attr); - } -} -function toast(text) { - var toast = document.getElementById('toast'); - toast.text = text; - toast.show(); -} -function showMessageDialog(title, text, positiveText, closeCallback) { - var dialog = document.createElement('loot-message-dialog'); - dialog.setButtonText(positiveText, l10n.jed.translate('Cancel').fetch()); - dialog.showModal(title, text, closeCallback); - document.body.appendChild(dialog); -} -function showMessageBox(title, text) { - var dialog = document.createElement('loot-message-dialog'); - dialog.setButtonText(l10n.jed.translate('OK').fetch()); - dialog.showModal(title, text); - document.body.appendChild(dialog); -} - -function showProgress(message) { - var progressDialog = document.getElementById('progressDialog'); - if (message) { - progressDialog.getElementsByTagName('p')[0].textContent = message; - } - if (!progressDialog.opened) { - progressDialog.showModal(); - } -} -function closeProgressDialog() { - var progressDialog = document.getElementById('progressDialog'); - if (progressDialog.opened) { - progressDialog.close(); - } -} -function areSettingsValid() { - /* Validate inputs individually. */ - var inputs = document.getElementById('settingsDialog').getElementsByTagName('input'); - for (var i = 0; i < inputs.length; ++i) { - if (!inputs[i].checkValidity()) { - return false; - console.log(inputs[i]); - } - } - return true; -} - -function handleUnappliedChangesClose(change) { - showMessageDialog('', l10n.jed.translate('You have not yet applied or cancelled your %s. Are you sure you want to quit?').fetch(change), l10n.jed.translate('Quit').fetch(), function(result){ - if (result) { - /* Cancel any sorting and close any editors. Cheat by sending a - cancelSort query for as many times as necessary. */ - var queries = []; - var numQueries = 0; - if (!document.getElementById('applySortButton').classList.contains('hidden')) { - numQueries += 1; - } - numQueries += document.body.getAttribute('data-editors'); - for (var i = 0; i < numQueries; ++i) { - queries.push(loot.query('cancelSort')); - } - Promise.all(queries).then(function(){ - window.close(); - }).catch(processCefError); - } - }); -} - function initVars() { loot.query('getVersion').then(function(result){ try { @@ -267,79 +174,12 @@ function initVars() { }).catch(processCefError); }).catch(processCefError); } -function onContentRefresh(evt) { - /* Send a query for updated load order and plugin header info. */ - showProgress(l10n.jed.translate('Refreshing data...').fetch()); - loot.query('getGameData').then(function(result){ - /* Parse the data sent from C++. */ - try { - /* We don't want the plugin info creating cards, so don't convert - to plugin objects. */ - var gameInfo = JSON.parse(result); - } catch (e) { - console.log(e); - console.log('getGameData response: ' + result); - } - - /* Now overwrite plugin data with the newly sent data. Also update - card and li vars as they were unset when the game was switched - from before. */ - var pluginNames = []; - gameInfo.plugins.forEach(function(plugin){ - var foundPlugin = false; - for (var i = 0; i < loot.game.plugins.length; ++i) { - if (loot.game.plugins[i].name == plugin.name) { - - loot.game.plugins[i].isActive = plugin.isActive; - loot.game.plugins[i].isEmpty = plugin.isEmpty; - loot.game.plugins[i].loadsBSA = plugin.loadsBSA; - loot.game.plugins[i].crc = plugin.crc; - loot.game.plugins[i].version = plugin.version; - - loot.game.plugins[i].modPriority = plugin.modPriority; - loot.game.plugins[i].isGlobalPriority = plugin.isGlobalPriority; - loot.game.plugins[i].messages = plugin.messages; - loot.game.plugins[i].tags = plugin.tags; - loot.game.plugins[i].isDirty = plugin.isDirty; - - foundPlugin = true; - break; - } - } - if (!foundPlugin) { - /* A new plugin. */ - loot.game.plugins.push(new Plugin(plugin)); - } - pluginNames.push(plugin.name); - }); - for (var i = 0; i < loot.game.plugins.length;) { - var foundPlugin = false; - for (var j = 0; j < pluginNames.length; ++j) { - if (loot.game.plugins[i].name == pluginNames[j]) { - foundPlugin = true; - break; - } - } - if (!foundPlugin) { - /* Remove plugin. */ - loot.game.plugins.splice(i, 1); - } else { - ++i; - } - } - - /* Reapply filters. */ - setFilteredUIData(); - - closeProgressDialog(); - }).catch(processCefError); -} 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/loot', 'js/filters', 'js/events.js'], function(markedResponse, l10nResponse) { + require(['bower_components/marked/lib/marked', 'js/l10n', 'js/plugin', 'js/helpers', 'js/loot', 'js/filters', 'js/events'], function(markedResponse, l10nResponse) { /* Register object observers. */ Object.observe(loot, loot.observer); diff --git a/resources/report/report.html b/resources/report/report.html index 49b11d99..a05ff08e 100644 --- a/resources/report/report.html +++ b/resources/report/report.html @@ -298,5 +298,5 @@

LOOT is free, but if you want to show your appreciation with some money, donations may be made to WrinklyNinja (LOOT's creator and main developer) using PayPal, Bitcoin or Flattr.

OK - + From 484dfb82e71b3aa419de35b904c4b67569959eb4 Mon Sep 17 00:00:00 2001 From: Oliver Hamlet Date: Thu, 15 Jan 2015 11:26:20 +0000 Subject: [PATCH 5/7] Moved another event function. --- resources/report/js/events.js | 10 ++++++++-- resources/report/js/helpers.js | 8 -------- 2 files changed, 8 insertions(+), 10 deletions(-) diff --git a/resources/report/js/events.js b/resources/report/js/events.js index 6cae4031..76f8ee7c 100644 --- a/resources/report/js/events.js +++ b/resources/report/js/events.js @@ -1,3 +1,11 @@ +function toggleDisplayCSS(evt) { + var attr = 'data-hide-' + evt.target.getAttribute('data-class'); + if (evt.target.checked) { + document.getElementById('main').setAttribute(attr, true); + } else { + document.getElementById('main').removeAttribute(attr); + } +} function openLogLocation(evt) { loot.query('openLogLocation').catch(processCefError); } @@ -297,7 +305,6 @@ function switchSidebarTab(evt) { document.getElementById(evt.target.selected).parentElement.selected = evt.target.selected; } } - function showAboutDialog(evt) { document.getElementById('about').showModal(); } @@ -353,7 +360,6 @@ function closeSettingsDialog(evt) { } evt.target.parentElement.close(); } - function showSettingsDialog(evt) { document.getElementById('settingsDialog').showModal(); } diff --git a/resources/report/js/helpers.js b/resources/report/js/helpers.js index fd419402..d5231983 100644 --- a/resources/report/js/helpers.js +++ b/resources/report/js/helpers.js @@ -17,14 +17,6 @@ function hideElement(element) { element.classList.toggle('hidden', true); } } -function toggleDisplayCSS(evt) { - var attr = 'data-hide-' + evt.target.getAttribute('data-class'); - if (evt.target.checked) { - document.getElementById('main').setAttribute(attr, true); - } else { - document.getElementById('main').removeAttribute(attr); - } -} function toast(text) { var toast = document.getElementById('toast'); toast.text = text; From 3a0014c935a175947c28931eacce6be89359b47d Mon Sep 17 00:00:00 2001 From: Oliver Hamlet Date: Thu, 15 Jan 2015 11:46:05 +0000 Subject: [PATCH 6/7] Updated packaging scripts for new JS files. --- src/archive.py | 7 +++++-- src/installer.nsi | 14 ++++++++++---- 2 files changed, 15 insertions(+), 6 deletions(-) diff --git a/src/archive.py b/src/archive.py index 7400f310..fe3dfd67 100644 --- a/src/archive.py +++ b/src/archive.py @@ -141,9 +141,12 @@ def createAppArchive(archive_path): shutil.copy( os.path.join('..', 'resources', 'report', 'bower_components', 'Jed', 'jed.js'), os.path.join(temp_path, 'resources', 'report', 'bower_components', 'Jed') ) shutil.copy( os.path.join('..', 'resources', 'report', 'bower_components', 'jed-gettext-parser', 'jedGettextParser.js'), os.path.join(temp_path, 'resources', 'report', 'bower_components', 'jed-gettext-parser') ) shutil.copytree( os.path.join('..', 'resources', 'report', 'fonts'), os.path.join(temp_path, 'resources', 'report', 'fonts') ) - shutil.copy( os.path.join('..', 'resources', 'report', 'js', 'l10n.js'), os.path.join(temp_path, 'resources', 'report', 'js') ) - shutil.copy( os.path.join('..', 'resources', 'report', 'js', 'plugin.js'), os.path.join(temp_path, 'resources', 'report', 'js') ) + shutil.copy( os.path.join('..', 'resources', 'report', 'js', 'events.js'), os.path.join(temp_path, 'resources', 'report', 'js') ) shutil.copy( os.path.join('..', 'resources', 'report', 'js', 'filters.js'), os.path.join(temp_path, 'resources', 'report', 'js') ) + shutil.copy( os.path.join('..', 'resources', 'report', 'js', 'helpers.js'), os.path.join(temp_path, 'resources', 'report', 'js') ) + shutil.copy( os.path.join('..', 'resources', 'report', 'js', 'l10n.js'), os.path.join(temp_path, 'resources', 'report', 'js') ) + shutil.copy( os.path.join('..', 'resources', 'report', 'js', 'loot.js'), os.path.join(temp_path, 'resources', 'report', 'js') ) + shutil.copy( os.path.join('..', 'resources', 'report', 'js', 'plugin.js'), os.path.join(temp_path, 'resources', 'report', 'js') ) # Docs. shutil.copytree( os.path.join('..', 'docs', 'images'), os.path.join(temp_path, 'docs', 'images') ) diff --git a/src/installer.nsi b/src/installer.nsi index d6de37d0..1a25f7b5 100644 --- a/src/installer.nsi +++ b/src/installer.nsi @@ -348,9 +348,12 @@ FunctionEnd SetOutPath "$INSTDIR\resources\report\fonts" File "..\resources\report\fonts\*" SetOutPath "$INSTDIR\resources\report\js" - File "..\resources\report\js\l10n.js" - File "..\resources\report\js\plugin.js" + File "..\resources\report\js\events.js" File "..\resources\report\js\filters.js" + File "..\resources\report\js\helpers.js" + File "..\resources\report\js\l10n.js" + File "..\resources\report\js\loot.js" + File "..\resources\report\js\plugin.js" ;Install documentation images. SetOutPath "$INSTDIR\docs\images" @@ -508,9 +511,12 @@ FunctionEnd Delete "$INSTDIR\resources\report\bower_components\Jed\jed.js" Delete "$INSTDIR\resources\report\bower_components\jed-gettext-parser\jedGettextParser.js" RMDir /r "$INSTDIR\resources\report\fonts" - Delete "$INSTDIR\resources\report\js\l10n.js" - Delete "$INSTDIR\resources\report\js\plugin.js" + Delete "$INSTDIR\resources\report\js\events.js" Delete "$INSTDIR\resources\report\js\filters.js" + Delete "$INSTDIR\resources\report\js\helpers.js" + Delete "$INSTDIR\resources\report\js\l10n.js" + Delete "$INSTDIR\resources\report\js\loot.js" + Delete "$INSTDIR\resources\report\js\plugin.js" RMDir /r "$INSTDIR\resources\report" ;Remove language files. From 3e86aa2bb4b9b2a5a4d6febaf384f9f73915e04a Mon Sep 17 00:00:00 2001 From: Oliver Hamlet Date: Thu, 15 Jan 2015 12:16:11 +0000 Subject: [PATCH 7/7] Use uniform on* naming for JS event handling. --- resources/report/html/editable-table.html | 28 +++--- resources/report/html/loot-plugin-item.html | 2 +- resources/report/js/events.js | 106 ++++++++++---------- resources/report/js/filters.js | 2 +- resources/report/js/loot.js | 6 +- 5 files changed, 72 insertions(+), 72 deletions(-) diff --git a/resources/report/html/editable-table.html b/resources/report/html/editable-table.html index 11e453fb..40517fc7 100644 --- a/resources/report/html/editable-table.html +++ b/resources/report/html/editable-table.html @@ -148,7 +148,7 @@ html /deep/ table[is=editable-table] paper-icon-button[icon=add]:hover { /* Create a element type that extends from . */ var EditableTableProto = Object.create(HTMLTableElement.prototype, { - handleDrop: { + onDrop: { value: function(evt) { evt.stopPropagation(); @@ -163,7 +163,7 @@ html /deep/ table[is=editable-table] paper-icon-button[icon=add]:hover { } }, - handleDragOver: { + onDragOver: { value: function(evt) { evt.preventDefault(); evt.dataTransfer.dropEffect = 'copy'; @@ -234,21 +234,21 @@ html /deep/ table[is=editable-table] paper-icon-button[icon=add]:hover { } }, - removeRow: { + onRemoveRow: { value: function(evt) { var tr = evt.target.parentElement.parentElement.parentElement; var tbody = tr.parentElement; var table = tbody.parentElement; /* Remove deletion listener. */ - evt.target.removeEventListener('click', table.removeRow, false); + evt.target.removeEventListener('click', table.onRemoveRow, false); /* Now remove row. */ tbody.removeChild(tr); } }, - addEmptyRow: { + onAddEmptyRow: { value: function(evt) { /* Create new row. */ var table = evt.currentTarget.parentElement.parentElement.parentElement.parentElement.parentElement; @@ -264,7 +264,7 @@ html /deep/ table[is=editable-table] paper-icon-button[icon=add]:hover { table.tBodies[0].insertBefore(row, table.tBodies[0].lastElementChild); /* Add deletion listener. */ - table.tBodies[0].lastElementChild.previousElementSibling.getElementsByClassName('delete')[0].addEventListener('click', table.removeRow, false); + table.tBodies[0].lastElementChild.previousElementSibling.getElementsByClassName('delete')[0].addEventListener('click', table.onRemoveRow, false); } }, @@ -292,7 +292,7 @@ html /deep/ table[is=editable-table] paper-icon-button[icon=add]:hover { } /* Add deletion listener. */ - row.getElementsByClassName('delete')[0].addEventListener('click', this.removeRow, false); + row.getElementsByClassName('delete')[0].addEventListener('click', this.onRemoveRow, false); return row; } @@ -312,14 +312,14 @@ html /deep/ table[is=editable-table] paper-icon-button[icon=add]:hover { row = this.tBodies[0].lastElementChild; /* Add new row listener. */ - row.querySelector('paper-icon-button').addEventListener('click', this.addEmptyRow, false); + row.querySelector('paper-icon-button').addEventListener('click', this.onAddEmptyRow, false); /* Add drag 'n' drop listeners. Drag 'n' drop should only be enabled for file-row tables. */ if (this.getAttribute('data-template') == 'fileRow') { - this.addEventListener('drop', this.handleDrop, false); - this.addEventListener('dragover', this.handleDragOver, false); + this.addEventListener('drop', this.onDrop, false); + this.addEventListener('dragover', this.onDragOver, false); } } }, @@ -329,15 +329,15 @@ html /deep/ table[is=editable-table] paper-icon-button[icon=add]:hover { /* Remove deletion listener. */ var icons = this.tBodies[0].getElementsByClassName('delete'); for (var i = 0; i < icons.length; ++i) { - icons[i].removeEventListener('click', this.removeRow, false); + icons[i].removeEventListener('click', this.onRemoveRow, false); } /* Remove new row listener. */ - this.querySelector('tbody tr:last-child paper-icon-button').removeEventListener('click', this.addEmptyRow, false); + this.querySelector('tbody tr:last-child paper-icon-button').removeEventListener('click', this.onAddEmptyRow, false); /* Remove drag 'n' drop listeners. */ - this.removeEventListener('drop', this.handleDrop, false); - this.removeEventListener('dragover', this.handleDragOver, false); + this.removeEventListener('drop', this.onDrop, false); + this.removeEventListener('dragover', this.onDragOver, false); } }, diff --git a/resources/report/html/loot-plugin-item.html b/resources/report/html/loot-plugin-item.html index c185f1bb..04ae8f95 100644 --- a/resources/report/html/loot-plugin-item.html +++ b/resources/report/html/loot-plugin-item.html @@ -149,7 +149,7 @@ return this.textContent.trim(); }, - handleDragStart: function(evt) { + onDragStart: function(evt) { evt.dataTransfer.effectAllowed = 'copy'; evt.dataTransfer.setData('text/plain', evt.currentTarget.getName()); }, diff --git a/resources/report/js/events.js b/resources/report/js/events.js index 76f8ee7c..f958aad8 100644 --- a/resources/report/js/events.js +++ b/resources/report/js/events.js @@ -1,4 +1,4 @@ -function toggleDisplayCSS(evt) { +function onToggleDisplayCSS(evt) { var attr = 'data-hide-' + evt.target.getAttribute('data-class'); if (evt.target.checked) { document.getElementById('main').setAttribute(attr, true); @@ -6,10 +6,10 @@ function toggleDisplayCSS(evt) { document.getElementById('main').removeAttribute(attr); } } -function openLogLocation(evt) { +function onOpenLogLocation(evt) { loot.query('openLogLocation').catch(processCefError); } -function changeGame(evt) { +function onChangeGame(evt) { /* Check that the selected game isn't the current one. */ if (evt.target.className.indexOf('core-selected') != -1) { return; @@ -59,7 +59,7 @@ function changeGame(evt) { closeProgressDialog(); }).catch(processCefError); } -function openReadme(evt) { +function onOpenReadme(evt) { loot.query('openReadme').catch(processCefError); } /* Masterlist update process, minus progress dialog. */ @@ -92,13 +92,13 @@ function updateMasterlistNoProgress() { } }).catch(processCefError); } -function updateMasterlist(evt) { +function onUpdateMasterlist(evt) { showProgress(l10n.jed.translate('Updating masterlist...').fetch()); updateMasterlistNoProgress().then(function(result){ closeProgressDialog(); }).catch(processCefError); } -function sortPlugins(evt) { +function onSortPlugins(evt) { var mlistUpdate; if (loot.settings.updateMasterlist) { mlistUpdate = updateMasterlistNoProgress(); @@ -159,7 +159,7 @@ function sortPlugins(evt) { }).catch(processCefError); }).catch(processCefError); } -function applySort(evt) { +function onApplySort(evt) { var loadOrder = []; loot.game.plugins.forEach(function(plugin){ loadOrder.push(plugin.name); @@ -186,7 +186,7 @@ function applySort(evt) { document.getElementById('gameMenu').removeAttribute('disabled'); }).catch(processCefError); } -function cancelSort(evt) { +function onCancelSort(evt) { return loot.query('cancelSort').then(function(){ /* Sort UI elements again according to stored old load order. */ loot.game.plugins = loot.game.oldLoadOrder; @@ -205,7 +205,7 @@ function cancelSort(evt) { document.getElementById('gameMenu').removeAttribute('disabled'); }).catch(processCefError); } -function redatePlugins(evt) { +function onRedatePlugins(evt) { if (evt.target.hasAttribute('disabled')) { return; } @@ -218,7 +218,7 @@ function redatePlugins(evt) { } }); } -function clearAllMetadata(evt) { +function onClearAllMetadata(evt) { showMessageDialog('', l10n.jed.translate('Are you sure you want to clear all existing user-added metadata from all plugins?').fetch(), l10n.jed.translate('Clear').fetch(), function(result){ if (result) { loot.query('clearAllMetadata').then(JSON.parse).then(function(result){ @@ -246,7 +246,7 @@ function clearAllMetadata(evt) { } }); } -function copyContent(evt) { +function onCopyContent(evt) { var messages = []; var plugins = []; @@ -300,12 +300,12 @@ function copyContent(evt) { toast(l10n.jed.translate("LOOT's content has been copied to the clipboard.").fetch()); }).catch(processCefError); } -function switchSidebarTab(evt) { +function onSwitchSidebarTab(evt) { if (evt.detail.isSelected) { document.getElementById(evt.target.selected).parentElement.selected = evt.target.selected; } } -function showAboutDialog(evt) { +function onShowAboutDialog(evt) { document.getElementById('about').showModal(); } function areSettingsValid() { @@ -319,7 +319,7 @@ function areSettingsValid() { } return true; } -function closeSettingsDialog(evt) { +function onCloseSettingsDialog(evt) { if (evt.target.classList.contains('accept')) { if (!areSettingsValid()) { return; @@ -360,20 +360,20 @@ function closeSettingsDialog(evt) { } evt.target.parentElement.close(); } -function showSettingsDialog(evt) { +function onShowSettingsDialog(evt) { document.getElementById('settingsDialog').showModal(); } -function focusSearch(evt) { +function onFocusSearch(evt) { if (evt.ctrlKey && evt.keyCode == 70) { //'f' document.getElementById('searchBox').focus(); } } -function handleEditorOpen(evt) { +function onEditorOpen(evt) { /* Set up drag 'n' drop event handlers. */ var elements = document.getElementById('cardsNav').getElementsByTagName('loot-plugin-item'); for (var i = 0; i < elements.length; ++i) { elements[i].draggable = true; - elements[i].addEventListener('dragstart', elements[i].handleDragStart, false); + elements[i].addEventListener('dragstart', elements[i].onDragStart, false); } /* Now show editor. */ @@ -404,7 +404,7 @@ function handleEditorOpen(evt) { return loot.query('editorOpened').catch(processCefError); } -function handleEditorClose(evt) { +function onEditorClose(evt) { /* evt.detail is true if the apply button was pressed. */ if (evt.detail) { /* Need to record the editor control values and work out what's @@ -444,7 +444,7 @@ function handleEditorClose(evt) { var elements = document.getElementById('cardsNav').getElementsByTagName('loot-plugin-item'); for (var i = 0; i < elements.length; ++i) { elements[i].removeAttribute('draggable'); - elements[i].removeEventListener('dragstart', elements[i].handleDragStart, false); + elements[i].removeEventListener('dragstart', elements[i].onDragStart, false); } /* Disable priority hover in plugins list and enable header @@ -469,7 +469,7 @@ function handleEditorClose(evt) { } document.getElementById('cardsNav').updateSize(); } -function handleConflictsFilter(evt) { +function onConflictsFilter(evt) { /* evt.detail is true if the filter has been activated. */ if (evt.detail) { /* Un-highlight any existing filter plugin. */ @@ -488,7 +488,7 @@ function handleConflictsFilter(evt) { } setFilteredUIData(evt); } -function handleCopyMetadata(evt) { +function onCopyMetadata(evt) { /* evt.detail is the name of the plugin. */ var request = JSON.stringify({ name: 'copyMetadata', @@ -501,7 +501,7 @@ function handleCopyMetadata(evt) { toast(l10n.jed.translate('The metadata for "%s" has been copied to the clipboard.').fetch(evt.target.getName())); }).catch(processCefError); } -function handleClearMetadata(evt) { +function onClearMetadata(evt) { showMessageDialog('', l10n.jed.translate('Are you sure you want to clear all existing user-added metadata from "%s"?').fetch(evt.target.getName()), l10n.jed.translate('Clear').fetch(), function(result){ if (result) { var request = JSON.stringify({ @@ -533,7 +533,7 @@ function handleClearMetadata(evt) { } }); } -function handleSidebarClick(evt) { +function onSidebarClick(evt) { if (evt.target.hasAttribute('data-index')) { document.getElementById('main').lastElementChild.scrollToItem(evt.target.getAttribute('data-index')); @@ -545,7 +545,7 @@ function handleSidebarClick(evt) { } } } -function handleQuit(evt) { +function onQuit(evt) { if (!document.getElementById('applySortButton').classList.contains('hidden')) { handleUnappliedChangesClose(l10n.jed.translate('sorted load order').fetch()); } else if (document.body.hasAttribute('data-editors')) { @@ -554,7 +554,7 @@ function handleQuit(evt) { window.close(); } } -function jumpToGeneralInfo(evt) { +function onJumpToGeneralInfo(evt) { window.location.hash = ''; document.getElementById('main').scrollTop = 0; } @@ -627,48 +627,48 @@ function onContentRefresh(evt) { } function setupEventHandlers() { /*Set up handlers for filters.*/ - document.getElementById('hideVersionNumbers').addEventListener('change', toggleDisplayCSS, false); - document.getElementById('hideCRCs').addEventListener('change', toggleDisplayCSS, false); - document.getElementById('hideBashTags').addEventListener('change', toggleDisplayCSS, false); + document.getElementById('hideVersionNumbers').addEventListener('change', onToggleDisplayCSS, false); + document.getElementById('hideCRCs').addEventListener('change', onToggleDisplayCSS, false); + document.getElementById('hideBashTags').addEventListener('change', onToggleDisplayCSS, false); document.getElementById('hideNotes').addEventListener('change', setFilteredUIData, false); document.getElementById('hideDoNotCleanMessages').addEventListener('change', setFilteredUIData, false); document.getElementById('hideInactivePlugins').addEventListener('change', setFilteredUIData, false); document.getElementById('hideAllPluginMessages').addEventListener('change', setFilteredUIData, false); document.getElementById('hideMessagelessPlugins').addEventListener('change', setFilteredUIData, false); - document.body.addEventListener('loot-filter-conflicts', handleConflictsFilter, false); + document.body.addEventListener('loot-filter-conflicts', onConflictsFilter, false); /* Set up event handlers for content filter. */ document.getElementById('searchBox').addEventListener('change', setFilteredUIData, false); - window.addEventListener('keyup', focusSearch, false); + window.addEventListener('keyup', onFocusSearch, false); /* Set up handlers for buttons. */ - document.getElementById('redatePluginsButton').addEventListener('click', redatePlugins, false); - document.getElementById('openLogButton').addEventListener('click', openLogLocation, false); - document.getElementById('wipeUserlistButton').addEventListener('click', clearAllMetadata, false); - document.getElementById('copyContentButton').addEventListener('click', copyContent, false); + document.getElementById('redatePluginsButton').addEventListener('click', onRedatePlugins, false); + document.getElementById('openLogButton').addEventListener('click', onOpenLogLocation, false); + document.getElementById('wipeUserlistButton').addEventListener('click', onClearAllMetadata, false); + document.getElementById('copyContentButton').addEventListener('click', onCopyContent, false); document.getElementById('refreshContentButton').addEventListener('click', onContentRefresh, false); - document.getElementById('settingsButton').addEventListener('click', showSettingsDialog, false); - document.getElementById('helpButton').addEventListener('click', openReadme, false); - document.getElementById('aboutButton').addEventListener('click', showAboutDialog, false); - document.getElementById('quitButton').addEventListener('click', handleQuit, false); - document.getElementById('updateMasterlistButton').addEventListener('click', updateMasterlist, false); - document.getElementById('sortButton').addEventListener('click', sortPlugins, false); - document.getElementById('applySortButton').addEventListener('click', applySort, false); - document.getElementById('cancelSortButton').addEventListener('click', cancelSort, false); - document.getElementById('sidebarTabs').addEventListener('core-select', switchSidebarTab, false); - document.getElementById('jumpToGeneralInfo').addEventListener('click', jumpToGeneralInfo, false); + document.getElementById('settingsButton').addEventListener('click', onShowSettingsDialog, false); + document.getElementById('helpButton').addEventListener('click', onOpenReadme, false); + document.getElementById('aboutButton').addEventListener('click', onShowAboutDialog, false); + document.getElementById('quitButton').addEventListener('click', onQuit, false); + document.getElementById('updateMasterlistButton').addEventListener('click', onUpdateMasterlist, false); + document.getElementById('sortButton').addEventListener('click', onSortPlugins, false); + document.getElementById('applySortButton').addEventListener('click', onApplySort, false); + document.getElementById('cancelSortButton').addEventListener('click', onCancelSort, false); + document.getElementById('sidebarTabs').addEventListener('core-select', onSwitchSidebarTab, false); + document.getElementById('jumpToGeneralInfo').addEventListener('click', onJumpToGeneralInfo, false); /* Set up event handlers for settings dialog. */ var settings = document.getElementById('settingsDialog'); - settings.getElementsByClassName('accept')[0].addEventListener('click', closeSettingsDialog, false); - settings.getElementsByClassName('cancel')[0].addEventListener('click', closeSettingsDialog, false); + settings.getElementsByClassName('accept')[0].addEventListener('click', onCloseSettingsDialog, false); + settings.getElementsByClassName('cancel')[0].addEventListener('click', onCloseSettingsDialog, false); /* Set up handler for opening and closing editors. */ - document.body.addEventListener('loot-editor-open', handleEditorOpen, false); - document.body.addEventListener('loot-editor-close', handleEditorClose, false); - document.body.addEventListener('loot-copy-metadata', handleCopyMetadata, false); - document.body.addEventListener('loot-clear-metadata', handleClearMetadata, false); + document.body.addEventListener('loot-editor-open', onEditorOpen, false); + document.body.addEventListener('loot-editor-close', onEditorClose, false); + document.body.addEventListener('loot-copy-metadata', onCopyMetadata, false); + document.body.addEventListener('loot-clear-metadata', onClearMetadata, false); - document.getElementById('cardsNav').addEventListener('click', handleSidebarClick, false); - document.getElementById('cardsNav').addEventListener('dblclick', handleSidebarClick, false); + document.getElementById('cardsNav').addEventListener('click', onSidebarClick, false); + document.getElementById('cardsNav').addEventListener('dblclick', onSidebarClick, false); } \ No newline at end of file diff --git a/resources/report/js/filters.js b/resources/report/js/filters.js index 8b9a756c..b2b1faf9 100644 --- a/resources/report/js/filters.js +++ b/resources/report/js/filters.js @@ -191,7 +191,7 @@ function getConflictingPluginsFromFilter() { return Promise.resolve([]); } -function setFilteredUIData(evt) { +function setFilteredUIData() { /* The conflict filter, if enabled, executes C++ code, so needs to be handled using a promise, so the rest of the function should wait until it is completed. diff --git a/resources/report/js/loot.js b/resources/report/js/loot.js index 830d0b59..183ce78a 100644 --- a/resources/report/js/loot.js +++ b/resources/report/js/loot.js @@ -113,10 +113,10 @@ var loot = { 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); + gameMenuItems[i].removeEventListener('click', onChangeGame, false); } else { gameMenuItems[i].removeAttribute('disabled'); - gameMenuItems[i].addEventListener('click', changeGame, false); + gameMenuItems[i].addEventListener('click', onChangeGame, false); } } }, @@ -132,7 +132,7 @@ var loot = { gameSelect.removeChild(gameSelect.lastElementChild); } while (gameMenu.firstElementChild) { - gameMenu.firstElementChild.removeEventListener('click', changeGame, false); + gameMenu.firstElementChild.removeEventListener('click', onChangeGame, false); gameMenu.removeChild(gameMenu.firstElementChild); } gameTable.clear();