How to add custom icons to edit toolbar (MediaWiki)
From WhyNotWiki
[edit] What I did
Get the icons:
wiki/trunk > svn export http://svn.tylerrick.com/wiki/custom_toolbar_icons wiki/trunk > cp -R custom_toolbar_icons/. skins/common/images wiki/trunk > rm -r custom_toolbar_icons/
In your MediaWiki:Common.js, put this code (you can export it from my site):
/* Purge cache */ /* vim: shiftwidth=2 tabstop=2 expandtab
- /
/*
* Based on: * http://en.wikipedia.org/w/index.php?title=MediaWiki:Common.js * http://en.wikipedia.org/w/index.php?title=MediaWiki:Common.js&action=edit */
/* Test if an element has a certain class ************************************** * * Description: Uses regular expressions and caching for better performance. * Maintainers: User:Mike Dillon, User:R. Koot, User:SG */ var hasClass = (function () { var reCache = {}; return function (element, className) { return (reCache[className] ? reCache[className] : (reCache[className] = new RegExp("(?:\\s|^)" + className + "(?:\\s|$)"))).test(element.className); }; })();
/***************************************
- Maintainers: User:Tyler
- /
function collapseCategoryTrees() {var indexCollapsible = 0; // iterate over all < div >-elements var divs = document.getElementsByTagName("div"); for(var i=0; div = divs[i]; i++ ) {
if (hasClass(div, "DoNotCollapseCategoryTrees")) { break; }
if (hasClass(div, "CategoryTreeTag")) {// To do: describe this using XPath or the HTML structure, so it's not just magic numbers (1101)... link_tag_for_top_level_tree = div.childNodes[1].childNodes[1].childNodes[0].childNodes[1];
link_tag_for_top_level_tree.href = "javascript:void(0)"; // not # categoryTreeCollapseNode( 'whatever', '20', link_tag_for_top_level_tree);
} // is CategoryTree
}}
addOnloadHook( collapseCategoryTrees );
/** Collapsible sections *************************************
- an
- Description: See Template:Collapsible and Template:Inline collapsible.
- Maintainers: User:Tyler
- /
// set up the words in your language var CollapsibleHide = '[' + 'Hide' + ']'; var CollapsibleShow = '[' + 'Show' + ']'; // var InlineCollapsibleHide = '[hide]'; var InlineCollapsibleShow = '...';
// set up max count of Collapsibles on page, // if there are more, all will be hidden // CollapsibleShowDefault = 0; // all bars will be hidden // NavigationBarShowDefault = 1; // on pages with more than 1 bar all bars will be hidden var CollapsibleShowDefault = 0;
function toggleAllCollapsibles(set_to) {if (typeof(set_to) == 'undefined') { set_to = 'show' };for (var i = 0; document.getElementById("CollapsibleFrame" + i); i++) { toggleCollapsible(i, set_to); }}
// shows and hides content and picture (if available) of Collapsibles // Parameters: // indexCollapsible: the index of Collapsible to be toggled // set_to: 'show' or 'hide' to set; null to toggle function toggleCollapsible(indexCollapsible, set_to) {
if (typeof(set_to) == 'undefined') { set_to = null }; //alert('toggleCollapsible(' + indexCollapsible + ',' + set_to + ')');var CollapsibleFrame = document.getElementById("CollapsibleFrame" + indexCollapsible); var CollapsibleToggle = document.getElementById("CollapsibleToggle" + indexCollapsible);// If there aren't *any* if (!CollapsibleFrame || !CollapsibleToggle) { return false; }// if shown now if ( CollapsibleToggle.firstChild.data == CollapsibleHide || CollapsibleToggle.firstChild.data == InlineCollapsibleHide || set_to == 'hide' ) { for ( var CollapsibleChild = CollapsibleFrame.firstChild; CollapsibleChild != null; CollapsibleChild = CollapsibleChild.nextSibling ) { if ( hasClass( CollapsibleChild, 'CollapsiblePic' ) ) { CollapsibleChild.style.display = 'none'; } if ( hasClass( CollapsibleChild, 'CollapsibleContent') ) { CollapsibleChild.style.display = 'none'; } } // Switch the text (from 'Hide' to 'Show') if (CollapsibleFrame.tagName == 'SPAN') { CollapsibleToggle.firstChild.data = InlineCollapsibleShow; } else { CollapsibleToggle.firstChild.data = CollapsibleShow; }// if hidden now } else if (CollapsibleToggle.firstChild.data == CollapsibleShow || CollapsibleToggle.firstChild.data == InlineCollapsibleShow || set_to == 'show' ) { for ( var CollapsibleChild = CollapsibleFrame.firstChild; CollapsibleChild != null; CollapsibleChild = CollapsibleChild.nextSibling ) { if (hasClass(CollapsibleChild, 'CollapsiblePic') || hasClass(CollapsibleChild, 'CollapsibleContent')) { if (CollapsibleFrame.tagName == 'SPAN') { CollapsibleChild.style.display = 'inline'; } else { CollapsibleChild.style.display = 'block'; } } } // Switch the text (from 'Show' to 'Hide') if (CollapsibleFrame.tagName == 'SPAN') { CollapsibleToggle.firstChild.data = InlineCollapsibleHide; } else { CollapsibleToggle.firstChild.data = CollapsibleHide; } }}
// adds show/hide-button to Collapsibles function createCollapsibleToggleButton() {
var indexCollapsible = 0;// iterate over alland elementsvar divs = document.getElementsByTagName("div"); var spans = document.getElementsByTagName("span");// I would rather just combine them into one array and do the iteration within this function, but... // var divs_and_spans = divs.concat(spans); // Tried this but it said concat wasn't a valid method? So is divs not actually an array??indexCollapsible = createCollapsibleToggleButtonForCollection(divs, indexCollapsible); createCollapsibleToggleButtonForCollection(spans, indexCollapsible); // Inline sections} // function createCollapsibleToggleButton()
function createCollapsibleToggleButtonForCollection(collection, indexCollapsible) {
for( var i=0; CollapsibleFrame = collection[i]; i++ ) {// if found a Collapsible if (hasClass(CollapsibleFrame, "CollapsibleFrame")) {indexCollapsible++; var CollapsibleToggle = document.createElement("a"); CollapsibleToggle.className = 'CollapsibleToggle'; CollapsibleToggle.setAttribute('id', 'CollapsibleToggle' + indexCollapsible); CollapsibleToggle.setAttribute('href', 'javascript:toggleCollapsible(' + indexCollapsible + ');'); if (CollapsibleFrame.tagName == 'SPAN') { var CollapsibleToggleText = document.createTextNode(InlineCollapsibleHide); } else { var CollapsibleToggleText = document.createTextNode(CollapsibleHide); } CollapsibleToggle.appendChild(CollapsibleToggleText);var CollapsibleHider = document.createElement("a"); CollapsibleHider.className = 'CollapsibleHider'; CollapsibleHider.setAttribute('id', 'CollapsibleHider' + indexCollapsible); CollapsibleHider.setAttribute('href', 'javascript:toggleCollapsible(' + indexCollapsible + ');'); CollapsibleHider.appendChild(document.createTextNode(CollapsibleHide));var CollapsibleExpandAllLink = document.createElement("a"); CollapsibleExpandAllLink.className = 'CollapsibleExpandAllLink'; CollapsibleExpandAllLink.setAttribute('id', 'CollapsibleExpandAllLink' + indexCollapsible); CollapsibleExpandAllLink.setAttribute('href', 'javascript:toggleAllCollapsibles("show");'); CollapsibleExpandAllLink.appendChild(document.createTextNode('[Expand all]'));var CollapsibleCollapseAllLink = document.createElement("a"); CollapsibleCollapseAllLink.className = 'CollapsibleCollapseAllLink'; CollapsibleCollapseAllLink.setAttribute('id', 'CollapsibleCollapseAllLink' + indexCollapsible); CollapsibleCollapseAllLink.setAttribute('href', 'javascript:toggleAllCollapsibles("hide");'); CollapsibleCollapseAllLink.appendChild(document.createTextNode('[Collapse all]')); // Find the CollapsibleHead and attach the toggle link (Must be this complicated because Moz's firstChild handling is borked) for( var j=0; j < CollapsibleFrame.childNodes.length; j++ ) { if (hasClass(CollapsibleFrame.childNodes[j], "CollapsibleHead")) { if (CollapsibleFrame.tagName == 'SPAN') { CollapsibleFrame.childNodes[j].firstChild.data = ; } CollapsibleFrame.childNodes[j].appendChild(CollapsibleToggle); if (CollapsibleFrame.tagName != 'SPAN') { CollapsibleFrame.childNodes[j].appendChild(CollapsibleExpandAllLink); CollapsibleFrame.childNodes[j].appendChild(CollapsibleCollapseAllLink); } } } CollapsibleFrame.setAttribute('id', 'CollapsibleFrame' + indexCollapsible);
// The hider if (CollapsibleFrame.tagName == 'SPAN') { // Don't need one } else { // Find the CollapsibleFoot within the CollapsibleContent and attach the hider link for (var j=0; j < CollapsibleFrame.childNodes.length; j++) { if (hasClass(current = CollapsibleFrame.childNodes[j], "CollapsibleContent")) { for (var k=0; k < current.childNodes.length; k++) { if (hasClass(current2 = current.childNodes[k], "CollapsibleFoot")) { current2.appendChild(CollapsibleHider); } } } } }
if (hasClass(CollapsibleFrame, "InitiallyExpanded")) { } else { toggleCollapsible(indexCollapsible); }
} // is CollapsibleFrame} // forreturn indexCollapsible;} // function createCollapsibleToggleButtonForCollection()
addOnloadHook( createCollapsibleToggleButton );
/** } Collapsible sections *************************************/
/*{ Dynamic Navigation Bars (experimental) *************************************
- Description: See Wikipedia:NavFrame.
- Maintainers: UNMAINTAINED
- /
// set up the words in your language var NavigationBarHide = '[' + 'Hide' + ']'; var NavigationBarShow = '[' + 'Show' + ']';
// set up max count of Navigation Bars on page, // if there are more, all will be hidden // NavigationBarShowDefault = 0; // all bars will be hidden // NavigationBarShowDefault = 1; // on pages with more than 1 bar all bars will be hidden var NavigationBarShowDefault = 1; // autoCollapse
// shows and hides content and picture (if available) of navigation bars // Parameters: // indexNavigationBar: the index of navigation bar to be toggled function toggleNavigationBar(indexNavigationBar) {var NavToggle = document.getElementById("NavToggle" + indexNavigationBar); var NavFrame = document.getElementById("NavFrame" + indexNavigationBar);if (!NavFrame || !NavToggle) {return false;
}// if shown now if (NavToggle.firstChild.data == NavigationBarHide) {for ( var NavChild = NavFrame.firstChild; NavChild != null; NavChild = NavChild.nextSibling ) { if ( hasClass( NavChild, 'NavPic' ) ) { NavChild.style.display = 'none'; } if ( hasClass( NavChild, 'NavContent') ) { NavChild.style.display = 'none'; } }
NavToggle.firstChild.data = NavigationBarShow;// if hidden now } else if (NavToggle.firstChild.data == NavigationBarShow) {for ( var NavChild = NavFrame.firstChild; NavChild != null; NavChild = NavChild.nextSibling ) { if (hasClass(NavChild, 'NavPic')) { NavChild.style.display = 'block'; } if (hasClass(NavChild, 'NavContent')) { NavChild.style.display = 'block'; } }
NavToggle.firstChild.data = NavigationBarHide; }}
// adds show/hide-button to navigation bars function createNavigationBarToggleButton() {
var indexNavigationBar = 0; // iterate over all < div >-elements var divs = document.getElementsByTagName("div"); for(var i=0; NavFrame = divs[i]; i++ ) { // if found a navigation bar if (hasClass(NavFrame, "NavFrame")) {
indexNavigationBar++; var NavToggle = document.createElement("a"); NavToggle.className = 'NavToggle'; NavToggle.setAttribute('id', 'NavToggle' + indexNavigationBar); NavToggle.setAttribute('href', 'javascript:toggleNavigationBar(' + indexNavigationBar + ');');
var NavToggleText = document.createTextNode(NavigationBarHide); NavToggle.appendChild(NavToggleText); // Find the NavHead and attach the toggle link (Must be this complicated because Moz's firstChild handling is borked) for( var j=0; j < NavFrame.childNodes.length; j++ ) { if (hasClass(NavFrame.childNodes[j], "NavHead")) { NavFrame.childNodes[j].appendChild(NavToggle); } } NavFrame.setAttribute('id', 'NavFrame' + indexNavigationBar); }
} // if more Navigation Bars found than Default: hide all if (NavigationBarShowDefault < indexNavigationBar) {for( var i=1; i<=indexNavigationBar; i++ ) { toggleNavigationBar(i); }
}}
addOnloadHook( createNavigationBarToggleButton );
/** } Dynamic Navigation Bars (experimental) *************************************/
base_url = "http://whynotwiki.com/"; include_advanced_icons = true;if (mwCustomEditButtons) {
mwCustomEditButtons[mwCustomEditButtons.length] = { "imageFile": base_url + "skins/common/images/button_headline.png", "speedTip": "Level-1 headline", "tagOpen": "=", "sampleText": "", "tagClose": "=\n" };mwCustomEditButtons[mwCustomEditButtons.length] = { "imageFile": base_url + "skins/common/images/button_headline.png", "speedTip": "Level-2 headline", "tagOpen": "==", "sampleText": "", "tagClose": "==\n" };mwCustomEditButtons[mwCustomEditButtons.length] = { "imageFile": base_url + "skins/common/images/button_headline.png", "speedTip": "Level-3 headline", "tagOpen": "===", "sampleText": "", "tagClose": "===\n" };
// From http://en.wikipedia.org/wiki/MediaWiki:Common.js :mwCustomEditButtons[mwCustomEditButtons.length] = { "imageFile": base_url + "skins/common/images/button_redirect.png", "speedTip": "Redirect", "tagOpen": "#REDIRECT [[", "tagClose": "]]", "sampleText": "Insert text"}; mwCustomEditButtons[mwCustomEditButtons.length] = { "imageFile": base_url + "skins/common/images/button_strike.png", "speedTip": "Strike", "tagOpen": "", "tagClose": "", "sampleText": "Strike-through text"}; mwCustomEditButtons[mwCustomEditButtons.length] = { "imageFile": base_url + "skins/common/images/button_enter.png", "speedTip": "Line break", "tagOpen": "
", "tagClose": "", "sampleText": ""};/*
mwCustomEditButtons[mwCustomEditButtons.length] = { "imageFile": base_url + "skins/common/images/button_upper_letter.png", "speedTip": "Superscript", "tagOpen": "", "tagClose": "", "sampleText": "Superscript text"}; mwCustomEditButtons[mwCustomEditButtons.length] = { "imageFile": base_url + "skins/common/images/button_lower_letter.png", "speedTip": "Subscript", "tagOpen": "", "tagClose": "", "sampleText": "Subscript text"}; mwCustomEditButtons[mwCustomEditButtons.length] = { "imageFile": base_url + "skins/common/images/button_small.png", "speedTip": "Small", "tagOpen": "", "tagClose": "", "sampleText": "Small Text"};
- /
mwCustomEditButtons[mwCustomEditButtons.length] = { "imageFile": base_url + "skins/common/images/button_hide_comment.png", "speedTip": "Insert hidden comment (HTML comment)", "tagOpen": "", "sampleText": "Comment"};mwCustomEditButtons[mwCustomEditButtons.length] = { "imageFile": base_url + "skins/common/images/button_hide_comment.png", "speedTip": "Insert hidden content (hidden div)","tagOpen": "", "tagClose": "","sampleText": ""};/*
mwCustomEditButtons[mwCustomEditButtons.length] = { "imageFile": base_url + "skins/common/images/button_gallery.png", "speedTip": "Insert a picture gallery","tagOpen": "\n",
\n", "tagClose": "\n"sampleText": "Image:Example.jpg|Caption1\nImage:Example.jpg|Caption2"};
- /
mwCustomEditButtons[mwCustomEditButtons.length] = { "imageFile": base_url + "skins/common/images/button_media.png", "speedTip": "Web source", "tagOpen": "{" + "{cite web| url = ", "sampleText": "", "tagClose": "| title = | author = | date = | accessdate = 2007-05-11 11:18 | license = | other =}}\n" };mwCustomEditButtons[mwCustomEditButtons.length] = { "imageFile": base_url + "skins/common/images/button_media.png", "speedTip": "Web citation", "tagOpen": "{" + "{cite web| url = | title = | author = | date = | accessdate = 2007-05-11 11:18| license = }}\n{" + "{quotation}}\n", // | exact=?| excerpt=? "sampleText": "", "tagClose": "\n{" + "{end quotation}}\n" }; mwCustomEditButtons[mwCustomEditButtons.length] = { "imageFile": base_url + "skins/common/images/button_blockquote.png", "speedTip": "Exact or near-exact quote", "tagOpen": "{" + "{quotation}}\n", //| exact=?| excerpt=? "tagClose": "\n{" + "{end quotation}}", "sampleText": ""};// mwCustomEditButtons[mwCustomEditButtons.length] = { // "imageFile": base_url + "skins/common/images/button_blockquote.png", // "speedTip": "Paraphrase, derived/modified version of quote", // "tagOpen": "{" + "{quotation| modified=true| excerpt=?}}\n", // "tagClose": "\n{" + "{end quotation}}", // "sampleText": ""};
mwCustomEditButtons[mwCustomEditButtons.length] = { "imageFile": base_url + "skins/common/images/button_blockquote.png", "speedTip": "Thread / conversation / group of quotes", "tagOpen": "{" + "{thread}}\n", "tagClose": "\n{" + "{end thread}}", "sampleText": ""};mwCustomEditButtons[mwCustomEditButtons.length] = { "imageFile": base_url + "skins/common/images/button_blockquote.png", "speedTip": "Comment (from a blog, etc.)", "tagOpen": "{" + "{comment | author = | date = | url = }}\n", "tagClose": "\n{" + "{comment end}}", "sampleText": ""};// {mine /* Not necessary if you patch the parser to fix the bug...
mwCustomEditButtons[mwCustomEditButtons.length] = { "imageFile": base_url + "skins/common/images/button_blockquote.png","speedTip": "Block of quoted text that can contain paragraphs ()", "tagOpen": "
",\n", "tagClose": "\n
"sampleText": ""};
- /
// }mine
mwCustomEditButtons[mwCustomEditButtons.length] = { "imageFile": base_url + "skins/common/images/button_insert_table.png", "speedTip": "Insert a table", "tagOpen": '{| class="wikitable"\n|-\n', "tagClose": "|-\n| \n| \n| \n|}", "sampleText": "! \n! \n! \n"};// Custom:
mwCustomEditButtons[mwCustomEditButtons.length] = { "imageFile": base_url + "skins/common/images/button_link.png", "speedTip": "underlined text", "tagOpen": "", "tagClose": "", "sampleText": ""};mwCustomEditButtons[mwCustomEditButtons.length] = { "imageFile": base_url + "skins/common/images/button_blockquote.png","speedTip": "preformatted (fixed-width) text ()", "tagOpen": "<pre>\n", // "tagClose": "\n</pre>", // // "sampleText": "" }; mwCustomEditButtons[mwCustomEditButtons.length] = { "imageFile": base_url + "skins/common/images/button_blockquote.png", "speedTip": "Block of console (command-line/shell) commands and/or output", "tagOpen": "<pre class=\"console\">\n", "tagClose": "\n","sampleText": "" }; mwCustomEditButtons[mwCustomEditButtons.length] = { "imageFile": base_url + "skins/common/images/button_blockquote.png", "speedTip": "Block of Ruby code","tagOpen": "\n", "tagClose": "\n","sampleText": "" };mwCustomEditButtons[mwCustomEditButtons.length] = { "imageFile": base_url + "skins/common/images/button_math.png", "speedTip": "preformatted (fixed-width) text ()", "tagOpen": "", "tagClose": "", "sampleText": ""};/*
mwCustomEditButtons[mwCustomEditButtons.length] = { "imageFile": base_url + "skins/common/images/button_redirect.png", "speedTip": "unordered list item (*)", "tagOpen": "*", "tagClose": "\n", "sampleText": ""};mwCustomEditButtons[mwCustomEditButtons.length] = { "imageFile": base_url + "skins/common/images/button_redirect.png", "speedTip": "ordered list item (#)", "tagOpen": "#", "tagClose": "\n", "sampleText": ""};
- /
if (include_advanced_icons) {
mwCustomEditButtons[mwCustomEditButtons.length] = { "imageFile": base_url + "skins/common/images/button_italic.png", "speedTip": "(wrap in parentheses)", "tagOpen": "(", "tagClose": ")", "sampleText": "" };mwCustomEditButtons[mwCustomEditButtons.length] = { "imageFile": base_url + "skins/common/images/button_italic.png", "speedTip": "Template:Wrap in template delimiters", "tagOpen": "{{", "tagClose": "}}", "sampleText": "" };} // if (include_advanced_icons)
mwCustomEditButtons[mwCustomEditButtons.length] = { "imageFile": base_url + "skins/common/images/button_link.png", "speedTip": "Add this page to a category", "tagOpen": "[[Category:", "tagClose": "]]", "sampleText": "" };if (include_advanced_icons) {
mwCustomEditButtons[mwCustomEditButtons.length] = { "imageFile": base_url + "skins/common/images/button_link.png", "speedTip": "Add this *section* to a category", "tagOpen": "{" + "{section category|", "sampleText": "", "tagClose": "}}" };mwCustomEditButtons[mwCustomEditButtons.length] = { "imageFile": base_url + "skins/common/images/button_link.png", "speedTip": "Make this into a *keyword* (adds it as a category)", "tagOpen": "{" + "{keyword|", "sampleText": "", "tagClose": "}}" };
} // if (include_advanced_icons)mwCustomEditButtons[mwCustomEditButtons.length] = { "imageFile": base_url + "skins/common/images/button_link.png", "speedTip": "This page has an associated category", "tagOpen": "{" + "{Has associated category|}}" };mwCustomEditButtons[mwCustomEditButtons.length] = { "imageFile": base_url + "skins/common/images/button_link.png", "speedTip": "Meta information", "tagOpen": "{"+"{meta}}\n", "sampleText": "", "tagClose": "{"+"{meta end}}" };/*
mwCustomEditButtons[mwCustomEditButtons.length] = { "imageFile": base_url + "skins/common/images/button_extlink.png", "speedTip": "Link to wikipedia", "tagOpen": "[[w:", "tagClose": "]]", "sampleText": ""};
- /
mwCustomEditButtons[mwCustomEditButtons.length] = { "imageFile": base_url + "skins/common/images/button_nowiki.png", "speedTip": "", "tagOpen": "<nowiki>", "sampleText": "", "tagClose": "" };if (include_advanced_icons) {
mwCustomEditButtons[mwCustomEditButtons.length] = { "imageFile": base_url + "skins/common/images/button_nowiki.png", "speedTip": "<"+"includeonly>", "tagOpen": "<"+"includeonly>", "sampleText": "", "tagClose": "<"+"/includeonly>" };mwCustomEditButtons[mwCustomEditButtons.length] = { "imageFile": base_url + "skins/common/images/button_nowiki.png", "speedTip": "<"+"noinclude>", "tagOpen": "<"+"noinclude>\n", "sampleText": "", "tagClose": "\n<"+"/noinclude>" };} // if (include_advanced_icons)
} // if (mwCustomEditButtons)
/*
- /
//
/* Any JavaScript here will be loaded for all users on every page load. */ //Modifications that I made to code copied from http://en.wikipedia.org/wiki/MediaWiki:Common.js:
- change <s> tag to <del> tag because <s> tag is apparently deprecated.
For your change to MediaWiki:Common.js to take effect, I found I had to touch includes/EditPage.php . Interesting. Must force that file to be reloaded; otherwise it was pulling it from a cache.
In addition, I make these in-place modifications to the code in function
getEditToolbar()in./includes/EditPage.phpnear 1431// Added: array( 'image'=>'button_headline.png', 'open' => "\\n=", 'close' => "=\\n", 'sample'=> wfMsg('headline_sample'), 'tip' => 'Level 1 headline', 'key' => '' ), // Removed extra spaces in open and close: array( 'image'=>'button_headline.png', 'open' => "\\n==", 'close' => "==\\n", 'sample'=> wfMsg('headline_sample'), 'tip' => 'Level 2 headline', 'key' => 'H' ), // Added: array( 'image'=>'button_headline.png', 'open' => "\\n===", 'close' => "===\\n", 'sample'=> wfMsg('headline_sample'), 'tip' => 'Level 3 headline', 'key' => '' ), array( 'image' =>'button_sig.png', 'open' => '~~~~', 'close' => '', 'sample'=> '', 'tip' => wfMsg('sig_tip'), 'key' => 'Y' ),[edit] To do
http://en.wikipedia.org/wiki/User:MarkS/Extra_edit_buttons !!!
