Use hashing to reduce diff/highlight calls

pull/111/head
MattIPv4 2020-05-26 16:26:11 +01:00
parent 73ee2033cd
commit a07cc51e61
3 changed files with 51 additions and 26 deletions

View File

@ -23,8 +23,12 @@ limitations under the License.
<template v-slot:header> <template v-slot:header>
</template> </template>
<template v-slot:buttons> <template v-slot:buttons>
<a v-if="splitColumn" class="button is-primary is-outline" @click="splitColumn = false">Single column mode</a> <a v-if="splitColumn" class="button is-primary is-outline" @click="splitColumn = false">
<a v-else class="button is-primary" @click="splitColumn = true">Split column mode</a> Single column mode
</a>
<a v-else class="button is-primary" @click="splitColumn = true">
Split column mode
</a>
</template> </template>
</Header> </Header>
@ -66,12 +70,13 @@ limitations under the License.
<div :class="`column ${splitColumn ? 'is-half' : 'is-full'} is-full-mobile is-full-tablet`"> <div :class="`column ${splitColumn ? 'is-half' : 'is-full'} is-full-mobile is-full-tablet`">
<h2>Config files</h2> <h2>Config files</h2>
<div ref="files" class="columns is-multiline"> <div ref="files" class="columns is-multiline">
<div v-for="conf in confFilesOutput" <NginxPrism v-for="conf in confFilesOutput"
:class="`column ${confFilesOutput.length > 1 && !splitColumn ? 'is-half' : 'is-full'} is-full-mobile is-full-tablet`" :key="`${conf[0]}-${hash(conf[1])}`"
:name="`${nginxDir}/${conf[0]}`"
:conf="conf[1]"
:half="confFilesOutput.length > 1 && !splitColumn"
> >
<h3>{{ nginxDir }}/{{ conf[0] }}</h3> </NginxPrism>
<pre><code class="language-nginx" v-html="conf[1]"></code></pre>
</div>
</div> </div>
</div> </div>
</div> </div>
@ -82,11 +87,11 @@ limitations under the License.
</template> </template>
<script> <script>
import crypto from 'crypto';
import clone from 'clone'; import clone from 'clone';
import { diffLines } from 'diff'; import { diffLines } from 'diff';
import escape from 'escape-html'; import escape from 'escape-html';
import deepEqual from 'deep-equal'; import deepEqual from 'deep-equal';
import Prism from 'prismjs';
import Header from 'do-vue/src/templates/header'; import Header from 'do-vue/src/templates/header';
import Footer from 'do-vue/src/templates/footer'; import Footer from 'do-vue/src/templates/footer';
import isChanged from '../util/is_changed'; import isChanged from '../util/is_changed';
@ -97,6 +102,7 @@ limitations under the License.
import Domain from './domain'; import Domain from './domain';
import Global from './global'; import Global from './global';
import Setup from './setup'; import Setup from './setup';
import NginxPrism from './nginx_prism';
export default { export default {
name: 'App', name: 'App',
@ -106,6 +112,7 @@ limitations under the License.
Domain, Domain,
Global, Global,
Setup, Setup,
NginxPrism,
}, },
data() { data() {
return { return {
@ -168,8 +175,8 @@ limitations under the License.
this.$set(this.$data.domains, index, null); this.$set(this.$data.domains, index, null);
if (this.$data.active === index) this.$data.active = this.$data.domains.findIndex(d => d !== null); if (this.$data.active === index) this.$data.active = this.$data.domains.findIndex(d => d !== null);
}, },
highlightFiles() { hash(content) {
Prism.highlightAllUnder(this.$refs.files, true); return crypto.createHash('sha256').update(content).digest('base64');
}, },
checkChange(oldConf) { checkChange(oldConf) {
// If nothing has changed for a tick, we can use the config files // If nothing has changed for a tick, we can use the config files
@ -179,7 +186,6 @@ limitations under the License.
this.$data.confFilesOutput = this.confFiles; this.$data.confFilesOutput = this.confFiles;
this.$nextTick(() => { this.$nextTick(() => {
this.$data.confWatcherWaiting = false; this.$data.confWatcherWaiting = false;
this.highlightFiles();
this.$data.ready = true; this.$data.ready = true;
}); });
return; return;
@ -197,11 +203,12 @@ limitations under the License.
// Work through each file in the new config // Work through each file in the new config
const newFiles = []; const newFiles = [];
for (const [newFileName, newFileConf] of newConf) { for (const [newFileName, newFileConf] of newConf) {
// If a file with the same name existed before, diff! // If a file with the same name existed before, diff!
// TODO: Handle diffing across file renames (eg. when a user changes a domain name) // TODO: Handle diffing across file renames (eg. when a user changes a domain name)
const old = oldConf && oldConf.find(c => c[0] === newFileName); const old = oldConf && oldConf.find(c => c[0] === newFileName);
if (old) { if (old && this.hash(old[1]) !== this.hash(newFileConf)) {
console.info(`Diffing ${newFileName}...`);
// Get the diff // Get the diff
const diff = diffLines(old[1], newFileConf); const diff = diffLines(old[1], newFileConf);
@ -242,12 +249,7 @@ limitations under the License.
newFiles.push([newFileName, newFileConf]); newFiles.push([newFileName, newFileConf]);
} }
this.$data.confFilesOutput = newFiles; this.$data.confFilesOutput = newFiles;
this.$nextTick(() => this.$data.confWatcherWaiting = false);
// Highlight in-browser (using web workers so UI isn't blocked) once these files are rendered
this.$nextTick(() => {
this.$data.confWatcherWaiting = false;
this.highlightFiles();
});
}, },
}, },
}; };

