MediaWiki talk:Common.js/Archive 2

From Wikipedia, the free encyclopedia
Jump to: navigation, search

Main Page Hack

For the main page hack that removes stuff on the main page, why not just use the page title mentioned in the HTML header of every page?

For example, this was on this page in the html sourcecode:

                <script type= "text/javascript">
                        var skin = "monobook";
                        var stylepath = "/skins-1.5";

                        var wgArticlePath = "/wiki/$1";
                        var wgScriptPath = "/w";
                        var wgServer = "http://en.wikipedia.org";
                        
                        var wgCanonicalNamespace = "MediaWiki_talk";
                        var wgPageName = "MediaWiki_talk:Monobook.js";
                        var wgTitle = "Monobook.js";
                        var wgArticleId = 725652;
                        
                        var wgUserName = "GeorgeMoney";
                        var wgUserLanguage = "en";
                        var wgContentLanguage = "en";
                </script>
                               

.

GeorgeMoney (talk) 22:03, 4 August 2006 (UTC)

We in Kazakh wiki use like:
// BEGIN Remove weird mainPage titling
// var wgPageName - from global variables on HTML header of every page
var isMainPage = (wgPageName == "Main_Page");
var isDiff = (document.location.search && (document.location.search.indexOf("diff=") != -1 || document.location.search.indexOf("oldid=") != -1));

if (isMainPage && !isDiff) 
{
 document.write('<style type="text/css">/*<![CDATA[*/ #lastmod, #siteSub, #contentSub, h1.firstHeading { display: none !important; } /*]]>*/</style>');
}

//Main page tab no longer says article
function mainpg() {
      if ((isMainPage || /[\/=:]Main_Page/.test(document.location)) && document.getElementById('ca-nstab-main')) {
            document.getElementById('ca-nstab-main').firstChild.innerHTML = 'Main Page';
      }   
}
addOnloadHook(mainpg);

--AlefZet 11:17, 17 August 2006 (UTC)


Main Page Hack, pII

Is javascript even needed for some of this anymore? Per rev:17119 there is now a css class for each page. The following, hypothetically, could be added to MediaWiki:Monobook.css:

body.page-Main_Page #lastmod, 
body.page-Main_Page #siteSub, 
body.page-Main_Page #contentSub, 
body.page-Main_Page h1.firstHeading { display: none !important; }

As this section is UNDOCUMENTED and UNMAINTAINED, perhaps it should be removed and started over, with appropriate use of the javascript variables, as well as taking advantage of per-page CSS support. IMHO --Splarka (rant) 07:39, 17 December 2006 (UTC)

I support this. Many browsers that have javascript disabled probably do not have css disabled. I have not used any browser that lets you disable CSS (if it has CSS in the first place) so the amount of users affected by this "hack" will be higher. It would also be much cleaner and easier to update by moving it to the monobook.css file. GeorgeMoney (talk) 01:54, 18 December 2006 (UTC)

History and 'My Contributions'

I'm not sure if this is the right place to report this, but the worst that can happen is someone will say 'This isn't the right place to post this'. Anyway, I'm using Internet Explorer 6, and the content boxes on the history pages, and 'My Contributions' are compressed so that I can't see the text. I'm wondering if this is a problem that everyone with Internet Explorer 6 gets, and if this is something that can be fixed here?--Jcvamp

Erm, I don't know, but try Wikipedia:Village pump (technical). Snoutwood 21:23, 10 January 2007 (UTC)

Accesskey for project page

Please change ta['ca-nstab-wp'] = new Array('c','View the project page'); to ta['ca-nstab-project'] = new Array('c','View the project page');. That is the name of the Project tab. Thank you. --Thunderhead 09:21, 16 August 2006 (UTC)

Also, ca-article is the name for the Special page tab, not ca-nstab-special. --Thunderhead 09:24, 16 August 2006 (UTC)

Done, thanks for the note. -- Jitse Niesen (talk) 10:46, 16 August 2006 (UTC)
Thank you. --Thunderhead 15:33, 16 August 2006 (UTC)

Popup table generator

fr.wikipedia.org uses a nice hack in its monobook.js to add a toolbar button which opens a little popup window to ask for table dimensions, and to insert the table as wikitext into the edit box. Try it out by editing a page and clicking the table button (first from the left). Should we copy this idea?--Eloquence* 14:14, 25 August 2006 (UTC)

Well, if there is no objections to this, we should try it out. I do not see any harm in doing this as well. --Siva1979Talk to me 05:25, 26 August 2006 (UTC)
Actually much of the stuff here[1] would be very useful for basic editing too.Voice-of-All 10:12, 26 August 2006 (UTC)
I've implemented all of these.Voice-of-All 19:13, 24 September 2006 (UTC)

Reference navbar

See [2]. Within these scripts there is also a simple script ("Reference divs") that makes the auto-generated references appear with a scrollbar so that they won't take up so much room. I'd like to add this here.Voice-of-All 10:05, 26 August 2006 (UTC)

Default hide/show for NavFrame

