r56417 MediaWiki - Code Review archive

Repository:MediaWiki
Revision:r56416‎ | r56417 | r56418 >
Date:15:33, 16 September 2009
Author:catrope
Status:ok (Comments)
Tags:
Comment:
UsabilityInitiative:
* Make NavigableTOC disableable with a preference, similar to EditToolbar
* Make content generation dialogs (CGDs) in EditToolbar disableable with a preference; bring back the old ilink, xlink and table dialogs to show when CGDs are disabled
** Resurrected the edittoolbar-{i,x}link-{,example} messages; Nikerabbit says i18n for these will sort itself out
** Resurrected the old edittoolbar-table-example (pre-r55207) as edittoolbar-table-example-old, because table-example was repurposed (evil, I know); this is probably trickier i18n-wise
** Resurrected the xlink and ilink icons
* Moved code around in wikiEditor.js so it doesn't depend on the first call being in object mode; with the toolbar disabled and NTOC enabled, this broke because NTOC uses two-param mode
* Do injection of JS vars properly
* Kill some 'context not defined' errors in NTOC
Modified paths:
  • /trunk/extensions/UsabilityInitiative/ClickTracking/ClickTracking.hooks.php (modified) (history)
  • /trunk/extensions/UsabilityInitiative/EditToolbar/EditToolbar.hooks.php (modified) (history)
  • /trunk/extensions/UsabilityInitiative/EditToolbar/EditToolbar.i18n.php (modified) (history)
  • /trunk/extensions/UsabilityInitiative/EditToolbar/EditToolbar.js (modified) (history)
  • /trunk/extensions/UsabilityInitiative/EditToolbar/EditToolbar.php (modified) (history)
  • /trunk/extensions/UsabilityInitiative/NavigableTOC/NavigableTOC.hooks.php (modified) (history)
  • /trunk/extensions/UsabilityInitiative/NavigableTOC/NavigableTOC.i18n.php (modified) (history)
  • /trunk/extensions/UsabilityInitiative/NavigableTOC/NavigableTOC.php (modified) (history)
  • /trunk/extensions/UsabilityInitiative/UsabilityInitiative.hooks.php (modified) (history)
  • /trunk/extensions/UsabilityInitiative/UsabilityInitiative.php (modified) (history)
  • /trunk/extensions/UsabilityInitiative/images/wikiEditor/toolbar/insert-ilink.png (added) (history)
  • /trunk/extensions/UsabilityInitiative/images/wikiEditor/toolbar/insert-xlink.png (added) (history)
  • /trunk/extensions/UsabilityInitiative/js/plugins.combined.js (modified) (history)
  • /trunk/extensions/UsabilityInitiative/js/plugins.combined.min.js (modified) (history)
  • /trunk/extensions/UsabilityInitiative/js/plugins/jquery.wikiEditor.js (modified) (history)
  • /trunk/extensions/UsabilityInitiative/js/plugins/jquery.wikiEditor.toc.js (modified) (history)

Diff [purge]

Index: trunk/extensions/UsabilityInitiative/UsabilityInitiative.php
@@ -45,3 +45,4 @@
4646
4747 // Registers Hooks
4848 $wgHooks['BeforePageDisplay'][] = 'UsabilityInitiativeHooks::addResources';
 49+$wgHooks['MakeGlobalVariablesScript'][] = 'UsabilityInitiativeHooks::addJSVars';
\ No newline at end of file
Index: trunk/extensions/UsabilityInitiative/NavigableTOC/NavigableTOC.i18n.php
@@ -14,6 +14,7 @@
1515 $messages['en'] = array(
1616 'navigabletoc' => 'Navigable table of contents',
1717 'navigabletoc-desc' => 'Adds a table of contents to the edit form that scrolls the text box when a section is clicked',
 18+ 'navigabletoc-preference' => 'Enable navigable table of contents',
1819 );
1920
2021 /** Afrikaans (Afrikaans)
Index: trunk/extensions/UsabilityInitiative/NavigableTOC/NavigableTOC.php
@@ -18,6 +18,14 @@
1919
2020 /* Configuration */
2121
 22+// Set this to true to simply force NavigableTOC on everyone
 23+$wgNavigableTOCGlobalEnable = false;
 24+
 25+// Set this to true to add a preference to the editing section of preferences
 26+// which enables and disables NavigableTOC (if $wgNavigableTOCGlobalEnable, this
 27+// will not do anything)
 28+$wgNavigableTOCUserEnable = true;
 29+
2230 // Bump the version number every time you change any of the .css/.js files
2331 $wgNavigableTOCStyleVersion = 3;
2432
@@ -45,4 +53,5 @@
4654 dirname( __FILE__ ) . '/NavigableTOC.i18n.php';
4755
4856 // Registers Hooks
49 -$wgHooks['EditPageBeforeEditToolbar'][] = 'NavigableTOCHooks::addTOC';
\ No newline at end of file
 57+$wgHooks['EditPageBeforeEditToolbar'][] = 'NavigableTOCHooks::addTOC';
 58+$wgHooks['GetPreferences'][] = 'NavigableTOCHooks::addPreferences';
