Merge branch 'polymer-0.5' into dev

This commit is contained in:
Oliver Hamlet
2014-11-15 15:19:07 +00:00
18 changed files with 1424 additions and 1326 deletions
+18 -14
View File
@@ -13,21 +13,25 @@
"tests"
],
"dependencies": {
"polymer": "Polymer/polymer#~0.4.2",
"paper-icon-button": "Polymer/paper-icon-button#~0.4.2",
"paper-dropdown-menu": "Polymer/paper-dropdown-menu#~0.4.2",
"core-toolbar": "Polymer/core-toolbar#~0.4.2",
"core-icons": "Polymer/core-icons#~0.4.2",
"core-tooltip": "Polymer/core-tooltip#~0.4.2",
"core-drawer-panel": "Polymer/core-drawer-panel#~0.4.2",
"paper-input": "Polymer/paper-input#~0.4.2",
"paper-tabs": "Polymer/paper-tabs#~0.4.2",
"core-menu": "Polymer/core-menu#~0.4.2",
"paper-checkbox": "Polymer/paper-checkbox#~0.4.2",
"paper-dialog": "Polymer/paper-dialog#~0.4.2",
"paper-menu-button": "Polymer/paper-menu-button#~0.4.2",
"polymer": "Polymer/polymer#~0.5.0",
"paper-icon-button": "Polymer/paper-icon-button#~0.5.0",
"paper-dropdown-menu": "Polymer/paper-dropdown-menu#~0.5.0",
"core-toolbar": "Polymer/core-toolbar#~0.5.0",
"core-icons": "Polymer/core-icons#~0.5.0",
"core-tooltip": "Polymer/core-tooltip#~0.5.0",
"core-drawer-panel": "Polymer/core-drawer-panel#~0.5.0",
"paper-input": "Polymer/paper-input#~0.5.0",
"paper-tabs": "Polymer/paper-tabs#~0.5.0",
"core-menu": "Polymer/core-menu#~0.5.0",
"paper-checkbox": "Polymer/paper-checkbox#~0.5.0",
"paper-dialog": "Polymer/paper-dialog#~0.5.0",
"paper-menu-button": "Polymer/paper-menu-button#~0.5.0",
"Jed": "SlexAxton/Jed#a9d03e1bbca9211a8b29a93a298a7ee9ddb353f0",
"marked": "chjj/marked#~0.3.2",
"requirejs": "jrburke/requirejs-bower#~2.1.15"
"requirejs": "jrburke/requirejs-bower#~2.1.15",
"paper-progress": "Polymer/paper-progress#~0.5.0",
"core-animated-pages": "Polymer/core-animated-pages#~0.5.1",
"paper-toast": "Polymer/paper-toast#~0.5.1",
"core-list": "Polymer/core-list#~0.5.1"
}
}
+57 -22
View File
@@ -1,22 +1,25 @@
/* These styles override Polymer's own internal styling for certain elements. */
/* The following 3 rules are for setting the sizes of the drawer and panel. */
#container::shadow #main {
left: 33% !important;
}
#container::shadow .narrow-layout #main {
left: 0 !important;
}
#container::shadow #drawer {
width: 33% !important;
/* The following is for setting the size of the drawer in narrow mode. */
#container::shadow .narrow-layout #drawer {
width: 50% !important;
background: #f8f8f8;
}
/* These overrides change the colour of the game menu's text and underline. */
#gameMenu::shadow #control {
color: white;
#gameMenu::shadow > paper-dropdown-menu {
border-bottom-color: #f1f1f1;
}
#gameMenu::shadow #menu {
#gameMenu[disabled]::shadow > paper-dropdown-menu {
border-bottom-color: #c9c9c9;
}
#gameMenu::shadow > paper-dropdown-menu::shadow #label, #gameMenu::shadow > paper-dropdown-menu::shadow #arrow {
color: white;
}
#gameMenu[disabled]::shadow > paper-dropdown-menu::shadow #label, #gameMenu[disabled]::shadow > paper-dropdown-menu::shadow #arrow {
color: #c9c9c9;
}
#gameMenu {
color: black;
}
@@ -43,16 +46,6 @@ html /deep/ paper-tab::shadow #ink {
color: #4285f4;
}
/* This override change the font size of the sidebar items to be the body text size. */
#cardsNav /deep/ #label {
font-size: 10pt;
}
/* This override change the position of the link in <loot-plugin-item> so that it doesn't cover up tooltips. */
loot-plugin-item::shadow ::content > a {
left: 112px;
}
/* This override change the positioning of the progress dialog to adapt to content changes. */
#progressDialog {
position: inherit !important;
@@ -61,4 +54,46 @@ loot-plugin-item::shadow ::content > a {
left: 0;
bottom: 0;
right: 0;
}
/* This stops transitions from overflowing onto other elements. */
html /deep/ core-animated-pages {
overflow: hidden;
}
/* This stops menus keeping the last item clicked highlighted. */
paper-item.core-selected {
background: inherit;
}
/* This styles divs like core-menus. */
html /deep/ paper-dropdown > div {
margin: 12px;
}
/* This stops the main core-list having its own scrollbars. */
#main > core-list {
overflow-y: initial !important;
}
/* This makes paper-menu-button icons align like paper-icon-buttons do. */
html /deep/ paper-menu-button > paper-icon-button,
html /deep/ core-tooltip > paper-icon-button,
html /deep/ core-tooltip > core-icon {
display: block;
}
/* Center paper-dropdown-menu text better. */
html /deep/ paper-dropdown-menu {
padding-top: 0;
}
/* This adds padding between icons and text in menus. */
html /deep/ paper-item > core-icon {
margin-right: 1em;
}
/* This makes checkboxes have the same padding as icons in lists. */
html /deep/ paper-checkbox::shadow #checkboxLabel {
padding-left: 1em;
}
+42 -114
View File
@@ -30,46 +30,44 @@ body {
background:#f8f8f8;
height: 100%;
}
noscript {
background:#c00;
display:block;
padding:10px 5px;
color:white;
}
#mainToolbar {
background: #4285f4;
/*font-size: 1em;
height: 3em;*/
color: white;
color: white;
}
/*#mainToolbar > * {
top: -1em;
}*/
#gameMenu {
background: inherit;
}
#filtersToggle > span {
margin-right: 1em;
#mainToolbar paper-dropdown {
color: black;
}
div[drawer] > core-tooltip {
width: 100%;
margin: 0 12px;
}
#searchBox {
width: calc(100% - 24px);
div[drawer] {
z-index: 1;
}
#main {
overflow: auto;
overflow-y: auto;
overflow-x: hidden;
position: relative;
z-index: 0;
}
#cardsNav {
margin: 0;
overflow: auto;
}
#cardsNav > paper-item, #cardsNav > loot-plugin-item {
height: 2em;
/*height: 2em;*/
}
paper-item > a {
text-decoration: none;
color: black;
position: absolute;
top: 0;
bottom: 0;
left: 0;
right: 0;
}
#searchBox {
display: block;
}
#container {
position: fixed;
@@ -90,33 +88,9 @@ section {
border-bottom-left-radius: 2px;
box-shadow: rgba(0, 0, 0, 0.0980392) 0px 2px 4px, rgba(0, 0, 0, 0.0980392) 0px 0px 3px;
}
dialog {
border: 1px solid rgba(0, 0, 0, 0.3);
border-radius: 6px;
box-shadow: 0 3px 7px rgba(0, 0, 0, 0.3);
overflow:hidden;
padding: 2em;
top: 3em;
max-width: 40em;
max-height: calc(100% - 8em);
overflow: auto;
#generalMessages {
margin-bottom: 0.5em;
}
dialog > h1 {
font-weight: normal;
text-align: center;
}
dialog[data-type=warn] > span:first-child {
color: gold;
}
dialog button {
margin: 0.5em;
}
#about blockquote {
white-space: pre;
@@ -153,11 +127,6 @@ section h1 {
text-align:left;
padding-left:0;
}
input[type='checkbox'] {
position:relative;
top:0.15em;
margin-left:0.5em;
}
ul {
margin-top:0.5em;
margin-bottom:0;
@@ -206,10 +175,6 @@ li.warn{
paper-checkbox {
padding: 0.5em 1em;
}
loot-dropdown-menu {
padding-left: 2em;
top: -0.25em;
}
input[readonly] {
border: none;
@@ -220,24 +185,10 @@ td input {
text-overflow: ellipsis;
}
body.editMode header {
color: #999;
}
body.editMode header #headerOverlay {
z-index: 3;
width: 100%;
height: 100%;
position: absolute;
top: 0;
left: 0;
}
[draggable] {
-webkit-user-select: none;
cursor: move;
}
.highlight {
outline: 3px solid #69aaff;
}
#applySortButton {
box-shadow: none;
outline: none;
@@ -252,53 +203,30 @@ input:valid {
background-color: white;
color: black;
}
#hoverText {
position: fixed;
z-index: 5;
background: white;
box-shadow:0 0 3px 0px rgba(0,0,0,0.5);
padding: 2px 5px;
paper-progress {
width: 100%;
}
progress, .progress {
/* Reset the default appearance */
-webkit-appearance: none;
width: 250px;
height: 20px;
display: block;
margin: 0 auto;
}
#progressDialog > h1 {
font-size: 1.5em;
}
@-webkit-keyframes indeterminate {
0% { width: 0% }
100% { width: 100% }
}
progress::-webkit-progress-bar, .progress.bar {
background-color: #eee;
border-radius: 2px;
box-shadow: 0 2px 5px rgba(0, 0, 0, 0.25) inset;
}
progress::-webkit-progress-value, .progress .value {
height: 100%;
background-color: green;
-webkit-animation: indeterminate 2s linear 0 infinite alternate paused;
}
.progress.running > .value {
-webkit-animation-play-state: running;
}
:host > span {
display: inline-block;
width: 1.2em;
}
#firstRun > ul {
list-style-type: disc;
padding-left: 40px;
}
#firstRun .tag {
margin: 0;
}
/* This animates the drawer toggle appearing in narrow view. */
#drawerToggle {
opacity: 0;
visibility: hidden;
transition: opacity 0.5s;
}
@media screen and (max-width: 640px) {
#drawerToggle {
opacity: 1;
visibility: visible;
}
}
#settingsDialog > paper-checkbox {
display: block;
}
+47 -67
View File
@@ -1,76 +1,83 @@
<link rel="import" href="../bower_components/polymer/polymer.html">
<link rel="import" href="../bower_components/paper-input/paper-input.html">
<link rel="import" href="../bower_components/paper-item/paper-item.html">
<link rel="import" href="../bower_components/paper-icon-button/paper-icon-button.html">
<link rel="import" href="../bower_components/core-icons/core-icons.html">
<link rel="import" href="loot-dropdown-menu.html">
<link rel="import" href="loot-validated-input.html">
<template id="fileRow">
<tr>
<td><input class="name" type="text" required></td>
<td><input class="display" type="text"></td>
<td><input class="condition" type="text"></td>
<td><loot-validated-input error="A filename is required." class="name" required></loot-validated-input></td>
<td><paper-input class="display"></paper-input></td>
<td><paper-input class="condition"></paper-input></td>
<td><paper-icon-button class="delete" icon="delete"></paper-icon-button></td>
</tr>
</template>
<template id="messageRow">
<tr>
<td><select class="type">
<option value="say">Note</option>
<option value="warn">Warning</option>
<option value="error">Error</option>
</select>
<td>
<loot-dropdown-menu class="type" valueattr="value">
<paper-item value="say">Note</paper-item>
<paper-item value="warn">Warning</paper-item>
<paper-item value="error">Error</paper-item>
</loot-dropdown-menu>
</td>
<td><input class="content" type="text" required></td>
<td><input class="condition" type="text"></td>
<td><select class="language">
<td><loot-validated-input error="A content string is required." class="content" required></loot-validated-input></td>
<td><paper-input class="condition"></paper-input></td>
<td>
<loot-dropdown-menu class="language" valueattr="value">
<!-- Language <option> elements go here. -->
</select>
</loot-dropdown-menu>
</td>
<td><paper-icon-button class="delete" icon="delete"></paper-icon-button></td>
</tr>
</template>
<template id="tagRow">
<tr>
<td><select class="type">
<option value="add">Add</option>
<option value="remove">Remove</option>
</select>
<td>
<loot-dropdown-menu class="type" valueattr="value">
<paper-item value="add">Add</paper-item>
<paper-item value="remove">Remove</paper-item>
</loot-dropdown-menu>
</td>
<td><input class="name" type="text" required></td>
<td><input class="condition" type="text"></td>
<td><loot-validated-input error="A name is required." class="name" required></loot-validated-input></td>
<td><paper-input class="condition"></paper-input></td>
<td><paper-icon-button class="delete" icon="delete"></paper-icon-button></td>
</tr>
</template>
<template id="dirtyInfoRow">
<tr>
<td><input class="crc" type="text" maxlength="8" minlength="8" pattern="[0-9A-Fa-f]{8}" required></td>
<td><input class="itm" type="number" min="0" step="1" value="0"></td>
<td><input class="udr" type="number" min="0" step="1" value="0"></td>
<td><input class="nav" type="number" min="0" step="1" value="0"></td>
<td><input class="util" type="text" required></td>
<td><loot-validated-input error="A CRC is required." class="crc" maxlength="8" minlength="8" pattern="[0-9A-Fa-f]{8}" required></loot-validated-input></td>
<td><loot-validated-input error="Values must be integers." class="itm" type="number" min="0" step="1" value="0"></loot-validated-input></td>
<td><loot-validated-input error="Values must be integers." class="udr" type="number" min="0" step="1" value="0"></loot-validated-input></td>
<td><loot-validated-input error="Values must be integers." class="nav" type="number" min="0" step="1" value="0"></loot-validated-input></td>
<td><loot-validated-input error="A utility name is required." class="util" required></loot-validated-input></td>
<td><paper-icon-button class="delete" icon="delete"></paper-icon-button></td>
</tr>
</template>
<template id="locationRow">
<tr>
<td><input class="link" type="text" required></td>
<td><input class="ver" type="text"></td>
<td><loot-validated-input error="A link is required." class="link" required></loot-validated-input></td>
<td><paper-input class="ver"></paper-input></td>
<td><paper-icon-button class="delete" icon="delete"></paper-icon-button></td>
</tr>
</template>
<template id="gameRow">
<tr>
<td><input class="name" type="text" required></td>
<td><loot-validated-input error="A name is required." class="name" required></loot-validated-input></td>
<td>
<select class="type">
<!-- Game <option> elements go here. -->
</select>
<loot-dropdown-menu class="type" valueattr="value">
<!-- Game <option> elements go here. -->
</loot-dropdown-menu>
</td>
<td><input class="folder" type="text" required></td>
<td><input class="master" type="text"></td>
<td><input class="repo" type="text"></td>
<td><input class="branch" type="text"></td>
<td><input class="path" type="text"></td>
<td><input class="registry" type="text"></td>
<td><loot-validated-input error="A folder is required." class="folder" required></loot-validated-input></td>
<td><paper-input class="master"></paper-input></td>
<td><paper-input class="repo"></paper-input></td>
<td><paper-input class="branch"></paper-input></td>
<td><paper-input class="path"></paper-input></td>
<td><paper-input class="registry"></paper-input></td>
<td><paper-icon-button class="delete" icon="delete"></paper-icon-button></td>
</tr>
</template>
@@ -136,23 +143,18 @@ td paper-icon-button.hidden {
getRowsData: {
value: function(writableOnly) {
var writableRows = [];
var rows = this.tBodies[0].rows[0];
var rows = this.tBodies[0].rows;
for (var i = 0; i < rows.length; ++i) {
var trash = rows[i].getElementsByClassName('delete');
if (trash.length > 0 && (!writableOnly || !trash[0].classList.contains('hidden'))) {
var rowData = {};
var inputs = rows[i].querySelectorAll('input, paper-input');
var inputs = rows[i].querySelectorAll('paper-input, loot-validated-input, loot-dropdown-menu');
for (var j = 0; j < inputs.length; ++j) {
rowData[inputs[j].className] = inputs[j].value;
}
var selects = rows[i].getElementsByTagName('select');
for (var j = 0; j < selects.length; ++j) {
rowData[selects[j].className] = selects[j].value;
}
writableRows.push(rowData);
}
}
@@ -176,39 +178,17 @@ td paper-icon-button.hidden {
trash.classList.toggle('hidden', readOnly);
}
var inputs = row.querySelectorAll('input, paper-input');
var inputs = row.querySelectorAll('paper-input, loot-validated-input, loot-dropdown-menu');
for (var i = 0; i < inputs.length; ++i) {
if (classMask) {
for (var j = 0; j < classMask.length; ++j) {
if (inputs[i].classList.contains(classMask[j])) {
if (inputs[i].tagName == 'PAPER-INPUT') {
inputs[i].readonly = readOnly;
} else {
inputs[i].readOnly = readOnly;
}
inputs[i].disabled = readOnly;
break;
}
}
} else {
if (inputs[i].tagName == 'PAPER-INPUT') {
inputs[i].disabled = readOnly;
} else {
inputs[i].readOnly = readOnly;
}
}
}
var selects = row.getElementsByTagName('select');
for (var i = 0; i < selects.length; ++i) {
if (classMask) {
for (var j = 0; j < classMask.length; ++j) {
if (selects[i].classList.contains(classMask[j])) {
selects[i].disabled = readOnly;
break;
}
}
} else {
selects[i].disabled = readOnly;
inputs[i].disabled = readOnly;
}
}
}
+8 -18
View File
@@ -9,35 +9,25 @@ Still missing compared to <dialog> are:
-->
<link rel="import" href="../bower_components/polymer/polymer.html">
<link rel="import" href="../bower_components/paper-dialog/paper-dialog.html">
<link rel="import" href="../bower_components/paper-dialog/paper-action-dialog.html">
<polymer-element name="loot-dialog" extends="paper-dialog" attributes="open" transition="core-transition-center" autoCloseDisabled backdrop>
<polymer-element name="loot-dialog" extends="paper-action-dialog" transition="core-transition-center" layered="false">
<script>
Polymer({
open: false,
openedChanged: function(oldValue, newValue) {
this.open = newValue;
},
openChanged: function(oldValue, newValue) {
this.opened = newValue;
},
show: function() {
this.backdrop = false;
this.opened = true;
this.layered = false;
this.autoCloseDisabled = false;
this.setAttribute(opened, true);
},
showModal: function() {
this.backdrop = true;
this.opened = true;
// The layered attribute seems to cause the dialog to be destroyed for some reason, so don't use it. It doesn't seem to be necessary anyway.
this.layered = false;
this.autoCloseDisabled = true;
this.open();
this.setAttribute('opened', true);
},
close: function(retVal) {
this.setAttribute('returnValue', retVal);
this.opened = false;
this.super();
},
});
</script>
+22 -7
View File
@@ -8,26 +8,41 @@ it a <select>-like API. This means:
-->
<link rel="import" href="../bower_components/polymer/polymer.html">
<link rel="import" href="../bower_components/paper-dropdown/paper-dropdown.html">
<link rel="import" href="../bower_components/paper-dropdown-menu/paper-dropdown-menu.html">
<link rel="import" href="../bower_components/core-menu/core-menu.html">
<polymer-element name="loot-dropdown-menu" extends="paper-dropdown-menu">
<polymer-element name="loot-dropdown-menu">
<template>
<shadow></shadow>
<paper-dropdown-menu disabled="{{disabled}}">
<paper-dropdown class="dropdown">
<core-menu valueattr="value">
<content></content>
</core-menu>
</paper-dropdown>
</paper-dropdown-menu>
</template>
<script>
Polymer({
value: undefined,
disabled: false,
ready: function() {
this.valueattr = 'value';
attached: function() {
this.shadowRoot.firstElementChild.lastElementChild.firstElementChild.addEventListener('core-select', this.onItemSelect, false);
},
selectedChanged: function(oldValue, newValue) {
this.value = newValue;
detached: function() {
this.shadowRoot.firstElementChild.lastElementChild.firstElementChild.removeEventListener('core-select', this.onItemSelect, false);
},
onItemSelect: function(evt) {
if (evt.detail.isSelected) {
evt.currentTarget.parentElement.parentElement.parentNode.host.value = evt.currentTarget.selected;
}
},
valueChanged: function(oldValue, newValue) {
this.selected = newValue;
this.shadowRoot.firstElementChild.lastElementChild.firstElementChild.selected = newValue;
},
});
</script>
@@ -13,6 +13,7 @@ was pressed.
-->
<link rel="import" href="../bower_components/polymer/polymer.html">
<link rel="import" href="../bower_components/paper-button/paper-button.html">
<link rel="import" href="loot-dialog.html">
<polymer-element name="loot-message-dialog" extends="loot-dialog">
@@ -50,15 +51,15 @@ was pressed.
showModal: function(title, text, closeCallback) {
this.heading = title;
this.querySelector('#message').textContent = text;
this.querySelector('.message').textContent = text;
this.closeCallback = closeCallback;
this.super();
},
ready: function() {
created: function() {
var p = document.createElement('p');
p.id = 'message';
p.className = 'message';
this.appendChild(p);
var accept = document.createElement('paper-button');
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
+14 -66
View File
@@ -4,96 +4,44 @@
<link rel="import" href="../bower_components/core-icon/core-icon.html">
<link rel="import" href="../bower_components/core-icons/core-icons.html">
<polymer-element name="loot-plugin-item" extends="paper-item">
<polymer-element name="loot-plugin-item" attributes="priorityText">
<template>
<style>
:host([data-bsa=false]) #loadsBSA,
:host([data-dummy=false]) #dummyPlugin,
:host([data-edits=false]) #hasUserEdits,
:host([data-global-priority=false]) #hasGlobalPriority,
:host #hasPriority:not([label^=Priority]) {
:host(:not([data-bsa])) #loadsBSA,
:host(:not([data-edits])) #hasUserEdits {
visibility: hidden;
}
:host a {
::content a {
text-decoration: none;
color: black;
}
:host .hasGlobalPriority, :host #hasPriority {
display:none;
}
:host-context(body.editMode) #hasGlobalPriority,
:host-context(body.editMode) #hasPriority {
display: inline-block;
core-tooltip {
margin: 0.25em;
}
div {
min-width: 62px;
}
/* The default styling for Polymer's <paper-item>, which seems to be applied in an external stylesheet, so isn't inherited. */
:host::shadow paper-ripple {
position: absolute;
top: 0;
bottom: 0;
left: 0;
right: 0;
pointer-events: none;
}
:host {
display: block;
position: relative;
font-size: 16px;
-webkit-user-select: none;
cursor: pointer;
box-sizing: border-box;
height: 48px;
padding: 0 16px;
white-space: nowrap;
}
:host::shadow ::content > a {
position: absolute;
top: 0;
bottom: 0;
left: 0;
right: 0;
padding-left: 0.75em;
}
</style>
<div center horizontal layout>
<core-tooltip id="dummyPlugin" label="Dummy Plugin">
<core-icon icon="visibility-off"></core-icon>
</core-tooltip>
<paper-item>
<core-tooltip id="loadsBSA" label="Loads BSA">
<core-icon icon="attachment"></core-icon>
</core-tooltip>
<core-tooltip id="hasUserEdits" label="Has User Metadata">
<core-icon icon="account-circle"></core-icon>
</core-tooltip>
<core-tooltip id="hasGlobalPriority" label="Priority Is Global">
<core-icon icon="language"></core-icon>
</core-tooltip>
<core-tooltip id="hasPriority" label="">
<core-icon icon="star"></core-icon>
</core-tooltip>
</div>
<shadow></shadow>
<div><content></content></div>
</paper-item>
</template>
<script>
Polymer({
setLink: function(url) {
this.getElementsByTagName('a')[0].href = url;
},
setPriority: function(text) {
this.shadowRoot.getElementById('hasPriority').label = text;
getName: function() {
return this.getElementsByTagName('a')[0].textContent;
},
handleDragStart: function(evt) {
evt.dataTransfer.effectAllowed = 'copy';
evt.dataTransfer.setData('text/plain', evt.currentTarget.label);
},
created: function() {
var a = document.createElement('a');
this.appendChild(a);
evt.dataTransfer.setData('text/plain', evt.currentTarget.getName());
},
});
</script>
@@ -0,0 +1,17 @@
<link rel="import" href="../bower_components/polymer/polymer.html">
<link rel="import" href="../bower_components/paper-input/paper-input.html">
<link rel="import" href="../bower_components/paper-input/paper-input-decorator.html">
<link rel="import" href="../bower_components/core-input/core-input.html">
<polymer-element name="loot-validated-input" attributes="error type required maxlength minlength pattern max min step value disabled">
<template>
<paper-input-decorator error="{{error}}" isInvalid="{{!$.input.validity.valid}}" disabled?="{{disabled != undefined}}">
<input id="input" is="core-input" type="{{type}}" class="{{class}}" required?="{{required != undefined}}" maxlength?="{{maxlength}}" minlength?="{{minlength}}" pattern?="{{pattern}}" max?="{{max}}" min?="{{min}}" step?="{{step}}" value="{{value}}" disabled?="{{disabled != undefined}}">
</paper-input-decorator>
</template>
<script>
Polymer({
type: 'text',
});
</script>
</polymer-element>
+166
View File
@@ -0,0 +1,166 @@
var filters = {
/* Filter functions return true if the given plugin passes the filter and
should be displayed, otherwise false. */
hiddenPluginNo: 0,
hiddenMessageNo: 0,
conflicts: [],
searchFilter: function(plugin, needle) {
if (needle.length == 0) {
return true;
}
if (plugin.name.toLowerCase().indexOf(needle) != -1
|| plugin.getCrcString().toLowerCase().indexOf(needle) != -1
|| plugin.version.toLowerCase().indexOf(needle) != -1) {
return true;
}
var tags = plugin.getTagStrings();
if (tags.added.toLowerCase().indexOf(needle) != -1
|| tags.removed.toLowerCase().indexOf(needle) != -1) {
return true;
}
for (var i = 0; i < plugin.messages.length; ++i) {
if (plugin.messages[i].content[0].str.toLowerCase().indexOf(needle) != -1) {
return true;
}
}
},
messagelessFilter: function(plugin) {
/* This function could be further optimised to perform fewer checks,
but it's also responsible for setting the hidden message count, so
has to go through everything. */
var hasMessages = false;
/* If any messages exist, check if they are hidden or not. Note
that the messages may not be present as elements, so the check
is actually if they would be hidden according to the message
filters. */
if (this.allMessageFilter()) {
plugin.messages.forEach(function(message){
if (this.noteFilter(message)
&& this.doNotCleanFilter(message)) {
hasMessages = true;
return;
}
++hiddenMessageNo;
}, this);
} else {
hiddenMessageNo += plugin.messages.length;
}
if (document.getElementById('hideMessagelessPlugins').checked) {
return hasMessages;
} else {
return true;
}
},
inactiveFilter: function(plugin) {
if (document.getElementById('hideInactivePlugins').checked) {
return plugin.isActive;
} else {
return true;
}
},
conflictsFilter: function(plugin) {
if (this.conflicts.length > 0) {
return this.conflicts.indexOf(plugin.name) != -1;
} else {
return true;
}
},
applyPluginFilters: function(plugins) {
var search = document.getElementById('searchBox').value.toLowerCase();
hiddenPluginNo = 0;
hiddenMessageNo = 0;
var filteredPlugins = [];
plugins.forEach(function(plugin){
/* Messageless filter needs to run first. */
if (this.messagelessFilter(plugin)
&& this.inactiveFilter(plugin)
&& this.conflictsFilter(plugin)
&& this.searchFilter(plugin, search)) {
filteredPlugins.push(plugin);
return;
}
++hiddenPluginNo;
}, this);
document.getElementById('hiddenPluginNo').textContent = hiddenPluginNo;
document.getElementById('hiddenMessageNo').textContent = hiddenMessageNo;
return filteredPlugins;
},
/* Message filter functions are run from within plugin cards, when the card's
messages are to be added as elements. Each filter should return true if the
message is to be displayed. */
noteFilter: function(message) {
if (document.getElementById('hideNotes').checked) {
return message.type != 'say';
} else {
return true;
}
},
doNotCleanFilter: function(message) {
if (document.getElementById('hideDoNotCleanMessages').checked) {
return message.content[0].str.indexOf(l10n.jed.translate("Do not clean").fetch()) == -1;
} else {
return true;
}
},
allMessageFilter: function() {
return !document.getElementById('hideAllPluginMessages').checked;
},
applyMessageFilters: function(messages) {
var filteredMessages = [];
if (this.allMessageFilter()) {
messages.forEach(function(message){
if (this.noteFilter(message)
&& this.doNotCleanFilter(message)) {
filteredMessages.push(message);
return;
}
}, this);
}
return filteredMessages;
},
};
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
it is completed.
*/
getConflictingPluginsFromFilter().then(function(conflicts) {
filters.conflicts = conflicts;
var filtered = filters.applyPluginFilters(loot.game.plugins);
document.getElementById('cardsNav').lastElementChild.data = filtered;
document.getElementById('main').lastElementChild.data = filtered;
/* Also run message filters on the current card elements. */
var cards = document.getElementById('main').getElementsByTagName('loot-plugin-card');
for (var i = 0; i < cards.length; ++i) {
cards[i].onMessagesChange(); // Calls Plugin.getUIMessages(), which calls filters.applyMessageFilters().
}
});
}
+84 -77
View File
@@ -58,71 +58,80 @@
pluginCard = document.querySelector('polymer-element[name="loot-plugin-card"]').querySelector('template').content;
}
pluginCard.getElementById('front').querySelector('.activeTick').label = l10n.translate("Active Plugin").fetch();
pluginCard.getElementById('editor').querySelector('.activeTick').label = l10n.translate("Active Plugin").fetch();
pluginCard.getElementById('front').querySelector('.dummyPlugin').label = l10n.translate("Dummy Plugin").fetch();
pluginCard.getElementById('editor').querySelector('.dummyPlugin').label = l10n.translate("Dummy Plugin").fetch();
pluginCard.getElementById('front').querySelector('.loadsBSA').label = l10n.translate("Loads BSA").fetch();
pluginCard.getElementById('editor').querySelector('.loadsBSA').label = l10n.translate("Loads BSA").fetch();
pluginCard.getElementById('activeTick').label = l10n.translate("Active Plugin").fetch();
pluginCard.getElementById('dummyPlugin').label = l10n.translate("Dummy Plugin").fetch();
pluginCard.getElementById('loadsBSA').label = l10n.translate("Loads BSA").fetch();
pluginCard.getElementById('hasUserEdits').label = l10n.translate("Has User Metadata").fetch();
pluginCard.getElementById('enableEdits').label = l10n.translate("Enable Edits").fetch();
pluginCard.getElementById('globalPriority').parentElement.label = l10n.translate("Global priorities are compared against all other plugins. Normal priorities are compared against only conflicting plugins.").fetch();
pluginCard.getElementById('globalPriority').label = l10n.translate("Global Priority").fetch();
pluginCard.getElementById('priorityValue').previousElementSibling.textContent = l10n.translate("Priority Value").fetch();
pluginCard.getElementById('fileTabs').querySelector('[data-for=loadAfter]').textContent = l10n.translate("Load After").fetch();
pluginCard.getElementById('fileTabs').querySelector('[data-for=req]').textContent = l10n.translate("Requirements").fetch();
pluginCard.getElementById('fileTabs').querySelector('[data-for=inc]').textContent = l10n.translate("Incompatibilities").fetch();
pluginCard.getElementById('miscTabs').querySelector('[data-for=message]').textContent = l10n.translate("Messages").fetch();
pluginCard.getElementById('miscTabs').querySelector('[data-for=tags]').textContent = l10n.translate("Bash Tags").fetch();
pluginCard.getElementById('miscTabs').querySelector('[data-for=dirty]').textContent = l10n.translate("Dirty Info").fetch();
pluginCard.getElementById('miscTabs').querySelector('[data-for=locations]').textContent = l10n.translate("Locations").fetch();
pluginCard.getElementById('loadAfter').querySelector('th:first-child').textContent = l10n.translate("Filename").fetch();
pluginCard.getElementById('loadAfter').querySelector('th:nth-child(2)').textContent = l10n.translate("Display Name").fetch();
pluginCard.getElementById('loadAfter').querySelector('th:nth-child(3)').textContent = l10n.translate("Condition").fetch();
pluginCard.getElementById('loadAfter').querySelector('td:first-child').textContent = l10n.translate("Add new row...").fetch();
pluginCard.getElementById('req').querySelector('th:first-child').textContent = l10n.translate("Filename").fetch();
pluginCard.getElementById('req').querySelector('th:nth-child(2)').textContent = l10n.translate("Display Name").fetch();
pluginCard.getElementById('req').querySelector('th:nth-child(3)').textContent = l10n.translate("Condition").fetch();
pluginCard.getElementById('req').querySelector('td:first-child').textContent = l10n.translate("Add new row...").fetch();
pluginCard.getElementById('inc').querySelector('th:first-child').textContent = l10n.translate("Filename").fetch();
pluginCard.getElementById('inc').querySelector('th:nth-child(2)').textContent = l10n.translate("Display Name").fetch();
pluginCard.getElementById('inc').querySelector('th:nth-child(3)').textContent = l10n.translate("Condition").fetch();
pluginCard.getElementById('inc').querySelector('td:first-child').textContent = l10n.translate("Add new row...").fetch();
pluginCard.getElementById('message').querySelector('th:first-child').textContent = l10n.translate("Type").fetch();
pluginCard.getElementById('message').querySelector('th:nth-child(2)').textContent = l10n.translate("Content").fetch();
pluginCard.getElementById('message').querySelector('th:nth-child(3)').textContent = l10n.translate("Condition").fetch();
pluginCard.getElementById('message').querySelector('th:nth-child(4)').textContent = l10n.translate("Language").fetch();
pluginCard.getElementById('message').querySelector('td:first-child').textContent = l10n.translate("Add new row...").fetch();
pluginCard.getElementById('tags').querySelector('th:first-child').textContent = l10n.translate("Add/Remove").fetch();
pluginCard.getElementById('tags').querySelector('th:nth-child(2)').textContent = l10n.translate("Bash Tag").fetch();
pluginCard.getElementById('tags').querySelector('th:nth-child(3)').textContent = l10n.translate("Condition").fetch();
pluginCard.getElementById('tags').querySelector('td:first-child').textContent = l10n.translate("Add new row...").fetch();
pluginCard.getElementById('dirty').querySelector('th:first-child').textContent = l10n.translate("CRC").fetch();
pluginCard.getElementById('dirty').querySelector('th:nth-child(2)').textContent = l10n.translate("ITM Count").fetch();
pluginCard.getElementById('dirty').querySelector('th:nth-child(3)').textContent = l10n.translate("Deleted References").fetch();
pluginCard.getElementById('dirty').querySelector('th:nth-child(4)').textContent = l10n.translate("Deleted Navmeshes").fetch();
pluginCard.getElementById('dirty').querySelector('th:nth-child(5)').textContent = l10n.translate("Cleaning Utility").fetch();
pluginCard.getElementById('dirty').querySelector('td:first-child').textContent = l10n.translate("Add new row...").fetch();
pluginCard.getElementById('locations').querySelector('th:first-child').textContent = l10n.translate("URL").fetch();
pluginCard.getElementById('locations').querySelector('th:nth-child(2)').textContent = l10n.translate("Version").fetch();
pluginCard.getElementById('locations').querySelector('td:first-child').textContent = l10n.translate("Add new row...").fetch();
pluginCard.getElementById('accept').textContent = l10n.translate("Apply").fetch();
pluginCard.getElementById('cancel').textContent = l10n.translate("Cancel").fetch();
pluginCard.getElementById('showOnlyConflicts').label = l10n.translate("Show Only Conflicts").fetch();
pluginCard.getElementById('editMetadata').label = l10n.translate("Edit Metadata").fetch();
pluginCard.getElementById('copyMetadata').label = l10n.translate("Copy Metadata As Text").fetch();
pluginCard.getElementById('clearMetadata').label = l10n.translate("Clear User Metadata").fetch();
pluginCard.getElementById('editMetadata').lastChild.textContent = l10n.translate("Edit Metadata").fetch();
pluginCard.getElementById('copyMetadata').lastChild.textContent = l10n.translate("Copy Metadata As Text").fetch();
pluginCard.getElementById('clearMetadata').lastChild.textContent = l10n.translate("Clear User Metadata").fetch();
/* Plugin editor template. */
var pluginEditor = document.querySelector('link[rel="import"][href$="loot-plugin-card.html"]');
if (pluginEditor) {
pluginEditor = pluginEditor.import.querySelector('link[rel="import"][href$="loot-plugin-editor.html"]').import.querySelector('template').content;
} else {
pluginEditor = document.querySelector('polymer-element[name="loot-plugin-editor"]').querySelector('template').content;
}
pluginEditor.getElementById('activeTick').label = l10n.translate("Active Plugin").fetch();
pluginEditor.getElementById('dummyPlugin').label = l10n.translate("Dummy Plugin").fetch();
pluginEditor.getElementById('loadsBSA').label = l10n.translate("Loads BSA").fetch();
pluginEditor.getElementById('enableEdits').label = l10n.translate("Enable Edits").fetch();
pluginEditor.getElementById('globalPriority').parentElement.label = l10n.translate("Global priorities are compared against all other plugins. Normal priorities are compared against only conflicting plugins.").fetch();
pluginEditor.getElementById('globalPriority').label = l10n.translate("Global Priority").fetch();
pluginEditor.getElementById('priorityValue').parentElement.previousElementSibling.textContent = l10n.translate("Priority Value").fetch();
pluginEditor.getElementById('tableTabs').querySelector('[data-for=loadAfter]').textContent = l10n.translate("Load After").fetch();
pluginEditor.getElementById('tableTabs').querySelector('[data-for=req]').textContent = l10n.translate("Requirements").fetch();
pluginEditor.getElementById('tableTabs').querySelector('[data-for=inc]').textContent = l10n.translate("Incompatibilities").fetch();
pluginEditor.getElementById('tableTabs').querySelector('[data-for=message]').textContent = l10n.translate("Messages").fetch();
pluginEditor.getElementById('tableTabs').querySelector('[data-for=tags]').textContent = l10n.translate("Bash Tags").fetch();
pluginEditor.getElementById('tableTabs').querySelector('[data-for=dirty]').textContent = l10n.translate("Dirty Info").fetch();
pluginEditor.getElementById('tableTabs').querySelector('[data-for=locations]').textContent = l10n.translate("Locations").fetch();
pluginEditor.getElementById('loadAfter').querySelector('th:first-child').textContent = l10n.translate("Filename").fetch();
pluginEditor.getElementById('loadAfter').querySelector('th:nth-child(2)').textContent = l10n.translate("Display Name").fetch();
pluginEditor.getElementById('loadAfter').querySelector('th:nth-child(3)').textContent = l10n.translate("Condition").fetch();
pluginEditor.getElementById('loadAfter').querySelector('td:first-child').textContent = l10n.translate("Add new row...").fetch();
pluginEditor.getElementById('req').querySelector('th:first-child').textContent = l10n.translate("Filename").fetch();
pluginEditor.getElementById('req').querySelector('th:nth-child(2)').textContent = l10n.translate("Display Name").fetch();
pluginEditor.getElementById('req').querySelector('th:nth-child(3)').textContent = l10n.translate("Condition").fetch();
pluginEditor.getElementById('req').querySelector('td:first-child').textContent = l10n.translate("Add new row...").fetch();
pluginEditor.getElementById('inc').querySelector('th:first-child').textContent = l10n.translate("Filename").fetch();
pluginEditor.getElementById('inc').querySelector('th:nth-child(2)').textContent = l10n.translate("Display Name").fetch();
pluginEditor.getElementById('inc').querySelector('th:nth-child(3)').textContent = l10n.translate("Condition").fetch();
pluginEditor.getElementById('inc').querySelector('td:first-child').textContent = l10n.translate("Add new row...").fetch();
pluginEditor.getElementById('message').querySelector('th:first-child').textContent = l10n.translate("Type").fetch();
pluginEditor.getElementById('message').querySelector('th:nth-child(2)').textContent = l10n.translate("Content").fetch();
pluginEditor.getElementById('message').querySelector('th:nth-child(3)').textContent = l10n.translate("Condition").fetch();
pluginEditor.getElementById('message').querySelector('th:nth-child(4)').textContent = l10n.translate("Language").fetch();
pluginEditor.getElementById('message').querySelector('td:first-child').textContent = l10n.translate("Add new row...").fetch();
pluginEditor.getElementById('tags').querySelector('th:first-child').textContent = l10n.translate("Add/Remove").fetch();
pluginEditor.getElementById('tags').querySelector('th:nth-child(2)').textContent = l10n.translate("Bash Tag").fetch();
pluginEditor.getElementById('tags').querySelector('th:nth-child(3)').textContent = l10n.translate("Condition").fetch();
pluginEditor.getElementById('tags').querySelector('td:first-child').textContent = l10n.translate("Add new row...").fetch();
pluginEditor.getElementById('dirty').querySelector('th:first-child').textContent = l10n.translate("CRC").fetch();
pluginEditor.getElementById('dirty').querySelector('th:nth-child(2)').textContent = l10n.translate("ITM Count").fetch();
pluginEditor.getElementById('dirty').querySelector('th:nth-child(3)').textContent = l10n.translate("Deleted References").fetch();
pluginEditor.getElementById('dirty').querySelector('th:nth-child(4)').textContent = l10n.translate("Deleted Navmeshes").fetch();
pluginEditor.getElementById('dirty').querySelector('th:nth-child(5)').textContent = l10n.translate("Cleaning Utility").fetch();
pluginEditor.getElementById('dirty').querySelector('td:first-child').textContent = l10n.translate("Add new row...").fetch();
pluginEditor.getElementById('locations').querySelector('th:first-child').textContent = l10n.translate("URL").fetch();
pluginEditor.getElementById('locations').querySelector('th:nth-child(2)').textContent = l10n.translate("Version").fetch();
pluginEditor.getElementById('locations').querySelector('td:first-child').textContent = l10n.translate("Add new row...").fetch();
pluginEditor.getElementById('accept').textContent = l10n.translate("Apply").fetch();
pluginEditor.getElementById('cancel').textContent = l10n.translate("Cancel").fetch();
/* Plugin List Item Template */
var pluginItem = document.querySelector('link[rel="import"][href$="loot-plugin-item.html"]');
@@ -131,10 +140,8 @@
} else {
pluginItem = document.querySelector('polymer-element[name="loot-plugin-item"]').querySelector('template').content;
}
pluginItem.querySelector('#dummyPlugin').label = l10n.translate("Dummy Plugin").fetch();
pluginItem.querySelector('#loadsBSA').label = l10n.translate("Loads BSA").fetch();
pluginItem.querySelector('#hasUserEdits').label = l10n.translate("Has User Metadata").fetch();
pluginItem.querySelector('#hasGlobalPriority').label = l10n.translate("Priority Is Global").fetch();
pluginItem.getElementById('loadsBSA').label = l10n.translate("Loads BSA").fetch();
pluginItem.getElementById('hasUserEdits').label = l10n.translate("Has User Metadata").fetch();
/* Message row template */
var messageRow = document.querySelector('link[rel="import"][href$="editable-table.html"]');
@@ -158,20 +165,20 @@
tagRow.querySelector('.type').children[1].textContent = l10n.translate("Remove").fetch();
/* Toolbar menu */
document.getElementById('redatePluginsButton').label = l10n.translate("Redate Plugins").fetch();
document.getElementById('openLogButton').label = l10n.translate("Open Debug Log Location").fetch();
document.getElementById('wipeUserlistButton').label = l10n.translate("Clear All User Metadata").fetch();
document.getElementById('copyContentButton').label = l10n.translate("Copy Content As Text").fetch();
document.getElementById('refreshContentButton').label = l10n.translate("Refresh Content").fetch();
document.getElementById('helpButton').label = l10n.translate("View Documentation").fetch();
document.getElementById('aboutButton').label = l10n.translate("About").fetch();
document.getElementById('settingsButton').label = l10n.translate("Settings").fetch();
document.getElementById('redatePluginsButton').lastChild.textContent = l10n.translate("Redate Plugins").fetch();
document.getElementById('openLogButton').lastChild.textContent = l10n.translate("Open Debug Log Location").fetch();
document.getElementById('wipeUserlistButton').lastChild.textContent = l10n.translate("Clear All User Metadata").fetch();
document.getElementById('copyContentButton').lastChild.textContent = l10n.translate("Copy Content As Text").fetch();
document.getElementById('refreshContentButton').lastChild.textContent = l10n.translate("Refresh Content").fetch();
document.getElementById('helpButton').lastChild.textContent = l10n.translate("View Documentation").fetch();
document.getElementById('aboutButton').lastChild.textContent = l10n.translate("About").fetch();
document.getElementById('settingsButton').lastChild.textContent = l10n.translate("Settings").fetch();
document.getElementById('applySortButton').textContent = l10n.translate("Apply").fetch();
document.getElementById('cancelSortButton').textContent = l10n.translate("Cancel").fetch();
/* Nav items */
document.getElementById('container').querySelector('div[drawer] > core-menu > paper-item[label=Summary]').label = l10n.translate("Summary").fetch();
document.getElementById('container').querySelector('div[drawer] > core-menu > paper-item[label^=General]').label = l10n.translate("General Messages").fetch();
document.getElementById('cardsNav').firstElementChild.lastChild.textContent = l10n.translate("Summary").fetch();
document.getElementById('cardsNav').firstElementChild.nextElementSibling.lastChild.textContent = l10n.translate("General Messages").fetch();
document.getElementById('sidebarTabs').firstElementChild.textContent = l10n.translate("Plugins").fetch();
document.getElementById('sidebarTabs').firstElementChild.nextElementSibling.textContent = l10n.translate("Filters").fetch();
document.getElementById('searchBox').parentElement.label = l10n.translate("Press Enter when searching to select the next match.").fetch();
@@ -206,7 +213,7 @@
document.getElementById('settingsDialog').heading = l10n.translate("Settings").fetch();
document.getElementById('defaultGameSelect').previousElementSibling.textContent = l10n.translate("Default Game").fetch();
document.getElementById('defaultGameSelect').children[0].label = l10n.translate("Autodetect").fetch();
document.getElementById('defaultGameSelect').firstElementChild.textContent = l10n.translate("Autodetect").fetch();
document.getElementById('languageSelect').previousElementSibling.textContent = l10n.translate("Language").fetch();
+25 -89
View File
@@ -41,6 +41,9 @@ function Plugin(obj) {
this.isDirty = obj.isDirty;
this.id = this.name.replace(/\s+/g, '');
this.isMenuOpen = false;
this.isEditorOpen = false;
this.isConflictFilterChecked = false;
/* Converts between the LOOT metadata object for tags, and their
editor row representation. */
@@ -63,7 +66,7 @@ function Plugin(obj) {
return tag;
}
Plugin.prototype.updateCardTags = function() {
Plugin.prototype.getTagStrings = function() {
var tagsAdded = [];
var tagsRemoved = [];
@@ -88,107 +91,50 @@ function Plugin(obj) {
}
}
if (tagsAdded.length != 0) {
this.card.getElementsByClassName('tag add')[0].textContent = tagsAdded.join(', ');
this.card.getElementsByClassName('tag add')[0].classList.toggle('hidden', false);
} else {
this.card.getElementsByClassName('tag add')[0].classList.toggle('hidden', true);
}
if (tagsRemoved.length != 0) {
this.card.getElementsByClassName('tag remove')[0].textContent = tagsRemoved.join(', ');
this.card.getElementsByClassName('tag remove')[0].classList.toggle('hidden', false);
} else {
this.card.getElementsByClassName('tag remove')[0].classList.toggle('hidden', true);
}
return {
added: tagsAdded.join(', '),
removed: tagsRemoved.join(', ')
};
}
Plugin.prototype.getPriorityString = function() {
if (this.modPriority != 0) {
return 'Priority: ' + this.modPriority;
return this.modPriority.toString();
} else {
return '';
}
}
Plugin.prototype.updateCardMessages = function() {
var messageUL = this.card.getElementsByTagName('ul')[0];
/* First clear any existing messages. */
while(messageUL.firstElementChild) {
messageUL.removeChild(messageUL.firstElementChild);
Plugin.prototype.getCrcString = function() {
if (this.crc == 0) {
return '';
} else {
return this.crc.toString(16).toUpperCase();
}
}
Plugin.prototype.getUIMessages = function() {
var uiMessages = [];
/* Now add the new messages. */
if (this.messages && this.messages.length != 0) {
this.messages.forEach(function(message) {
var messages = filters.applyMessageFilters(this.messages);
messages.forEach(function(message) {
var messageLi = document.createElement('li');
messageLi.className = message.type;
// Use the Marked library for Markdown formatting support.
messageLi.innerHTML = marked(message.content[0].str);
messageUL.appendChild(messageLi);
uiMessages.push(messageLi);
});
this.card.getElementsByTagName('ul')[0].classList.toggle('hidden', false);
} else {
this.card.getElementsByTagName('ul')[0].classList.toggle('hidden', true);
}
}
Plugin.prototype.createCard = function() {
var card = document.createElement('loot-plugin-card');
this.card = card;
card.id = this.id;
card.setAttribute('data-active', this.isActive);
card.setAttribute('data-dummy', this.isDummy);
card.setAttribute('data-bsa', this.loadsBSA);
card.setAttribute('data-edits', this.userlist != undefined);
/* Fill in name, version, CRC. */
card.getElementsByTagName('h1')[0].textContent = this.name;
card.getElementsByClassName('version')[0].textContent = this.version;
if (this.crc != 0) {
card.getElementsByClassName('crc')[0].textContent = this.crc.toString(16).toUpperCase();
}
/* Fill in Bash Tag suggestions. */
this.updateCardTags();
/* Fill in messages. */
this.updateCardMessages();
document.getElementById('main').appendChild(card);
}
Plugin.prototype.createListItem = function() {
var li = document.createElement('loot-plugin-item');
this.li = li;
li.label = this.name;
li.setLink('#' + this.id);
li.setPriority(this.getPriorityString());
li.setAttribute('data-dummy', this.isDummy);
li.setAttribute('data-bsa', this.loadsBSA);
li.setAttribute('data-edits', this.userlist != undefined);
li.setAttribute('data-global-priority', this.isGlobalPriority);
document.getElementById('cardsNav').appendChild(li);
return uiMessages;
}
Plugin.prototype.observer = function(changes) {
changes.forEach(function(change) {
if (change.name == 'userlist') {
change.object.li.setAttribute('data-edits', change.object[change.name] != undefined);
change.object.card.setAttribute('data-edits', change.object[change.name] != undefined);
} else if (change.name == 'modPriority') {
change.object.li.setPriority(this.getPriorityString());
change.object.card.shadowRoot.getElementById('priorityValue').value = change.object[change.name];
} else if (change.name == 'isGlobalPriority') {
change.object.li.setAttribute('data-global-priority', change.object[change.name]);
} else if (change.name == 'messages') {
change.object.updateCardMessages();
/* For messages, the card's messages need updating,
as do the message counts. */
if (change.name == 'messages') {
/* Update the message counts. */
var oldTotal = 0;
var newTotal = 0;
var oldWarns = 0;
@@ -223,27 +169,17 @@ function Plugin(obj) {
document.getElementById('totalMessageNo').textContent = parseInt(document.getElementById('totalMessageNo').textContent, 10) + newTotal - oldTotal;
document.getElementById('totalWarningNo').textContent = parseInt(document.getElementById('totalWarningNo').textContent, 10) + newWarns - oldWarns;
document.getElementById('totalErrorNo').textContent = parseInt(document.getElementById('totalErrorNo').textContent, 10) + newErrs - oldErrs;
} else if (change.name == 'tags') {
change.object.updateCardTags();
} else if (change.name == 'isDirty') {
/* Update dirty counts. */
if (change.object[change.name]) {
document.getElementById('dirtyPluginNo').textContent = ++parseInt(document.getElementById('dirtyPluginNo').textContent, 10);
} else {
document.getElementById('dirtyPluginNo').textContent = --parseInt(document.getElementById('dirtyPluginNo').textContent, 10);
}
} else if (change.name == 'crc') {
if (change.object[change.name] != 0) {
change.object.card.getElementsByClassName('crc')[0].textContent = change.object[change.name].toString(16).toUpperCase();
}
} else if (change.name == 'isDummy') {
change.object.li.setAttribute('data-dummy', change.object[change.name]);
change.object.card.setAttribute('data-dummy', change.object[change.name]);
}
});
}
this.createCard();
this.createListItem();
Object.observe(this, this.observer);
}
File diff suppressed because it is too large Load Diff
+103 -56
View File
@@ -5,7 +5,6 @@
<link rel="stylesheet" href="css/style.css" />
<link rel="stylesheet" href="css/overrides.css" />
<script src="bower_components/platform/platform.js"></script>
<link rel="import" href="bower_components/polymer/polymer.html">
<link rel="import" href="html/editable-table.html">
@@ -20,12 +19,12 @@
<link rel="import" href="bower_components/core-icons/core-icons.html">
<link rel="import" href="bower_components/core-tooltip/core-tooltip.html">
<link rel="import" href="bower_components/core-drawer-panel/core-drawer-panel.html">
<link rel="import" href="bower_components/core-menu/core-menu.html">
<link rel="import" href="bower_components/core-menu/core-submenu.html">
<link rel="import" href="bower_components/core-animated-pages/core-animated-pages.html">
<link rel="import" href="bower_components/core-animated-pages/transitions/slide-from-right.html">
<link rel="import" href="bower_components/core-list/core-list.html">
<link rel="import" href="bower_components/paper-menu-button/paper-menu-button.html">
<link rel="import" href="bower_components/paper-item/paper-item.html">
<link rel="import" href="bower_components/paper-dropdown-menu/paper-dropdown-menu.html">
<link rel="import" href="bower_components/paper-icon-button/paper-icon-button.html">
<link rel="import" href="bower_components/paper-button/paper-button.html">
<link rel="import" href="bower_components/paper-input/paper-input.html">
@@ -33,24 +32,57 @@
<link rel="import" href="bower_components/paper-checkbox/paper-checkbox.html">
<link rel="import" href="bower_components/paper-dialog/paper-dialog.html">
<link rel="import" href="bower_components/paper-dialog/paper-dialog-transition.html">
<link rel="import" href="bower_components/paper-dropdown/paper-dropdown.html">
<link rel="import" href="bower_components/paper-progress/paper-progress.html">
<link rel="import" href="bower_components/paper-toast/paper-toast.html">
<script src="bower_components/requirejs/require.js"></script>
</head>
<!-- oncontextmenu attribute disables the right-click menu. -->
<body oncontextmenu="return false" unresolved fullbleed vertical layout >
<core-toolbar id="mainToolbar">
<paper-menu-button icon="menu">
<paper-item id="redatePluginsButton" icon="today" label="Redate Plugins"></paper-item>
<paper-item id="wipeUserlistButton" icon="delete" label="Clear All User Metadata"></paper-item>
<paper-item id="copyContentButton" icon="content-copy" label="Copy Content As Text"></paper-item>
<paper-item id="refreshContentButton" icon="cached" label="Refresh Content"></paper-item>
<paper-item separator></paper-item>
<paper-item id="settingsButton" icon="settings" label="Settings"></paper-item>
<paper-item separator></paper-item>
<paper-item id="helpButton" icon="book" label="View Documentation"></paper-item>
<paper-item id="openLogButton" icon="folder" label="Open Debug Log Location"></paper-item>
<paper-item id="aboutButton" icon="help" label="About"></paper-item>
<paper-menu-button>
<paper-icon-button icon="menu"></paper-icon-button>
<paper-dropdown class="dropdown">
<div>
<paper-item id="redatePluginsButton">
<core-icon icon="today"></core-icon>
Redate Plugins
</paper-item>
<paper-item id="wipeUserlistButton">
<core-icon icon="delete"></core-icon>
Clear All User Metadata
</paper-item>
<paper-item id="copyContentButton">
<core-icon icon="content-copy"></core-icon>
Copy Content As Text
</paper-item>
<paper-item id="refreshContentButton">
<core-icon icon="cached"></core-icon>
Refresh Content
</paper-item>
<paper-item separator></paper-item>
<paper-item id="settingsButton">
<core-icon icon="settings"></core-icon>
Settings
</paper-item>
<paper-item separator></paper-item>
<paper-item id="helpButton">
<core-icon icon="book"></core-icon>
View Documentation
</paper-item>
<paper-item id="openLogButton">
<core-icon icon="folder"></core-icon>
Open Debug Log Location
</paper-item>
<paper-item id="aboutButton">
<core-icon icon="help"></core-icon>
About
</paper-item>
</div>
</paper-dropdown>
</paper-menu-button>
<paper-icon-button icon="drawer" id="drawerToggle"></paper-icon-button>
<loot-dropdown-menu id="gameMenu">
<!-- Generated game <li> elements go here. -->
</loot-dropdown-menu>
@@ -64,41 +96,50 @@
<paper-button id="applySortButton" class="hidden">Apply</paper-button>
<paper-button id="cancelSortButton" class="hidden">Cancel</paper-button>
</core-toolbar>
<core-drawer-panel id="container">
<core-drawer-panel id="container" drawerWidth="33%">
<div drawer vertical layout>
<paper-tabs id="sidebarTabs" selected="0">
<paper-tab>Plugins</paper-tab>
<paper-tab>Filters</paper-tab>
</paper-tabs>
<core-menu id="cardsNav" class="tab-content" flex>
<paper-item label="Summary">
<a href="#summary"></a>
</paper-item>
<paper-item label="General Messages">
<a href="#generalMessages"></a>
</paper-item>
<!-- Generated <loot-plugin-item> elements go here, containing # links to each plugin's section in the list. -->
</core-menu>
<core-menu id="filters" class="tab-content hidden" flex>
<paper-checkbox id="hideVersionNumbers" data-class="version" label="Hide version numbers"></paper-checkbox>
<paper-checkbox id="hideCRCs" data-class="crc" label="Hide CRCs"></paper-checkbox>
<paper-checkbox id="hideBashTags" data-class="tag" label="Hide Bash Tags"></paper-checkbox>
<paper-checkbox id="hideNotes" label="Hide notes"></paper-checkbox>
<paper-checkbox id="hideDoNotCleanMessages" label="Hide 'Do not clean' messages"></paper-checkbox>
<paper-checkbox id="hideInactivePluginMessages" label="Hide inactive plugin messages"></paper-checkbox>
<paper-checkbox id="hideAllPluginMessages" label="Hide all plugin messages"></paper-checkbox>
<paper-checkbox id="hideMessagelessPlugins" label="Hide messageless plugins"></paper-checkbox>
<div center horizontal layout>
<div id="hiddenPluginsTxt" flex>Hidden plugins:</div>
<div><span id="hiddenPluginNo">0</span> / <span id="filterTotalPluginNo">0</span></div>
<core-animated-pages selected="0" transitions="slide-from-right" flex>
<div id="cardsNav" class="tab-content" layout vertical>
<paper-item>
<a href="#summary"></a>Summary
</paper-item>
<paper-item>
<a href="#generalMessages"></a>General Messages
</paper-item>
<core-list flex>
<template>
<loot-plugin-item data-bsa?="{{model.loadsBSA}}" data-edits?="{{model.userlist != undefined}}" data-index="{{index}}">
{{model.name}}
</loot-plugin-item>
</template>
<!-- Generated <loot-plugin-item> elements go here. -->
</core-list>
</div>
<div center horizontal layout>
<div id="hiddenMessagesTxt" flex>Hidden messages:</div>
<div><span id="hiddenMessageNo">0</span> / <span id="filterTotalMessageNo">0</span></div>
<div id="filters" class="tab-content" flex>
<paper-checkbox id="hideVersionNumbers" data-class="version" label="Hide version numbers"></paper-checkbox>
<paper-checkbox id="hideCRCs" data-class="crc" label="Hide CRCs"></paper-checkbox>
<paper-checkbox id="hideBashTags" data-class="tag" label="Hide Bash Tags"></paper-checkbox>
<paper-checkbox id="hideNotes" label="Hide notes"></paper-checkbox>
<paper-checkbox id="hideDoNotCleanMessages" label="Hide 'Do not clean' messages"></paper-checkbox>
<paper-checkbox id="hideAllPluginMessages" label="Hide all plugin messages"></paper-checkbox>
<paper-checkbox id="hideInactivePlugins" label="Hide inactive plugins"></paper-checkbox>
<paper-checkbox id="hideMessagelessPlugins" label="Hide messageless plugins"></paper-checkbox>
<div center horizontal layout>
<div id="hiddenPluginsTxt" flex>Hidden plugins:</div>
<div><span id="hiddenPluginNo">0</span> / <span id="filterTotalPluginNo">0</span></div>
</div>
<div center horizontal layout>
<div id="hiddenMessagesTxt" flex>Hidden messages:</div>
<div><span id="hiddenMessageNo">0</span> / <span id="filterTotalMessageNo">0</span></div>
</div>
</div>
</core-menu>
<core-tooltip label="Press Enter when searching to select the next match." position="top">
<paper-input id="searchBox" type="search" label="Search content..."></paper-input>
</core-animated-pages>
<core-tooltip label="Press Enter or click outside the input to set the filter." position="top">
<paper-input id="searchBox" label="Filter content..."></paper-input>
</core-tooltip>
</div>
<div main id="main">
@@ -155,9 +196,26 @@
<!-- Generated message <li> elements go here. -->
</ul>
</section>
<!-- Generated plugin <loot-plugin-card> elements go here. -->
<core-list>
<template>
<loot-plugin-card data="{{model}}" id="{{model.id}}" data-active="{{model.isActive}}" data-dummy="{{model.isDummy}}" data-bsa="{{model.loadsBSA}}" data-edits="{{model.userlist != undefined}}">
<h1>{{model.name}}</h1>
<span class="version">{{model.version}}</span>
<span class="crc"></span>
<span class="tag add"></span>
<span class="tag remove"></span>
<ul></ul>
</loot-plugin-card>
</template>
<!-- Generated <loot-plugin-card> elements go here. -->
</core-list>
</div>
</core-drawer-panel>
<paper-toast id="toast"></paper-toast>
<loot-dialog id="progressDialog">
<paper-progress indeterminate></paper-progress>
<p>Calculating the last digit of &pi;...</p>
</loot-dialog>
<loot-dialog id="about" heading="About LOOT">
<p>Version <span id="LOOTVersion"></span> (build <span id="LOOTBuild"></span>)</p>
@@ -185,7 +243,7 @@ along with LOOT. If not, see &lt;http://www.gnu.org/licenses/&gt;.
<div center horizontal layout>
<div>Default Game</div>
<loot-dropdown-menu id="defaultGameSelect">
<paper-item value="auto" label="Autodetect"></paper-item>
<paper-item value="auto">Autodetect</paper-item>
<!-- Game <option> elements go here. -->
</loot-dropdown-menu>
</div>
@@ -227,17 +285,6 @@ along with LOOT. If not, see &lt;http://www.gnu.org/licenses/&gt;.
<paper-button class="cancel" affirmative>Cancel</paper-button>
</loot-dialog>
<div id="hoverText" class="hidden"></div>
<loot-dialog id="progressDialog">
<!-- CEF doesn't seem to want to play any animation set through CSS
for <progress>'s internal value pseudo-element, so use this
instead. -->
<div class="progress bar">
<div class="value"></div>
</div>
<h1>Calculating the last digit of &pi;...</h1>
</loot-dialog>
<loot-dialog id="firstRun" heading="First-Time Tips">
<p>This appears to be the first time you have run LOOT v<span id="firstTimeLootVersion"></span>. Here are some tips to help you get started with the interface.</p>
<ul>
+1 -35
View File
@@ -196,13 +196,7 @@ namespace loot {
CefRefPtr<Callback> callback) {
const string requestName = request["name"].as<string>();
if (requestName == "find") {
// Has one arg, which is the search string.
Find(browser, request["args"][0].as<string>(), request["args"][1].as<bool>());
callback->Success("");
return true;
}
else if (requestName == "changeGame") {
if (requestName == "changeGame") {
try {
// Has one arg, which is the folder name of the new game.
g_app_state.ChangeGame(request["args"][0].as<string>());
@@ -302,13 +296,6 @@ namespace loot {
return true;
}
else if (requestName == "saveFilterState") {
const string id = request["args"][0].as<string>();
const string value = request["args"][1].as<string>();
SaveFilterState(id, value);
callback->Success("");
return true;
}
else if (requestName == "copyContent") {
// Has one arg, just convert it to a YAML output string.
try {
@@ -334,13 +321,6 @@ namespace loot {
return false;
}
void Handler::Find(CefRefPtr<CefBrowser> browser, const std::string& search, bool findNext) {
// Only one search at a time is allowed, so give a constant identifier,
// and we want case-insensitive forward searching, with no repeated
// searches.
browser->GetHost()->Find(0, search, true, false, findNext);
}
void Handler::GetConflictingPlugins(const std::string& pluginName, CefRefPtr<CefFrame> frame, CefRefPtr<Callback> callback) {
BOOST_LOG_TRIVIAL(debug) << "Searching for plugins that conflict with " << pluginName;
@@ -422,20 +402,6 @@ namespace loot {
return "null";
}
void Handler::SaveFilterState(const std::string& id, const std::string& value) {
BOOST_LOG_TRIVIAL(trace) << "Saving state of filter " << id << " as " << value;
YAML::Node settings = g_app_state.GetSettings();
if (value == "true")
settings["filters"][id] = true;
else if (value == "false" || value.empty())
settings["filters"].remove(id);
else
settings["filters"][id] = value;
g_app_state.UpdateSettings(settings);
}
std::string Handler::ApplyUserEdits(const YAML::Node& pluginMetadata) {
BOOST_LOG_TRIVIAL(trace) << "Applying user edits for: " << pluginMetadata["name"].as<string>();
// Create new object for userlist entry.
-2
View File
@@ -66,11 +66,9 @@ namespace loot {
YAML::Node& request,
CefRefPtr<Callback> callback);
void Find(CefRefPtr<CefBrowser> browser, const std::string& search, bool findNext);
void GetConflictingPlugins(const std::string& pluginName, CefRefPtr<CefFrame> frame, CefRefPtr<Callback> callback);
void CopyMetadata(const std::string& pluginName);
std::string ClearPluginMetadata(const std::string& pluginName);
void SaveFilterState(const std::string& filterId, const std::string& value);
std::string ApplyUserEdits(const YAML::Node& pluginMetadata);
YAML::Node GenerateDerivedMetadata(const std::string& pluginName);