[scaladoc] Fixed popup content lookup so that it works on all browsers. Speed-up in entity index search (according to jQuery manual, observed no notable difference). Some small aesthetic cleanups in the way index initialization and filtering behaves. No review.

git-svn-id: http://lampsvn.epfl.ch/svn-repos/scala/scala/trunk@20864 5e8d7ff9-d8ef-0310-90f0-a4852d11357a
This commit is contained in:
dubochet 2010-02-11 13:55:34 +00:00
parent 6698d0a6e5
commit 0a474e7966
5 changed files with 147 additions and 141 deletions

View File

@ -37,15 +37,8 @@ class Index(modelRoot: Package) extends HtmlPage {
<img class='package icon' src='lib/package.png'/>
</div>
<div id="browser">
<div id="filter">
<div id="textfilter">
<input type="text" accesskey="/"/>
</div>
<div id="focusfilter">
focus on <span class="focuscoll"></span> <a class="focusremove">(remove)</a>
</div>
</div>
<div class="wu" id="tpl">{
<div id="filter"></div>
<div class="pack" id="tpl">{
def isExcluded(dtpl: DocTemplateEntity) = {
val qname = dtpl.qualifiedName
(qname.startsWith("scala.Tuple") || qname.startsWith("scala.Product") || qname.startsWith("scala.Function")) &&
@ -79,7 +72,7 @@ class Index(modelRoot: Package) extends HtmlPage {
}</ol>
<ol class="packages"> {
for (sp <- pack.packages sortBy (_.name.toLowerCase)) yield
<li class="wu" title={ sp.qualifiedName }>{ packageElem(sp) }</li>
<li class="pack" title={ sp.qualifiedName }>{ packageElem(sp) }</li>
}</ol>
</xml:group>
}

View File

@ -99,7 +99,7 @@ h1 {
right: 0;
left: 0;
bottom: 0;
top: 0;
top: 5px;
position: absolute;
display: block;
}

View File

@ -1,10 +1,11 @@
// © 20092010 EPFL/LAMP
// code by Gilles Dubochet with contributions by Johannes Rudolph and "spiros"
var topLevelTemplates = null;
var topLevelPackages = null;
var topLevelTemplates = undefined;
var topLevelPackages = undefined;
var scheduler = undefined;
var domCache = undefined;
$(document).ready(function() {
@ -13,13 +14,20 @@ $(document).ready(function() {
scheduler.addLabel("focus", 7);
scheduler.addLabel("filter", 10);
// Saves a pointer to top-level templates and packages (used to regain top-level focus after removing
// a focusing filter).
topLevelTemplates = $("#tpl > ol.templates").clone();
topLevelPackages = $("#tpl > ol.packages").clone();
scheduler.addForAll = function(labelName, elems, fn) {
var idx = 0;
var elem = undefined;
while (idx < elems.length) {
elem = elems[idx];
scheduler.add(labelName, function(elem0) { fn(elem0); }, undefined, [elem]);
idx = idx + 1;
}
}
// Hides unavailable tools
$("#focusfilter").hide();
domCache = new DomCache();
domCache.update();
prepareEntityList();
configureTextFilter();
configureEntityList();
@ -27,52 +35,61 @@ $(document).ready(function() {
});
function configureEntityList() {
resizeFilterBlock();
redirectEntityLinks();
setEntityIcons();
configureHideFilter();
configureFocusFilter();
resizeFilterBlock();
textFilter();
}
// Configure behaviour: links open in right frame
function redirectEntityLinks() {
$(".wu").each(function() {
scheduler.add("init", this, function() {
$("> h3 a.tplshow", this).add("> .templates a.tplshow", this).attr("target", "template");
});
/* The DomCache class holds a series of pointers to interesting parts of the page's DOM tree. Generally, any DOM
accessor should be reduced to the context of a relevant entity from the cache. This is crucial to maintaining
decent performance of the page. */
function DomCache() {
var cache = this;
this.packs = undefined;
this.liPacks = undefined;
this.update = function() {
cache.packs = $(".pack");
cache.liPacks = cache.packs.filter("li");
}
}
/* 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 objectIcon = $("#library > img.object");
var packageIcon = $("#library > img.package");
scheduler.addForAll("init", domCache.packs, function(pack) {
var packTemplates = $("> ol.templates > li", pack);
$("> h3 > a.tplshow", pack).add("> a.tplshow", packTemplates).attr("target", "template");
$("span.class", packTemplates).each(function() { $(this).replaceWith(classIcon.clone()); });
$("span.trait", packTemplates).each(function() { $(this).replaceWith(traitIcon.clone()); });
$("span.object", packTemplates).each(function() { $(this).replaceWith(objectIcon.clone()); });
$("span.package", packTemplates).each(function() { $(this).replaceWith(packageIcon.clone()); });
});
scheduler.add("init", function() {
topLevelTemplates = $("#tpl > ol.templates").clone();
topLevelPackages = $("#tpl > ol.packages").clone();
});
}
// Configure layout: replace text by icons when necessary
function setEntityIcons() {
var classIcon = $("#library img.class");
var traitIcon = $("#library img.trait");
var objectIcon = $("#library img.object");
var packageIcon = $("#library img.package");
$("#tpl ol.templates").each(function() {
scheduler.add("init", this, function() {
$("> li span.class", this).each(function() { $(this).replaceWith(classIcon.clone()); });
$("> li span.trait", this).each(function() { $(this).replaceWith(traitIcon.clone()); });
$("> li span.object", this).each(function() { $(this).replaceWith(objectIcon.clone()); });
$("> li span.package", this).each(function() { $(this).replaceWith(packageIcon.clone()); });
});
});
}
// Configures behaviour: text filter filters
/* Configures the text filter */
function configureTextFilter() {
scheduler.add("init", this, function() {
$("#textfilter input").bind("keyup", function(event) {
scheduler.add("init", function() {
$("#filter").append("<div id='textfilter'><input type='text' accesskey='/'/></div>");
var input = $("#textfilter > input");
resizeFilterBlock();
input.bind("keyup", function(event) {
if (event.keyCode == 27) { // escape
$("#textfilter input").attr("value", "");
input.attr("value", "");
}
textFilter();
});
$("#textfilter input").focus(function(event) {
$("#textfilter input").select();
});
input.focus(function(event) { input.select(); });
});
}
@ -80,122 +97,121 @@ function configureTextFilter() {
// @param query The string of the query
function textFilter() {
scheduler.clear("filter");
scheduler.add("filter", this, function() {
scheduler.add("filter", function() {
var query = $("#textfilter input").attr("value")
var queryRegExp;
if (query.toLowerCase() != query)
if (query.toLowerCase() != query) {
// Regexp that matches CamelCase subbits: "BiSe" is
// "[a-z]*Bi[a-z]*Se" and matches "BitSet", "ABitSet", ...
queryRegExp = new RegExp(query.replace(/([A-Z])/g,"[a-z]*$1"));
else
// if query is all lower case make a normal case insensitive search
}
else { // if query is all lower case make a normal case insensitive search
queryRegExp = new RegExp(query, "i");
$(".wu").each(function() {
var pack = $(this);
scheduler.add("filter", this, function() {
$("> ol.templates > li", pack).each(function(){
var item = $(this).attr("title");
if (item == "" || queryRegExp.test(item)) {
$(this).show();
$(this).removeClass("hide");
}
else {
$(this).addClass("hide");
$(this).hide();
}
});
if ($("> ol > li:not(.hide)", pack).length > 0) {
pack.show();
pack.removeClass("hide");
}
scheduler.addForAll("filter", domCache.packs, function(pack0) {
var pack = $(pack0);
$("> ol.templates > li", pack).each(function(){
var item = $(this).attr("title");
if (item == "" || queryRegExp.test(item)) {
$(this).show();
$(this).removeClass("hide");
}
else {
pack.addClass("hide");
pack.hide();
};
if ($("> ol.templates > li:not(.hide)", pack).length > 0) {
$("> h3", pack).show();
$("> .packhide", pack).show();
$("> .packfocus", pack).show();
$(this).addClass("hide");
$(this).hide();
}
else {
$("> h3", pack).hide();
$("> .packhide", pack).hide();
$("> .packfocus", pack).hide();
};
});
if ($("> ol > li:not(.hide)", pack).length > 0) {
pack.show();
pack.removeClass("hide");
}
else {
pack.addClass("hide");
pack.hide();
}
if ($("> ol.templates > li:not(.hide)", pack).length > 0) {
$("> h3", pack).show();
$("> .packhide", pack).show();
$("> .packfocus", pack).show();
}
else {
$("> h3", pack).hide();
$("> .packhide", pack).hide();
$("> .packfocus", pack).hide();
}
});
});
}
// Configure behaviour and layout: add focus and hide links on packages
/* Configures the hide tool by adding the hide link to all packages. */
function configureHideFilter() {
scheduler.add("init", this, function() {
$("#tpl .packages > li").prepend("<a class='packhide'>hide</a>");
// Configures the hide links of packages
$("#tpl .packages > li > a.packhide").click(function(event){
var action = $(this).text();
scheduler.addForAll("init", domCache.liPacks, function(pack) {
$(pack).prepend("<a class='packhide'>hide</a>");
$("> a.packhide", pack).click(function(event) {
var packhide = $(this)
var action = packhide.text();
if (action == "hide") {
$("~ ol", $(this)).hide();
$(this).text("show");
$("~ ol", packhide).hide();
packhide.text("show");
}
else {
$("~ ol", $(this)).show();
$(this).text("hide");
$("~ ol", packhide).show();
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", this, function() {
// Configures the focus links of packages
$("#focusfilter .focusremove").replaceWith("<img class='focusremove icon' src='lib/remove.png'/>");
$("#tpl .packages > li").prepend("<a class='packfocus'>focus</a>");
$("#tpl .packages > li > a.packfocus").click(function(event){
scheduler.add("init", function() {
if ($("#focusfilter").length == 0) {
$("#filter").append("<div id='focusfilter'>focused on <span class='focuscoll'></span> <a class='focusremove'><img class='icon' src='lib/remove.png'/></a></div>");
$("#focusfilter > .focusremove").click(function(event) {
scheduler.clear("filter");
scheduler.add("focus", function() {
$("#tpl > ol.templates").replaceWith(topLevelTemplates.clone());
$("#tpl > ol.packages").replaceWith(topLevelPackages.clone());
domCache.update();
$("#focusfilter").hide();
resizeFilterBlock();
configureEntityList();
});
});
$("#focusfilter").hide();
resizeFilterBlock();
}
});
scheduler.addForAll("init", domCache.liPacks, function(pack) {
$(pack).prepend("<a class='packfocus'>focus</a>");
$("> a.packfocus", pack).click(function(event) {
focusFilter($(this).parent());
return false;
});
$("#focusfilter .focusremove").click(function(event){
scheduler.clear("filter");
$("#tpl > ol.templates").replaceWith(topLevelTemplates.clone());
$("#tpl > ol.packages").replaceWith(topLevelPackages.clone());
$("#focusfilter").hide();
configureEntityList();
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 <li> element that corresponds to the package in the entity index
/* 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 <li> element that corresponds to the package in the entity index */
function focusFilter(package) {
scheduler.add("focus", this, function() {
scheduler.add("focus", function() {
scheduler.clear("filter");
var currentFocus = package.attr("title");
$("#focusfilter .focuscoll").empty();
$("#focusfilter .focuscoll").append(currentFocus);
var templates = $(" > ol.templates", package);
var packages = $(" > ol.packages", package);
$("#tpl > ol.templates").replaceWith(templates);
$("#tpl > ol.packages").replaceWith(packages);
$("#focusfilter > .focuscoll").empty();
$("#focusfilter > .focuscoll").append(currentFocus);
var packTemplates = $("> ol.templates", package);
var packPackages = $("> ol.packages", package);
$("#tpl > ol.templates").replaceWith(packTemplates);
$("#tpl > ol.packages").replaceWith(packPackages);
domCache.update();
$("#focusfilter").show();
resizeFilterBlock();
});
}
function resizeFilterBlock() {
scheduler.add("init", this, function() {
$("#tpl").css("top", $("#filter").outerHeight(true));
});
$("#tpl").css("top", $("#filter").outerHeight(true));
}

View File

@ -3,7 +3,7 @@
function Scheduler() {
var scheduler = this;
var resolution = 1;
var resolution = 0;
this.timeout = undefined;
this.queues = new Array(0); // an array of work pacakges indexed by index in the labels table.
this.labels = new Array(0); // an indexed array of labels indexed by priority. This should be short.
@ -34,12 +34,13 @@ function Scheduler() {
}
return fn;
}
this.add = function(labelName, self, fn) {
this.add = function(labelName, fn, self, args) {
var doWork = function() {
scheduler.timeout = setTimeout(function() {
var work = scheduler.nextWork();
if (work != undefined) {
work[1].call(work[0]);
//alert(work[0]);
work[0].apply(work[1], work[2]);
doWork();
}
else {
@ -50,14 +51,10 @@ function Scheduler() {
var idx = 0;
while (idx < scheduler.labels.length && scheduler.labels[idx].name != labelName) { idx = idx + 1; }
if (idx < scheduler.queues.length && scheduler.labels[idx].name == labelName) {
scheduler.queues[idx].push([self, fn]);
if (scheduler.timeout == undefined) {
doWork();
}
}
else {
throw("queue for add is non existant");
scheduler.queues[idx].push([fn, self, args]);
if (scheduler.timeout == undefined) doWork();
}
else throw("queue for add is non existant");
}
this.clear = function(labelName) {
var idx = 0;

View File

@ -37,7 +37,7 @@ $(document).ready(function(){
tip: "#tooltip",
position:"top center",
onBeforeShow: function(ev) {
$(this.getTip()).text($(ev.srcElement).attr("name"));
$(this.getTip()).text(this.getTrigger().attr("name"));
}
});
$("#template div.fullcomment").hide();