# src/view/Parts.ts

`

1import { m, Vnode} from <quote>'hslayout'</quote>;

2import { tooltip } from <quote>'./Tooltip'</quote>;

3import { DocSets } from <quote>'../DocSets'</quote>;

4import { log as _log } from <quote>'hsutil'</quote>; const log = _log(<quote>'Parts'</quote>);

5

6const SourceBase = <quote>'data/src/'</quote>;

7

8

9<comment>// TODO: sort flags in array to garantee sequence of printing</comment>

10<comment></comment>export function flags(mdl:any, ignore:string[]=[]) {

11 const ignoreExportInKind = [<quote>'Method'</quote>, <quote>'Property'</quote>];

12 const knownFlags = {

13 isExported: <quote>'export'</quote>,

14 isExternal: <quote>'external'</quote>, <comment>// </comment>

15<comment></comment> isPublic: <quote>'public'</quote>,

16 isPrivate: <quote>'private'</quote>,

17 isProtected: <quote>'protected'</quote>,

18 isConstructorProperty: <quote>'constructorProperty'</quote>,

19 isAbstract: <quote>'abstract'</quote>,

20 isConst: <quote>'const'</quote>,

21 isLet: <quote>'let'</quote>,

22 isVar: <quote>'var'</quote>,

23 isStatic: <quote>'static'</quote>,

24 isOptional: <quote>'optional'</quote>

25 };

26 return m(<quote>'span.hs-item-flags'</quote>, !mdl.flags? [] :

27 Object.keys(mdl.flags).map((f:string) => {

28 let ign = false;

29 let flag = knownFlags[f];

30 if (flag === undefined) { flag = f; }

31 else { ign = (ignore.indexOf(flag) >= 0); }

32 if (flag === <quote>'export'</quote> && ignoreExportInKind.indexOf(mdl.kindString)>=0) { ign = true; }

33 return m(`span.hs-item-${ign?<quote>'ignore'</quote>:(flag===f?<quote>'unknown'</quote>:flag)}-flag`, ign? undefined : flag);

34 })

35 );

36}

37

38export function kindString(mdl:any) {

39 return m(<quote>'span.hs-item-kind'</quote>, mdl.kindString);

40}

41

42export function itemName(mdl:any, sub:any) {

43 return m(<quote>'span.hs-item-name'</quote>, !mdl.fullPath? sub.name : libLink(<quote>'a'</quote>, mdl.lib, mdl.fullPath, sub.name));

44}

45

46

47export function itemTooltip(mdl:any) {

48 return m(<quote>'span.hs-item-name'</quote>, tooltip(mdl.name, <quote>'class name and then some'</quote>, <quote>'bottom'</quote>));

49}

50

51export function extensionOf(mdl:any) {

52 return m(<quote>'span.hs-item-extensions'</quote>, !mdl.extendedTypes? undefined : [

53 m(<quote>'span.hs-item-extends'</quote>, <quote>'extends'</quote>),

54 m(<quote>'span'</quote>, mdl.extendedTypes.map((t:any, i:number) =>

55 m(<quote>'span.hs-item-extension'</quote>, [

56 libLink(<quote>'a'</quote>, mdl.lib, DocSets.get(mdl.lib, t.id).fullPath, t.name),

57 mdl.extendedTypes.length>(i+1)? <quote>', '</quote>: <quote>''</quote>

58 ])

59 )),

60 ]);

61}

62

63export function implementationOf(mdl:any) {

64 return !mdl.implementedTypes? undefined : m(<quote>'span.hs-item-implementations'</quote>, [

65 m(<quote>'span.hs-item-implements'</quote>, <quote>'implements'</quote>),

66 m(<quote>'span'</quote>, mdl.implementedTypes.map((t:any, i:number) =>

67 m(<quote>'span.hs-item-extension'</quote>, [

68 libLink(<quote>'a'</quote>, mdl.lib, DocSets.get(mdl.lib, t.id).fullPath, t.name),

69 mdl.implementedTypes.length>(i+1)? <quote>', '</quote>: <quote>''</quote>

70 ])

71 )),

72 ]);

73}

74

75export function extendedBy(mdl:any) {

76 return !mdl.extendedBy? undefined : m(<quote>'div.hs-item-extensions'</quote>,[

77 m(<quote>'span.hs-item-extendedby'</quote>, <quote>'extended by'</quote>),

78 m(<quote>'span'</quote>, mdl.extendedBy.map((t:any, i:number) =>

79 m(<quote>'span.hs-item-extendedby'</quote>, [

80 libLink(<quote>'a'</quote>, mdl.lib, DocSets.get(mdl.lib, t.id).fullPath, t.name),

81 mdl.extendedBy.length>(i+1)? <quote>', '</quote>: <quote>''</quote>

82 ])

83 )),

84 ]);

85}

86

87export function implementedBy(mdl:any) {

88 return !mdl.implementedBy? undefined : m(<quote>'div.hs-item-implementations'</quote>,[

89 m(<quote>'span.hs-item-implementedby'</quote>, <quote>'implemented by'</quote>),

90 m(<quote>'span'</quote>, mdl.implementedBy.map((t:any, i:number) =>

91 m(<quote>'span.hs-item-implementedby'</quote>, [

92 libLink(<quote>'a'</quote>, mdl.lib, DocSets.get(mdl.lib, t.id).fullPath, t.name),

93 mdl.implementedBy.length>(i+1)? <quote>', '</quote>: <quote>''</quote>

94 ])

95 )),

96 ]);

97}

98

99export function inheritedFrom(mdl:any) {

100 if (mdl.inheritedFrom) {

101 let parent = DocSets.get(mdl.lib, mdl.inheritedFrom.id);

102 parent = DocSets.get(mdl.lib, parent.fullPath.substring(0, parent.fullPath.lastIndexOf(<quote>'.'</quote>)));

103 return m(<quote>'span.hs-item-inherited-from'</quote>, [

104 m(<quote>'span'</quote>, <quote>'inherited from '</quote>),

105 libLink(<quote>'a'</quote>, parent.lib, parent.fullPath, parent.name)

106 ]);

107 } else {

108 return m(<quote>'span.hs-item-inherited-from'</quote>, undefined);

109 }

110}

111

112export function sourceLink(mdl:any) {

113 const source = mdl.sources? mdl.sources[0] : undefined;

114 if (source) {

115 let file = (source.fileName || <quote>''</quote>).replace(<quote>'.ts'</quote>, <quote>'.html'</quote>);

116 const index = file.indexOf(mdl.lib);

117 if (index>0) {

118 file = file.substr(index); <comment>// only consider links within the docSet (everything after the lib name)</comment>

119<comment></comment> }

120 return m(<quote>'span.hs-item-member-source'</quote>,

121 m(<quote>'a'</quote>, { href:`${SourceBase}${mdl.lib}/${file}#${Math.max(0,source.line-5)}`, target:<quote>"_blank"</quote>}, <quote>'[source]'</quote>)

