Skip to content

Commit 0c57874

Browse files
committed
Add syntax highlighting to the curl section while preserving copying ability 💾
1 parent c1cb8b7 commit 0c57874

File tree

2 files changed

+35
-10
lines changed

2 files changed

+35
-10
lines changed

src/core/components/curl.jsx

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,16 @@
11
import React from "react"
22
import PropTypes from "prop-types"
33
import curlify from "core/curlify"
4+
import Lowlight from "../lowlight"
5+
import {copyToClipboard} from "../utils"
46

57
export default class Curl extends React.Component {
68
static propTypes = {
79
request: PropTypes.object.isRequired
810
}
911

10-
handleFocus(e) {
11-
e.target.select()
12-
document.execCommand("copy")
12+
copy(curlCommand) {
13+
return () => copyToClipboard(curlCommand)
1314
}
1415

1516
render() {
@@ -18,9 +19,10 @@ export default class Curl extends React.Component {
1819

1920
return (
2021
<div>
21-
<h4>Curl</h4>
22-
<div className="copy-paste">
23-
<textarea onFocus={this.handleFocus} readOnly="true" className="curl" style={{ whiteSpace: "normal" }} value={curl}></textarea>
22+
<h4>Curl <i onClick={this.copy(curl)}>(copyCommand)</i></h4>
23+
24+
<div>
25+
<Lowlight language="bash" className="curl" style={{ whiteSpace: "normal" }} value={curl}/>
2426
</div>
2527
</div>
2628
)

src/core/utils.js

Lines changed: 27 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -182,20 +182,43 @@ export function mapToList(map, keyNames="key", collectedKeys=Im.Map()) {
182182
return list
183183
}
184184

185+
export const copyToClipboard = str => {
186+
// adapted from https://hackernoon.com/copying-text-to-clipboard-with-javascript-df4d4988697f
187+
const el = document.createElement("textarea")
188+
el.value = str
189+
el.setAttribute("readonly", "")
190+
el.style.position = "absolute"
191+
el.style.left = "-9999px"
192+
193+
document.body.appendChild(el)
194+
// preserve selection
195+
const selected =
196+
document.getSelection().rangeCount > 0
197+
? document.getSelection().getRangeAt(0)
198+
: false
199+
el.select()
200+
document.execCommand("copy")
201+
document.body.removeChild(el)
202+
if (selected) {
203+
document.getSelection().removeAllRanges()
204+
document.getSelection().addRange(selected)
205+
}
206+
}
207+
185208
export function extractFileNameFromContentDispositionHeader(value){
186209
let patterns = [
187210
/filename\*=[^']+'\w*'"([^"]+)";?/i,
188211
/filename\*=[^']+'\w*'([^;]+);?/i,
189212
/filename="([^;]*);?"/i,
190213
/filename=([^;]*);?/i
191214
]
192-
215+
193216
let responseFilename
194217
patterns.some(regex => {
195218
responseFilename = regex.exec(value)
196219
return responseFilename !== null
197220
})
198-
221+
199222
if (responseFilename !== null && responseFilename.length > 1) {
200223
try {
201224
return decodeURIComponent(responseFilename[1])
@@ -650,15 +673,15 @@ export function paramToIdentifier(param, { returnAll = false, allowHashes = true
650673
}
651674
const paramName = param.get("name")
652675
const paramIn = param.get("in")
653-
676+
654677
let generatedIdentifiers = []
655678

656679
// Generate identifiers in order of most to least specificity
657680

658681
if (param && param.hashCode && paramIn && paramName && allowHashes) {
659682
generatedIdentifiers.push(`${paramIn}.${paramName}.hash-${param.hashCode()}`)
660683
}
661-
684+
662685
if(paramIn && paramName) {
663686
generatedIdentifiers.push(`${paramIn}.${paramName}`)
664687
}

0 commit comments

Comments
 (0)