(following up from Wikipedia:Village pump (technical)/Archive 132#Template:Hidden - Auto Show/Hide)

I coded up a replacement for the createNavigationBarToggleButton function at MediaWiki:Monobook.js which allows one to specify if the box should be open or closed by default. It can be found at [3] if you want to check the code. Once it's added to Monobook.js (replacing the function already there), using NavFrameDefaultHide instead of NavFrame will force the box to be hidden by default, and using NavFrameDefaultShow instead of NavFrame will force the box to be shown by default. I intend to add the code to Monobook.js in a few days if nobody complains. --cesarb 16:59, 2 September 2006 (UTC)
Hold on. Two months ago I proposed a more general enhancement to the functionality of the navigation bars above; test code is here, sandbox here. My code is currently written with different class names. The idea was to allow alternate texts for the button (implemented with the "title" attribute), and to allow "inline" dynamic nav content. I would really like to see some work on getting this functionality implemented.
On defaults, I don't think it's a good idea to build the show-default into the name of the header class; in my test code I indicate a show-default through a separate class used in addition to the header class. Gimmetrow 17:58, 2 September 2006 (UTC)


Where the hell are the docs for all of the NavFrame stuff? I've been searching for about 45 minutes now. Michael Z. 2006-10-31 04:01 Z

oh no!

The new "section 0 edit link" is really ugly and messes up alot of pages pushing text a long way. It is really obtrusive and messes with already installed scripts.

If you do want to add one please add it higher so it doesn't mess up anything else and remove that part from the monobook.css you can add it to the div's style.

Why not use Wikipedia:WikiProject User scripts/Scripts/Edit Top which is much better coded and more stable, and doesn't intrude.

This really messes everything up, especially userpages and some articles.

GeorgeMoney (talk) 01:21, 3 September 2006 (UTC)

OK, it was removed for now. Let's see what other people say. —Mets501 (talk) 01:32, 3 September 2006 (UTC)

Using an older version of Safari, this turned most article text smaller and gray, and also caused some sentences to look like a hyperlink (but when clicked they went nowhere). Seems better after the revert. Carl Lindberg 01:34, 3 September 2006 (UTC)

Yes, this new code created links in some odd places on some pages (in Safari 2.0.4). However, Edit Top, which I have been using, doesn't have a look consistent with the other edit tabs. I agree this should be part of the site software, however it also shouldn't be beta tested live on the site. I've been asking for two months to have my own codes tested and rolled in... Gimmetrow 01:46, 3 September 2006 (UTC)
I've tried the updated version of Edit Top and the edit tab seems to be consistent with the others on the page. The edit link is showing up on diff and history pages, however. Gimmetrow 03:53, 3 September 2006 (UTC)
Well, for reference, here is the old Edit Top script:
function edittop() {
  if(document.getElementById("wikiPreview") || window.location.href.indexOf("/wiki/Special:") != -1) return;
  var pageTitle = document.title.split(" - ")[0].replace(" ", "_"); 
  var divContainer = document.createElement("div");
  divContainer.innerHTML = '<div class="editsection" style="float:right;margin-left:5px;margin-right:15px;margin-top:3px;">[<a href="'+phpurl+pageTitle+'&action=edit&section=0" title="'+document.title.split(" - ")[0]+'">edit top</a>]</div>';
  if(window.location.href.indexOf("&action=edit") == -1)
    document.getElementById("content").insertBefore(divContainer, document.getElementsByTagName("h1")[0]);
  if(window.location.href.indexOf("&action=edit&section=0") != -1)
    document.getElementById("wpSummary").value = "/* Intro */ ";
};

GeorgeMoney (talk) 04:04, 3 September 2006 (UTC)

If people really want to do this, it should probably be on the right side of the page above the border-bottom for the headline for the section you will be editing, like the other section-edit edit links are. Personally I would never use it, but from answering help desk questions it does seem to be a point of confusion for at least a few people, some even thinking the top section was some locked section only editable by special people. - cohesion 17:46, 5 September 2006 (UTC)

Helper function for user scripts

I would like this funtion to be included so it's easier for users to include user scripts. —The preceding unsigned comment was added by AzaToth (talkcontribs).

/*Takes the wikipage "page" and includes it's raw text as javascript.*/
function import_external(page){
    if( document.createElement && document.childNodes ) {
        var url = 
            'http://en.wikipedia.org/w/index.php?title=' + 
            page + 
            '&action=raw&ctype=text/javascript';
        var scriptElem = document.createElement('script');
        scriptElem.setAttribute('src',url);
        scriptElem.setAttribute('type','text/javascript');
        document.getElementsByTagName('head')[0].appendChild(scriptElem);
    }
}
  • I don't know, is this generally done for user scripts? The script would break on non-monobook skins, and there is no common site-wide local javascript. Would it be fine if users just added this helper script when they are using scripts that call it? —Mets501 (talk) 18:14, 21 September 2006 (UTC)
    • I think {{subst:js}} covers this. I've seen following used when someone needs to include a lot of scripts. Gimmetrow 23:41, 21 September 2006 (UTC)
/*** [[User:Lightdarkness]]'s include function ***/
function inc (file) {
  var lt = String.fromCharCode(60);
  var gt = String.fromCharCode(62);
  document.writeln(lt+'script type="text/javascript" src="/w/index.php?title='+file+'&action=raw&ctype=text/javascript&dontcountme=s"'+gt+lt+'/script'+gt);
}
    • Off course every one can include it in their own script, but it's more tedious, also most people are using code like the one gimmetrow showed, and that's non optimal in at least two ways. First it will need to be reparsed when written, it is much faster to include it directly in the DOM-tree, second, when using document.writeln, the output will be written to the end of the document, generating a non-compatible page (application/xhtml-xml will bail out on such code generally). AzaToth 23:55, 21 September 2006 (UTC)

New buttons in edit toolbar

Please revert the addition of a ton of extra buttons, if a user wants them they can add them themself but that is truely overkill, i also see no visible consensus asking users if they would like them. thanks/Fenton, Matthew Lexic Dark 52278 Alpha 771 19:17, 24 September 2006 (UTC)

This was brought up here a month ago, without objection. For such a visually minor change, I don't see the problem with adding some small buttons to the toolbar (and it is not bleeding over or anything). The vast majority of people who edit this site do not even know how to just "add them" or that they need an account, and they don't know javascript either. Some of these buttons are badly needed (ie table, which fr. has). Though perhaps a few could be shaved off just for the sake of simplicity.Voice-of-All 19:28, 24 September 2006 (UTC)
Digital_me plans to write a bit of disabling javascript, but I agree with perhaps cutting them down. It is a little mad, and the WYSIWYG will be here reasonably soon. —Xyrael / 19:30, 24 September 2006 (UTC)
Well, I don't think most people would know that there was discussion here. I think that this is a pretty major change, and the discussion should be more publicized. I, for one, oppose them, as they are more unnessecary clutter to the already mostly unused edit toolbar.--digital_me(TalkContribs) 19:31, 24 September 2006 (UTC)
I just trimmed down the options. That should make it better for low-res now.Voice-of-All 19:36, 24 September 2006 (UTC)
To disable the new buttons just add the following to your monobook.js, save, and do a hard refresh (ctrl-F5).
mwCustomEditButtons = false;
--digital_me(TalkContribs) 19:40, 24 September 2006 (UTC)
The table button isn't such a bad idea. But the table code produced by the form popping up needs to be improved. I wouln't want to have newbies entering such ugly defaults for tables. Hey and the template call button wasn't that bad. Too bad it has already been removed again. --Ligulem 19:42, 24 September 2006 (UTC)
I suppose we need to keep these for more bread-and-butter kind of tedious tasks, so that had to go.Voice-of-All 19:50, 24 September 2006 (UTC)
Theres a transclusion button underneath the edit box ;-) thanks/Fenton, Matthew Lexic Dark 52278 Alpha 771 19:45, 24 September 2006 (UTC)
Argh. I forgot my [4]. Thanks :) --Ligulem 19:49, 24 September 2006 (UTC)
The template button on the top of the edit window is better than the "Wiki-markup" section below the edit window. --Ligulem 19:56, 24 September 2006 (UTC)
Then can we get rid of the redundant items in the wiki markup section? Gimmetrow 20:03, 24 September 2006 (UTC)
Agree with that. But could be dangerous. I fear hordes of angry Wikipedians piling at VPT :). Removing things is always delicate... --Ligulem 20:07, 24 September 2006 (UTC)
Many of the buttons are redundant with the wiki markup section, and do we really need a javascript button just to add a ':' ? Gimmetrow 19:46, 24 September 2006 (UTC)
The ":" thing is now removed.Voice-of-All 19:50, 24 September 2006 (UTC)
I'd say it's useful for new editors. On the other hand coloured text (already removed), left-aligned and centered text are not. —Ruud 20:00, 24 September 2006 (UTC)
The : tab is rarely useful to a new editor in article space. By the time an editor runs across a need, they will have seen it on talk pages. Gimmetrow 20:03, 24 September 2006 (UTC)
True. —Ruud 20:09, 24 September 2006 (UTC)

I want to remind people that while these buttons may be very useless to most of us, they are very useful for new editors (who, obviously, have absolutely no clue how to add these buttons to their perosnal monobook.js). —Ruud 19:52, 24 September 2006 (UTC)

I am a fairly experienced WP editor. I still think the new buttons are a big help They are easier to use than the codes below the edit box, and easier than typing (or remembering) code. Individuals can quibble about whether some are more helpful than others, but that is mostly personal preference experssed by people who do know how to edit their perosnal monobook.js. Finell (Talk) 19:16, 26 September 2006 (UTC)

  • hem* The new JS-code looks a bit bad (I thought VoA knows JS). Look some comments from me [[5]] (and my corresponding optimized code here, you can also look at the talkpage). I've completly replaced the function marque_tab() for the table button (after all buttons be added) p.s. I've not read any discussion to this relation before, so you can hint me. --Olliminatore 12:49, 28 September 2006 (UTC)
I mainly copied these from MarkS and they seemed to be fine. If anything can be optimized, then I'd {{sofixit}}.Voice-of-All 15:23, 1 October 2006 (UTC)
I can't do that but you can look my code . Other matter: I think the center, left text align should not be used in normal articles, so remove them from standard of all (maybe <br /> too). --Olliminatore 10:18, 3 October 2006 (UTC)

Table button

I have removed the "add table" button from the toolbar. As a piece of code it is incomplete (the popup it generates is awful), and the tables it makes are equally poor. If you are going to develop new components, please submit them to the community for review and debugging before adding them to the core javascript. I don't object to have a table generator - but we can do much better than a quick hack. Thanks, ed g2stalk 13:55, 29 September 2006 (UTC)

Here is an example of a good table:

{| class="wikitable" style="margin: 0 auto;" <!-- if centering required -->
|+ TABLE CAPTION <!-- if required -->
|-
! Heading 1
! Heading 2
! Heading 3
|-
| R1C1
| R1C2
| R1C3
|-
| R2C1
| R2C2
| R2C3
|}

Note that all background colour and other styling is (as it should be) done in the stylesheet (.wikitable). Options such as "border width" and "alternate rows" should not be provided. ed g2stalk 14:08, 29 September 2006 (UTC)

