Added show/hide button for password input

 Updated vector icons
This commit is contained in:
Liyas Thomas
2019-09-13 10:32:49 +05:30
parent d67e22e57b
commit 2f39f7f68b
3 changed files with 144 additions and 121 deletions

View File

@@ -29,7 +29,7 @@
<label :for="'delete-button#'+index" class="hide-on-small-screen">&nbsp;</label> <label :for="'delete-button#'+index" class="hide-on-small-screen">&nbsp;</label>
<button class="icon" :id="'delete-button#'+index" :disabled="isClearingHistory" @click="deleteHistory(entry)"> <button class="icon" :id="'delete-button#'+index" :disabled="isClearingHistory" @click="deleteHistory(entry)">
<svg width="24" height="24" xmlns="http://www.w3.org/2000/svg" fill-rule="evenodd" clip-rule="evenodd"> <svg width="24" height="24" xmlns="http://www.w3.org/2000/svg" fill-rule="evenodd" clip-rule="evenodd">
<path d="M5.662 23l-5.369-5.365c-.195-.195-.293-.45-.293-.707 0-.256.098-.512.293-.707l14.929-14.928c.195-.194.451-.293.707-.293.255 0 .512.099.707.293l7.071 7.073c.196.195.293.451.293.708 0 .256-.097.511-.293.707l-11.216 11.219h5.514v2h-12.343zm3.657-2l-5.486-5.486-1.419 1.414 4.076 4.072h2.829zm6.605-17.581l-10.677 10.68 5.658 5.659 10.676-10.682-5.657-5.657z" /> <path d="M19 24h-14c-1.104 0-2-.896-2-2v-17h-1v-2h6v-1.5c0-.827.673-1.5 1.5-1.5h5c.825 0 1.5.671 1.5 1.5v1.5h6v2h-1v17c0 1.104-.896 2-2 2zm0-19h-14v16.5c0 .276.224.5.5.5h13c.276 0 .5-.224.5-.5v-16.5zm-9 4c0-.552-.448-1-1-1s-1 .448-1 1v9c0 .552.448 1 1 1s1-.448 1-1v-9zm6 0c0-.552-.448-1-1-1s-1 .448-1 1v9c0 .552.448 1 1 1s1-.448 1-1v-9zm-2-7h-4v1h4v-1z"/>
</svg> </svg>
</button> </button>
</li> </li>

View File

@@ -1,60 +1,58 @@
<template> <template>
<div label="import_modal"> <transition name="modal-fade">
<transition name="modal"> <div class="modal-backdrop">
<div class="modal-mask"> <div class="modal-wrapper">
<div class="modal-wrapper"> <div class="modal-container">
<div class="modal-container"> <div class="modal-header">
<div class="modal-header"> <slot name="header"></slot>
<slot name="header"></slot> </div>
</div> <div class="modal-body">
<div class="modal-body"> <slot name="body"></slot>
<slot name="body"></slot> </div>
</div> <div class="modal-footer">
<div class="modal-footer"> <slot name="footer"></slot>
<slot name="footer"></slot>
</div>
</div> </div>
</div> </div>
</div> </div>
</transition> </div>
</div> </transition>
</template> </template>
<style scoped> <style scoped>
.modal-mask { .modal-backdrop {
position: fixed; position: fixed;
z-index: 998; z-index: 998;
top: 0; top: 0;
left: 0; left: 0;
width: 100%; width: 100%;
height: 100%; height: 100%;
background-color: rgba(0, 0, 0, 0.5); background-color: rgba(0, 0, 0, 0.75);
display: flex; display: flex;
align-items: center; align-items: center;
justify-content: center; justify-content: center;
transition: all 0.2s ease; transition: all 0.2s ease;
} }
.modal-wrapper { .modal-wrapper {
display: flex; display: flex;
align-items: center; align-items: center;
justify-content: center; justify-content: center;
flex-grow: 1; flex-grow: 1;
max-width: 800px; max-width: 800px;
} }
.modal-container { .modal-container {
display: flex; display: flex;
flex-grow: 1; flex-grow: 1;
flex-direction: column; flex-direction: column;
margin: 8px; margin: 8px;
padding: 12px; padding: 12px;
transition: all 0.2s ease; transition: all 0.2s ease;
background-color: var(--bg-color); background-color: var(--bg-color);
border: 2px solid var(--ac-color); border: 2px solid var(--ac-color);
border-radius: 4px; border-radius: 4px;
} }
/* /*
* The following styles are auto-applied to elements with * The following styles are auto-applied to elements with
* transition="modal" when their visibility is toggled * transition="modal" when their visibility is toggled
* by Vue.js. * by Vue.js.
@@ -63,17 +61,14 @@
* these styles. * these styles.
*/ */
.modal-enter { .modal-fade-enter,
opacity: 0; .modal-fade-leave-active {
} opacity: 0;
}
.modal-leave-active { .modal-fade-enter .modal-container,
opacity: 0; .modal-fade-leave-active .modal-container {
} transform: scale(0.9);
transition: all .2s ease;
.modal-enter .modal-container, }
.modal-leave-active .modal-container {
-webkit-transform: scale(1.1);
transform: scale(1.1);
}
</style> </style>

