* Although jQuery covers for us in most cases (since .prop didn't exist before jQuery 1.6 and many people abused .attr in laziness of doing their own loop and setting the property manually). It's better to know what we're doing and call the function we intend to call. Both because jQuery may decide to stop rerouting common mistakes to .prop and because it makes code more readable.
* Aside from switching to prop, for boolean properties also replacing null/undefined with false and 'propname' with true. This is no longer being covered by jQuery when using prop directly (as it shouldn't). When an element is created the HTML specification says that the attribute should be set to it's name (ie. '<foo selected="selected">'), the properties however must remain boolean.
* Changing the attribute value for a boolean property (ie. checkbox.setAttribute( 'checked', 'checked' ) does not make the checkbox enabled. All it does is set the attribute. The reason this works with jQuery's attr() is because jQuery calls .prop internally after a bunch of checking inside attr().
-- Reference --
The list of keys that .attr and .removeAttr jQuery is currently (as of jQuery 1.6.1) remapping to use .prop and .removeProp can be found here:
b22c904652/src/attributes.js (L425)
{
tabindex: "tabIndex",
readonly: "readOnly",
"for": "htmlFor",
"class": "className",
maxlength: "maxLength",
cellspacing: "cellSpacing",
cellpadding: "cellPadding",
rowspan: "rowSpan",
colspan: "colSpan",
usemap: "useMap",
frameborder: "frameBorder",
contenteditable: "contentEditable"
}
In addition to those, jQuery also maps these boolean properties to .prop when they are passed to .attr:
rboolean = /^(?:autofocus|autoplay|async|checked|controls|defer|disabled|hidden|loop|multiple|open|readonly|required|scoped|selected)$/i,
(source: b22c904652/src/attributes.js (L9) )
* Browsers should ignore the maxLength when the .value is set manually through JavaScript, but for some reason Safari 4 (not 5 and later) is enforcing the limit even when the value property is set from JavaScript. Usually this bug doesn't become visible in this module because the byteLength can't be lower than the number of characters, so we'd never see the bug. However since r94066 we're supporting callbacks, and callbacks could do anything to the calculation, including but not limited to making the string that is being checked shorter (ie. suppose maxLength/byteLimit is 8, value is 'User:Sam', and callback filters like "return new mw.Title(val).getName()". If we set it to 'User:Samp' (+p) then Safari 4 would chop the value, because the total string is longer than 8. Whereas all other browsers ignore maxLength (like they should) and let it be and would allow our callback to happen and instead give byteLimit 'Samp' which is length 4 and we still have 4 more characters to go until we reach 8.
The fix is easy, simply do not set the maxLength property if there's a callback.
Instead of having getFullURL and getLocalURL call each other, move the interwiki workload into getLocalURL, and make getFullURL simply call getLocalURL then expand it (use the wf method in case it's already a full url) and append the fragment to it.
- Allow extensions to hook into WebRequest::getPathInfo and add to or alter the way titles are extracted from paths
- Add a $variant argument to the GetLocalURL hook; It's always had $query, but never had $variant. As a result extensions using GetLocalURL never new if getLocalURL and have the possibility of trying to change the url in cases where they shouldn't and as a result breaking links on wiki with language variants.
- Add GetLocalURL::Internal hook for non-interwiki links. These kinds of links internally use a ugly hack for action=render and an extension using GetLocalURL can be buggy in render mode if they don't re-implement the same ugly hack that MW does. This ::Internal hook runs before the hack does so extension authors don't need to be exposed to our ugly hacky code.
- Add GetLocalURL::Article hook specifically for url tweaks to pretty urls (ie: Only when we would apply $wgArticlePath); This hook avoids the need for extensions that only want to tweak pretty url output. This hook avoids the need to make a bunch of tests for things like !$title->isExternal(), $query == '', and $variant === false which getLocalURL does and could potentially change in the future making wider GetLocalURL hooks change in function requiring extension updates.
* Moved PopulateRevisionLength/PopulateRevisionSha1 scripts to $postDatabaseUpdateMaintenance
* Fixed bogus "{$prefix}_sha1 != ''" comparison (r94362)
* Removed unneeded NOT NULL check (speeds up script a bit) from populateRevisionSha1 script
* Various code cleanups
* There shouldn't be two files with the same name in core, especially not the module and the test suite. Previously postponed due to compatibility with our TestSwarm script, that has been fixed now.
* Had to modify the files in the same commit since the module name is referenced inside the test suite in the module() call, which is the hint for QUnit when filtering is done through the ?filter= parameter.
* As has been added to the conventions, there must be only one module() call per test suite file and it MUST match "filename without .test.js". Otherwise the module will not be submitted to TestSwarm (which glob()'s at the /suites/ directory and extracts test-suite-module-names from the filenames).
Update the Interwiki::getURL code to use isset(), and update the comment to tell pre-1.19 supporting extensions to do the entire urlencoding and $1 substitution on their own since Interwiki::getURL was essentially buggy and broken before now.
Scanning all of core and all the extensions we have in svn, it doesn't look like anyone makes any calls to Interwiki::getURL using the argument so this should be safe enough to clean up the api.
Also update Title::getFullURL to make use of the first arg now.
* Html-escaping unescaped message in summaryHolder
* Check for errors in the API response
* Pass true for existence of redirect origin and value of 'exists' for target (instead of backwards)
* Comment fixes
- jQuery changed to $ in some files because there is a closure that creates a locally scoped $, but the jQuery var is globally scoped, meaning using jQuery instead of $ inside that closure could result in interacting with a different instance of jQuery than the uses of $ in that same closure.
- In mwExtension wrap the code inside a closure which it is missing. Also take this chance to fix the whitespace style `fn( arg )` instead of `fn(arg)` on the isArray I added.
This is partially a followup to r94331.
Note: The jquery plugins inside the jquery/ folder look fine for use of jQuery within closures, except for mockjax.
Produced the following fatal on Unix systems when trying to update:
Warning: require(maintenance/PopulateRevisionSha1.php): failed to open stream: No such file or directory in includes/AutoLoader.php on line 922
Fatal error: require(): Failed opening required 'maintenance/PopulateRevisionSha1.php' in includes/AutoLoader.php on line 922
* Parser.php: Apparently that was a much bigger bug: do not convert interface text going through the parser either.
* Preferences.php: Do not convert the user signature.
For this bug in action, see e.g. http://sr.wikipedia.org/sr-ec/Посебно:Подешавањ?uselang=en (e.g. "Username" -> "Усернаме")
* Using typeof check in clean()
* Use mw.Title to get page title from fullpagename instead of split(':')
* replaceNowikis() and restoreNowikis()
- Improve documentation
- Moved dash in the UNIQUEKEY to between the id and the incrementing integer, and made it start with an empty string (so that all following concatenations are toString'ed).
* makeCaseInsensitive(): Moved the wgCaseSensitiveNamespaces-check out and wrapped it around the caller instead. Also cached the outcome of "Is category namespace sensitive ?".
* createButton(): text-argument is indeed text, not html. Applying html-escaping.
* resolveRedirects():
- Replace access to private property _name of mw.Title with function getMainText().
* handleCategoryAdd() and handleEditLink():
- Restructure title-handling (no local replace() calls and clean(), let mw.Title handle it)
- Renaming arguments and documenting them better
- Renaming local variables and removing redundant parts
- Preserving sortkey as sortkey as long as possible without the pipe
- Calling the combination of sortkey and leading pipe 'suffix' instead of, also, sortkey.
* createCatLink():
- Remove the sanitizing here, the string passed is already clean as it comes from mw.Title now
- Using .text() instead of .append( which is .html-like), category names can contain special characters.
* containsCat():
- Using $.each instead of [].filter. Stopping after first match.
* buildRegex(): Allow whitespace before namespace colon, and allow whitespace after category name (but before ]] and |..]])
Additional changes not for any function in particular:
* Literally return null in $.map callbacks.
* Using the existence-system of mw.Title instead of passing around booleans everywhere
** Removed 'exists' argument from the resolveRedirects() and handleCategoryAdd() functions, instead checking .exists() of the mw.Title object.
* Passing and using mw.Title objects where possible instead of converting back and forth between strings and objects etc.
* Using "TitleObj.getUrl()" instead of "catUrl( titleString )". Removed now unused catUrl() function.
* To improve readability, renamed local uses of 'var that = this' to 'var ajaxcat = this'.
* Syntax error fixes (.parent -> .parent())
* Merging var statements
* Renamed generic members of 'stash' from 'stash.summaries' to 'stash.dialogDescriptions' and 'stash.shortSum' to 'stash.editSummaries'. dialogDescription is always HTML (input should be escaped before hand)