* Fix deeplinking for topbar plugin * Lint & added tests for search parsing/serializationbubble
@@ -623,13 +623,19 @@ export const parseSearch = () => { | |||||
continue | continue | ||||
} | } | ||||
i = params[i].split("=") | i = params[i].split("=") | ||||
map[decodeURIComponent(i[0])] = decodeURIComponent(i[1]) | |||||
map[decodeURIComponent(i[0])] = (i[1] && decodeURIComponent(i[1])) || "" | |||||
} | } | ||||
} | } | ||||
return map | return map | ||||
} | } | ||||
export const serializeSearch = (searchMap) => { | |||||
return Object.keys(searchMap).map(k => { | |||||
return encodeURIComponent(k) + "=" + encodeURIComponent(searchMap[k]) | |||||
}).join("&") | |||||
} | |||||
export const btoa = (str) => { | export const btoa = (str) => { | ||||
let buffer | let buffer | ||||
@@ -3,6 +3,7 @@ import PropTypes from "prop-types" | |||||
//import "./topbar.less" | //import "./topbar.less" | ||||
import Logo from "./logo_small.png" | import Logo from "./logo_small.png" | ||||
import {parseSearch, serializeSearch} from "../../core/utils" | |||||
export default class Topbar extends React.Component { | export default class Topbar extends React.Component { | ||||
@@ -41,6 +42,12 @@ export default class Topbar extends React.Component { | |||||
e.preventDefault() | e.preventDefault() | ||||
} | } | ||||
setSearch = (spec) => { | |||||
let search = parseSearch() | |||||
search["urls.primaryName"] = spec.name | |||||
window.location.search = serializeSearch(search) | |||||
} | |||||
setSelectedUrl = (selectedUrl) => { | setSelectedUrl = (selectedUrl) => { | ||||
const configs = this.props.getConfigs() | const configs = this.props.getConfigs() | ||||
const urls = configs.urls || [] | const urls = configs.urls || [] | ||||
@@ -52,6 +59,7 @@ export default class Topbar extends React.Component { | |||||
if(spec.url === selectedUrl) | if(spec.url === selectedUrl) | ||||
{ | { | ||||
this.setState({selectedIndex: i}) | this.setState({selectedIndex: i}) | ||||
this.setSearch(spec) | |||||
} | } | ||||
}) | }) | ||||
} | } | ||||
@@ -3,6 +3,8 @@ import expect from "expect" | |||||
import { fromJS, OrderedMap } from "immutable" | import { fromJS, OrderedMap } from "immutable" | ||||
import { | import { | ||||
mapToList, | mapToList, | ||||
parseSearch, | |||||
serializeSearch, | |||||
validatePattern, | validatePattern, | ||||
validateMinLength, | validateMinLength, | ||||
validateMaxLength, | validateMaxLength, | ||||
@@ -940,6 +942,48 @@ describe("utils", function() { | |||||
}) | }) | ||||
}) | }) | ||||
describe("parse and serialize search", function() { | |||||
afterEach(function() { | |||||
win.location.search = "" | |||||
}) | |||||
describe("parsing", function() { | |||||
it("works with empty search", function() { | |||||
win.location.search = "" | |||||
expect(parseSearch()).toEqual({}) | |||||
}) | |||||
it("works with only one key", function() { | |||||
win.location.search = "?foo" | |||||
expect(parseSearch()).toEqual({foo: ""}) | |||||
}) | |||||
it("works with keys and values", function() { | |||||
win.location.search = "?foo=fooval&bar&baz=bazval" | |||||
expect(parseSearch()).toEqual({foo: "fooval", bar: "", baz: "bazval"}) | |||||
}) | |||||
it("decode url encoded components", function() { | |||||
win.location.search = "?foo=foo%20bar" | |||||
expect(parseSearch()).toEqual({foo: "foo bar"}) | |||||
}) | |||||
}) | |||||
describe("serializing", function() { | |||||
it("works with empty map", function() { | |||||
expect(serializeSearch({})).toEqual("") | |||||
}) | |||||
it("works with multiple keys with and without values", function() { | |||||
expect(serializeSearch({foo: "", bar: "barval"})).toEqual("foo=&bar=barval") | |||||
}) | |||||
it("encode url components", function() { | |||||
expect(serializeSearch({foo: "foo bar"})).toEqual("foo=foo%20bar") | |||||
}) | |||||
}) | |||||
}) | |||||
describe("sanitizeUrl", function() { | describe("sanitizeUrl", function() { | ||||
it("should sanitize a `javascript:` url", function() { | it("should sanitize a `javascript:` url", function() { | ||||
const res = sanitizeUrl("javascript:alert('bam!')") | const res = sanitizeUrl("javascript:alert('bam!')") | ||||