commited entire static.scrapy.org tree
--HG-- rename : sites/dev.scrapy.org/htdocs/images/logo.jpg => sites/dev.scrapy.org/htdocs/logo.jpg extra : convert_revision : svn%3Ab85faa78-f9eb-468e-a121-7cced6da292c%4021
|
After Width: | Height: | Size: 222 B |
|
After Width: | Height: | Size: 280 B |
|
After Width: | Height: | Size: 294 B |
|
After Width: | Height: | Size: 297 B |
|
After Width: | Height: | Size: 218 B |
|
|
@ -1,5 +1,5 @@
|
|||
body {
|
||||
background: #FFFFFF url('/scrapy/chrome/site/main-bg.jpg') repeat-x left top;
|
||||
background: #FFFFFF url('/main-bg.jpg') repeat-x left top;
|
||||
color: #000;
|
||||
margin: 10px;
|
||||
padding: 0;
|
||||
|
|
|
|||
|
After Width: | Height: | Size: 222 B |
|
After Width: | Height: | Size: 50 B |
|
After Width: | Height: | Size: 4.8 KiB |
|
After Width: | Height: | Size: 1.4 KiB |
|
After Width: | Height: | Size: 241 B |
|
After Width: | Height: | Size: 180 B |
|
After Width: | Height: | Size: 227 B |
|
After Width: | Height: | Size: 241 B |
|
After Width: | Height: | Size: 212 B |
|
After Width: | Height: | Size: 223 B |
|
After Width: | Height: | Size: 209 B |
|
After Width: | Height: | Size: 90 B |
|
After Width: | Height: | Size: 638 B |
|
After Width: | Height: | Size: 285 B |
|
After Width: | Height: | Size: 357 B |
|
After Width: | Height: | Size: 8.8 KiB |
|
After Width: | Height: | Size: 5.6 KiB |
|
After Width: | Height: | Size: 347 B |
|
After Width: | Height: | Size: 205 B |
|
|
@ -0,0 +1,102 @@
|
|||
|
||||
(function($){
|
||||
|
||||
window.enableBlame = function(url, original_path) {
|
||||
var message = null;
|
||||
var message_rev = null;
|
||||
|
||||
/* for each blame cell containing a changeset link... */
|
||||
var rev_paths = {};
|
||||
$("table.code th.blame a").each(function() {
|
||||
href = $(this).attr("href");
|
||||
$(this).removeAttr("href");
|
||||
rev_href = href.substr(href.indexOf("changeset/") + 10);
|
||||
elts = rev_href.split("/");
|
||||
var path = elts.slice(1).join("/");
|
||||
if (path != original_path)
|
||||
rev_paths["r"+elts[0]] = path;
|
||||
});
|
||||
|
||||
/* for each blame cell... */
|
||||
$("table.code th.blame").each(function() {
|
||||
var rev = $(this).attr("class").split(" ")[1]; // "blame r123"
|
||||
var path = rev_paths[rev] || original_path; // only found if != orig
|
||||
|
||||
if (!rev)
|
||||
return;
|
||||
|
||||
$(this).css("cursor", "pointer").click(function() {
|
||||
var row = this.parentNode;
|
||||
var message_is_visible = message && message.css("display") == "block";
|
||||
var highlight_rev = null;
|
||||
|
||||
function show() {
|
||||
/* Display commit message for the selected revision */
|
||||
|
||||
var message_w = message.get(0).offsetWidth;
|
||||
|
||||
// limit message panel width to 3/5 of the row width
|
||||
var row_w = row.offsetWidth;
|
||||
var max_w = (3.0 * row_w / 5.0);
|
||||
if (!message_w || message_w > max_w) {
|
||||
message_w = max_w;
|
||||
var borderw = (3+8)*2; // borderwidth + padding on both sides
|
||||
message.css({width: message_w - borderw + "px"});
|
||||
}
|
||||
|
||||
var row_offset = $(row).offset();
|
||||
var left = row_offset.left + row.offsetWidth - message_w;
|
||||
message.css({display: "block", top: row_offset.top+"px", left: left-2+"px"});
|
||||
}
|
||||
|
||||
function hide() {
|
||||
/* Hide commit message */
|
||||
message.css({display: "none"});
|
||||
|
||||
/* Remove highlighting for lines of the current revision */
|
||||
$("table.code th."+message_rev).each(function() {
|
||||
$(this.parentNode).removeClass("hilite")
|
||||
});
|
||||
}
|
||||
|
||||
if (message_rev != rev) { // fetch a new revision
|
||||
if (message_is_visible) {
|
||||
hide();
|
||||
}
|
||||
message_rev = rev;
|
||||
highlight_rev = message_rev;
|
||||
|
||||
$.get(url + rev.substr(1), {annotate: path}, function(data) {
|
||||
// remove former message panel if any
|
||||
if (message)
|
||||
message.remove();
|
||||
// create new message panel
|
||||
message = $('<div class="message">').css("position", "absolute")
|
||||
.append($('<div class="inlinebuttons">')
|
||||
.append($('<input value="Close" type="button">').click(hide)))
|
||||
.append($('<div>').html(data || "<strong>(no changeset information)</strong>"))
|
||||
.appendTo("body");
|
||||
|
||||
// workaround non-clickable "Close" issue in Firefox
|
||||
if ($.browser.mozilla)
|
||||
message.find("div.inlinebuttons").next().css("clear", "right");
|
||||
|
||||
show();
|
||||
});
|
||||
} else if (message_is_visible) {
|
||||
hide();
|
||||
} else {
|
||||
show();
|
||||
highlight_rev = message_rev;
|
||||
}
|
||||
|
||||
/* Highlight all lines of the current revision */
|
||||
$("table.code th."+highlight_rev).each(function() {
|
||||
$(this.parentNode).addClass("hilite")
|
||||
});
|
||||
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
})(jQuery);
|
||||
|
|
@ -0,0 +1,113 @@
|
|||
(function($){
|
||||
|
||||
function convertDiff(name, table) {
|
||||
var inline = table.className == 'inline';
|
||||
var ths = table.tHead.rows[0].cells;
|
||||
var afile, bfile;
|
||||
if ( inline ) {
|
||||
afile = ths[0].title;
|
||||
bfile = ths[1].title;
|
||||
} else {
|
||||
afile = $(ths[0]).find('a').text();
|
||||
bfile = $(ths[1]).find('a').text();
|
||||
}
|
||||
if ( afile.match(/^Revision /) ) {
|
||||
afile = 'a/' + name;
|
||||
bfile = 'b/' + name;
|
||||
}
|
||||
var lines = [
|
||||
"Index: " + name,
|
||||
"===================================================================",
|
||||
"--- " + afile.replace(/File /, ''),
|
||||
"+++ " + bfile.replace(/File /, ''),
|
||||
];
|
||||
var sepIndex = 0;
|
||||
var oldOffset = 0, oldLength = 0, newOffset = 0, newLength = 0;
|
||||
|
||||
for (var i = 0; i < table.tBodies.length; i++) {
|
||||
var tBody = table.tBodies[i];
|
||||
if (i == 0 || tBody.className == "skipped") {
|
||||
if (i > 0) {
|
||||
if (!oldOffset && oldLength) oldOffset = 1
|
||||
if (!newOffset && newLength) newOffset = 1
|
||||
lines[sepIndex] = lines[sepIndex]
|
||||
.replace("{1}", oldOffset).replace("{2}", oldLength)
|
||||
.replace("{3}", newOffset).replace("{4}", newLength);
|
||||
}
|
||||
sepIndex = lines.length;
|
||||
lines.push("@@ -{1},{2} +{3},{4} @@");
|
||||
oldOffset = 0, oldLength = 0, newOffset = 0, newLength = 0;
|
||||
if (tBody.className == "skipped") continue;
|
||||
}
|
||||
var tmpLines = [];
|
||||
for (var j = 0; j < tBody.rows.length; j++) {
|
||||
var cells = tBody.rows[j].cells;
|
||||
var oldLineNo = parseInt($(cells[0]).text());
|
||||
var newLineNo = parseInt($(cells[inline ? 1 : 2]).text());
|
||||
if (tBody.className == 'unmod') {
|
||||
lines.push(" " + $(cells[inline ? 2 : 1]).text());
|
||||
oldLength += 1;
|
||||
newLength += 1;
|
||||
if (!oldOffset) oldOffset = oldLineNo;
|
||||
if (!newOffset) newOffset = newLineNo;
|
||||
} else {
|
||||
var oldLine;
|
||||
var newLine;
|
||||
if (inline) {
|
||||
oldLine = newLine = $(cells[2]).text();
|
||||
} else {
|
||||
oldLine = $(cells[1]).text();
|
||||
newLine = $(cells[3]).text();
|
||||
}
|
||||
if (!isNaN(oldLineNo)) {
|
||||
lines.push("-" + oldLine);
|
||||
oldLength += 1;
|
||||
}
|
||||
if (!isNaN(newLineNo)) {
|
||||
tmpLines.push("+" + newLine);
|
||||
newLength += 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (tmpLines.length > 0) {
|
||||
lines = lines.concat(tmpLines);
|
||||
}
|
||||
}
|
||||
|
||||
if (!oldOffset && oldLength) oldOffset = 1;
|
||||
if (!newOffset && newLength) newOffset = 1;
|
||||
lines[sepIndex] = lines[sepIndex]
|
||||
.replace("{1}", oldOffset).replace("{2}", oldLength)
|
||||
.replace("{3}", newOffset).replace("{4}", newLength);
|
||||
|
||||
/* remove trailing and join lines (with CR for IExplorer) */
|
||||
for ( var i = 0; i < lines.length; i++ )
|
||||
if ( lines[i] )
|
||||
lines[i] = lines[i].replace(/\xa0$/, '');
|
||||
return lines.join($.browser.msie ? "\r" : "\n");
|
||||
}
|
||||
|
||||
$(document).ready(function($) {
|
||||
$("div.diff h2").each(function() {
|
||||
var switcher = $("<span class='switch'></span>").prependTo(this);
|
||||
var name = $.trim($(this).text());
|
||||
var table = $(this).siblings("table").get(0);
|
||||
if (! table) return;
|
||||
var pre = $("<pre></pre>").hide().insertAfter(table);
|
||||
$("<span>Tabular</span>").click(function() {
|
||||
$(pre).hide();
|
||||
$(table).show();
|
||||
$(this).addClass("active").siblings("span").removeClass("active");
|
||||
return false;
|
||||
}).addClass("active").appendTo(switcher);
|
||||
$("<span>Unified</span>").click(function() {
|
||||
$(table).hide();
|
||||
if (!pre.get(0).firstChild) pre.text(convertDiff(name, table));
|
||||
$(pre).fadeIn("fast")
|
||||
$(this).addClass("active").siblings("span").removeClass("active");
|
||||
return false;
|
||||
}).appendTo(switcher);
|
||||
});
|
||||
});
|
||||
|
||||
})(jQuery);
|
||||
|
|
@ -0,0 +1,116 @@
|
|||
// Enable expanding/folding folders in TracBrowser
|
||||
|
||||
(function($){
|
||||
var FOLDERID_COUNTER = 0;
|
||||
var SUBFOLDER_INDENT = 20;
|
||||
|
||||
// enableExpandDir adds the capability to folder rows to be expanded and folded
|
||||
// It also teach the rows about their ancestors. It expects:
|
||||
// - `parent_tr`, the logical parent row (`null` if there's no ancestor)
|
||||
// - a `rows` jQuery object matching the newly created entry rows
|
||||
// - `qargs`, additional parameters to send to the server when expanding
|
||||
|
||||
window.enableExpandDir = function(parent_tr, rows, qargs) {
|
||||
// the ancestors folder ids are present in the parent_tr class attribute
|
||||
var ancestor_folderids = [];
|
||||
if (parent_tr)
|
||||
ancestor_folderids = $.grep(parent_tr.attr("class").split(" "),
|
||||
function(c) { return c.match(/^f\d+$/)});
|
||||
rows.each(function () {
|
||||
var a = $(this).find("a.dir");
|
||||
|
||||
if (a.length) { // then the entry is a folder
|
||||
// create new folder id
|
||||
var folderid = "f" + FOLDERID_COUNTER++;
|
||||
this.id = folderid;
|
||||
$(this).addClass(folderid);
|
||||
|
||||
// add the expander icon
|
||||
a.wrap('<div></div>');
|
||||
var expander = a.before('<span class="expander"> </span>').prev();
|
||||
expander.attr("title", "Expand sub-directory in place")
|
||||
.click(function() { toggleDir($(this), qargs); });
|
||||
}
|
||||
|
||||
// tie that row to ancestor folders
|
||||
if (parent_tr)
|
||||
$(this).addClass(ancestor_folderids.join(" "));
|
||||
});
|
||||
}
|
||||
|
||||
// handler for click event on the expander icons
|
||||
window.toggleDir = function(expander, qargs) {
|
||||
var tr = expander.parents("tr");
|
||||
var folderid = tr.get(0).id;
|
||||
|
||||
if ( tr.filter(".expanded").length ) { // then *fold*
|
||||
tr.removeClass("expanded").addClass("collapsed");
|
||||
tr.siblings("tr."+folderid).hide();
|
||||
expander.attr("title", "Re-expand directory");
|
||||
return;
|
||||
}
|
||||
|
||||
if ( tr.filter(".collapsed").length ) { // then *expand*
|
||||
tr.removeClass("collapsed").addClass("expanded");
|
||||
tr.siblings("tr."+folderid).show();
|
||||
// Note that the above will show all the already fetched subtree,
|
||||
// so we have to fold again the folders which were already collapsed.
|
||||
tr.siblings("tr.collapsed").each(function() {
|
||||
tr.siblings("tr."+this.id).not(this).hide();
|
||||
});
|
||||
} else { // then *fetch*
|
||||
var td = expander.parents("td");
|
||||
var td_class = td.attr("class");
|
||||
var a = expander.next("a");
|
||||
var depth =
|
||||
parseFloat(td.css("padding-left").replace(/^(\d*\.\d*).*$/, "$1")) +
|
||||
SUBFOLDER_INDENT;
|
||||
|
||||
tr.addClass("expanded");
|
||||
// insert "Loading ..." row
|
||||
tr.after('<tr><td><span class="loading"></span></td></tr>');
|
||||
var loading_row = tr.next();
|
||||
loading_row.children("td").addClass(td_class)
|
||||
.attr("colspan", tr.children("td").length)
|
||||
.css("padding-left", depth);
|
||||
loading_row.find("span.loading").text("Loading " + a.text() + "...");
|
||||
|
||||
// XHR for getting the rows corresponding to the folder entries
|
||||
$.ajax({
|
||||
type: "GET",
|
||||
url: a.attr("href"),
|
||||
data: qargs,
|
||||
dataType: "html",
|
||||
success: function(data) {
|
||||
// Safari 3.1.1 has some trouble reconstructing HTML snippets
|
||||
// bigger than 50k - splitting in rows before building DOM nodes
|
||||
var rows = data.replace(/^<!DOCTYPE[^>]+>/, "").split("</tr>");
|
||||
if (rows.length) {
|
||||
// insert entry rows
|
||||
$(rows).each(function() {
|
||||
row = $(this+"</tr>");
|
||||
row.children("td."+td_class).css("padding-left", depth);
|
||||
// make all entry rows collapsible but only subdir rows expandable
|
||||
enableExpandDir(tr, row, qargs);
|
||||
loading_row.before(row);
|
||||
});
|
||||
// remove "Loading ..." row
|
||||
loading_row.remove();
|
||||
} else {
|
||||
loading_row.find("span.loading").text("").append("<i>(empty)</i>")
|
||||
.removeClass("loading");
|
||||
// make the (empty) row collapsible
|
||||
enableExpandDir(tr, loading_row, qargs);
|
||||
}
|
||||
},
|
||||
error: function(req, err, exc) {
|
||||
loading_row.find("span.loading").text("").append("<i>(error)</i>")
|
||||
.removeClass("loading");
|
||||
enableExpandDir(tr, loading_row, qargs);
|
||||
}
|
||||
});
|
||||
}
|
||||
expander.attr("title", "Fold directory");
|
||||
}
|
||||
|
||||
})(jQuery);
|
||||
|
|
@ -0,0 +1,26 @@
|
|||
(function($){
|
||||
|
||||
$.fn.enableFolding = function(autofold) {
|
||||
var fragId = document.location.hash;
|
||||
if (fragId && /^#no\d+$/.test(fragId)) {
|
||||
fragId = parseInt(fragId.substr(3));
|
||||
}
|
||||
|
||||
var count = 1;
|
||||
return this.each(function() {
|
||||
var t = $(this).text();
|
||||
$(this).text("");
|
||||
var trigger = $(this).append("<a href='#no" + count + "'></a>").children();
|
||||
trigger.text(t);
|
||||
|
||||
trigger.click(function() {
|
||||
if (fragId == count) { fragId = 0; return; }
|
||||
$(this.parentNode.parentNode).toggleClass("collapsed");
|
||||
});
|
||||
if ( autofold )
|
||||
trigger.click();
|
||||
count++;
|
||||
}).css("cursor", "pointer");
|
||||
}
|
||||
|
||||
})(jQuery);
|
||||
|
|
@ -0,0 +1,7 @@
|
|||
jQuery(function($) { // onload
|
||||
$('select').bind('focusin', function() {
|
||||
this.tmpIndex = this.selectedIndex;
|
||||
}).bind('focus', function() {
|
||||
this.selectedIndex = this.tmpIndex;
|
||||
});
|
||||
});
|
||||
|
|
@ -0,0 +1,61 @@
|
|||
(function($){
|
||||
var SELECTED_FILE_ELEM = null;
|
||||
var ENABLE_KEY_NAV = true;
|
||||
|
||||
$(document).keydown(function(event) {
|
||||
if (!ENABLE_KEY_NAV)
|
||||
return true;
|
||||
var selection = SELECTED_FILE_ELEM;
|
||||
switch (event.keyCode) {
|
||||
case 74: // j
|
||||
if (selection == null) {
|
||||
selection = $('#f0');
|
||||
} else {
|
||||
do {
|
||||
selection = selection.next();
|
||||
} while (selection.length > 0 && selection.css('display') == 'none');
|
||||
}
|
||||
break;
|
||||
case 75: // k
|
||||
if (selection == null) {
|
||||
selection = $('#f0');
|
||||
} else {
|
||||
do {
|
||||
selection = selection.prev();
|
||||
} while (selection.length > 0 && selection.css('display') == 'none');
|
||||
}
|
||||
break;
|
||||
case 13: // Enter
|
||||
case 79: // o
|
||||
if (selection != null) {
|
||||
var expander = selection.find('.expander');
|
||||
if (expander.length > 0) {
|
||||
expander.click();
|
||||
} else {
|
||||
window.location = selection.find('a.file').attr('href');
|
||||
}
|
||||
}
|
||||
return false;
|
||||
break;
|
||||
default:
|
||||
return true;
|
||||
}
|
||||
if (selection.length > 0) {
|
||||
if (SELECTED_FILE_ELEM != null)
|
||||
SELECTED_FILE_ELEM.removeClass('focus');
|
||||
selection.addClass('focus');
|
||||
SELECTED_FILE_ELEM = selection;
|
||||
}
|
||||
return false;
|
||||
});
|
||||
|
||||
$(function() {
|
||||
$('a,input,select,textarea,button')
|
||||
.focus(function(event) {
|
||||
ENABLE_KEY_NAV = false;
|
||||
})
|
||||
.blur(function(event) {
|
||||
ENABLE_KEY_NAV = true;
|
||||
});
|
||||
});
|
||||
})(jQuery);
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
jQuery.noConflict(); // jQuery is now removed from the $ namespace
|
||||
// to use the $ shorthand, use (function($){ ... })(jQuery);
|
||||
// and for the onload handler: jQuery(function($){ ... });
|
||||
|
|
@ -0,0 +1,278 @@
|
|||
|
||||
(function($){
|
||||
|
||||
window.initializeFilters = function() {
|
||||
|
||||
// Bail early for Konqueror and IE5.2/Mac, which don't fully support dynamic
|
||||
// creation of form controls
|
||||
try {
|
||||
var test = document.createElement("input");
|
||||
test.type = "button";
|
||||
if (test.type != "button") throw Error();
|
||||
} catch (e) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Removes an existing row from the filters table
|
||||
function removeRow(button, propertyName) {
|
||||
var tr = getAncestorByTagName(button, "tr");
|
||||
|
||||
var mode = null;
|
||||
var selects = tr.getElementsByTagName("select");
|
||||
for (var i = 0; i < selects.length; i++) {
|
||||
if (selects[i].name == propertyName + "_mode") {
|
||||
mode = selects[i];
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (mode && (getAncestorByTagName(mode, "tr") == tr)) {
|
||||
// Check whether there are more 'or' rows for this filter
|
||||
var next = tr.nextSibling;
|
||||
if (next && (next.className == propertyName)) {
|
||||
function getChildElementAt(e, idx) {
|
||||
e = e.firstChild;
|
||||
var cur = 0;
|
||||
while (cur <= idx) {
|
||||
while (e && e.nodeType != 1) e = e.nextSibling;
|
||||
if (cur++ == idx) break;
|
||||
e = e.nextSibling;
|
||||
}
|
||||
return e;
|
||||
}
|
||||
|
||||
var thisTh = getChildElementAt(tr, 0);
|
||||
var nextTh = getChildElementAt(next, 0);
|
||||
next.insertBefore(thisTh, nextTh);
|
||||
nextTh.colSpan = 1;
|
||||
|
||||
thisTd = getChildElementAt(tr, 0);
|
||||
nextTd = getChildElementAt(next, 1);
|
||||
next.replaceChild(thisTd, nextTd);
|
||||
}
|
||||
}
|
||||
|
||||
var tBody = tr.parentNode;
|
||||
tBody.deleteRow(tr.sectionRowIndex);
|
||||
if (!tBody.rows.length) {
|
||||
tBody.parentNode.removeChild(tBody);
|
||||
}
|
||||
|
||||
if (propertyName) {
|
||||
var select = document.forms["query"].elements["add_filter"];
|
||||
for (var i = 0; i < select.options.length; i++) {
|
||||
var option = select.options[i];
|
||||
if (option.value == propertyName) option.disabled = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Initializes a filter row, the 'input' parameter is the submit
|
||||
// button for removing the filter
|
||||
function initializeFilter(input) {
|
||||
var removeButton = document.createElement("input");
|
||||
removeButton.type = "button";
|
||||
removeButton.value = input.value;
|
||||
if (input.name.substr(0, 10) == "rm_filter_") {
|
||||
removeButton.onclick = function() {
|
||||
var endIndex = input.name.search(/_\d+$/);
|
||||
if (endIndex < 0) endIndex = input.name.length;
|
||||
removeRow(removeButton, input.name.substring(10, endIndex));
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
removeButton.onclick = function() {
|
||||
removeRow(removeButton);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
input.parentNode.replaceChild(removeButton, input);
|
||||
}
|
||||
|
||||
// Make the submit buttons for removing filters client-side triggers
|
||||
var filters = document.getElementById("filters");
|
||||
var inputs = filters.getElementsByTagName("input");
|
||||
for (var i = 0; i < inputs.length; i++) {
|
||||
var input = inputs[i];
|
||||
if (input.type == "submit" && input.name
|
||||
&& input.name.match(/^rm_filter_/)) {
|
||||
initializeFilter(input);
|
||||
}
|
||||
}
|
||||
|
||||
// Make the drop-down menu for adding a filter a client-side trigger
|
||||
var addButton = document.forms["query"].elements["add"];
|
||||
addButton.parentNode.removeChild(addButton);
|
||||
var select = document.getElementById("add_filter");
|
||||
select.onchange = function() {
|
||||
if (select.selectedIndex < 1) return;
|
||||
|
||||
if (select.options[select.selectedIndex].disabled) {
|
||||
// Neither IE nor Safari supported disabled options at the time this was
|
||||
// written, so alert the user
|
||||
alert("A filter already exists for that property");
|
||||
return;
|
||||
}
|
||||
|
||||
// Convenience function for creating a <label>
|
||||
function createLabel(text, htmlFor) {
|
||||
var label = document.createElement("label");
|
||||
if (text) label.appendChild(document.createTextNode(text));
|
||||
if (htmlFor) label.htmlFor = htmlFor;
|
||||
return label;
|
||||
}
|
||||
|
||||
// Convenience function for creating an <input type="checkbox">
|
||||
function createCheckbox(name, value, id) {
|
||||
var input = document.createElement("input");
|
||||
input.type = "checkbox";
|
||||
if (name) input.name = name;
|
||||
if (value) input.value = value;
|
||||
if (id) input.id = id;
|
||||
return input;
|
||||
}
|
||||
|
||||
// Convenience function for creating an <input type="radio">
|
||||
function createRadio(name, value, id) {
|
||||
var str = '<input type="radio"';
|
||||
if (name) str += ' name="' + name + '"';
|
||||
if (value) str += ' value="' + value + '"';
|
||||
if (id) str += ' id="' + id + '"';
|
||||
str += '/>';
|
||||
var span = document.createElement('span');
|
||||
// create radio button with innerHTML to avoid IE mangling it.
|
||||
span.innerHTML = str;
|
||||
return span;
|
||||
}
|
||||
|
||||
// Convenience function for creating a <select>
|
||||
function createSelect(name, options, optional) {
|
||||
var e = document.createElement("select");
|
||||
if (name) e.name = name;
|
||||
if (optional) e.options[0] = new Option();
|
||||
if (options) {
|
||||
for (var i = 0; i < options.length; i++) {
|
||||
var option;
|
||||
if (typeof(options[i]) == "object") {
|
||||
option = new Option(options[i].text, options[i].value);
|
||||
} else {
|
||||
option = new Option(options[i], options[i]);
|
||||
}
|
||||
e.options[e.options.length] = option;
|
||||
}
|
||||
}
|
||||
return e;
|
||||
}
|
||||
|
||||
var propertyName = select.options[select.selectedIndex].value;
|
||||
var property = properties[propertyName];
|
||||
var table = document.getElementById("filters").getElementsByTagName("table")[0];
|
||||
var tr = document.createElement("tr");
|
||||
tr.className = propertyName;
|
||||
|
||||
var alreadyPresent = false;
|
||||
for (var i = 0; i < table.rows.length; i++) {
|
||||
if (table.rows[i].className == propertyName) {
|
||||
var existingTBody = table.rows[i].parentNode;
|
||||
alreadyPresent = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Add the row header
|
||||
var th = document.createElement("th");
|
||||
th.scope = "row";
|
||||
if (!alreadyPresent) {
|
||||
th.appendChild(createLabel(property.label));
|
||||
} else {
|
||||
th.colSpan = 2;
|
||||
th.appendChild(createLabel("or"));
|
||||
}
|
||||
tr.appendChild(th);
|
||||
|
||||
var td = document.createElement("td");
|
||||
if (property.type == "radio" || property.type == "checkbox") {
|
||||
td.colSpan = 2;
|
||||
td.className = "filter";
|
||||
if (property.type == "radio") {
|
||||
for (var i = 0; i < property.options.length; i++) {
|
||||
var option = property.options[i];
|
||||
td.appendChild(createCheckbox(propertyName, option,
|
||||
propertyName + "_" + option));
|
||||
td.appendChild(createLabel(option ? option : "none",
|
||||
propertyName + "_" + option));
|
||||
}
|
||||
} else {
|
||||
td.appendChild(createRadio(propertyName, "1", propertyName + "_on"));
|
||||
td.appendChild(document.createTextNode(" "));
|
||||
td.appendChild(createLabel("yes", propertyName + "_on"));
|
||||
td.appendChild(createRadio(propertyName, "0", propertyName + "_off"));
|
||||
td.appendChild(document.createTextNode(" "));
|
||||
td.appendChild(createLabel("no", propertyName + "_off"));
|
||||
}
|
||||
tr.appendChild(td);
|
||||
} else {
|
||||
if (!alreadyPresent) {
|
||||
// Add the mode selector
|
||||
td.className = "mode";
|
||||
var modeSelect = createSelect(propertyName + "_mode",
|
||||
modes[property.type]);
|
||||
td.appendChild(modeSelect);
|
||||
tr.appendChild(td);
|
||||
}
|
||||
|
||||
// Add the selector or text input for the actual filter value
|
||||
td = document.createElement("td");
|
||||
td.className = "filter";
|
||||
if (property.type == "select") {
|
||||
var element = createSelect(propertyName, property.options, true);
|
||||
} else if (property.type == "text") {
|
||||
var element = document.createElement("input");
|
||||
element.type = "text";
|
||||
element.name = propertyName;
|
||||
element.size = 42;
|
||||
}
|
||||
td.appendChild(element);
|
||||
element.focus();
|
||||
tr.appendChild(td);
|
||||
}
|
||||
|
||||
// Add the add and remove buttons
|
||||
td = document.createElement("td");
|
||||
td.className = "actions";
|
||||
var removeButton = document.createElement("input");
|
||||
removeButton.type = "button";
|
||||
removeButton.value = "-";
|
||||
removeButton.onclick = function() { removeRow(removeButton, propertyName) };
|
||||
td.appendChild(removeButton);
|
||||
tr.appendChild(td);
|
||||
|
||||
if (alreadyPresent) {
|
||||
existingTBody.appendChild(tr);
|
||||
} else {
|
||||
// Find the insertion point for the new row. We try to keep the filter rows
|
||||
// in the same order as the options in the 'Add filter' drop-down, because
|
||||
// that's the order they'll appear in when submitted.
|
||||
var insertionPoint = getAncestorByTagName(select, "tbody");
|
||||
outer: for (var i = select.selectedIndex + 1; i < select.options.length; i++) {
|
||||
for (var j = 0; j < table.tBodies.length; j++) {
|
||||
if (table.tBodies[j].rows[0].className == select.options[i].value) {
|
||||
insertionPoint = table.tBodies[j];
|
||||
break outer;
|
||||
}
|
||||
}
|
||||
}
|
||||
// Finally add the new row to the table
|
||||
var tbody = document.createElement("tbody");
|
||||
tbody.appendChild(tr);
|
||||
insertionPoint.parentNode.insertBefore(tbody, insertionPoint);
|
||||
}
|
||||
|
||||
// Disable the add filter in the drop-down list
|
||||
if (property.type == "radio" || property.type == "checkbox") {
|
||||
select.options[select.selectedIndex].disabled = true;
|
||||
}
|
||||
select.selectedIndex = 0;
|
||||
}
|
||||
}
|
||||
|
||||
})(jQuery);
|
||||
|
|
@ -0,0 +1,59 @@
|
|||
|
||||
(function($){
|
||||
|
||||
/* Adapted from http://www.kryogenix.org/code/browser/searchhi/ */
|
||||
$.fn.highlightText = function(text, className) {
|
||||
function highlight(node) {
|
||||
if (node.nodeType == 3) { // Node.TEXT_NODE
|
||||
var val = node.nodeValue;
|
||||
var pos = val.toLowerCase().indexOf(text);
|
||||
if (pos >= 0 && !$.className.has(node.parentNode, className)) {
|
||||
var span = document.createElement("span");
|
||||
span.className = className;
|
||||
span.appendChild(document.createTextNode(val.substr(pos, text.length)));
|
||||
node.parentNode.insertBefore(span, node.parentNode.insertBefore(
|
||||
document.createTextNode(val.substr(pos + text.length)),
|
||||
node.nextSibling));
|
||||
node.nodeValue = val.substr(0, pos);
|
||||
}
|
||||
} else if (!$(node).is("button, select, textarea")) {
|
||||
$.each(node.childNodes, function() { highlight(this) });
|
||||
}
|
||||
}
|
||||
return this.each(function() { highlight(this) });
|
||||
}
|
||||
|
||||
$(document).ready(function() {
|
||||
var elems = $(".searchable");
|
||||
if (!elems.length) return;
|
||||
|
||||
function getSearchTerms(url) {
|
||||
if (url.indexOf("?") == -1) return [];
|
||||
var params = url.substr(url.indexOf("?") + 1).split("&");
|
||||
for (var p in params) {
|
||||
var param = params[p].split("=");
|
||||
if (param.length < 2) continue;
|
||||
if (param[0] == "q" || param[0] == "p") { // q= for Google, p= for Yahoo
|
||||
var query = decodeURIComponent(param[1].replace(/\+/g, " "));
|
||||
if (query[0] == "!") query = query.slice(1);
|
||||
var terms = [];
|
||||
$.each(query.split(/(".*?")|('.*?')|(\s+)/), function() {
|
||||
term = this.replace(/^\s+$/, "");
|
||||
if (term.length) {
|
||||
terms.push(term.replace(/^['"]/, "").replace(/['"]$/, ""));
|
||||
}
|
||||
});
|
||||
return terms;
|
||||
}
|
||||
}
|
||||
return [];
|
||||
}
|
||||
|
||||
var terms = getSearchTerms(document.URL);
|
||||
if (!terms.length) terms = getSearchTerms(document.referrer);
|
||||
$.each(terms, function(idx) {
|
||||
elems.highlightText(this.toLowerCase(), "searchword" + (idx % 5));
|
||||
});
|
||||
});
|
||||
|
||||
})(jQuery);
|
||||
|
|
@ -0,0 +1,144 @@
|
|||
|
||||
(function($){
|
||||
|
||||
|
||||
/*
|
||||
Text field auto-completion plugin for jQuery.
|
||||
Based on http://www.dyve.net/jquery/?autocomplete by Dylan Verheul.
|
||||
*/
|
||||
$.suggest = function(input, url, paramName, minChars, delay) {
|
||||
var input = $(input).addClass("suggest").attr("autocomplete", "off");
|
||||
var timeout = null;
|
||||
var prev = "";
|
||||
var selectedIndex = -1;
|
||||
var results = null;
|
||||
|
||||
input.keydown(function(e) {
|
||||
switch(e.keyCode) {
|
||||
case 27: // escape
|
||||
hide();
|
||||
break;
|
||||
case 38: // up
|
||||
case 40: // down
|
||||
e.preventDefault();
|
||||
if (results) {
|
||||
var items = $("li", results);
|
||||
if (!items) return;
|
||||
var index = selectedIndex + (e.keyCode == 38 ? -1 : 1);
|
||||
if (index >= 0 && index < items.length) {
|
||||
move(index);
|
||||
}
|
||||
} else {
|
||||
show();
|
||||
}
|
||||
break;
|
||||
case 9: // tab
|
||||
case 13: // return
|
||||
case 39: // right
|
||||
if (results) {
|
||||
var li = $("li.selected", results);
|
||||
if (li.length) {
|
||||
select(li);
|
||||
e.preventDefault();
|
||||
}
|
||||
}
|
||||
break;
|
||||
default:
|
||||
if (timeout) clearTimeout(timeout);
|
||||
timeout = setTimeout(show, delay);
|
||||
break;
|
||||
}
|
||||
});
|
||||
input.blur(function() {
|
||||
if (timeout) clearTimeout(timeout);
|
||||
timeout = setTimeout(hide, 200);
|
||||
});
|
||||
|
||||
function hide() {
|
||||
if (timeout) clearTimeout(timeout);
|
||||
input.removeClass("loading");
|
||||
if (results) {
|
||||
results.fadeOut("fast").remove();
|
||||
results = null;
|
||||
}
|
||||
$("iframe.iefix").remove();
|
||||
selectedIndex = -1;
|
||||
}
|
||||
|
||||
function move(index) {
|
||||
if (!results) return;
|
||||
items = $("li", results);
|
||||
items.removeClass("selected");
|
||||
$(items[index]).addClass("selected");
|
||||
selectedIndex = index;
|
||||
}
|
||||
|
||||
function select(li) {
|
||||
if (!li) li = $("<li>");
|
||||
else li = $(li);
|
||||
var val = $.trim(li.text());
|
||||
prev = val;
|
||||
input.val(val);
|
||||
hide();
|
||||
selectedIndex = -1;
|
||||
}
|
||||
|
||||
function show() {
|
||||
var val = input.val();
|
||||
if (val == prev) return;
|
||||
prev = val;
|
||||
if (val.length < minChars) { hide(); return; }
|
||||
input.addClass("loading");
|
||||
var params = {};
|
||||
params[paramName] = val;
|
||||
$.get(url, params, function(data) {
|
||||
if (!data) { hide(); return; }
|
||||
if (!results) {
|
||||
var offset = input.offset();
|
||||
results = $("<div>").addClass("suggestions").css({
|
||||
position: "absolute",
|
||||
minWidth: input.get(0).offsetWidth + "px",
|
||||
top: (offset.top + input.get(0).offsetHeight) + "px",
|
||||
left: offset.left + "px",
|
||||
zIndex: 2
|
||||
}).appendTo("body");
|
||||
if ($.browser.msie) {
|
||||
var iframe = $("<iframe style='display:none;position:absolute;" +
|
||||
"filter:progid:DXImageTransform.Microsoft.Alpha(opacity=0);'" +
|
||||
" class='iefix' src='javascript:false;' frameborder='0'" +
|
||||
" scrolling='no'></iframe>").insertAfter(results);
|
||||
setTimeout(function() {
|
||||
var offset = getOffset(results);
|
||||
iframe.css({
|
||||
top: offset.top + "px",
|
||||
right: (offset.left + results.get(0).offsetWidth) + "px",
|
||||
bottom: (offset.top + results.get(0).offsetHeight) + "px",
|
||||
left: offset.left + "px",
|
||||
zIndex: 1
|
||||
});
|
||||
iframe.show();
|
||||
}, 10);
|
||||
}
|
||||
}
|
||||
results.html(data).fadeTo("fast", 0.92);
|
||||
items = $("li", results);
|
||||
items
|
||||
.hover(function() { move(items.index(this)) },
|
||||
function() { $(this).removeClass("selected") })
|
||||
.click(function() { select(this); input.get(0).focus() });
|
||||
move(0);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
$.fn.suggest = function(url, paramName, minChars, delay) {
|
||||
url = url || window.location.pathname;
|
||||
paramName = paramName || 'q';
|
||||
minChars = minChars || 1;
|
||||
delay = delay || 400;
|
||||
return this.each(function() {
|
||||
new $.suggest(this, url, paramName, minChars, delay);
|
||||
});
|
||||
}
|
||||
|
||||
})(jQuery);
|
||||
|
|
@ -0,0 +1,75 @@
|
|||
(function($){
|
||||
|
||||
$.fn.addAnchor = function(title) {
|
||||
title = title || "Link here";
|
||||
return this.filter("*[@id]").each(function() {
|
||||
$("<a class='anchor'> \u00B6</a>").attr("href", "#" + this.id)
|
||||
.attr("title", title).appendTo(this);
|
||||
});
|
||||
}
|
||||
|
||||
$.fn.checked = function(checked) {
|
||||
if (checked == undefined) { // getter
|
||||
if (!this.length) return false;
|
||||
return this.get(0).checked;
|
||||
} else { // setter
|
||||
return this.each(function() {
|
||||
this.checked = checked;
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
$.fn.enable = function(enabled) {
|
||||
if (enabled == undefined) enabled = true;
|
||||
return this.each(function() {
|
||||
this.disabled = !enabled;
|
||||
var label = $(this).parents("label");
|
||||
if (!label.length && this.id) {
|
||||
label = $("label[@for='" + this.id + "']");
|
||||
}
|
||||
if (!enabled) {
|
||||
label.addClass("disabled");
|
||||
} else {
|
||||
label.removeClass("disabled");
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
$.loadStyleSheet = function(href, type) {
|
||||
type = type || "text/css";
|
||||
$(document).ready(function() {
|
||||
if (document.createStyleSheet) { // MSIE
|
||||
document.createStyleSheet(href);
|
||||
} else {
|
||||
$("<link rel='stylesheet' type='" + type + "' href='" + href + "' />")
|
||||
.appendTo("head");
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// Used for dynamically updating the height of a textarea
|
||||
window.resizeTextArea = function (id, rows) {
|
||||
var textarea = $("#" + id).get(0);
|
||||
if (!textarea || textarea.rows == undefined) return;
|
||||
textarea.rows = rows;
|
||||
}
|
||||
|
||||
// The following are defined for backwards compatibility with releases prior
|
||||
// to Trac 0.11
|
||||
|
||||
window.addEvent = function(elem, type, func) {
|
||||
$(elem).bind(type, func);
|
||||
}
|
||||
window.addHeadingLinks = function(container, title) {
|
||||
$.each(["h1", "h2", "h3", "h4", "h5", "h6"], function() {
|
||||
$(this, container).addAnchor(title);
|
||||
});
|
||||
}
|
||||
window.enableControl = function(id, enabled) {
|
||||
$("#" + id).enable(enabled);
|
||||
}
|
||||
window.getAncestorByTagName = function(elem, tagName) {
|
||||
return $(elem).parents(tagName).get(0);
|
||||
}
|
||||
|
||||
})(jQuery);
|
||||
|
|
@ -0,0 +1,93 @@
|
|||
|
||||
|
||||
(function($){
|
||||
|
||||
|
||||
window.addWikiFormattingToolbar = function(textarea) {
|
||||
if ((document.selection == undefined)
|
||||
&& (textarea.setSelectionRange == undefined)) {
|
||||
return;
|
||||
}
|
||||
|
||||
var toolbar = document.createElement("div");
|
||||
toolbar.className = "wikitoolbar";
|
||||
|
||||
function addButton(id, title, fn) {
|
||||
var a = document.createElement("a");
|
||||
a.href = "#";
|
||||
a.id = id;
|
||||
a.title = title;
|
||||
a.onclick = function() { try { fn() } catch (e) { } return false };
|
||||
a.tabIndex = 400;
|
||||
toolbar.appendChild(a);
|
||||
}
|
||||
|
||||
function encloseSelection(prefix, suffix) {
|
||||
textarea.focus();
|
||||
var start, end, sel, scrollPos, subst;
|
||||
if (document.selection != undefined) {
|
||||
sel = document.selection.createRange().text;
|
||||
} else if (textarea.setSelectionRange != undefined) {
|
||||
start = textarea.selectionStart;
|
||||
end = textarea.selectionEnd;
|
||||
scrollPos = textarea.scrollTop;
|
||||
sel = textarea.value.substring(start, end);
|
||||
}
|
||||
if (sel.match(/ $/)) { // exclude ending space char, if any
|
||||
sel = sel.substring(0, sel.length - 1);
|
||||
suffix = suffix + " ";
|
||||
}
|
||||
subst = prefix + sel + suffix;
|
||||
if (document.selection != undefined) {
|
||||
var range = document.selection.createRange().text = subst;
|
||||
textarea.caretPos -= suffix.length;
|
||||
} else if (textarea.setSelectionRange != undefined) {
|
||||
textarea.value = textarea.value.substring(0, start) + subst +
|
||||
textarea.value.substring(end);
|
||||
if (sel) {
|
||||
textarea.setSelectionRange(start + subst.length, start + subst.length);
|
||||
} else {
|
||||
textarea.setSelectionRange(start + prefix.length, start + prefix.length);
|
||||
}
|
||||
textarea.scrollTop = scrollPos;
|
||||
}
|
||||
}
|
||||
|
||||
addButton("strong", "Bold text: '''Example'''", function() {
|
||||
encloseSelection("'''", "'''");
|
||||
});
|
||||
addButton("em", "Italic text: ''Example''", function() {
|
||||
encloseSelection("''", "''");
|
||||
});
|
||||
addButton("heading", "Heading: == Example ==", function() {
|
||||
encloseSelection("\n== ", " ==\n", "Heading");
|
||||
});
|
||||
addButton("link", "Link: [http://www.example.com/ Example]", function() {
|
||||
encloseSelection("[", "]");
|
||||
});
|
||||
addButton("code", "Code block: {{{ example }}}", function() {
|
||||
encloseSelection("\n{{{\n", "\n}}}\n");
|
||||
});
|
||||
addButton("hr", "Horizontal rule: ----", function() {
|
||||
encloseSelection("\n----\n", "");
|
||||
});
|
||||
addButton("np", "New paragraph", function() {
|
||||
encloseSelection("\n\n", "");
|
||||
});
|
||||
addButton("br", "Line break: [[BR]]", function() {
|
||||
encloseSelection("[[BR]]\n", "");
|
||||
});
|
||||
addButton("img", "Image: [[Image()]]", function() {
|
||||
encloseSelection("[[Image(", ")]]");
|
||||
});
|
||||
|
||||
$(textarea).before(toolbar);
|
||||
}
|
||||
|
||||
})(jQuery);
|
||||
|
||||
// Add the toolbar to all <textarea> elements on the page with the class
|
||||
// 'wikitext'.
|
||||
jQuery(document).ready(function($) {
|
||||
$("textarea.wikitext").each(function() { addWikiFormattingToolbar(this) });
|
||||
});
|
||||
|
After Width: | Height: | Size: 2.2 KiB |
|
After Width: | Height: | Size: 358 B |
|
Before Width: | Height: | Size: 12 KiB After Width: | Height: | Size: 12 KiB |
|
After Width: | Height: | Size: 371 B |
|
After Width: | Height: | Size: 245 B |
|
After Width: | Height: | Size: 227 B |
|
After Width: | Height: | Size: 228 B |
|
After Width: | Height: | Size: 6.0 KiB |
|
After Width: | Height: | Size: 350 B |
|
After Width: | Height: | Size: 309 B |
|
After Width: | Height: | Size: 3.6 KiB |
|
After Width: | Height: | Size: 2.1 KiB |
|
After Width: | Height: | Size: 689 B |
|
After Width: | Height: | Size: 159 B |
|
After Width: | Height: | Size: 233 B |