diff --git a/package.json b/package.json index 709752ff36e6c1ec8baa366d22ef402397720c76..8d85d26ff157b2567e18fd8d08c9b69a4b6e7850 100644 --- a/package.json +++ b/package.json @@ -41,6 +41,7 @@ "dependencies": { "base64-js": "^1.2.0", "brace": "0.7.0", + "css.escape": "1.5.1", "deep-extend": "0.4.1", "expect": "1.20.2", "getbase": "^2.8.2", diff --git a/src/core/components/operations.jsx b/src/core/components/operations.jsx index d10f8a5b91c01bcb123d3af09424e912da6d997b..e0bf0645ae888caf237f69232c2753558488aeee 100644 --- a/src/core/components/operations.jsx +++ b/src/core/components/operations.jsx @@ -1,7 +1,7 @@ import React from "react" import PropTypes from "prop-types" import { helpers } from "swagger-client" -import { replaceSpacesWithUnderscores } from "core/utils" +import { createDeepLinkPath } from "core/utils" const { opId } = helpers export default class Operations extends React.Component { @@ -69,7 +69,7 @@ export default class Operations extends React.Component { let tagExternalDocsDescription = tagObj.getIn(["tagDetails", "externalDocs", "description"]) let tagExternalDocsUrl = tagObj.getIn(["tagDetails", "externalDocs", "url"]) - let isShownKey = ["operations-tag", replaceSpacesWithUnderscores(tag)] + let isShownKey = ["operations-tag", createDeepLinkPath(tag)] let showTag = layoutSelectors.isShown(isShownKey, docExpansion === "full" || docExpansion === "list") return ( @@ -124,7 +124,7 @@ export default class Operations extends React.Component { const operationId = op.getIn(["operation", "operationId"]) || op.getIn(["operation", "__originalOperationId"]) || opId(op.get("operation"), path, method) || op.get("id") - const isShownKey = ["operations", replaceSpacesWithUnderscores(tag), replaceSpacesWithUnderscores(operationId)] + const isShownKey = ["operations", createDeepLinkPath(tag), createDeepLinkPath(operationId)] const allowTryItOut = specSelectors.allowTryItOutFor(op.get("path"), op.get("method")) const response = specSelectors.responseFor(op.get("path"), op.get("method")) diff --git a/src/core/plugins/deep-linking/layout-wrap-actions.js b/src/core/plugins/deep-linking/layout-wrap-actions.js index 72d9894884aead0f93aa39bd9b54eeb94182846e..f1e67d12bdec262e7e2c183733bcde0020b8c174 100644 --- a/src/core/plugins/deep-linking/layout-wrap-actions.js +++ b/src/core/plugins/deep-linking/layout-wrap-actions.js @@ -1,4 +1,5 @@ import { setHash } from "./helpers" +import { createDeepLinkPath } from "core/utils" export const show = (ori, { getConfigs }) => (...args) => { ori(...args) @@ -19,12 +20,12 @@ export const show = (ori, { getConfigs }) => (...args) => { if(type === "operations") { let [, tag, operationId] = thing - setHash(`/${tag}/${operationId}`) + setHash(`/${createDeepLinkPath(tag)}/${createDeepLinkPath(operationId)}`) } if(type === "operations-tag") { let [, tag] = thing - setHash(`/${tag}`) + setHash(`/${createDeepLinkPath(tag)}`) } } diff --git a/src/core/plugins/deep-linking/spec-wrap-actions.js b/src/core/plugins/deep-linking/spec-wrap-actions.js index 79665536ca4b50d2dfc12ed7cf38202b406d9448..ebeebe5cb0c1232f7f5e27a1aa8c95273fa700f8 100644 --- a/src/core/plugins/deep-linking/spec-wrap-actions.js +++ b/src/core/plugins/deep-linking/spec-wrap-actions.js @@ -1,5 +1,5 @@ import scrollTo from "scroll-to-element" -import { replaceSpacesWithUnderscores } from "core/utils" +import { escapeDeepLinkPath } from "core/utils" const SCROLL_OFFSET = -5 let hasHashBeenParsed = false @@ -28,21 +28,21 @@ export const updateResolved = (ori, { layoutActions, getConfigs }) => (...args) hash = hash.slice(1) } - let [tag, operationId] = hash.split("/").map(v => replaceSpacesWithUnderscores(v)) + let [tag, operationId] = hash.split("/") if(tag && operationId) { // Pre-expand and scroll to the operation layoutActions.show(["operations-tag", tag], true) layoutActions.show(["operations", tag, operationId], true) - scrollTo(`#operations-${tag}-${operationId}`, { + scrollTo(`#operations-${escapeDeepLinkPath(tag)}-${escapeDeepLinkPath(operationId)}`, { offset: SCROLL_OFFSET }) } else if(tag) { // Pre-expand and scroll to the tag layoutActions.show(["operations-tag", tag], true) - scrollTo(`#operations-tag-${tag}`, { + scrollTo(`#operations-tag-${escapeDeepLinkPath(tag)}`, { offset: SCROLL_OFFSET }) } diff --git a/src/core/utils.js b/src/core/utils.js index 75ee0f0823fc9cf94fa22e515284918a92ac7f25..eda25c3f6d59291cde73e313a4cccb81491fdea3 100644 --- a/src/core/utils.js +++ b/src/core/utils.js @@ -8,6 +8,7 @@ import some from "lodash/some" import eq from "lodash/eq" import { memoizedSampleFromSchema, memoizedCreateXMLExample } from "core/plugins/samples/fn" import win from "./window" +import cssEscape from "css.escape" const DEFAULT_REPONSE_KEY = "default" @@ -651,4 +652,5 @@ export const shallowEqualKeys = (a,b, keys) => { }) } -export const replaceSpacesWithUnderscores = (str) => str.replace(/\s/, "_") +export const createDeepLinkPath = (str) => str.replace(/\s/g, "_") +export const escapeDeepLinkPath = (str) => cssEscape( createDeepLinkPath(str) ) \ No newline at end of file