Index: trunk/extensions/UsabilityInitiative/NavigableTOC/NavigableTOC.hooks.php
@@ -15,14 +15,36 @@
1616 * Adds the TOC to the edit form
1717 */
1818 public static function addTOC( &$toolbar ) {
19 - global $wgNavigableTOCStyleVersion, $wgParser, $wgUser;
20 - global $wgEnableParserCache;
 19+ global $wgNavigableTOCStyleVersion, $wgUser;
 20+ global $wgNavigableTOCGlobalEnable, $wgNavigableTOCUserEnable;
2121
22 - // Adds script to document
23 - UsabilityInitiativeHooks::initialize();
24 - UsabilityInitiativeHooks::addScript(
25 - 'NavigableTOC/NavigableTOC.js', $wgNavigableTOCStyleVersion
26 - );
 22+ if ( $wgNavigableTOCGlobalEnable || ( $wgNavigableTOCUserEnable && $wgUser->getOption( 'usenavigabletoc' ) ) ) {
 23+ // Adds script to document
 24+ UsabilityInitiativeHooks::initialize();
 25+ UsabilityInitiativeHooks::addScript(
 26+ 'NavigableTOC/NavigableTOC.js', $wgNavigableTOCStyleVersion
 27+ );
 28+ }
2729 return true;
2830 }
 31+
 32+ /**
 33+ * GetPreferences hook
 34+ * Add NTOC-related items to the preferences
 35+ */
 36+ public static function addPreferences( $user, &$defaultPreferences ) {
 37+ global $wgNavigableTOCGlobalEnable, $wgNavigableTOCUserEnable;
 38+
 39+ if ( !$wgNavigableTOCGlobalEnable && $wgNavigableTOCUserEnable ) {
 40+ wfLoadExtensionMessages( 'NavigableTOC' );
 41+ // Adds preference for opting in
 42+ $defaultPreferences['usenavigabletoc'] =
 43+ array(
 44+ 'type' => 'toggle',
 45+ 'label-message' => 'navigabletoc-preference',
 46+ 'section' => 'editing/advancedediting',
 47+ );
 48+ }
 49+ return true;
 50+ }
2951 }
Index: trunk/extensions/UsabilityInitiative/UsabilityInitiative.hooks.php
@@ -63,17 +63,17 @@
6464 array( 'src' => 'js/plugins/jquery.namespaceSelect.js', 'version' => 1 ),
6565 array( 'src' => 'js/plugins/jquery.suggestions.js', 'version' => 3 ),
6666 array( 'src' => 'js/plugins/jquery.textSelection.js', 'version' => 9 ),
67 - array( 'src' => 'js/plugins/jquery.wikiEditor.js', 'version' => 4 ),
 67+ array( 'src' => 'js/plugins/jquery.wikiEditor.js', 'version' => 5 ),
6868 array( 'src' => 'js/plugins/jquery.wikiEditor.toolbar.js', 'version' => 11 ),
6969 array( 'src' => 'js/plugins/jquery.wikiEditor.dialogs.js', 'version' => 2 ),
70 - array( 'src' => 'js/plugins/jquery.wikiEditor.toc.js', 'version' => 5 ),
 70+ array( 'src' => 'js/plugins/jquery.wikiEditor.toc.js', 'version' => 6 ),
7171 array( 'src' => 'js/js2/jquery-ui-1.7.2.js', 'version' => '1.7.2x' ),
7272 ),
7373 'combined' => array(
74 - array( 'src' => 'js/plugins.combined.js', 'version' => 21 ),
 74+ array( 'src' => 'js/plugins.combined.js', 'version' => 22 ),
7575 ),
7676 'minified' => array(
77 - array( 'src' => 'js/plugins.combined.min.js', 'version' => 21 ),
 77+ array( 'src' => 'js/plugins.combined.min.js', 'version' => 22 ),
7878 ),
7979 ),
8080 );
@@ -125,31 +125,7 @@
126126
127127 if ( !self::$doOutput )
128128 return true;
129 - // Transforms variables into javascript global variables
130 - foreach ( self::$variables as $key => $value ) {
131 - $escapedVariableValue = Xml::escapeJsString( $value );
132 - $escapedVariableKey = Xml::escapeJsString( $key );
133 - self::$variables[$key] =
134 - "var {$escapedVariableKey} = '{$escapedVariableValue}';";
135 - }
136129
137 - //literal variables, ie ones we do not want escaped as strings
138 - foreach( self::$literalVariables as $key => $value){
139 - $escapedVariableValue = Xml::escapeJsString( $value );
140 - $escapedVariableKey = Xml::escapeJsString( $key );
141 - self::$variables[$key] =
142 - "var {$escapedVariableKey} = {$escapedVariableValue};";
143 - }
144 - if ( count( self::$variables ) > 0 ) {
145 - $out->addScript(
146 - Xml::tags(
147 - 'script',
148 - array( 'type' => $wgJsMimeType ),
149 - implode( self::$variables )
150 - )
151 - );
152 - }
153 -
154130 // Loops over each script
155131 foreach ( self::$scripts as $script ) {
156132 // Add javascript to document
@@ -199,6 +175,14 @@
200176 }
201177 return true;
202178 }
 179+
 180+ /**
 181+ * MakeGlobalVariablesScript hook
 182+ */
 183+ public static function addJSVars( &$vars ) {
 184+ $vars = array_merge( $vars, self::$variables );
 185+ return true;
 186+ }
