'
+ ].join('');
+ }
+
+
+ ns.createPackageTree = function (pack, matched, focused) {
+ var html = $.map(matched, function (child, i) {
+ return createListItem(child);
+ }).join('');
+
+ var header;
+ if (focused && pack == focused) {
+ header = '';
+ } else {
+ header = createPackageHeader(pack);
+ }
+
+ return [
+ '',
+ header,
+ '',
+ html,
+ ''
+ ].join('');
+ }
+
+ ns.keys = function (obj) {
+ var result = [];
+ var key;
+ for (key in obj) {
+ result.push(key);
+ }
+ return result;
+ }
+
+ var hiddenPackages = {};
+
+ function subPackages(pack) {
+ return $.grep($('#tpl ol.packages'), function (element, index) {
+ var pack = $('li.pack > .tplshow', element).text();
+ return pack.indexOf(pack + '.') == 0;
+ });
+ }
+
+ ns.hidePackage = function (ol) {
+ var selected = $('li.pack > .tplshow', ol).text();
+ hiddenPackages[selected] = true;
+
+ $('ol.templates', ol).hide();
+
+ $.each(subPackages(selected), function (index, element) {
+ $(element).hide();
+ });
+ }
+
+ ns.showPackage = function (ol, state) {
+ var selected = $('li.pack > .tplshow', ol).text();
+ hiddenPackages[selected] = false;
+
+ $('ol.templates', ol).show();
+
+ $.each(subPackages(selected), function (index, element) {
+ $(element).show();
+
+ // When the filter is in "packs" state,
+ // we don't want to show the `.templates`
+ var key = $('li.pack > .tplshow', element).text();
+ if (hiddenPackages[key] || state == 'packs') {
+ $('ol.templates', element).hide();
+ }
+ });
+ }
+
+})(Index);
+
+function configureEntityList() {
+ kindFilterSync();
+ configureHideFilter();
+ configureFocusFilter();
+ textFilter();
+}
+
+/* Updates the list of entities (i.e. the content of the #tpl element) from the raw form generated by Scaladoc to a
+ form suitable for display. In particular, it adds class and object etc. icons, and it configures links to open in
+ the right frame. Furthermore, it sets the two reference top-level entities lists (topLevelTemplates and
+ topLevelPackages) to serve as reference for resetting the list when needed.
+ Be advised: this function should only be called once, on page load. */
+function prepareEntityList() {
+ var classIcon = $("#library > img.class");
+ var traitIcon = $("#library > img.trait");
+ var typeIcon = $("#library > img.type");
+ var objectIcon = $("#library > img.object");
+ var packageIcon = $("#library > img.package");
+
+ $('#tpl li.pack > a.tplshow').attr("target", "template");
+ $('#tpl li.pack').each(function () {
+ $("span.class", this).each(function() { $(this).replaceWith(classIcon.clone()); });
+ $("span.trait", this).each(function() { $(this).replaceWith(traitIcon.clone()); });
+ $("span.type", this).each(function() { $(this).replaceWith(typeIcon.clone()); });
+ $("span.object", this).each(function() { $(this).replaceWith(objectIcon.clone()); });
+ $("span.package", this).each(function() { $(this).replaceWith(packageIcon.clone()); });
+ });
+ $('#tpl li.pack')
+ .prepend("hide")
+ .prepend("focus");
+}
+
+/* Handles all key presses while scrolling around with keyboard shortcuts in left panel */
+function keyboardScrolldownLeftPane() {
+ scheduler.add("init", function() {
+ $("#textfilter input").blur();
+ var $items = $("#tpl li");
+ $items.first().addClass('selected');
+
+ $(window).bind("keydown", function(e) {
+ var $old = $items.filter('.selected'),
+ $new;
+
+ switch ( e.keyCode ) {
+
+ case 9: // tab
+ $old.removeClass('selected');
+ break;
+
+ case 13: // enter
+ $old.removeClass('selected');
+ var $url = $old.children().filter('a:last').attr('href');
+ $("#template").attr("src",$url);
+ break;
+
+ case 27: // escape
+ $old.removeClass('selected');
+ $(window).unbind(e);
+ $("#textfilter input").focus();
+
+ break;
+
+ case 38: // up
+ $new = $old.prev();
+
+ if (!$new.length) {
+ $new = $old.parent().prev();
+ }
+
+ if ($new.is('ol') && $new.children(':last').is('ol')) {
+ $new = $new.children().children(':last');
+ } else if ($new.is('ol')) {
+ $new = $new.children(':last');
+ }
+
+ break;
+
+ case 40: // down
+ $new = $old.next();
+ if (!$new.length) {
+ $new = $old.parent().parent().next();
+ }
+ if ($new.is('ol')) {
+ $new = $new.children(':first');
+ }
+ break;
+ }
+
+ if ($new.is('li')) {
+ $old.removeClass('selected');
+ $new.addClass('selected');
+ } else if (e.keyCode == 38) {
+ $(window).unbind(e);
+ $("#textfilter input").focus();
+ }
+ });
+ });
+}
+
+/* Configures the text filter */
+function configureTextFilter() {
+ scheduler.add("init", function() {
+ $("#textfilter").append("");
+ var input = $("#textfilter input");
+ resizeFilterBlock();
+ input.bind('keyup', function(event) {
+ if (event.keyCode == 27) { // escape
+ input.attr("value", "");
+ }
+ if (event.keyCode == 40) { // down arrow
+ $(window).unbind("keydown");
+ keyboardScrolldownLeftPane();
+ return false;
+ }
+ textFilter();
+ });
+ input.bind('keydown', function(event) {
+ if (event.keyCode == 9) { // tab
+ $("#template").contents().find("#mbrsel-input").focus();
+ input.attr("value", "");
+ return false;
+ }
+ textFilter();
+ });
+ input.focus(function(event) { input.select(); });
+ });
+ scheduler.add("init", function() {
+ $("#textfilter > .post").click(function(){
+ $("#textfilter input").attr("value", "");
+ textFilter();
+ });
+ });
+}
+
+function compilePattern(query) {
+ var escaped = query.replace(/([\.\*\+\?\|\(\)\[\]\\])/g, '\\$1');
+
+ if (query.toLowerCase() != query) {
+ // Regexp that matches CamelCase subbits: "BiSe" is
+ // "[a-z]*Bi[a-z]*Se" and matches "BitSet", "ABitSet", ...
+ return new RegExp(escaped.replace(/([A-Z])/g,"[a-z]*$1"));
+ }
+ else { // if query is all lower case make a normal case insensitive search
+ return new RegExp(escaped, "i");
+ }
+}
+
+// Filters all focused templates and packages. This function should be made less-blocking.
+// @param query The string of the query
+function textFilter() {
+ scheduler.clear("filter");
+
+ $('#tpl').html('');
+
+ var query = $("#textfilter input").attr("value") || '';
+ var queryRegExp = compilePattern(query);
+
+ var index = 0;
+
+ var searchLoop = function () {
+ var packages = Index.keys(Index.PACKAGES).sort();
+
+ while (packages[index]) {
+ var pack = packages[index];
+ var children = Index.PACKAGES[pack];
+ index++;
+
+ if (focusFilterState) {
+ if (pack == focusFilterState ||
+ pack.indexOf(focusFilterState + '.') == 0) {
+ ;
+ } else {
+ continue;
+ }
+ }
+
+ var matched = $.grep(children, function (child, i) {
+ return queryRegExp.test(child.name);
+ });
+
+ if (matched.length > 0) {
+ $('#tpl').append(Index.createPackageTree(pack, matched,
+ focusFilterState));
+ scheduler.add('filter', searchLoop);
+ return;
+ }
+ }
+
+ $('#tpl a.packfocus').click(function () {
+ focusFilter($(this).parent().parent());
+ });
+ configureHideFilter();
+ };
+
+ scheduler.add('filter', searchLoop);
+}
+
+/* Configures the hide tool by adding the hide link to all packages. */
+function configureHideFilter() {
+ $('#tpl li.pack a.packhide').click(function () {
+ var packhide = $(this)
+ var action = packhide.text();
+
+ var ol = $(this).parent().parent();
+
+ if (action == "hide") {
+ Index.hidePackage(ol);
+ packhide.text("show");
+ }
+ else {
+ Index.showPackage(ol, kindFilterState);
+ packhide.text("hide");
+ }
+ return false;
+ });
+}
+
+/* Configures the focus tool by adding the focus bar in the filter box (initially hidden), and by adding the focus
+ link to all packages. */
+function configureFocusFilter() {
+ scheduler.add("init", function() {
+ focusFilterState = null;
+ if ($("#focusfilter").length == 0) {
+ $("#filter").append("
focused on
");
+ $("#focusfilter > .focusremove").click(function(event) {
+ textFilter();
+
+ $("#focusfilter").hide();
+ $("#kindfilter").show();
+ resizeFilterBlock();
+ focusFilterState = null;
+ });
+ $("#focusfilter").hide();
+ resizeFilterBlock();
+ }
+ });
+ scheduler.add("init", function() {
+ $('#tpl li.pack a.packfocus').click(function () {
+ focusFilter($(this).parent());
+ return false;
+ });
+ });
+}
+
+/* Focuses the entity index on a specific package. To do so, it will copy the sub-templates and sub-packages of the
+ focuses package into the top-level templates and packages position of the index. The original top-level
+ @param package The
element that corresponds to the package in the entity index */
+function focusFilter(package) {
+ scheduler.clear("filter");
+
+ var currentFocus = $('li.pack > .tplshow', package).text();
+ $("#focusfilter > .focuscoll").empty();
+ $("#focusfilter > .focuscoll").append(currentFocus);
+
+ $("#focusfilter").show();
+ $("#kindfilter").hide();
+ resizeFilterBlock();
+ focusFilterState = currentFocus;
+ kindFilterSync();
+
+ textFilter();
+}
+
+function configureKindFilter() {
+ scheduler.add("init", function() {
+ kindFilterState = "all";
+ $("#filter").append("
'
+ ].join('');
+ }
+
+
+ ns.createPackageTree = function (pack, matched, focused) {
+ var html = $.map(matched, function (child, i) {
+ return createListItem(child);
+ }).join('');
+
+ var header;
+ if (focused && pack == focused) {
+ header = '';
+ } else {
+ header = createPackageHeader(pack);
+ }
+
+ return [
+ '',
+ header,
+ '',
+ html,
+ ''
+ ].join('');
+ }
+
+ ns.keys = function (obj) {
+ var result = [];
+ var key;
+ for (key in obj) {
+ result.push(key);
+ }
+ return result;
+ }
+
+ var hiddenPackages = {};
+
+ function subPackages(pack) {
+ return $.grep($('#tpl ol.packages'), function (element, index) {
+ var pack = $('li.pack > .tplshow', element).text();
+ return pack.indexOf(pack + '.') == 0;
+ });
+ }
+
+ ns.hidePackage = function (ol) {
+ var selected = $('li.pack > .tplshow', ol).text();
+ hiddenPackages[selected] = true;
+
+ $('ol.templates', ol).hide();
+
+ $.each(subPackages(selected), function (index, element) {
+ $(element).hide();
+ });
+ }
+
+ ns.showPackage = function (ol, state) {
+ var selected = $('li.pack > .tplshow', ol).text();
+ hiddenPackages[selected] = false;
+
+ $('ol.templates', ol).show();
+
+ $.each(subPackages(selected), function (index, element) {
+ $(element).show();
+
+ // When the filter is in "packs" state,
+ // we don't want to show the `.templates`
+ var key = $('li.pack > .tplshow', element).text();
+ if (hiddenPackages[key] || state == 'packs') {
+ $('ol.templates', element).hide();
+ }
+ });
+ }
+
+})(Index);
+
+function configureEntityList() {
+ kindFilterSync();
+ configureHideFilter();
+ configureFocusFilter();
+ textFilter();
+}
+
+/* Updates the list of entities (i.e. the content of the #tpl element) from the raw form generated by Scaladoc to a
+ form suitable for display. In particular, it adds class and object etc. icons, and it configures links to open in
+ the right frame. Furthermore, it sets the two reference top-level entities lists (topLevelTemplates and
+ topLevelPackages) to serve as reference for resetting the list when needed.
+ Be advised: this function should only be called once, on page load. */
+function prepareEntityList() {
+ var classIcon = $("#library > img.class");
+ var traitIcon = $("#library > img.trait");
+ var typeIcon = $("#library > img.type");
+ var objectIcon = $("#library > img.object");
+ var packageIcon = $("#library > img.package");
+
+ $('#tpl li.pack > a.tplshow').attr("target", "template");
+ $('#tpl li.pack').each(function () {
+ $("span.class", this).each(function() { $(this).replaceWith(classIcon.clone()); });
+ $("span.trait", this).each(function() { $(this).replaceWith(traitIcon.clone()); });
+ $("span.type", this).each(function() { $(this).replaceWith(typeIcon.clone()); });
+ $("span.object", this).each(function() { $(this).replaceWith(objectIcon.clone()); });
+ $("span.package", this).each(function() { $(this).replaceWith(packageIcon.clone()); });
+ });
+ $('#tpl li.pack')
+ .prepend("hide")
+ .prepend("focus");
+}
+
+/* Handles all key presses while scrolling around with keyboard shortcuts in left panel */
+function keyboardScrolldownLeftPane() {
+ scheduler.add("init", function() {
+ $("#textfilter input").blur();
+ var $items = $("#tpl li");
+ $items.first().addClass('selected');
+
+ $(window).bind("keydown", function(e) {
+ var $old = $items.filter('.selected'),
+ $new;
+
+ switch ( e.keyCode ) {
+
+ case 9: // tab
+ $old.removeClass('selected');
+ break;
+
+ case 13: // enter
+ $old.removeClass('selected');
+ var $url = $old.children().filter('a:last').attr('href');
+ $("#template").attr("src",$url);
+ break;
+
+ case 27: // escape
+ $old.removeClass('selected');
+ $(window).unbind(e);
+ $("#textfilter input").focus();
+
+ break;
+
+ case 38: // up
+ $new = $old.prev();
+
+ if (!$new.length) {
+ $new = $old.parent().prev();
+ }
+
+ if ($new.is('ol') && $new.children(':last').is('ol')) {
+ $new = $new.children().children(':last');
+ } else if ($new.is('ol')) {
+ $new = $new.children(':last');
+ }
+
+ break;
+
+ case 40: // down
+ $new = $old.next();
+ if (!$new.length) {
+ $new = $old.parent().parent().next();
+ }
+ if ($new.is('ol')) {
+ $new = $new.children(':first');
+ }
+ break;
+ }
+
+ if ($new.is('li')) {
+ $old.removeClass('selected');
+ $new.addClass('selected');
+ } else if (e.keyCode == 38) {
+ $(window).unbind(e);
+ $("#textfilter input").focus();
+ }
+ });
+ });
+}
+
+/* Configures the text filter */
+function configureTextFilter() {
+ scheduler.add("init", function() {
+ $("#textfilter").append("");
+ var input = $("#textfilter input");
+ resizeFilterBlock();
+ input.bind('keyup', function(event) {
+ if (event.keyCode == 27) { // escape
+ input.attr("value", "");
+ }
+ if (event.keyCode == 40) { // down arrow
+ $(window).unbind("keydown");
+ keyboardScrolldownLeftPane();
+ return false;
+ }
+ textFilter();
+ });
+ input.bind('keydown', function(event) {
+ if (event.keyCode == 9) { // tab
+ $("#template").contents().find("#mbrsel-input").focus();
+ input.attr("value", "");
+ return false;
+ }
+ textFilter();
+ });
+ input.focus(function(event) { input.select(); });
+ });
+ scheduler.add("init", function() {
+ $("#textfilter > .post").click(function(){
+ $("#textfilter input").attr("value", "");
+ textFilter();
+ });
+ });
+}
+
+function compilePattern(query) {
+ var escaped = query.replace(/([\.\*\+\?\|\(\)\[\]\\])/g, '\\$1');
+
+ if (query.toLowerCase() != query) {
+ // Regexp that matches CamelCase subbits: "BiSe" is
+ // "[a-z]*Bi[a-z]*Se" and matches "BitSet", "ABitSet", ...
+ return new RegExp(escaped.replace(/([A-Z])/g,"[a-z]*$1"));
+ }
+ else { // if query is all lower case make a normal case insensitive search
+ return new RegExp(escaped, "i");
+ }
+}
+
+// Filters all focused templates and packages. This function should be made less-blocking.
+// @param query The string of the query
+function textFilter() {
+ scheduler.clear("filter");
+
+ $('#tpl').html('');
+
+ var query = $("#textfilter input").attr("value") || '';
+ var queryRegExp = compilePattern(query);
+
+ var index = 0;
+
+ var searchLoop = function () {
+ var packages = Index.keys(Index.PACKAGES).sort();
+
+ while (packages[index]) {
+ var pack = packages[index];
+ var children = Index.PACKAGES[pack];
+ index++;
+
+ if (focusFilterState) {
+ if (pack == focusFilterState ||
+ pack.indexOf(focusFilterState + '.') == 0) {
+ ;
+ } else {
+ continue;
+ }
+ }
+
+ var matched = $.grep(children, function (child, i) {
+ return queryRegExp.test(child.name);
+ });
+
+ if (matched.length > 0) {
+ $('#tpl').append(Index.createPackageTree(pack, matched,
+ focusFilterState));
+ scheduler.add('filter', searchLoop);
+ return;
+ }
+ }
+
+ $('#tpl a.packfocus').click(function () {
+ focusFilter($(this).parent().parent());
+ });
+ configureHideFilter();
+ };
+
+ scheduler.add('filter', searchLoop);
+}
+
+/* Configures the hide tool by adding the hide link to all packages. */
+function configureHideFilter() {
+ $('#tpl li.pack a.packhide').click(function () {
+ var packhide = $(this)
+ var action = packhide.text();
+
+ var ol = $(this).parent().parent();
+
+ if (action == "hide") {
+ Index.hidePackage(ol);
+ packhide.text("show");
+ }
+ else {
+ Index.showPackage(ol, kindFilterState);
+ packhide.text("hide");
+ }
+ return false;
+ });
+}
+
+/* Configures the focus tool by adding the focus bar in the filter box (initially hidden), and by adding the focus
+ link to all packages. */
+function configureFocusFilter() {
+ scheduler.add("init", function() {
+ focusFilterState = null;
+ if ($("#focusfilter").length == 0) {
+ $("#filter").append("
focused on
");
+ $("#focusfilter > .focusremove").click(function(event) {
+ textFilter();
+
+ $("#focusfilter").hide();
+ $("#kindfilter").show();
+ resizeFilterBlock();
+ focusFilterState = null;
+ });
+ $("#focusfilter").hide();
+ resizeFilterBlock();
+ }
+ });
+ scheduler.add("init", function() {
+ $('#tpl li.pack a.packfocus').click(function () {
+ focusFilter($(this).parent());
+ return false;
+ });
+ });
+}
+
+/* Focuses the entity index on a specific package. To do so, it will copy the sub-templates and sub-packages of the
+ focuses package into the top-level templates and packages position of the index. The original top-level
+ @param package The
element that corresponds to the package in the entity index */
+function focusFilter(package) {
+ scheduler.clear("filter");
+
+ var currentFocus = $('li.pack > .tplshow', package).text();
+ $("#focusfilter > .focuscoll").empty();
+ $("#focusfilter > .focuscoll").append(currentFocus);
+
+ $("#focusfilter").show();
+ $("#kindfilter").hide();
+ resizeFilterBlock();
+ focusFilterState = currentFocus;
+ kindFilterSync();
+
+ textFilter();
+}
+
+function configureKindFilter() {
+ scheduler.add("init", function() {
+ kindFilterState = "all";
+ $("#filter").append("
To use this, just write the following in src/main/resources/scalac-plugin.xml:
+ <plugin>
+ <name>debuggable-macros</name>
+ <classname>scalaxy.debug.plugin.DebuggableMacroPlugin</classname>
+ </plugin>
+
'
+ ].join('');
+ }
+
+
+ ns.createPackageTree = function (pack, matched, focused) {
+ var html = $.map(matched, function (child, i) {
+ return createListItem(child);
+ }).join('');
+
+ var header;
+ if (focused && pack == focused) {
+ header = '';
+ } else {
+ header = createPackageHeader(pack);
+ }
+
+ return [
+ '',
+ header,
+ '',
+ html,
+ ''
+ ].join('');
+ }
+
+ ns.keys = function (obj) {
+ var result = [];
+ var key;
+ for (key in obj) {
+ result.push(key);
+ }
+ return result;
+ }
+
+ var hiddenPackages = {};
+
+ function subPackages(pack) {
+ return $.grep($('#tpl ol.packages'), function (element, index) {
+ var pack = $('li.pack > .tplshow', element).text();
+ return pack.indexOf(pack + '.') == 0;
+ });
+ }
+
+ ns.hidePackage = function (ol) {
+ var selected = $('li.pack > .tplshow', ol).text();
+ hiddenPackages[selected] = true;
+
+ $('ol.templates', ol).hide();
+
+ $.each(subPackages(selected), function (index, element) {
+ $(element).hide();
+ });
+ }
+
+ ns.showPackage = function (ol, state) {
+ var selected = $('li.pack > .tplshow', ol).text();
+ hiddenPackages[selected] = false;
+
+ $('ol.templates', ol).show();
+
+ $.each(subPackages(selected), function (index, element) {
+ $(element).show();
+
+ // When the filter is in "packs" state,
+ // we don't want to show the `.templates`
+ var key = $('li.pack > .tplshow', element).text();
+ if (hiddenPackages[key] || state == 'packs') {
+ $('ol.templates', element).hide();
+ }
+ });
+ }
+
+})(Index);
+
+function configureEntityList() {
+ kindFilterSync();
+ configureHideFilter();
+ configureFocusFilter();
+ textFilter();
+}
+
+/* Updates the list of entities (i.e. the content of the #tpl element) from the raw form generated by Scaladoc to a
+ form suitable for display. In particular, it adds class and object etc. icons, and it configures links to open in
+ the right frame. Furthermore, it sets the two reference top-level entities lists (topLevelTemplates and
+ topLevelPackages) to serve as reference for resetting the list when needed.
+ Be advised: this function should only be called once, on page load. */
+function prepareEntityList() {
+ var classIcon = $("#library > img.class");
+ var traitIcon = $("#library > img.trait");
+ var typeIcon = $("#library > img.type");
+ var objectIcon = $("#library > img.object");
+ var packageIcon = $("#library > img.package");
+
+ $('#tpl li.pack > a.tplshow').attr("target", "template");
+ $('#tpl li.pack').each(function () {
+ $("span.class", this).each(function() { $(this).replaceWith(classIcon.clone()); });
+ $("span.trait", this).each(function() { $(this).replaceWith(traitIcon.clone()); });
+ $("span.type", this).each(function() { $(this).replaceWith(typeIcon.clone()); });
+ $("span.object", this).each(function() { $(this).replaceWith(objectIcon.clone()); });
+ $("span.package", this).each(function() { $(this).replaceWith(packageIcon.clone()); });
+ });
+ $('#tpl li.pack')
+ .prepend("hide")
+ .prepend("focus");
+}
+
+/* Handles all key presses while scrolling around with keyboard shortcuts in left panel */
+function keyboardScrolldownLeftPane() {
+ scheduler.add("init", function() {
+ $("#textfilter input").blur();
+ var $items = $("#tpl li");
+ $items.first().addClass('selected');
+
+ $(window).bind("keydown", function(e) {
+ var $old = $items.filter('.selected'),
+ $new;
+
+ switch ( e.keyCode ) {
+
+ case 9: // tab
+ $old.removeClass('selected');
+ break;
+
+ case 13: // enter
+ $old.removeClass('selected');
+ var $url = $old.children().filter('a:last').attr('href');
+ $("#template").attr("src",$url);
+ break;
+
+ case 27: // escape
+ $old.removeClass('selected');
+ $(window).unbind(e);
+ $("#textfilter input").focus();
+
+ break;
+
+ case 38: // up
+ $new = $old.prev();
+
+ if (!$new.length) {
+ $new = $old.parent().prev();
+ }
+
+ if ($new.is('ol') && $new.children(':last').is('ol')) {
+ $new = $new.children().children(':last');
+ } else if ($new.is('ol')) {
+ $new = $new.children(':last');
+ }
+
+ break;
+
+ case 40: // down
+ $new = $old.next();
+ if (!$new.length) {
+ $new = $old.parent().parent().next();
+ }
+ if ($new.is('ol')) {
+ $new = $new.children(':first');
+ }
+ break;
+ }
+
+ if ($new.is('li')) {
+ $old.removeClass('selected');
+ $new.addClass('selected');
+ } else if (e.keyCode == 38) {
+ $(window).unbind(e);
+ $("#textfilter input").focus();
+ }
+ });
+ });
+}
+
+/* Configures the text filter */
+function configureTextFilter() {
+ scheduler.add("init", function() {
+ $("#textfilter").append("");
+ var input = $("#textfilter input");
+ resizeFilterBlock();
+ input.bind('keyup', function(event) {
+ if (event.keyCode == 27) { // escape
+ input.attr("value", "");
+ }
+ if (event.keyCode == 40) { // down arrow
+ $(window).unbind("keydown");
+ keyboardScrolldownLeftPane();
+ return false;
+ }
+ textFilter();
+ });
+ input.bind('keydown', function(event) {
+ if (event.keyCode == 9) { // tab
+ $("#template").contents().find("#mbrsel-input").focus();
+ input.attr("value", "");
+ return false;
+ }
+ textFilter();
+ });
+ input.focus(function(event) { input.select(); });
+ });
+ scheduler.add("init", function() {
+ $("#textfilter > .post").click(function(){
+ $("#textfilter input").attr("value", "");
+ textFilter();
+ });
+ });
+}
+
+function compilePattern(query) {
+ var escaped = query.replace(/([\.\*\+\?\|\(\)\[\]\\])/g, '\\$1');
+
+ if (query.toLowerCase() != query) {
+ // Regexp that matches CamelCase subbits: "BiSe" is
+ // "[a-z]*Bi[a-z]*Se" and matches "BitSet", "ABitSet", ...
+ return new RegExp(escaped.replace(/([A-Z])/g,"[a-z]*$1"));
+ }
+ else { // if query is all lower case make a normal case insensitive search
+ return new RegExp(escaped, "i");
+ }
+}
+
+// Filters all focused templates and packages. This function should be made less-blocking.
+// @param query The string of the query
+function textFilter() {
+ scheduler.clear("filter");
+
+ $('#tpl').html('');
+
+ var query = $("#textfilter input").attr("value") || '';
+ var queryRegExp = compilePattern(query);
+
+ var index = 0;
+
+ var searchLoop = function () {
+ var packages = Index.keys(Index.PACKAGES).sort();
+
+ while (packages[index]) {
+ var pack = packages[index];
+ var children = Index.PACKAGES[pack];
+ index++;
+
+ if (focusFilterState) {
+ if (pack == focusFilterState ||
+ pack.indexOf(focusFilterState + '.') == 0) {
+ ;
+ } else {
+ continue;
+ }
+ }
+
+ var matched = $.grep(children, function (child, i) {
+ return queryRegExp.test(child.name);
+ });
+
+ if (matched.length > 0) {
+ $('#tpl').append(Index.createPackageTree(pack, matched,
+ focusFilterState));
+ scheduler.add('filter', searchLoop);
+ return;
+ }
+ }
+
+ $('#tpl a.packfocus').click(function () {
+ focusFilter($(this).parent().parent());
+ });
+ configureHideFilter();
+ };
+
+ scheduler.add('filter', searchLoop);
+}
+
+/* Configures the hide tool by adding the hide link to all packages. */
+function configureHideFilter() {
+ $('#tpl li.pack a.packhide').click(function () {
+ var packhide = $(this)
+ var action = packhide.text();
+
+ var ol = $(this).parent().parent();
+
+ if (action == "hide") {
+ Index.hidePackage(ol);
+ packhide.text("show");
+ }
+ else {
+ Index.showPackage(ol, kindFilterState);
+ packhide.text("hide");
+ }
+ return false;
+ });
+}
+
+/* Configures the focus tool by adding the focus bar in the filter box (initially hidden), and by adding the focus
+ link to all packages. */
+function configureFocusFilter() {
+ scheduler.add("init", function() {
+ focusFilterState = null;
+ if ($("#focusfilter").length == 0) {
+ $("#filter").append("
focused on
");
+ $("#focusfilter > .focusremove").click(function(event) {
+ textFilter();
+
+ $("#focusfilter").hide();
+ $("#kindfilter").show();
+ resizeFilterBlock();
+ focusFilterState = null;
+ });
+ $("#focusfilter").hide();
+ resizeFilterBlock();
+ }
+ });
+ scheduler.add("init", function() {
+ $('#tpl li.pack a.packfocus').click(function () {
+ focusFilter($(this).parent());
+ return false;
+ });
+ });
+}
+
+/* Focuses the entity index on a specific package. To do so, it will copy the sub-templates and sub-packages of the
+ focuses package into the top-level templates and packages position of the index. The original top-level
+ @param package The
element that corresponds to the package in the entity index */
+function focusFilter(package) {
+ scheduler.clear("filter");
+
+ var currentFocus = $('li.pack > .tplshow', package).text();
+ $("#focusfilter > .focuscoll").empty();
+ $("#focusfilter > .focuscoll").append(currentFocus);
+
+ $("#focusfilter").show();
+ $("#kindfilter").hide();
+ resizeFilterBlock();
+ focusFilterState = currentFocus;
+ kindFilterSync();
+
+ textFilter();
+}
+
+function configureKindFilter() {
+ scheduler.add("init", function() {
+ kindFilterState = "all";
+ $("#filter").append("
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/IDEAS b/IDEAS
deleted file mode 100644
index 43c436b8..00000000
--- a/IDEAS
+++ /dev/null
@@ -1,45 +0,0 @@
-- //inside[_ <: javax.swing.JComponent].
- // BOF : insidePackage("scala.lang").
-
-- activer remplacements dans un scope
-
- replacing(..., ..., ...) {
-
- }
-
-- activer ou desactiver
-
-- ajouter dependence des rewrites dans sbt
-
-- plugin sbt pour generer remplacement pour sa librairie et les publier (replacements.properties...)
-
-- Refactoring : hyper utile pour migrer ˆ nouvelle version code
- -> ...
-
-- object MesExemples extends Rock {
-
- def enabled(compilerContext) = {
- if (compC.scalaVersion < ...)
- false
-
- }
-
- def context1(....) =
- replace(patt, rep)
-
- def context1(...) =
- warn(msg) { patt }
-
- def context1(...) =
- fail(msg) { patt }
-
- def context1(...) =
- when(patt)(id1, id2...) {
- case ...: Tree =>
- replacement(rep)
- case ... =>
- error(rep)
- case ... =>
- warning(rep)
- }
-}
diff --git a/JSON/index.md b/JSON/index.md
new file mode 100644
index 00000000..c1d33d5d
--- /dev/null
+++ b/JSON/index.md
@@ -0,0 +1,78 @@
+# Scalaxy/JSON
+
+Macro-based JSON string interpolation, to create JSON objects as well as to extract values from them.
+
+Currently uses [json4s](https://github.com/json4s/json4s), but decoupling is in progress.
+
+```scala
+import org.json4s._
+
+import scalaxy.json.jackson._
+import org.json4s.jackson.JsonMethods._
+
+// import scalaxy.json.native._
+// import org.json4s.native.JsonMethods._
+
+val a = 10
+val b = "123"
+
+// Two ways to create objects: named params or string interpolation.
+// Both are macro expanded into the corresponding JSON creation code.
+// No parsing takes place at runtime, it all happens during compilation.
+// The resulting JSON is renormalized during compilation, so it's possible to drop some noisy quotes.
+val obj = json(x = a, y = b)
+val obj2 = json"{ x: $a, y: $b }"
+// {
+// "x" : 10.0,
+// "y" : "123"
+// }
+
+// Same for arrays:
+val arr = json(a, b)
+val arr2 = json"[$a, $b]"
+// [ 10.0, "123" ]
+
+// Extraction also works, but currently requires some runtime parsing.
+// Runtime improvements will come in 2.11 using https://issues.scala-lang.org/browse/SI-5903.
+val json"{ x: $x, y: $y }" = obj
+```
+
+For more examples, [have a look at the tests](https://github.com/ochafik/Scalaxy/blob/master/JSON/src/test/scala/scalaxy/json/JSONTest.scala).
+
+# Features
+
+- `json` string interpolation that is macro-expanded (type-safe and with no runtime parsing)
+- `json` string interpolation extractor
+- Smart error reporting for `json` string interpolation when using the `json4s.jackson`: JSON parsing errors are seamlessly transformed to Scala compiler errors, with the correct location.
+
+# TODO
+
+- `json` string interpolation should create something between a string and a JSON object (it currently creates an object), so as to optimize the .toString use case.
+- Current matching is exact (all the extracted keys must exist, and no other must exist).
+ By introducing a `...` notation, it will be possible to accept more unexpected keys.
+
+# Usage
+
+If you're using `sbt` 0.12.2+, just put the following lines in `build.sbt`:
+```scala
+// Only works with 2.10.0+
+scalaVersion := "2.10.0"
+
+// Dependency at compilation-time only (not at runtime).
+libraryDependencies += "com.nativelibs4java" %% "scalaxy-json" % "0.3-SNAPSHOT" % "provided"
+
+// Scalaxy/JSON snapshots are published on the Sonatype repository.
+resolvers += Resolver.sonatypeRepo("snapshots")
+```
+
+# Hacking
+
+If you want to build / test / hack on this project:
+- Make sure to use [paulp's sbt script](https://github.com/paulp/sbt-extras) with `sbt` 0.12.2+
+- Use the following commands to checkout the sources and build the tests continuously:
+
+ ```
+ git clone git://github.com/ochafik/Scalaxy.git
+ cd Scalaxy
+ sbt "project scalaxy-json" "; clean ; ~test"
+ ```
diff --git a/JSON/latest/api/index.html b/JSON/latest/api/index.html
new file mode 100644
index 00000000..d83de23f
--- /dev/null
+++ b/JSON/latest/api/index.html
@@ -0,0 +1,57 @@
+
+
+
+
+ scalaxy-json: scalaxy-json 0.3-SNAPSHOT
+
+
+
+
+
+
+
+
+
'
+ ].join('');
+ }
+
+
+ ns.createPackageTree = function (pack, matched, focused) {
+ var html = $.map(matched, function (child, i) {
+ return createListItem(child);
+ }).join('');
+
+ var header;
+ if (focused && pack == focused) {
+ header = '';
+ } else {
+ header = createPackageHeader(pack);
+ }
+
+ return [
+ '',
+ header,
+ '',
+ html,
+ ''
+ ].join('');
+ }
+
+ ns.keys = function (obj) {
+ var result = [];
+ var key;
+ for (key in obj) {
+ result.push(key);
+ }
+ return result;
+ }
+
+ var hiddenPackages = {};
+
+ function subPackages(pack) {
+ return $.grep($('#tpl ol.packages'), function (element, index) {
+ var pack = $('li.pack > .tplshow', element).text();
+ return pack.indexOf(pack + '.') == 0;
+ });
+ }
+
+ ns.hidePackage = function (ol) {
+ var selected = $('li.pack > .tplshow', ol).text();
+ hiddenPackages[selected] = true;
+
+ $('ol.templates', ol).hide();
+
+ $.each(subPackages(selected), function (index, element) {
+ $(element).hide();
+ });
+ }
+
+ ns.showPackage = function (ol, state) {
+ var selected = $('li.pack > .tplshow', ol).text();
+ hiddenPackages[selected] = false;
+
+ $('ol.templates', ol).show();
+
+ $.each(subPackages(selected), function (index, element) {
+ $(element).show();
+
+ // When the filter is in "packs" state,
+ // we don't want to show the `.templates`
+ var key = $('li.pack > .tplshow', element).text();
+ if (hiddenPackages[key] || state == 'packs') {
+ $('ol.templates', element).hide();
+ }
+ });
+ }
+
+})(Index);
+
+function configureEntityList() {
+ kindFilterSync();
+ configureHideFilter();
+ configureFocusFilter();
+ textFilter();
+}
+
+/* Updates the list of entities (i.e. the content of the #tpl element) from the raw form generated by Scaladoc to a
+ form suitable for display. In particular, it adds class and object etc. icons, and it configures links to open in
+ the right frame. Furthermore, it sets the two reference top-level entities lists (topLevelTemplates and
+ topLevelPackages) to serve as reference for resetting the list when needed.
+ Be advised: this function should only be called once, on page load. */
+function prepareEntityList() {
+ var classIcon = $("#library > img.class");
+ var traitIcon = $("#library > img.trait");
+ var typeIcon = $("#library > img.type");
+ var objectIcon = $("#library > img.object");
+ var packageIcon = $("#library > img.package");
+
+ $('#tpl li.pack > a.tplshow').attr("target", "template");
+ $('#tpl li.pack').each(function () {
+ $("span.class", this).each(function() { $(this).replaceWith(classIcon.clone()); });
+ $("span.trait", this).each(function() { $(this).replaceWith(traitIcon.clone()); });
+ $("span.type", this).each(function() { $(this).replaceWith(typeIcon.clone()); });
+ $("span.object", this).each(function() { $(this).replaceWith(objectIcon.clone()); });
+ $("span.package", this).each(function() { $(this).replaceWith(packageIcon.clone()); });
+ });
+ $('#tpl li.pack')
+ .prepend("hide")
+ .prepend("focus");
+}
+
+/* Handles all key presses while scrolling around with keyboard shortcuts in left panel */
+function keyboardScrolldownLeftPane() {
+ scheduler.add("init", function() {
+ $("#textfilter input").blur();
+ var $items = $("#tpl li");
+ $items.first().addClass('selected');
+
+ $(window).bind("keydown", function(e) {
+ var $old = $items.filter('.selected'),
+ $new;
+
+ switch ( e.keyCode ) {
+
+ case 9: // tab
+ $old.removeClass('selected');
+ break;
+
+ case 13: // enter
+ $old.removeClass('selected');
+ var $url = $old.children().filter('a:last').attr('href');
+ $("#template").attr("src",$url);
+ break;
+
+ case 27: // escape
+ $old.removeClass('selected');
+ $(window).unbind(e);
+ $("#textfilter input").focus();
+
+ break;
+
+ case 38: // up
+ $new = $old.prev();
+
+ if (!$new.length) {
+ $new = $old.parent().prev();
+ }
+
+ if ($new.is('ol') && $new.children(':last').is('ol')) {
+ $new = $new.children().children(':last');
+ } else if ($new.is('ol')) {
+ $new = $new.children(':last');
+ }
+
+ break;
+
+ case 40: // down
+ $new = $old.next();
+ if (!$new.length) {
+ $new = $old.parent().parent().next();
+ }
+ if ($new.is('ol')) {
+ $new = $new.children(':first');
+ }
+ break;
+ }
+
+ if ($new.is('li')) {
+ $old.removeClass('selected');
+ $new.addClass('selected');
+ } else if (e.keyCode == 38) {
+ $(window).unbind(e);
+ $("#textfilter input").focus();
+ }
+ });
+ });
+}
+
+/* Configures the text filter */
+function configureTextFilter() {
+ scheduler.add("init", function() {
+ $("#textfilter").append("");
+ var input = $("#textfilter input");
+ resizeFilterBlock();
+ input.bind('keyup', function(event) {
+ if (event.keyCode == 27) { // escape
+ input.attr("value", "");
+ }
+ if (event.keyCode == 40) { // down arrow
+ $(window).unbind("keydown");
+ keyboardScrolldownLeftPane();
+ return false;
+ }
+ textFilter();
+ });
+ input.bind('keydown', function(event) {
+ if (event.keyCode == 9) { // tab
+ $("#template").contents().find("#mbrsel-input").focus();
+ input.attr("value", "");
+ return false;
+ }
+ textFilter();
+ });
+ input.focus(function(event) { input.select(); });
+ });
+ scheduler.add("init", function() {
+ $("#textfilter > .post").click(function(){
+ $("#textfilter input").attr("value", "");
+ textFilter();
+ });
+ });
+}
+
+function compilePattern(query) {
+ var escaped = query.replace(/([\.\*\+\?\|\(\)\[\]\\])/g, '\\$1');
+
+ if (query.toLowerCase() != query) {
+ // Regexp that matches CamelCase subbits: "BiSe" is
+ // "[a-z]*Bi[a-z]*Se" and matches "BitSet", "ABitSet", ...
+ return new RegExp(escaped.replace(/([A-Z])/g,"[a-z]*$1"));
+ }
+ else { // if query is all lower case make a normal case insensitive search
+ return new RegExp(escaped, "i");
+ }
+}
+
+// Filters all focused templates and packages. This function should be made less-blocking.
+// @param query The string of the query
+function textFilter() {
+ scheduler.clear("filter");
+
+ $('#tpl').html('');
+
+ var query = $("#textfilter input").attr("value") || '';
+ var queryRegExp = compilePattern(query);
+
+ var index = 0;
+
+ var searchLoop = function () {
+ var packages = Index.keys(Index.PACKAGES).sort();
+
+ while (packages[index]) {
+ var pack = packages[index];
+ var children = Index.PACKAGES[pack];
+ index++;
+
+ if (focusFilterState) {
+ if (pack == focusFilterState ||
+ pack.indexOf(focusFilterState + '.') == 0) {
+ ;
+ } else {
+ continue;
+ }
+ }
+
+ var matched = $.grep(children, function (child, i) {
+ return queryRegExp.test(child.name);
+ });
+
+ if (matched.length > 0) {
+ $('#tpl').append(Index.createPackageTree(pack, matched,
+ focusFilterState));
+ scheduler.add('filter', searchLoop);
+ return;
+ }
+ }
+
+ $('#tpl a.packfocus').click(function () {
+ focusFilter($(this).parent().parent());
+ });
+ configureHideFilter();
+ };
+
+ scheduler.add('filter', searchLoop);
+}
+
+/* Configures the hide tool by adding the hide link to all packages. */
+function configureHideFilter() {
+ $('#tpl li.pack a.packhide').click(function () {
+ var packhide = $(this)
+ var action = packhide.text();
+
+ var ol = $(this).parent().parent();
+
+ if (action == "hide") {
+ Index.hidePackage(ol);
+ packhide.text("show");
+ }
+ else {
+ Index.showPackage(ol, kindFilterState);
+ packhide.text("hide");
+ }
+ return false;
+ });
+}
+
+/* Configures the focus tool by adding the focus bar in the filter box (initially hidden), and by adding the focus
+ link to all packages. */
+function configureFocusFilter() {
+ scheduler.add("init", function() {
+ focusFilterState = null;
+ if ($("#focusfilter").length == 0) {
+ $("#filter").append("
focused on
");
+ $("#focusfilter > .focusremove").click(function(event) {
+ textFilter();
+
+ $("#focusfilter").hide();
+ $("#kindfilter").show();
+ resizeFilterBlock();
+ focusFilterState = null;
+ });
+ $("#focusfilter").hide();
+ resizeFilterBlock();
+ }
+ });
+ scheduler.add("init", function() {
+ $('#tpl li.pack a.packfocus').click(function () {
+ focusFilter($(this).parent());
+ return false;
+ });
+ });
+}
+
+/* Focuses the entity index on a specific package. To do so, it will copy the sub-templates and sub-packages of the
+ focuses package into the top-level templates and packages position of the index. The original top-level
+ @param package The
element that corresponds to the package in the entity index */
+function focusFilter(package) {
+ scheduler.clear("filter");
+
+ var currentFocus = $('li.pack > .tplshow', package).text();
+ $("#focusfilter > .focuscoll").empty();
+ $("#focusfilter > .focuscoll").append(currentFocus);
+
+ $("#focusfilter").show();
+ $("#kindfilter").hide();
+ resizeFilterBlock();
+ focusFilterState = currentFocus;
+ kindFilterSync();
+
+ textFilter();
+}
+
+function configureKindFilter() {
+ scheduler.add("init", function() {
+ kindFilterState = "all";
+ $("#filter").append("