122 );

123 } else {

124 return m(<quote>'span.hs-item-member-source'</quote>, <quote>''</quote>);

125 }

126}

127

128<comment>/**</comment>

129<comment> * creates a library link on the specified `name`. </comment>

130<comment> * The link points to `/api/<lib>/<id>`</comment>

131<comment> * @param css the css tag selector to use</comment>

132<comment> * @param cls the css class selector to use</comment>

133<comment> * @param lib the lib string to point to</comment>

134<comment> * @param id the id number to point to</comment>

135<comment> * @param name the name on which to formt he link</comment>

136<comment> */</comment>

137export function libLink(css:string, lib:string, id:string, name:string) {

138 return m(css, { href:`#!/api/${lib}/${id}`, oncreate: m.route.link, onupdate: m.route.link }, name);

139}

140

141<comment>/**</comment>

142<comment> * creates a function or method signature</comment>

143<comment> */</comment>

144export function signature(s:any, mdl:any): Vnode {

145 function params(s:any) {

146 return s.parameters.map((p:any, i:number) => m(<quote>'span'</quote>, [

147 comma(i),

148 m(<quote>'span.hs-item-sig-param'</quote>, [

149 m(`span.hs-item-name${optional(p.flags)}`, p.name),

150 type(p, mdl.lib)

151 ])

152 ]));

153 }

154 const comma = (i:number) => (i>0)? <quote>', '</quote>: <quote>''</quote>;

155 const optional = (flags:any) => (flags && flags.isOptional)? <quote>'.hs-item-optional'</quote> : <quote>''</quote>;

156

157 let sig = [];

158 if (s) {

159 if (s.parameters) { sig = params(s); }

160 else if (s.type && s.type.declaration && s.type.declaration.indexSignature) {

161 sig = s.type.declaration.indexSignature.map((isig:any) => m(<quote>'span'</quote>, params(isig)));

162 }

163 else if (s.type && s.type.declaration && s.type.declaration.signatures) {

164 sig = s.type.declaration.signatures.map((isig:any) => m(<quote>'span'</quote>, params(isig)));

165 }

166 switch (mdl.kindString) {

167 <comment>// unmodified:</comment>

168<comment></comment> case <quote>'Variable'</quote>:

169 case <quote>'Parameter'</quote>:

170 case <quote>'Property'</quote>:

171 case <quote>'Type alias'</quote>:

172 case <quote>'Interface'</quote>:

173 case <quote>'Class'</quote>:

174 case <quote>'External module'</quote>:

175 case <quote>'Enumeration'</quote>:

176 case <quote>'Enumeration member'</quote>:

177 break;

178 <comment>// enclose in (...):</comment>

179<comment></comment> case undefined: break;

180 case <quote>'Method'</quote>:

181 case <quote>'Accessor'</quote>:

182 case <quote>'Function'</quote>:

183 case <quote>'Constructor'</quote>:

184 case <quote>'Object literal'</quote>:

185 sig.unshift(m(<quote>'span.hs-item-name'</quote>, <quote>'('</quote>));

186 sig.push(m(<quote>'span.hs-item-name'</quote>, <quote>')'</quote>));

187 break;

188 default: log.warn(`unexpected kindString <quote>'${mdl.kindString}'</quote>`);

189 }

190 }

191 return m(<quote>'span.hs-item-signature'</quote>, sig);

192}

