Merge pull request #292 from hosseinnedaee/implement-ace-instead-highlightjs

Replace highlight.js with ace editor.
This commit is contained in:
Hossein Nedaee
2019-11-12 06:58:51 +03:30
committed by GitHub
7 changed files with 150 additions and 52 deletions

View File

@@ -512,9 +512,9 @@ pre {
resize: vertical; resize: vertical;
text-overflow: ellipsis; text-overflow: ellipsis;
&:not([readonly]):hover, &:not([readonly]):not(.ace_editor):hover,
&:not([readonly]):active, &:not([readonly]):not(.ace_editor):active,
&:not([readonly]):focus { &:not([readonly]):not(.ace_editor):focus {
box-shadow: inset 0 0 0 2px var(--fg-light-color); box-shadow: inset 0 0 0 2px var(--fg-light-color);
transition: all 0.2s ease-in-out; transition: all 0.2s ease-in-out;
} }
@@ -524,6 +524,11 @@ pre {
display: grid; display: grid;
} }
pre.ace_editor {
font-family: Roboto Mono, monospace;
z-index: 0;
}
code { code {
height: 336px; height: 336px;
border-radius: 8px; border-radius: 8px;

85
components/ace-editor.vue Normal file
View File

@@ -0,0 +1,85 @@
<template>
<pre ref="editor"></pre>
</template>
<script>
const DEFAULT_THEME = 'dracula';
import ace from 'ace-builds';
import "ace-builds/webpack-resolver";
export default {
props: {
value: {
type: String,
default: ''
},
theme: {
type: String,
required: false
},
lang: {
type: String,
default: 'json',
},
options: {
type: Object,
default: {}
}
},
data() {
return {
editor: null,
cacheValue: ''
}
},
watch: {
value(value) {
if(value !== this.cacheValue) {
this.editor.session.setValue(value,1);
this.cacheValue = value;
}
},
theme() {
this.editor.setTheme('ace/theme/' + this.defineTheme())
},
lang(value) {
this.editor.getSession().setMode('ace/mode/' + value);
},
options(value) {
this.editor.setOptions(value);
}
},
mounted() {
const editor = ace.edit(this.$refs.editor, {
theme: 'ace/theme/'+ this.defineTheme(),
mode: "ace/mode/" + this.lang,
...this.options
})
editor.setValue(this.value);
this.editor = editor;
this.cacheValue = this.value;
},
methods: {
defineTheme() {
if(this.theme) {
return this.theme;
} else {
return this.$store.state.postwoman.settings.THEME_ACE_EDITOR || DEFAULT_THEME
}
}
},
beforeDestroy() {
this.editor.destroy();
this.editor.container.remove();
}
}
</script>

10
package-lock.json generated
View File

@@ -1756,6 +1756,11 @@
"negotiator": "0.6.2" "negotiator": "0.6.2"
} }
}, },
"ace-builds": {
"version": "1.4.7",
"resolved": "https://registry.npmjs.org/ace-builds/-/ace-builds-1.4.7.tgz",
"integrity": "sha512-gwQGVFewBopRLho08BfahyvRa9FlB43JUig5ItAKTYc9kJJsbA9QNz75p28QtQomoPQ9rJx82ymL21x4ZSZmdg=="
},
"acorn": { "acorn": {
"version": "6.3.0", "version": "6.3.0",
"resolved": "https://registry.npmjs.org/acorn/-/acorn-6.3.0.tgz", "resolved": "https://registry.npmjs.org/acorn/-/acorn-6.3.0.tgz",
@@ -5237,11 +5242,6 @@
"resolved": "https://registry.npmjs.org/hex-color-regex/-/hex-color-regex-1.1.0.tgz", "resolved": "https://registry.npmjs.org/hex-color-regex/-/hex-color-regex-1.1.0.tgz",
"integrity": "sha512-l9sfDFsuqtOqKDsQdqrMRk0U85RZc0RtOR9yPI7mRVOa4FsR/BVnZ0shmQRM96Ji99kYZP/7hn1cedc1+ApsTQ==" "integrity": "sha512-l9sfDFsuqtOqKDsQdqrMRk0U85RZc0RtOR9yPI7mRVOa4FsR/BVnZ0shmQRM96Ji99kYZP/7hn1cedc1+ApsTQ=="
}, },
"highlight.js": {
"version": "9.16.2",
"resolved": "https://registry.npmjs.org/highlight.js/-/highlight.js-9.16.2.tgz",
"integrity": "sha512-feMUrVLZvjy0oC7FVJQcSQRqbBq9kwqnYE4+Kj9ZjbHh3g+BisiPgF49NyQbVLNdrL/qqZr3Ca9yOKwgn2i/tw=="
},
"hmac-drbg": { "hmac-drbg": {
"version": "1.0.1", "version": "1.0.1",
"resolved": "https://registry.npmjs.org/hmac-drbg/-/hmac-drbg-1.0.1.tgz", "resolved": "https://registry.npmjs.org/hmac-drbg/-/hmac-drbg-1.0.1.tgz",

View File

@@ -25,7 +25,7 @@
"@nuxtjs/robots": "^2.4.2", "@nuxtjs/robots": "^2.4.2",
"@nuxtjs/sitemap": "^2.0.0", "@nuxtjs/sitemap": "^2.0.0",
"@nuxtjs/toast": "^3.3.0", "@nuxtjs/toast": "^3.3.0",
"highlight.js": "^9.16.2", "ace-builds": "^1.4.7",
"nuxt": "^2.10.2", "nuxt": "^2.10.2",
"v-tooltip": "^2.0.2", "v-tooltip": "^2.0.2",
"vue-virtual-scroll-list": "^1.4.2", "vue-virtual-scroll-list": "^1.4.2",

View File

@@ -568,14 +568,19 @@
</div> </div>
</div> </div>
<div id="response-details-wrapper"> <div id="response-details-wrapper">
<pre> <ResponseBody
<code :value="responseBodyText"
ref="responseBody" :lang="responseBodyType"
id="body" :options="{
rows="16" maxLines: '16',
placeholder="(waiting to send request)" minLines: '16',
>{{response.body}}</code> fontSize: '16px',
</pre> autoScrollEditorIntoView: true,
readOnly: true,
showPrintMargin: false,
useWorker: false
}"
/>
<iframe <iframe
:class="{hidden: !previewEnabled}" :class="{hidden: !previewEnabled}"
class="covers-response" class="covers-response"
@@ -617,8 +622,7 @@ import modal from "../components/modal";
import collections from "../components/collections"; import collections from "../components/collections";
import saveRequestAs from "../components/collections/saveRequestAs"; import saveRequestAs from "../components/collections/saveRequestAs";
import parseCurlCommand from "../assets/js/curlparser.js"; import parseCurlCommand from "../assets/js/curlparser.js";
import hljs from "highlight.js"; import AceEditor from '../components/ace-editor';
import "highlight.js/styles/androidstudio.css";
import getEnvironmentVariablesFromScript from "../functions/preRequest"; import getEnvironmentVariablesFromScript from "../functions/preRequest";
import parseTemplateString from "../functions/templating"; import parseTemplateString from "../functions/templating";
@@ -684,7 +688,8 @@ export default {
history, history,
autocomplete, autocomplete,
collections, collections,
saveRequestAs saveRequestAs,
ResponseBody: AceEditor
}, },
data() { data() {
return { return {
@@ -726,7 +731,9 @@ export default {
showRequestModal: false, showRequestModal: false,
editRequest: {}, editRequest: {},
urlExcludes: {} urlExcludes: {},
responseBodyText: '',
responseBodyType: 'text'
}; };
}, },
watch: { watch: {
@@ -747,33 +754,24 @@ export default {
else this.setRouteQueryState(); else this.setRouteQueryState();
}, },
"response.body": function(val) { "response.body": function(val) {
var responseText = if (
document.querySelector("div#response-details-wrapper pre code") != null this.response.body === "(waiting to send request)" ||
? document.querySelector("div#response-details-wrapper pre code") this.response.body === "Loading..."
: null; ) {
if (responseText) { this.responseBodyText = this.response.body;
if ( this.responseBodyType = 'text';
document.querySelector(".hljs") !== null && } else {
responseText.innerHTML.indexOf('<span class="hljs') !== -1 if(this.responseType === "application/json" ||
this.responseType === "application/hal+json"
) { ) {
responseText.removeAttribute("class"); this.responseBodyText = JSON.stringify(this.response.body, null, 2)
responseText.innerHTML = null; this.responseBodyType = 'json'
responseText.innerText = this.response.body; } else if (this.responseType === "text/html") {
} else if ( this.responseBodyText = this.response.body;
responseText && this.responseBodyType = 'html'
this.response.body !== "(waiting to send request)" &&
this.response.body !== "Loading..."
) {
responseText.innerText =
this.responseType === "application/json" ||
this.responseType === "application/hal+json"
? JSON.stringify(this.response.body, null, 2)
: this.response.body;
hljs.highlightBlock(
document.querySelector("div#response-details-wrapper pre code")
);
} else { } else {
responseText.innerText = this.response.body; this.responseBodyText = this.response.body;
this.responseBodyType = 'text';
} }
} }
}, },

View File

@@ -7,7 +7,7 @@
<div class="backgrounds"> <div class="backgrounds">
<span <span
:key="theme.class" :key="theme.class"
@click="applyTheme(theme.class, theme.color)" @click="applyTheme(theme)"
v-for="theme in themes" v-for="theme in themes"
> >
<swatch <swatch
@@ -128,24 +128,28 @@ export default {
{ {
color: "#252628", color: "#252628",
name: "Kinda Dark", name: "Kinda Dark",
class: "" class: "",
aceEditor: "dracula"
}, },
{ {
color: "#ffffff", color: "#ffffff",
name: "Clearly White", name: "Clearly White",
vibrant: true, vibrant: true,
class: "light" class: "light",
aceEditor: "xcode"
}, },
{ {
color: "#000000", color: "#000000",
name: "Just Black", name: "Just Black",
class: "black" class: "black",
aceEditor: "tomorrow_night_blue"
}, },
{ {
color: "var(--bg-color)", color: "var(--bg-color)",
name: "Auto (system)", name: "Auto (system)",
vibrant: window.matchMedia("(prefers-color-scheme: light)").matches, vibrant: window.matchMedia("(prefers-color-scheme: light)").matches,
class: "auto" class: "auto",
aceEditor: window.matchMedia("(prefers-color-scheme: light)").matches ? 'xcode' : 'dracula'
} }
], ],
// You can define a new color here! It will simply store the color value. // You can define a new color here! It will simply store the color value.
@@ -220,8 +224,9 @@ export default {
}, },
methods: { methods: {
applyTheme(name, color) { applyTheme({class:name, color, aceEditor}) {
this.applySetting("THEME_CLASS", name); this.applySetting("THEME_CLASS", name);
this.applySetting("THEME_ACE_EDITOR", aceEditor);
document document
.querySelector("meta[name=theme-color]") .querySelector("meta[name=theme-color]")
.setAttribute("content", color); .setAttribute("content", color);

View File

@@ -26,6 +26,11 @@ export const SETTINGS_KEYS = [
*/ */
"THEME_COLOR_VIBRANT", "THEME_COLOR_VIBRANT",
/**
* The Ace editor theme
*/
"THEME_ACE_EDITOR",
/** /**
* Normally, section frames are multicolored in the UI * Normally, section frames are multicolored in the UI
* to emphasise the different sections. * to emphasise the different sections.