completed initial draft of import/export functionality, needs tests
This commit is contained in:
parent
1b62fd1ffe
commit
49b9833f86
4 changed files with 238 additions and 21 deletions
|
@ -11,28 +11,56 @@
|
|||
</head>
|
||||
<body>
|
||||
<section class="container">
|
||||
<div class="row">
|
||||
<div class="col-xs-12 col-md-12">
|
||||
<p>
|
||||
Enter <a href="https://developer.mozilla.org/en-US/Add-ons/WebExtensions/Match_patterns">domain matching rules</a>
|
||||
on the right, to create a new blocking rule. On the
|
||||
right, select which functionality should be blocked for
|
||||
hosts matching each rule.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col-xs-4 col-md-4">
|
||||
<domain-rules :domain-names="domainNames" :selected-domain="selectedDomain"></domain-rules>
|
||||
<ul class="nav nav-tabs" role="tablist">
|
||||
<li role="presentation" :class="activeTab === 'domain-rules' ? 'active' : ''">
|
||||
<a href="#domain-rules" @click="setActiveTab">Domain Rules</a>
|
||||
</li>
|
||||
<li role="presentation" :class="activeTab === 'import-export' ? 'active' : ''">
|
||||
<a href="#import-export" @click="setActiveTab">Import / Export</a>
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
<logging-settings :should-log="shouldLog"></logging-settings>
|
||||
<div class="tab-content">
|
||||
<div role="tabpanel" :class="['tab-pane', activeTab === 'domain-rules' ? 'active' : '']" id="domain-rules">
|
||||
<div class="row">
|
||||
<div class="col-xs-12 col-md-12">
|
||||
<p>
|
||||
Enter <a href="https://developer.mozilla.org/en-US/Add-ons/WebExtensions/Match_patterns">domain matching rules</a>
|
||||
on the right, to create a new blocking rule. On the
|
||||
right, select which functionality should be blocked for
|
||||
hosts matching each rule.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col-xs-4 col-md-4">
|
||||
<domain-rules
|
||||
:domain-names="domainNames"
|
||||
:selected-domain="selectedDomain"
|
||||
></domain-rules>
|
||||
|
||||
<logging-settings :should-log="shouldLog"></logging-settings>
|
||||
</div>
|
||||
|
||||
<div class="col-xs-8 col-md-8">
|
||||
<web-api-standards
|
||||
:standards="standards"
|
||||
:selected-standards="selectedStandards"
|
||||
:selected-domain="selectedDomain">
|
||||
</web-api-standards>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="col-xs-8 col-md-8">
|
||||
<web-api-standards :standards="standards"
|
||||
:selected-standards="selectedStandards"
|
||||
:selected-domain="selectedDomain">
|
||||
</web-api-standards>
|
||||
<div role="tabpanel" :class="['tab-pane', activeTab === 'import-export' ? 'active' : '']" id="import-export">
|
||||
<div class="row">
|
||||
<div class="col-xs-12 col-md-12">
|
||||
<import-export
|
||||
:domain-names="domainNames"
|
||||
:selected-standards="selectedStandards">
|
||||
</import-export>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
@ -43,6 +71,7 @@
|
|||
<script src="js/third_party/vue.js"></script>
|
||||
<script src="js/state.js"></script>
|
||||
<script src="js/components/domain-rules.vue.js"></script>
|
||||
<script src="js/components/import-export.vue.js"></script>
|
||||
<script src="js/components/web-api-standards.vue.js"></script>
|
||||
<script src="js/components/logging-settings.vue.js"></script>
|
||||
<script src="js/config.js"></script>
|
||||
|
|
172
add-on/config/js/components/import-export.vue.js
Normal file
172
add-on/config/js/components/import-export.vue.js
Normal file
|
@ -0,0 +1,172 @@
|
|||
(function () {
|
||||
"use strict";
|
||||
|
||||
const Vue = window.Vue;
|
||||
|
||||
const generateExportString = function (domainsToExport, allDomainData) {
|
||||
|
||||
const dataToExport = domainsToExport.map(function (domain) {
|
||||
return {
|
||||
"pattern": domain,
|
||||
"standards": allDomainData[domain]
|
||||
};
|
||||
});
|
||||
|
||||
return JSON.stringify(dataToExport);
|
||||
};
|
||||
|
||||
Vue.component("import-export", {
|
||||
props: ["domainNames", "selectedStandards"],
|
||||
template: `
|
||||
<h2>Export Settings</h2>
|
||||
<div class="form-group">
|
||||
<label class="control-label">Select domain rules to export:</label>
|
||||
<select multiple class="form-control" v-model="domainsToExport">
|
||||
<option v-for="domain in domainNames" :value="domain">
|
||||
{{ domain }}
|
||||
</option>
|
||||
</select>
|
||||
<span class="help-block">
|
||||
Select one or more domain rules to export.
|
||||
</span>
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<label class="control-label">
|
||||
The below is a copy of the selected standards to export elsewhere:
|
||||
</label>
|
||||
<textarea
|
||||
class="form-control"
|
||||
rows="3"
|
||||
readonly
|
||||
v-model="exportedData"
|
||||
placeholder="Exported data will appear here."></textarea>
|
||||
</div>
|
||||
|
||||
<h2>Import Settings</h2>
|
||||
|
||||
<div :class="['form-group', {'has-error': importError }]">
|
||||
<label class="control-label">
|
||||
Paste the exported data you'd like to import in the textarea below:
|
||||
</label>
|
||||
<textarea
|
||||
class="form-control"
|
||||
rows="3"
|
||||
v-model="importTextAreaData"
|
||||
placeholder="Paste the data you would like to import below."></textarea>
|
||||
</div>
|
||||
|
||||
<div :class="['form-group', {'has-error': importError }]">
|
||||
<div class="checkbox">
|
||||
<label>
|
||||
<input type="checkbox" v-model="shouldOverwrite">
|
||||
Overwrite existing settings?
|
||||
</label>
|
||||
<span class="help-block">
|
||||
If this option is selected, than existing options will be
|
||||
overwritten. If it is unchecked, then the blocked standards
|
||||
for existing domains will not be affected.
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<button class="btn btn-primary"
|
||||
v-bind:disabled="!isValidToImport()"
|
||||
@click="onImportClicked">Import Settings</button>
|
||||
</div>
|
||||
|
||||
<div class="form-group>
|
||||
<label class="control-label">Import log:</label>
|
||||
<textarea
|
||||
readonly
|
||||
:class="['form-control', importError ? 'alert-danger' : '']"
|
||||
rows="3"
|
||||
v-model="importLog"
|
||||
placeholder="The results of each import will be presented here."></textarea>
|
||||
</div>
|
||||
`,
|
||||
data: function () {
|
||||
return {
|
||||
exportedData: "",
|
||||
domainsToExport: [],
|
||||
importError: false,
|
||||
importLog: "",
|
||||
importTextAreaData: "",
|
||||
dataToImport: "",
|
||||
shouldOverwrite: false
|
||||
};
|
||||
},
|
||||
methods: {
|
||||
onImportClicked: function (event) {
|
||||
|
||||
if (!this.isValidToImport()) {
|
||||
this.importError = true;
|
||||
this.dataToImport = "";
|
||||
this.importLog = "No data to import.";
|
||||
return;
|
||||
}
|
||||
|
||||
const shouldOverwrite = !!this.shouldOverwrite;
|
||||
const stateObject = this.$root.$data;
|
||||
const currentDomainRules = stateObject.domainRules;
|
||||
const newDomainRules = this.dataToImport;
|
||||
this.importLog = "";
|
||||
|
||||
const logMessages = newDomainRules.map(function (newDomainRule) {
|
||||
const {pattern, standards} = newDomainRule;
|
||||
if (currentDomainRules[pattern] !== undefined && shouldOverwrite === false) {
|
||||
return ` ! ${pattern}: Skipped. Set to not override.\n`;
|
||||
}
|
||||
|
||||
stateObject.setStandardsForDomain(pattern, standards);
|
||||
return ` * ${pattern}: Blocking ${standards.length} standards.\n`;
|
||||
});
|
||||
|
||||
this.importError = false;
|
||||
this.importLog = logMessages.join("\n");
|
||||
|
||||
event.stopPropagation();
|
||||
event.preventDefault();
|
||||
},
|
||||
isValidToImport: function () {
|
||||
return (this.importError === false) && (this.dataToImport !== "");
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
selectedStandards: function () {
|
||||
this.exportedData = generateExportString(
|
||||
this.domainsToExport,
|
||||
this.$root.$data.domainRules
|
||||
);
|
||||
},
|
||||
domainsToExport: function (selectedDomains) {
|
||||
this.exportedData = generateExportString(
|
||||
selectedDomains,
|
||||
this.$root.$data.domainRules
|
||||
);
|
||||
},
|
||||
importTextAreaData: function () {
|
||||
|
||||
const value = this.importTextAreaData;
|
||||
|
||||
if (value.trim() === "") {
|
||||
this.dataToImport = "";
|
||||
this.importError = false;
|
||||
this.importLog = "";
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
this.dataToImport = JSON.parse(value);
|
||||
this.importError = false;
|
||||
this.importLog = "";
|
||||
} catch (ignore) {
|
||||
this.dataToImport = "";
|
||||
this.importError = true;
|
||||
this.importLog = "Invalid import data provided.";
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
}());
|
|
@ -13,10 +13,19 @@
|
|||
const onSettingsLoaded = function (storedSettings) {
|
||||
|
||||
state.populateFromStorage(storedSettings);
|
||||
state.activeTab = "domain-rules";
|
||||
|
||||
const vm = new Vue({
|
||||
el: doc.body,
|
||||
data: state
|
||||
el: doc.querySelector("section.container"),
|
||||
data: state,
|
||||
methods: {
|
||||
setActiveTab: function (event) {
|
||||
const targetElement = event.target;
|
||||
this.activeTab = targetElement.hash.replace("#", "");
|
||||
event.stopPropagation();
|
||||
event.preventDefault();
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
const updateStoredSettings = function () {
|
||||
|
|
|
@ -62,6 +62,13 @@
|
|||
|
||||
setShouldLog: function (shouldLog) {
|
||||
this.shouldLog = shouldLog;
|
||||
},
|
||||
|
||||
setStandardsForDomain: function (domain, standards) {
|
||||
this.domainRules[domain] = standards;
|
||||
if (domain === this.selectedDomain) {
|
||||
this.selectedStandards = standards;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
|
Loading…
Reference in a new issue