As I noted on your talk. That button was already disabled (by me). --Ligulem 14:01, 29 September 2006 (UTC)
Cross post: Hmm, odd. It was still showing up on my toolbar. After my edit I did a hard refresh and it went away - so unless my cache was two days old (possible) - your commenting might not have been enough. Anyway, no harm done. ed g2stalk 14:04, 29 September 2006 (UTC)
Cross post: :Yes, you did have had an outdated cache, as the button already went away thanks to my edit. I'm going to revert your edit, if you don't mind. We either disable that code on the top-most level (as I did it with my edit), or we remove that stuff completely. Keeping some brain dead code there serves not much purpose. --Ligulem 14:08, 29 September 2006 (UTC)
First a simple IE detector need to be added. If a user is using IE, then the button should be disabled. As for table appearance, anyone is welcome to fix it with something that looks prettier.Voice-of-All 20:01, 30 September 2006 (UTC)
My mentioned version has that feature, for IE (Opera too) the button makes only table sample syntax (from MarkS). (p.s. I don't tested IE for window open, because this function also don't works with my expanded function method) --Olliminatore 20:26, 30 September 2006 (UTC)
Ok I simplified the code, and it does not seem to crash IE either. The talble now uses the pretty and simple wikiclasses.Voice-of-All 20:33, 30 September 2006 (UTC)
You forgot to remove ''' ''' from TABLE CAPTION and |----- to |- --Olliminatore 10:37, 1 October 2006 (UTC)
It crashed my version of IE (IE 6) about 5 minutes ago. Someone who know how should definitely disable the button in IE until the problem is fixed. (It doesn't always crash IE, just sometimes; it's worked for me before, so testing it once in IE isn't enough to indicate the end of the problem.) 147.188.147.47

Why not just the standard control for generating a table you get in word editors, like this? That's just a demo I knocked up in half an hour, but you get the idea. ed g2stalk 11:08, 2 October 2006 (UTC)

Wow. Cool! --Ligulem 11:20, 2 October 2006 (UTC)
Yes, that looks cool, can "you" make this function (with headline and item column option) to a corresponding popup window? That would be it. --Olliminatore 15:45, 4 October 2006 (UTC)

Archive

Just a note to all. I have archived some of the contents of this page. If anyone has any objects over this, please feel free to state your concerns. --Siva1979Talk to me 04:38, 25 September 2006 (UTC)

Page not found

I propose we add:

addOnloadHook(function(){
if(document.getElementById('noarticletext')) {
var pgs = wgPageName.replace(/_/g, " ");
document.title = pgs+" - Page Not Found - Wikipedia, the free encyclopedia";
document.getElementById('searchInput').value = pgs;
}
});

Which does:

  • Adds a "page not found" message to the page title (which is pretty useful, because sometimes I open many pages in tabs and want to know if any are non-existant)
  • And adds the page title into the search box just incase someone typed something wrong and wants to fix their mistake.

GeorgeMoney (talk) 05:56, 28 September 2006 (UTC)

Both of these should be submitted to bugzilla as enhancements and implemented in PHP, not JavaScript hacks. ed g2stalk 21:38, 7 October 2006 (UTC)

addLoadEvent versus addOnloadHook

Is there a reason that the code here doesn't use addOnloadHook that's defined in wikibits.js? Instead, addLoadEvent is defined and used. They would seem to do the same thing, but I might be missing a difference since I'm not very knowledgeable about JS. --68.142.14.91 14:59, 28 September 2006 (UTC)

I think the sequencing is in some cases, sensitive and decisively. --Olliminatore 10:11, 3 October 2006 (UTC)

Toolbar extras

The extra buttons in the toolbar, though useful, are causing serious lag in the edit page load time. I first tried adding these extra buttons (stolen from the Hebrew Wikipedia) several months back, and noticed the problem then, as did others. The problem still exists. Currently, for me at least, the toolbar takes 5+ seconds to load. — BRIAN0918 • 2006-10-11 02:25Z

I've never had them take 5 seconds, odd.Voice-of-All 04:50, 11 October 2006 (UTC)
Me neither. IIRC I noticed a very minor lag the first time they had to load (but far below 5 seconds). Since then, they are in the cache of my Firefox 1.5.0.7 (Windows XP) and everything loads immediately (I still have them right now even though they have been removed already by Brian0918, because I didn't force a cache update yet). --Ligulem 08:42, 11 October 2006 (UTC)
These should really be added back. The toolbar can be disabled via prefrences. Many other wikipedias, like RU and FR, already have such buttons. I don't see a need to remove a few very useful sitewide buttons due to one user having them take too long to load.Voice-of-All 16:21, 15 October 2006 (UTC)
Does the loading of the toolbar prevent editing? If not I don't see a problem with it loading so slowly. Even the standard toolbar can take 2 or 3 seconds to load when I'm running BitTorrent in the background. —Ruud 16:35, 15 October 2006 (UTC)
No, it just loads in the background. Actually, the bar loads near instantly, its the images that take a while sometimes, but it does not hang the page or anything, they just appear one by one.Voice-of-All 16:39, 15 October 2006 (UTC)
Please restore the extra buttons. They were very helpful. I experienced no delay in the edit box opening, and did not notice any delay in the button graphics being rendered (but a 5-second delay in that, if there was one, would not delay my editing). Finell (Talk) 07:22, 16 October 2006 (UTC)
I agree: Bring back the buttons! They are very useful, and the only delay present is caused by loading the images. Albany NY 13:22, 16 October 2006 (UTC)

I propose we add the buttons back and post a message on WP:VPT and WP:AN if anyone is experiencing the problems Brian0918 describes. Non-instantaneous loading should only happen sporadically when the images have disappeared from the browser cache, however it might also be possible that the Javascript executes too slowly one some computer/browser configurations. —Ruud 17:39, 16 October 2006 (UTC)

There is a strong concensus, in this and another item on this Talk page, for restoring the additional edit toolbar buttons. Will it be done? Finell (Talk) 20:57, 26 October 2006 (UTC)

I'd like for someone to add them back soon.Voice-of-All 22:45, 1 November 2006 (UTC)

Not a fan. Makes finding the few useful buttons (sig and redirect) harder. But I appear to be in the minority, so how can I remove these from my monobook? Should the "mwCustomEditButtons = false;" thing still work? --Spangineerws (háblame) 22:35, 4 November 2006 (UTC)

Seems to work, except that it doesn't remove the "make table" button. —Ruud 23:22, 5 November 2006 (UTC)

Firefox 2.0

The access keys don't work in the newly released Firefox 2.0 :( 555pt | msg | msg on w:pt 04:27, 24 October 2006 (UTC)

Use the Shift key as well. --TheParanoidOne 09:34, 24 October 2006 (UTC)
Er... Shift? If I press Shift+P in a edit box I get the P, not the preview page o.0 555pt | msg | msg on w:pt 17:27, 24 October 2006 (UTC)
You missed the "as well" part. Normally your would type Alt+P but with FF2 you need to do Shit+Alt+P. --TheParanoidOne 19:14, 24 October 2006 (UTC)

Collapsible tables fix for IE

Please make this change so that collapsible tables will display correctly in Internet Explorer:

Line 278: Line 278:
  var ButtonText = document.createTextNode( collapseCaption );   var ButtonText = document.createTextNode( collapseCaption );
       
- Button.setAttribute( "style", "float: right;" ); + Button.style.styleFloat = "right";
    + Button.style.cssFloat = "right";
  ButtonLink.setAttribute( "id", "collapseButton" + tableIndex );   ButtonLink.setAttribute( "id", "collapseButton" + tableIndex );
  ButtonLink.setAttribute( "href", "javascript:collapseTable(" + tableIndex + ");" );   ButtonLink.setAttribute( "href", "javascript:collapseTable(" + tableIndex + ");" );
Notes
  • Original code: Setting the style attribute works in Mozilla, but IE forgets it. The result was that the triangle appeared immediately to the left of the header text in IE.
  • Patched code: Assigning the style as an attribute forces IE to remember that the element should be floated. Mozilla ignores "styleFloat" and will still display the triangle correctly; IE ignores "cssFloat" and will still display the triangle correctly.[6]
  • I have tested this patch on a local, bleeding-edge copy of MediaWiki from SVN using IE6 and Ffx2: no browser recorded a javascript error.
  • From my experience coding this and the above source, I believe that this patch will work on all browsers.

—Cheers, DavidHOzAu 05:58, 7 November 2006 (UTC)

I "committed" your patch. —Ruud 19:41, 7 November 2006 (UTC)

pl.wiki edit summaries

What do people think of the pl.wiki's "auto edit summary" thing? (See [7] for example, and try clicking on one of the green boxes below the edit summary field.) Is it worth implementing here? It might encourage people to use edit summaries more, because it'll be very easy to add. It will probably also help newbies who aren't sure what to type in the edit field by giving examples. —Mets501 (talk) 18:22, 7 November 2006 (UTC)

We now have that to some extent, thanks to Automatic edit summaries, which was recently checked in. What the Polish Wikipedia's doing sounds neat, though. – Minh Nguyễn (talk, contribs) 08:06, 20 November 2006 (UTC)

Initial letter is shown capitalized due to technical restrictions

frwiki has implemented a change where if you go to fr:IPod, their javascript hides the {{lowercase}} warning, and just modifies the name at the top of the page to read correctly (and it fails gracefully because the original {{lowercase}} is still shown if javascript is off). I'd like to get this working on enwiki. Many of the templates have been changed, and User:Interiot/js/RealTitle.js is working now, if included from an individual's monobook.js. I've brought up the possibility of including the change in the global monobook.js at Wikipedia:Village pump (technical)#Name technical restrictions workaround. --Interiot 08:28, 16 November 2006 (UTC)

I've implemented several proposed fixes brought up at the village pump and the various Category:Wrong title templates. The code is now more complex, but I believe it does the Right Thing in almost every case. Its operation and downsides are detailed at User talk:Interiot/js/RealTitle.js. If a few more days pass without any issues brought up, I'd like to add it to the global monobook.js. --Interiot 06:17, 21 November 2006 (UTC)
I added this to the common.js now. Now everyone should see that pages like mod_perl, Category:x86 microprocessors, and User:rambot show up with lowercase and underscores as needed (turn off javascript in your browser to see how they were displayed before). Pages like Softimage XSI shouldn't have their main title changed, but should have the title at the very top of the browser (or in the tab) changed. --Interiot 04:18, 24 November 2006 (UTC)

Do you know how much confusion this has caused? And I'm only talking about myself here; think about all the other people that may have been racking their brains out over this. This thing shouldn't be here without more discussion first; if capital letters aren't technically possible for whatever reason, we shouldn't be making adjustments to make article titles look correct. Did nobody think that four people don't speak for everybody that has an account on Wikipedia? I don't want this; I want to see the {{lowercase}} tags in articles as they should appear. Either revert this change and start a new discussion where more people are likely to comment, or give me a way to make article titles look the way I want them to look. JDtalk 20:38, 29 November 2006 (UTC)

You can disable this now by adding disableRealTitle = 1; to your monobook.js. The idea behind hiding {{lowercase}} is that the only reason they're included on articles is because the title displays incorrectly. Once the title displays correctly, the reader doesn't need to be bothered about the internal limitation on that page anymore... is that incorrect? (just to clarify: it still appears on articles that don't have a pasteable title, for instance {{pipe in title}}) As this discussion notes, multiple wikis have taken up this feature before en.wikipedia.org did, and there were a group of people who wanted English Wikipedia to have it earlier. The feature was discussed in numerous places... [8] [9] [10] but I'd be happy to discuss it WP:VPT or elsewhere again if you'd like.
If it's an issue about making sure people are informed, we could update the relevant templates and/or their talk pages to note the details of how/where this works. --Interiot 23:53, 29 November 2006 (UTC)
Out of curiosity, why is the variable called diableRealTitle instead of disableRealTitle (with an s)?
In my opinion, Interiot allowed for enough discussion before making the change. -- Jitse Niesen (talk) 00:25, 30 November 2006 (UTC)
Oops, thanks for noting that. It's been changed to the obviously more correct disableRealTitle. --Interiot 00:57, 30 November 2006 (UTC)
Nicely done, by the way, good work! Seems to work well, and the work's appreciated. Snoutwood (talk) 06:40, 30 November 2006 (UTC)

Copying to MediaWiki:Common.js

According to the Signpost, this page is now deprecated. All of this should be copied to MediaWiki:Common.js, and all of the stuff that we still want to keep specific only to Monobook.js should be added using a skin test with the skin variable. —Mets501 (talk) 21:19, 21 November 2006 (UTC)

Looks like it's already working. (eg. [11] mentions that it's pulling its data from both MediaWiki:Common.js and MediaWiki:Monobook.js). If there's no monobook.js-specific code here, can we just move this page there? --Interiot 21:36, 21 November 2006 (UTC)
I've moved the page, but it doesn't seem to work. Also {{interwiki-all}} seems to be expanded now, I believe it didn't do that before. —Ruud 22:55, 21 November 2006 (UTC)
Does this mean that now we can use show/hide boxes and they will work for everyone using any skin? —Mets501 (talk) 23:49, 21 November 2006 (UTC)

I'm not sure why the page was blanked after being moved over? It seems like it should work better without the blanking. --Interiot 00:02, 22 November 2006 (UTC)

Copied (not moved) the JS back to MediaWiki:Monobook.js for now. If common.js suddenly does start working, the code might be included twice, perhaps with worse sideeffect than having no JS for a while. —Ruud 00:05, 22 November 2006 (UTC)
This edit shows up [12] for me. I think it's working, but maybe needs some waiting time or an action=purge? --Interiot 00:10, 22 November 2006 (UTC)
It now works here as well. —Ruud 00:16, 22 November 2006 (UTC)
Works here too. —Mets501 (talk) 00:22, 22 November 2006 (UTC)

NavigationBarShowDefault

I'd suggest to change the max. before collapsing to 2, or even 3, rather than just on 1 (current NavigationBarShowDefault setting). -- User:Docu

If this is what makes some templates with the show/hide thing in them automatically close, could you revert this please, or tell me how I could make templates that are showing automatically stay hidden? JDtalk 06:45, 1 December 2006 (UTC)
Template:Dynamic navigation box with image has a parameter "STATE=" which collapses them by default. -- User:Docu
Some templates assume the collapse count is either 0 or 1. It's unfortunate, but raising it above 1 will break some behaviour somewhere. Gimmetrow 02:23, 18 December 2006 (UTC)

IE fix?

Exactly what does this do and why isn't it in /skins-1.5/common/IEFixes.js? —Ruud 15:22, 26 November 2006 (UTC)

if (window.showModalDialog && document.compatMode && document.compatMode == "CSS1Compat")
{
  var oldWidth;
  var docEl = document.documentElement;

  function fixIEScroll()
  {
    if (!oldWidth || docEl.clientWidth > oldWidth)
      doFixIEScroll();
    else
      setTimeout(doFixIEScroll, 1);
  
    oldWidth = docEl.clientWidth;
  }

  function doFixIEScroll() {
    docEl.style.overflowX = (docEl.scrollWidth - docEl.clientWidth < 4) ? "hidden" : "";
  }

  document.attachEvent("onreadystatechange", fixIEScroll);
  attachEvent("onresize", fixIEScroll);
}

deprecating addLoadEvent

Should we remove adLoadEvent, as it only duplicates the functionality of addOnloadHook (defined in wikibits.js). This will break the user scripts of a few dozen users. —Ruud 15:51, 26 November 2006 (UTC)

Maybe make it a thin wrapper around the latter at first, and add a comment about it being deprecated. Do the same here and here, and fix the call here. Then contact the users still using it and suggest they change their scripts, and wait a bit. Before finally removing it completely an admin can fix the remaining instances, but it's probably more polite to ask before poking around other people's user scripts. —Ilmari Karonen (talk) 17:42, 26 November 2006 (UTC)

Floating boxes

Why is there no floating box for 'Featured content' in the sidebar? --Eleassar my talk 10:31, 28 November 2006 (UTC)

"Technical restrictions" title fix

I've noticed two problem with this fix, both relating to when a page using it is edited. The first occurs when editing either the whole page or the "0" section. The correcting of the capitalisation occurs, but the "Editing " is not added to the beginning, nor it the "(section)" part for editing the "0" section. The second occurs when editing any other section in which no correction occurs but the "Editing " remains, effectively doing nothing at all.

Example for editing eBay:

Editing: Intended result Actual result
Whole page Editing eBay eBay
Editing "0" section Editing eBay (section) eBay
Editing any other section Editing eBay (section) Editing EBay (section)

Harryboyles 11:13, 5 December 2006 (UTC)

It doesn't happen if you're editing but not previewing the article. But anyway...
What's the best thing to trigger off of, for the script to know it's in editing mode? Is wgIsArticle appropriate? --Interiot 11:17, 5 December 2006 (UTC)
I suggest checking if document.location contains /wiki/ or /w/ at the beginning of the path.
if (document.location.indexOf(wgServer + wgScriptPath + "/") == 0) { // editing mode
   ...
} else { // browse mode
   ...
}
Monobook emits wgServer and wgScriptPath as global javascript variables; I'm not sure if other skins do the same. It might be better to just hard-wire it to http://en.wikipedia.org/w/ in that case. --DavidHOzAu 03:35, 10 December 2006 (UTC)
That catches a lot more than editing (e.g., history, and even articles themselves if a URL like http://en.wikipedia.org/w/index.php?title=EBay is used). For history and diff pages, wgIsArticle is also set to false. If you want to catch only edit pages, perhaps check for "action=edit" and "action=submit" (the latter for previews) in the URL? -- Jitse Niesen (talk) 04:55, 10 December 2006 (UTC)
Ooops, I forgot about page actions. Ok then here's the full-blown code snippet:
if (document.location.indexOf(wgServer + wgScriptPath + "/") == 0) {
  var action_matches = document.location.match( /action=([^&]+)/ );
  var action = (action_matches == null) ? 'view' : action_matches[1];
  switch(action) {
    case 'history':
    case 'print':
    case 'purge':
    case 'render':
    case 'view':
      isPreview = false;
      break;
    case 'submit':
      isPreview = true;
      break;
    default: // nothing to do
      return;
  }
}
// rest of code here
Or something. --DavidHOzAu 01:23, 11 December 2006 (UTC)
Right, it would be good to keep the code as simple as possible. Yes, wgIsArticle's value does vary a bit in history/diff/move/protect/delete, but it doesn't matter what its value is under those situations, because true or false, we can't display the RealTitle in those cases anyway. wgIsArticle's value really only matters when RealTitleBanner is rendered on screen, which is: 1) when viewing an article, and 2) when editing an article, and its value is good in both cases. So wgIsArticle should work fine, I think. --Interiot 01:50, 11 December 2006 (UTC)

NavFrame styles limitation

As it stands right now, NavFrame limits the use of class tags on elements to ONLY the Nav* classes. You cannot do something like class="NavFrame messagebox standard-talk". This is because of the following lines:

           if (NavChild.className == 'NavPic') {
...
           if (NavChild.className == 'NavContent') {
...
           if (NavChild.className == 'NavPic') {
...
           if (NavChild.className == 'NavContent') {
...
       if (NavFrame.className == "NavFrame") {
...
             if (NavFrame.childNodes[j].className == "NavHead") {

Each of these should be changed to regular expression matches, respectively:

           if (NavChild.className.match(/(\s|^)NavPic(\s|$)/)) {
...
           if (NavChild.className.match(/(\s|^)NavContent(\s|$)/)) {
...
           if (NavChild.className.match(/(\s|^)NavPic(\s|$)/)) {
...
           if (NavChild.className.match(/(\s|^)NavContent(\s|$)/)) {
...
       if (NavFrame.className.match(/(\s|^)NavFrame(\s|$)/)) {
...
             if (NavFrame.childNodes[j].className.match(/(\s|^)NavHead(\s|$)/)) {

This will allow us to apply other classes to NavFrame and related elements. ♠ SG →Talk 20:11, 25 December 2006 (UTC)


  • Also, after looking into it further, there seem to be some inconsistencies in the file. Some parts use function hasClass, which is horribly inefficient:
function hasClass( element, className ) {
  var Classes = element.className.split( " " );
  for ( var i = 0; i < Classes.length; i++ ) {
    if ( Classes[i] == className ) {
      return ( true );
    }
  }
  return ( false );
}

It could easily be rewritten as:

function hasClass(element, className) {
  return element.className.match((new RegExp("(\\s|^)"+className+"(\\s|$)")));
}

After making that change, the previous rewrites I mentioned (such as if (NavChild.className.match(/(\s|^)NavPic(\s|$)/)) {) should be reformed (ie. if (hasClass(NavChild, 'NavPic')) {). ♠ SG →Talk 20:43, 25 December 2006 (UTC)

I've modified the collapsible tables to use literal regular expressions (which are faster than dynamically created RegExp-obejcts [13]). I'm having trouble changing NavFrame, though. —Ruud 23:47, 25 December 2006 (UTC)
It's not "horribly inefficient". There are seldom more than 3 spaces in the "class" attribute. Unless you have a performance test showing that there's a problem, this is a premature optimization. Mike Dillon 16:26, 26 December 2006 (UTC)
If we are going to premative optimize a bit more, I would change (foo) to (?:foo) to ansure we cont capture it. AzaToth 16:43, 26 December 2006 (UTC)

I just ran this test (sorry for the size):

See code at User:Mike Dillon/NavFrame test

The results were pretty consistently something like:

  • hasClass1() x 10000: 532 ms
  • hasClass2() x 10000: 818 ms
  • hasClass3() x 10000: 765 ms
  • hasClass4() x 10000: 523 ms

So, the regex version is fastest, but only if you can avoid recompiling it every time. I didn't see a consistent difference between hasClass2 and hasClass3, but hasClass1/4 were always about 30% faster than the others. Feel free to rerun this stuff yourself. The differences between the versions are:

  • hasClass1: Compiles regex, uses reCache to avoid recompiling
  • hasClass2: Compiles regex every time
  • hasClass3: Uses split on space and equality check
  • hasClass4: Compiles regex, uses reCache, avoids an extra function call for regex cache lookup

Another possible version would use indexOf, but I don't think it's worth writing it. Since the number of iterations of this thing will almost certainly be 2 orders of magnitude less than 10000, I can't see this stuff making a huge difference to load time. My feeling is that "hasClass" should remain a function, for convenience, and it should be implemented in the most readable way. Mike Dillon 17:16, 26 December 2006 (UTC)

P.S. I just tested the capture v. no capture versions by adding hasClass5:

function hasClass5 (element, className) {
    return element.className.match(
        new RegExp("(\\s|^)\\Q" + className + "\\E(\\s|$)"));
}

It made no consistent difference. It was a tiny bit faster to avoid the capture, but once again, the scale of this thing makes it moot. That doesn't mean that we shouldn't use the fastest one, it just means it doesn't make a significant difference. Mike Dillon 17:20, 26 December 2006 (UTC)

Just for kicks, I decided to reimplement part of Perl's Benchmark.pm in Javascript:

See code at User:Mike Dillon/NavFrame test or User:Mike Dillon/Scripts/bench.js

Here were the results for running the tests shown above:

  • hasClass1() x 10000: 546 ms
  • hasClass2() x 10000: 737 ms
  • hasClass3() x 10000: 750 ms
  • hasClass4() x 10000: 529 ms
  • hasClass5() x 10000: 737 ms
  Rate hasClass3 hasClass2 hasClass5 hasClass1 hasClass4
hasClass3 13333/s -- -1.8% -1.8% -37.4% -41.8%
hasClass2 13569/s +1.7% -- 0% -35% -39.3%
hasClass5 13569/s +1.7% 0% -- -35% -39.3%
hasClass1 18315/s +27.2% +25.9% +25.9% -- -3.2%
hasClass4 18904/s +29.5% +28.2% +28.2% +3.1% --

-- Mike Dillon 18:07, 26 December 2006 (UTC)

I added the literal regex test as well:

compareAll(10000, {
    "re+cache": function () { hasClass1(test, "a") },
    "re+nocache": function () { hasClass2(test, "a") },
    "split": function () { hasClass3(test, "a") },
    "re+cache+onefunc": function () { hasClass4(test, "a") },
    "re+nocache+capture": function () { hasClass5(test, "a") },
    "re+literal": function () { test.className.match(/(?:^|\s)a(?:$|\s)/) },
});

It is indeed the fastest, coming in at about 10-15% faster than the one-function caching version (hasClass4). However, like I said before, I think the value of having this as a function outweighs the value of having the fastest implementation, given that the order of magnitude is much lower than 10000. Mike Dillon 18:47, 26 December 2006 (UTC)

I've posted all of this code together at User:Mike Dillon/NavFrame test. Mike Dillon 18:49, 26 December 2006 (UTC)

Cool! (Even though the outcome doesn't really surprise me.) I initially planned to comment on the "horrible inefficiency" of my hasClass function, but then decided I did like the elegance of regular expressions in JavaScript. —Ruud 20:11, 26 December 2006 (UTC)
What do you think about using a version of "hasClass" with the regex caching? Mike Dillon 20:23, 26 December 2006 (UTC)
At the risk of sounding like I'm talking to myself... I've removed the previous code samples out of this discussion. You can see them at User:Mike Dillon/NavFrame test. The summary is that the testing results consistently show the following performance order:
  1. Constant regex (Ruud's version)
  2. hasClass() implemented with regex cache (my version, a.k.a. hasClass4)
  3. hasClass() implemented with split (old version, a.k.a. hasClass3)
  4. hasClass() implemented with regex and no cache (SG's version, a.k.a. hasClass2)
There was a little variance in whether the split or uncached regex version were faster, but in most of my test runs the split version was faster than SG's version (one of the results shown above was an exception to this). I'm obviously partial to my version, because it is fast enough compared to the constant regex version and allows the function to be reused. Mike Dillon 20:21, 26 December 2006 (UTC)
Since this stuff is obviously browser specific, I tested this again in Firefox 2.0 (I was using Galeon/Mozilla 1.7). In Firefox, the split version is consistently the slowest. The caching versions are always faster than the non-caching versions and the constant regex is always fastest. Mike Dillon 20:28, 26 December 2006 (UTC)
This is way cool! Good jobs! --ChoChoPK (球球PK) (talk | contrib) 05:03, 27 December 2006 (UTC)
Thanks! After a discussion on Ruud's talk page, I'm pretty sure I figured out the problem he was having with the regex matching code for the NavFrame structures. I believe the issue was that the code was calling ".className.match()" on all the child nodes of the NavFrame and some of them were text nodes, not elements (which means they don't have ".className"). For me, this is yet another reason to retain the hasClass() function instead of using constant regexes. Mike Dillon 16:05, 27 December 2006 (UTC)

Long response

Ah, great tests! I believe I did exaggerate in saying that the function is slow, so I apologize for that. Good move with the cache idea and ?:; your function is quite superior to mine.

Failure

However, actually testing the result of your regular expression ALWAYS returns false/null. This is due to using quote: \Q...\E. As far as I know, JavaScript regexp does not support this. That's alright, though, because valid classNames never contain any metacharacters (except -, which is useless without []).

Optimized optimization

I ran some tests of my own, and optimized your function. I created four variations, but only one of them turned out faster than yours:

var hasClass9 = (function () {
    var reCache = {};
    return function (element, className) {
        return (reCache[className] ? reCache[className] : (reCache[className] = new RegExp("(?:\\s|^)" + className + "(?:\\s|$)"))).test(element.className);
    };
})();

Now, on average, Internet Explorer 6/7 and Firefox 2.0 show no difference whatsoever between my function and yours, so I'll just show one of IE7's results, while skipping a few of the slow ones (note: in Firefox, I had to test each function one at a time; it seems Firefox executes scripts slower as they progress, I assume this is a memory issue as Firefox has always had): Edit: These Internet Explorer 7 results are from before I removed \\Q...\\E. Strangely enough, after cleaning that out, Internet Explorer started running onefunc9 faster than onefunc4. Weird!

  1. re+cache x 10000: 441 ms
  2. split x 10000: 611 ms
  3. re+literal x 10000: 420 ms
  4. re+cache+onefunc4 x 10000: 351 ms
  5. re+cache+onefunc9 x 10000: 351 ms
Internet Explorer 7 Rate split re+cache re+literal re+cache+onefunc4 re+cache+onefunc9
split 16367/s -- -38.5% -45.5% -74.1% -74.1%
re+cache 22676/s +27.8% -- -5% -25.6% -25.6%
re+literal 23810/s +31.3% +4.8% -- -19.7% -19.7%
re+cache+onefunc4 28490/s +42.6% +20.4% +16.4% -- 0%
re+cache+onefunc9 28490/s +42.6% +20.4% +16.4% 0% --

Ah, but then I tested it on Safari and Opera -- and trust me, I'm as surprised as you:

  1. re+cache x 10000: 403 ms
  2. split x 10000: 494 ms
  3. re+literal x 10000: 411 ms
  4. re+cache+onefunc4 x 10000: 362 ms
  5. re+cache+onefunc9 x 10000: 277 ms
Safari Rate split re+cache re+literal re+cache+onefunc4 re+cache+onefunc9
split 20243/s -- -20.2% -22.6% -36.5% -78.3%
re+cache 24331/s +16.8% -- -2% -13.5% -48.4%
re+literal 24814/s +18.4% +1.9% -- -11.3% -45.5%
re+cache+onefunc4 27624/s +26.7% +11.9% +10.2% -- 30.7%
re+cache+onefunc9 36101/s +43.9% +32.6% +31.3% 23.5% --

Opera is even crazier, look at how fast it does the split function:

  1. re+cache x 10000: 260 ms
  2. split x 10000: 190 ms
  3. re+literal x 10000: 231 ms
  4. re+cache+onefunc4 x 10000: 240 ms
  5. re+cache+onefunc9 x 10000: 150 ms
Opera 9 Rate re+cache re+cache+onefunc4 re+literal split re+cache+onefunc9
re+cache 38462/s -- -8.3% -12.6% -36.8% -73.3%
re+cache+onefunc4 41667/s +7.7% -- -3.9% -26.3% -60%
re+literal 43290/s +11.2% +3.8% -- -21.6% -54%
split 52632/s +26.9% +20.8% +17.7% -- +26.7%
re+cache+onefunc9 66667/s +42.3% +37.5% +35.1% -21.1% --

Better testing

Regardless, this is a highly unrealistic test case. More often than not, we will only be looking for a specific class a few times per page (on a busy talk page, with a few project headers, let's say 1-4). To simulate this, we'll pick a random character each time the function is called (still unrealistic, as we won't be doing 10000 of these with 27 choices). So, instead of searching for "d": String.fromCharCode(97 + Math.round(Math.random() * 25).

With this test in Opera, re+cache+onefunc9 wins every time by 30-40%. re+cache+onefunc4, split and re+cache seem to vary, randomly trading places on each try. re+nocache and re+nocache+capture are a whopping 260% slower than onefunc9.

Firefox shows me that re+cache+onefunc9 bests re+cache+onefunc4 again, but only by about 5-20%. Like Opera, the nocache functions are the slowest, by about 120%.

Internet Explorer is faster than Firefox overall, except that split is the slowest, at around -80%.

Safari showed results similar to Internet Explorer, except split was at -115%.

Whew, sorry for this long comment, but JavaScript is fun! ♠ SG →Talk 01:18, 28 December 2006 (UTC)

By the way, User:SG/NavFrame test. ♠ SG →Talk 01:21, 28 December 2006 (UTC)
Thanks for the catch on \Q...\E. I obviously didn't to any functional testing, just performance testing ;) You're right that the lack of quoting shouldn't be a problem in practice, since valid CSS class names can't contain any metacharacters. I was just being paranoid. Thanks also for the extra testing. So correct me if I'm wrong, but the difference between hasClass4 and hasClass9 is that hasClass9 substitutes an extra array access for an assignment? I reran the same tests on Linux and the no-assign version is faster there too, so I guess we have a winner. Mike Dillon 01:54, 28 December 2006 (UTC)
Yes, it seems pretty weird. It's just that the JavaScript implementations vary widely from browser to browser. Oh, one other thing. In response to the error that occurs when trying to .className.match() on an element which doesn't have className (such as a text node, though you shouldn't be doing that in the first place), a simple if (element.className) could be added, and that prevents the browser from trying to do a match. ♠ SG →Talk 02:13, 28 December 2006 (UTC)
Exactly what I was thinking. I think the value of being able to blindly call hasClass() on everything in .childNodes makes it worth having the .className check in the function.
However, I just realized that another way to avoid this is using RegExp.test(String) instead of String.match(RegExp), just as you did in hasClass9(). I pretty sure that calling test with a null argument isn't ever a problem. That way the extra "if" test isn't done in cases where it isn't needed; the miniscule performance hit only happens if you lazily pass a non-Element node to hasClass(). I'd appreciate it if you could test RegExp.test(null) on the browsers you have access to, but I assume it shouldn't be a problem on any of them. Mike Dillon 02:22, 28 December 2006 (UTC)
You are right. I tested it on IE6/7, FF2, Opera 9 and Safari; none of them report an error. So, I guess we won't be needing that if statement after all. We won't need to accommodate non-elements though, as that would be the fault of the coder, not the function. ♠ SG →Talk 02:40, 28 December 2006 (UTC)
If you mean non-Nodes, I agree. But I think any DOM node, including Text nodes should be testable with this function, for the sake of convenience. Limiting to Element limits usefulness. Mike Dillon 02:43, 28 December 2006 (UTC)
Yes, sorry, non-nodes. It'll work on anything that exists (it'll only throw an error if you try to access element.attribute if element does not exist). Oh, I forgot to mention that this also works on IE5.5, but IE5 fails (for other reasons; .test(null) actually works). ♠ SG →Talk 02:47, 28 December 2006 (UTC)
I hate to ask, but what failed in IE5? I'm pretty sure IE5 is almost negligible these days, but I couldn't find current browser stats for English Wikipedia. Wikipedia:Browsers still had about 16% IE5 in October 2004...
P.S. It looks like you have a faster computer than me :) Mine's a Pentium 4 2.6 GHz running Linux (Fedora Core 5). Mike Dillon 03:08, 28 December 2006 (UTC)
Well, IE5 doesn't support ?:. It really doesn't conform to the regex specs. It also doesn't have array.push, which is used in your test function (but that is easily fixed). It's pointless to support IE5 anymore; approximately 1% of the world's browser usage is IE5.x, of which the majority is 5.5. With IE7 out and already gaining share, there is no reason to even test with IE5 anymore, due to the workarounds required. Wikipedia doesn't render properly in IE5 anyways, and there are plenty of script errors.
Just by guessing, I'd say Wikipedia's IE5.x usage is at 1-3%. Back in October 2004, the world IE5.x share was approximately 12%. Really, that 1-3% is not worth putting in time and effort to make scripts less efficient. They can still access the site, it just renders improperly and most scripts don't work.
As for my computer, well, I'm using a Pentium 4-M 2.2GHz on Windows XP (actually, TinyXP). I'm guessing I have a faster hard drive and/or RAM, seeing as how your CPU is obviously superior to mine. ♠ SG →Talk 04:12, 28 December 2006 (UTC)

hasClass doesn't work with NavFrame

I get the error element has no properties when viewing my sandbox, after which the page is blanked. —Ruud 16:25, 28 December 2006 (UTC)

I'm not getting an error... I guess we could put an if (!element) { return false } inside the inner function of hasClass() just to be safe. It's weird that you're getting that error and I'm not. Mike Dillon 16:42, 28 December 2006 (UTC)
Also, what browser are you testing and where does the page blank? That might give some indication of where the problem is. Mike Dillon 16:44, 28 December 2006 (UTC)
FF 2.0.0.1. I've added a test for a non-existant element, but now NavFrame is broken? (The show/hide button doesn't appear.) —Ruud 17:30, 28 December 2006 (UTC)
I assume this is fixed, am I correct? I don't see an additional if statement and all of the collapsible elements seem to be working in your sandbox. ♠ SG →Talk 19:07, 28 December 2006 (UTC)
Yes, it's fix now [14]. —Ruud 20:25, 28 December 2006 (UTC)

It appears that there was an attempt to assimilate NavFrame with collapsible by this line

var NavigationBarShowDefault = autoCollapse;

where it was previously initialized as 3. The old behavior was 4 or more of NavFrame boxes will be collapsed. So should the line read

var NavigationBarShowDefault = autoCollapse - 1;

?? --ChoChoPK (球球PK) (talk | contrib) 02:33, 29 December 2006 (UTC)

Not according to the comment in the code just above that line, I'll look into it. —Ruud 13:24, 29 December 2006 (UTC)

Too many calls to document.getElementsByTagName()

Since we're on the topic of optimizing Common.js, I looked through all the code and noticed that there are three places that are calling document.getElementsByTagName() on every iteration of a for loop. In these cases, that function should only be called once, before the for loop. I've made a personal copy of Common.js at User:Mike Dillon/MediaWiki:Common.js that shows the changes in the most recent diff. Mike Dillon 18:57, 28 December 2006 (UTC)

Actually, it's faster to only search for getElementsByTagName at each iteration. Why? Because if you do this:
var all = elem.getElementsByTagName('li'); for (...) { ... }

...every time ANY element contained in all is changed even slightly, the entire array has to be updated again. By accessing getElementsByTagName on each iteration, we only update one variable. Here's a good reference:[15]

In most cases, this is faster than caching the NodeList. In the second example, the browser doesn't need to create the node list object. It needs only to find the element at index i at that exact moment.

However, there are some cases where optimization is due, such as:

         for(var j=0; b = document.getElementsByTagName("li")[j]; j++) {

This here, in function LinkFA, is actually searching the entire document for list elements. It should actually only be looking for them in the 'p-lang' element:

document.getElementById('p-lang').getElementsByTagName("li")[j]

Except here, I'm not sure whether or not it's faster to cache p-lang or to look it up every time. Time for more execution speed tests? ♠ SG →Talk 19:32, 28 December 2006 (UTC)

I'm not sure what you're saying here. From what I can see, document.getElementsByTagName("div")[i] searches for all divs and then indexes into the resulting HTMLCollection on each pass. I don't think you can assume that it would optimize that into "look for the i-th div" on each pass. Is that what you're saying? This isn't a caching thing. It's avoiding repeatedly collecting the divs. The HTMLCollection contains a bunch of pointers to nodes, so I don't see what updating the nodes themselves has to do with that. All of the cases I changed are cases of calling getElementsByTagName() on Document, not on an individual element. Mike Dillon 20:46, 28 December 2006 (UTC)
I'm already busy rewriting LinkFA() (which requires a change to {{Link FA}} as well.) —Ruud 20:27, 28 December 2006 (UTC)
I'm getting a "missing name after . operator". I think you need to use ".className" instead of ".class" in the code if ( document.getElementById( InterwikiLinks[i].class + "-fa" ) ) {. Mike Dillon 20:52, 28 December 2006 (UTC)
Indeed, I hate not being able to use Eclipse ;) —Ruud 21:12, 28 December 2006 (UTC)

I just did this quick test in a document with 100 empty divs:

compareAll(1000, {
    "fetch-many": function () {
        var d;
        for (var i = 0; d = document.getElementsByTagName("div")[i]; i++) {
        }
    },
    "fetch-once": function () {
        var d;
        var divs = document.getElementsByTagName("div");
        for (var i = 0; d = divs[i]; i++) {
        }
    },
});

The results were:

  • fetch-many x 1000: 4702 ms
  • fetch-once x 1000: 1305 ms

The result had pretty much the same time profiles in Galeon and Firefox on Linux. Maybe the results will be different in another browser, but I doubt it. Mike Dillon 21:20, 28 December 2006 (UTC)

I just tested with 10 divs and "fetch-once" is still faster:
var body = document.getElementsByTagName("body")[0];
var div = document.createElement("div");
for (var i = 0; i < 10; i++) {
    body.appendChild(div.cloneNode(false));
}

compareAll(1000, {
    "fetch-many": function () {
        var d;
        for (var i = 0; d = document.getElementsByTagName("div")[i]; i++) {
        }
    },
    "fetch-once": function () {
        var d;
        var divs = document.getElementsByTagName("div");
        for (var i = 0; d = divs[i]; i++) {
        }
    },
});
I don't think that the Peachpit article is right. Mike Dillon 21:24, 28 December 2006 (UTC)
The article seems to be assuming that you're manipulating the DOM tree within the loop, such that the content of the NodeList object returned by getElementsByTagName() gets updated deveral times. In that case the method recommended in the article might be faster. In any case, I suspect that an even better solution for such cases would be to copy the content of the NodeList into an ordinary array before the actual DOM-manipulation loop. —Ilmari Karonen (talk) 22:30, 28 December 2006 (UTC)
Go ahead and test it. I'm not sure you're right, since you have to iterate through the whole HTMLCollection followed by the array if you do that, but maybe there's some bookkeeping overhead of iterating through the HTMLCollection while unrelated changes are happening in the DOM. My tests weren't doing any DOM manipulation, so maybe that makes a difference. Mike Dillon 22:34, 28 December 2006 (UTC)

This was easy enough to test, so I did it:

var body = document.getElementsByTagName("body")[0];
var div = document.createElement("div");
for (var i = 0; i < 10; i++) {
    body.appendChild(div.cloneNode(false));
}

var span = document.createElement("div");
compareAll(1000, {
    "fetch-many": function () {
        var d;
        for (var i = 0; d = document.getElementsByTagName("div")[i]; i++) {
            var copy = span.cloneNode(false);
            d.appendChild(copy);
            d.removeChild(copy);
        }
    },
    "fetch-once": function () {
        var d;
        var divs = document.getElementsByTagName("div");
        for (var i = 0; d = divs[i]; i++) {
            var copy = span.cloneNode(false);
            d.appendChild(copy);
            d.removeChild(copy);
        }
    },
    "fetch-copy": function () {
        var d;
        var divs = document.getElementsByTagName("div");

        var divsCopy = new Array();
        for (var i = 0; d = divs[i]; i++) {
            divsCopy.push(d);
        }

        for (var i = 0; d = divsCopy[i]; i++) {
            var copy = span.cloneNode(false);
            d.appendChild(copy);
            d.removeChild(copy);
        }
    },
});

The order was:

  1. fetch-many (slowest)
  2. fetch-once
  3. fetch-copy (fastest)

So, the PeachPit article may be right if there are DOM changes happening, which there are in the NavFrame case. Mike Dillon 22:38, 28 December 2006 (UTC)


Well I'll be damned. I ran some tests of my own; mine modified className instead of the whole DOM tree, I figured it would be more realistic, as that's usually what we do on WP.
  1. fetch-many x 1000: 3245 ms
  2. fetch-copy x 1000: 2113 ms
  3. fetch-once x 1000: 1813 ms

Turns out once is a bit faster, with many being the slowest by far. So your original plan to do

       var d;
       var divs = document.getElementsByTagName("div");
       for (var i = 0; d = divs[i]; i++) { ... }

was right on the money. ♠ SG →Talk 03:09, 29 December 2006 (UTC)

So it seems the conclusion is:
  • Don't call getElementsByTagName() repeatedly.
  • If you need to modify the DOM tree (not just attributes) while looping over the list, make a copy first.
Ilmari Karonen (talk) 06:30, 29 December 2006 (UTC)
I don't know if my tests were totally representative, but I only saw a 5-15% difference when making the copy, so I'd say the copy may be a micro-optimization for the use cases represented in Common.js. We should keep in mind that the copy is a way to optimize code that does heavy DOM manipulation in a loop, but I don't think the extra complexity is warranted except to fix a known performance problem. Mike Dillon 06:37, 29 December 2006 (UTC)
Maybe it's time to start Wikipedia:Javascript as a more long-term place to put performance hints for writing site-wide and personal Javascript. It would be a good place to highlight comparative testing strategies and caveats as well, along with pointers to things like the PeachPit article. Mike Dillon 06:40, 29 December 2006 (UTC)
I have to agree; while copying the nodes is faster, we probably won't be doing it 1000 times per page, so the difference is negligible. For the sake of simplicity, I say we should just list the elements once.
As for a WP:JS project, yes, that does sound like a good idea. Instead of just archiving all of these benchmarks, we could copy the important parts (ie. the speed tables) to various subpages of a WP:JS project. Of course, as much as I like the idea (honestly, a place to store real JavaScript optimization tips -- sign me up!), I wonder how much relevance it has to a WP project.
Though, we COULD always start up an actual JavaScript optimization article (not a guide, but rather a "list" of sorts). ♠ SG →Talk 08:06, 29 December 2006 (UTC)
I guess it could just be part of Wikipedia:WikiProject User scripts, since the people interested in site-wide JS are pretty much here on this talk page. Mike Dillon 19:50, 29 December 2006 (UTC)

Main page fix

rewrote the main page fix as follow:

/** Main Page Append Complete list Link *******************************************************
 *
 *  Description:        Adds a link to the complete list of languages available of the main page.
 *  Maintainers:        [[User:AzaToth]]
 */

if ( wgPageName == 'Main_Page' && wgIsArticle ) {

        // Add a "Complete list" link to the "in other languages" box on the main page,
        // using some very unstable Javscript.
        function mainPageAppendCompleteListLink() {
                try {
                        var node = document.
                                getElementById( "p-lang" ).
                                getElementsByTagName('div')[0].
                                getElementsByTagName('ul')[0];

                        var strongNode = document.createElement( 'strong' );
                        var aNode = document.createElement( 'a' );
                        var liNode = document.createElement( 'li' );

                        strongNode.appendChild( document.createTextNode( 'Complete list' ) );
                        aNode.setAttribute( 'href' , 'http://meta.wikimedia.org/wiki/List_of_Wikipedias' );
                        aNode.appendChild( strongNode );
                        liNode.appendChild( aNode );
                        node.appendChild( liNode );

                } catch(e) {
                        // lets just ignore what's happened
                        return;
                }
        }
        addOnloadHook( mainPageAppendCompleteListLink );
}

AzaToth 22:48, 28 December 2006 (UTC)

Nice work. There is a typo in your comment in the catch block ("happend" for "happened"), and there is no need to recheck wgTitle in mainPageTransform, since it only executes if the title is "Main Page". Mike Dillon 22:54, 28 December 2006 (UTC)
Hehe, yea, I had (or still have) problem finding exact when it should be executed and when not. AzaToth 23:11, 28 December 2006 (UTC)
Not sure about when it should be executed or not, since the old version is pretty hard to decipher. I was mainly saying that if the outer if statement already checks if ( wgTitle == 'Main Page' ), then the hooks will only be added when that condition is true and it doesn't need to be rechecked inside the hook function itself.
BTW, thanks for deciding to maintain this thing. Mike Dillon 23:14, 28 December 2006 (UTC)
Yea, I thought about that, but the only problem is that I'm not admin (yet for the millionth time), so I can't make edits directly. AzaToth 23:53, 28 December 2006 (UTC)
I was just referring to the fact that you stuck your name on the "maintained by" comment. Just because you can't edit it doesn't mean you don't maintain it. I'm involved with "maintaining" plenty of stuff at work, but the QA team still has to approve releases and the operations team has to actually make the changes ;) Mike Dillon 01:48, 29 December 2006 (UTC)
I've changed the check done to make sure the script is only executed on the main page. I'm puzzled by what mainPageTransform does, though. Shouldn't both the if and else if check for mpSmallEnabled (instead of !mpSmallEnabled?)

Those EnWpMp* things seems to be left-overs from Wikipedia:WikiProject Usability and aren't actually used on the current main page. —Ruud 00:02, 29 December 2006 (UTC)

Then we just remove that part, if it's unnecessary. AzaToth 02:08, 29 December 2006 (UTC)

mainPageRenameNamespaceTab()

I think it's a bad habit of using innerHTML as it's a rather expensive operation, following code should work as well I belive:

function mainPageRenameNamespaceTab() {
        try {
                document.getElementById( 'ca-nstab-main' ).firstChild.textContent = 'Main Page';
        } catch(e) {
                return;
        }
}

AzaToth 13:48, 29 December 2006 (UTC)

Fixed. —Ruud 14:45, 29 December 2006 (UTC)
Actually, Internet Explorer does NOT support textContent, but rather uses innerText. You need to test for innerText first, and then use textContent if that fails. I suggest setting a global var for this, so you don't have to keep testing every time you want to change the text of something. ♠ SG →Talk 18:28, 29 December 2006 (UTC)
Oh, I thought also IE did handle DOM level 3. We dont need to test for it before, we just do it in the catch AzaToth 18:45, 29 December 2006 (UTC)
function mainPageRenameNamespaceTab() {
        try {
                node = document.getElementById( 'ca-nstab-main' ).firstChild;
                try {
                        node.textContent = 'Main Page'; // Per DOM Level 3
                } catch(e) {
                        node.innerText = 'Main Page'; // IE doesn't handle .textContent
                }
        } catch(e) {
        // node not found
        }
}
This needs to use var node, or else it leaks out of the function. Mike Dillon 19:45, 29 December 2006 (UTC)

So IE didn't like it? try this then:

function mainPageRenameNamespaceTab() {
        try {
                var node = document.getElementById( 'ca-nstab-main' ).firstChild;
                if( Element.textContent ) {
                        node.textContent = 'Main Page'; // Per DOM Level 3
                } else if( Element.innerHTML ) {
                        node.innerHTML = 'Main Page'; // IE doesn't handle .textContent
                } else {
                        node.replaceChild(node.firstChild, document.createTextNode('Main Page')); // Fallback
                }
        } catch(e) {
                // bailing out!
        }
}

AzaToth 23:55, 29 December 2006 (UTC)

innerHTML works fine, maybe the problem lies in IE's try/catch handling? —Ruud 00:05, 30 December 2006 (UTC)
Don't use innerHTML; use innerText. It's much, much faster for modifying the text of a node. ♠ SG →Talk 05:14, 30 December 2006 (UTC)

Import Module

As we now have a Common.js, we could include this module here, to be used for user created modules, was rejected before in Monobook.js because it should be able to be used by everyone, and not only those who where using monobook. AzaToth 17:52, 29 December 2006 (UTC)

/** Import Module *************************************************************
 *
 *  Description: Includes a raw wiki page as javascript, 
 *               used for including user made modules as scripts
 *  Maintainers: User:AzaToth
 */

function import_module( page ){
        try {
                var url = wgServer + wgArticlePath.replace( '$1' , escape( page ) ) + '?action=raw&ctype=text/css';
                var scriptElem = document.createElement( 'script' );
                scriptElem.setAttribute( 'src' , url );
                scriptElem.setAttribute( 'type' , 'text/javascript' );
                document.getElementsByTagName( 'head' )[0].appendChild( scriptElem );
        } catch( e ) {
                return;
        }
}
  • Maybe there should be two functions: import_script and import_stylesheet?
  • The URL isn't correct: this should be wgScriptPath + "/index.php?title=" + escape( page.replace( " ", "_" ) ) + "&amp;action=raw&amp;ctype=text/javascript&amp;dontcountme=s".
  • I don't think silently ignoring any errors is the correct thing to do in this case.
  • I've added another feature to my own import function, don't know if it's useful. —Ruud 21:59, 29 December 2006 (UTC)
The "&amp;" is not correct, since this is in JavaScript, not HTML. Mike Dillon 22:04, 29 December 2006 (UTC)
No it's a string in JavaScript that is outputted as HTML. See the source of this page and see how your personal stylesheet is included. —Ruud 22:25, 29 December 2006 (UTC)
That's simply not true. This file is included from a script tag with an src attribute. It is not HTML. Mike Dillon 22:27, 29 December 2006 (UTC)

Here's what it looks like:

<script type="text/javascript" src="/w/index.php?title=-&action=raw&smaxage=0&gen=js"><!-- site js --></script>

The source text of the src is interpreted as pure JS, not HTML. Mike Dillon 22:28, 29 December 2006 (UTC)

(Despite the <nowiki> tags, the &amp;s got lost in your code above.) The extra &amp;s have disappeared in FF's DOM inspector as well, so it indeed seems that the JS src attribute is not interpreted literally as the HTML src attribute. —Ruud 22:37, 29 December 2006 (UTC)
Yeah, I saw that. Weird. Anyways, the escaping is a source-level thing. By the time you're in the DOM, everything is raw characters. Escaping ampersands in JavaScript code is only necessary if the code itself is in a raw script tag in the HTML without a CDATA wrapper. Even then, browser quirks let you get away with not escaping there even. Mike Dillon 22:44, 29 December 2006 (UTC)

I saw that these were added, which is really cool. Two things though:

  1. The page.replace(" ", "_") is not necessary; escape(page) will make a valid "title" param that MediaWiki can understand
  2. The CDATA stuff in the body of the "style" tag is not needed

Neither of these things will break anything, but they aren't doing anything useful either. As I said, a plain escaped title will work fine. The CDATA thing will just be ignored because the CSS parser sees them as comments. Mike Dillon 15:30, 31 December 2006 (UTC)

The CDATA will cause the browser's XML parser not to parse the stylesheet, which is invalid XML due to the presence of ampersands. —Ruud 18:21, 31 December 2006 (UTC)
This won't go through the XML parser. It's in raw JavaScript code and direct additions to the DOM are by necessity pre-parsed. It won't have any effect one way or the other. Mike Dillon 18:29, 31 December 2006 (UTC)
Makes sense (and it's stated in the DOM specification). —Ruud 18:36, 31 December 2006 (UTC)

Possible solution to {{click}}?

Because {{click}} is an ugly hack, and messes up screen readers, etc. why not make a JS version?

The benefits would be:

  • If something like a screen reader was being used, it would just not execute the js and no harm done
  • There are some browsers that have trouble rendering things like this, but would have no problem using js
  • ..please add more..

Here is a prototype:

/** Click on Image ***********************************************************
 *
 *  Description: Make images clickable to a different location
 *               than the one set by MediaWiki
 *  Maintainers: User:GeorgeMoney
 */
 
addOnloadHook(function() {
        var usebody = document.getElementById('bodyContent') || document;
        var divs = usebody.getElementsByTagName('div');
        for(var i = 0; i < divs.length; i++) {
                try {
                        if(divs[i].getAttribute('class') != 'click') continue;
                        var titleurl =  divs[i].getAttribute('title').split('URL=');
                        divs[i].getElementsByTagName('a')[0]
                                .setAttribute('title', titleurl[0]);
                        divs[i].setAttribute('title', );
                        if(typeof titleurl[1] == 'undefined') continue;
                        var useurl;
                        if(titleurl[1].substr(0, 2) == '[[' 
                        && titleurl[1].substr(titleurl[1].length-2) == ']]') {
                                useurl = titleurl[1].substr(0, titleurl[1].length-2).substr(2);
                                useurl = wgServer + wgArticlePath.replace('$1', useurl);
                        } else
                                useurl = titleurl[1];
                        divs[i].getElementsByTagName('a')[0]
                                .setAttribute('href', useurl);
                } catch(e) { }
        }
});

so you would type <div class="click" title="title to be set after javascript parses URL=http://example.com">[[Image:Myimage]]</div> Which would then set the href (url) of the link which contains the image to http://example.com, and link's title to "title to be set after javascript parses".

Using wikilinks on the link works too.

I know this might sound complicated, but it is actually quite simple.

GeorgeMoney (talk) 04:52, 3 January 2007 (UTC)

This doesn't solve the copyright info problem. — Omegatron 15:21, 3 January 2007 (UTC)
I guess to solve the copyright problem we could set the title of the link to the old link's href, like "Please see foo for copright info", or maybe even have it append fromimage=true&oldimage=foo which could add in the contentSub "For information on the image that refered you here, see: foo", etc.. GeorgeMoney (talk) 23:54, 3 January 2007 (UTC)
That wouldn't work on the Main Page, where {{click}} is used to link a picture of Wiktionary's logo to Wiktionary, etc.. --ais523 15:17, 9 January 2007 (UTC)