// global variables
var cls = getQuerystring('c');
+var rel = getQuerystring('r');
function qualifier(q)
{
return 'Unknown[' + t + ']';
}
+function current_lifecycle_stage(s)
+{
+ if (s.length == 0)
+ return 'Prototype';
+ else {
+ last_transition = s[s.length-1][0];
+ switch (last_transition) {
+ case 'Deprecated':
+ return 'Deprecated';
+ break;
+ case 'Removed':
+ return 'Removed';
+ break;
+ case 'Published':
+ case 'Changed':
+ case 'Extended':
+ default:
+ return '';
+ break;
+ }
+ }
+}
+
function make_field(fld, n)
{
name = fld.field_name;
html = "";
html = '<div class="field' + toggle(n) + '">';
html += '<input type="button" class="small-button" value="details" onclick="showhide(document.getElementById(\'' + name + '_details\'))" />';
+ html += '<div class="lifecycle">' + current_lifecycle_stage(fld.lifecycle) + '</div>';
html += '<div><span class="inline-type">' + transform_type(fld.ty) + '</span> <span class="field-name">' + name + '</span> <span class="inline-qualifier">[' + qualifier(fld.qualifier) + ']</span></div>';
html += '<div id="' + name + '_details" style="display: none">';
html += '<div class="field-description">' + fld.field_description + '</div>';
html += '<table class="field-table">';
- if (fld.release != undefined) {
- html += '<tr><td width="130px"><span class="field-head">Introduced in:</span></td><td>' + fld.release.internal[1] + '</td></tr>';
- if (fld.release.internal_deprecated_since != undefined)
- html += '<tr><td width="130px"><span class="field-head">Deprecated since:</span></td><td>' + fld.release.internal_deprecated_since + '</td></tr>';
- }
if (fld.default_value != undefined)
html += '<tr><td width="130px"><span class="field-head">Default value:</span></td><td>' + transform_default(fld.default_value) + '</td></tr>';
+ html += '</table>';
+ html += '<table class="field-table">';
+ for (i in fld.lifecycle) {
+ l = fld.lifecycle[i];
+ html += '<tr><td width="130px"><span class="field-head">' + l[0] + ' in:</span></td><td width="130px">' + l[1] + '</td><td>' + l[2] + '</td></tr>';
+ }
html += '</table>';
html += '</div></div>';
html += '<div class="field' + toggle(n) + '">';
html += '<input type="button" class="small-button" value="details" onclick="showhide(document.getElementById(\'' + name + '_details\'))" />';
+ html += '<div class="lifecycle">' + current_lifecycle_stage(msg.msg_lifecycle) + '</div>';
html += '<div><span class="inline-type">' +
(msg.msg_result != undefined ? transform_type(msg.msg_result[0]) : 'void') +
'</span> <span class="field-name">' + name + '</span> <span class="inline-params">(' +
}
html += '</table></td></tr>';
}
- if (msg.msg_release != undefined) {
- html += '<tr><td><span class="field-head">Introduced in:</span></td><td>' + msg.msg_release.internal[1] + '</td></tr>';
- if (msg.msg_release.internal_deprecated_since != undefined)
- html += '<tr><td><span class="field-head">Deprecated since:</span></td><td>' + msg.msg_release.internal_deprecated_since + '</td></tr>';
+ html += '</table>';
+
+ html += '<table class="field-table">';
+ for (i in msg.msg_lifecycle) {
+ l = msg.msg_lifecycle[i];
+ html += '<tr><td width="130px"><span class="field-head">' + l[0] + ' in:</span></td><td width="130px">' + l[1] + '</td><td>' + l[2] + '</td></tr>';
}
html += '</table>';
messages.sort(function(a, b){return a.msg_name.toLowerCase().charCodeAt(0) - b.msg_name.toLowerCase().charCodeAt(0)});
html = "";
+ html += '<input type="button" class="small-button" value="details" onclick="showhide(document.getElementById(\'class_details\'))" />';
+ html += '<div class="lifecycle">' + current_lifecycle_stage(clsdoc.obj_lifecycle) + '</div>';
html += '<h1 class="title">Class: ' + cls + '</h1>\n';
html += '<div class="description">' + clsdoc.description + '</div>';
+ html += '<div id="class_details" style="display: none">';
+ html += '<table class="field-table">';
+ for (i in clsdoc.obj_lifecycle) {
+ l = clsdoc.obj_lifecycle[i];
+ html += '<tr><td width="130px"><span class="field-head">' + l[0] + ' in:</span></td><td width="130px">' + l[1] + '</td><td>' + l[2] + '</td></tr>';
+ }
+ html += '</table>';
+ html += '</div>';
+
html += '<h2>Fields</h2>';
if (fields.length > 0) {
for (i in fields)
set_content(html);
}
-function build()
+function compare_release_notes(a, b)
{
+ function change_to_num(x) {
+ if (x.indexOf('Published') > -1) return '0';
+ else if (x.indexOf('Extended') > -1) return '1';
+ else if (x.indexOf('Changed') > -1) return '2';
+ else if (x.indexOf('Deprecated') > -1) return '3';
+ else if (x.indexOf('Removed') > -1) return '4';
+ else return '5';
+ }
+ function element_to_num(x) {
+ if (x.indexOf('object') > -1) return '0';
+ else if (x.indexOf('field') > -1) return '1';
+ else if (x.indexOf('message') > -1) return '2';
+ else return '3';
+ }
+ a = change_to_num(a[0]) + element_to_num(a[0]) + (a[1]+a[2]).toLowerCase();
+ b = change_to_num(b[0]) + element_to_num(b[0]) + (b[1]+b[2]).toLowerCase();
+ return a > b;
+}
+
+function release_doc()
+{
+ changes = [];
+
+ for (i in release_info) {
+ c = release_info[i];
+ for (j in c.obj_changes)
+ changes.push([c.obj_changes[j][0] + ' object', c.cls, '', c.obj_changes[j][2]]);
+ for (j in c.field_changes)
+ changes.push([c.field_changes[j][0] + ' field', c.cls, c.field_changes[j][1], c.field_changes[j][2]]);
+ for (j in c.msg_changes)
+ changes.push([c.msg_changes[j][0] + ' message', c.cls, c.msg_changes[j][1], c.msg_changes[j][2]]);
+ }
+
+ changes.sort(compare_release_notes);
+
html = "";
+ html += '<h1 class="title">Release notes: ' + rel + '</h1>\n';
+
+ html += '<table><tr><th style="width: 12em">Change</th><th>Element</th><th>Description</th></tr>';
+
+ for (i in changes) {
+ html += '<tr><td>' + changes[i][0] + '</td><td><a href="?c=' + changes[i][1] + (changes[i][2] != '' ? '#' + changes[i][2] : '') + '">' +
+ changes[i][1] + (changes[i][2] != '' ? '.' + changes[i][2] : '') + '</a></td><td>' + changes[i][3] + '</td></tr>';
+ }
+
+ html += '</table>';
+
+ set_content(html);
+}
+
+function class_list()
+{
html = '<h2 class="title">Classes</h2>';
classes.sort(function(a, b){return a.toLowerCase().charCodeAt(0) - b.toLowerCase().charCodeAt(0)});
}
append_sidebar(html);
+}
+
+function release_list()
+{
+ html = '<h2>Release notes</h2>';
+
+ for (i in releases) {
+ r = releases[i];
+ html += '<a href="?r=' + r + '">' + r + '</a><br>';
+ }
+ append_sidebar(html);
+}
+
+function build()
+{
if (cls != "") {
+ class_list();
+ release_list();
class_doc();
}
+ else if (rel != "") {
+ class_list();
+ release_list();
+ release_doc();
+ }
+ else {
+ class_list();
+ release_list();
+ }
}
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*)
+
+open Datamodel_types
+open Stringext
+type change_t = lifecycle_change * string * string
+and changes_t = change_t list
+with rpc
+
+let obj_change_in_release rel o =
+ let rec find_rel rel = function
+ | [] -> None
+ | (transition, release, doc) :: tl when release = rel -> Some (transition, o.name, doc)
+ | _ :: tl -> find_rel rel tl
+ in
+ find_rel rel o.obj_lifecycle
+
+let msg_change_in_release rel m =
+ let rec find_rel rel = function
+ | [] -> None
+ | (transition, release, doc) :: tl when release = rel -> Some (transition, m.msg_name, doc)
+ | _ :: tl -> find_rel rel tl
+ in
+ find_rel rel m.msg_lifecycle
+
+let field_change_in_release rel f =
+ let rec find_rel rel = function
+ | [] -> None
+ | (transition, release, doc) :: tl when release = rel -> Some (transition, f.field_name, doc)
+ | _ :: tl -> find_rel rel tl
+ in
+ find_rel rel f.lifecycle
+
let _ =
- let api = (* Datamodel_utils.add_implicit_messages *) (Datamodel.all_api) in
+ let api = (Datamodel.all_api) in
let objs = Dm_api.objects_of_api api in
let create_json obj =
- let name = obj.Datamodel_types.name in
- let s = Jsonrpc.to_string (Datamodel_types.rpc_of_obj obj) in
+ let name = obj.name in
+ let s = Jsonrpc.to_string (rpc_of_obj obj) in
Unixext.write_string_to_file ("api/" ^ name ^ ".json") ("clsdoc = " ^ s);
name
in
let names = List.map create_json objs in
let class_list = String.concat ", " (List.map (fun s -> "'" ^ s ^ "'") names) in
- Unixext.write_string_to_file "api/index.json" ("classes = [" ^ class_list ^ "]")
+ Unixext.write_string_to_file "api/index.json" ("classes = [" ^ class_list ^ "]");
+ let new_in_release rel =
+ let search_obj obj =
+ let obj_changes : changes_t =
+ match obj_change_in_release rel obj with
+ | None -> []
+ | Some x -> [x]
+ in
+
+ let msgs = List.filter (fun m -> not m.msg_hide_from_docs) obj.messages in
+ let msg_changes : changes_t = List.fold_left
+ (fun l m -> match msg_change_in_release rel m with None -> l | Some x -> x :: l) [] msgs in
+
+ let flds = List.filter (function Field f -> true | _ -> false) obj.contents in
+ let field_changes : changes_t = List.fold_left
+ (fun l (Field f) -> match field_change_in_release rel f with None -> l | Some x -> x :: l) [] flds in
+
+ "{'cls': '" ^ obj.name ^ "', 'obj_changes': " ^ Jsonrpc.to_string (rpc_of_changes_t obj_changes) ^ ", 'field_changes': " ^ Jsonrpc.to_string (rpc_of_changes_t field_changes) ^ ", 'msg_changes': " ^ Jsonrpc.to_string (rpc_of_changes_t msg_changes) ^ "}"
+ in
+ let release_info = String.concat ", " (List.map search_obj objs) in
+ Unixext.write_string_to_file ("api/" ^ rel ^ ".json") ("release_info = [" ^ release_info ^ "]")
+ in
+ List.iter new_in_release release_order;
+ let release_list = String.concat ", " (List.map (fun s -> "'" ^ s ^ "'") release_order) in
+ Unixext.write_string_to_file "api/releases.json" ("releases = [" ^ release_list ^ "]");