[Code] fix query string key conflict (#36620) (#37060)

* fix code query string key conflict

* fix code go to definition url
This commit is contained in:
WangQianliang 2019-05-25 09:17:50 +08:00 committed by GitHub
parent bd19868e00
commit 61b93b938c
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
11 changed files with 94 additions and 36 deletions

View file

@ -57,7 +57,7 @@ export class EditorComponent extends React.Component<IProps> {
public componentDidMount(): void {
this.container = document.getElementById('mainEditor') as HTMLElement;
this.monaco = new MonacoHelper(this.container, this.props);
this.monaco = new MonacoHelper(this.container, this.props, this.props.location.search);
const { file } = this.props;
if (file && file.content) {
@ -100,6 +100,9 @@ export class EditorComponent extends React.Component<IProps> {
) {
this.revealPosition(this.props.revealPosition);
}
if (this.monaco && qs !== prevProps.location.search) {
this.monaco.updateUrlQuery(qs);
}
if (this.monaco && this.monaco.editor) {
if (prevProps.showBlame !== this.props.showBlame && this.props.showBlame) {
this.loadBlame(this.props.blames);

View file

@ -33,7 +33,7 @@ class CodeSideTabs extends React.PureComponent<Props> {
if (search.charAt(0) === '?') {
qs = search.substr(1);
}
const tab = parseQuery(qs).tab;
const tab = parseQuery(qs).sideTab;
return tab === Tabs.structure ? Tabs.structure : Tabs.file;
}
@ -87,7 +87,7 @@ class CodeSideTabs extends React.PureComponent<Props> {
const { history } = this.props;
const { pathname, search } = history.location;
// @ts-ignore
history.push(QueryString.replaceParamInUrl(`${pathname}${search}`, 'tab', tab));
history.push(QueryString.replaceParamInUrl(`${pathname}${search}`, 'sideTab', tab));
};
public render() {

View file

@ -107,7 +107,7 @@ exports[`render symbol tree correctly 1`] = `
</svg>
<a
className="code-symbol-link"
href="/github.com/vmware/clarity/blob/master/src/clr-angular/data/stack-view/stack-control.ts!L1:0?tab=structure"
href="/github.com/vmware/clarity/blob/master/src/clr-angular/data/stack-view/stack-control.ts!L1:0?sideTab=structure"
onClick={[Function]}
>
<div
@ -157,7 +157,7 @@ exports[`render symbol tree correctly 1`] = `
>
<a
className="code-symbol-link"
href="/github.com/vmware/clarity/blob/master/src/clr-angular/data/stack-view/stack-control.ts!L10:9?tab=structure"
href="/github.com/vmware/clarity/blob/master/src/clr-angular/data/stack-view/stack-control.ts!L10:9?sideTab=structure"
onClick={[Function]}
>
<div
@ -203,7 +203,7 @@ exports[`render symbol tree correctly 1`] = `
>
<a
className="code-symbol-link"
href="/github.com/vmware/clarity/blob/master/src/clr-angular/data/stack-view/stack-control.ts!L11:9?tab=structure"
href="/github.com/vmware/clarity/blob/master/src/clr-angular/data/stack-view/stack-control.ts!L11:9?sideTab=structure"
onClick={[Function]}
>
<div
@ -271,7 +271,7 @@ exports[`render symbol tree correctly 1`] = `
</svg>
<a
className="code-symbol-link"
href="/github.com/vmware/clarity/blob/master/src/clr-angular/data/stack-view/stack-control.ts!L13:0?tab=structure"
href="/github.com/vmware/clarity/blob/master/src/clr-angular/data/stack-view/stack-control.ts!L13:0?sideTab=structure"
onClick={[Function]}
>
<div
@ -319,7 +319,7 @@ exports[`render symbol tree correctly 1`] = `
>
<a
className="code-symbol-link"
href="/github.com/vmware/clarity/blob/master/src/clr-angular/data/stack-view/stack-control.ts!L14:2?tab=structure"
href="/github.com/vmware/clarity/blob/master/src/clr-angular/data/stack-view/stack-control.ts!L14:2?sideTab=structure"
onClick={[Function]}
>
<div
@ -365,7 +365,7 @@ exports[`render symbol tree correctly 1`] = `
>
<a
className="code-symbol-link"
href="/github.com/vmware/clarity/blob/master/src/clr-angular/data/stack-view/stack-control.ts!L15:2?tab=structure"
href="/github.com/vmware/clarity/blob/master/src/clr-angular/data/stack-view/stack-control.ts!L15:2?sideTab=structure"
onClick={[Function]}
>
<div
@ -411,7 +411,7 @@ exports[`render symbol tree correctly 1`] = `
>
<a
className="code-symbol-link"
href="/github.com/vmware/clarity/blob/master/src/clr-angular/data/stack-view/stack-control.ts!L17:14?tab=structure"
href="/github.com/vmware/clarity/blob/master/src/clr-angular/data/stack-view/stack-control.ts!L17:14?sideTab=structure"
onClick={[Function]}
>
<div
@ -457,7 +457,7 @@ exports[`render symbol tree correctly 1`] = `
>
<a
className="code-symbol-link"
href="/github.com/elastic/kibana/blob/master/packages/elastic-datemath/src/index.d.ts!L21:0?tab=structure"
href="/github.com/elastic/kibana/blob/master/packages/elastic-datemath/src/index.d.ts!L21:0?sideTab=structure"
onClick={[Function]}
>
<div
@ -503,7 +503,7 @@ exports[`render symbol tree correctly 1`] = `
>
<a
className="code-symbol-link"
href="/github.com/elastic/kibana/blob/master/packages/elastic-datemath/src/index.d.ts!L23:14?tab=structure"
href="/github.com/elastic/kibana/blob/master/packages/elastic-datemath/src/index.d.ts!L23:14?sideTab=structure"
onClick={[Function]}
>
<div
@ -571,7 +571,7 @@ exports[`render symbol tree correctly 1`] = `
</svg>
<a
className="code-symbol-link"
href="/github.com/elastic/openjdkMirror/blob/master/jdk/src/share/classes/java/util/HashMap.java!L137:13?tab=structure"
href="/github.com/elastic/openjdkMirror/blob/master/jdk/src/share/classes/java/util/HashMap.java!L137:13?sideTab=structure"
onClick={[Function]}
>
<div
@ -619,7 +619,7 @@ exports[`render symbol tree correctly 1`] = `
>
<a
className="code-symbol-link"
href="/github.com/elastic/openjdkMirror/blob/master/jdk/src/share/classes/java/util/HashMap.java!L140:30?tab=structure"
href="/github.com/elastic/openjdkMirror/blob/master/jdk/src/share/classes/java/util/HashMap.java!L140:30?sideTab=structure"
onClick={[Function]}
>
<div

View file

@ -5,17 +5,47 @@
*/
import React from 'react';
import { MemoryRouter } from 'react-router-dom';
import { MemoryRouter, match } from 'react-router-dom';
import renderer from 'react-test-renderer';
import { mockFunction } from '../../../utils/test_utils';
import {
mockFunction,
createLocation,
createMatch,
createHistory,
} from '../../../utils/test_utils';
import { CodeSymbolTree } from '../code_symbol_tree';
import { props } from './__fixtures__/props';
import { MainRouteParams, PathTypes } from '../../../common/types';
import { History, Location } from 'history';
const location: Location = createLocation({
pathname: '/github.com/google/guava/tree/master/guava/src/com/google',
});
const m: match<MainRouteParams> = createMatch({
path: '/:resource/:org/:repo/:pathType(blob|tree)/:revision/:path*:goto(!.*)?',
url: '/github.com/google/guava/tree/master/guava/src/com/google',
isExact: true,
params: {
resource: 'github.com',
org: 'google',
repo: 'guava',
pathType: PathTypes.tree,
revision: 'master',
path: 'guava/src/com/google',
},
});
const history: History = createHistory({ location, length: 8, action: 'POP' });
test('render symbol tree correctly', () => {
const tree = renderer
.create(
<MemoryRouter>
<CodeSymbolTree
location={location}
history={history}
match={m}
structureTree={props.structureTree}
closedPaths={[]}
openSymbolPath={mockFunction}

View file

@ -7,16 +7,16 @@
import { EuiFlexGroup, EuiIcon, EuiSideNav, EuiText, EuiToken } from '@elastic/eui';
import { IconType } from '@elastic/eui';
import React from 'react';
import { Link } from 'react-router-dom';
import { Link, RouteComponentProps } from 'react-router-dom';
import url from 'url';
import { Location, SymbolKind } from 'vscode-languageserver-types/lib/umd/main';
import { isEqual } from 'lodash';
import { RepositoryUtils } from '../../../common/repository_utils';
import { EuiSideNavItem } from '../../common/types';
import { EuiSideNavItem, MainRouteParams } from '../../common/types';
import { SymbolWithMembers } from '../../reducers/symbol';
interface Props {
interface Props extends RouteComponentProps<MainRouteParams> {
structureTree: SymbolWithMembers[];
closedPaths: string[];
openSymbolPath: (p: string) => void;
@ -64,6 +64,7 @@ export class CodeSymbolTree extends React.PureComponent<Props, { activeSymbol?:
) {
bg = <div className="code-full-width-node" />;
}
const queries = url.parse(this.props.location.search, true).query;
return (
<div className="code-symbol-container">
{bg}
@ -89,7 +90,7 @@ export class CodeSymbolTree extends React.PureComponent<Props, { activeSymbol?:
<Link
to={url.format({
pathname: RepositoryUtils.locationToUrl(location),
query: { tab: 'structure' },
query: { sideTab: 'structure', ...queries },
})}
className="code-symbol-link"
onClick={this.getClickHandler({ name, location })}

View file

@ -5,6 +5,7 @@
*/
import { connect } from 'react-redux';
import { withRouter } from 'react-router-dom';
import { closeSymbolPath, openSymbolPath } from '../../actions';
import { RootState } from '../../reducers';
import { structureSelector } from '../../selectors';
@ -20,7 +21,9 @@ const mapDispatchToProps = {
closeSymbolPath,
};
export const SymbolTree = connect(
mapStateToProps,
mapDispatchToProps
)(CodeSymbolTree);
export const SymbolTree = withRouter(
connect(
mapStateToProps,
mapDispatchToProps
)(CodeSymbolTree)
);

View file

@ -19,7 +19,10 @@ interface IResourceInput {
}
export class EditorService extends StandaloneCodeEditorServiceImpl {
public static async handleSymbolUri(qname: string) {
constructor(private readonly getUrlQuery: () => string) {
super();
}
public static async handleSymbolUri(qname: string, getUrlQuery: () => string) {
const result = await EditorService.findSymbolByQname(qname);
if (result.symbols.length > 0) {
const symbol = result.symbols[0].symbolInformation;
@ -27,7 +30,7 @@ export class EditorService extends StandaloneCodeEditorServiceImpl {
if (schema === 'git:') {
const { line, character } = symbol.location.range.start;
const url = uri + `!L${line + 1}:${character + 1}`;
history.push(url);
history.push(`${url}${getUrlQuery()}`);
}
}
}
@ -52,7 +55,7 @@ export class EditorService extends StandaloneCodeEditorServiceImpl {
) {
const { scheme, authority, path } = input.resource;
if (scheme === 'symbol') {
await EditorService.handleSymbolUri(authority);
await EditorService.handleSymbolUri(authority, this.getUrlQuery);
} else {
const uri = `/${authority}${path}`;
if (input.options && input.options.selection) {
@ -62,7 +65,7 @@ export class EditorService extends StandaloneCodeEditorServiceImpl {
if (currentPath === url) {
this.helper!.revealPosition(startLineNumber, startColumn);
} else {
history.push(url);
history.push(`${url}${this.getUrlQuery()}`);
}
}
}

View file

@ -29,7 +29,8 @@ export class MonacoHelper {
constructor(
public readonly container: HTMLElement,
private readonly editorActions: EditorActions
private readonly editorActions: EditorActions,
private urlQuery: string
) {
this.handleCopy = this.handleCopy.bind(this);
}
@ -47,7 +48,7 @@ export class MonacoHelper {
if (chrome.getInjected('enableLangserversDeveloping', false) === true) {
this.monaco.languages.registerDefinitionProvider('go', definitionProvider);
}
const codeEditorService = new EditorService();
const codeEditorService = new EditorService(this.getUrlQuery);
codeEditorService.setMonacoHelper(this);
this.editor = monaco.editor.create(
this.container!,
@ -80,7 +81,7 @@ export class MonacoHelper {
this.editor!.layout();
});
});
registerReferencesAction(this.editor);
registerReferencesAction(this.editor, this.getUrlQuery);
const hoverController: HoverController = new HoverController(this.editor);
hoverController.setReduxActions(this.editorActions);
document.addEventListener('copy', this.handleCopy);
@ -89,6 +90,14 @@ export class MonacoHelper {
});
}
updateUrlQuery = (q: string) => {
this.urlQuery = q;
};
getUrlQuery = () => {
return this.urlQuery;
};
public destroy = () => {
this.monaco = null;
document.removeEventListener('copy', this.handleCopy);

View file

@ -5,10 +5,14 @@
*/
import { editor } from 'monaco-editor';
import queryString from 'querystring';
import url from 'url';
import { parseSchema } from '../../../common/uri_util';
import { history } from '../../utils/url';
export function registerReferencesAction(e: editor.IStandaloneCodeEditor) {
export function registerReferencesAction(
e: editor.IStandaloneCodeEditor,
getUrlQuery: () => string
) {
e.addAction({
id: 'editor.action.referenceSearch.trigger',
label: 'Find All References',
@ -18,7 +22,7 @@ export function registerReferencesAction(e: editor.IStandaloneCodeEditor) {
const position = ed.getPosition();
const { uri } = parseSchema(ed.getModel().uri.toString());
const refUrl = `git:/${uri}!L${position.lineNumber - 1}:${position.column - 1}`;
const queries = queryString.parse(location.search);
const queries = url.parse(getUrlQuery(), true).query;
const query = queryString.stringify({
...queries,
tab: 'references',

View file

@ -8,6 +8,7 @@ import queryString from 'querystring';
import { Action } from 'redux-actions';
import { kfetch } from 'ui/kfetch';
import { TextDocumentPositionParams } from 'vscode-languageserver';
import Url from 'url';
import { call, put, select, takeEvery, takeLatest } from 'redux-saga/effects';
import { parseGoto, parseLspUrl, toCanonicalUrl } from '../../common/uri_util';
import { FileTree } from '../../model';
@ -41,6 +42,7 @@ import {
lastRequestPathSelector,
refUrlSelector,
repoScopeSelector,
urlQueryStringSelector,
} from '../selectors';
import { history } from '../utils/url';
import { mainRoutePattern } from './patterns';
@ -68,10 +70,11 @@ export function* watchLspMethods() {
yield takeLatest(String(findReferences), handleReferences);
}
function handleCloseReferences(action: Action<boolean>) {
function* handleCloseReferences(action: Action<boolean>) {
if (action.payload) {
const { pathname, search } = history.location;
const queryParams = queryString.parse(search);
const search = yield select(urlQueryStringSelector);
const { pathname } = history.location;
const queryParams = Url.parse(search, true).query;
if (queryParams.tab) {
delete queryParams.tab;
}

View file

@ -94,3 +94,5 @@ export const createTreeSelector = (path: string) => (state: RootState) => {
export const currentRepoSelector = (state: RootState) => state.repository.currentRepository;
export const repoScopeSelector = (state: RootState) => state.search.searchOptions.repoScope;
export const urlQueryStringSelector = (state: RootState) => state.route.match.location.search;