193

194<comment>/**</comment>

195<comment> * adds a default value, if defined</comment>

196<comment> */</comment>

197export function defaultVal(s:any, lib:string): Vnode {

198 if (s && s.defaultValue) {

199 let val = ` = ${s.defaultValue}`.replace(/{/gi, <quote>'{ '</quote>).replace(/}/gi, <quote>' }'</quote>);

200 return m(<quote>'span.hs-item-default'</quote>, val);

201 } else {

202 return;

203 }

204}

205

206export function type(t:any, lib:string) {

207 function _type(tt:any):any {

208 if (!tt) { return <quote>''</quote>; }

209 else { switch (tt.type) {

210 case undefined: return <quote>''</quote>;

211 case <quote>'array'</quote>: return m(<quote>'span.hs-item-type-array'</quote>, [<quote>'Array<'</quote>, _type(tt.elementType), <quote>'>'</quote>]);

212

213 case <quote>'tuple'</quote>: return m(<quote>'span.hs-item-type-tuple'</quote>, [

214 <quote>'[ '</quote>,

215 ...tt.elements.map((e:any, i:number) => [i>0?<quote>', '</quote>:undefined, _type(e)]),

216 <quote>' ]'</quote>

217 ]);

218 case <quote>'intrinsic'</quote>:

219 case <quote>'instrinct'</quote>: return m(<quote>'span.hs-item-type-instrinct'</quote>, tt.id? libLink(<quote>'span'</quote>, lib, tt.fullPath, tt.name) : tt.name);

220 case <quote>'stringLiteral'</quote>: return m(<quote>'span.hs-item-type-string-literal'</quote>, tt.type);

221 case <quote>'union'</quote>: return m(<quote>'span.hs-item-type-union'</quote>, [...tt.types.map((e:any, i:number) => [i>0?<quote>' | '</quote>:undefined, _type(e)])]);

222 case <quote>'reference'</quote>: let refRes = tt.name;

223 if (tt.id) {

224 const typeRef = DocSets.get(lib, tt.id);

225 if (typeRef.typeArguments) { refRes = typeRef.name+<quote>'<'</quote>+ typeRef.typeArguments.map(_type).join(<quote>', '</quote>) + <quote>'>'</quote>; }

226 else if (typeRef.id) { refRes = libLink(<quote>'a'</quote>, lib, typeRef.fullPath, typeRef.name); }

227 else { refRes = typeRef.name; }

228 }

229 return m(<quote>'span.hs-item-type-reference'</quote>, refRes);

230 case <quote>'reflection'</quote>: let rflRes;

231 if (tt.declaration) {

232 rflRes = !tt.declaration.children? tt.declaration.kindString :

233 m(<quote>'span.hs-item-reflection'</quote>, [

234 <quote>'{ '</quote>,

235 ...tt.declaration.children.map((c:any, i:number) =>

236 [i>0?<quote>', '</quote>:undefined, c.name, <quote>': '</quote>, _type(c.type)]

237 ),

238 <quote>' }'</quote>

239 ]);

240 } else {

241 rflRes = <quote>'UNKNOWN'</quote>;

242 }

243 return m(<quote>'span.hs-item-type-reflection'</quote>, rflRes);

244 default: log.warn(<quote>'unknown type '</quote>+ tt.type);

245 log.debug(log.inspect(t,3));

246 return t.type;

247 }}

248 }

249

250 try {

251 return m(<quote>'span'</quote>, !t.type? <quote>''</quote>: [

252 m(<quote>'span.hs-item-name'</quote>,<quote>':'</quote>),

253 m(<quote>'span.hs-item-sig-type'</quote>, _type(t.type)),

254 defaultVal(t, lib)

255 ]);

256 } catch(e) { log.error(e); log.error(e.trace); }

257}

258

259export function makeID(section:string, mdl:any) {

260 let result = section? section+<quote>'_'</quote> : <quote>''</quote>;

261 result = (result + (mdl.name || <quote>''</quote>)).toLowerCase();

262 return (result!==<quote>''</quote>)? result : undefined;

263}

`