improve(deeplink): support utf16 tags and IDs (via #4921)

* ref #3958, support utf16 fragments on the deeplink plugin
* put -> head for UTF16 operation
this is a temporary fix, eventually we will run out
of methods and need to use a new targeting strategy
* drop obsolete %20 decoder
* add full test suite for UTF16 operation
* use encodeURIComponent when setting hash
* drop obsolete test cases
This commit is contained in:
James ZHANG
2018-10-19 05:55:30 +08:00
committed by kyle
parent 3c3b7e0bf1
commit 1791759de5
5 changed files with 87 additions and 8 deletions

View File

@@ -9,7 +9,8 @@ export default function() {
wrapActions: { wrapActions: {
loaded: (ori, system) => (...args) => { loaded: (ori, system) => (...args) => {
ori(...args) ori(...args)
const hash = window.location.hash // location.hash was an UTF-16 String, here is required UTF-8
const hash = decodeURIComponent(window.location.hash)
system.layoutActions.parseDeepLinkHash(hash) system.layoutActions.parseDeepLinkHash(hash)
} }
} }

View File

@@ -32,9 +32,9 @@ export const show = (ori, { getConfigs, layoutSelectors }) => (...args) => {
} }
if (urlHashArray.length === 2) { if (urlHashArray.length === 2) {
setHash(createDeepLinkPath(`/${type}/${assetName}`)) setHash(createDeepLinkPath(`/${encodeURIComponent(type)}/${encodeURIComponent(assetName)}`))
} else if (urlHashArray.length === 1) { } else if (urlHashArray.length === 1) {
setHash(createDeepLinkPath(`/${type}`)) setHash(createDeepLinkPath(`/${encodeURIComponent(type)}`))
} }
} catch (e) { } catch (e) {
@@ -73,7 +73,7 @@ export const parseDeepLinkHash = (rawHash) => ({ layoutActions, layoutSelectors,
hash = hash.slice(1) hash = hash.slice(1)
} }
const hashArray = hash.split("/").map(val => (val || "").replace(/%20/g, " ")) const hashArray = hash.split("/").map(val => (val || ""))
const isShownKey = layoutSelectors.isShownKeyFromUrlHashArray(hashArray) const isShownKey = layoutSelectors.isShownKeyFromUrlHashArray(hashArray)

View File

@@ -25,6 +25,14 @@ paths:
application/json: application/json:
schema: schema:
type: object type: object
/utf16fragments:
head:
operationId: "пошел"
tags: ["шеллы"]
summary: an operation
responses:
"200":
description: ok
/withUnderscores: /withUnderscores:
patch: patch:
operationId: "underscore_Operation" operationId: "underscore_Operation"

View File

@@ -17,6 +17,10 @@ paths:
responses: responses:
"200": "200":
description: ok description: ok
/utf16fragments:
head:
operationId: "пошел"
tags: ["шеллы"]
/withUnderscores: /withUnderscores:
patch: patch:
operationId: "underscore_Operation" operationId: "underscore_Operation"
@@ -28,7 +32,3 @@ paths:
/noOperationId: /noOperationId:
put: put:
tags: ["tagTwo"] tags: ["tagTwo"]
summary: an operation
responses:
"200":
description: ok

View File

@@ -114,6 +114,41 @@ describe("Deep linking feature", () => {
}) })
}) })
describe("Operation with UTF-16 characters", () => {
const elementToGet = ".opblock-head"
const correctElementId = "operations-шеллы-пошел"
const correctFragment = "#/%D1%88%D0%B5%D0%BB%D0%BB%D1%8B/%D0%BF%D0%BE%D1%88%D0%B5%D0%BB"
const correctHref = "#/шеллы/пошел"
it("should generate a correct element ID", () => {
cy.get(elementToGet)
.should("have.id", correctElementId)
})
it("should add the correct element fragment to the URL when expanded", () => {
cy.get(elementToGet)
.click()
.window()
.should("have.deep.property", "location.hash", correctFragment)
})
it("should provide an anchor link that has the correct fragment as href", () => {
cy.get(elementToGet)
.find("a")
.should("have.attr", "href", correctHref)
.click()
.should("have.attr", "href", correctHref) // should be valid after expanding
})
it("should expand the operation when reloaded", () => {
cy.visit(`${baseUrl}${correctFragment}`)
.reload()
.get(`${elementToGet}.is-open`)
.should("exist")
})
})
describe("Operation with no operationId", () => { describe("Operation with no operationId", () => {
const elementToGet = ".opblock-put" const elementToGet = ".opblock-put"
const correctElementId = "operations-tagTwo-put_noOperationId" const correctElementId = "operations-tagTwo-put_noOperationId"
@@ -276,6 +311,41 @@ describe("Deep linking feature", () => {
}) })
}) })
describe("Operation with UTF-16 characters", () => {
const elementToGet = ".opblock-head"
const correctElementId = "operations-шеллы-пошел"
const correctFragment = "#/%D1%88%D0%B5%D0%BB%D0%BB%D1%8B/%D0%BF%D0%BE%D1%88%D0%B5%D0%BB"
const correctHref = "#/шеллы/пошел"
it("should generate a correct element ID", () => {
cy.get(elementToGet)
.should("have.id", correctElementId)
})
it("should add the correct element fragment to the URL when expanded", () => {
cy.get(elementToGet)
.click()
.window()
.should("have.deep.property", "location.hash", correctFragment)
})
it("should provide an anchor link that has the correct fragment as href", () => {
cy.get(elementToGet)
.find("a")
.should("have.attr", "href", correctHref)
.click()
.should("have.attr", "href", correctHref) // should be valid after expanding
})
it("should expand the operation when reloaded", () => {
cy.visit(`${baseUrl}${correctFragment}`)
.reload()
.get(`${elementToGet}.is-open`)
.should("exist")
})
})
describe("Operation with no operationId", () => { describe("Operation with no operationId", () => {
const elementToGet = ".opblock-put" const elementToGet = ".opblock-put"
const correctElementId = "operations-tagTwo-put_noOperationId" const correctElementId = "operations-tagTwo-put_noOperationId"