Page MenuHomePhabricator

JavaScript error in jQuery 1.7.2 in FireFox on Special:MovePage
Closed, ResolvedPublic

Description

Going to [[Special:MovePage/Foobar]] gives JavaScript error since 1.20wmf1:

[23:07:28.898] mw.loader::execute> Exception thrown by mediawiki.special.movePage: Index or size is negative or greater than the allowed amount @ https://bits.wikimedia.org/en.wikipedia.org/load.php?debug=false&lang=de&modules=jquery%2Cmediawiki&only=scripts&skin=monobook&version=20120423T214913Z:151[23:07:28.912] [Exception... "Index or size is negative or greater than the allowed amount" code: "1" nsresult: "0x80530001 (NS_ERROR_DOM_INDEX_SIZE_ERR)" location: "https://bits.wikimedia.org/en.wikipedia.org/load.php?debug=false&lang=de&modules=jquery%2Cmediawiki&only=scripts&skin=monobook&version=20120423T214913Z Line: 38"] @ https://bits.wikimedia.org/en.wikipedia.org/load.php?debug=false&lang=de&modules=jquery%2Cmediawiki&only=scripts&skin=monobook&version=20120423T214913Z:151

Looks like a problem within $.prop which is called from $.byteLimit.


Version: 1.20.x
Severity: major

Details

Reference
bz36310

Event Timeline

bzimport raised the priority of this task from to High.Nov 22 2014, 12:28 AM
bzimport set Reference to bz36310.

It seems that this is what happens:
If the maxLength property is missing, $.prop returns -1, but when you try to set maxLength explicitly to -1 the above error is thrown.

But works with jQuery 1.7.1, which was used under 1.19wmf1.

