57edb1fc602fd2140075f7660d815a9e9869b0e4
[platform/core/csapi/tizenfx.git] / docs / template / tizen / UniversalReference.common.js
1 // Copyright (c) Microsoft. All rights reserved. Licensed under the MIT license. See LICENSE file in the project root for full license information.
2
3 var common = require('./common.js');;
4 var classCategory = 'class';
5 var namespaceCategory = 'ns';
6
7 exports.transform = function (model) {
8   if (!model) return
9
10   handleItem(model, model._gitContribute, model._gitUrlPattern);
11   if (model.children) {
12     normalizeChildren(model.children).forEach(function (item) {
13       handleItem(item, model._gitContribute, model._gitUrlPattern);
14     });
15   };
16
17   if (model.type) {
18     switch (model.type.toLowerCase()) {
19       case 'namespace':
20         model.isNamespace = true;
21         if (model.children) groupChildren(model, namespaceCategory);
22         break;
23       case 'package':
24       case 'class':
25       case 'interface':
26       case 'struct':
27       case 'delegate':
28         model.isClass = true;
29         if (model.children) groupChildren(model, classCategory);
30         model[getTypePropertyName(model.type)] = true;
31         break;
32       case 'enum':
33         model.isEnum = true;
34         if (model.children) groupChildren(model, classCategory);
35         model[getTypePropertyName(model.type)] = true;
36         break;
37       default:
38         break;
39     }
40   }
41
42   return model;
43 }
44
45 exports.getBookmarks = function (model, ignoreChildren)  {
46   if (!model || !model.type || model.type.toLowerCase() === "namespace") return null;
47
48   var bookmarks = {};
49
50   if (typeof ignoreChildren == 'undefined' || ignoreChildren === false) {
51     if (model.children) {
52       normalizeChildren(model.children).forEach(function (item) {
53         bookmarks[item.uid] = common.getHtmlId(item.uid);
54         if (item.overload && item.overload.uid) {
55           bookmarks[item.overload.uid] = common.getHtmlId(item.overload.uid);
56         }
57       });
58     }
59   }
60
61   // Reference's first level bookmark should have no anchor
62   bookmarks[model.uid] = "";
63   return bookmarks;
64 }
65
66 function handleItem(vm, gitContribute, gitUrlPattern) {
67   // get contribution information
68   vm.docurl = common.getImproveTheDocHref(vm, gitContribute, gitUrlPattern);
69   vm.sourceurl = common.getViewSourceHref(vm, null, gitUrlPattern);
70
71   // set to null incase mustache looks up
72   vm.summary = vm.summary || null;
73   vm.remarks = vm.remarks || null;
74   vm.conceptual = vm.conceptual || null;
75   vm.syntax = vm.syntax || null;
76   vm.implements = vm.implements || null;
77   vm.example = vm.example || null;
78   common.processSeeAlso(vm);
79
80   // id is used as default template's bookmark
81   vm.id = common.getHtmlId(vm.uid);
82   if (vm.overload && vm.overload.uid) {
83     vm.overload.id = common.getHtmlId(vm.overload.uid);
84   }
85
86   // concatenate multiple types with `|`
87   if (vm.syntax) {
88     var syntax = vm.syntax;
89     if (syntax.parameters) {
90       syntax.parameters = syntax.parameters.map(function (p) {
91         return joinType(p);
92       })
93       syntax.parameters = groupParameters(syntax.parameters);
94     }
95     if (syntax.return) {
96       syntax.return = joinType(syntax.return);
97     }
98   }
99 }
100
101 function joinType(parameter) {
102   // change type in syntax from array to string
103   var joinTypeProperty = function (type, key) {
104     if (!type || !type[0] || !type[0][key]) return null;
105     var value = type.map(function (t) {
106       return t[key][0].value;
107     }).join(' | ');
108     return [{
109       lang: type[0][key][0].lang,
110       value: value
111     }];
112   };
113   if (parameter.type) {
114     parameter.type = {
115       name: joinTypeProperty(parameter.type, "name"),
116       nameWithType: joinTypeProperty(parameter.type, "nameWithType"),
117       fullName: joinTypeProperty(parameter.type, "fullName"),
118       specName: joinTypeProperty(parameter.type, "specName")
119     }
120   }
121   return parameter;
122 }
123
124 function groupParameters(parameters) {
125   // group parameter with properties
126   if (!parameters || parameters.length == 0) return parameters;
127   var groupedParameters = [];
128   var stack = [];
129   for (var i = 0; i < parameters.length; i++) {
130     var parameter = parameters[i];
131     parameter.properties = null;
132     var prefixLength = 0;
133     while (stack.length > 0) {
134       var top = stack.pop();
135       var prefix = top.id + '.';
136       if (parameter.id.indexOf(prefix) == 0) {
137         prefixLength = prefix.length;
138         if (!top.parameter.properties) {
139           top.parameter.properties = [];
140         }
141         top.parameter.properties.push(parameter);
142         stack.push(top);
143         break;
144       }
145       if (stack.length == 0) {
146         groupedParameters.push(top.parameter);
147       }
148     }
149     stack.push({ id: parameter.id, parameter: parameter });
150     parameter.id = parameter.id.substring(prefixLength);
151   }
152   while (stack.length > 0) {
153     top = stack.pop();
154   }
155   groupedParameters.push(top.parameter);
156   return groupedParameters;
157 }
158
159 function groupChildren(model, category, typeChildrenItems) {
160   if (!model || !model.type) {
161     return;
162   }
163   if (!typeChildrenItems) {
164     var typeChildrenItems = getDefinitions(category);
165   }
166   var grouped = {};
167
168   normalizeChildren(model.children).forEach(function (c) {
169     if (c.isEii) {
170       var type = "eii";
171     } else {
172       var type = c.type.toLowerCase();
173     }
174     if (!grouped.hasOwnProperty(type)) {
175       grouped[type] = [];
176     }
177     // special handle for field
178     if (type === "field" && c.syntax) {
179       c.syntax.fieldValue = c.syntax.return;
180       c.syntax.return = undefined;
181     }
182     // special handle for property
183     if (type === "property" && c.syntax) {
184       c.syntax.propertyValue = c.syntax.return;
185       c.syntax.return = undefined;
186     }
187     // special handle for event
188     if (type === "event" && c.syntax) {
189       c.syntax.eventType = c.syntax.return;
190       c.syntax.return = undefined;
191     }
192     grouped[type].push(c);
193   })
194
195   var children = [];
196   for (var key in typeChildrenItems) {
197     if (typeChildrenItems.hasOwnProperty(key) && grouped.hasOwnProperty(key)) {
198       var typeChildrenItem = typeChildrenItems[key];
199       var items = grouped[key];
200       if (items && items.length > 0) {
201         var item = {};
202         for (var itemKey in typeChildrenItem) {
203           if (typeChildrenItem.hasOwnProperty(itemKey)){
204             item[itemKey] = typeChildrenItem[itemKey];
205           }
206         }
207         item.children = items;
208         children.push(item);
209       }
210     }
211   }
212
213   model.children = children;
214 }
215
216 function getTypePropertyName(type) {
217   if (!type) {
218     return undefined;
219   }
220   var loweredType = type.toLowerCase();
221   var definition = getDefinition(loweredType);
222   if (definition) {
223     return definition.typePropertyName;
224   }
225
226   return undefined;
227 }
228
229 function getCategory(type) {
230   var classItems = getDefinitions(classCategory);
231   if (classItems.hasOwnProperty(type)) {
232     return classCategory;
233   }
234
235   var namespaceItems = getDefinitions(namespaceCategory);
236   if (namespaceItems.hasOwnProperty(type)) {
237     return namespaceCategory;
238   }
239   return undefined;
240 }
241
242 function getDefinition(type) {
243   var classItems = getDefinitions(classCategory);
244   if (classItems.hasOwnProperty(type)) {
245     return classItems[type];
246   }
247   var namespaceItems = getDefinitions(namespaceCategory);
248   if (namespaceItems.hasOwnProperty(type)) {
249     return namespaceItems[type];
250   }
251   return undefined;
252 }
253
254 function getDefinitions(category) {
255   var namespaceItems = {
256     "class":        { inClass: true,        typePropertyName: "inClass",        id: "classes" },
257     "struct":       { inStruct: true,       typePropertyName: "inStruct",       id: "structs" },
258     "interface":    { inInterface: true,    typePropertyName: "inInterface",    id: "interfaces" },
259     "enum":         { inEnum: true,         typePropertyName: "inEnum",         id: "enums" },
260     "delegate":     { inDelegate: true,     typePropertyName: "inDelegate",     id: "delegates" },
261     "package":      { inDelegate: true,     typePropertyName: "inPackage",      id: "packages" }
262   };
263   var classItems = {
264     "constructor":  { inConstructor: true,  typePropertyName: "inConstructor",  id: "constructors" },
265     "field":        { inField: true,        typePropertyName: "inField",        id: "fields" },
266     "property":     { inProperty: true,     typePropertyName: "inProperty",     id: "properties" },
267     "method":       { inMethod: true,       typePropertyName: "inMethod",       id: "methods" },
268     "event":        { inEvent: true,        typePropertyName: "inEvent",        id: "events" },
269     "operator":     { inOperator: true,     typePropertyName: "inOperator",     id: "operators" },
270     "eii":          { inEii: true,          typePropertyName: "inEii",          id: "eii" },
271     "function":     { inFunction: true,     typePropertyName: "inFunction",     id: "functions"},
272     "member":       { inMember: true,       typePropertyName: "inMember",       id: "members"}
273   };
274   if (category === 'class') {
275     return classItems;
276   }
277   if (category === 'ns') {
278     return namespaceItems;
279   }
280   console.err("category '" + category + "' is not valid.");
281   return undefined;
282 }
283
284 function normalizeChildren(children) {
285   if (children[0] && children[0].lang && children[0].value) {
286     return children[0].value;
287   }
288   return children;
289 }