utils.js revision c6d2bb78af2f7ed5cdc80dec65d0d084cd035b22
b4b45a7526fef6a514d6c746d80a05f898ba573dKryštof Tulinger * CDDL HEADER START
b4b45a7526fef6a514d6c746d80a05f898ba573dKryštof Tulinger * The contents of this file are subject to the terms of the
b4b45a7526fef6a514d6c746d80a05f898ba573dKryštof Tulinger * Common Development and Distribution License (the "License").
b4b45a7526fef6a514d6c746d80a05f898ba573dKryštof Tulinger * You may not use this file except in compliance with the License.
b4b45a7526fef6a514d6c746d80a05f898ba573dKryštof Tulinger * See LICENSE.txt included in this distribution for the specific
b4b45a7526fef6a514d6c746d80a05f898ba573dKryštof Tulinger * language governing permissions and limitations under the License.
b4b45a7526fef6a514d6c746d80a05f898ba573dKryštof Tulinger * When distributing Covered Code, include this CDDL HEADER in each
b4b45a7526fef6a514d6c746d80a05f898ba573dKryštof Tulinger * file and include the License file at LICENSE.txt.
b4b45a7526fef6a514d6c746d80a05f898ba573dKryštof Tulinger * If applicable, add the following below this CDDL HEADER, with the
b4b45a7526fef6a514d6c746d80a05f898ba573dKryštof Tulinger * fields enclosed by brackets "[]" replaced with your own identifying
b4b45a7526fef6a514d6c746d80a05f898ba573dKryštof Tulinger * information: Portions Copyright [yyyy] [name of copyright owner]
b4b45a7526fef6a514d6c746d80a05f898ba573dKryštof Tulinger * CDDL HEADER END
b4b45a7526fef6a514d6c746d80a05f898ba573dKryštof Tulinger * Copyright (c) 2009, 2016, Oracle and/or its affiliates. All rights reserved.
b4b45a7526fef6a514d6c746d80a05f898ba573dKryštof Tulinger * Portions Copyright 2011 Jens Elkner.
b4b45a7526fef6a514d6c746d80a05f898ba573dKryštof Tulinger * Spaces plugin.
b4b45a7526fef6a514d6c746d80a05f898ba573dKryštof Tulinger * Inserts a dummy space between line number and the text so that on copy-paste
b4b45a7526fef6a514d6c746d80a05f898ba573dKryštof Tulinger * the white space is preserved.
b4b45a7526fef6a514d6c746d80a05f898ba573dKryštof Tulinger * Internally listens on scroll events and autofills the spaces only for the visible
b4b45a7526fef6a514d6c746d80a05f898ba573dKryštof Tulinger * IMPORTANT: This plugin is strictly dependent on ascending order of lines
b4b45a7526fef6a514d6c746d80a05f898ba573dKryštof Tulinger * and on their attribute "name". It performs a binary search which boosts performance
b4b45a7526fef6a514d6c746d80a05f898ba573dKryštof Tulinger * of this plugin for really long files.
b4b45a7526fef6a514d6c746d80a05f898ba573dKryštof Tulinger * @author Krystof Tulinger
b4b45a7526fef6a514d6c746d80a05f898ba573dKryštof Tulinger(function (w, $) {
b4b45a7526fef6a514d6c746d80a05f898ba573dKryštof Tulinger var spaces = function () {
b4b45a7526fef6a514d6c746d80a05f898ba573dKryštof Tulinger callback: function () {
b4b45a7526fef6a514d6c746d80a05f898ba573dKryštof Tulinger binarySearch: function (array, key, compare) {
b4b45a7526fef6a514d6c746d80a05f898ba573dKryštof Tulinger // the first element in viewport
b4b45a7526fef6a514d6c746d80a05f898ba573dKryštof Tulinger start: Math.floor(inner.options.$parent.scrollTop() / inner.$collection.first().height()),
b4b45a7526fef6a514d6c746d80a05f898ba573dKryštof Tulinger // the last element in viewport
b4b45a7526fef6a514d6c746d80a05f898ba573dKryštof Tulinger end: Math.ceil((inner.options.$parent.scrollTop()
b4b45a7526fef6a514d6c746d80a05f898ba573dKryštof Tulinger + inner.options.$parent.height()) / inner.$collection.first().height())
b4b45a7526fef6a514d6c746d80a05f898ba573dKryštof Tulinger return $(a).attr("name") - key; // comparing the "name" attribute with the desired value
b4b45a7526fef6a514d6c746d80a05f898ba573dKryštof Tulinger indices.start = inner.binarySearch(inner.$collection, expectations.start, cmp);
b4b45a7526fef6a514d6c746d80a05f898ba573dKryštof Tulinger indices.end = inner.binarySearch(inner.$collection, expectations.end, cmp);
b4b45a7526fef6a514d6c746d80a05f898ba573dKryštof Tulinger /** cutoffs */
b4b45a7526fef6a514d6c746d80a05f898ba573dKryštof Tulinger indices.start = Math.max(0, indices.start);
b4b45a7526fef6a514d6c746d80a05f898ba573dKryštof Tulinger indices.start = Math.min(inner.$collection.length - 1, indices.start);
b4b45a7526fef6a514d6c746d80a05f898ba573dKryštof Tulinger indices.end = inner.$collection.length - 1;
b4b45a7526fef6a514d6c746d80a05f898ba573dKryštof Tulinger indices.end = Math.min(inner.$collection.length - 1, indices.end);
b4b45a7526fef6a514d6c746d80a05f898ba573dKryštof Tulinger /** calling callback for every element in the viewport */
b4b45a7526fef6a514d6c746d80a05f898ba573dKryštof Tulinger for (var i = indices.start; i <= indices.end; i++) {
b4b45a7526fef6a514d6c746d80a05f898ba573dKryštof Tulinger inner.options.callback.apply(inner.$collection[i])
b4b45a7526fef6a514d6c746d80a05f898ba573dKryštof Tulinger init: function () {
b4b45a7526fef6a514d6c746d80a05f898ba573dKryštof Tulinger inner.$collection = inner.options.$parent.find(inner.options.selector);
b4b45a7526fef6a514d6c746d80a05f898ba573dKryštof Tulinger var scrollHandler = function (e) {
b4b45a7526fef6a514d6c746d80a05f898ba573dKryštof Tulinger setTimeout(inner.handleScrollEvent, inner.options.interval);
b4b45a7526fef6a514d6c746d80a05f898ba573dKryštof Tulinger inner.options.$parent.scroll(scrollHandler)
b4b45a7526fef6a514d6c746d80a05f898ba573dKryštof Tulinger inner.options = $.extend({}, inner.defaults, {$parent: $("#content")}, options)
b4b45a7526fef6a514d6c746d80a05f898ba573dKryštof Tulinger $.spaces = new ($.extend(spaces, $.spaces ? $.spaces : {}));
b4b45a7526fef6a514d6c746d80a05f898ba573dKryštof Tulinger(function(window, $) {
b4b45a7526fef6a514d6c746d80a05f898ba573dKryštof Tulinger var hash = function () {
b4b45a7526fef6a514d6c746d80a05f898ba573dKryštof Tulinger linkSelectorTemplate: '{parent} a[name={n}]',
b4b45a7526fef6a514d6c746d80a05f898ba573dKryštof Tulinger clickSelector: '{parent} a.l, {parent} a.hl',
b4b45a7526fef6a514d6c746d80a05f898ba573dKryštof Tulinger $(inner.format(inner.options.clickSelector, {parent: inner.options.parent})).click (function (e){
b4b45a7526fef6a514d6c746d80a05f898ba573dKryštof Tulinger // shift pressed
b4b45a7526fef6a514d6c746d80a05f898ba573dKryštof Tulinger var val = inner.toInt($(this).attr("name"))
b4b45a7526fef6a514d6c746d80a05f898ba573dKryštof Tulinger var l = inner.getLinesParts(window.location.hash)
b4b45a7526fef6a514d6c746d80a05f898ba573dKryštof Tulinger window.location.hash = "#" + Math.min(l[0], val) + "-" + Math.max(val, l[1])
b4b45a7526fef6a514d6c746d80a05f898ba573dKryštof Tulinger window.location.hash = "#" + Math.min(l[0], val) + "-" + Math.max(l[0], val)
b4b45a7526fef6a514d6c746d80a05f898ba573dKryštof Tulinger return (hash = hash.split("#")).length > 1 ? hash[1] : "";
b4b45a7526fef6a514d6c746d80a05f898ba573dKryštof Tulinger if(s.length > 1 && inner.toInt(s[0]) && inner.toInt(s[1]))
b4b45a7526fef6a514d6c746d80a05f898ba573dKryštof Tulinger return [ inner.toInt(s[0]), inner.toInt(s[1]) ]
b4b45a7526fef6a514d6c746d80a05f898ba573dKryštof Tulinger for ( var i = Math.min(p[0],p[1]); i <= Math.max(p[0], p[1]); i ++ )
b4b45a7526fef6a514d6c746d80a05f898ba573dKryštof Tulinger return [ p[0] ]
b4b45a7526fef6a514d6c746d80a05f898ba573dKryštof Tulinger for ( var i = 0; i < inner.highlighted.length; i ++ ) {
b4b45a7526fef6a514d6c746d80a05f898ba573dKryštof Tulinger // remove color
b4b45a7526fef6a514d6c746d80a05f898ba573dKryštof Tulinger inner.highlighted[i].removeClass(inner.options.highlightedClass)
b4b45a7526fef6a514d6c746d80a05f898ba573dKryštof Tulinger var lines = inner.lines(window.location.hash);
b4b45a7526fef6a514d6c746d80a05f898ba573dKryštof Tulinger // not a case of line highlighting
b4b45a7526fef6a514d6c746d80a05f898ba573dKryštof Tulinger for ( var i = 0; i < lines.length; i ++ ) {
b4b45a7526fef6a514d6c746d80a05f898ba573dKryštof Tulinger var slc = inner.format(inner.options.linkSelectorTemplate, { "parent": inner.options.parent,
b4b45a7526fef6a514d6c746d80a05f898ba573dKryštof Tulinger var el = $(slc).addClass(inner.options.highlightedClass)
b4b45a7526fef6a514d6c746d80a05f898ba573dKryštof Tulinger var args = Array.prototype.slice.call(arguments, 1);
b4b45a7526fef6a514d6c746d80a05f898ba573dKryštof Tulinger args = args.length > 0 ? typeof args[0] === "object" ? args[0] : args : args;
b4b45a7526fef6a514d6c746d80a05f898ba573dKryštof Tulinger return format.replace(/{([a-zA-Z0-9_-]+)}/g, function(match, number) {
b4b45a7526fef6a514d6c746d80a05f898ba573dKryštof Tulinger var lines = inner.getLinesParts(window.location.hash);
b4b45a7526fef6a514d6c746d80a05f898ba573dKryštof Tulinger scrollTop: $(inner.format(inner.options.linkSelectorTemplate, {
b4b45a7526fef6a514d6c746d80a05f898ba573dKryštof Tulinger })).offset().top - $(inner.options.parent).offset().top
b4b45a7526fef6a514d6c746d80a05f898ba573dKryštof Tulinger $("<div>Did you know? You can select a range of lines<br /> by clicking on the other while holding shift key.</div>")
b4b45a7526fef6a514d6c746d80a05f898ba573dKryštof Tulinger $(inner.format(inner.options.clickSelector, {parent: inner.options.parent}))
b4b45a7526fef6a514d6c746d80a05f898ba573dKryštof Tulinger .click(function(e) {
b4b45a7526fef6a514d6c746d80a05f898ba573dKryštof Tulinger var $el = $(this)
b4b45a7526fef6a514d6c746d80a05f898ba573dKryštof Tulinger inner.options = $.extend(inner.defaults, options, {})
b4b45a7526fef6a514d6c746d80a05f898ba573dKryštof Tulinger $.hash = new ($.extend(hash, $.hash ? $.hash : {}));
b4b45a7526fef6a514d6c746d80a05f898ba573dKryštof Tulinger // starting spaces plugin
b4b45a7526fef6a514d6c746d80a05f898ba573dKryštof Tulinger $("#sbox input[type='submit']").click(function (e) {
b4b45a7526fef6a514d6c746d80a05f898ba573dKryštof Tulinger $("#results > p.pagetitle").hide(); // description
b4b45a7526fef6a514d6c746d80a05f898ba573dKryštof Tulinger $("#results > p.slider").hide(); // pagination
b4b45a7526fef6a514d6c746d80a05f898ba573dKryštof Tulinger $("#results > table, #results > ul").hide(); // results + empty
b4b45a7526fef6a514d6c746d80a05f898ba573dKryštof Tulinger $("#results > table + p, #results > ul + p").hide(); // results + empty timing
b4b45a7526fef6a514d6c746d80a05f898ba573dKryštof Tulinger for(var i in this.domReady) {
b4b45a7526fef6a514d6c746d80a05f898ba573dKryštof Tulinger * Resize the element with the ID 'content' so that it fills the whole browser
b4b45a7526fef6a514d6c746d80a05f898ba573dKryštof Tulinger * window (i.e. the space between the header and the bottom of the window) and
b4b45a7526fef6a514d6c746d80a05f898ba573dKryštof Tulinger * thus get rid off the scrollbar in the page header.
b4b45a7526fef6a514d6c746d80a05f898ba573dKryštof Tulinger $('#content').css('top', $('body').outerHeight(true)).css('bottom', 0);
b4b45a7526fef6a514d6c746d80a05f898ba573dKryštof Tulinger * Get a parameter value from the URL.
b4b45a7526fef6a514d6c746d80a05f898ba573dKryštof Tulinger * @param p the name of the parameter
b4b45a7526fef6a514d6c746d80a05f898ba573dKryštof Tulinger * @return the decoded value of parameter p
b4b45a7526fef6a514d6c746d80a05f898ba573dKryštof Tulinger // First split up the parameter list. That is, transform from
b4b45a7526fef6a514d6c746d80a05f898ba573dKryštof Tulinger // [ ["a", "b"], ["c","d"] ]
b4b45a7526fef6a514d6c746d80a05f898ba573dKryštof Tulinger getParameter.params = window.location.search.substr(1).split("&").map(
b4b45a7526fef6a514d6c746d80a05f898ba573dKryštof Tulinger // Then look for the parameter.
b4b45a7526fef6a514d6c746d80a05f898ba573dKryštof Tulinger for (var i in params) {
b4b45a7526fef6a514d6c746d80a05f898ba573dKryštof Tulinger if (params[i][0] === p && params[i].length > 1) {
b4b45a7526fef6a514d6c746d80a05f898ba573dKryštof Tulinger if (h && h !== "") {
b4b45a7526fef6a514d6c746d80a05f898ba573dKryštof Tulinger content: function () {
b4b45a7526fef6a514d6c746d80a05f898ba573dKryštof Tulinger var element = $(this);
b4b45a7526fef6a514d6c746d80a05f898ba573dKryštof Tulinger var parts = title.split(/<br\/>(?=[a-zA-Z0-9]+:)/g);
b4b45a7526fef6a514d6c746d80a05f898ba573dKryštof Tulinger $("<dt>").text(definitions.shift().trim()).appendTo($el);
b4b45a7526fef6a514d6c746d80a05f898ba573dKryštof Tulinger $.each(definitions.join("").split("<br/>"), function (i, el) {
b4b45a7526fef6a514d6c746d80a05f898ba573dKryštof Tulinger //$('a.r').tooltip({ left: 5, showURL: false });
b4b45a7526fef6a514d6c746d80a05f898ba573dKryštof Tulinger var toggle_js = document.getElementById('toggle-annotate-by-javascript');
b4b45a7526fef6a514d6c746d80a05f898ba573dKryštof Tulinger var toggle_ss = document.getElementById('toggle-annotate');
b4b45a7526fef6a514d6c746d80a05f898ba573dKryštof Tulinger // When we move to a version of XHTML that supports the onscroll
b4b45a7526fef6a514d6c746d80a05f898ba573dKryštof Tulinger // attribute in the div element, we should add an onscroll attribute
b4b45a7526fef6a514d6c746d80a05f898ba573dKryštof Tulinger // in the generated XHTML in mast.jsp. For now, set it with jQuery.
b4b45a7526fef6a514d6c746d80a05f898ba573dKryštof Tulinger if ($('#whole_header') != null && $('#content') != null) {
b4b45a7526fef6a514d6c746d80a05f898ba573dKryštof Tulinger var sbox = document.getElementById('sbox');
b4b45a7526fef6a514d6c746d80a05f898ba573dKryštof Tulinger $("#project").autocomplete(projects, {
b4b45a7526fef6a514d6c746d80a05f898ba573dKryštof Tulinger multiple: true,
b4b45a7526fef6a514d6c746d80a05f898ba573dKryštof Tulinger multipleSeparator: ",",
b4b45a7526fef6a514d6c746d80a05f898ba573dKryštof Tulinger //mustMatch: true,
b4b45a7526fef6a514d6c746d80a05f898ba573dKryštof Tulinger matchContains: "word",
b4b45a7526fef6a514d6c746d80a05f898ba573dKryštof Tulinger cacheLength:20,
b4b45a7526fef6a514d6c746d80a05f898ba573dKryštof Tulinger //autoFill: false,
b4b45a7526fef6a514d6c746d80a05f898ba573dKryštof Tulinger formatItem: function(row, i, max) {
b4b45a7526fef6a514d6c746d80a05f898ba573dKryštof Tulinger return (row != null) ? i + "/" + max + ": " + row[0] : "";
b4b45a7526fef6a514d6c746d80a05f898ba573dKryštof Tulinger formatMatch: function(row, i, max) {
b4b45a7526fef6a514d6c746d80a05f898ba573dKryštof Tulinger return (row != null) ? row[0] : "";
b4b45a7526fef6a514d6c746d80a05f898ba573dKryštof Tulinger formatResult: function(row) {
b4b45a7526fef6a514d6c746d80a05f898ba573dKryštof Tulinger return (row != null) ? row[0] : "";
b4b45a7526fef6a514d6c746d80a05f898ba573dKryštof Tulinger width: "300px"
b4b45a7526fef6a514d6c746d80a05f898ba573dKryštof Tulinger // TODO Bug 11749
b4b45a7526fef6a514d6c746d80a05f898ba573dKryštof Tulinger // var p = document.getElementById('project');
b4b45a7526fef6a514d6c746d80a05f898ba573dKryštof Tulinger // p.setAttribute("autocomplete", "off");
b4b45a7526fef6a514d6c746d80a05f898ba573dKryštof Tulinger // start state should ALWAYS be: first row: r1 hidden, r2 checked ;
b4b45a7526fef6a514d6c746d80a05f898ba573dKryštof Tulinger // second row: r1 clicked, (r2 hidden)(optionally)
b4b45a7526fef6a514d6c746d80a05f898ba573dKryštof Tulinger // I cannot say what will happen if they are not like that, togglediffs
b4b45a7526fef6a514d6c746d80a05f898ba573dKryštof Tulinger // will go mad !
b4b45a7526fef6a514d6c746d80a05f898ba573dKryštof Tulinger $("#revisions input[type=radio]").click(togglediffs);
b4b45a7526fef6a514d6c746d80a05f898ba573dKryštof Tulinger var link = window.location.pathname + "?a=true";
b4b45a7526fef6a514d6c746d80a05f898ba573dKryštof Tulinger link += "&r=" + encodeURIComponent(document.rev);
b4b45a7526fef6a514d6c746d80a05f898ba573dKryštof Tulinger // If a line is highlighted when "annotate" is clicked, we want to
b4b45a7526fef6a514d6c746d80a05f898ba573dKryštof Tulinger // preserve the highlighting, but we don't want the page to scroll
b4b45a7526fef6a514d6c746d80a05f898ba573dKryštof Tulinger // to the highlighted line. So put the line number in a URL parameter
b4b45a7526fef6a514d6c746d80a05f898ba573dKryštof Tulinger // instead of in the hash.
b4b45a7526fef6a514d6c746d80a05f898ba573dKryštof Tulinger link += window.location.hash.substring(1, window.location.hash.length);
b4b45a7526fef6a514d6c746d80a05f898ba573dKryštof Tulinger $(document.body).toggleClass("blame-hidden");
b4b45a7526fef6a514d6c746d80a05f898ba573dKryštof Tulinger * Initialize defaults for list.jsp
b4b45a7526fef6a514d6c746d80a05f898ba573dKryštof Tulinger document.sym_div.style.left = get_sym_div_left() + "px";
function get_sym_list_contents() {
var contents =
return contents;
contents += "<a href=\"#" + line + "\" class=\"" + class_name + "\" onclick=\"lnshow(); return true;\">"
return contents;
function get_sym_div_left() {
function get_sym_div_height() {
function get_sym_div_top() {
function get_sym_div_width() {
function lsttoggle() {
function lntoggle() {
function lnshow() {
function add_highlight() {
function toggle_filelist() {
function toggle_revtags() {
function togglediffs() {
var cr2 = false;
var cr1 = false;
if (this.checked) {
cr1 = true;
if (cr2) {
if (this.checked) {
cr2=true;
if (!cr1) {
function togglerevs() {
function selectAllProjects() {
function invertAllProjects() {
function goFirstProject(e) {
return $(e).text();
if(! e.shiftKey) {
function clearSearchFrom() {
(bgcolor === "rgb(255, 215, 0)" || bgcolor === "rgb(255,215,0)" || bgcolor === "#ffd700"); // gold. the last two cover IE
var header = [
function showIntelliWindow() {
var top;
var left;
function createIntelliWindow() {
function hideIntelliWindow() {
function createCapitionHTML() {
switch (symbolType) {
function unhighlightAll() {
return bgcolor === "rgb(255, 215, 0)" || bgcolor === "rgb(255,215,0)" || bgcolor === "#ffd700"; // gold. the last two cover IE
function scope_on_scroll() {
prev = c;
if (par === null) {