Setting maxLength to -1 also breaks Opera, you cannot write text in the input field (here #wpReason).

A JavaScript error in the main module should not a low prio, because you have no chance to use a workaround a do other things to get that fixed.

Looks like the next upgrade (1.20wmf2) fixes this. I can't reproduce it on mediawiki.org (which runs 1.20wmf2)

Hm.. So I can reproduce it on en.wikipedia.org (1.20wmf1 at the moment). However it doesn't happen on mediawiki.org (1.20wmf2), but it *does* occur on meta.wikimedia.org (also 1.20wmf2). Doesn't appear to be version related.

The problem is that wgHtml5 is still false on most wikis (such as en.wikipedia and meta.wikimedia, but mediawiki.org has wgHtml5 enabled). And since maxlength="" attribute is next for <textarea> in HTML5, MediaWiki strips it from textarea#wpReason on en.wiki and meta.wikimedia causing the problem.

The reason this wasn't in 1.19 is because wpReason was changed from an <input> to a <textarea> in 1.20. And maxlength="" is supported on <input> before HTML5, but not on <textarea>.

The javascript written for it here https://gerrit.wikimedia.org/r/gitweb?p=mediawiki/core.git;a=blob;f=resources/mediawiki.special/mediawiki.special.movePage.js;h=68c2ed078e98b87c3bd29794c67d6036b2577553;hb=HEAD

.. was written in 1.19 and assumes (and could assume) that there is a maxlength attribute on both elements, except that in 1.20 #wpReason will not have a maxlength attribute on it when wgHtml5=false, because it is stripped from <textarea>

So there's 2 bugs (one is visible now, the other will be visible when the first is fixed)

  • jquery.byteLimit needs to verify that the value is above zero
  • We need to hardcode the limit in mediawiki.special.movePage.js instead of assuming the html will contain it.

mr.heat wrote:

I'm not sure if this is a bug in jQuery or in MediaWiki. But it is a major problem because of this bug no Opera user can enter a reason when moving a page. The textarea is locked. I'm not allowed to enter anything. Here is what happens:

In the script

http://bits.wikimedia.org/static-1.20wmf3/resources/mediawiki.special/mediawiki.special.movePage.js

the line

$( '#wpReason, #wpNewTitleMain' ).byteLimit();

is called. The idea is to add JavaScript handlers to two input fields. I'm not sure why because such limits should be set by adding an maxlength attribute, but anyway. This calls a method found in the script

http://bits.wikimedia.org/static-1.20wmf3/resources/jquery/jquery.byteLimit.js

The code in this script basically looks for an attribute called "maxLength". But since the textarea #wpReason does not have a maxlength it returns -1 and uses this number to set a maxlength attribute. I'm not sure if this makes sense. Again: It reads the number from the maxlength attribute and all it does is setting the maxlength attribute to this number? Why?

I did a test with Firefox and Opera, it's the same bug.

Possible fixes:

In the script

http://bits.wikimedia.org/static-1.20wmf3/resources/jquery/jquery.byteLimit.js

change the line

if ( fn === undefined ) {

into

if ( fn === undefined && limit !== undefined && elLimit >= 0 ) {

In the script

http://bits.wikimedia.org/static-1.20wmf3/resources/mediawiki.special/mediawiki.special.movePage.js

change the line

$( '#wpReason, #wpNewTitleMain' ).byteLimit();

to

$( '#wpNewTitleMain' ).byteLimit();
$( '#wpReason' ).byteLimit(255); //not sure about the number

maxLength only checks for characters, but the database field used by mediawiki for comments can only hold 255 *bytes*, that can be 255 characters, but for example german umlauts needs two bytes ...

The problem here is, that #wpReason was changed from input to textarea, but textarea does not have a maxlength attribute (under HTML 4), but mediawiki adds a maxlength, some browser are very restricted against this and break or play not nice with this situation.

mr.heat wrote:

I understand. In this case there is a third solution: Add maxlength="255" to the textarea. I tested it and it works as expected.

Note: You may say a textarea can have a maxlength in HTML5 only. I say: jQuery does not care (it adds a maxlength not matter if the page is HTML5 or not), the browsers do not care (they are reading the maxlength not matter if the page is HTML5 or not) so I do not care as well. Add maxlength="255" please, not matter if MediaWiki is in HTML5 mode or not.

It is already there (includes/specials/SpecialMovepage.php, around line 290) and that makes problems, because the browser is deleted it on first validate, that gives -1 for the javascript.

			<tr>
				<td class='mw-label'>" .
					Xml::label( $this->msg( 'movereason' )->text(), 'wpReason' ) .
				"</td>
				<td class='mw-input'>" .
					Html::element( 'textarea', array( 'name' => 'wpReason', 'id' => 'wpReason', 'cols' => 60, 'rows' => 2,
					'maxlength' => 200 ), $this->reason ) .
				"</td>
			</tr>"

After the dom is ready and shown, you can add maxlength with javascript and it works (de.wp uses a workaround). Maybe jQuery simulates it, I do not know.
if( mw.config.get( 'wgCanonicalSpecialPageName' ) === 'Movepage' ) {
$( function() {

var wpReason = $( '#wpReason' );
wpReason.removeAttr( 'maxLength' );
mw.loader.using( [ 'jquery.byteLimit' ], function() {
 //restore byteLimit
 wpReason.byteLimit( 200 );
});

});
}

content hidden as private in Bugzilla

(In reply to comment #9)

It is already there (includes/specials/SpecialMovepage.php, around line 290)
and that makes problems, because the browser is deleted it on first validate,
that gives -1 for the javascript.

<tr>
    <td class='mw-label'>" .
        Xml::label( $this->msg( 'movereason' )->text(), 'wpReason'

) .

"</td>
<td class='mw-input'>" .
    Html::element( 'textarea', array( 'name' => 'wpReason',

'id' => 'wpReason', 'cols' => 60, 'rows' => 2,

        'maxlength' => 200 ), $this->reason ) .
    "</td>
</tr>"

After the dom is ready and shown, [ .. ]

This is not true. Browsers never delete properties or attributes*. MediaWiki
itself removes the attribute for wikis that are not in HTML5 mode. -1 is the default value in Firefox when accessing the maxlength property of an element where that attribute does not exist (look at the raw HTML output. You can see that MediaWiki removes it before outputting, Firefox doesn't do this).

I refer to comment 5 where I've mentioned 2 things that should be fixed. I
don't think anything else is needed in this case.

  • Krinkle
  • Maybe in some other case, but certainly not in this case.

mr.heat wrote:

Here is a hint: Even the most obscure Unicode characters are only 4 bytes long when encoded in UTF-8. You can *always* enter 50 characters in a 200 bytes field.

Currently I can't enter anything. Please disable the broken code till it is fixed.

Fixed in I28490b61bd5a20dd1d84c4730615514d3822aa77.