Skip to content

Instantly share code, notes, and snippets.

@yousefamar
Last active May 17, 2019 01:43
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save yousefamar/0132f7d4e5ac69213aaf495637380d11 to your computer and use it in GitHub Desktop.
Save yousefamar/0132f7d4e5ac69213aaf495637380d11 to your computer and use it in GitHub Desktop.
A simple, configurable, persistent, reactive search-and-replace tool
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width" />
<title>String Substituter</title>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<!-- <script src="https://cdn.jsdelivr.net/npm/vue"></script> -->
<link rel='stylesheet' href='https://cdn.jsdelivr.net/gh/kognise/water.css@latest/dist/light.min.css'>
<style>
th {
text-align: left;
}
[contenteditable="true"].singleLine {
white-space: nowrap;
width: 200px;
overflow: hidden;
}
[contenteditable="true"].singleLine br {
display: none;
}
[contenteditable="true"].singleLine * {
display: inline;
white-space: nowrap;
}
td {
background-color: white;
}
textarea {
width: 100%;
height: 20em;
}
.inline {
display: inline;
}
</style>
</head>
<body>
<div id="content">
<h1>String Substituter</h1>
<h2>Input</h2>
<textarea v-model='input'></textarea>
<h2>Output</h2>
<textarea v-model='output'></textarea>
<h2>Mappings</h2>
<table id="mappings">
<tr>
<th>From</th>
<th>To</th>
<th></th>
</tr>
<tr v-for="mapping in mappings">
<td contenteditable="true" class="singleLine" @blur="mappingEdited(mapping, 'from', $event.target.innerText)" v-text="mapping.from"></td>
<td contenteditable="true" class="singleLine" @blur="mappingEdited(mapping, 'to', $event.target.innerText)" v-text="mapping.to"></td>
<td><button @click="removeMapping(mapping)">−</button></td>
</tr>
<tr>
<td><input type="text" id="mappingFromInput"></td>
<td><input type="text" id="mappingToInput"></td>
<td><button @click="addMapping">+</button></td>
</tr>
</table>
</div>
<script charset="utf-8">
new Vue({
el: '#content',
data: {
mappings: [],
input: ''
},
computed: {
output: function () {
if (this.mappings.length < 1)
return this.input;
let map = {};
this.mappings.forEach(m => map[m.from] = m.to);
return this.input.replace(new RegExp('(' + Object.keys(map).join('|') + ')', 'g'), match => map[match]);
}
},
created: function () {
this.input = window.localStorage.getItem('input') || "That’s the vision for the development of cloud computing during the next decade. Movement towards this cloud-first vision of business is already being established. The cloud industry has matured rapidly during the past decade and the technology is now embedded across enterprises, regardless of size and sector.";
let mappings = JSON.parse(window.localStorage.getItem('mappings'));
if (!mappings || mappings.length < 1)
mappings = [
{
from: 'the cloud',
to: 'my butt'
}, {
from: 'cloud',
to: 'butt'
}
];
this.mappings.push(...mappings);
},
methods: {
saveMappings() {
window.localStorage.setItem('mappings', JSON.stringify(this.mappings));
},
mappingEdited(mapping, property, value) {
mapping[property] = value;
this.saveMappings();
},
addMapping() {
let mappingFromInput = document.getElementById('mappingFromInput');
let mappingToInput = document.getElementById('mappingToInput');
this.mappings.push({
from: mappingFromInput.value,
to: mappingToInput.value,
});
mappingFromInput.value = '';
mappingToInput.value = '';
this.saveMappings();
},
removeMapping(mapping) {
this.mappings.splice(this.mappings.indexOf(mapping), 1);
this.saveMappings();
}
}
});
</script>
</body>
</html>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment