Changeset 6572
- Timestamp:
- Feb 20, 2008, 2:57:20 PM (16 years ago)
- Location:
- trunk
- Files:
-
- 24 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/THANKS
r6283 r6572 26 26 * Michael Hope michael.hope@hamjet.co.nz 27 27 * Richard Hult richard@imendio.com 28 * Paul Irish paul.irishEWWSPAM@gmail.com 28 29 * Noah Kantrowitz (coderanger) coderanger@yahoo.com 29 30 * Waldemar Kornewald wkornew@gmx.net -
trunk/trac/admin/templates/admin_logging.html
r6324 r6572 9 9 <title>Logging</title> 10 10 <script type="text/javascript">/*<![CDATA[*/ 11 $(document).ready(function() {11 jQuery(document).ready(function($) { 12 12 $("#log_type").change(function() { 13 13 $("#log_level").enable(this.selectedIndex > 0); -
trunk/trac/admin/templates/admin_plugins.html
r6324 r6572 10 10 <script type="text/javascript" src="${chrome.htdocs_location}js/folding.js"></script> 11 11 <script type="text/javascript"> 12 $(document).ready(function(){ $("div.plugin h3").enableFolding(true) });12 jQuery(document).ready(function($){ $("div.plugin h3").enableFolding(true) }); 13 13 </script> 14 14 </head> -
trunk/trac/htdocs/js/blame.js
r4574 r6572 1 function enableBlame(url, original_path) {2 var message = null;3 var message_rev = null;4 1 5 function getOffset(elem) { 6 elem = $(elem).get(0); 7 var offset = {left: 0, top: 0}; 8 do { 9 offset.left += elem.offsetLeft || 0; 10 offset.top += elem.offsetTop || 0; 11 elem = elem.offsetParent; 12 } while (elem); 13 return offset; 14 } 2 (function($){ 15 3 16 /* for each blame cell containing a changeset link... */ 17 var rev_paths = {}; 18 $("table.code th.blame a").each(function() { 19 href = $(this).attr("href"); 20 rev_href = href.substr(href.indexOf("changeset/") + 10); 21 elts = rev_href.split("/"); 22 var path = elts.slice(1).join("/"); 23 if (path != original_path) 24 rev_paths["r"+elts[0]] = path; 25 }); 4 window.enableBlame = function(url, original_path) { 5 var message = null; 6 var message_rev = null; 7 8 function getOffset(elem) { 9 elem = $(elem).get(0); 10 var offset = {left: 0, top: 0}; 11 do { 12 offset.left += elem.offsetLeft || 0; 13 offset.top += elem.offsetTop || 0; 14 elem = elem.offsetParent; 15 } while (elem); 16 return offset; 17 } 18 19 /* for each blame cell containing a changeset link... */ 20 var rev_paths = {}; 21 $("table.code th.blame a").each(function() { 22 href = $(this).attr("href"); 23 rev_href = href.substr(href.indexOf("changeset/") + 10); 24 elts = rev_href.split("/"); 25 var path = elts.slice(1).join("/"); 26 if (path != original_path) 27 rev_paths["r"+elts[0]] = path; 28 }); 29 30 /* for each blame cell... */ 31 $("table.code th.blame").each(function() { 32 var rev = $(this).attr("class").split(" ")[1]; // "blame r123" 33 var path = rev_paths[rev] || original_path; // only found if != orig 34 35 if (!rev) 36 return; 37 38 $(this).click(function() { 39 var row = this.parentNode; 40 var message_is_visible = message && message.css("display") == "block"; 41 var highlight_rev = null; 42 43 function show() { 44 /* Display commit message for the selected revision */ 45 46 var message_w = message.get(0).offsetWidth; 47 48 // limit message panel width to 3/5 of the row width 49 var row_w = row.offsetWidth; 50 var max_w = (3.0 * row_w / 5.0); 51 if (!message_w || message_w > max_w) { 52 message_w = max_w; 53 var borderw = (2+8)*2; // borderwidth + padding on both sides 54 message.css({width: message_w - borderw + "px"}); 55 } 56 57 var row_offset = getOffset(row); 58 var left = row_offset.left + row.offsetWidth - message_w; 59 message.css({display: "block", top: row_offset.top+"px", left: left-2+"px"}); 60 } 61 62 function hide() { 63 /* Hide commit message */ 64 message.css({display: "none"}); 65 66 /* Remove highlighting for lines of the current revision */ 67 $("table.code th."+message_rev).each(function() { 68 $(this.parentNode).removeClass("hilite") 69 }); 70 } 71 72 if (message_rev != rev) { // fetch a new revision 73 if (message_is_visible) { 74 hide(); 75 } 76 message_rev = rev; 77 highlight_rev = message_rev; 78 79 $.get(url + rev.substr(1), {annotate: path}, function(data) { 80 // remove former message panel if any 81 if (message) 82 message.remove(); 83 // create new message panel 84 message = $("<div>").addClass("message").css({ 85 position: "absolute", zIndex: 2 86 }).appendTo("body"); /* add a close button somehow... */ 87 // fill in changeset data 88 message.html(data || "<strong>(no changeset information)</strong>"); 89 90 show(); 91 }); 92 } else if (message_is_visible) { 93 hide(); 94 } else { 95 show(); 96 highlight_rev = message_rev; 97 } 98 99 /* Highlight all lines of the current revision */ 100 $("table.code th."+highlight_rev).each(function() { 101 $(this.parentNode).addClass("hilite") 102 }); 103 104 }); 105 }); 106 } 26 107 27 /* for each blame cell... */ 28 $("table.code th.blame").each(function() { 29 var rev = $(this).attr("class").split(" ")[1]; // "blame r123" 30 var path = rev_paths[rev] || original_path; // only found if != orig 31 32 if (!rev) 33 return; 34 35 $(this).click(function() { 36 var row = this.parentNode; 37 var message_is_visible = message && message.css("display") == "block"; 38 var highlight_rev = null; 39 40 function show() { 41 /* Display commit message for the selected revision */ 42 43 var message_w = message.get(0).offsetWidth; 44 45 // limit message panel width to 3/5 of the row width 46 var row_w = row.offsetWidth; 47 var max_w = (3.0 * row_w / 5.0); 48 if (!message_w || message_w > max_w) { 49 message_w = max_w; 50 var borderw = (2+8)*2; // borderwidth + padding on both sides 51 message.css({width: message_w - borderw + "px"}); 52 } 53 54 var row_offset = getOffset(row); 55 var left = row_offset.left + row.offsetWidth - message_w; 56 message.css({display: "block", top: row_offset.top+"px", left: left-2+"px"}); 57 } 58 59 function hide() { 60 /* Hide commit message */ 61 message.css({display: "none"}); 62 63 /* Remove highlighting for lines of the current revision */ 64 $("table.code th."+message_rev).each(function() { 65 $(this.parentNode).removeClass("hilite") 66 }); 67 } 68 69 if (message_rev != rev) { // fetch a new revision 70 if (message_is_visible) { 71 hide(); 72 } 73 message_rev = rev; 74 highlight_rev = message_rev; 75 76 $.get(url + rev.substr(1), {annotate: path}, function(data) { 77 // remove former message panel if any 78 if (message) 79 message.remove(); 80 // create new message panel 81 message = $("<div>").addClass("message").css({ 82 position: "absolute", zIndex: 2 83 }).appendTo("body"); /* add a close button somehow... */ 84 // fill in changeset data 85 message.html(data || "<strong>(no changeset information)</strong>"); 86 87 show(); 88 }); 89 } else if (message_is_visible) { 90 hide(); 91 } else { 92 show(); 93 highlight_rev = message_rev; 94 } 95 96 /* Highlight all lines of the current revision */ 97 $("table.code th."+highlight_rev).each(function() { 98 $(this.parentNode).addClass("hilite") 99 }); 100 101 }); 102 }); 103 } 108 })(jQuery); -
trunk/trac/htdocs/js/diff.js
r6490 r6572 70 70 } 71 71 72 $(document).ready(function() {72 jQuery(document).ready(function($) { 73 73 $("div.diff h2").each(function() { 74 74 var switcher = $("<span class='switch'></span>").prependTo(this); -
trunk/trac/htdocs/js/expand_dir.js
r6375 r6572 4 4 var SUBFOLDER_INDENT = 20; 5 5 6 // enableExpandDir adds the capability to folder rows to be expanded and folded 7 // It also teach the rows about their ancestors. It expects: 8 // - `parent_tr`, the logical parent row (`null` if there's no ancestor) 9 // - a `rows` jQuery object matching the newly created entry rows 10 // - `qargs`, additional parameters to send to the server when expanding 6 (function($){ 7 8 // enableExpandDir adds the capability to folder rows to be expanded and folded 9 // It also teach the rows about their ancestors. It expects: 10 // - `parent_tr`, the logical parent row (`null` if there's no ancestor) 11 // - a `rows` jQuery object matching the newly created entry rows 12 // - `qargs`, additional parameters to send to the server when expanding 13 14 window.enableExpandDir = function(parent_tr, rows, qargs) { 15 // the ancestors folder ids are present in the parent_tr class attribute 16 var ancestor_folderids = []; 17 if (parent_tr) 18 ancestor_folderids = $.grep(parent_tr.attr("class").split(" "), 19 function(c) { return c.match(/^f\d+$/)}); 20 rows.each(function () { 21 var a = $(this).find("a.dir"); 22 23 if (a.length) { // then the entry is a folder 24 // create new folder id 25 var folderid = "f" + FOLDERID_COUNTER++; 26 this.id = folderid; 27 $(this).addClass(folderid); 28 29 // add the expander icon 30 a.wrap('<div></div>'); 31 var expander = a.before('<span class="expander"> </span>').prev(); 32 expander.attr("title", "Expand sub-directory in place") 33 .click(function() { toggleDir($(this), qargs); }); 34 } 35 36 // tie that row to ancestor folders 37 if (parent_tr) 38 $(this).addClass(ancestor_folderids.join(" ")); 39 }); 40 } 41 42 // handler for click event on the expander icons 43 window.toggleDir = function(expander, qargs) { 44 var tr = expander.parents("tr"); 45 var folderid = tr.get(0).id; 46 47 if ( tr.filter(".expanded").length ) { // then *fold* 48 tr.removeClass("expanded").addClass("collapsed"); 49 tr.siblings("tr."+folderid).hide(); 50 expander.attr("title", "Re-expand directory"); 51 return; 52 } 53 54 if ( tr.filter(".collapsed").length ) { // then *expand* 55 tr.removeClass("collapsed").addClass("expanded"); 56 tr.siblings("tr."+folderid).show(); 57 // Note that the above will show all the already fetched subtree, 58 // so we have to fold again the folders which were already collapsed. 59 tr.siblings("tr.collapsed").each(function() { 60 tr.siblings("tr."+this.id).not(this).hide(); 61 }); 62 } else { // then *fetch* 63 var td = expander.parents("td"); 64 var td_class = td.attr("class"); 65 var a = expander.next("a"); 66 var depth = 67 parseFloat(td.css("padding-left").replace(/^(\d*\.\d*).*$/, "$1")) + 68 SUBFOLDER_INDENT; 69 70 tr.addClass("expanded"); 71 // insert "Loading ..." row 72 tr.after('<tr><td><span class="loading"></span></td></tr>'); 73 var loading_row = tr.next(); 74 loading_row.children("td").addClass(td_class) 75 .attr("colspan", tr.children("td").length) 76 .css("padding-left", depth); 77 loading_row.find("span.loading").text("Loading " + a.text() + "..."); 78 79 // XHR for getting the rows corresponding to the folder entries 80 $.ajax({ 81 type: "GET", 82 url: a.attr("href"), 83 data: qargs, 84 dataType: "html", 85 success: function(data) { 86 var rows = $(data.replace(/^<!DOCTYPE[^>]+>/, "")).filter("tr"); 87 if (rows.length) { 88 // insert entry rows 89 rows.children("td."+td_class).css("padding-left", depth); 90 // make all entry rows collapsible but only subdir rows expandable 91 enableExpandDir(tr, rows, qargs); 92 tr.after(rows); 93 // remove "Loading ..." row 94 loading_row.remove(); 95 } else { 96 loading_row.find("span.loading").text("").append("<i>(empty)</i>") 97 .removeClass("loading"); 98 // make the (empty) row collapsible 99 enableExpandDir(tr, loading_row, qargs); 100 } 101 }, 102 error: function(req, err, exc) { 103 loading_row.find("span.loading").text("").append("<i>(error)</i>") 104 .removeClass("loading"); 105 enableExpandDir(tr, loading_row, qargs); 106 } 107 }); 108 } 109 expander.attr("title", "Fold directory"); 110 } 11 111 12 function enableExpandDir(parent_tr, rows, qargs) { 13 // the ancestors folder ids are present in the parent_tr class attribute 14 var ancestor_folderids = []; 15 if (parent_tr) 16 ancestor_folderids = $.grep(parent_tr.attr("class").split(" "), 17 function(c) { return c.match(/^f\d+$/)}); 18 rows.each(function () { 19 var a = $(this).find("a.dir"); 20 21 if (a.length) { // then the entry is a folder 22 // create new folder id 23 var folderid = "f" + FOLDERID_COUNTER++; 24 this.id = folderid; 25 $(this).addClass(folderid); 26 27 // add the expander icon 28 a.wrap('<div></div>'); 29 var expander = a.before('<span class="expander"> </span>').prev(); 30 expander.attr("title", "Expand sub-directory in place") 31 .click(function() { toggleDir($(this), qargs); }); 32 } 33 34 // tie that row to ancestor folders 35 if (parent_tr) 36 $(this).addClass(ancestor_folderids.join(" ")); 37 }); 38 } 39 40 // handler for click event on the expander icons 41 function toggleDir(expander, qargs) { 42 var tr = expander.parents("tr"); 43 var folderid = tr.get(0).id; 44 45 if ( tr.filter(".expanded").length ) { // then *fold* 46 tr.removeClass("expanded").addClass("collapsed"); 47 tr.siblings("tr."+folderid).hide(); 48 expander.attr("title", "Re-expand directory"); 49 return; 50 } 51 52 if ( tr.filter(".collapsed").length ) { // then *expand* 53 tr.removeClass("collapsed").addClass("expanded"); 54 tr.siblings("tr."+folderid).show(); 55 // Note that the above will show all the already fetched subtree, 56 // so we have to fold again the folders which were already collapsed. 57 tr.siblings("tr.collapsed").each(function() { 58 tr.siblings("tr."+this.id).not(this).hide(); 59 }); 60 } else { // then *fetch* 61 var td = expander.parents("td"); 62 var td_class = td.attr("class"); 63 var a = expander.next("a"); 64 var depth = 65 parseFloat(td.css("padding-left").replace(/^(\d*\.\d*).*$/, "$1")) + 66 SUBFOLDER_INDENT; 67 68 tr.addClass("expanded"); 69 // insert "Loading ..." row 70 tr.after('<tr><td><span class="loading"></span></td></tr>'); 71 var loading_row = tr.next(); 72 loading_row.children("td").addClass(td_class) 73 .attr("colspan", tr.children("td").length) 74 .css("padding-left", depth); 75 loading_row.find("span.loading").text("Loading " + a.text() + "..."); 76 77 // XHR for getting the rows corresponding to the folder entries 78 $.ajax({ 79 type: "GET", 80 url: a.attr("href"), 81 data: qargs, 82 dataType: "html", 83 success: function(data) { 84 var rows = $(data.replace(/^<!DOCTYPE[^>]+>/, "")).filter("tr"); 85 if (rows.length) { 86 // insert entry rows 87 rows.children("td."+td_class).css("padding-left", depth); 88 // make all entry rows collapsible but only subdir rows expandable 89 enableExpandDir(tr, rows, qargs); 90 tr.after(rows); 91 // remove "Loading ..." row 92 loading_row.remove(); 93 } else { 94 loading_row.find("span.loading").text("").append("<i>(empty)</i>") 95 .removeClass("loading"); 96 // make the (empty) row collapsible 97 enableExpandDir(tr, loading_row, qargs); 98 } 99 }, 100 error: function(req, err, exc) { 101 loading_row.find("span.loading").text("").append("<i>(error)</i>") 102 .removeClass("loading"); 103 enableExpandDir(tr, loading_row, qargs); 104 } 105 }); 106 } 107 expander.attr("title", "Fold directory"); 108 } 112 })(jQuery); -
trunk/trac/htdocs/js/folding.js
r5413 r6572 1 $.fn.enableFolding = function(autofold) { 2 var fragId = document.location.hash; 3 if (fragId && /^#no\d+$/.test(fragId)) { 4 fragId = parseInt(fragId.substr(3)); 5 } 1 (function($){ 6 2 7 var count = 1; 8 return this.each(function() { 9 var t = $(this).text(); 10 $(this).text(""); 11 var trigger = $(this).append("<a href='#no" + count + "'></a>").children(); 12 trigger.text(t); 3 $.fn.enableFolding = function(autofold) { 4 var fragId = document.location.hash; 5 if (fragId && /^#no\d+$/.test(fragId)) { 6 fragId = parseInt(fragId.substr(3)); 7 } 8 9 var count = 1; 10 return this.each(function() { 11 var t = $(this).text(); 12 $(this).text(""); 13 var trigger = $(this).append("<a href='#no" + count + "'></a>").children(); 14 trigger.text(t); 15 16 trigger.click(function() { 17 if (fragId == count) { fragId = 0; return; } 18 $(this.parentNode.parentNode).toggleClass("collapsed"); 19 }); 20 if ( autofold ) 21 trigger.click(); 22 count++; 23 }).css("cursor", "pointer"); 24 } 13 25 14 trigger.click(function() { 15 if (fragId == count) { fragId = 0; return; } 16 $(this.parentNode.parentNode).toggleClass("collapsed"); 17 }); 18 if ( autofold ) 19 trigger.click(); 20 count++; 21 }).css("cursor", "pointer"); 22 } 26 })(jQuery); -
trunk/trac/htdocs/js/ie_pre7_hacks.js
r6324 r6572 1 $(function() { 1 jQuery(function($) { // onload 2 2 $('select').bind('focusin', function() { 3 3 this.tmpIndex = this.selectedIndex; -
trunk/trac/htdocs/js/query.js
r4462 r6572 1 function initializeFilters() {2 1 3 // Bail early for Konqueror and IE5.2/Mac, which don't fully support dynamic 4 // creation of form controls 5 try { 6 var test = document.createElement("input"); 7 test.type = "button"; 8 if (test.type != "button") throw Error(); 9 } catch (e) { 10 return; 11 } 2 (function($){ 3 4 window.initializeFilters = function() { 5 6 // Bail early for Konqueror and IE5.2/Mac, which don't fully support dynamic 7 // creation of form controls 8 try { 9 var test = document.createElement("input"); 10 test.type = "button"; 11 if (test.type != "button") throw Error(); 12 } catch (e) { 13 return; 14 } 15 16 // Removes an existing row from the filters table 17 function removeRow(button, propertyName) { 18 var tr = getAncestorByTagName(button, "tr"); 19 20 var mode = null; 21 var selects = tr.getElementsByTagName("select"); 22 for (var i = 0; i < selects.length; i++) { 23 if (selects[i].name == propertyName + "_mode") { 24 mode = selects[i]; 25 break; 26 } 27 } 28 if (mode && (getAncestorByTagName(mode, "tr") == tr)) { 29 // Check whether there are more 'or' rows for this filter 30 var next = tr.nextSibling; 31 if (next && (next.className == propertyName)) { 32 function getChildElementAt(e, idx) { 33 e = e.firstChild; 34 var cur = 0; 35 while (cur <= idx) { 36 while (e && e.nodeType != 1) e = e.nextSibling; 37 if (cur++ == idx) break; 38 e = e.nextSibling; 39 } 40 return e; 41 } 42 43 var thisTh = getChildElementAt(tr, 0); 44 var nextTh = getChildElementAt(next, 0); 45 next.insertBefore(thisTh, nextTh); 46 nextTh.colSpan = 1; 47 48 thisTd = getChildElementAt(tr, 0); 49 nextTd = getChildElementAt(next, 1); 50 next.replaceChild(thisTd, nextTd); 51 } 52 } 53 54 var tBody = tr.parentNode; 55 tBody.deleteRow(tr.sectionRowIndex); 56 if (!tBody.rows.length) { 57 tBody.parentNode.removeChild(tBody); 58 } 59 60 if (propertyName) { 61 var select = document.forms["query"].elements["add_filter"]; 62 for (var i = 0; i < select.options.length; i++) { 63 var option = select.options[i]; 64 if (option.value == propertyName) option.disabled = false; 65 } 66 } 67 } 68 69 // Initializes a filter row, the 'input' parameter is the submit 70 // button for removing the filter 71 function initializeFilter(input) { 72 var removeButton = document.createElement("input"); 73 removeButton.type = "button"; 74 removeButton.value = input.value; 75 if (input.name.substr(0, 10) == "rm_filter_") { 76 removeButton.onclick = function() { 77 var endIndex = input.name.search(/_\d+$/); 78 if (endIndex < 0) endIndex = input.name.length; 79 removeRow(removeButton, input.name.substring(10, endIndex)); 80 return false; 81 } 82 } else { 83 removeButton.onclick = function() { 84 removeRow(removeButton); 85 return false; 86 } 87 } 88 input.parentNode.replaceChild(removeButton, input); 89 } 90 91 // Make the submit buttons for removing filters client-side triggers 92 var filters = document.getElementById("filters"); 93 var inputs = filters.getElementsByTagName("input"); 94 for (var i = 0; i < inputs.length; i++) { 95 var input = inputs[i]; 96 if (input.type == "submit" && input.name 97 && input.name.match(/^rm_filter_/)) { 98 initializeFilter(input); 99 } 100 } 101 102 // Make the drop-down menu for adding a filter a client-side trigger 103 var addButton = document.forms["query"].elements["add"]; 104 addButton.parentNode.removeChild(addButton); 105 var select = document.getElementById("add_filter"); 106 select.onchange = function() { 107 if (select.selectedIndex < 1) return; 108 109 if (select.options[select.selectedIndex].disabled) { 110 // Neither IE nor Safari supported disabled options at the time this was 111 // written, so alert the user 112 alert("A filter already exists for that property"); 113 return; 114 } 115 116 // Convenience function for creating a <label> 117 function createLabel(text, htmlFor) { 118 var label = document.createElement("label"); 119 if (text) label.appendChild(document.createTextNode(text)); 120 if (htmlFor) label.htmlFor = htmlFor; 121 return label; 122 } 123 124 // Convenience function for creating an <input type="checkbox"> 125 function createCheckbox(name, value, id) { 126 var input = document.createElement("input"); 127 input.type = "checkbox"; 128 if (name) input.name = name; 129 if (value) input.value = value; 130 if (id) input.id = id; 131 return input; 132 } 133 134 // Convenience function for creating an <input type="radio"> 135 function createRadio(name, value, id) { 136 var input = document.createElement("input"); 137 input.type = "radio"; 138 if (name) input.name = name; 139 if (value) input.value = value; 140 if (id) input.id = id; 141 return input; 142 } 143 144 // Convenience function for creating a <select> 145 function createSelect(name, options, optional) { 146 var e = document.createElement("select"); 147 if (name) e.name = name; 148 if (optional) e.options[0] = new Option(); 149 if (options) { 150 for (var i = 0; i < options.length; i++) { 151 var option; 152 if (typeof(options[i]) == "object") { 153 option = new Option(options[i].text, options[i].value); 154 } else { 155 option = new Option(options[i], options[i]); 156 } 157 e.options[e.options.length] = option; 158 } 159 } 160 return e; 161 } 162 163 var propertyName = select.options[select.selectedIndex].value; 164 var property = properties[propertyName]; 165 var table = document.getElementById("filters").getElementsByTagName("table")[0]; 166 var tr = document.createElement("tr"); 167 tr.className = propertyName; 168 169 var alreadyPresent = false; 170 for (var i = 0; i < table.rows.length; i++) { 171 if (table.rows[i].className == propertyName) { 172 var existingTBody = table.rows[i].parentNode; 173 alreadyPresent = true; 174 break; 175 } 176 } 177 178 // Add the row header 179 var th = document.createElement("th"); 180 th.scope = "row"; 181 if (!alreadyPresent) { 182 th.appendChild(createLabel(property.label)); 183 } else { 184 th.colSpan = 2; 185 th.appendChild(createLabel("or")); 186 } 187 tr.appendChild(th); 188 189 var td = document.createElement("td"); 190 if (property.type == "radio" || property.type == "checkbox") { 191 td.colSpan = 2; 192 td.className = "filter"; 193 if (property.type == "radio") { 194 for (var i = 0; i < property.options.length; i++) { 195 var option = property.options[i]; 196 td.appendChild(createCheckbox(propertyName, option, 197 propertyName + "_" + option)); 198 td.appendChild(createLabel(option ? option : "none", 199 propertyName + "_" + option)); 200 } 201 } else { 202 td.appendChild(createRadio(propertyName, "1", propertyName + "_on")); 203 td.appendChild(document.createTextNode(" ")); 204 td.appendChild(createLabel("yes", propertyName + "_on")); 205 td.appendChild(createRadio(propertyName, "0", propertyName + "_off")); 206 td.appendChild(document.createTextNode(" ")); 207 td.appendChild(createLabel("no", propertyName + "_off")); 208 } 209 tr.appendChild(td); 210 } else { 211 if (!alreadyPresent) { 212 // Add the mode selector 213 td.className = "mode"; 214 var modeSelect = createSelect(propertyName + "_mode", 215 modes[property.type]); 216 td.appendChild(modeSelect); 217 tr.appendChild(td); 218 } 219 220 // Add the selector or text input for the actual filter value 221 td = document.createElement("td"); 222 td.className = "filter"; 223 if (property.type == "select") { 224 var element = createSelect(propertyName, property.options, true); 225 } else if (property.type == "text") { 226 var element = document.createElement("input"); 227 element.type = "text"; 228 element.name = propertyName; 229 element.size = 42; 230 } 231 td.appendChild(element); 232 element.focus(); 233 tr.appendChild(td); 234 } 235 236 // Add the add and remove buttons 237 td = document.createElement("td"); 238 td.className = "actions"; 239 var removeButton = document.createElement("input"); 240 removeButton.type = "button"; 241 removeButton.value = "-"; 242 removeButton.onclick = function() { removeRow(removeButton, propertyName) }; 243 td.appendChild(removeButton); 244 tr.appendChild(td); 245 246 if (alreadyPresent) { 247 existingTBody.appendChild(tr); 248 } else { 249 // Find the insertion point for the new row. We try to keep the filter rows 250 // in the same order as the options in the 'Add filter' drop-down, because 251 // that's the order they'll appear in when submitted. 252 var insertionPoint = getAncestorByTagName(select, "tbody"); 253 outer: for (var i = select.selectedIndex + 1; i < select.options.length; i++) { 254 for (var j = 0; j < table.tBodies.length; j++) { 255 if (table.tBodies[j].rows[0].className == select.options[i].value) { 256 insertionPoint = table.tBodies[j]; 257 break outer; 258 } 259 } 260 } 261 // Finally add the new row to the table 262 var tbody = document.createElement("tbody"); 263 tbody.appendChild(tr); 264 insertionPoint.parentNode.insertBefore(tbody, insertionPoint); 265 } 266 267 // Disable the add filter in the drop-down list 268 if (property.type == "radio" || property.type == "checkbox") { 269 select.options[select.selectedIndex].disabled = true; 270 } 271 select.selectedIndex = 0; 272 } 273 } 12 274 13 // Removes an existing row from the filters table 14 function removeRow(button, propertyName) { 15 var tr = getAncestorByTagName(button, "tr"); 16 17 var mode = null; 18 var selects = tr.getElementsByTagName("select"); 19 for (var i = 0; i < selects.length; i++) { 20 if (selects[i].name == propertyName + "_mode") { 21 mode = selects[i]; 22 break; 23 } 24 } 25 if (mode && (getAncestorByTagName(mode, "tr") == tr)) { 26 // Check whether there are more 'or' rows for this filter 27 var next = tr.nextSibling; 28 if (next && (next.className == propertyName)) { 29 function getChildElementAt(e, idx) { 30 e = e.firstChild; 31 var cur = 0; 32 while (cur <= idx) { 33 while (e && e.nodeType != 1) e = e.nextSibling; 34 if (cur++ == idx) break; 35 e = e.nextSibling; 36 } 37 return e; 38 } 39 40 var thisTh = getChildElementAt(tr, 0); 41 var nextTh = getChildElementAt(next, 0); 42 next.insertBefore(thisTh, nextTh); 43 nextTh.colSpan = 1; 44 45 thisTd = getChildElementAt(tr, 0); 46 nextTd = getChildElementAt(next, 1); 47 next.replaceChild(thisTd, nextTd); 48 } 49 } 50 51 var tBody = tr.parentNode; 52 tBody.deleteRow(tr.sectionRowIndex); 53 if (!tBody.rows.length) { 54 tBody.parentNode.removeChild(tBody); 55 } 56 57 if (propertyName) { 58 var select = document.forms["query"].elements["add_filter"]; 59 for (var i = 0; i < select.options.length; i++) { 60 var option = select.options[i]; 61 if (option.value == propertyName) option.disabled = false; 62 } 63 } 64 } 65 66 // Initializes a filter row, the 'input' parameter is the submit 67 // button for removing the filter 68 function initializeFilter(input) { 69 var removeButton = document.createElement("input"); 70 removeButton.type = "button"; 71 removeButton.value = input.value; 72 if (input.name.substr(0, 10) == "rm_filter_") { 73 removeButton.onclick = function() { 74 var endIndex = input.name.search(/_\d+$/); 75 if (endIndex < 0) endIndex = input.name.length; 76 removeRow(removeButton, input.name.substring(10, endIndex)); 77 return false; 78 } 79 } else { 80 removeButton.onclick = function() { 81 removeRow(removeButton); 82 return false; 83 } 84 } 85 input.parentNode.replaceChild(removeButton, input); 86 } 87 88 // Make the submit buttons for removing filters client-side triggers 89 var filters = document.getElementById("filters"); 90 var inputs = filters.getElementsByTagName("input"); 91 for (var i = 0; i < inputs.length; i++) { 92 var input = inputs[i]; 93 if (input.type == "submit" && input.name 94 && input.name.match(/^rm_filter_/)) { 95 initializeFilter(input); 96 } 97 } 98 99 // Make the drop-down menu for adding a filter a client-side trigger 100 var addButton = document.forms["query"].elements["add"]; 101 addButton.parentNode.removeChild(addButton); 102 var select = document.getElementById("add_filter"); 103 select.onchange = function() { 104 if (select.selectedIndex < 1) return; 105 106 if (select.options[select.selectedIndex].disabled) { 107 // Neither IE nor Safari supported disabled options at the time this was 108 // written, so alert the user 109 alert("A filter already exists for that property"); 110 return; 111 } 112 113 // Convenience function for creating a <label> 114 function createLabel(text, htmlFor) { 115 var label = document.createElement("label"); 116 if (text) label.appendChild(document.createTextNode(text)); 117 if (htmlFor) label.htmlFor = htmlFor; 118 return label; 119 } 120 121 // Convenience function for creating an <input type="checkbox"> 122 function createCheckbox(name, value, id) { 123 var input = document.createElement("input"); 124 input.type = "checkbox"; 125 if (name) input.name = name; 126 if (value) input.value = value; 127 if (id) input.id = id; 128 return input; 129 } 130 131 // Convenience function for creating an <input type="radio"> 132 function createRadio(name, value, id) { 133 var input = document.createElement("input"); 134 input.type = "radio"; 135 if (name) input.name = name; 136 if (value) input.value = value; 137 if (id) input.id = id; 138 return input; 139 } 140 141 // Convenience function for creating a <select> 142 function createSelect(name, options, optional) { 143 var e = document.createElement("select"); 144 if (name) e.name = name; 145 if (optional) e.options[0] = new Option(); 146 if (options) { 147 for (var i = 0; i < options.length; i++) { 148 var option; 149 if (typeof(options[i]) == "object") { 150 option = new Option(options[i].text, options[i].value); 151 } else { 152 option = new Option(options[i], options[i]); 153 } 154 e.options[e.options.length] = option; 155 } 156 } 157 return e; 158 } 159 160 var propertyName = select.options[select.selectedIndex].value; 161 var property = properties[propertyName]; 162 var table = document.getElementById("filters").getElementsByTagName("table")[0]; 163 var tr = document.createElement("tr"); 164 tr.className = propertyName; 165 166 var alreadyPresent = false; 167 for (var i = 0; i < table.rows.length; i++) { 168 if (table.rows[i].className == propertyName) { 169 var existingTBody = table.rows[i].parentNode; 170 alreadyPresent = true; 171 break; 172 } 173 } 174 175 // Add the row header 176 var th = document.createElement("th"); 177 th.scope = "row"; 178 if (!alreadyPresent) { 179 th.appendChild(createLabel(property.label)); 180 } else { 181 th.colSpan = 2; 182 th.appendChild(createLabel("or")); 183 } 184 tr.appendChild(th); 185 186 var td = document.createElement("td"); 187 if (property.type == "radio" || property.type == "checkbox") { 188 td.colSpan = 2; 189 td.className = "filter"; 190 if (property.type == "radio") { 191 for (var i = 0; i < property.options.length; i++) { 192 var option = property.options[i]; 193 td.appendChild(createCheckbox(propertyName, option, 194 propertyName + "_" + option)); 195 td.appendChild(createLabel(option ? option : "none", 196 propertyName + "_" + option)); 197 } 198 } else { 199 td.appendChild(createRadio(propertyName, "1", propertyName + "_on")); 200 td.appendChild(document.createTextNode(" ")); 201 td.appendChild(createLabel("yes", propertyName + "_on")); 202 td.appendChild(createRadio(propertyName, "0", propertyName + "_off")); 203 td.appendChild(document.createTextNode(" ")); 204 td.appendChild(createLabel("no", propertyName + "_off")); 205 } 206 tr.appendChild(td); 207 } else { 208 if (!alreadyPresent) { 209 // Add the mode selector 210 td.className = "mode"; 211 var modeSelect = createSelect(propertyName + "_mode", 212 modes[property.type]); 213 td.appendChild(modeSelect); 214 tr.appendChild(td); 215 } 216 217 // Add the selector or text input for the actual filter value 218 td = document.createElement("td"); 219 td.className = "filter"; 220 if (property.type == "select") { 221 var element = createSelect(propertyName, property.options, true); 222 } else if (property.type == "text") { 223 var element = document.createElement("input"); 224 element.type = "text"; 225 element.name = propertyName; 226 element.size = 42; 227 } 228 td.appendChild(element); 229 element.focus(); 230 tr.appendChild(td); 231 } 232 233 // Add the add and remove buttons 234 td = document.createElement("td"); 235 td.className = "actions"; 236 var removeButton = document.createElement("input"); 237 removeButton.type = "button"; 238 removeButton.value = "-"; 239 removeButton.onclick = function() { removeRow(removeButton, propertyName) }; 240 td.appendChild(removeButton); 241 tr.appendChild(td); 242 243 if (alreadyPresent) { 244 existingTBody.appendChild(tr); 245 } else { 246 // Find the insertion point for the new row. We try to keep the filter rows 247 // in the same order as the options in the 'Add filter' drop-down, because 248 // that's the order they'll appear in when submitted. 249 var insertionPoint = getAncestorByTagName(select, "tbody"); 250 outer: for (var i = select.selectedIndex + 1; i < select.options.length; i++) { 251 for (var j = 0; j < table.tBodies.length; j++) { 252 if (table.tBodies[j].rows[0].className == select.options[i].value) { 253 insertionPoint = table.tBodies[j]; 254 break outer; 255 } 256 } 257 } 258 // Finally add the new row to the table 259 var tbody = document.createElement("tbody"); 260 tbody.appendChild(tr); 261 insertionPoint.parentNode.insertBefore(tbody, insertionPoint); 262 } 263 264 // Disable the add filter in the drop-down list 265 if (property.type == "radio" || property.type == "checkbox") { 266 select.options[select.selectedIndex].disabled = true; 267 } 268 select.selectedIndex = 0; 269 } 270 } 275 })(jQuery); -
trunk/trac/htdocs/js/search.js
r4006 r6572 1 /* Adapted from http://www.kryogenix.org/code/browser/searchhi/ */2 1 3 $.fn.highlightText = function(text, className) { 4 function highlight(node) { 5 if (node.nodeType == 3) { // Node.TEXT_NODE 6 var val = node.nodeValue; 7 var pos = val.toLowerCase().indexOf(text); 8 if (pos >= 0 && !$.className.has(node.parentNode, className)) { 9 var span = document.createElement("span"); 10 span.className = className; 11 span.appendChild(document.createTextNode(val.substr(pos, text.length))); 12 node.parentNode.insertBefore(span, node.parentNode.insertBefore( 13 document.createTextNode(val.substr(pos + text.length)), 14 node.nextSibling)); 15 node.nodeValue = val.substr(0, pos); 16 } 17 } else if (!$(node).is("button, select, textarea")) { 18 $.each(node.childNodes, function() { highlight(this) }); 19 } 20 } 21 return this.each(function() { highlight(this) }); 22 } 2 (function($){ 3 4 /* Adapted from http://www.kryogenix.org/code/browser/searchhi/ */ 5 $.fn.highlightText = function(text, className) { 6 function highlight(node) { 7 if (node.nodeType == 3) { // Node.TEXT_NODE 8 var val = node.nodeValue; 9 var pos = val.toLowerCase().indexOf(text); 10 if (pos >= 0 && !$.className.has(node.parentNode, className)) { 11 var span = document.createElement("span"); 12 span.className = className; 13 span.appendChild(document.createTextNode(val.substr(pos, text.length))); 14 node.parentNode.insertBefore(span, node.parentNode.insertBefore( 15 document.createTextNode(val.substr(pos + text.length)), 16 node.nextSibling)); 17 node.nodeValue = val.substr(0, pos); 18 } 19 } else if (!$(node).is("button, select, textarea")) { 20 $.each(node.childNodes, function() { highlight(this) }); 21 } 22 } 23 return this.each(function() { highlight(this) }); 24 } 25 26 $(document).ready(function() { 27 var elems = $(".searchable"); 28 if (!elems.length) return; 29 30 function getSearchTerms(url) { 31 if (url.indexOf("?") == -1) return []; 32 var params = url.substr(url.indexOf("?") + 1).split("&"); 33 for (var p in params) { 34 var param = params[p].split("="); 35 if (param.length < 2) continue; 36 if (param[0] == "q" || param[0] == "p") { // q= for Google, p= for Yahoo 37 var query = decodeURIComponent(param[1].replace(/\+/g, " ")); 38 if (query[0] == "!") query = query.slice(1); 39 var terms = []; 40 $.each(query.split(/(".*?")|('.*?')|(\s+)/), function() { 41 term = this.replace(/^\s+$/, ""); 42 if (term.length) { 43 terms.push(term.replace(/^['"]/, "").replace(/['"]$/, "")); 44 } 45 }); 46 return terms; 47 } 48 } 49 return []; 50 } 51 52 var terms = getSearchTerms(document.URL); 53 if (!terms.length) terms = getSearchTerms(document.referrer); 54 $.each(terms, function(idx) { 55 elems.highlightText(this.toLowerCase(), "searchword" + (idx % 5)); 56 }); 57 }); 23 58 24 $(document).ready(function() { 25 var elems = $(".searchable"); 26 if (!elems.length) return; 27 28 function getSearchTerms(url) { 29 if (url.indexOf("?") == -1) return []; 30 var params = url.substr(url.indexOf("?") + 1).split("&"); 31 for (var p in params) { 32 var param = params[p].split("="); 33 if (param.length < 2) continue; 34 if (param[0] == "q" || param[0] == "p") { // q= for Google, p= for Yahoo 35 var query = decodeURIComponent(param[1].replace(/\+/g, " ")); 36 if (query[0] == "!") query = query.slice(1); 37 var terms = []; 38 $.each(query.split(/(".*?")|('.*?')|(\s+)/), function() { 39 term = this.replace(/^\s+$/, ""); 40 if (term.length) { 41 terms.push(term.replace(/^['"]/, "").replace(/['"]$/, "")); 42 } 43 }); 44 return terms; 45 } 46 } 47 return []; 48 } 49 50 var terms = getSearchTerms(document.URL); 51 if (!terms.length) terms = getSearchTerms(document.referrer); 52 $.each(terms, function(idx) { 53 elems.highlightText(this.toLowerCase(), "searchword" + (idx % 5)); 54 }); 55 }); 59 })(jQuery); -
trunk/trac/htdocs/js/suggest.js
r4000 r6572 1 /*2 Text field auto-completion plugin for jQuery.3 Based on http://www.dyve.net/jquery/?autocomplete by Dylan Verheul.4 */5 $.suggest = function(input, url, paramName, minChars, delay) {6 var input = $(input).addClass("suggest").attr("autocomplete", "off");7 var timeout = null;8 var prev = "";9 var selectedIndex = -1;10 var results = null;11 1 12 input.keydown(function(e) { 13 switch(e.keyCode) { 14 case 27: // escape 15 hide(); 16 break; 17 case 38: // up 18 case 40: // down 19 e.preventDefault(); 20 if (results) { 21 var items = $("li", results); 22 if (!items) return; 23 var index = selectedIndex + (e.keyCode == 38 ? -1 : 1); 24 if (index >= 0 && index < items.length) { 25 move(index); 26 } 27 } else { 28 show(); 29 } 30 break; 31 case 9: // tab 32 case 13: // return 33 case 39: // right 34 if (results) { 35 var li = $("li.selected", results); 36 if (li.length) { 37 select(li); 38 e.preventDefault(); 39 } 40 } 41 break; 42 default: 43 if (timeout) clearTimeout(timeout); 44 timeout = setTimeout(show, delay); 45 break; 46 } 47 }); 48 input.blur(function() { 49 if (timeout) clearTimeout(timeout); 50 timeout = setTimeout(hide, 200); 51 }); 2 (function($){ 3 4 5 /* 6 Text field auto-completion plugin for jQuery. 7 Based on http://www.dyve.net/jquery/?autocomplete by Dylan Verheul. 8 */ 9 $.suggest = function(input, url, paramName, minChars, delay) { 10 var input = $(input).addClass("suggest").attr("autocomplete", "off"); 11 var timeout = null; 12 var prev = ""; 13 var selectedIndex = -1; 14 var results = null; 15 16 input.keydown(function(e) { 17 switch(e.keyCode) { 18 case 27: // escape 19 hide(); 20 break; 21 case 38: // up 22 case 40: // down 23 e.preventDefault(); 24 if (results) { 25 var items = $("li", results); 26 if (!items) return; 27 var index = selectedIndex + (e.keyCode == 38 ? -1 : 1); 28 if (index >= 0 && index < items.length) { 29 move(index); 30 } 31 } else { 32 show(); 33 } 34 break; 35 case 9: // tab 36 case 13: // return 37 case 39: // right 38 if (results) { 39 var li = $("li.selected", results); 40 if (li.length) { 41 select(li); 42 e.preventDefault(); 43 } 44 } 45 break; 46 default: 47 if (timeout) clearTimeout(timeout); 48 timeout = setTimeout(show, delay); 49 break; 50 } 51 }); 52 input.blur(function() { 53 if (timeout) clearTimeout(timeout); 54 timeout = setTimeout(hide, 200); 55 }); 56 57 function getOffset(elem) { 58 elem = $(elem).get(0); 59 var offset = {left: 0, top: 0}; 60 do { 61 offset.left += elem.offsetLeft || 0; 62 offset.top += elem.offsetTop || 0; 63 elem = elem.offsetParent; 64 } while (elem); 65 return offset; 66 } 67 68 function hide() { 69 if (timeout) clearTimeout(timeout); 70 input.removeClass("loading"); 71 if (results) { 72 results.fadeOut("fast").remove(); 73 results = null; 74 } 75 $("iframe.iefix").remove(); 76 selectedIndex = -1; 77 } 78 79 function move(index) { 80 if (!results) return; 81 items = $("li", results); 82 items.removeClass("selected"); 83 $(items[index]).addClass("selected"); 84 selectedIndex = index; 85 } 86 87 function select(li) { 88 if (!li) li = $("<li>"); 89 else li = $(li); 90 var val = $.trim(li.text()); 91 prev = val; 92 input.val(val); 93 hide(); 94 selectedIndex = -1; 95 } 96 97 function show() { 98 var val = input.val(); 99 if (val == prev) return; 100 prev = val; 101 if (val.length < minChars) { hide(); return; } 102 input.addClass("loading"); 103 var params = {}; 104 params[paramName] = val; 105 $.get(url, params, function(data) { 106 if (!data) { hide(); return; } 107 if (!results) { 108 var offset = getOffset(input); 109 results = $("<div>").addClass("suggestions").css({ 110 position: "absolute", 111 minWidth: input.get(0).offsetWidth + "px", 112 top: (offset.top + input.get(0).offsetHeight) + "px", 113 left: offset.left + "px", 114 zIndex: 2 115 }).appendTo("body"); 116 if ($.browser.msie) { 117 var iframe = $("<iframe style='display:none;position:absolute;" + 118 "filter:progid:DXImageTransform.Microsoft.Alpha(opacity=0);'" + 119 " class='iefix' src='javascript:false;' frameborder='0'" + 120 " scrolling='no'></iframe>").insertAfter(results); 121 setTimeout(function() { 122 var offset = getOffset(results); 123 iframe.css({ 124 top: offset.top + "px", 125 right: (offset.left + results.get(0).offsetWidth) + "px", 126 bottom: (offset.top + results.get(0).offsetHeight) + "px", 127 left: offset.left + "px", 128 zIndex: 1 129 }); 130 iframe.show(); 131 }, 10); 132 } 133 } 134 results.html(data).fadeTo("fast", 0.92); 135 items = $("li", results); 136 items 137 .hover(function() { move(items.index(this)) }, 138 function() { $(this).removeClass("selected") }) 139 .click(function() { select(this); input.get(0).focus() }); 140 move(0); 141 }); 142 } 143 } 144 145 $.fn.suggest = function(url, paramName, minChars, delay) { 146 url = url || window.location.pathname; 147 paramName = paramName || 'q'; 148 minChars = minChars || 1; 149 delay = delay || 400; 150 return this.each(function() { 151 new $.suggest(this, url, paramName, minChars, delay); 152 }); 153 } 52 154 53 function getOffset(elem) { 54 elem = $(elem).get(0); 55 var offset = {left: 0, top: 0}; 56 do { 57 offset.left += elem.offsetLeft || 0; 58 offset.top += elem.offsetTop || 0; 59 elem = elem.offsetParent; 60 } while (elem); 61 return offset; 62 } 63 64 function hide() { 65 if (timeout) clearTimeout(timeout); 66 input.removeClass("loading"); 67 if (results) { 68 results.fadeOut("fast").remove(); 69 results = null; 70 } 71 $("iframe.iefix").remove(); 72 selectedIndex = -1; 73 } 74 75 function move(index) { 76 if (!results) return; 77 items = $("li", results); 78 items.removeClass("selected"); 79 $(items[index]).addClass("selected"); 80 selectedIndex = index; 81 } 82 83 function select(li) { 84 if (!li) li = $("<li>"); 85 else li = $(li); 86 var val = $.trim(li.text()); 87 prev = val; 88 input.val(val); 89 hide(); 90 selectedIndex = -1; 91 } 92 93 function show() { 94 var val = input.val(); 95 if (val == prev) return; 96 prev = val; 97 if (val.length < minChars) { hide(); return; } 98 input.addClass("loading"); 99 var params = {}; 100 params[paramName] = val; 101 $.get(url, params, function(data) { 102 if (!data) { hide(); return; } 103 if (!results) { 104 var offset = getOffset(input); 105 results = $("<div>").addClass("suggestions").css({ 106 position: "absolute", 107 minWidth: input.get(0).offsetWidth + "px", 108 top: (offset.top + input.get(0).offsetHeight) + "px", 109 left: offset.left + "px", 110 zIndex: 2 111 }).appendTo("body"); 112 if ($.browser.msie) { 113 var iframe = $("<iframe style='display:none;position:absolute;" + 114 "filter:progid:DXImageTransform.Microsoft.Alpha(opacity=0);'" + 115 " class='iefix' src='javascript:false;' frameborder='0'" + 116 " scrolling='no'></iframe>").insertAfter(results); 117 setTimeout(function() { 118 var offset = getOffset(results); 119 iframe.css({ 120 top: offset.top + "px", 121 right: (offset.left + results.get(0).offsetWidth) + "px", 122 bottom: (offset.top + results.get(0).offsetHeight) + "px", 123 left: offset.left + "px", 124 zIndex: 1 125 }); 126 iframe.show(); 127 }, 10); 128 } 129 } 130 results.html(data).fadeTo("fast", 0.92); 131 items = $("li", results); 132 items 133 .hover(function() { move(items.index(this)) }, 134 function() { $(this).removeClass("selected") }) 135 .click(function() { select(this); input.get(0).focus() }); 136 move(0); 137 }); 138 } 139 } 140 141 $.fn.suggest = function(url, paramName, minChars, delay) { 142 url = url || window.location.pathname; 143 paramName = paramName || 'q'; 144 minChars = minChars || 1; 145 delay = delay || 400; 146 return this.each(function() { 147 new $.suggest(this, url, paramName, minChars, delay); 148 }); 149 } 155 })(jQuery); -
trunk/trac/htdocs/js/trac.js
r4590 r6572 1 $.fn.addAnchor = function(title) { 2 title = title || "Link here"; 3 return this.filter("*[@id]").each(function() { 4 $("<a class='anchor'> \u00B6</a>").attr("href", "#" + this.id) 5 .attr("title", title).appendTo(this); 6 }); 7 } 1 jQuery.noConflict(); // jQuery is now removed from the $ namespace 2 // to use the $ shorthand, use (function($){ ... })(jQuery); 3 // and for the onload handler: jQuery(function($){ ... }); 8 4 9 $.fn.checked = function(checked) { 10 if (checked == undefined) { // getter 11 if (!this.length) return false; 12 return this.get(0).checked; 13 } else { // setter 14 return this.each(function() { 15 this.checked = checked; 16 }); 17 } 18 } 5 (function($){ 6 7 $.fn.addAnchor = function(title) { 8 title = title || "Link here"; 9 return this.filter("*[@id]").each(function() { 10 $("<a class='anchor'> \u00B6</a>").attr("href", "#" + this.id) 11 .attr("title", title).appendTo(this); 12 }); 13 } 14 15 $.fn.checked = function(checked) { 16 if (checked == undefined) { // getter 17 if (!this.length) return false; 18 return this.get(0).checked; 19 } else { // setter 20 return this.each(function() { 21 this.checked = checked; 22 }); 23 } 24 } 25 26 $.fn.enable = function(enabled) { 27 if (enabled == undefined) enabled = true; 28 return this.each(function() { 29 this.disabled = !enabled; 30 var label = $(this).parents("label"); 31 if (!label.length && this.id) { 32 label = $("label[@for='" + this.id + "']"); 33 } 34 if (!enabled) { 35 label.addClass("disabled"); 36 } else { 37 label.removeClass("disabled"); 38 } 39 }); 40 } 41 42 $.loadStyleSheet = function(href, type) { 43 type = type || "text/css"; 44 $(document).ready(function() { 45 if (document.createStyleSheet) { // MSIE 46 document.createStyleSheet(href); 47 } else { 48 $("<link rel='stylesheet type='" + type + "' href='" + href + "' />") 49 .appendTo("head"); 50 } 51 }); 52 } 53 54 // Used for dynamically updating the height of a textarea 55 window.resizeTextArea = function (id, rows) { 56 var textarea = $("#" + id).get(0); 57 if (!textarea || textarea.rows == undefined) return; 58 textarea.rows = rows; 59 } 60 61 // The following are defined for backwards compatibility with releases prior 62 // to Trac 0.11 63 64 window.addEvent = function(elem, type, func) { 65 $(elem).bind(type, func); 66 } 67 window.addHeadingLinks = function(container, title) { 68 $.each(["h1", "h2", "h3", "h4", "h5", "h6"], function() { 69 $(this, container).addAnchor(title); 70 }); 71 } 72 window.enableControl = function(id, enabled) { 73 $("#" + id).enable(enabled); 74 } 75 window.getAncestorByTagName = function(elem, tagName) { 76 return $(elem).parents(tagName).get(0); 77 } 19 78 20 $.fn.enable = function(enabled) { 21 if (enabled == undefined) enabled = true; 22 return this.each(function() { 23 this.disabled = !enabled; 24 var label = $(this).parents("label"); 25 if (!label.length && this.id) { 26 label = $("label[@for='" + this.id + "']"); 27 } 28 if (!enabled) { 29 label.addClass("disabled"); 30 } else { 31 label.removeClass("disabled"); 32 } 33 }); 34 } 35 36 $.loadStyleSheet = function(href, type) { 37 type = type || "text/css"; 38 $(document).ready(function() { 39 if (document.createStyleSheet) { // MSIE 40 document.createStyleSheet(href); 41 } else { 42 $("<link rel='stylesheet type='" + type + "' href='" + href + "' />") 43 .appendTo("head"); 44 } 45 }); 46 } 47 48 // Used for dynamically updating the height of a textarea 49 function resizeTextArea(id, rows) { 50 var textarea = $("#" + id).get(0); 51 if (!textarea || textarea.rows == undefined) return; 52 textarea.rows = rows; 53 } 54 55 // The following are defined for backwards compatibility with releases prior 56 // to Trac 0.11 57 58 function addEvent(elem, type, func) { 59 $(elem).bind(type, func); 60 } 61 function addHeadingLinks(container, title) { 62 $.each(["h1", "h2", "h3", "h4", "h5", "h6"], function() { 63 $(this, container).addAnchor(title); 64 }); 65 } 66 function enableControl(id, enabled) { 67 $("#" + id).enable(enabled); 68 } 69 function getAncestorByTagName(elem, tagName) { 70 return $(elem).parents(tagName).get(0); 71 } 79 })(jQuery); -
trunk/trac/htdocs/js/wikitoolbar.js
r4611 r6572 1 function addWikiFormattingToolbar(textarea) {2 if ((document.selection == undefined)3 && (textarea.setSelectionRange == undefined)) {4 return;5 }6 1 7 var toolbar = document.createElement("div");8 toolbar.className = "wikitoolbar";9 2 10 function addButton(id, title, fn) { 11 var a = document.createElement("a"); 12 a.href = "#"; 13 a.id = id; 14 a.title = title; 15 a.onclick = function() { try { fn() } catch (e) { } return false }; 16 a.tabIndex = 400; 17 toolbar.appendChild(a); 18 } 3 (function($){ 4 5 6 window.addWikiFormattingToolbar = function(textarea) { 7 if ((document.selection == undefined) 8 && (textarea.setSelectionRange == undefined)) { 9 return; 10 } 11 12 var toolbar = document.createElement("div"); 13 toolbar.className = "wikitoolbar"; 14 15 function addButton(id, title, fn) { 16 var a = document.createElement("a"); 17 a.href = "#"; 18 a.id = id; 19 a.title = title; 20 a.onclick = function() { try { fn() } catch (e) { } return false }; 21 a.tabIndex = 400; 22 toolbar.appendChild(a); 23 } 24 25 function encloseSelection(prefix, suffix) { 26 textarea.focus(); 27 var start, end, sel, scrollPos, subst; 28 if (document.selection != undefined) { 29 sel = document.selection.createRange().text; 30 } else if (textarea.setSelectionRange != undefined) { 31 start = textarea.selectionStart; 32 end = textarea.selectionEnd; 33 scrollPos = textarea.scrollTop; 34 sel = textarea.value.substring(start, end); 35 } 36 if (sel.match(/ $/)) { // exclude ending space char, if any 37 sel = sel.substring(0, sel.length - 1); 38 suffix = suffix + " "; 39 } 40 subst = prefix + sel + suffix; 41 if (document.selection != undefined) { 42 var range = document.selection.createRange().text = subst; 43 textarea.caretPos -= suffix.length; 44 } else if (textarea.setSelectionRange != undefined) { 45 textarea.value = textarea.value.substring(0, start) + subst + 46 textarea.value.substring(end); 47 if (sel) { 48 textarea.setSelectionRange(start + subst.length, start + subst.length); 49 } else { 50 textarea.setSelectionRange(start + prefix.length, start + prefix.length); 51 } 52 textarea.scrollTop = scrollPos; 53 } 54 } 55 56 addButton("strong", "Bold text: '''Example'''", function() { 57 encloseSelection("'''", "'''"); 58 }); 59 addButton("em", "Italic text: ''Example''", function() { 60 encloseSelection("''", "''"); 61 }); 62 addButton("heading", "Heading: == Example ==", function() { 63 encloseSelection("\n== ", " ==\n", "Heading"); 64 }); 65 addButton("link", "Link: [http://www.example.com/ Example]", function() { 66 encloseSelection("[", "]"); 67 }); 68 addButton("code", "Code block: {{{ example }}}", function() { 69 encloseSelection("\n{{{\n", "\n}}}\n"); 70 }); 71 addButton("hr", "Horizontal rule: ----", function() { 72 encloseSelection("\n----\n", ""); 73 }); 74 addButton("np", "New paragraph", function() { 75 encloseSelection("\n\n", ""); 76 }); 77 addButton("br", "Line break: [[BR]]", function() { 78 encloseSelection("[[BR]]\n", ""); 79 }); 80 addButton("img", "Image: [[Image()]]", function() { 81 encloseSelection("[[Image(", ")]]"); 82 }); 83 84 $(textarea).before(toolbar); 85 } 19 86 20 function encloseSelection(prefix, suffix) { 21 textarea.focus(); 22 var start, end, sel, scrollPos, subst; 23 if (document.selection != undefined) { 24 sel = document.selection.createRange().text; 25 } else if (textarea.setSelectionRange != undefined) { 26 start = textarea.selectionStart; 27 end = textarea.selectionEnd; 28 scrollPos = textarea.scrollTop; 29 sel = textarea.value.substring(start, end); 30 } 31 if (sel.match(/ $/)) { // exclude ending space char, if any 32 sel = sel.substring(0, sel.length - 1); 33 suffix = suffix + " "; 34 } 35 subst = prefix + sel + suffix; 36 if (document.selection != undefined) { 37 var range = document.selection.createRange().text = subst; 38 textarea.caretPos -= suffix.length; 39 } else if (textarea.setSelectionRange != undefined) { 40 textarea.value = textarea.value.substring(0, start) + subst + 41 textarea.value.substring(end); 42 if (sel) { 43 textarea.setSelectionRange(start + subst.length, start + subst.length); 44 } else { 45 textarea.setSelectionRange(start + prefix.length, start + prefix.length); 46 } 47 textarea.scrollTop = scrollPos; 48 } 49 } 50 51 addButton("strong", "Bold text: '''Example'''", function() { 52 encloseSelection("'''", "'''"); 53 }); 54 addButton("em", "Italic text: ''Example''", function() { 55 encloseSelection("''", "''"); 56 }); 57 addButton("heading", "Heading: == Example ==", function() { 58 encloseSelection("\n== ", " ==\n", "Heading"); 59 }); 60 addButton("link", "Link: [http://www.example.com/ Example]", function() { 61 encloseSelection("[", "]"); 62 }); 63 addButton("code", "Code block: {{{ example }}}", function() { 64 encloseSelection("\n{{{\n", "\n}}}\n"); 65 }); 66 addButton("hr", "Horizontal rule: ----", function() { 67 encloseSelection("\n----\n", ""); 68 }); 69 addButton("np", "New paragraph", function() { 70 encloseSelection("\n\n", ""); 71 }); 72 addButton("br", "Line break: [[BR]]", function() { 73 encloseSelection("[[BR]]\n", ""); 74 }); 75 addButton("img", "Image: [[Image()]]", function() { 76 encloseSelection("[[Image(", ")]]"); 77 }); 78 79 $(textarea).before(toolbar); 80 } 87 })(jQuery); 81 88 82 89 // Add the toolbar to all <textarea> elements on the page with the class 83 90 // 'wikitext'. 84 $(document).ready(function() {91 jQuery(document).ready(function($) { 85 92 $("textarea.wikitext").each(function() { addWikiFormattingToolbar(this) }); 86 93 }); -
trunk/trac/prefs/templates/prefs_pygments.html
r5816 r6572 16 16 href="${href.pygments('%s.css' % style)}" title="${style.title()}" /> 17 17 <script type="text/javascript"> 18 function switchStyleSheet(title) { 19 $('link[@rel="stylesheet"][@title]').each(function() { 20 this.disabled = this.getAttribute('title') != title; 21 }); 22 } 23 $(document).ready(function() { 18 (function($){ 19 window.switchStyleSheet = function(title) { 20 $('link[@rel="stylesheet"][@title]').each(function() { 21 this.disabled = this.getAttribute('title') != title; 22 }); 23 } 24 })(jQuery); 25 jQuery(document).ready(function($) { 24 26 switchStyleSheet("${selection.title()}"); 25 27 $("#pygment_theme").attr("autocomplete", "off").change(function() { -
trunk/trac/search/templates/search.html
r6357 r6572 15 15 </py:if> 16 16 <script type="text/javascript"> 17 $(document).ready(function() {$("#q").get(0).focus()});17 jQuery(document).ready(function($) {$("#q").get(0).focus()}); 18 18 </script> 19 19 </head> -
trunk/trac/templates/about.html
r6357 r6572 10 10 <link rel="stylesheet" type="text/css" href="${chrome.htdocs_location}css/about.css" /> 11 11 <script type="text/javascript"> 12 $(document).ready(function () {12 jQuery(document).ready(function ($) { 13 13 $("#systeminfo table").append("<tr><th>jQuery:</th><td>"+$().jquery+"</td></tr>"); 14 14 }); -
trunk/trac/templates/error.html
r6357 r6572 9 9 <title>${title or 'Error'}</title> 10 10 <script py:if="frames" type="text/javascript">/*<![CDATA[*/ 11 $(document).ready(function() {11 jQuery(document).ready(function($) { 12 12 $("#traceback a").click(function() { 13 13 $("div", this.parentNode).slideToggle("fast"); -
trunk/trac/ticket/templates/milestone_delete.html
r6357 r6572 11 11 href="${chrome.htdocs_location}css/roadmap.css" /> 12 12 <script type="text/javascript"> 13 $(document).ready(function() {13 jQuery(document).ready(function($) { 14 14 $("#retarget").click(function(){ $("#target").enable(this.checked) }); 15 15 }); -
trunk/trac/ticket/templates/milestone_edit.html
r6357 r6572 15 15 <script type="text/javascript" src="${chrome.htdocs_location}js/wikitoolbar.js"></script> 16 16 <script type="text/javascript">/*<![CDATA[*/ 17 $(document).ready(function() {17 jQuery(document).ready(function($) { 18 18 function updateCompletedDate() { 19 19 var checked = $("#completed").checked(); -
trunk/trac/ticket/templates/milestone_view.html
r6357 r6572 10 10 <title>Milestone ${milestone.name}</title> 11 11 <script type="text/javascript"> 12 $(document).ready(function() {12 jQuery(document).ready(function($) { 13 13 $("#content").find("h1,h2,h3,h4,h5,h6").addAnchor("Link to this section"); 14 14 }); -
trunk/trac/ticket/templates/query.html
r6570 r6572 10 10 <script type="text/javascript" src="${chrome.htdocs_location}js/folding.js"></script> 11 11 <script type="text/javascript"> 12 $(document).ready(function() {12 jQuery(document).ready(function($) { 13 13 $("#group").change(function() { 14 14 $("#groupdesc").enable(this.selectedIndex != 0) -
trunk/trac/ticket/templates/ticket.html
r6376 r6572 21 21 <script type="text/javascript" src="${chrome.htdocs_location}js/wikitoolbar.js"></script> 22 22 <script type="text/javascript" py:choose=""> 23 $(document).ready(function() {23 jQuery(document).ready(function($) { 24 24 $("div.description").find("h1,h2,h3,h4,h5,h6").addAnchor("Link to this section"); 25 25 <py:when test="ticket.exists"> … … 39 39 </py:when> 40 40 <py:otherwise> 41 $( document).ready(function() {$("#field-summary").get(0).focus()});41 $("#field-summary").focus(); 42 42 </py:otherwise> 43 43 }); -
trunk/trac/wiki/templates/wiki_edit.html
r6357 r6572 11 11 <script type="text/javascript" src="${chrome.htdocs_location}js/wikitoolbar.js"></script> 12 12 <script type="text/javascript"> 13 $(document).ready(function() {13 jQuery(document).ready(function($) { 14 14 $("#text").blur(function() { 15 15 $("#scroll_bar_pos").val(this.scrollTop); -
trunk/trac/wiki/templates/wiki_view.html
r6357 r6572 11 11 <meta py:if="version" name="ROBOTS" content="NOINDEX, NOFOLLOW" /> 12 12 <script type="text/javascript"> 13 $(document).ready(function() {13 jQuery(document).ready(function($) { 14 14 $("#content").find("h1,h2,h3,h4,h5,h6").addAnchor("Link to this section"); 15 15 });
Note:
See TracChangeset
for help on using the changeset viewer.