r55781 MediaWiki - Code Review archive

Repository:MediaWiki
Revision:r55780‎ | r55781 | r55782 >
Date:18:06, 3 September 2009
Author:tparscal
Status:deferred (Comments)
Tags:
Comment:
Solves r20485 by explicitly listing javascript files to be combined since order is important, and we were previously just getting luck that alphabetical order was acceptable.
Modified paths:
  • /trunk/extensions/UsabilityInitiative/combine.sh (modified) (history)
  • /trunk/extensions/UsabilityInitiative/js/plugins.combined.js (modified) (history)
  • /trunk/extensions/UsabilityInitiative/js/plugins.combined.min.js (modified) (history)

Diff [purge]

Index: trunk/extensions/UsabilityInitiative/combine.sh
@@ -3,8 +3,10 @@
44 rm js/plugins.combined.*
55 rm css/combined.*
66 echo "Merging raw scripts and styles"
7 -cat js/js2/*.js > js/js2.combined.js
8 -cat js/plugins/*.js > js/plugins.combined.js
 7+# Explicitly including scripts is important, because loading order is important
 8+cat js/js2/jquery-1.3.2.js js/js2/jquery-ui-1.7.2.js js/js2/js2.js > js/js2.combined.js
 9+cat js/plugins/jquery.async.js js/plugins/jquery.browser.js js/plugins/jquery.cookie.js js/plugins/jquery.suggestions.js js/plugins/jquery.textSelection.js js/plugins/jquery.wikiEditor.js js/plugins/jquery.wikiEditor.dialogs.js js/plugins/jquery.wikiEditor.toolbar.js js/plugins/jquery.wikiEditor.toc.js > js/plugins.combined.js
 10+# Styles can be loaded in any order
911 cat css/*.css > css/combined.css
1012 # For more info on JSMin, see: http://www.crockford.com/javascript/jsmin.html
1113 echo "Minifying merged scripts and styles"
Index: trunk/extensions/UsabilityInitiative/js/plugins.combined.js
@@ -1010,82 +1010,6 @@
10111011 }
10121012
10131013 } ); } )( jQuery );/**
1014 - * Extend the RegExp object with an escaping function
1015 - * From http://simonwillison.net/2006/Jan/20/escape/
1016 - */
1017 -RegExp.escape = function( s ) { return s.replace(/([.*+?^${}()|\/\\[\]])/g, '\\$1'); };
1018 -
1019 -/**
1020 - * Dialog Module for wikiEditor
1021 - */
1022 -( function( $ ) { $.wikiEditor.modules.dialogs = {
1023 -
1024 -/**
1025 - * API accessible functions
1026 - */
1027 -api: {
1028 - addDialog: function( context, data ) {
1029 - $.wikiEditor.modules.dialogs.fn.create( context, { 'modules': data } )
1030 - },
1031 - openDialog: function( context, data ) {
1032 - if ( data.dialog in $.wikiEditor.modules.dialogs.modules ) {
1033 - $( '#' + $.wikiEditor.modules.dialogs.modules[data.dialog].id ).dialog( 'open' );
1034 - }
1035 - },
1036 - closeDialog: function( context, data ) {
1037 - if ( data.dialog in $.wikiEditor.modules.dialogs.modules ) {
1038 - $( '#' + $.wikiEditor.modules.dialogs.modules[data.dialog].id ).dialog( 'close' );
1039 - }
1040 - }
1041 -},
1042 -/**
1043 - * Internally used functions
1044 - */
1045 -fn: {
1046 - /**
1047 - * Creates a dialog module within a wikiEditor
1048 - *
1049 - * @param {Object} context Context object of editor to create module in
1050 - * @param {Object} config Configuration object to create module from
1051 - */
1052 - create: function( context, config ) {
1053 - // Add modules
1054 - for ( module in config ) {
1055 - $.wikiEditor.modules.dialogs.modules[module] = config[module];
1056 - }
1057 - // Build out modules immediately
1058 - for ( module in $.wikiEditor.modules.dialogs.modules ) {
1059 - var module = $.wikiEditor.modules.dialogs.modules[module];
1060 - // Only create the dialog if it doesn't exist yet
1061 - if ( $( '#' + module.id ).size() == 0 ) {
1062 - var configuration = module.dialog;
1063 - // Add some stuff to configuration
1064 - configuration.bgiframe = true;
1065 - configuration.autoOpen = false;
1066 - configuration.modal = true;
1067 - configuration.title = $.wikiEditor.autoMsg( module, 'title' );
1068 - // Transform messages in keys
1069 - // Stupid JS won't let us do stuff like
1070 - // foo = { gM ('bar'): baz }
1071 - for ( msg in configuration.buttons ) {
1072 - configuration.buttons[gM( msg )] = configuration.buttons[msg];
1073 - delete configuration.buttons[msg];
1074 - }
1075 - // Create the dialog <div>
1076 - $( '<div /> ' )
1077 - .attr( 'id', module.id )
1078 - .html( module.html )
1079 - .data( 'context', context )
1080 - .appendTo( $( 'body' ) )
1081 - .each( module.init )
1082 - .dialog( configuration );
1083 - }
1084 - }
1085 - }
1086 -},
1087 -'modules': {}
1088 -
1089 -}; } ) ( jQuery );/**
10901014 * This plugin provides a way to build a user interface around a textarea. You
10911015 * can build the UI from a confguration..
10921016 * $j( 'div#edittoolbar' ).wikiEditor(
@@ -1246,226 +1170,80 @@
12471171 return $(this).data( 'context', context );
12481172
12491173 };})(jQuery);/**
1250 - * TOC Module for wikiEditor
 1174+ * Extend the RegExp object with an escaping function
 1175+ * From http://simonwillison.net/2006/Jan/20/escape/
12511176 */
1252 -( function( $ ) { $.wikiEditor.modules.toc = {
 1177+RegExp.escape = function( s ) { return s.replace(/([.*+?^${}()|\/\\[\]])/g, '\\$1'); };
12531178
12541179 /**
 1180+ * Dialog Module for wikiEditor
 1181+ */
 1182+( function( $ ) { $.wikiEditor.modules.dialogs = {
 1183+
 1184+/**
12551185 * API accessible functions
12561186 */
12571187 api: {
1258 - //
 1188+ addDialog: function( context, data ) {
 1189+ $.wikiEditor.modules.dialogs.fn.create( context, { 'modules': data } )
 1190+ },
 1191+ openDialog: function( context, data ) {
 1192+ if ( data.dialog in $.wikiEditor.modules.dialogs.modules ) {
 1193+ $( '#' + $.wikiEditor.modules.dialogs.modules[data.dialog].id ).dialog( 'open' );
 1194+ }
 1195+ },
 1196+ closeDialog: function( context, data ) {
 1197+ if ( data.dialog in $.wikiEditor.modules.dialogs.modules ) {
 1198+ $( '#' + $.wikiEditor.modules.dialogs.modules[data.dialog].id ).dialog( 'close' );
 1199+ }
 1200+ }
12591201 },
12601202 /**
12611203 * Internally used functions
12621204 */
12631205 fn: {
12641206 /**
1265 - * Creates a table of contents module within a wikiEditor
 1207+ * Creates a dialog module within a wikiEditor
12661208 *
12671209 * @param {Object} context Context object of editor to create module in
12681210 * @param {Object} config Configuration object to create module from
12691211 */
12701212 create: function( context, config ) {
1271 - if ( '$toc' in context.modules ) {
1272 - return;
 1213+ // Add modules
 1214+ for ( module in config ) {
 1215+ $.wikiEditor.modules.dialogs.modules[module] = config[module];
12731216 }
1274 - context.modules.$toc = $( '<div></div>' )
1275 - .addClass( 'wikiEditor-ui-toc' )
1276 - .attr( 'id', 'wikiEditor-ui-toc' );
1277 - $.wikiEditor.modules.toc.fn.build( context, config );
1278 - context.$ui.find( '.wikiEditor-ui-bottom' )
1279 - .append( context.modules.$toc );
1280 - context.modules.$toc.height(
1281 - context.$ui.find( '.wikiEditor-ui-bottom' ).height()
1282 - );
1283 - // Make some css modifications to make room for the toc on the right...
1284 - // Perhaps this could be configurable?
1285 - context.modules.$toc
1286 - .css( 'width', '12em' )
1287 - .css( 'marginTop', -( context.$ui.find( '.wikiEditor-ui-bottom' ).height() ) );
1288 - context.$ui.find( '.wikiEditor-ui-text' )
1289 - .css( ( $( 'body.rtl' ).size() ? 'marginLeft' : 'marginRight' ), '12em' );
1290 - // Add the TOC to the document
1291 - $.wikiEditor.modules.toc.fn.build( context );
1292 - $.wikiEditor.modules.toc.fn.update( context );
1293 - context.$textarea
1294 - .bind( 'keyup encapsulateSelection',
1295 - function( event ) {
1296 - var context = $(this).data( 'context' );
1297 - $(this).eachAsync( {
1298 - bulk: 0,
1299 - loop: function() {
1300 - $.wikiEditor.modules.toc.fn.build( context );
1301 - $.wikiEditor.modules.toc.fn.update( context );
1302 - }
1303 - } );
 1217+ // Build out modules immediately
 1218+ for ( module in $.wikiEditor.modules.dialogs.modules ) {
 1219+ var module = $.wikiEditor.modules.dialogs.modules[module];
 1220+ // Only create the dialog if it doesn't exist yet
 1221+ if ( $( '#' + module.id ).size() == 0 ) {
 1222+ var configuration = module.dialog;
 1223+ // Add some stuff to configuration
 1224+ configuration.bgiframe = true;
 1225+ configuration.autoOpen = false;
 1226+ configuration.modal = true;
 1227+ configuration.title = $.wikiEditor.autoMsg( module, 'title' );
 1228+ // Transform messages in keys
 1229+ // Stupid JS won't let us do stuff like
 1230+ // foo = { gM ('bar'): baz }
 1231+ for ( msg in configuration.buttons ) {
 1232+ configuration.buttons[gM( msg )] = configuration.buttons[msg];
 1233+ delete configuration.buttons[msg];
13041234 }
1305 - )
1306 - .bind( 'mouseup scrollToPosition',
1307 - function( event ) {
1308 - var context = $(this).data( 'context' );
1309 - $(this).eachAsync( {
1310 - bulk: 0,
1311 - loop: function() {
1312 - $.wikiEditor.modules.toc.fn.update( context );
1313 - }
1314 - } );
1315 - }
1316 - );
1317 - },
1318 - /**
1319 - * Highlight the section the cursor is currently within
1320 - *
1321 - * @param {Object} context
1322 - */
1323 - update: function( context ) {
1324 - context.modules.$toc.find( 'a' ).removeClass( 'currentSelection' );
1325 - var position = context.$textarea.getCaretPosition();
1326 - var section = 0;
1327 - if ( context.data.outline.length > 0 ) {
1328 - // If the caret is before the first heading, you must be in section
1329 - // 0, and there is no need to look any farther - otherwise check
1330 - // that the caret is before each section, and when it's not, we now
1331 - // know what section it is in
1332 - if ( !( position < context.data.outline[0].position - 1 ) ) {
1333 - while (
1334 - section < context.data.outline.length && context.data.outline[section].position - 1 < position
1335 - ) {
1336 - section++;
1337 - }
1338 - section = Math.max( 0, section );
 1235+ // Create the dialog <div>
 1236+ $( '<div /> ' )
 1237+ .attr( 'id', module.id )
 1238+ .html( module.html )
 1239+ .data( 'context', context )
 1240+ .appendTo( $( 'body' ) )
 1241+ .each( module.init )
 1242+ .dialog( configuration );
13391243 }
1340 - context.modules.$toc.find( 'a.section-' + section ).addClass( 'currentSelection' );
13411244 }
1342 - },
1343 - /**
1344 - * Builds table of contents
1345 - *
1346 - * @param {Object} context
1347 - */
1348 - build: function( context ) {
1349 - /**
1350 - * Builds a structured outline from flat outline
1351 - *
1352 - * @param {Object} outline Array of objects with level fields
1353 - */
1354 - function buildStructure( outline, offset, level ) {
1355 - if ( offset == undefined ) offset = 0;
1356 - if ( level == undefined ) level = 1;
1357 - var sections = [];
1358 - for ( var i = offset; i < outline.length; i++ ) {
1359 - if ( outline[i].nLevel == level ) {
1360 - var sub = buildStructure( outline, i + 1, level + 1 );
1361 - if ( sub.length ) {
1362 - outline[i].sections = sub;
1363 - }
1364 - sections[sections.length] = outline[i];
1365 - } else if ( outline[i].nLevel < level ) {
1366 - break;
1367 - }
1368 - }
1369 - return sections;
1370 - }
1371 - /**
1372 - * Bulds unordered list HTML object from structured outline
1373 - *
1374 - * @param {Object} structure Structured outline
1375 - */
1376 - function buildList( structure ) {
1377 - var list = $( '<ul></ul>' );
1378 - for ( i in structure ) {
1379 - var item = $( '<li></li>' )
1380 - .append(
1381 - $( '<a></a>' )
1382 - .attr( 'href', '#' )
1383 - .addClass( 'section-' + structure[i].index )
1384 - .data( 'textbox', context.$textarea )
1385 - .data( 'position', structure[i].position )
1386 - .click( function( event ) {
1387 - $(this).data( 'textbox' ).scrollToCaretPosition( $(this).data( 'position' ) );
1388 - event.preventDefault();
1389 - } )
1390 - .text( structure[i].text )
1391 - );
1392 - if ( structure[i].sections !== undefined ) {
1393 - item.append( buildList( structure[i].sections ) );
1394 - }
1395 - list.append( item );
1396 - }
1397 - return list;
1398 - }
1399 - // Build outline from wikitext
1400 - var outline = [];
1401 - var wikitext = '\n' + context.$textarea.val() + '\n';
1402 - var headings = wikitext.match( /\n={1,5}.*={1,5}(?=\n)/g );
1403 - var offset = 0;
1404 - headings = $.makeArray( headings );
1405 - for ( var h = 0; h < headings.length; h++ ) {
1406 - text = headings[h];
1407 - // Get position of first occurence
1408 - var position = wikitext.indexOf( text, offset );
1409 - // Update offset to avoid stumbling on duplicate headings
1410 - if ( position > offset ) {
1411 - offset = position;
1412 - } else if ( position == -1 ) {
1413 - // Not sure this is possible, or what should happen
1414 - continue;
1415 - }
1416 - // Trim off whitespace
1417 - text = $.trim( text );
1418 - // Detect the starting and ending heading levels
1419 - var startLevel = 0;
1420 - for ( var c = 0; c < text.length; c++ ) {
1421 - if ( text.charAt( c ) == '=' ) {
1422 - startLevel++;
1423 - } else {
1424 - break;
1425 - }
1426 - }
1427 - var endLevel = 0;
1428 - for ( var c = text.length - 1; c >= 0; c-- ) {
1429 - if ( text.charAt( c ) == '=' ) {
1430 - endLevel++;
1431 - } else {
1432 - break;
1433 - }
1434 - }
1435 - // Use the lowest number of =s as the actual level
1436 - var level = Math.min( startLevel, endLevel );
1437 - text = $.trim( text.substr( level, text.length - ( level * 2 ) ) );
1438 - // Add the heading data to the outline
1439 - outline[h] = { 'text': text, 'position': position, 'level': level, 'index': h + 1 };
1440 - }
1441 - // Normalize heading levels for list creation
1442 - // This is based on Linker::generateTOC() so, it should behave like the
1443 - // TOC on rendered articles does - which is considdered to be correct
1444 - // at this point in time.
1445 - var lastLevel = 0;
1446 - var nLevel = 0;
1447 - for ( var i = 0; i < outline.length; i++ ) {
1448 - if ( outline[i].level > lastLevel ) {
1449 - nLevel++;
1450 - }
1451 - else if ( outline[i].level < nLevel ) {
1452 - nLevel -= Math.max( 1, lastLevel - outline[i].level );
1453 - }
1454 - if ( nLevel <= 0 ) {
1455 - nLevel = 1;
1456 - }
1457 - outline[i].nLevel = nLevel;
1458 - lastLevel = outline[i].level;
1459 - }
1460 - // Recursively build the structure and add special item for
1461 - // section 0, if needed
1462 - var structure = buildStructure( outline );
1463 - if ( $( 'input[name=wpSection]' ).val() == '' )
1464 - structure.unshift( { 'text': wgPageName.replace(/_/g, ' '), 'level': 1, 'index': 0, 'position': 0 } );
1465 - context.modules.$toc.html( buildList( structure ) );
1466 - // Cache the outline for later use
1467 - context.data.outline = outline;
14681245 }
1469 -}
 1246+},
 1247+'modules': {}
14701248
14711249 }; } ) ( jQuery );/**
14721250 * Toolbar module for wikiEditor
@@ -1925,6 +1703,12 @@
19261704 $section.show();
19271705 $(this).addClass( 'current' );
19281706 }
 1707+
 1708+ //click tracking
 1709+ if($.trackAction != undefined){
 1710+ $.trackAction($section.attr('rel') + '.' + ( show ? 'show': 'hide' ) );
 1711+ }
 1712+
19291713 $.cookie(
19301714 'wikiEditor-' + $(this).data( 'context' ).instance + '-toolbar-section',
19311715 show ? $section.attr( 'rel' ) : null
@@ -2022,3 +1806,226 @@
20231807 }
20241808
20251809 }; } )( jQuery );
 1810+/**
 1811+ * TOC Module for wikiEditor
 1812+ */
 1813+( function( $ ) { $.wikiEditor.modules.toc = {
 1814+
 1815+/**
 1816+ * API accessible functions
 1817+ */
 1818+api: {
 1819+ //
 1820+},
 1821+/**
 1822+ * Internally used functions
 1823+ */
 1824+fn: {
 1825+ /**
 1826+ * Creates a table of contents module within a wikiEditor
 1827+ *
 1828+ * @param {Object} context Context object of editor to create module in
 1829+ * @param {Object} config Configuration object to create module from
 1830+ */
 1831+ create: function( context, config ) {
 1832+ if ( '$toc' in context.modules ) {
 1833+ return;
 1834+ }
 1835+ context.modules.$toc = $( '<div></div>' )
 1836+ .addClass( 'wikiEditor-ui-toc' )
 1837+ .attr( 'id', 'wikiEditor-ui-toc' );
 1838+ $.wikiEditor.modules.toc.fn.build( context, config );
 1839+ context.$ui.find( '.wikiEditor-ui-bottom' )
 1840+ .append( context.modules.$toc );
 1841+ context.modules.$toc.height(
 1842+ context.$ui.find( '.wikiEditor-ui-bottom' ).height()
 1843+ );
 1844+ // Make some css modifications to make room for the toc on the right...
 1845+ // Perhaps this could be configurable?
 1846+ context.modules.$toc
 1847+ .css( 'width', '12em' )
 1848+ .css( 'marginTop', -( context.$ui.find( '.wikiEditor-ui-bottom' ).height() ) );
 1849+ context.$ui.find( '.wikiEditor-ui-text' )
 1850+ .css( ( $( 'body.rtl' ).size() ? 'marginLeft' : 'marginRight' ), '12em' );
 1851+ // Add the TOC to the document
 1852+ $.wikiEditor.modules.toc.fn.build( context );
 1853+ $.wikiEditor.modules.toc.fn.update( context );
 1854+ context.$textarea
 1855+ .bind( 'keyup encapsulateSelection',
 1856+ function( event ) {
 1857+ var context = $(this).data( 'context' );
 1858+ $(this).eachAsync( {
 1859+ bulk: 0,
 1860+ loop: function() {
 1861+ $.wikiEditor.modules.toc.fn.build( context );
 1862+ $.wikiEditor.modules.toc.fn.update( context );
 1863+ }
 1864+ } );
 1865+ }
 1866+ )
 1867+ .bind( 'mouseup scrollToPosition',
 1868+ function( event ) {
 1869+ var context = $(this).data( 'context' );
 1870+ $(this).eachAsync( {
 1871+ bulk: 0,
 1872+ loop: function() {
 1873+ $.wikiEditor.modules.toc.fn.update( context );
 1874+ }
 1875+ } );
 1876+ }
 1877+ );
 1878+ },
 1879+ /**
 1880+ * Highlight the section the cursor is currently within
 1881+ *
 1882+ * @param {Object} context
 1883+ */
 1884+ update: function( context ) {
 1885+ context.modules.$toc.find( 'a' ).removeClass( 'currentSelection' );
 1886+ var position = context.$textarea.getCaretPosition();
 1887+ var section = 0;
 1888+ if ( context.data.outline.length > 0 ) {
 1889+ // If the caret is before the first heading, you must be in section
 1890+ // 0, and there is no need to look any farther - otherwise check
 1891+ // that the caret is before each section, and when it's not, we now
 1892+ // know what section it is in
 1893+ if ( !( position < context.data.outline[0].position - 1 ) ) {
 1894+ while (
 1895+ section < context.data.outline.length && context.data.outline[section].position - 1 < position
 1896+ ) {
 1897+ section++;
 1898+ }
 1899+ section = Math.max( 0, section );
 1900+ }
 1901+ context.modules.$toc.find( 'a.section-' + section ).addClass( 'currentSelection' );
 1902+ }
 1903+ },
 1904+ /**
 1905+ * Builds table of contents
 1906+ *
 1907+ * @param {Object} context
 1908+ */
 1909+ build: function( context ) {
 1910+ /**
 1911+ * Builds a structured outline from flat outline
 1912+ *
 1913+ * @param {Object} outline Array of objects with level fields
 1914+ */
 1915+ function buildStructure( outline, offset, level ) {
 1916+ if ( offset == undefined ) offset = 0;
 1917+ if ( level == undefined ) level = 1;
 1918+ var sections = [];
 1919+ for ( var i = offset; i < outline.length; i++ ) {
 1920+ if ( outline[i].nLevel == level ) {
 1921+ var sub = buildStructure( outline, i + 1, level + 1 );
 1922+ if ( sub.length ) {
 1923+ outline[i].sections = sub;
 1924+ }
 1925+ sections[sections.length] = outline[i];
 1926+ } else if ( outline[i].nLevel < level ) {
 1927+ break;
 1928+ }
 1929+ }
 1930+ return sections;
 1931+ }
 1932+ /**
 1933+ * Bulds unordered list HTML object from structured outline
 1934+ *
 1935+ * @param {Object} structure Structured outline
 1936+ */
 1937+ function buildList( structure ) {
 1938+ var list = $( '<ul></ul>' );
 1939+ for ( i in structure ) {
 1940+ var item = $( '<li></li>' )
 1941+ .append(
 1942+ $( '<a></a>' )
 1943+ .attr( 'href', '#' )
 1944+ .addClass( 'section-' + structure[i].index )
 1945+ .data( 'textbox', context.$textarea )
 1946+ .data( 'position', structure[i].position )
 1947+ .click( function( event ) {
 1948+ $(this).data( 'textbox' ).scrollToCaretPosition( $(this).data( 'position' ) );
 1949+ event.preventDefault();
 1950+ } )
 1951+ .text( structure[i].text )
 1952+ );
 1953+ if ( structure[i].sections !== undefined ) {
 1954+ item.append( buildList( structure[i].sections ) );
 1955+ }
 1956+ list.append( item );
 1957+ }
 1958+ return list;
 1959+ }
 1960+ // Build outline from wikitext
 1961+ var outline = [];
 1962+ var wikitext = '\n' + context.$textarea.val() + '\n';
 1963+ var headings = wikitext.match( /\n={1,5}.*={1,5}(?=\n)/g );
 1964+ var offset = 0;
 1965+ headings = $.makeArray( headings );
 1966+ for ( var h = 0; h < headings.length; h++ ) {
 1967+ text = headings[h];
 1968+ // Get position of first occurence
 1969+ var position = wikitext.indexOf( text, offset );
 1970+ // Update offset to avoid stumbling on duplicate headings
 1971+ if ( position > offset ) {
 1972+ offset = position;
 1973+ } else if ( position == -1 ) {
 1974+ // Not sure this is possible, or what should happen
 1975+ continue;
 1976+ }
 1977+ // Trim off whitespace
 1978+ text = $.trim( text );
 1979+ // Detect the starting and ending heading levels
 1980+ var startLevel = 0;
 1981+ for ( var c = 0; c < text.length; c++ ) {
 1982+ if ( text.charAt( c ) == '=' ) {
 1983+ startLevel++;
 1984+ } else {
 1985+ break;
 1986+ }
 1987+ }
 1988+ var endLevel = 0;
 1989+ for ( var c = text.length - 1; c >= 0; c-- ) {
 1990+ if ( text.charAt( c ) == '=' ) {
 1991+ endLevel++;
 1992+ } else {
 1993+ break;
 1994+ }
 1995+ }
 1996+ // Use the lowest number of =s as the actual level
 1997+ var level = Math.min( startLevel, endLevel );
 1998+ text = $.trim( text.substr( level, text.length - ( level * 2 ) ) );
 1999+ // Add the heading data to the outline
 2000+ outline[h] = { 'text': text, 'position': position, 'level': level, 'index': h + 1 };
 2001+ }
 2002+ // Normalize heading levels for list creation
 2003+ // This is based on Linker::generateTOC() so, it should behave like the
 2004+ // TOC on rendered articles does - which is considdered to be correct
 2005+ // at this point in time.
 2006+ var lastLevel = 0;
 2007+ var nLevel = 0;
 2008+ for ( var i = 0; i < outline.length; i++ ) {
 2009+ if ( outline[i].level > lastLevel ) {
 2010+ nLevel++;
 2011+ }
 2012+ else if ( outline[i].level < nLevel ) {
 2013+ nLevel -= Math.max( 1, lastLevel - outline[i].level );
 2014+ }
 2015+ if ( nLevel <= 0 ) {
 2016+ nLevel = 1;
 2017+ }
 2018+ outline[i].nLevel = nLevel;
 2019+ lastLevel = outline[i].level;
 2020+ }
 2021+ // Recursively build the structure and add special item for
 2022+ // section 0, if needed
 2023+ var structure = buildStructure( outline );
 2024+ if ( $( 'input[name=wpSection]' ).val() == '' )
 2025+ structure.unshift( { 'text': wgPageName.replace(/_/g, ' '), 'level': 1, 'index': 0, 'position': 0 } );
 2026+ context.modules.$toc.html( buildList( structure ) );
 2027+ // Cache the outline for later use
 2028+ context.data.outline = outline;
 2029+ }
 2030+}
 2031+
 2032+}; } ) ( jQuery );
\ No newline at end of file
Index: trunk/extensions/UsabilityInitiative/js/plugins.combined.min.js
@@ -107,34 +107,16 @@
108108 return($.os.name=='mac'?13:($.os.name=='linux'?15:16))*row;}
109109 return this.each(function(){$(this).focus();if(this.selectionStart||this.selectionStart=='0'){this.selectionStart=pos;this.selectionEnd=pos;$(this).scrollTop(getCaretScrollPosition(this));}else if(document.selection&&document.selection.createRange){var range=document.selection.createRange();var oldPos=$(this).getCaretPosition();var goBack=false;if(oldPos==pos){pos++;goBack=true;}
110110 range.moveToElementText(this);range.collapse();range.move('character',pos);range.select();this.scrollTop+=range.offsetTop;if(goBack){range.move('character',-1);range.select();}}
111 -$(this).trigger('scrollToPosition');});}});})(jQuery);RegExp.escape=function(s){return s.replace(/([.*+?^${}()|\/\\[\]])/g,'\\$1');};(function($){$.wikiEditor.modules.dialogs={api:{addDialog:function(context,data){$.wikiEditor.modules.dialogs.fn.create(context,{'modules':data})},openDialog:function(context,data){if(data.dialog in $.wikiEditor.modules.dialogs.modules){$('#'+$.wikiEditor.modules.dialogs.modules[data.dialog].id).dialog('open');}},closeDialog:function(context,data){if(data.dialog in $.wikiEditor.modules.dialogs.modules){$('#'+$.wikiEditor.modules.dialogs.modules[data.dialog].id).dialog('close');}}},fn:{create:function(context,config){for(module in config){$.wikiEditor.modules.dialogs.modules[module]=config[module];}
112 -for(module in $.wikiEditor.modules.dialogs.modules){var module=$.wikiEditor.modules.dialogs.modules[module];if($('#'+module.id).size()==0){var configuration=module.dialog;configuration.bgiframe=true;configuration.autoOpen=false;configuration.modal=true;configuration.title=$.wikiEditor.autoMsg(module,'title');for(msg in configuration.buttons){configuration.buttons[gM(msg)]=configuration.buttons[msg];delete configuration.buttons[msg];}
113 -$('<div /> ').attr('id',module.id).html(module.html).data('context',context).appendTo($('body')).each(module.init).dialog(configuration);}}}},'modules':{}};})(jQuery);(function($){$.wikiEditor={'modules':{},'instances':[],'supportedBrowsers':{'ltr':{'msie':7,'firefox':2,'opera':9,'safari':3,'chrome':1,'camino':1},'rtl':{'msie':8,'firefox':2,'opera':9,'safari':3,'chrome':1,'camino':1}},imgPath:wgScriptPath+'/extensions/UsabilityInitiative/images/wikiEditor/'};$.wikiEditor.isSupportKnown=function(){return(function(supportedBrowsers){return $.browser.name in supportedBrowsers;})($.wikiEditor.supportedBrowsers[$('body.rtl').size()?'rtl':'ltr']);};$.wikiEditor.isSupported=function(){return(function(supportedBrowsers){return $.browser.name in supportedBrowsers&&$.browser.versionNumber>=supportedBrowsers[$.browser.name];})($.wikiEditor.supportedBrowsers[$('body.rtl').size()?'rtl':'ltr']);};$.wikiEditor.autoMsg=function(object,property){if(typeof property=='object'){for(i in property){if(property[i]in object||property[i]+'Msg'in object){property=property[i];break;}}}
 111+$(this).trigger('scrollToPosition');});}});})(jQuery);(function($){$.wikiEditor={'modules':{},'instances':[],'supportedBrowsers':{'ltr':{'msie':7,'firefox':2,'opera':9,'safari':3,'chrome':1,'camino':1},'rtl':{'msie':8,'firefox':2,'opera':9,'safari':3,'chrome':1,'camino':1}},imgPath:wgScriptPath+'/extensions/UsabilityInitiative/images/wikiEditor/'};$.wikiEditor.isSupportKnown=function(){return(function(supportedBrowsers){return $.browser.name in supportedBrowsers;})($.wikiEditor.supportedBrowsers[$('body.rtl').size()?'rtl':'ltr']);};$.wikiEditor.isSupported=function(){return(function(supportedBrowsers){return $.browser.name in supportedBrowsers&&$.browser.versionNumber>=supportedBrowsers[$.browser.name];})($.wikiEditor.supportedBrowsers[$('body.rtl').size()?'rtl':'ltr']);};$.wikiEditor.autoMsg=function(object,property){if(typeof property=='object'){for(i in property){if(property[i]in object||property[i]+'Msg'in object){property=property[i];break;}}}
114112 if(property in object){return object[property];}else if(property+'Msg'in object){return gM(object[property+'Msg']);}else{return'';}};$.fn.wikiEditor=function(){var context=$(this).data('context');if(typeof context!=='undefined'){arguments=$.makeArray(arguments);if(arguments.length>0){var call=arguments.shift();if(call in context.api){context.api[call](context,arguments[0]==undefined?{}:arguments[0]);}
115113 return $(this).data('context',context);}
116114 return $(this);}
117115 var instance=$.wikiEditor.instances.length;context={'$textarea':$(this),'modules':{},'data':{},'instance':instance};$.wikiEditor.instances[instance]=$(this);$(this).wrap($('<div></div>').addClass('wikiEditor-ui').attr('id','wikiEditor-ui')).wrap($('<div></div>').addClass('wikiEditor-ui-bottom').attr('id','wikiEditor-ui-bottom')).wrap($('<div></div>').addClass('wikiEditor-ui-text').attr('id','wikiEditor-ui-text'));context.$ui=$(this).parent().parent().parent();context.$ui.after($('<div style="clear:both;"></div>'));context.$ui.prepend($('<div></div>').addClass('wikiEditor-ui-top').attr('id','wikiEditor-ui-top'));context.api={addModule:function(context,data){function callModuleApi(module,call,data){if(module in $.wikiEditor.modules&&'fn'in $.wikiEditor.modules[module]&&call in $.wikiEditor.modules[module].fn){$.wikiEditor.modules[module].fn[call](context,data);}}
118116 if(typeof data=='string'){callModuleApi(data,'create',{});}else if(typeof data=='object'){for(module in data){if(typeof module=='string'){callModuleApi(module,'create',data[module]);}}}}};for(module in $.wikiEditor.modules){if('api'in $.wikiEditor.modules[module]){for(call in $.wikiEditor.modules[module].api){if(!(call in context.api)){context.api[call]=$.wikiEditor.modules[module].api[call];}}}}
119117 if(arguments.length>0&&typeof arguments[0]=='object'){context.api.addModule(context,arguments[0]);}
120 -context.$textarea.scrollToCaretPosition(0);return $(this).data('context',context);};})(jQuery);(function($){$.wikiEditor.modules.toc={api:{},fn:{create:function(context,config){if('$toc'in context.modules){return;}
121 -context.modules.$toc=$('<div></div>').addClass('wikiEditor-ui-toc').attr('id','wikiEditor-ui-toc');$.wikiEditor.modules.toc.fn.build(context,config);context.$ui.find('.wikiEditor-ui-bottom').append(context.modules.$toc);context.modules.$toc.height(context.$ui.find('.wikiEditor-ui-bottom').height());context.modules.$toc.css('width','12em').css('marginTop',-(context.$ui.find('.wikiEditor-ui-bottom').height()));context.$ui.find('.wikiEditor-ui-text').css(($('body.rtl').size()?'marginLeft':'marginRight'),'12em');$.wikiEditor.modules.toc.fn.build(context);$.wikiEditor.modules.toc.fn.update(context);context.$textarea.bind('keyup encapsulateSelection',function(event){var context=$(this).data('context');$(this).eachAsync({bulk:0,loop:function(){$.wikiEditor.modules.toc.fn.build(context);$.wikiEditor.modules.toc.fn.update(context);}});}).bind('mouseup scrollToPosition',function(event){var context=$(this).data('context');$(this).eachAsync({bulk:0,loop:function(){$.wikiEditor.modules.toc.fn.update(context);}});});},update:function(context){context.modules.$toc.find('a').removeClass('currentSelection');var position=context.$textarea.getCaretPosition();var section=0;if(context.data.outline.length>0){if(!(position<context.data.outline[0].position-1)){while(section<context.data.outline.length&&context.data.outline[section].position-1<position){section++;}
122 -section=Math.max(0,section);}
123 -context.modules.$toc.find('a.section-'+section).addClass('currentSelection');}},build:function(context){function buildStructure(outline,offset,level){if(offset==undefined)offset=0;if(level==undefined)level=1;var sections=[];for(var i=offset;i<outline.length;i++){if(outline[i].nLevel==level){var sub=buildStructure(outline,i+1,level+1);if(sub.length){outline[i].sections=sub;}
124 -sections[sections.length]=outline[i];}else if(outline[i].nLevel<level){break;}}
125 -return sections;}
126 -function buildList(structure){var list=$('<ul></ul>');for(i in structure){var item=$('<li></li>').append($('<a></a>').attr('href','#').addClass('section-'+structure[i].index).data('textbox',context.$textarea).data('position',structure[i].position).click(function(event){$(this).data('textbox').scrollToCaretPosition($(this).data('position'));event.preventDefault();}).text(structure[i].text));if(structure[i].sections!==undefined){item.append(buildList(structure[i].sections));}
127 -list.append(item);}
128 -return list;}
129 -var outline=[];var wikitext='\n'+context.$textarea.val()+'\n';var headings=wikitext.match(/\n={1,5}.*={1,5}(?=\n)/g);var offset=0;headings=$.makeArray(headings);for(var h=0;h<headings.length;h++){text=headings[h];var position=wikitext.indexOf(text,offset);if(position>offset){offset=position;}else if(position==-1){continue;}
130 -text=$.trim(text);var startLevel=0;for(var c=0;c<text.length;c++){if(text.charAt(c)=='='){startLevel++;}else{break;}}
131 -var endLevel=0;for(var c=text.length-1;c>=0;c--){if(text.charAt(c)=='='){endLevel++;}else{break;}}
132 -var level=Math.min(startLevel,endLevel);text=$.trim(text.substr(level,text.length-(level*2)));outline[h]={'text':text,'position':position,'level':level,'index':h+1};}
133 -var lastLevel=0;var nLevel=0;for(var i=0;i<outline.length;i++){if(outline[i].level>lastLevel){nLevel++;}
134 -else if(outline[i].level<nLevel){nLevel-=Math.max(1,lastLevel-outline[i].level);}
135 -if(nLevel<=0){nLevel=1;}
136 -outline[i].nLevel=nLevel;lastLevel=outline[i].level;}
137 -var structure=buildStructure(outline);if($('input[name=wpSection]').val()=='')
138 -structure.unshift({'text':wgPageName.replace(/_/g,' '),'level':1,'index':0,'position':0});context.modules.$toc.html(buildList(structure));context.data.outline=outline;}}};})(jQuery);(function($){$.wikiEditor.modules.toolbar={api:{addToToolbar:function(context,data){for(type in data){switch(type){case'sections':var $sections=context.modules.$toolbar.find('div.sections');var $tabs=context.modules.$toolbar.find('div.tabs');for(section in data[type]){if(section=='main'){context.modules.$toolbar.prepend($.wikiEditor.modules.toolbar.fn.buildSection(context,section,data[type][section]));continue;}
 118+context.$textarea.scrollToCaretPosition(0);return $(this).data('context',context);};})(jQuery);RegExp.escape=function(s){return s.replace(/([.*+?^${}()|\/\\[\]])/g,'\\$1');};(function($){$.wikiEditor.modules.dialogs={api:{addDialog:function(context,data){$.wikiEditor.modules.dialogs.fn.create(context,{'modules':data})},openDialog:function(context,data){if(data.dialog in $.wikiEditor.modules.dialogs.modules){$('#'+$.wikiEditor.modules.dialogs.modules[data.dialog].id).dialog('open');}},closeDialog:function(context,data){if(data.dialog in $.wikiEditor.modules.dialogs.modules){$('#'+$.wikiEditor.modules.dialogs.modules[data.dialog].id).dialog('close');}}},fn:{create:function(context,config){for(module in config){$.wikiEditor.modules.dialogs.modules[module]=config[module];}
 119+for(module in $.wikiEditor.modules.dialogs.modules){var module=$.wikiEditor.modules.dialogs.modules[module];if($('#'+module.id).size()==0){var configuration=module.dialog;configuration.bgiframe=true;configuration.autoOpen=false;configuration.modal=true;configuration.title=$.wikiEditor.autoMsg(module,'title');for(msg in configuration.buttons){configuration.buttons[gM(msg)]=configuration.buttons[msg];delete configuration.buttons[msg];}
 120+$('<div /> ').attr('id',module.id).html(module.html).data('context',context).appendTo($('body')).each(module.init).dialog(configuration);}}}},'modules':{}};})(jQuery);(function($){$.wikiEditor.modules.toolbar={api:{addToToolbar:function(context,data){for(type in data){switch(type){case'sections':var $sections=context.modules.$toolbar.find('div.sections');var $tabs=context.modules.$toolbar.find('div.tabs');for(section in data[type]){if(section=='main'){context.modules.$toolbar.prepend($.wikiEditor.modules.toolbar.fn.buildSection(context,section,data[type][section]));continue;}
139121 $sections.append($.wikiEditor.modules.toolbar.fn.buildSection(context,section,data[type][section]));$tabs.append($.wikiEditor.modules.toolbar.fn.buildTab(context,section,data[type][section]));}
140122 break;case'groups':if(!('section'in data)){continue;}
141123 var $section=context.modules.$toolbar.find('div[rel='+data.section+'].section');for(group in data[type]){$section.append($.wikiEditor.modules.toolbar.fn.buildGroup(context,group,data[type][group]));}
@@ -173,10 +155,29 @@
174156 $.wikiEditor.autoMsg(row[cell],['html','text'])+'</span></td>';}
175157 html+='</tr>';return html;},buildCharacter:function(character,actions){if(typeof character=='string'){character={'label':character,'action':{'type':'encapsulate','options':{'pre':character}}};}else if(0 in character&&1 in character){character={'label':character[0],'action':{'type':'encapsulate','options':{'pre':character[1]}}};}
176158 if('action'in character&&'label'in character){actions[character.label]=character.action;return'<a rel="'+character.label+'" href="#">'+character.label+'</a>';}},buildTab:function(context,id,section){var selected=$.cookie('wikiEditor-'+context.instance+'-toolbar-section');return $('<span />').attr({'class':'tab tab-'+id,'rel':id}).append($('<a />').addClass(selected==id?'current':null).attr('href','#').text($.wikiEditor.autoMsg(section,'label')).data('context',context).click(function(){var $section=$(this).data('context').$ui.find('.section-'+$(this).parent().attr('rel'));$(this).blur();var show=$section.css('display')=='none';$section.parent().children().hide();$(this).parent().parent().find('a').removeClass('current');if(show){$section.show();$(this).addClass('current');}
 159+if($.trackAction!=undefined){$.trackAction($section.attr('rel')+'.'+(show?'show':'hide'));}
177160 $.cookie('wikiEditor-'+$(this).data('context').instance+'-toolbar-section',show?$section.attr('rel'):null);return false;}));},buildSection:function(context,id,section){var selected=$.cookie('wikiEditor-'+context.instance+'-toolbar-section');var $section;switch(section.type){case'toolbar':var $section=$('<div />').attr({'class':'toolbar section section-'+id,'rel':id});if('groups'in section){for(group in section.groups){$section.append($.wikiEditor.modules.toolbar.fn.buildGroup(context,group,section.groups[group]));}}
178161 break;case'booklet':var $pages=$('<div />').addClass('pages');var $index=$('<div />').addClass('index');if('pages'in section){for(page in section.pages){$pages.append($.wikiEditor.modules.toolbar.fn.buildPage(context,page,section.pages[page]));$index.append($.wikiEditor.modules.toolbar.fn.buildBookmark(context,page,section.pages[page]));}}
179162 $section=$('<div />').attr({'class':'booklet section section-'+id,'rel':id}).append($index).append($pages);$.wikiEditor.modules.toolbar.fn.updateBookletSelection(context,page,$pages,$index);break;}
180163 if($section!==null&&id!=='main'){$section.css('display',selected==id?'block':'none');}
181164 return $section;},updateBookletSelection:function(context,id,$pages,$index){var cookie='wikiEditor-'+context.instance+'-booklet-'+id+'-page';var selected=$.cookie(cookie);var $selectedIndex=$index.find('*[rel='+selected+']');if($selectedIndex.size()==0){selected=$index.children().eq(0).attr('rel');$.cookie(cookie,selected);}
182165 $pages.children().hide();$pages.find('*[rel='+selected+']').show();$index.children().removeClass('current');$selectedIndex.addClass('current');},build:function(context,config){var $tabs=$('<div />').addClass('tabs').appendTo(context.modules.$toolbar);var $sections=$('<div />').addClass('sections').appendTo(context.modules.$toolbar);context.modules.$toolbar.append($('<div />').css('clear','both'));var sectionQueue=[];for(section in config){if(section=='main'){context.modules.$toolbar.prepend($.wikiEditor.modules.toolbar.fn.buildSection(context,section,config[section]));}else{sectionQueue.push({'$sections':$sections,'context':context,'id':section,'config':config[section]});$tabs.append($.wikiEditor.modules.toolbar.fn.buildTab(context,section,config[section]));}}
183 -$.eachAsync(sectionQueue,{'bulk':0,'end':function(){$('body').css('position','static');$('body').css('position','relative');},'loop':function(i,s){s.$sections.append($.wikiEditor.modules.toolbar.fn.buildSection(s.context,s.id,s.config));}});}}};})(jQuery);
\ No newline at end of file
 166+$.eachAsync(sectionQueue,{'bulk':0,'end':function(){$('body').css('position','static');$('body').css('position','relative');},'loop':function(i,s){s.$sections.append($.wikiEditor.modules.toolbar.fn.buildSection(s.context,s.id,s.config));}});}}};})(jQuery);(function($){$.wikiEditor.modules.toc={api:{},fn:{create:function(context,config){if('$toc'in context.modules){return;}
 167+context.modules.$toc=$('<div></div>').addClass('wikiEditor-ui-toc').attr('id','wikiEditor-ui-toc');$.wikiEditor.modules.toc.fn.build(context,config);context.$ui.find('.wikiEditor-ui-bottom').append(context.modules.$toc);context.modules.$toc.height(context.$ui.find('.wikiEditor-ui-bottom').height());context.modules.$toc.css('width','12em').css('marginTop',-(context.$ui.find('.wikiEditor-ui-bottom').height()));context.$ui.find('.wikiEditor-ui-text').css(($('body.rtl').size()?'marginLeft':'marginRight'),'12em');$.wikiEditor.modules.toc.fn.build(context);$.wikiEditor.modules.toc.fn.update(context);context.$textarea.bind('keyup encapsulateSelection',function(event){var context=$(this).data('context');$(this).eachAsync({bulk:0,loop:function(){$.wikiEditor.modules.toc.fn.build(context);$.wikiEditor.modules.toc.fn.update(context);}});}).bind('mouseup scrollToPosition',function(event){var context=$(this).data('context');$(this).eachAsync({bulk:0,loop:function(){$.wikiEditor.modules.toc.fn.update(context);}});});},update:function(context){context.modules.$toc.find('a').removeClass('currentSelection');var position=context.$textarea.getCaretPosition();var section=0;if(context.data.outline.length>0){if(!(position<context.data.outline[0].position-1)){while(section<context.data.outline.length&&context.data.outline[section].position-1<position){section++;}
 168+section=Math.max(0,section);}
 169+context.modules.$toc.find('a.section-'+section).addClass('currentSelection');}},build:function(context){function buildStructure(outline,offset,level){if(offset==undefined)offset=0;if(level==undefined)level=1;var sections=[];for(var i=offset;i<outline.length;i++){if(outline[i].nLevel==level){var sub=buildStructure(outline,i+1,level+1);if(sub.length){outline[i].sections=sub;}
 170+sections[sections.length]=outline[i];}else if(outline[i].nLevel<level){break;}}
 171+return sections;}
 172+function buildList(structure){var list=$('<ul></ul>');for(i in structure){var item=$('<li></li>').append($('<a></a>').attr('href','#').addClass('section-'+structure[i].index).data('textbox',context.$textarea).data('position',structure[i].position).click(function(event){$(this).data('textbox').scrollToCaretPosition($(this).data('position'));event.preventDefault();}).text(structure[i].text));if(structure[i].sections!==undefined){item.append(buildList(structure[i].sections));}
 173+list.append(item);}
 174+return list;}
 175+var outline=[];var wikitext='\n'+context.$textarea.val()+'\n';var headings=wikitext.match(/\n={1,5}.*={1,5}(?=\n)/g);var offset=0;headings=$.makeArray(headings);for(var h=0;h<headings.length;h++){text=headings[h];var position=wikitext.indexOf(text,offset);if(position>offset){offset=position;}else if(position==-1){continue;}
 176+text=$.trim(text);var startLevel=0;for(var c=0;c<text.length;c++){if(text.charAt(c)=='='){startLevel++;}else{break;}}
 177+var endLevel=0;for(var c=text.length-1;c>=0;c--){if(text.charAt(c)=='='){endLevel++;}else{break;}}
 178+var level=Math.min(startLevel,endLevel);text=$.trim(text.substr(level,text.length-(level*2)));outline[h]={'text':text,'position':position,'level':level,'index':h+1};}
 179+var lastLevel=0;var nLevel=0;for(var i=0;i<outline.length;i++){if(outline[i].level>lastLevel){nLevel++;}
 180+else if(outline[i].level<nLevel){nLevel-=Math.max(1,lastLevel-outline[i].level);}
 181+if(nLevel<=0){nLevel=1;}
 182+outline[i].nLevel=nLevel;lastLevel=outline[i].level;}
 183+var structure=buildStructure(outline);if($('input[name=wpSection]').val()=='')
 184+structure.unshift({'text':wgPageName.replace(/_/g,' '),'level':1,'index':0,'position':0});context.modules.$toc.html(buildList(structure));context.data.outline=outline;}}};})(jQuery);
\ No newline at end of file

Past revisions this follows-up on

RevisionCommit summaryAuthorDate
r20485move to language subdirbrion14:10, 15 March 2007

Comments

#Comment by Mormegil (talk | contribs)   19:58, 3 September 2009

That would be “Solves bug #20485”, not “Solves r20485”. ;-)

#Comment by Trevor Parscal (WMF) (talk | contribs)   20:17, 3 September 2009

Yes, sorry - that's what I meant...

Status & tagging log