203187
204188 /**
205189 * Adds a reference to a javascript file to the head of the document
@@ -234,13 +218,4 @@
235219 public static function addVariables( $variables ) {
236220 self::$variables = array_merge( self::$variables, $variables );
237221 }
238 -
239 - /**
240 - * Adds variables that will be turned into global variables in JS, but not escaped as strings
241 - * @param $variables array of "name" => "value"
242 - */
243 - public static function addLiteralVariables( $variables ) {
244 - self::$literalVariables = array_merge( self::$literalVariables, $variables );
245 - }
246 -
247222 }
Index: trunk/extensions/UsabilityInitiative/images/wikiEditor/toolbar/insert-ilink.png
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
Property changes on: trunk/extensions/UsabilityInitiative/images/wikiEditor/toolbar/insert-ilink.png
___________________________________________________________________
Name: svn:mime-type
248223 + application/octet-stream
Index: trunk/extensions/UsabilityInitiative/images/wikiEditor/toolbar/insert-xlink.png
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
Property changes on: trunk/extensions/UsabilityInitiative/images/wikiEditor/toolbar/insert-xlink.png
___________________________________________________________________
Name: svn:mime-type
249224 + application/octet-stream
Index: trunk/extensions/UsabilityInitiative/ClickTracking/ClickTracking.hooks.php
@@ -57,7 +57,7 @@
5858 'wgTrackingToken' => ClickTrackingHooks::get_session_id()
5959 )
6060 );
61 - UsabilityInitiativeHooks::addLiteralVariables(
 61+ UsabilityInitiativeHooks::addVariables(
6262 array(
6363 'wgClickTrackingIsThrottled' => ClickTrackingHooks::isUserThrottled()
6464 )
Index: trunk/extensions/UsabilityInitiative/EditToolbar/EditToolbar.hooks.php
@@ -15,7 +15,9 @@
1616 * Intercept the display of the toolbar, replacing the content of $toolbar
1717 */
1818 public static function addToolbar( &$toolbar ) {
19 - global $wgUser, $wgEditToolbarGlobalEnable, $wgEditToolbarUserEnable;
 19+ global $wgUser, $wgEditToolbarGlobalEnable;
 20+ global $wgEditToolbarUserEnable, $wgEditToolbarCGDGlobalEnable;
 21+ global $wgEditToolbarCGDUserEnable;
2022
2123 // Only proceed if some specific conditions are met
2224 if ( $wgEditToolbarGlobalEnable || ( $wgEditToolbarUserEnable && $wgUser->getOption( 'usebetatoolbar' ) ) ) {
@@ -25,6 +27,9 @@
2628 UsabilityInitiativeHooks::addScript(
2729 'EditToolbar/EditToolbar.js', $wgEditToolbarStyleVersion
2830 );
 31+ UsabilityInitiativeHooks::addVariables( array(
 32+ 'wgEditToolbarCGD' => $wgEditToolbarCGDGlobalEnable || ( $wgEditToolbarCGDUserEnable && $wgUser->getOption( 'usebetatoolbar-cgd' ) )
 33+ ) );
2934 // Internationalization
3035 wfLoadExtensionMessages( 'EditToolbar' );
3136 UsabilityInitiativeHooks::addMessages(
@@ -35,6 +40,10 @@
3641 'edittoolbar-tool-bold-example',
3742 'edittoolbar-tool-italic',
3843 'edittoolbar-tool-italic-example',
 44+ 'edittoolbar-tool-ilink',
 45+ 'edittoolbar-tool-ilink-example',
 46+ 'edittoolbar-tool-xlink',
 47+ 'edittoolbar-tool-xlink-example',
3948 'edittoolbar-tool-link',
4049 'edittoolbar-tool-link-title',
4150 'edittoolbar-tool-link-int',
@@ -86,6 +95,7 @@
8796 'edittoolbar-tool-gallery-example',
8897 'edittoolbar-tool-newline',
8998 'edittoolbar-tool-table',
 99+ 'edittoolbar-tool-table-example-old',
90100 'edittoolbar-tool-table-example',
91101 'edittoolbar-tool-table-example-header',
92102 'edittoolbar-tool-table-title',
@@ -198,15 +208,9 @@
199209 */
200210 public static function addPreferences( $user, &$defaultPreferences ) {
201211 global $wgEditToolbarGlobalEnable, $wgEditToolbarUserEnable;
 212+ global $wgEditToolbarCGDGlobalEnable, $wgEditToolbarCGDUserEnable;
202213
203 - // Checks if...
204 - if (
205 - // Toolbar is NOT globablly enabled
206 - !$wgEditToolbarGlobalEnable &&
207 - // And Toolbar is per-user enablable
208 - $wgEditToolbarUserEnable
209 - ) {
210 - // Internationalization
 214+ if ( !$wgEditToolbarGlobalEnable && $wgEditToolbarUserEnable ) {
211215 wfLoadExtensionMessages( 'EditToolbar' );
212216 // Adds preference for opting in
213217 $defaultPreferences['usebetatoolbar'] =
@@ -216,6 +220,15 @@
217221 'section' => 'editing/advancedediting',
218222 );
219223 }
 224+
 225+ if ( !$wgEditToolbarGlobalEnable && $wgEditToolbarUserEnable ) {
 226+ wfLoadExtensionMessages( 'EditToolbar' );
 227+ $defaultPreferences['usebetatoolbar-cgd'] = array(
 228+ 'type' => 'toggle',
 229+ 'label-message' => 'edittoolbar-cgd-preference',
 230+ 'section' => 'editing/advancedediting',
 231+ );
 232+ }
220233 return true;
221234 }
222235 }
Index: trunk/extensions/UsabilityInitiative/EditToolbar/EditToolbar.js
@@ -1,6 +1,10 @@
22 /* JavaScript for EditToolbar extension */
33
44 js2AddOnloadHook( function() {
 5+ // Only show content generation dialogs if enabled
 6+ if ( typeof wgEditToolbarCGD != 'undefined' && wgEditToolbarCGD )
 7+ $j( '#wpTextbox1' ).addClass( 'withCGD' );
 8+
59 if ( $j.wikiEditor != undefined && $j.wikiEditor.isSupported() || !$j.wikiEditor.isSupportKnown() ) {
610 // Remove the old toolbar
711 $j( '#toolbar' ).remove();
@@ -47,10 +51,39 @@
4852 },
4953 'insert': {
5054 tools: {
51 - 'link': {
 55+ 'xlink': {
 56+ labelMsg: 'edittoolbar-tool-xlink',
 57+ type: 'button',
 58+ icon: 'insert-xlink.png',
 59+ filters: [ '#wpTextbox1:not(.withCGD)' ],
 60+ action: {
 61+ type: 'encapsulate',
 62+ options: {
 63+ pre: "[",
 64+ periMsg: 'edittoolbar-tool-xlink-example',
 65+ post: "]"
 66+ }
 67+ }
 68+ },
 69+ 'ilink': {
 70+ labelMsg: 'edittoolbar-tool-ilink',
 71+ type: 'button',
 72+ icon: 'insert-ilink.png',
 73+ filters: [ '#wpTextbox1:not(.withCGD)' ],
 74+ action: {
 75+ type: 'encapsulate',
 76+ options: {
 77+ pre: "[[",
 78+ periMsg: 'edittoolbar-tool-ilink-example',
 79+ post: "]]"
 80+ }
 81+ }
 82+ },
 83+ 'linkCGD': {
5284 labelMsg: 'edittoolbar-tool-link',
5385 type: 'button',
5486 icon: 'insert-link.png',
 87+ filters: [ '#wpTextbox1.withCGD' ],
5588 action: {
5689 type: 'dialog',
5790 module: 'insert-link'
@@ -271,15 +304,30 @@
272305 }
273306 }
274307 },
275 - 'table': {
 308+ 'tableCGD': {
276309 labelMsg: 'edittoolbar-tool-table',
277310 type: 'button',
278311 icon: 'insert-table.png',
 312+ filters: [ '#wpTextbox1.withCGD' ],
279313 action: {
280314 type: 'dialog',
281315 module: 'insert-table'
282316 }
283317 },
 318+ 'table': {
 319+ labelMsg: 'edittoolbar-tool-table',
 320+ type: 'button',
 321+ icon: 'insert-table.png',
 322+ filters: [ '#wpTextbox1:not(.withCGD)' ],
 323+ action: {
 324+ type: 'encapsulate',
 325+ options: {
 326+ pre: "{| class=\"wikitable\" border=\"1\"\n|",
 327+ periMsg: 'edittoolbar-tool-table-example-old',
 328+ post: "\n|}"
 329+ }
 330+ }
 331+ },
284332 'newline': {
285333 labelMsg: 'edittoolbar-tool-newline',
286334 type: 'button',
@@ -299,6 +347,7 @@
300348 labelMsg: 'edittoolbar-tool-replace',
301349 type: 'button',
302350 icon: 'search-replace.png',
 351+ filters: [ '#wpTextbox1.withCGD' ],
303352 action: {
304353 type: 'dialog',
305354 module: 'search-and-replace'
Index: trunk/extensions/UsabilityInitiative/EditToolbar/EditToolbar.i18n.php
@@ -15,12 +15,17 @@
1616 'edittoolbar' => 'Editing toolbar',
1717 'edittoolbar-desc' => 'Edit page toolbar with enhanced usability',
1818 'edittoolbar-preference' => 'Enable enhanced editing toolbar',
 19+ 'edittoolbar-cgd-preference' => 'Enable content generation dialogs in enhanced editing toolbar',
1920 'edittoolbar-loading' => 'Loading...',
2021 /* Main Section */
2122 'edittoolbar-tool-bold' => 'Bold',
2223 'edittoolbar-tool-bold-example' => 'Bold text',
2324 'edittoolbar-tool-italic' => 'Italic',
2425 'edittoolbar-tool-italic-example' => 'Italic text',
 26+ 'edittoolbar-tool-ilink' => 'Internal link',
 27+ 'edittoolbar-tool-ilink-example' => 'Link title',
 28+ 'edittoolbar-tool-xlink' => 'External link (remember http:// prefix)',
 29+ 'edittoolbar-tool-xlink-example' => 'http://www.example.com link title',
2530 'edittoolbar-tool-link' => 'Link',
2631 'edittoolbar-tool-link-title' => 'Insert link',
2732 'edittoolbar-tool-link-int' => 'To a wiki page',
@@ -73,6 +78,18 @@
7479 {{ns:file}}:Example.jpg|Caption2",
7580 'edittoolbar-tool-newline' => 'New line',
7681 'edittoolbar-tool-table' => 'Table',
 82+ 'edittoolbar-tool-table-example-old' => "-
 83+! header 1
 84+! header 2
 85+! header 3
 86+|-
 87+| row 1, cell 1
 88+| row 1, cell 2
 89+| row 1, cell 3
 90+|-
 91+| row 2, cell 1
 92+| row 2, cell 2
 93+| row 2, cell 3",
7794 'edittoolbar-tool-table-example' => 'Row $1, cell $2',
7895 'edittoolbar-tool-table-example-header' => 'Row $1, cell $2 (header)',
7996 'edittoolbar-tool-table-title' => 'Insert table',
Index: trunk/extensions/UsabilityInitiative/EditToolbar/EditToolbar.php
@@ -19,7 +19,7 @@
2020 /* Configuration */
2121
2222 // Bump the version number every time you change any of the .css/.js files
23 -$wgEditToolbarStyleVersion = 32;
 23+$wgEditToolbarStyleVersion = 33;
2424
2525 // Set this to true to simply override the stock toolbar for everyone
2626 $wgEditToolbarGlobalEnable = false;
@@ -29,6 +29,15 @@
3030 // will not do anything)
3131 $wgEditToolbarUserEnable = true;
3232
 33+// Set this to true to enable content generation dialogs for everyone who gets
 34+// the toolbar
 35+$wgEditToolbarCGDGlobalEnable = false;
 36+
 37+// Set this to true to add a preference to the editing section of preferences
 38+// which enabled and disables content generation dialogs
 39+// If $wgEditToolbatCGDGlobalEnable is true, this will be ignored
 40+$wgEditToolbarCGDUserEnable = true;
 41+
3342 // Set if we should include a client-side testing script
3443 $wgEditToolbarRunTests = false;
3544
Index: trunk/extensions/UsabilityInitiative/js/plugins/jquery.wikiEditor.js
@@ -65,96 +65,88 @@
6666 // gets called again we can pick up where we left off
6767 var context = $(this).data( 'wikiEditor-context' );
6868
69 -/* API */
7069
71 -// The first time this is called, we expect context to be undefined, meaning
72 -// the editing UI has not yet been, and still needs to be, built. However, each
73 -// additional call after that is expected to be an API call, which contains a
74 -// string as the first argument which corresponds to a supported API call
75 -if ( typeof context !== 'undefined' ) {
76 - // Since javascript gives arguments as an object, we need to convert them
77 - // so they can be used more easily
78 - arguments = $.makeArray( arguments );
79 - if ( arguments.length > 0 ) {
80 - // Handle API calls
81 - var call = arguments.shift();
82 - if ( call in context.api ) {
83 - context.api[call]( context, arguments[0] == undefined ? {} : arguments[0] );
84 - }
85 - // Store the context for next time and return
86 - return $(this).data( 'context', context );
87 - }
88 - // Nothing to do, just return
89 - return $(this);
90 -}
91 -
92 -/* Construction */
93 -
94 -var instance = $.wikiEditor.instances.length;
95 -context = { '$textarea': $(this), 'modules': {}, 'data': {}, 'instance': instance };
96 -$.wikiEditor.instances[instance] = $(this);
97 -
98 -// Encapsulate the textarea with some containers for layout
99 -$(this)
100 - .wrap( $( '<div></div>' ).addClass( 'wikiEditor-ui' ).attr( 'id', 'wikiEditor-ui' ) )
101 - .wrap( $( '<div></div>' ).addClass( 'wikiEditor-ui-bottom' ).attr( 'id', 'wikiEditor-ui-bottom' ) )
102 - .wrap( $( '<div></div>' ).addClass( 'wikiEditor-ui-text' ).attr( 'id', 'wikiEditor-ui-text' ) );
103 -
104 -// Get a reference to the outer container
105 -context.$ui = $(this).parent().parent().parent();
106 -context.$ui.after( $( '<div style="clear:both;"></div>' ) );
107 -// Attach a container in the top
108 -context.$ui.prepend( $( '<div></div>' ).addClass( 'wikiEditor-ui-top' ).attr( 'id', 'wikiEditor-ui-top' ) );
109 -
110 -// Create a set of standard methods for internal and external use
111 -context.api = {
112 - /**
113 - * Accepts either a string of the name of a module to add without any
114 - * additional configuration parameters, or an object with members keyed with
115 - * module names and valued with configuration objects
116 - */
117 - addModule: function( context, data ) {
118 - // A safe way of calling an API function on a module
119 - function callModuleApi( module, call, data ) {
120 - if (
121 - module in $.wikiEditor.modules &&
122 - 'fn' in $.wikiEditor.modules[module] &&
123 - call in $.wikiEditor.modules[module].fn
124 - ) {
125 - $.wikiEditor.modules[module].fn[call]( context, data );
 70+if ( typeof context == 'undefined' ) {
 71+ /* Construction */
 72+ var instance = $.wikiEditor.instances.length;
 73+ context = { '$textarea': $(this), 'modules': {}, 'data': {}, 'instance': instance };
 74+ $.wikiEditor.instances[instance] = $(this);
 75+
 76+ // Encapsulate the textarea with some containers for layout
 77+ $(this)
 78+ .wrap( $( '<div></div>' ).addClass( 'wikiEditor-ui' ).attr( 'id', 'wikiEditor-ui' ) )
 79+ .wrap( $( '<div></div>' ).addClass( 'wikiEditor-ui-bottom' ).attr( 'id', 'wikiEditor-ui-bottom' ) )
 80+ .wrap( $( '<div></div>' ).addClass( 'wikiEditor-ui-text' ).attr( 'id', 'wikiEditor-ui-text' ) );
 81+
 82+ // Get a reference to the outer container
 83+ context.$ui = $(this).parent().parent().parent();
 84+ context.$ui.after( $( '<div style="clear:both;"></div>' ) );
 85+ // Attach a container in the top
 86+ context.$ui.prepend( $( '<div></div>' ).addClass( 'wikiEditor-ui-top' ).attr( 'id', 'wikiEditor-ui-top' ) );
 87+
 88+ // Create a set of standard methods for internal and external use
 89+ context.api = {
 90+ /**
 91+ * Accepts either a string of the name of a module to add without any
 92+ * additional configuration parameters, or an object with members keyed with
 93+ * module names and valued with configuration objects
 94+ */
 95+ addModule: function( context, data ) {
 96+ // A safe way of calling an API function on a module
 97+ function callModuleApi( module, call, data ) {
 98+ if (
 99+ module in $.wikiEditor.modules &&
 100+ 'fn' in $.wikiEditor.modules[module] &&
 101+ call in $.wikiEditor.modules[module].fn
 102+ ) {
 103+ $.wikiEditor.modules[module].fn[call]( context, data );
 104+ }
126105 }
127 - }
128 - if ( typeof data == 'string' ) {
129 - callModuleApi( data, 'create', {} );
130 - } else if ( typeof data == 'object' ) {
131 - for ( module in data ) {
132 - if ( typeof module == 'string' ) {
133 - callModuleApi( module, 'create', data[module] );
 106+ if ( typeof data == 'string' ) {
 107+ callModuleApi( data, 'create', {} );
 108+ } else if ( typeof data == 'object' ) {
 109+ for ( module in data ) {
 110+ if ( typeof module == 'string' ) {
 111+ callModuleApi( module, 'create', data[module] );
 112+ }
134113 }
135114 }
136115 }
137 - }
138 -};
139 -// Allow modules to extend the API
140 -for ( module in $.wikiEditor.modules ) {
141 - if ( 'api' in $.wikiEditor.modules[module] ) {
142 - for ( call in $.wikiEditor.modules[module].api ) {
143 - // Modules may not overwrite existing API functions - first come,
144 - // first serve
145 - if ( !( call in context.api ) ) {
146 - context.api[call] = $.wikiEditor.modules[module].api[call];
 116+ };
 117+ // Allow modules to extend the API
 118+ for ( module in $.wikiEditor.modules ) {
 119+ if ( 'api' in $.wikiEditor.modules[module] ) {
 120+ for ( call in $.wikiEditor.modules[module].api ) {
 121+ // Modules may not overwrite existing API functions - first come,
 122+ // first serve
 123+ if ( !( call in context.api ) ) {
 124+ context.api[call] = $.wikiEditor.modules[module].api[call];
 125+ }
147126 }
148127 }
149128 }
 129+ //Each browser seems to do this differently, so let's keep our editor
 130+ //consistent by always starting at the begining
 131+ context.$textarea.scrollToCaretPosition( 0 );
150132 }
 133+
151134 // If there was a configuration passed, it's assumed to be for the addModule
152 -// API call, so we can just send it on it's way right now
 135+// API call
153136 if ( arguments.length > 0 && typeof arguments[0] == 'object' ) {
154137 context.api.addModule( context, arguments[0] );
 138+} else {
 139+ // Since javascript gives arguments as an object, we need to convert them
 140+ // so they can be used more easily
 141+ arguments = $.makeArray( arguments );
 142+ if ( arguments.length > 0 ) {
 143+ // Handle API calls
 144+ var call = arguments.shift();
 145+ if ( call in context.api ) {
 146+ context.api[call]( context, arguments[0] == undefined ? {} : arguments[0] );
 147+ }
 148+ }
155149 }
156 -//Each browser seems to do this differently, so let's keep our editor
157 -//consistent by always starting at the begining
158 -context.$textarea.scrollToCaretPosition( 0 );
 150+
159151 // Store the context for next time, and support chaining
160152 return $(this).data( 'wikiEditor-context', context );
161153
Index: trunk/extensions/UsabilityInitiative/js/plugins/jquery.wikiEditor.toc.js
@@ -45,7 +45,7 @@
4646 context.$textarea
4747 .bind( 'keyup encapsulateSelection',
4848 function( event ) {
49 - var context = $(this).data( 'context' );
 49+ var context = $(this).data( 'wikiEditor-context' );
5050 $(this).eachAsync( {
5151 bulk: 0,
5252 loop: function() {
@@ -57,7 +57,7 @@
5858 )
5959 .bind( 'mouseup scrollToPosition focus',
6060 function( event ) {
61 - var context = $(this).data( 'context' );
 61+ var context = $(this).data( 'wikiEditor-context' );
6262 $(this).eachAsync( {
6363 bulk: 0,
6464 loop: function() {
@@ -67,6 +67,7 @@
6868 }
6969 )
7070 .blur( function() {
 71+ var context = $(this).data( 'wikiEditor-context' );
7172 $.wikiEditor.modules.toc.fn.unhighlight( context );
7273 });
7374 },
Index: trunk/extensions/UsabilityInitiative/js/plugins.combined.js
@@ -1086,96 +1086,88 @@
10871087 // gets called again we can pick up where we left off
10881088 var context = $(this).data( 'wikiEditor-context' );
10891089
1090 -/* API */
10911090
1092 -// The first time this is called, we expect context to be undefined, meaning
1093 -// the editing UI has not yet been, and still needs to be, built. However, each
1094 -// additional call after that is expected to be an API call, which contains a
1095 -// string as the first argument which corresponds to a supported API call
1096 -if ( typeof context !== 'undefined' ) {
1097 - // Since javascript gives arguments as an object, we need to convert them
1098 - // so they can be used more easily
1099 - arguments = $.makeArray( arguments );
1100 - if ( arguments.length > 0 ) {
1101 - // Handle API calls
1102 - var call = arguments.shift();
1103 - if ( call in context.api ) {
1104 - context.api[call]( context, arguments[0] == undefined ? {} : arguments[0] );
1105 - }
1106 - // Store the context for next time and return
1107 - return $(this).data( 'context', context );
1108 - }
1109 - // Nothing to do, just return
1110 - return $(this);
1111 -}
1112 -
1113 -/* Construction */
1114 -
1115 -var instance = $.wikiEditor.instances.length;
1116 -context = { '$textarea': $(this), 'modules': {}, 'data': {}, 'instance': instance };
1117 -$.wikiEditor.instances[instance] = $(this);
1118 -
1119 -// Encapsulate the textarea with some containers for layout
1120 -$(this)
1121 - .wrap( $( '<div></div>' ).addClass( 'wikiEditor-ui' ).attr( 'id', 'wikiEditor-ui' ) )
1122 - .wrap( $( '<div></div>' ).addClass( 'wikiEditor-ui-bottom' ).attr( 'id', 'wikiEditor-ui-bottom' ) )
1123 - .wrap( $( '<div></div>' ).addClass( 'wikiEditor-ui-text' ).attr( 'id', 'wikiEditor-ui-text' ) );
1124 -
1125 -// Get a reference to the outer container
1126 -context.$ui = $(this).parent().parent().parent();
1127 -context.$ui.after( $( '<div style="clear:both;"></div>' ) );
1128 -// Attach a container in the top
1129 -context.$ui.prepend( $( '<div></div>' ).addClass( 'wikiEditor-ui-top' ).attr( 'id', 'wikiEditor-ui-top' ) );
1130 -
1131 -// Create a set of standard methods for internal and external use
1132 -context.api = {
1133 - /**
1134 - * Accepts either a string of the name of a module to add without any
1135 - * additional configuration parameters, or an object with members keyed with
1136 - * module names and valued with configuration objects
1137 - */
1138 - addModule: function( context, data ) {
1139 - // A safe way of calling an API function on a module
1140 - function callModuleApi( module, call, data ) {
1141 - if (
1142 - module in $.wikiEditor.modules &&
1143 - 'fn' in $.wikiEditor.modules[module] &&
1144 - call in $.wikiEditor.modules[module].fn
1145 - ) {
1146 - $.wikiEditor.modules[module].fn[call]( context, data );
 1091+if ( typeof context == 'undefined' ) {
 1092+ /* Construction */
 1093+ var instance = $.wikiEditor.instances.length;
 1094+ context = { '$textarea': $(this), 'modules': {}, 'data': {}, 'instance': instance };
 1095+ $.wikiEditor.instances[instance] = $(this);
 1096+
 1097+ // Encapsulate the textarea with some containers for layout
 1098+ $(this)
 1099+ .wrap( $( '<div></div>' ).addClass( 'wikiEditor-ui' ).attr( 'id', 'wikiEditor-ui' ) )
 1100+ .wrap( $( '<div></div>' ).addClass( 'wikiEditor-ui-bottom' ).attr( 'id', 'wikiEditor-ui-bottom' ) )
 1101+ .wrap( $( '<div></div>' ).addClass( 'wikiEditor-ui-text' ).attr( 'id', 'wikiEditor-ui-text' ) );
 1102+
 1103+ // Get a reference to the outer container
 1104+ context.$ui = $(this).parent().parent().parent();
 1105+ context.$ui.after( $( '<div style="clear:both;"></div>' ) );
 1106+ // Attach a container in the top
 1107+ context.$ui.prepend( $( '<div></div>' ).addClass( 'wikiEditor-ui-top' ).attr( 'id', 'wikiEditor-ui-top' ) );
 1108+
 1109+ // Create a set of standard methods for internal and external use
 1110+ context.api = {
 1111+ /**
 1112+ * Accepts either a string of the name of a module to add without any
 1113+ * additional configuration parameters, or an object with members keyed with
 1114+ * module names and valued with configuration objects
 1115+ */
 1116+ addModule: function( context, data ) {
 1117+ // A safe way of calling an API function on a module
 1118+ function callModuleApi( module, call, data ) {
 1119+ if (
 1120+ module in $.wikiEditor.modules &&
 1121+ 'fn' in $.wikiEditor.modules[module] &&
 1122+ call in $.wikiEditor.modules[module].fn
 1123+ ) {
 1124+ $.wikiEditor.modules[module].fn[call]( context, data );
 1125+ }
11471126 }
1148 - }
1149 - if ( typeof data == 'string' ) {
1150 - callModuleApi( data, 'create', {} );
1151 - } else if ( typeof data == 'object' ) {
1152 - for ( module in data ) {
1153 - if ( typeof module == 'string' ) {
1154 - callModuleApi( module, 'create', data[module] );
 1127+ if ( typeof data == 'string' ) {
 1128+ callModuleApi( data, 'create', {} );
 1129+ } else if ( typeof data == 'object' ) {
 1130+ for ( module in data ) {
 1131+ if ( typeof module == 'string' ) {
 1132+ callModuleApi( module, 'create', data[module] );
 1133+ }
11551134 }
11561135 }
11571136 }
1158 - }
1159 -};
1160 -// Allow modules to extend the API
1161 -for ( module in $.wikiEditor.modules ) {
1162 - if ( 'api' in $.wikiEditor.modules[module] ) {
1163 - for ( call in $.wikiEditor.modules[module].api ) {
1164 - // Modules may not overwrite existing API functions - first come,
1165 - // first serve
1166 - if ( !( call in context.api ) ) {
1167 - context.api[call] = $.wikiEditor.modules[module].api[call];
 1137+ };
 1138+ // Allow modules to extend the API
 1139+ for ( module in $.wikiEditor.modules ) {
 1140+ if ( 'api' in $.wikiEditor.modules[module] ) {
 1141+ for ( call in $.wikiEditor.modules[module].api ) {
 1142+ // Modules may not overwrite existing API functions - first come,
 1143+ // first serve
 1144+ if ( !( call in context.api ) ) {
 1145+ context.api[call] = $.wikiEditor.modules[module].api[call];
 1146+ }
11681147 }
11691148 }
11701149 }
 1150+ //Each browser seems to do this differently, so let's keep our editor
 1151+ //consistent by always starting at the begining
 1152+ context.$textarea.scrollToCaretPosition( 0 );
11711153 }
 1154+
11721155 // If there was a configuration passed, it's assumed to be for the addModule
1173 -// API call, so we can just send it on it's way right now
 1156+// API call
11741157 if ( arguments.length > 0 && typeof arguments[0] == 'object' ) {
11751158 context.api.addModule( context, arguments[0] );
 1159+} else {
 1160+ // Since javascript gives arguments as an object, we need to convert them
 1161+ // so they can be used more easily
 1162+ arguments = $.makeArray( arguments );
 1163+ if ( arguments.length > 0 ) {
 1164+ // Handle API calls
 1165+ var call = arguments.shift();
 1166+ if ( call in context.api ) {
 1167+ context.api[call]( context, arguments[0] == undefined ? {} : arguments[0] );
 1168+ }
 1169+ }
11761170 }
1177 -//Each browser seems to do this differently, so let's keep our editor
1178 -//consistent by always starting at the begining
1179 -context.$textarea.scrollToCaretPosition( 0 );
 1171+
11801172 // Store the context for next time, and support chaining
11811173 return $(this).data( 'wikiEditor-context', context );
11821174
@@ -1926,7 +1918,7 @@
19271919 context.$textarea
19281920 .bind( 'keyup encapsulateSelection',
19291921 function( event ) {
1930 - var context = $(this).data( 'context' );
 1922+ var context = $(this).data( 'wikiEditor-context' );
19311923 $(this).eachAsync( {
19321924 bulk: 0,
19331925 loop: function() {
@@ -1938,7 +1930,7 @@
19391931 )
19401932 .bind( 'mouseup scrollToPosition focus',
19411933 function( event ) {
1942 - var context = $(this).data( 'context' );
 1934+ var context = $(this).data( 'wikiEditor-context' );
19431935 $(this).eachAsync( {
19441936 bulk: 0,
19451937 loop: function() {
@@ -1948,6 +1940,7 @@
19491941 }
19501942 )
19511943 .blur( function() {
 1944+ var context = $(this).data( 'wikiEditor-context' );
19521945 $.wikiEditor.modules.toc.fn.unhighlight( context );
19531946 });
19541947 },
Index: trunk/extensions/UsabilityInitiative/js/plugins.combined.min.js
@@ -70,13 +70,11 @@
7171 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;}
7272 range.moveToElementText(this);range.collapse();range.move('character',pos);range.select();this.scrollTop+=range.offsetTop;if(goBack){range.move('character',-1);range.select();}}
7373 $(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;}}}
74 -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('wikiEditor-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]);}
75 -return $(this).data('context',context);}
76 -return $(this);}
77 -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);}}
 74+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('wikiEditor-context');if(typeof context=='undefined'){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);}}
7875 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];}}}}
79 -if(arguments.length>0&&typeof arguments[0]=='object'){context.api.addModule(context,arguments[0]);}
80 -context.$textarea.scrollToCaretPosition(0);return $(this).data('wikiEditor-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];}
 76+context.$textarea.scrollToCaretPosition(0);}
 77+if(arguments.length>0&&typeof arguments[0]=='object'){context.api.addModule(context,arguments[0]);}else{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]);}}}
 78+return $(this).data('wikiEditor-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];}
8179 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];}
8280 $('<div /> ').attr('id',module.id).html(module.html).data('context',context).appendTo($('body')).each(module.init).dialog(configuration).bind('dialogopen',$.wikiEditor.modules.dialogs.fn.resize).find('.ui-tabs').bind('tabsshow',function(){$(this).closest('.ui-dialog-content').each($.wikiEditor.modules.dialogs.fn.resize);});var maxTI=0;$j('[tabindex]').each(function(){var ti=parseInt($j(this).attr('tabindex'));if(ti>maxTI)
8381 maxTI=ti;});var tabIndex=maxTI+1;$j('.ui-dialog input, .ui-dialog button').not('[tabindex]').each(function(){$j(this).attr('tabindex',tabIndex++);});}}},resize:function(){var wrapper=$(this).closest('.ui-dialog');var oldHidden=$(this).find('*').not(':visible');oldHidden.each(function(){$(this).data('oldstyle',$(this).attr('style'));});oldHidden.show();var oldWS=$(this).css('white-space');$(this).css('white-space','nowrap');if(wrapper.width()<=$(this).get(0).scrollWidth){$(this).width($(this).get(0).scrollWidth);wrapper.width(wrapper.get(0).scrollWidth);$(this).dialog({'width':wrapper.width()});}
@@ -127,7 +125,7 @@
128126 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);}
129127 $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]));}}
130128 $.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;}
131 -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 focus',function(event){var context=$(this).data('context');$(this).eachAsync({bulk:0,loop:function(){$.wikiEditor.modules.toc.fn.update(context);}});}).blur(function(){$.wikiEditor.modules.toc.fn.unhighlight(context);});},unhighlight:function(context){context.modules.$toc.find('a').removeClass('currentSelection');},update:function(context){$.wikiEditor.modules.toc.fn.unhighlight(context);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++;}
 129+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('wikiEditor-context');$(this).eachAsync({bulk:0,loop:function(){$.wikiEditor.modules.toc.fn.build(context);$.wikiEditor.modules.toc.fn.update(context);}});}).bind('mouseup scrollToPosition focus',function(event){var context=$(this).data('wikiEditor-context');$(this).eachAsync({bulk:0,loop:function(){$.wikiEditor.modules.toc.fn.update(context);}});}).blur(function(){var context=$(this).data('wikiEditor-context');$.wikiEditor.modules.toc.fn.unhighlight(context);});},unhighlight:function(context){context.modules.$toc.find('a').removeClass('currentSelection');},update:function(context){$.wikiEditor.modules.toc.fn.unhighlight(context);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++;}
132130 section=Math.max(0,section);}
133131 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;}
134132 sections[sections.length]=outline[i];}else if(outline[i].nLevel<level){break;}}

Follow-up revisions

RevisionCommit summaryAuthorDate
r56421wmf-deployment-work: Merge r56417 (pre-deployment usability fixes) from...catrope17:47, 16 September 2009
r56424EditToolbar: Fix for r56417: put inserted tables on their own line, like beforecatrope18:12, 16 September 2009
r56425wmf-deployment-work: Merge r56424 (fix for r56417 which was merged...catrope18:20, 16 September 2009
r56426EditToolbar: Fix stupid copypaste mess-up from r56417catrope18:26, 16 September 2009
r56428wmf-deployment-work: Merge r56426 (fix stupid mistake in r56417, which...catrope18:27, 16 September 2009

Past revisions this follows-up on

RevisionCommit summaryAuthorDate
r55207EditToolbar: Add table CGDcatrope21:43, 17 August 2009

Comments

#Comment by Nimish Gautam (talk | contribs)   20:44, 23 September 2009

How would you propose getting JS vars into the JS code differently?

#Comment by Catrope (talk | contribs)   21:09, 23 September 2009

It now uses the MakeGlobalVariablesScript hook, which is the proper way. UsabilityInitiativeHooks::addVariables() still works, addLiteralVariables() was renamed and its callers updated. This means injection of JS vars should still work the way it used to from e.g. ClickTracking's perspective, with different code behind the scenes.

Status & tagging log