summaryrefslogtreecommitdiff
path: root/src/compiler
diff options
context:
space:
mode:
authorGilles Dubochet <gilles.dubochet@epfl.ch>2010-02-11 13:55:34 +0000
committerGilles Dubochet <gilles.dubochet@epfl.ch>2010-02-11 13:55:34 +0000
commita78bf650be7cc82e43907d1bbf966b3d802fc301 (patch)
tree841f40d822d2a33cd05570909f7d1d06676abfc7 /src/compiler
parentc37cb5ad1d8977ebbd9a559a884d7115df980a53 (diff)
downloadscala-a78bf650be7cc82e43907d1bbf966b3d802fc301.tar.gz
scala-a78bf650be7cc82e43907d1bbf966b3d802fc301.tar.bz2
scala-a78bf650be7cc82e43907d1bbf966b3d802fc301.zip
[scaladoc] Fixed popup content lookup so that i...
[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.
Diffstat (limited to 'src/compiler')
-rw-r--r--src/compiler/scala/tools/nsc/doc/html/page/Index.scala13
-rw-r--r--src/compiler/scala/tools/nsc/doc/html/resource/lib/index.css2
-rw-r--r--src/compiler/scala/tools/nsc/doc/html/resource/lib/index.js252
-rw-r--r--src/compiler/scala/tools/nsc/doc/html/resource/lib/scheduler.js17
-rw-r--r--src/compiler/scala/tools/nsc/doc/html/resource/lib/template.js2
5 files changed, 146 insertions, 140 deletions
diff --git a/src/compiler/scala/tools/nsc/doc/html/page/Index.scala b/src/compiler/scala/tools/nsc/doc/html/page/Index.scala
index 786bb5d11d..135696a869 100644
--- a/src/compiler/scala/tools/nsc/doc/html/page/Index.scala
+++ b/src/compiler/scala/tools/nsc/doc/html/page/Index.scala
@@ -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>
}
diff --git a/src/compiler/scala/tools/nsc/doc/html/resource/lib/index.css b/src/compiler/scala/tools/nsc/doc/html/resource/lib/index.css
index 84855d0d1a..fc759867a4 100644
--- a/src/compiler/scala/tools/nsc/doc/html/resource/lib/index.css
+++ b/src/compiler/scala/tools/nsc/doc/html/resource/lib/index.css
@@ -99,7 +99,7 @@ h1 {
right: 0;
left: 0;
bottom: 0;
- top: 0;
+ top: 5px;
position: absolute;
display: block;
}
diff --git a/src/compiler/scala/tools/nsc/doc/html/resource/lib/index.js b/src/compiler/scala/tools/nsc/doc/html/resource/lib/index.js
index e70b1a0725..09e298e98a 100644
--- a/src/compiler/scala/tools/nsc/doc/html/resource/lib/index.js
+++ b/src/compiler/scala/tools/nsc/doc/html/resource/lib/index.js
@@ -1,10 +1,11 @@
// © 2009–2010 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");
+ }
}
-// 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()); });
- });
- });
+/* 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();
+ });
}
-// 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){
- 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());
+ 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();
- configureEntityList();
+ 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;
});
});
}
-// 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));
}
diff --git a/src/compiler/scala/tools/nsc/doc/html/resource/lib/scheduler.js b/src/compiler/scala/tools/nsc/doc/html/resource/lib/scheduler.js
index d9fb8a453c..51d8ae8cc3 100644
--- a/src/compiler/scala/tools/nsc/doc/html/resource/lib/scheduler.js
+++ b/src/compiler/scala/tools/nsc/doc/html/resource/lib/scheduler.js
@@ -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;
diff --git a/src/compiler/scala/tools/nsc/doc/html/resource/lib/template.js b/src/compiler/scala/tools/nsc/doc/html/resource/lib/template.js
index e69a055951..4ff278e80b 100644
--- a/src/compiler/scala/tools/nsc/doc/html/resource/lib/template.js
+++ b/src/compiler/scala/tools/nsc/doc/html/resource/lib/template.js
@@ -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();