View File

@@ -3,21 +3,21 @@
<pw-section class="yellow" label="Import" ref="import"> <pw-section class="yellow" label="Import" ref="import">
<ul> <ul>
<li> <li>
<button id="show-modal" @click="showModal = true">Import cURL</button> <button id="show-modal" @click="showModal = true">Import cURL</button>
</li> </li>
</ul> </ul>
<import-modal v-if="showModal" @close="showModal = false"> <pw-modal v-if="showModal" @close="showModal = false">
<div slot="header"> <div slot="header">
<ul> <ul>
<li> <li>
<div class="flex-wrap"> <div class="flex-wrap">
<h3 class="title">Import cURL</h3> <h3 class="title">Import cURL</h3>
<div> <div>
<button class="icon" @click="toggleModal"> <button class="icon" @click="toggleModal">
<svg xmlns="http://www.w3.org/2000/svg" width="18" height="18" viewBox="0 0 24 24"> <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24">
<path d="M23 20.168l-8.185-8.187 8.185-8.174-2.832-2.807-8.182 8.179-8.176-8.179-2.81 2.81 8.186 8.196-8.186 8.184 2.81 2.81 8.203-8.192 8.18 8.192z"/> <path d="M23 20.168l-8.185-8.187 8.185-8.174-2.832-2.807-8.182 8.179-8.176-8.179-2.81 2.81 8.186 8.196-8.186 8.184 2.81 2.81 8.203-8.192 8.18 8.192z" />
</svg> </svg>
</button> </button>
</div> </div>
</div> </div>
</li> </li>
@@ -37,7 +37,7 @@
</li> </li>
</ul> </ul>
</div> </div>
</import-modal> </pw-modal>
</pw-section> </pw-section>
<pw-section class="blue" label="Request" ref="request"> <pw-section class="blue" label="Request" ref="request">
<ul> <ul>
@@ -65,7 +65,7 @@
<li> <li>
<label class="hide-on-small-screen" for="copyRequest">&nbsp;</label> <label class="hide-on-small-screen" for="copyRequest">&nbsp;</label>
<button class="icon" @click="copyRequest" id="copyRequest" ref="copyRequest" :disabled="!isValidURL"> <button class="icon" @click="copyRequest" id="copyRequest" ref="copyRequest" :disabled="!isValidURL">
<svg xmlns="http://www.w3.org/2000/svg" width="18" height="18" viewBox="0 0 24 24"> <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24">
<path d="M22 6v16h-16v-16h16zm2-2h-20v20h20v-20zm-24 17v-21h21v2h-19v19h-2z" /> <path d="M22 6v16h-16v-16h16zm2-2h-20v20h20v-20zm-24 17v-21h21v2h-19v19h-2z" />
</svg> </svg>
<span>Share URL</span> <span>Share URL</span>
@@ -89,8 +89,8 @@
<button :disabled="!isValidURL" @click="sendRequest" class="show" id="action" name="action" ref="sendButton"> <button :disabled="!isValidURL" @click="sendRequest" class="show" id="action" name="action" ref="sendButton">
Send <span id="hidden-message">Again</span> Send <span id="hidden-message">Again</span>
<span> <span>
<svg xmlns="http://www.w3.org/2000/svg" width="18" height="18" viewBox="0 0 24 24"> <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24">
<path d="M5 3l3.057-3 11.943 12-11.943 12-3.057-3 9-9z"/> <path d="M0 12l11 3.1 7-8.1-8.156 5.672-4.312-1.202 15.362-7.68-3.974 14.57-3.75-3.339-2.17 2.925v-.769l-2-.56v7.383l4.473-6.031 4.527 4.031 6-22z" />
</svg> </svg>
</span> </span>
</button> </button>
@@ -114,14 +114,14 @@
<label for="generatedCode">Generated Code</label> <label for="generatedCode">Generated Code</label>
<div> <div>
<button class="icon" @click="copyRequestCode" name="copyRequestCode" ref="copyRequestCode"> <button class="icon" @click="copyRequestCode" name="copyRequestCode" ref="copyRequestCode">
<svg xmlns="http://www.w3.org/2000/svg" width="18" height="18" viewBox="0 0 24 24"> <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24">
<path d="M22 6v16h-16v-16h16zm2-2h-20v20h20v-20zm-24 17v-21h21v2h-19v19h-2z" /> <path d="M22 6v16h-16v-16h16zm2-2h-20v20h20v-20zm-24 17v-21h21v2h-19v19h-2z" />
</svg> </svg>
<span>Copy</span> <span>Copy</span>
</button> </button>
</div> </div>
</div> </div>
<textarea ref="generatedCode" name="generatedCode" rows="16" v-model="requestCode"></textarea> <textarea ref="generatedCode" name="generatedCode" rows="8" v-model="requestCode"></textarea>
</li> </li>
</ul> </ul>
</pw-section> </pw-section>
@@ -152,7 +152,7 @@
<label class="hide-on-small-screen" for="request">&nbsp;</label> <label class="hide-on-small-screen" for="request">&nbsp;</label>
<button class="icon" @click="removeRequestBodyParam(index)" name="request"> <button class="icon" @click="removeRequestBodyParam(index)" name="request">
<svg width="24" height="24" xmlns="http://www.w3.org/2000/svg" fill-rule="evenodd" clip-rule="evenodd"> <svg width="24" height="24" xmlns="http://www.w3.org/2000/svg" fill-rule="evenodd" clip-rule="evenodd">
<path d="M5.662 23l-5.369-5.365c-.195-.195-.293-.45-.293-.707 0-.256.098-.512.293-.707l14.929-14.928c.195-.194.451-.293.707-.293.255 0 .512.099.707.293l7.071 7.073c.196.195.293.451.293.708 0 .256-.097.511-.293.707l-11.216 11.219h5.514v2h-12.343zm3.657-2l-5.486-5.486-1.419 1.414 4.076 4.072h2.829zm6.605-17.581l-10.677 10.68 5.658 5.659 10.676-10.682-5.657-5.657z" /> <path d="M19 24h-14c-1.104 0-2-.896-2-2v-17h-1v-2h6v-1.5c0-.827.673-1.5 1.5-1.5h5c.825 0 1.5.671 1.5 1.5v1.5h6v2h-1v17c0 1.104-.896 2-2 2zm0-19h-14v16.5c0 .276.224.5.5.5h13c.276 0 .5-.224.5-.5v-16.5zm-9 4c0-.552-.448-1-1-1s-1 .448-1 1v9c0 .552.448 1 1 1s1-.448 1-1v-9zm6 0c0-.552-.448-1-1-1s-1 .448-1 1v9c0 .552.448 1 1 1s1-.448 1-1v-9zm-2-7h-4v1h4v-1z" />
</svg> </svg>
</button> </button>
</li> </li>
@@ -172,7 +172,7 @@
</ul> </ul>
</div> </div>
<div v-else> <div v-else>
<textarea @keydown="formatRawParams" rows="16" v-model="rawParams" v-textarea-auto-height="rawParams"></textarea> <textarea @keydown="formatRawParams" rows="8" v-model="rawParams" v-textarea-auto-height="rawParams"></textarea>
</div> </div>
</pw-section> </pw-section>
<pw-section class="purple" id="response" label="Response" ref="response"> <pw-section class="purple" id="response" label="Response" ref="response">
@@ -194,7 +194,7 @@
<label for="body">response</label> <label for="body">response</label>
<div> <div>
<button class="icon" @click="copyResponse" name="copyResponse" ref="copyResponse" v-if="response.body"> <button class="icon" @click="copyResponse" name="copyResponse" ref="copyResponse" v-if="response.body">
<svg xmlns="http://www.w3.org/2000/svg" width="18" height="18" viewBox="0 0 24 24"> <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24">
<path d="M22 6v16h-16v-16h16zm2-2h-20v20h20v-20zm-24 17v-21h21v2h-19v19h-2z" /> <path d="M22 6v16h-16v-16h16zm2-2h-20v20h20v-20zm-24 17v-21h21v2h-19v19h-2z" />
</svg> </svg>
<span>Copy</span> <span>Copy</span>
@@ -237,8 +237,21 @@
</li> </li>
<li> <li>
<label for="http_basic_passwd">Password</label> <label for="http_basic_passwd">Password</label>
<input type="password" v-model="httpPassword"> <input :type="passwordFieldType" v-model="httpPassword">
</li> </li>
<div>
<li>
<label class="hide-on-small-screen" for="switchVisibility">&nbsp;</label>
<button class="icon" ref="switchVisibility" @click="switchVisibility">
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" v-if="passwordFieldType === 'text'">
<path d="M12.015 7c4.751 0 8.063 3.012 9.504 4.636-1.401 1.837-4.713 5.364-9.504 5.364-4.42 0-7.93-3.536-9.478-5.407 1.493-1.647 4.817-4.593 9.478-4.593zm0-2c-7.569 0-12.015 6.551-12.015 6.551s4.835 7.449 12.015 7.449c7.733 0 11.985-7.449 11.985-7.449s-4.291-6.551-11.985-6.551zm-.015 5c1.103 0 2 .897 2 2s-.897 2-2 2-2-.897-2-2 .897-2 2-2zm0-2c-2.209 0-4 1.792-4 4 0 2.209 1.791 4 4 4s4-1.791 4-4c0-2.208-1.791-4-4-4z" />
</svg>
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" v-if="passwordFieldType !== 'text'">
<path d="M19.604 2.562l-3.346 3.137c-1.27-.428-2.686-.699-4.243-.699-7.569 0-12.015 6.551-12.015 6.551s1.928 2.951 5.146 5.138l-2.911 2.909 1.414 1.414 17.37-17.035-1.415-1.415zm-6.016 5.779c-3.288-1.453-6.681 1.908-5.265 5.206l-1.726 1.707c-1.814-1.16-3.225-2.65-4.06-3.66 1.493-1.648 4.817-4.594 9.478-4.594.927 0 1.796.119 2.61.315l-1.037 1.026zm-2.883 7.431l5.09-4.993c1.017 3.111-2.003 6.067-5.09 4.993zm13.295-4.221s-4.252 7.449-11.985 7.449c-1.379 0-2.662-.291-3.851-.737l1.614-1.583c.715.193 1.458.32 2.237.32 4.791 0 8.104-3.527 9.504-5.364-.729-.822-1.956-1.99-3.587-2.952l1.489-1.46c2.982 1.9 4.579 4.327 4.579 4.327z" />
</svg>
</button>
</li>
</div>
</ul> </ul>
<ul v-if="auth === 'Bearer Token'"> <ul v-if="auth === 'Bearer Token'">
<li> <li>
@@ -262,7 +275,7 @@
<label class="hide-on-small-screen" for="header">&nbsp;</label> <label class="hide-on-small-screen" for="header">&nbsp;</label>
<button class="icon" @click="removeRequestHeader(index)" name="header"> <button class="icon" @click="removeRequestHeader(index)" name="header">
<svg width="24" height="24" xmlns="http://www.w3.org/2000/svg" fill-rule="evenodd" clip-rule="evenodd"> <svg width="24" height="24" xmlns="http://www.w3.org/2000/svg" fill-rule="evenodd" clip-rule="evenodd">
<path d="M5.662 23l-5.369-5.365c-.195-.195-.293-.45-.293-.707 0-.256.098-.512.293-.707l14.929-14.928c.195-.194.451-.293.707-.293.255 0 .512.099.707.293l7.071 7.073c.196.195.293.451.293.708 0 .256-.097.511-.293.707l-11.216 11.219h5.514v2h-12.343zm3.657-2l-5.486-5.486-1.419 1.414 4.076 4.072h2.829zm6.605-17.581l-10.677 10.68 5.658 5.659 10.676-10.682-5.657-5.657z" /> <path d="M19 24h-14c-1.104 0-2-.896-2-2v-17h-1v-2h6v-1.5c0-.827.673-1.5 1.5-1.5h5c.825 0 1.5.671 1.5 1.5v1.5h6v2h-1v17c0 1.104-.896 2-2 2zm0-19h-14v16.5c0 .276.224.5.5.5h13c.276 0 .5-.224.5-.5v-16.5zm-9 4c0-.552-.448-1-1-1s-1 .448-1 1v9c0 .552.448 1 1 1s1-.448 1-1v-9zm6 0c0-.552-.448-1-1-1s-1 .448-1 1v9c0 .552.448 1 1 1s1-.448 1-1v-9zm-2-7h-4v1h4v-1z" />
</svg> </svg>
</button> </button>
</li> </li>
@@ -295,7 +308,7 @@
<label class="hide-on-small-screen" for="param">&nbsp;</label> <label class="hide-on-small-screen" for="param">&nbsp;</label>
<button class="icon" @click="removeRequestParam(index)" name="param"> <button class="icon" @click="removeRequestParam(index)" name="param">
<svg width="24" height="24" xmlns="http://www.w3.org/2000/svg" fill-rule="evenodd" clip-rule="evenodd"> <svg width="24" height="24" xmlns="http://www.w3.org/2000/svg" fill-rule="evenodd" clip-rule="evenodd">
<path d="M5.662 23l-5.369-5.365c-.195-.195-.293-.45-.293-.707 0-.256.098-.512.293-.707l14.929-14.928c.195-.194.451-.293.707-.293.255 0 .512.099.707.293l7.071 7.073c.196.195.293.451.293.708 0 .256-.097.511-.293.707l-11.216 11.219h5.514v2h-12.343zm3.657-2l-5.486-5.486-1.419 1.414 4.076 4.072h2.829zm6.605-17.581l-10.677 10.68 5.658 5.659 10.676-10.682-5.657-5.657z" /> <path d="M19 24h-14c-1.104 0-2-.896-2-2v-17h-1v-2h6v-1.5c0-.827.673-1.5 1.5-1.5h5c.825 0 1.5.671 1.5 1.5v1.5h6v2h-1v17c0 1.104-.896 2-2 2zm0-19h-14v16.5c0 .276.224.5.5.5h13c.276 0 .5-.224.5-.5v-16.5zm-9 4c0-.552-.448-1-1-1s-1 .448-1 1v9c0 .552.448 1 1 1s1-.448 1-1v-9zm6 0c0-.552-.448-1-1-1s-1 .448-1 1v9c0 .552.448 1 1 1s1-.448 1-1v-9zm-2-7h-4v1h4v-1z" />
</svg> </svg>
</button> </button>
</li> </li>
@@ -313,7 +326,7 @@
</li> </li>
</ul> </ul>
</pw-section> </pw-section>
<history @useHistory="handleUseHistory" ref="historyComponent" /> <history @useHistory="handleUseHistory" ref="historyComponent"></history>
</div> </div>
</template> </template>
<script> <script>
@@ -322,7 +335,7 @@
import section from "../components/section"; import section from "../components/section";
import textareaAutoHeight from "../directives/textareaAutoHeight"; import textareaAutoHeight from "../directives/textareaAutoHeight";
import toggle from "../components/toggle"; import toggle from "../components/toggle";
import import_modal from "../components/modal"; import modal from "../components/modal";
import parseCurlCommand from '../assets/js/curlparser.js'; import parseCurlCommand from '../assets/js/curlparser.js';
import hljs from 'highlight.js'; import hljs from 'highlight.js';
import 'highlight.js/styles/dracula.css'; import 'highlight.js/styles/dracula.css';
@@ -371,7 +384,8 @@
return headerMap return headerMap
}; };
export const findStatusGroup = responseStatus => statusCategories.find(status => status.statusCodeRegex.test(responseStatus)); export const findStatusGroup = responseStatus => statusCategories.find(status => status.statusCodeRegex.test(
responseStatus));
export default { export default {
directives: { directives: {
@@ -381,21 +395,22 @@
components: { components: {
'pw-section': section, 'pw-section': section,
'pw-toggle': toggle, 'pw-toggle': toggle,
'import-modal': import_modal, 'pw-modal': modal,
history, history,
autocomplete, autocomplete,
}, },
data() { data() {
return { return {
showModal: false, showModal: false,
copyButton: '<svg xmlns="http://www.w3.org/2000/svg" width="18" height="18" viewBox="0 0 24 24"><path d="M22 6v16h-16v-16h16zm2-2h-20v20h20v-20zm-24 17v-21h21v2h-19v19h-2z" /></svg>', copyButton: '<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><path d="M22 6v16h-16v-16h16zm2-2h-20v20h20v-20zm-24 17v-21h21v2h-19v19h-2z" /></svg>',
copiedButton: '<svg xmlns="http://www.w3.org/2000/svg" width="18" height="18" viewBox="0 0 24 24"><path d="M22 2v20h-20v-20h20zm2-2h-24v24h24v-24zm-5.541 8.409l-1.422-1.409-7.021 7.183-3.08-2.937-1.395 1.435 4.5 4.319 8.418-8.591z"/></svg>', copiedButton: '<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><path d="M22 2v20h-20v-20h20zm2-2h-24v24h24v-24zm-5.541 8.409l-1.422-1.409-7.021 7.183-3.08-2.937-1.395 1.435 4.5 4.319 8.418-8.591z"/></svg>',
method: 'GET', method: 'GET',
url: 'https://reqres.in', url: 'https://reqres.in',
auth: 'None', auth: 'None',
path: '/api/users', path: '/api/users',
httpUser: '', httpUser: '',
httpPassword: '', httpPassword: '',
passwordFieldType: 'password',
bearerToken: '', bearerToken: '',
headers: [], headers: [],
params: [], params: [],
@@ -438,19 +453,23 @@
contentType(val) { contentType(val) {
this.rawInput = !this.knownContentTypes.includes(val); this.rawInput = !this.knownContentTypes.includes(val);
}, },
rawInput (status) { rawInput(status) {
if (status && this.rawParams === '') this.rawParams = '{}' if (status && this.rawParams === '') this.rawParams = '{}'
else this.setRouteQueryState() else this.setRouteQueryState()
}, },
'response.body': function (val) { 'response.body': function (val) {
var responseText = document.querySelector("div#response-details-wrapper pre code") != null ? document.querySelector("div#response-details-wrapper pre code") : null; var responseText = document.querySelector("div#response-details-wrapper pre code") != null ? document
.querySelector("div#response-details-wrapper pre code") : null;
if (responseText) { if (responseText) {
if (document.querySelector('.hljs') !== null && responseText.innerHTML.indexOf('<span class="hljs') !== -1) { if (document.querySelector('.hljs') !== null && responseText.innerHTML.indexOf('<span class="hljs') !== -
1) {
responseText.removeAttribute("class"); responseText.removeAttribute("class");
responseText.innerHTML = null; responseText.innerHTML = null;
responseText.innerText = this.response.body; responseText.innerText = this.response.body;
} else if (responseText && this.response.body != "(waiting to send request)" && this.response.body != "Loading..." && this.response.body != "See JavaScript console (F12) for details.") { } else if (responseText && this.response.body != "(waiting to send request)" && this.response.body !=
responseText.innerText = this.responseType == 'application/json' ? JSON.stringify(this.response.body, null, 2) : this.response.body; "Loading..." && this.response.body != "See JavaScript console (F12) for details.") {
responseText.innerText = this.responseType == 'application/json' ? JSON.stringify(this.response.body,
null, 2) : this.response.body;
hljs.highlightBlock(document.querySelector("div#response-details-wrapper pre code")); hljs.highlightBlock(document.querySelector("div#response-details-wrapper pre code"));
} else { } else {
responseText.innerText = this.response.body responseText.innerText = this.response.body
@@ -464,8 +483,11 @@
}, },
isValidURL() { isValidURL() {
const protocol = '^(https?:\\/\\/)?'; const protocol = '^(https?:\\/\\/)?';
const validIP = new RegExp(protocol + "(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])$"); const validIP = new RegExp(protocol +
const validHostname = new RegExp(protocol + "(([a-zA-Z0-9]|[a-zA-Z0-9][a-zA-Z0-9\-]*[a-zA-Z0-9])\.)*([A-Za-z0-9]|[A-Za-z0-9][A-Za-z0-9\-]*[A-Za-z0-9])$"); "(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])$");
const validHostname = new RegExp(protocol +
"(([a-zA-Z0-9]|[a-zA-Z0-9][a-zA-Z0-9\-]*[a-zA-Z0-9])\.)*([A-Za-z0-9]|[A-Za-z0-9][A-Za-z0-9\-]*[A-Za-z0-9])$"
);
return validIP.test(this.url) || validHostname.test(this.url); return validIP.test(this.url) || validHostname.test(this.url);
}, },
hasRequestBody() { hasRequestBody() {
@@ -526,12 +548,13 @@
requestString.push('const xhr = new XMLHttpRequest()'); requestString.push('const xhr = new XMLHttpRequest()');
const user = this.auth === 'Basic' ? this.httpUser : null const user = this.auth === 'Basic' ? this.httpUser : null
const pswd = this.auth === 'Basic' ? this.httpPassword : null const pswd = this.auth === 'Basic' ? this.httpPassword : null
requestString.push('xhr.open(' + this.method + ', ' + this.url + this.path + this.queryString + ', true, ' + user + ', ' + pswd + ')'); requestString.push('xhr.open(' + this.method + ', ' + this.url + this.path + this.queryString + ', true, ' +
user + ', ' + pswd + ')');
if (this.auth === 'Bearer Token') { if (this.auth === 'Bearer Token') {
requestString.push("xhr.setRequestHeader('Authorization', 'Bearer ' + " + this.bearerToken + ")"); requestString.push("xhr.setRequestHeader('Authorization', 'Bearer ' + " + this.bearerToken + ")");
} }
if (this.headers) { if (this.headers) {
this.headers.forEach(function(element) { this.headers.forEach(function (element) {
requestString.push('xhr.setRequestHeader(' + element.key + ', ' + element.value + ')'); requestString.push('xhr.setRequestHeader(' + element.key + ', ' + element.value + ')');
}) })
} }
@@ -562,7 +585,7 @@
headers.push(' "Content-Type": "' + this.contentType + '; charset=utf-8",\n') headers.push(' "Content-Type": "' + this.contentType + '; charset=utf-8",\n')
} }
if (this.headers) { if (this.headers) {
this.headers.forEach(function(element) { this.headers.forEach(function (element) {
headers.push(' "' + element.key + '": "' + element.value + '",\n'); headers.push(' "' + element.key + '": "' + element.value + '",\n');
}) })
} }
@@ -585,12 +608,13 @@
requestString.push(" '" + this.url + this.path + this.queryString + "' \\\n") requestString.push(" '" + this.url + this.path + this.queryString + "' \\\n")
if (this.auth === 'Basic') { if (this.auth === 'Basic') {
var basic = this.httpUser + ':' + this.httpPassword; var basic = this.httpUser + ':' + this.httpPassword;
requestString.push(" -H 'Authorization: Basic " + window.btoa(unescape(encodeURIComponent(basic))) + "' \\\n") requestString.push(" -H 'Authorization: Basic " + window.btoa(unescape(encodeURIComponent(basic))) +
"' \\\n")
} else if (this.auth === 'Bearer Token') { } else if (this.auth === 'Bearer Token') {
requestString.push(" -H 'Authorization: Bearer Token " + this.bearerToken + "' \\\n") requestString.push(" -H 'Authorization: Bearer Token " + this.bearerToken + "' \\\n")
} }
if (this.headers) { if (this.headers) {
this.headers.forEach(function(element) { this.headers.forEach(function (element) {
requestString.push(" -H '" + element.key + ": " + element.value + "' \\\n"); requestString.push(" -H '" + element.key + ": " + element.value + "' \\\n");
}) })
} }
@@ -767,7 +791,8 @@
const lastLine = textBeforeCursor.split('\n').slice(-1)[0]; const lastLine = textBeforeCursor.split('\n').slice(-1)[0];
const rightPadding = lastLine.match(/([\s\t]*).*/)[1] || ""; const rightPadding = lastLine.match(/([\s\t]*).*/)[1] || "";
event.target.value = textBeforeCursor + '\n' + rightPadding + textAfterCursor; event.target.value = textBeforeCursor + '\n' + rightPadding + textAfterCursor;
setTimeout(() => event.target.selectionStart = event.target.selectionEnd = oldSelectionStart + rightPadding.length + 1, 1); setTimeout(() => event.target.selectionStart = event.target.selectionEnd = oldSelectionStart + rightPadding
.length + 1, 1);
} else if (event.which === 9) { } else if (event.which === 9) {
event.preventDefault(); event.preventDefault();
const oldSelectionStart = event.target.selectionStart; const oldSelectionStart = event.target.selectionStart;
@@ -781,12 +806,12 @@
let time = new Date().toLocaleTimeString(); let time = new Date().toLocaleTimeString();
let date = new Date().toLocaleDateString(); let date = new Date().toLocaleDateString();
navigator.share({ navigator.share({
text: `Postwoman • API request builder at ${time} on ${date}`, text: `Postwoman • API request builder at ${time} on ${date}`,
url: window.location.href url: window.location.href
}).then(() => { }).then(() => {
// console.log('Thanks for sharing!'); // console.log('Thanks for sharing!');
}) })
.catch(console.error); .catch(console.error);
} else { } else {
this.$refs.copyRequest.innerHTML = this.copiedButton + '<span>Copied</span>'; this.$refs.copyRequest.innerHTML = this.copiedButton + '<span>Copied</span>';
var dummy = document.createElement('input'); var dummy = document.createElement('input');
@@ -847,20 +872,21 @@
return `${key}=${JSON.stringify(this[key])}&` return `${key}=${JSON.stringify(this[key])}&`
} else return '' } else return ''
} }
let flats = ['method', 'url', 'path', 'auth', 'httpUser', 'httpPassword', 'bearerToken', 'contentType'].map(item => flat(item)) let flats = ['method', 'url', 'path', 'auth', 'httpUser', 'httpPassword', 'bearerToken', 'contentType'].map(
item => flat(item))
let deeps = ['headers', 'params'].map(item => deep(item)) let deeps = ['headers', 'params'].map(item => deep(item))
let bodyParams = this.rawInput ? [flat('rawParams')] : [deep('bodyParams')]; let bodyParams = this.rawInput ? [flat('rawParams')] : [deep('bodyParams')];
this.$router.replace('/?' + flats.concat(deeps, bodyParams).join('').slice(0, -1)) this.$router.replace('/?' + flats.concat(deeps, bodyParams).join('').slice(0, -1))
}, },
setRouteQueries(queries) { setRouteQueries(queries) {
if (typeof(queries) !== 'object') throw new Error('Route query parameters must be a Object') if (typeof (queries) !== 'object') throw new Error('Route query parameters must be a Object')
for (const key in queries) { for (const key in queries) {
if (key === 'headers' || key === 'params' || key === 'bodyParams') this[key] = JSON.parse(queries[key]) if (key === 'headers' || key === 'params' || key === 'bodyParams') this[key] = JSON.parse(queries[key])
if (key === 'rawParams') { if (key === 'rawParams') {
this.rawInput = true this.rawInput = true
this.rawParams = queries['rawParams'] this.rawParams = queries['rawParams']
} else if (typeof(this[key]) === 'string') this[key] = queries[key] } else if (typeof (this[key]) === 'string') this[key] = queries[key]
} }
}, },
observeRequestButton() { observeRequestButton() {
@@ -876,22 +902,22 @@
observer.observe(requestElement); observer.observe(requestElement);
}, },
handleImport () { handleImport() {
let textarea = document.getElementById("import-text") let textarea = document.getElementById("import-text")
let text = textarea.value; let text = textarea.value;
try { try {
let parsedCurl = parseCurlCommand(text); let parsedCurl = parseCurlCommand(text);
this.url = parsedCurl.url.replace(/"/g,"").replace(/'/g,""); this.url = parsedCurl.url.replace(/"/g, "").replace(/'/g, "");
this.url = this.url[this.url.length -1] == '/' ? this.url.slice(0, -1): this.url; this.url = this.url[this.url.length - 1] == '/' ? this.url.slice(0, -1) : this.url;
this.path = ""; this.path = "";
this.headers this.headers
this.showModal = false; this.showModal = false;
this.headers = []; this.headers = [];
for (const key of Object.keys(parsedCurl.headers)) { for (const key of Object.keys(parsedCurl.headers)) {
this.headers.push({ this.headers.push({
key: key, key: key,
value: parsedCurl.headers[key] value: parsedCurl.headers[key]
}) })
} }
this.method = parsedCurl.method.toUpperCase(); this.method = parsedCurl.method.toUpperCase();
} catch (error) { } catch (error) {
@@ -900,6 +926,9 @@
}, },
toggleModal() { toggleModal() {
this.showModal = !this.showModal; this.showModal = !this.showModal;
},
switchVisibility() {
this.passwordFieldType = this.passwordFieldType === 'password' ? 'text' : 'password'
} }
}, },
mounted() { mounted() {
@@ -925,5 +954,4 @@
}) })
} }
} }
</script> </script>