View File

@ -0,0 +1,23 @@
<template>
<div :class="`column ${half ? 'is-half' : 'is-full'} is-full-mobile is-full-tablet`">
<h3>{{ name }}</h3>
<pre><code class="language-nginx" v-html="conf"></code></pre>
</div>
</template>
<script>
import Prism from 'prismjs';
export default {
name: 'NginxPrism',
props: {
name: String,
conf: String,
half: Boolean,
},
mounted() {
console.info(`Highlighting ${this.$props.name}...`);
Prism.highlightAllUnder(this.$el);
},
};
</script>

View File

@ -116,10 +116,10 @@
mounted() { mounted() {
this.$nextTick(() => this.certbotCmds()); this.$nextTick(() => this.certbotCmds());
this.$nextTick(() => this.sitesAvailable()); this.$nextTick(() => this.sitesAvailable());
this.$nextTick(() => Prism.highlightElement(this.$refs.reload, true)); this.$nextTick(() => Prism.highlightElement(this.$refs.reload));
this.$nextTick(() => Prism.highlightElement(this.$refs.reload2, true)); this.$nextTick(() => Prism.highlightElement(this.$refs.reload2));
this.$nextTick(() => Prism.highlightElement(this.$refs.renewal, true)); this.$nextTick(() => Prism.highlightElement(this.$refs.renewal));
this.$nextTick(() => Prism.highlightElement(this.$refs.chmod, true)); this.$nextTick(() => Prism.highlightElement(this.$refs.chmod));
}, },
methods: { methods: {
certbotCmds() { certbotCmds() {
@ -139,7 +139,7 @@
].filter(x => x !== null).join(' ') ].filter(x => x !== null).join(' ')
)).join('\n'); )).join('\n');
this.$nextTick(() => Prism.highlightElement(this.$refs.certBot, true)); this.$nextTick(() => Prism.highlightElement(this.$refs.certBot));
}, },
sitesAvailable() { sitesAvailable() {
if (!this.$refs.commentOut) return; if (!this.$refs.commentOut) return;
@ -156,8 +156,8 @@
this.$refs.commentOut.textContent = `sed -i -r 's/(listen .*443)/\\1;#/g; s/(ssl_(certificate|certificate_key|trusted_certificate) )/#;#\\1/g' ${sitesAvailable}`; this.$refs.commentOut.textContent = `sed -i -r 's/(listen .*443)/\\1;#/g; s/(ssl_(certificate|certificate_key|trusted_certificate) )/#;#\\1/g' ${sitesAvailable}`;
this.$refs.unComment.textContent = `sed -i -r 's/#?;#//g' ${sitesAvailable}`; this.$refs.unComment.textContent = `sed -i -r 's/#?;#//g' ${sitesAvailable}`;
this.$nextTick(() => Prism.highlightElement(this.$refs.commentOut, true)); this.$nextTick(() => Prism.highlightElement(this.$refs.commentOut));
this.$nextTick(() => Prism.highlightElement(this.$refs.unComment, true)); this.$nextTick(() => Prism.highlightElement(this.$refs.unComment));
}, },
}, },
}; };