Skip to content

Commit

Permalink
refactor(syntax-highlighting): use component wrapping for syntax high…
Browse files Browse the repository at this point in the history
…lighting activation (#9784)
  • Loading branch information
char0n committed Apr 5, 2024
1 parent 7260005 commit ac0d2a3
Show file tree
Hide file tree
Showing 15 changed files with 143 additions and 112 deletions.
26 changes: 11 additions & 15 deletions src/core/components/curl.jsx
Original file line number Diff line number Diff line change
@@ -1,39 +1,35 @@
import React from "react"
import PropTypes from "prop-types"
import { CopyToClipboard } from "react-copy-to-clipboard"
import get from "lodash/get"
import { requestSnippetGenerator_curl_bash } from "../plugins/request-snippets/fn"

export default class Curl extends React.Component {
static propTypes = {
getConfigs: PropTypes.func.isRequired,
getComponent: PropTypes.func.isRequired,
request: PropTypes.object.isRequired
}

render() {
let { request, getConfigs, getComponent } = this.props
let curl = requestSnippetGenerator_curl_bash(request)

const config = getConfigs()
const { request, getComponent } = this.props
const curl = requestSnippetGenerator_curl_bash(request)
const SyntaxHighlighter = getComponent("SyntaxHighlighter", true)

const curlBlock = get(config, "syntaxHighlight.activated") ? (
<SyntaxHighlighter language="bash" className="curl microlight">
{curl}
</SyntaxHighlighter>
) : (
<textarea readOnly={true} className="curl" value={curl}></textarea>
)

return (
<div className="curl-command">
<h4>Curl</h4>
<div className="copy-to-clipboard">
<CopyToClipboard text={curl}><button/></CopyToClipboard>
</div>
<div>
{curlBlock}
<SyntaxHighlighter
language="bash"
className="curl microlight"
renderPlainText={({ children, PlainTextViewer }) => (
<PlainTextViewer className="curl">{children}</PlainTextViewer>
)}
>
{curl}
</SyntaxHighlighter>
</div>
</div>
)
Expand Down
8 changes: 2 additions & 6 deletions src/core/components/example.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import ImPropTypes from "react-immutable-proptypes"
import { stringify } from "core/utils"

export default function Example(props) {
const { example, showValue, getComponent, getConfigs } = props
const { example, showValue, getComponent } = props

const Markdown = getComponent("Markdown", true)
const HighlightCode = getComponent("HighlightCode", true)
Expand All @@ -28,10 +28,7 @@ export default function Example(props) {
{showValue && example.has("value") ? (
<section className="example__section">
<div className="example__section-header">Example Value</div>
<HighlightCode
getConfigs={getConfigs}
value={stringify(example.get("value"))}
/>
<HighlightCode>{stringify(example.get("value"))}</HighlightCode>
</section>
) : null}
</div>
Expand All @@ -42,5 +39,4 @@ Example.propTypes = {
example: ImPropTypes.map.isRequired,
showValue: PropTypes.bool,
getComponent: PropTypes.func.isRequired,
getConfigs: PropTypes.func.getConfigs,
}
5 changes: 1 addition & 4 deletions src/core/components/model-example.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -113,10 +113,7 @@ const ModelExample = ({
{example ? (
example
) : (
<HighlightCode
value="(no example available)"
getConfigs={getConfigs}
/>
<HighlightCode>(no example available</HighlightCode>
)}
</div>
)}
Expand Down
7 changes: 1 addition & 6 deletions src/core/components/param-body.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,6 @@ export default class ParamBody extends PureComponent {
consumes: PropTypes.object,
consumesValue: PropTypes.string,
fn: PropTypes.object.isRequired,
getConfigs: PropTypes.func.isRequired,
getComponent: PropTypes.func.isRequired,
isExecute: PropTypes.bool,
specSelectors: PropTypes.object.isRequired,
Expand Down Expand Up @@ -98,7 +97,6 @@ export default class ParamBody extends PureComponent {
isExecute,
specSelectors,
pathMethod,
getConfigs,
getComponent,
} = this.props

Expand Down Expand Up @@ -127,10 +125,7 @@ export default class ParamBody extends PureComponent {
{
isEditBox && isExecute
? <TextArea className={ "body-param__text" + ( errors.count() ? " invalid" : "")} value={value} onChange={ this.handleOnChange }/>
: (value && <HighlightCode className="body-param__example"
language={ language }
getConfigs={ getConfigs }
value={ value }/>)
: (value && <HighlightCode className="body-param__example" language={ language }>{value}</HighlightCode>)
}
<div className="body-param-options">
{
Expand Down
15 changes: 7 additions & 8 deletions src/core/components/response-body.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,6 @@ export default class ResponseBody extends React.PureComponent {
static propTypes = {
content: PropTypes.any.isRequired,
contentType: PropTypes.string,
getConfigs: PropTypes.func.isRequired,
getComponent: PropTypes.func.isRequired,
headers: PropTypes.object,
url: PropTypes.string
Expand Down Expand Up @@ -51,7 +50,7 @@ export default class ResponseBody extends React.PureComponent {
}

render() {
let { content, contentType, url, headers={}, getConfigs, getComponent } = this.props
let { content, contentType, url, headers={}, getComponent } = this.props
const { parsedContent } = this.state
const HighlightCode = getComponent("HighlightCode", true)
const downloadName = "response_" + new Date().getTime()
Expand Down Expand Up @@ -108,23 +107,23 @@ export default class ResponseBody extends React.PureComponent {
body = "can't parse JSON. Raw result:\n\n" + content
}

bodyEl = <HighlightCode language={language} downloadable fileName={`${downloadName}.json`} value={ body } getConfigs={ getConfigs } canCopy />
bodyEl = <HighlightCode language={language} downloadable fileName={`${downloadName}.json`} canCopy>{body}</HighlightCode>

// XML
} else if (/xml/i.test(contentType)) {
body = formatXml(content, {
textNodesOnSameLine: true,
indentor: " "
})
bodyEl = <HighlightCode downloadable fileName={`${downloadName}.xml`} value={ body } getConfigs={ getConfigs } canCopy />
bodyEl = <HighlightCode downloadable fileName={`${downloadName}.xml`} canCopy>{body}</HighlightCode>

// HTML or Plain Text
} else if (toLower(contentType) === "text/html" || /text\/plain/.test(contentType)) {
bodyEl = <HighlightCode downloadable fileName={`${downloadName}.html`} value={ content } getConfigs={ getConfigs } canCopy />
bodyEl = <HighlightCode downloadable fileName={`${downloadName}.html`} canCopy>{content}</HighlightCode>

// CSV
} else if (toLower(contentType) === "text/csv" || /text\/csv/.test(contentType)) {
bodyEl = <HighlightCode downloadable fileName={`${downloadName}.csv`} value={ content } getConfigs={ getConfigs } canCopy />
bodyEl = <HighlightCode downloadable fileName={`${downloadName}.csv`} canCopy>{content}</HighlightCode>

// Image
} else if (/^image\//i.test(contentType)) {
Expand All @@ -138,7 +137,7 @@ export default class ResponseBody extends React.PureComponent {
} else if (/^audio\//i.test(contentType)) {
bodyEl = <pre className="microlight"><audio controls key={ url }><source src={ url } type={ contentType } /></audio></pre>
} else if (typeof content === "string") {
bodyEl = <HighlightCode downloadable fileName={`${downloadName}.txt`} value={ content } getConfigs={ getConfigs } canCopy />
bodyEl = <HighlightCode downloadable fileName={`${downloadName}.txt`} canCopy>{content}</HighlightCode>
} else if ( content.size > 0 ) {
// We don't know the contentType, but there was some content returned
if(parsedContent) {
Expand All @@ -148,7 +147,7 @@ export default class ResponseBody extends React.PureComponent {
<p className="i">
Unrecognized response type; displaying content as text.
</p>
<HighlightCode downloadable fileName={`${downloadName}.txt`} value={ parsedContent } getConfigs={ getConfigs } canCopy />
<HighlightCode downloadable fileName={`${downloadName}.txt`} canCopy>{parsedContent}</HighlightCode>
</div>

} else {
Expand Down
6 changes: 3 additions & 3 deletions src/core/components/response.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,15 +7,15 @@ import { getExtensions, fromJSOrdered, stringify } from "core/utils"
import { getKnownSyntaxHighlighterLanguage } from "core/utils/jsonParse"


const getExampleComponent = ( sampleResponse, HighlightCode, getConfigs ) => {
const getExampleComponent = ( sampleResponse, HighlightCode ) => {
if (sampleResponse == null) return null

const testValueForJson = getKnownSyntaxHighlighterLanguage(sampleResponse)
const language = testValueForJson ? "json" : null

return (
<div>
<HighlightCode className="example" getConfigs={ getConfigs } language={ language } value={ stringify(sampleResponse) } />
<HighlightCode className="example" language={language}>{stringify(sampleResponse)}</HighlightCode>
</div>
)
}
Expand Down Expand Up @@ -167,7 +167,7 @@ export default class Response extends React.Component {
shouldOverrideSchemaExample ? mediaTypeExample : undefined
)

const example = getExampleComponent( sampleResponse, HighlightCode, getConfigs )
const example = getExampleComponent( sampleResponse, HighlightCode )

return (
<tr className={ "response " + ( className || "") } data-code={code}>
Expand Down
9 changes: 3 additions & 6 deletions src/core/plugins/oas3/components/request-body.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -289,12 +289,9 @@ const RequestBody = ({
schema={mediaTypeValue.get("schema")}
specPath={specPath.push("content", contentType)}
example={
<HighlightCode
className="body-param__example"
getConfigs={getConfigs}
language={language}
value={stringify(requestBodyValue) || sampleRequestBody}
/>
<HighlightCode className="body-param__example" language={language}>
{stringify(requestBodyValue) || sampleRequestBody}
</HighlightCode>
}
includeWriteOnly={true}
/>
Expand Down
64 changes: 29 additions & 35 deletions src/core/plugins/request-snippets/request-snippets.jsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,5 @@
import React, { useRef, useEffect, useState } from "react"
import PropTypes from "prop-types"
import get from "lodash/get"
import isFunction from "lodash/isFunction"
import { CopyToClipboard } from "react-copy-to-clipboard"

const style = {
Expand Down Expand Up @@ -34,9 +32,7 @@ const activeStyle = {
borderBottom: "none"
}

const RequestSnippets = ({ request, requestSnippetsSelectors, getConfigs, getComponent }) => {
const config = isFunction(getConfigs) ? getConfigs() : null
const canSyntaxHighlight = get(config, "syntaxHighlight") !== false && get(config, "syntaxHighlight.activated", true)
const RequestSnippets = ({ request, requestSnippetsSelectors, getComponent }) => {
const rootRef = useRef(null)

const ArrowIcon = getComponent("ArrowUpIcon")
Expand All @@ -45,24 +41,6 @@ const RequestSnippets = ({ request, requestSnippetsSelectors, getConfigs, getCom

const [activeLanguage, setActiveLanguage] = useState(requestSnippetsSelectors.getSnippetGenerators()?.keySeq().first())
const [isExpanded, setIsExpanded] = useState(requestSnippetsSelectors?.getDefaultExpanded())
useEffect(() => {
const doIt = () => {

}
doIt()
}, [])
useEffect(() => {
const childNodes = Array
.from(rootRef.current.childNodes)
.filter(node => !!node.nodeType && node.classList?.contains("curl-command"))
// eslint-disable-next-line no-use-before-define
childNodes.forEach(node => node.addEventListener("mousewheel", handlePreventYScrollingBeyondElement, { passive: false }))

return () => {
// eslint-disable-next-line no-use-before-define
childNodes.forEach(node => node.removeEventListener("mousewheel", handlePreventYScrollingBeyondElement))
}
}, [request])

const snippetGenerators = requestSnippetsSelectors.getSnippetGenerators()
const activeGenerator = snippetGenerators.get(activeLanguage)
Expand Down Expand Up @@ -99,16 +77,25 @@ const RequestSnippets = ({ request, requestSnippetsSelectors, getConfigs, getCom
}
}

const SnippetComponent = canSyntaxHighlight ? (
<SyntaxHighlighter
language={activeGenerator.get("syntax")}
className="curl microlight"
>
{snippet}
</SyntaxHighlighter>
) : (
<textarea readOnly={true} className="curl" value={snippet}></textarea>
)
useEffect(() => {
const doIt = () => {

}
doIt()
}, [])

useEffect(() => {
const childNodes = Array
.from(rootRef.current.childNodes)
.filter(node => !!node.nodeType && node.classList?.contains("curl-command"))
// eslint-disable-next-line no-use-before-define
childNodes.forEach(node => node.addEventListener("mousewheel", handlePreventYScrollingBeyondElement, { passive: false }))

return () => {
// eslint-disable-next-line no-use-before-define
childNodes.forEach(node => node.removeEventListener("mousewheel", handlePreventYScrollingBeyondElement))
}
}, [request])

return (
<div className="request-snippets" ref={rootRef}>
Expand Down Expand Up @@ -142,7 +129,15 @@ const RequestSnippets = ({ request, requestSnippetsSelectors, getConfigs, getCom
</CopyToClipboard>
</div>
<div>
{SnippetComponent}
<SyntaxHighlighter
language={activeGenerator.get("syntax")}
className="curl microlight"
renderPlainText={({ children, PlainTextViewer }) => (
<PlainTextViewer className="curl">{children}</PlainTextViewer>
)}
>
{snippet}
</SyntaxHighlighter>
</div>
</div>
}
Expand All @@ -153,7 +148,6 @@ const RequestSnippets = ({ request, requestSnippetsSelectors, getConfigs, getCom
RequestSnippets.propTypes = {
request: PropTypes.object.isRequired,
requestSnippetsSelectors: PropTypes.object.isRequired,
getConfigs: PropTypes.object.isRequired,
getComponent: PropTypes.func.isRequired,
requestSnippetsActions: PropTypes.object,
}
Expand Down
Loading

0 comments on commit ac0d2a3

Please sign in to comment.