Add sectionName prefix to all anchor links in order to fix method name collisions between sections

This commit is contained in:
Fabio Berger
2017-12-21 17:28:06 +01:00
parent 66cf60f9cb
commit 3e91773cd9
8 changed files with 64 additions and 20 deletions

View File

@@ -195,6 +195,7 @@ export class Documentation extends
const typeDefs = _.map(sortedTypes, customType => {
return (
<TypeDefinition
sectionName={sectionName}
key={`type-${customType.name}`}
customType={customType}
docsInfo={this.props.docsInfo}
@@ -203,7 +204,7 @@ export class Documentation extends
});
const sortedProperties = _.sortBy(docSection.properties, 'name');
const propertyDefs = _.map(sortedProperties, this.renderProperty.bind(this));
const propertyDefs = _.map(sortedProperties, this.renderProperty.bind(this, sectionName));
const sortedMethods = _.sortBy(docSection.methods, 'name');
const methodDefs = _.map(sortedMethods, method => {
@@ -217,6 +218,7 @@ export class Documentation extends
<EventDefinition
key={`event-${event.name}-${i}`}
event={event}
sectionName={sectionName}
docsInfo={this.props.docsInfo}
/>
);
@@ -311,14 +313,19 @@ export class Documentation extends
</div>
);
}
private renderProperty(property: Property): React.ReactNode {
private renderProperty(sectionName: string, property: Property): React.ReactNode {
return (
<div
key={`property-${property.name}-${property.type.name}`}
className="pb3"
>
<code className="hljs">
{property.name}: <Type type={property.type} docsInfo={this.props.docsInfo} />
{property.name}:
<Type
type={property.type}
sectionName={sectionName}
docsInfo={this.props.docsInfo}
/>
</code>
{property.source &&
<SourceLink
@@ -342,6 +349,7 @@ export class Documentation extends
return (
<MethodBlock
key={`method-${method.name}-${sectionName}`}
sectionName={sectionName}
method={method}
typeDefinitionByName={typeDefinitionByName}
libraryVersion={this.props.docsVersion}

View File

@@ -8,6 +8,7 @@ import {colors} from 'ts/utils/colors';
interface EventDefinitionProps {
event: Event;
sectionName: string;
docsInfo: DocsInfo;
}
@@ -26,7 +27,7 @@ export class EventDefinition extends React.Component<EventDefinitionProps, Event
const event = this.props.event;
return (
<div
id={event.name}
id={`${this.props.sectionName}-${event.name}`}
className="pb2"
style={{overflow: 'hidden', width: '100%'}}
onMouseOver={this.setAnchorVisibility.bind(this, true)}
@@ -54,6 +55,7 @@ export class EventDefinition extends React.Component<EventDefinitionProps, Event
const type = (
<Type
type={eventArg.type}
sectionName={this.props.sectionName}
docsInfo={this.props.docsInfo}
/>
);

View File

@@ -7,6 +7,7 @@ import {CustomType, TypeDocTypes} from 'ts/types';
interface InterfaceProps {
type: CustomType;
sectionName: string;
docsInfo: DocsInfo;
}
@@ -17,9 +18,14 @@ export function Interface(props: InterfaceProps) {
<span key={`property-${property.name}-${property.type}-${type.name}`}>
{property.name}:{' '}
{property.type.typeDocType !== TypeDocTypes.Reflection ?
<Type type={property.type} docsInfo={props.docsInfo} /> :
<Type
type={property.type}
sectionName={props.sectionName}
docsInfo={props.docsInfo}
/> :
<MethodSignature
method={property.type.method}
sectionName={props.sectionName}
shouldHideMethodName={true}
shouldUseArrowSyntax={true}
docsInfo={props.docsInfo}
@@ -33,7 +39,7 @@ export function Interface(props: InterfaceProps) {
const is = type.indexSignature;
const param = (
<span key={`indexSigParams-${is.keyName}-${is.keyType}-${type.name}`}>
{is.keyName}: <Type type={is.keyType} docsInfo={props.docsInfo} />
{is.keyName}: <Type type={is.keyType} sectionName={props.sectionName} docsInfo={props.docsInfo} />
</span>
);
properties.push((

View File

@@ -18,6 +18,7 @@ import {typeDocUtils} from 'ts/utils/typedoc_utils';
interface MethodBlockProps {
method: SolidityMethod|TypescriptMethod;
sectionName: string;
libraryVersion: string;
typeDefinitionByName: TypeDefinitionByName;
docsInfo: DocsInfo;
@@ -54,7 +55,7 @@ export class MethodBlock extends React.Component<MethodBlockProps, MethodBlockSt
return (
<div
id={method.name}
id={`${this.props.sectionName}-${method.name}`}
style={{overflow: 'hidden', width: '100%'}}
className="pb4"
onMouseOver={this.setAnchorVisibility.bind(this, true)}
@@ -74,7 +75,7 @@ export class MethodBlock extends React.Component<MethodBlockProps, MethodBlockSt
<AnchorTitle
headerSize={HeaderSizes.H3}
title={method.name}
id={method.name}
id={`${this.props.sectionName}-${method.name}`}
shouldShowAnchor={this.state.shouldShowAnchor}
/>
</div>
@@ -82,6 +83,7 @@ export class MethodBlock extends React.Component<MethodBlockProps, MethodBlockSt
<code className="hljs">
<MethodSignature
method={method}
sectionName={this.props.sectionName}
typeDefinitionByName={this.props.typeDefinitionByName}
docsInfo={this.props.docsInfo}
/>

View File

@@ -6,6 +6,7 @@ import {Parameter, SolidityMethod, TypeDefinitionByName, TypescriptMethod} from
interface MethodSignatureProps {
method: TypescriptMethod|SolidityMethod;
sectionName: string;
shouldHideMethodName?: boolean;
shouldUseArrowSyntax?: boolean;
typeDefinitionByName?: TypeDefinitionByName;
@@ -18,14 +19,19 @@ const defaultProps = {
};
export const MethodSignature: React.SFC<MethodSignatureProps> = (props: MethodSignatureProps) => {
const parameters = renderParameters(props.method, props.docsInfo, props.typeDefinitionByName);
const sectionName = 'types';
const parameters = renderParameters(
props.method, props.docsInfo, sectionName, props.typeDefinitionByName,
);
const paramString = _.reduce(parameters, (prev: React.ReactNode, curr: React.ReactNode) => {
return [prev, ', ', curr];
});
const methodName = props.shouldHideMethodName ? '' : props.method.name;
const typeParameterIfExists = _.isUndefined((props.method as TypescriptMethod).typeParameter) ?
undefined :
renderTypeParameter(props.method, props.docsInfo, props.typeDefinitionByName);
renderTypeParameter(
props.method, props.docsInfo, sectionName, props.typeDefinitionByName,
);
return (
<span>
{props.method.callPath}{methodName}{typeParameterIfExists}({paramString})
@@ -34,6 +40,7 @@ export const MethodSignature: React.SFC<MethodSignatureProps> = (props: MethodSi
{props.method.returnType &&
<Type
type={props.method.returnType}
sectionName={sectionName}
typeDefinitionByName={props.typeDefinitionByName}
docsInfo={props.docsInfo}
/>
@@ -45,7 +52,8 @@ export const MethodSignature: React.SFC<MethodSignatureProps> = (props: MethodSi
MethodSignature.defaultProps = defaultProps;
function renderParameters(
method: TypescriptMethod|SolidityMethod, docsInfo: DocsInfo, typeDefinitionByName?: TypeDefinitionByName,
method: TypescriptMethod|SolidityMethod, docsInfo: DocsInfo,
sectionName: string, typeDefinitionByName?: TypeDefinitionByName,
) {
const parameters = method.parameters;
const params = _.map(parameters, (p: Parameter) => {
@@ -53,6 +61,7 @@ function renderParameters(
const type = (
<Type
type={p.type}
sectionName={sectionName}
typeDefinitionByName={typeDefinitionByName}
docsInfo={docsInfo}
/>
@@ -67,7 +76,8 @@ function renderParameters(
}
function renderTypeParameter(
method: TypescriptMethod, docsInfo: DocsInfo, typeDefinitionByName?: TypeDefinitionByName,
method: TypescriptMethod, docsInfo: DocsInfo,
sectionName: string, typeDefinitionByName?: TypeDefinitionByName,
) {
const typeParameter = method.typeParameter;
const typeParam = (
@@ -75,6 +85,7 @@ function renderTypeParameter(
{`<${typeParameter.name} extends `}
<Type
type={typeParameter.type}
sectionName={sectionName}
typeDefinitionByName={typeDefinitionByName}
docsInfo={docsInfo}
/>

View File

@@ -37,6 +37,7 @@ const typeToSection: {[typeName: string]: string} = {
interface TypeProps {
type: TypeDef;
docsInfo: DocsInfo;
sectionName: string;
typeDefinitionByName?: TypeDefinitionByName;
}
@@ -66,6 +67,7 @@ export function Type(props: TypeProps): any {
<Type
key={key}
type={arg.elementType}
sectionName={props.sectionName}
typeDefinitionByName={props.typeDefinitionByName}
docsInfo={props.docsInfo}
/>[]
@@ -76,6 +78,7 @@ export function Type(props: TypeProps): any {
<Type
key={`type-${arg.name}-${arg.value}-${arg.typeDocType}`}
type={arg}
sectionName={props.sectionName}
typeDefinitionByName={props.typeDefinitionByName}
docsInfo={props.docsInfo}
/>
@@ -100,6 +103,7 @@ export function Type(props: TypeProps): any {
<Type
key={`type-${t.name}-${t.value}-${t.typeDocType}`}
type={t}
sectionName={props.sectionName}
typeDefinitionByName={props.typeDefinitionByName}
docsInfo={props.docsInfo}
/>
@@ -144,7 +148,9 @@ export function Type(props: TypeProps): any {
(props.docsInfo.isPublicType(typeName as string) ||
!_.isUndefined(sectionNameIfExists))) {
const id = Math.random().toString();
const typeDefinitionAnchorId = _.isUndefined(sectionNameIfExists) ? typeName : sectionNameIfExists;
const typeDefinitionAnchorId = _.isUndefined(sectionNameIfExists) ?
`${props.sectionName}-${typeName}` :
sectionNameIfExists;
let typeDefinition;
if (props.typeDefinitionByName) {
typeDefinition = props.typeDefinitionByName[typeName as string];
@@ -177,6 +183,7 @@ export function Type(props: TypeProps): any {
className="typeTooltip"
>
<TypeDefinition
sectionName={props.sectionName}
customType={typeDefinition}
shouldAddId={false}
docsInfo={props.docsInfo}

View File

@@ -13,6 +13,7 @@ import {colors} from 'ts/utils/colors';
import {utils} from 'ts/utils/utils';
interface TypeDefinitionProps {
sectionName: string;
customType: CustomType;
shouldAddId?: boolean;
docsInfo: DocsInfo;
@@ -46,6 +47,7 @@ export class TypeDefinition extends React.Component<TypeDefinitionProps, TypeDef
codeSnippet = (
<Interface
type={customType}
sectionName={this.props.sectionName}
docsInfo={this.props.docsInfo}
/>
);
@@ -85,9 +87,14 @@ export class TypeDefinition extends React.Component<TypeDefinitionProps, TypeDef
type
</span> {customType.name} ={' '}
{customType.type.typeDocType !== TypeDocTypes.Reflection ?
<Type type={customType.type} docsInfo={this.props.docsInfo} /> :
<Type
type={customType.type}
sectionName={this.props.sectionName}
docsInfo={this.props.docsInfo}
/> :
<MethodSignature
method={customType.type.method}
sectionName={this.props.sectionName}
shouldHideMethodName={true}
shouldUseArrowSyntax={true}
docsInfo={this.props.docsInfo}
@@ -101,7 +108,7 @@ export class TypeDefinition extends React.Component<TypeDefinitionProps, TypeDef
throw utils.spawnSwitchErr('type.kindString', customType.kindString);
}
const typeDefinitionAnchorId = customType.name;
const typeDefinitionAnchorId = `${this.props.sectionName}-${customType.name}`;
return (
<div
id={this.props.shouldAddId ? typeDefinitionAnchorId : ''}

View File

@@ -130,7 +130,8 @@ export class NestedSidebarMenu extends React.Component<NestedSidebarMenuProps, N
return (
<ul style={{margin: 0, listStyleType: 'none', paddingLeft: 0}} key={menuItemName}>
{_.map(entityNames, entityName => {
const id = utils.getIdFromName(entityName);
const name = `${menuItemName}-${entityName}`;
const id = utils.getIdFromName(name);
return (
<li key={`menuItem-${entityName}`}>
<ScrollLink
@@ -138,10 +139,10 @@ export class NestedSidebarMenu extends React.Component<NestedSidebarMenuProps, N
offset={0}
duration={constants.DOCS_SCROLL_DURATION_MS}
containerId={constants.DOCS_CONTAINER_ID}
onTouchTap={this.onMenuItemClick.bind(this, entityName)}
onTouchTap={this.onMenuItemClick.bind(this, name)}
>
<MenuItem
onTouchTap={this.onMenuItemClick.bind(this, menuItemName)}
onTouchTap={this.onMenuItemClick.bind(this, name)}
style={{minHeight: 35}}
innerDivStyle={{paddingLeft: 36, fontSize: 14, lineHeight: '35px'}}
>
@@ -154,8 +155,8 @@ export class NestedSidebarMenu extends React.Component<NestedSidebarMenuProps, N
</ul>
);
}
private onMenuItemClick(menuItemName: string): void {
const id = utils.getIdFromName(menuItemName);
private onMenuItemClick(name: string): void {
const id = utils.getIdFromName(name);
utils.setUrlHash(id);
this.props.onMenuItemClick();
}