r61137 MediaWiki - Code Review archive

Repository:MediaWiki
Revision:r61136‎ | r61137 | r61138 >
Date:17:42, 16 January 2010
Author:dale
Status:reverted (Comments)
Tags:
Comment:
* added inline section edit to wikiEditor ( using js2 / mwEmbed conventions )
** added "loaders" to "WikiEditor" and UsabilityInitiative core js
** added >= 1.17 script include calls
* some general mwEmbed loader fixes (around loadDone )
* fixed $j.cookie jquery wrapping
* more jsClassLoader clean up.
* unified wgJSAutoloadLocalClasses var
Modified paths:
  • /branches/js2-work/phase3/includes/AutoLoader.php (modified) (history)
  • /branches/js2-work/phase3/includes/DefaultSettings.php (modified) (history)
  • /branches/js2-work/phase3/includes/EditPage.php (modified) (history)
  • /branches/js2-work/phase3/includes/OutputPage.php (modified) (history)
  • /branches/js2-work/phase3/includes/Skin.php (modified) (history)
  • /branches/js2-work/phase3/includes/specials/SpecialUpload.php (modified) (history)
  • /branches/js2-work/phase3/js/mwEmbed/includes/jsClassLoader.php (modified) (history)
  • /branches/js2-work/phase3/js/mwEmbed/includes/noMediaWikiConfig.php (modified) (history)
  • /branches/js2-work/phase3/js/mwEmbed/jquery/plugins/jquery.cookie.js (modified) (history)
  • /branches/js2-work/phase3/js/mwEmbed/jsScriptLoader.php (modified) (history)
  • /branches/js2-work/phase3/js/mwEmbed/modules/AddMedia/searchLibs/mediaWikiSearch.js (modified) (history)
  • /branches/js2-work/phase3/js/mwEmbed/mwEmbed.js (modified) (history)
  • /trunk/extensions/UsabilityInitiative/InlineSectionEdit (added) (history)
  • /trunk/extensions/UsabilityInitiative/InlineSectionEdit/InlineSectionEdit.js (added) (history)
  • /trunk/extensions/UsabilityInitiative/InlineSectionEdit/InlineSectionEdit.php (added) (history)
  • /trunk/extensions/UsabilityInitiative/UsabilityInitiative.hooks.php (modified) (history)
  • /trunk/extensions/UsabilityInitiative/UsabilityInitiative.php (modified) (history)
  • /trunk/extensions/UsabilityInitiative/WikiEditor/Modules/Highlight/Highlight.js (modified) (history)
  • /trunk/extensions/UsabilityInitiative/WikiEditor/Modules/Preview/Preview.js (modified) (history)
  • /trunk/extensions/UsabilityInitiative/WikiEditor/Modules/Publish/Publish.js (modified) (history)
  • /trunk/extensions/UsabilityInitiative/WikiEditor/Modules/TemplateEditor/TemplateEditor.js (modified) (history)
  • /trunk/extensions/UsabilityInitiative/WikiEditor/Modules/Toc/Toc.js (modified) (history)
  • /trunk/extensions/UsabilityInitiative/WikiEditor/Modules/Toolbar/Toolbar.js (modified) (history)
  • /trunk/extensions/UsabilityInitiative/WikiEditor/WikiEditor.hooks.php (modified) (history)
  • /trunk/extensions/UsabilityInitiative/WikiEditor/WikiEditor.php (modified) (history)
  • /trunk/extensions/UsabilityInitiative/WikiEditor/loader.js (added) (history)
  • /trunk/extensions/UsabilityInitiative/js/js2stopgap/jquery.cookie.js (added) (history)
  • /trunk/extensions/UsabilityInitiative/js/js2stopgap/jquery.textSelection.js (added) (history)
  • /trunk/extensions/UsabilityInitiative/js/loader.js (added) (history)
  • /trunk/extensions/UsabilityInitiative/js/plugins/jquery.cookie.js (deleted) (history)
  • /trunk/extensions/UsabilityInitiative/js/plugins/jquery.textSelection.js (deleted) (history)
  • /trunk/extensions/UsabilityInitiative/js/plugins/jquery.wikiEditor.dialogs.js (modified) (history)
  • /trunk/extensions/UsabilityInitiative/js/plugins/jquery.wikiEditor.js (modified) (history)
  • /trunk/phase3/includes/DefaultSettings.php (modified) (history)
  • /trunk/phase3/js2/js2stopgap.js (modified) (history)

Diff [purge]

Index: trunk/phase3/js2/js2stopgap.js
@@ -4405,6 +4405,9 @@
44064406 // Define a dummy mw.load function:
44074407 mw.load = function( deps, callback ) { callback(); };
44084408
 4409+ // Deinfe a dummy mw.loadDone function:
 4410+ mw.loadDone = function( className ) { };
 4411+
44094412 // Creates global message object if not already in existence
44104413 if ( !gMsg ) var gMsg = {};
44114414
Index: trunk/phase3/includes/DefaultSettings.php
@@ -3083,9 +3083,9 @@
30843084 /**
30853085 * Fake out the timezone that the server thinks it's in. This will be used for
30863086 * date display and not for what's stored in the DB. Leave to null to retain
3087 - * your server's OS-based timezone value.
 3087+ * your server's OS-based timezone value.
30883088 *
3089 - * This variable is currently used only for signature formatting and for local
 3089+ * This variable is currently used only for signature formatting and for local
30903090 * time/date parser variables ({{LOCALTIME}} etc.)
30913091 *
30923092 * Timezones can be translated by editing MediaWiki messages of type
@@ -4311,3 +4311,11 @@
43124312 * Use old names for change_tags indices.
43134313 */
43144314 $wgOldChangeTagsIndex = false;
 4315+
 4316+/**
 4317+ * Set of loader.js files to setup dynamic loading of javascript libraries using mwEmbed
 4318+ *
 4319+ * Extensions can add mwEmbed modules via adding paths to their loader.js to
 4320+ * $wgExtensionJavascriptLoader[] = path/to/loader.js
 4321+ */
 4322+$wgExtensionJavascriptLoader = array();
\ No newline at end of file
Index: trunk/extensions/UsabilityInitiative/InlineSectionEdit/InlineSectionEdit.php
@@ -0,0 +1,24 @@
 2+<?php
 3+
 4+$wgExtensionCredits['other'][] = array(
 5+ 'path' => __FILE__,
 6+ 'name' => 'inlineSectionEdit',
 7+ 'author' => array( 'Michael Dale' ),
 8+ 'version' => '0.1',
 9+ 'url' => 'http://www.mediawiki.org/wiki/Extension:UsabilityInitiative',
 10+ 'description' => 'Simple example of inline-section editing using js2 & UsabilityInitiative wikiEditor'
 11+);
 12+
 13+$wgHooks['BeforePageDisplay'][] = 'inlineSectionJsCheck';
 14+
 15+$wgJSAutoloadClasses[ 'inlineSectionEdit' ] =
 16+ "extensions/UsabilityInitiative/InlineSectionEdit/InlineSectionEdit.js";
 17+
 18+function inlineSectionJsCheck( &$out, &$sk ){
 19+ global $wgRequest;
 20+ if( $wgRequest->getText( 'action', 'view' ) == 'view' ){
 21+ $out->addScriptClass( 'inlineSectionEdit' );
 22+ }
 23+ return true;
 24+}
 25+?>
\ No newline at end of file
Index: trunk/extensions/UsabilityInitiative/InlineSectionEdit/InlineSectionEdit.js
@@ -0,0 +1,130 @@
 2+/**
 3+* Simple inline section edit example h3 ->h3 h2
 4+*/
 5+mw.ready(function(){
 6+ var htags = 'h6,h5,h4,h3,h2,h1';
 7+ //var htags = 'h1,h2,h3,h4,h5,h6';
 8+ $j('.editsection').click(function(){
 9+ // Get section number:
 10+ var href = $j( this ).children('a').attr( 'href');
 11+ var sectionNumber = mw.parseUri( href ).queryKey['section'];
 12+
 13+ // Get the H tag
 14+ var $htop = $j(this).parents( htags ).filter(':first');
 15+ var htagName = $htop.get(0).tagName;
 16+ var hlevel = parseInt( htagName.replace(/h/i, '') );
 17+
 18+ //Set up the list of h tags that we break on:
 19+ hSet = [];
 20+ for( var i = hlevel; i !=0 ; i -- ){
 21+ hSet.push( 'h'+i );
 22+ }
 23+
 24+ // Remove all child elements until we reach the same level or higher
 25+ $j(this).parent().nextAll().each(function(){
 26+ //Break if we reach the same h or higher
 27+ for(var i =0; i < hSet.length; i++){
 28+ if( $j(this).is( hSet[i] ) ) {
 29+ return false;
 30+ }
 31+ };
 32+ //Break if we reach the "end"
 33+ if( $j(this).is( '.visualClear' ) ){
 34+ return false;
 35+ }
 36+
 37+ // Otherwise remove the nodes until we find any of the above
 38+ $j(this).remove();
 39+ });
 40+
 41+ // Add the section edit loader
 42+ $htop.before(
 43+ $j('<div>')
 44+ .addClass("sectionEdit")
 45+ .attr('id', 'edit_section_' + sectionNumber )
 46+ .loadingSpinner()
 47+ )
 48+ // Remove the parent htag
 49+ .remove();
 50+
 51+ // Here we would setup the configuration something like:
 52+ //mw.setConfig('WikiEditor.modlue.{modName}', true );
 53+
 54+ // @@NOTE: should refactor to use mw.{set|get}Config instead of all this
 55+ // global context specific stuff
 56+ window.wgWikiEditorEnabledModules = {
 57+ "highlight": true,
 58+ "preview": true,
 59+ "toc": true,
 60+ "toolbar": true,
 61+ "global": true
 62+ };
 63+ window.wgWikiEditorPreferences = {
 64+ "highlight": {
 65+ "enable": "1"
 66+ },
 67+ "preview": {
 68+ "enable": "1"
 69+ },
 70+ "toc": {
 71+ "enable": "1"
 72+ },
 73+ "toolbar": {
 74+ "enable": "1",
 75+ "dialogs": "1"
 76+ }
 77+ };
 78+ window.wgWikiEditorIconVersion=0;
 79+ window.wgNavigableTOCResizable=null;
 80+
 81+
 82+ //Grab the section text from the api:
 83+ mw.getJSON({
 84+ 'prop' : 'revisions',
 85+ 'titles' : wgTitle,
 86+ 'rvprop' : 'content',
 87+ 'rvsection' : sectionNumber
 88+ }, function( data ){
 89+ if( data.query && data.query.pages ){
 90+ for ( var i in data.query.pages ) {
 91+ var page = data.query.pages[i];
 92+ if ( page.revisions[0]['*'] ){
 93+ doInlineWikiEditor( page.revisions[0]['*'], sectionNumber );
 94+ }
 95+ }
 96+ }
 97+ //@@todo error out
 98+ });
 99+ // don't folow the link:
 100+ return false;
 101+ });
 102+});
 103+function doInlineWikiEditor( wikiText, sectionNumber ){
 104+ // Here we have to plop in a hidden wikitext box identical to edit page
 105+ // We don't want to build out custom config
 106+ // ( too much config is sotred in wikiEditor/Toolbar/Toolbar.js )
 107+ $j('#edit_section_' + sectionNumber).append(
 108+ $j('<textarea>')
 109+ .attr({
 110+ 'name' : "wpTextbox1",
 111+ 'id' : "wpTextbox1",
 112+ 'cols' : "80",
 113+ 'rows' : "20",
 114+ 'tabindex' : "1",
 115+ 'accesskey' : ","
 116+ })
 117+ .val( wikiText )
 118+ .hide()
 119+ );
 120+ //Remove the loader ( callback on mw.load('WikiEditor') is having trouble atm )
 121+ $j('.loading_spinner').remove();
 122+ //load the wikitext module:
 123+ mw.load('WikiEditor', function(){
 124+ // show the editor:
 125+ $j('#wpTextbox1').show( 'fast' );
 126+ // add the add-media-wizard binding"
 127+ mw.load( 'editPage', function(){
 128+ mw.log("editPage loaded");
 129+ });
 130+ });
 131+}
\ No newline at end of file
Index: trunk/extensions/UsabilityInitiative/WikiEditor/WikiEditor.php
@@ -49,6 +49,9 @@
5050 // Add Autoload Classes
5151 $wgAutoloadClasses['WikiEditorHooks'] = dirname( __FILE__ ) . '/WikiEditor.hooks.php';
5252
 53+// Add javascript loader
 54+$wgExtensionJavascriptLoader[] = "UsabilityInitiative/WikiEditor/loader.js";
 55+
5356 // Add Internationalized Messages
5457 $wgExtensionMessagesFiles['WikiEditor'] = dirname( __FILE__ ) . '/WikiEditor.i18n.php';
5558 $wgExtensionMessagesFiles['WikiEditorHighlight'] = dirname( __FILE__ ) . '/Modules/Highlight/Highlight.i18n.php';
Index: trunk/extensions/UsabilityInitiative/WikiEditor/loader.js
@@ -0,0 +1,50 @@
 2+/**
 3+* javascript loader for wikiEditor config classes
 4+*/
 5+// For non-script loader javascript path
 6+mw.setConfig('loaderContext', wgScriptPath + '/extensions/UsabilityInitiative/WikiEditor/');
 7+
 8+mw.addClassFilePaths({
 9+ "wikiEditorHighlight" : "Modules/Highlight/Highlight.js",
 10+ "wikiEditor.config.preview" : "Modules/Preview/Preview.js",
 11+ "wikiEditor.config.publish" : "Modules/Publish/Publish.js",
 12+ "wikiEditor.config.toc" : "Modules/Toc/Toc.js",
 13+ "wikiEditor.config.toolbar" : "Modules/Toolbar/Toolbar.js",
 14+ "wikiEditor.config.templateEditor" : "Modules/TemplateEditor/TemplateEditor.js"
 15+});
 16+
 17+mw.addModuleLoader( 'WikiEditor', function( callback ){
 18+ //@@todo we should check config and skip stuff we don't want need
 19+ var libReq = [
 20+ "$j.whileAsync" ,
 21+ "$j.fn.autoEllipsis" ,
 22+ "$j.browserTest" ,
 23+ "$j.fn.collapsibleTabs" ,
 24+ "$j.fn.delayedBind" ,
 25+ "inherit",
 26+ "$j.fn.namespaceSelector" ,
 27+ "$j.suggestions" ,
 28+ "$j.wikiEditor",
 29+
 30+ //@@NOTE we should only include the modules we need
 31+ "$j.wikiEditor.modules.highlight" ,
 32+ "$j.wikiEditor.modules.toolbar",
 33+ "$j.wikiEditor.modules.dialogs",
 34+ "$j.wikiEditor.modules.toc" ,
 35+ "$j.wikiEditor.modules.preview" ,
 36+ "$j.wikiEditor.modules.templateEditor" ,
 37+ "$j.wikiEditor.modules.publish",
 38+
 39+ //Also load per module configuration
 40+ "wikiEditor.config.highlight",
 41+ "wikiEditor.config.preview",
 42+ "wikiEditor.config.publish",
 43+ "wikiEditor.config.toc",
 44+ "wikiEditor.config.toolbar" ,
 45+ "wikiEditor.config.templateEditor"
 46+ ];
 47+ mw.load(libReq, function(){
 48+ callback( 'WikiEditor' );
 49+ });
 50+
 51+});
\ No newline at end of file
Index: trunk/extensions/UsabilityInitiative/WikiEditor/WikiEditor.hooks.php
@@ -7,17 +7,41 @@
88 */
99
1010 class WikiEditorHooks {
11 -
 11+
1212 /* Static Members */
13 -
 13+
1414 static $scripts = array(
1515 'raw' => array(
16 - array( 'src' => 'Modules/Highlight/Highlight.js', 'version' => 3 ),
17 - array( 'src' => 'Modules/Preview/Preview.js', 'version' => 4 ),
18 - array( 'src' => 'Modules/Publish/Publish.js', 'version' => 3 ),
19 - array( 'src' => 'Modules/Toc/Toc.js', 'version' => 5 ),
20 - array( 'src' => 'Modules/Toolbar/Toolbar.js', 'version' => 18 ),
21 - array( 'src' => 'Modules/TemplateEditor/TemplateEditor.js', 'version' => 2 ),
 16+ array(
 17+ 'src' => 'Modules/Highlight/Highlight.js',
 18+ 'class' => 'wikiEditor.config.highlight',
 19+ 'version' => 3
 20+ ),
 21+ array(
 22+ 'src' => 'Modules/Preview/Preview.js',
 23+ 'class' => 'wikiEditor.config.preview',
 24+ 'version' => 4
 25+ ),
 26+ array(
 27+ 'src' => 'Modules/Publish/Publish.js',
 28+ 'class' => 'wikiEditor.config.publish',
 29+ 'version' => 3
 30+ ),
 31+ array(
 32+ 'src' => 'Modules/Toc/Toc.js',
 33+ 'class' => 'wikiEditor.config.toc',
 34+ 'version' => 5
 35+ ),
 36+ array(
 37+ 'src' => 'Modules/Toolbar/Toolbar.js',
 38+ 'class' => 'wikiEditor.config.toolbar',
 39+ 'version' => 18
 40+ ),
 41+ array(
 42+ 'src' => 'Modules/TemplateEditor/TemplateEditor.js',
 43+ 'class' => 'wikiEditor.config.templateEditor',
 44+ 'version' => 2
 45+ ),
2246 ),
2347 'combined' => array(
2448 array( 'src' => 'WikiEditor.combined.js', 'version' => 19 ),
@@ -333,22 +357,22 @@
334358 ),
335359 ),
336360 );
337 -
 361+
338362 /* Static Functions */
339 -
 363+
340364 /**
341365 * From here down, with very little modification is a copy of what's found in Vector/Vector.hooks.php.
342366 * Perhaps we could find a clean way of eliminating this redundancy.
343367 */
344 -
 368+
345369 /**
346370 * EditPage::showEditForm:initial hook
347371 * Adds the modules to the edit form
348372 */
349373 public static function addModules( &$toolbar ) {
350 - global $wgOut, $wgUser, $wgJsMimeType;
 374+ global $wgOut, $wgUser, $wgJsMimeType, $wgVersion;
351375 global $wgWikiEditorModules, $wgUsabilityInitiativeResourceMode;
352 -
 376+
353377 // Modules
354378 $preferences = array();
355379 $enabledModules = array();
@@ -396,9 +420,15 @@
397421 UsabilityInitiativeHooks::addMessages( self::$messages );
398422 // Add all scripts
399423 foreach ( self::$scripts[$wgUsabilityInitiativeResourceMode] as $script ) {
400 - UsabilityInitiativeHooks::addScript(
401 - basename( dirname( __FILE__ ) ) . '/' . $script['src'], $script['version']
402 - );
 424+ if ( !version_compare( floatval( $wgVersion ), '1.17', '>=') ) {
 425+ UsabilityInitiativeHooks::addScript(
 426+ basename( dirname( __FILE__ ) ) . '/' . $script['src'], $script['version']
 427+ );
 428+ continue;
 429+ }
 430+ if( isset( $script['class'] ) ){
 431+ $wgOut->addScriptClass( $script['class'] );
 432+ }
403433 }
404434 // Preferences (maybe the UsabilityInitiative class could do most of this for us?)
405435 $wgOut->addScript(
@@ -411,14 +441,14 @@
412442 );
413443 return true;
414444 }
415 -
 445+
416446 /**
417447 * GetPreferences hook
418448 * Add module-releated items to the preferences
419449 */
420450 public static function addPreferences( $user, &$defaultPreferences ) {
421451 global $wgWikiEditorModules;
422 -
 452+
423453 foreach ( $wgWikiEditorModules as $module => $enable ) {
424454 if ( ( $enable['global'] || $enable['user'] ) &&
425455 isset( self::$modules[$module]['i18n'] ) &&
@@ -428,7 +458,7 @@
429459 if ( $key == 'enable' && !$enable['user'] ) {
430460 continue;
431461 }
432 -
 462+
433463 // The preference with the key 'enable' determines if the rest are even relevant, so in the future
434464 // setting up some dependencies on that might make sense
435465 $defaultPreferences[$preference['key']] = $preference['ui'];
Index: trunk/extensions/UsabilityInitiative/WikiEditor/Modules/Preview/Preview.js
@@ -1,5 +1,11 @@
22 /* JavaScript for WikiEditor Preview module */
33
 4+mw.addMessages({
 5+ "wikieditor-preview-preference" : "Enable side-by-side preview",
 6+ "wikieditor-preview-tab" : "Preview",
 7+ "wikieditor-preview-changes-tab" : "Changes",
 8+ "wikieditor-preview-loading" : "Loading..."
 9+});
410 mw.ready( function() {
511 // Check preferences for preview
612 if ( !wgWikiEditorEnabledModules.preview ) {
@@ -10,3 +16,5 @@
1117 $j( 'textarea#wpTextbox1' ).wikiEditor( 'addModule', 'preview' );
1218 }
1319 });
 20+
 21+mw.loadDone( 'wikiEditor.config.preview' );
\ No newline at end of file
Index: trunk/extensions/UsabilityInitiative/WikiEditor/Modules/TemplateEditor/TemplateEditor.js
@@ -1,5 +1,9 @@
22 /* JavaScript for WikiEditor Template Editor module */
33
 4+mw.addMessages({
 5+ "wikieditor-template-editor-preference": "Enable form-based editing of wiki templates"
 6+});
 7+
48 mw.ready( function() {
59 // Check preferences for templateEditor
610 if ( !wgWikiEditorEnabledModules.templateEditor ) {
@@ -10,3 +14,5 @@
1115 $j( 'textarea#wpTextbox1' ).wikiEditor( 'addModule', 'templateEditor' );
1216 }
1317 });
 18+
 19+mw.loadDone( 'wikiEditor.config.templateEditor' );
\ No newline at end of file
Index: trunk/extensions/UsabilityInitiative/WikiEditor/Modules/Toolbar/Toolbar.js
@@ -1,5 +1,190 @@
22 /* JavaScript for WikiEditor Toolbar module */
33
 4+mw.addMessages({
 5+ "wikieditor-toolbar" : "Editing toolbar",
 6+ "wikieditor-toolbar-desc" : "Edit page toolbar with enhanced usability",
 7+ "wikieditor-toolbar-preference" : "Enable enhanced editing toolbar",
 8+ "wikieditor-toolbar-dialogs-preference" : "Enable dialogs for inserting links, tables and more",
 9+ "wikieditor-toolbar-loading" : "Loading...",
 10+ "wikieditor-toolbar-tool-bold" : "Bold",
 11+ "wikieditor-toolbar-tool-bold-example" : "Bold text",
 12+ "wikieditor-toolbar-tool-italic" : "Italic",
 13+ "wikieditor-toolbar-tool-italic-example" : "Italic text",
 14+ "wikieditor-toolbar-tool-ilink" : "Internal link",
 15+ "wikieditor-toolbar-tool-ilink-example" : "Link title",
 16+ "wikieditor-toolbar-tool-xlink" : "External link (remember http:// prefix)",
 17+ "wikieditor-toolbar-tool-xlink-example" : "http://www.example.com link title",
 18+ "wikieditor-toolbar-tool-link" : "Link",
 19+ "wikieditor-toolbar-tool-link-title" : "Insert link",
 20+ "wikieditor-toolbar-tool-link-int" : "To a wiki page",
 21+ "wikieditor-toolbar-tool-link-int-target" : "Target page or URL:",
 22+ "wikieditor-toolbar-tool-link-int-target-tooltip" : "Enter the page title",
 23+ "wikieditor-toolbar-tool-link-int-text" : "Displayed text:",
 24+ "wikieditor-toolbar-tool-link-int-text-tooltip" : "Enter the text that should be displayed",
 25+ "wikieditor-toolbar-tool-link-ext" : "To an external web page",
 26+ "wikieditor-toolbar-tool-link-ext-target" : "Link URL:",
 27+ "wikieditor-toolbar-tool-link-ext-text" : "Link text:",
 28+ "wikieditor-toolbar-tool-link-insert" : "Insert link",
 29+ "wikieditor-toolbar-tool-link-cancel" : "Cancel",
 30+ "wikieditor-toolbar-tool-link-int-target-status-exists" : "Page exists",
 31+ "wikieditor-toolbar-tool-link-int-target-status-notexists" : "Page does not exist",
 32+ "wikieditor-toolbar-tool-link-int-target-status-invalid" : "Invalid title",
 33+ "wikieditor-toolbar-tool-link-int-target-status-external" : "External link",
 34+ "wikieditor-toolbar-tool-link-int-target-status-loading" : "Checking page existence...",
 35+ "wikieditor-toolbar-tool-link-int-invalid" : "The title you specified is invalid.",
 36+ "wikieditor-toolbar-tool-link-lookslikeinternal" : "The URL you specified looks like it was intended as a link to another wiki page. Do you want to make it an internal link?",
 37+ "wikieditor-toolbar-tool-link-lookslikeinternal-int" : "Internal link",
 38+ "wikieditor-toolbar-tool-link-lookslikeinternal-ext" : "External link",
 39+ "wikieditor-toolbar-tool-link-empty" : "You did not enter anything to link to.",
 40+ "wikieditor-toolbar-tool-file" : "Embedded file",
 41+ "wikieditor-toolbar-tool-file-pre" : "$1{{ns:file}}:",
 42+ "wikieditor-toolbar-tool-file-example" : "Example.jpg",
 43+ "wikieditor-toolbar-tool-reference" : "Reference",
 44+ "wikieditor-toolbar-tool-reference-example" : "Insert footnote text here",
 45+ "wikieditor-toolbar-tool-signature" : "Signature and timestamp",
 46+ "wikieditor-toolbar-section-advanced" : "Advanced",
 47+ "wikieditor-toolbar-tool-heading" : "Heading",
 48+ "wikieditor-toolbar-tool-heading-1" : "Level 1",
 49+ "wikieditor-toolbar-tool-heading-2" : "Level 2",
 50+ "wikieditor-toolbar-tool-heading-3" : "Level 3",
 51+ "wikieditor-toolbar-tool-heading-4" : "Level 4",
 52+ "wikieditor-toolbar-tool-heading-5" : "Level 5",
 53+ "wikieditor-toolbar-tool-heading-example" : "Heading text",
 54+ "wikieditor-toolbar-group-list" : "List",
 55+ "wikieditor-toolbar-tool-ulist" : "Bulleted list",
 56+ "wikieditor-toolbar-tool-ulist-example" : "Bulleted list item",
 57+ "wikieditor-toolbar-tool-olist" : "Numbered list",
 58+ "wikieditor-toolbar-tool-olist-example" : "Numbered list item",
 59+ "wikieditor-toolbar-tool-indent" : "Indentation",
 60+ "wikieditor-toolbar-tool-indent-example" : "Indented line",
 61+ "wikieditor-toolbar-group-size" : "Size",
 62+ "wikieditor-toolbar-tool-big" : "Big",
 63+ "wikieditor-toolbar-tool-big-example" : "Big text",
 64+ "wikieditor-toolbar-tool-small" : "Small",
 65+ "wikieditor-toolbar-tool-small-example" : "Small text",
 66+ "wikieditor-toolbar-group-baseline" : "Baseline",
 67+ "wikieditor-toolbar-tool-superscript" : "Superscript",
 68+ "wikieditor-toolbar-tool-superscript-example" : "Superscript text",
 69+ "wikieditor-toolbar-tool-subscript" : "Subscript",
 70+ "wikieditor-toolbar-tool-subscript-example" : "Subscript text",
 71+ "wikieditor-toolbar-group-insert" : "Insert",
 72+ "wikieditor-toolbar-tool-gallery" : "Picture gallery",
 73+ "wikieditor-toolbar-tool-gallery-example" : "{{ns:file}}:Example.jpg|Caption1\n{{ns:file}}:Example.jpg|Caption2",
 74+ "wikieditor-toolbar-tool-newline" : "New line",
 75+ "wikieditor-toolbar-tool-table" : "Table",
 76+ "wikieditor-toolbar-tool-table-example-old" : "-\n! header 1\n! header 2\n! header 3\n|-\n| row 1, cell 1\n| row 1, cell 2\n| row 1, cell 3\n|-\n| row 2, cell 1\n| row 2, cell 2\n| row 2, cell 3",
 77+ "wikieditor-toolbar-tool-table-example-cell-text" : "Cell text",
 78+ "wikieditor-toolbar-tool-table-example-header" : "Header text",
 79+ "wikieditor-toolbar-tool-table-title" : "Insert table",
 80+ "wikieditor-toolbar-tool-table-dimensions-rows" : "Rows",
 81+ "wikieditor-toolbar-tool-table-dimensions-columns" : "Columns",
 82+ "wikieditor-toolbar-tool-table-dimensions-header" : "Add header row",
 83+ "wikieditor-toolbar-tool-table-wikitable" : "Style with borders",
 84+ "wikieditor-toolbar-tool-table-sortable" : "Make table sortable",
 85+ "wikieditor-toolbar-tool-table-example" : "Example",
 86+ "wikieditor-toolbar-tool-table-preview" : "Preview",
 87+ "wikieditor-toolbar-tool-table-insert" : "Insert",
 88+ "wikieditor-toolbar-tool-table-cancel" : "Cancel",
 89+ "wikieditor-toolbar-tool-table-example-text" : "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Ut nec purus diam. Sed aliquam imperdiet nunc quis lacinia. Donec rutrum consectetur placerat. Sed volutpat neque non purus faucibus id ultricies enim euismod.",
 90+ "wikieditor-toolbar-tool-table-toomany" : "Inserting a table with more than $1 cells is not possible with this dialog.",
 91+ "wikieditor-toolbar-tool-table-invalidnumber" : "You have not entered a valid number of rows or columns.",
 92+ "wikieditor-toolbar-tool-table-zero" : "You cannot insert a table with zero rows or columns.",
 93+ "wikieditor-toolbar-tool-replace" : "Search and replace",
 94+ "wikieditor-toolbar-tool-replace-title" : "Search and replace",
 95+ "wikieditor-toolbar-tool-replace-search" : "Search for:",
 96+ "wikieditor-toolbar-tool-replace-replace" : "Replace with:",
 97+ "wikieditor-toolbar-tool-replace-case" : "Match case",
 98+ "wikieditor-toolbar-tool-replace-regex" : "Treat search string as a regular expression",
 99+ "wikieditor-toolbar-tool-replace-button-findnext" : "Find next",
 100+ "wikieditor-toolbar-tool-replace-button-replacenext" : "Replace next",
 101+ "wikieditor-toolbar-tool-replace-button-replaceall" : "Replace all",
 102+ "wikieditor-toolbar-tool-replace-close" : "Cancel",
 103+ "wikieditor-toolbar-tool-replace-nomatch" : "Your search did not match anything.",
 104+ "wikieditor-toolbar-tool-replace-success" : "$1 replacement(s) made.",
 105+ "wikieditor-toolbar-tool-replace-emptysearch" : "You did not enter anything to search for.",
 106+ "wikieditor-toolbar-tool-replace-invalidregex" : "The regular expression you entered is invalid: $1",
 107+ "wikieditor-toolbar-section-characters" : "Special characters",
 108+ "wikieditor-toolbar-characters-page-latin" : "Latin",
 109+ "wikieditor-toolbar-characters-page-latinextended" : "Latin extended",
 110+ "wikieditor-toolbar-characters-page-ipa" : "IPA",
 111+ "wikieditor-toolbar-characters-page-symbols" : "Symbols",
 112+ "wikieditor-toolbar-characters-page-greek" : "Greek",
 113+ "wikieditor-toolbar-characters-page-cyrillic" : "Cyrillic",
 114+ "wikieditor-toolbar-characters-page-arabic" : "Arabic",
 115+ "wikieditor-toolbar-characters-page-hebrew" : "Hebrew",
 116+ "wikieditor-toolbar-characters-page-telugu" : "Telugu",
 117+ "wikieditor-toolbar-characters-page-sinhala" : "Sinhala",
 118+ "wikieditor-toolbar-characters-page-gujarati" : "Gujarati",
 119+ "wikieditor-toolbar-section-help" : "Help",
 120+ "wikieditor-toolbar-help-heading-description" : "Description",
 121+ "wikieditor-toolbar-help-heading-syntax" : "What you type",
 122+ "wikieditor-toolbar-help-heading-result" : "What you get",
 123+ "wikieditor-toolbar-help-page-format" : "Formatting",
 124+ "wikieditor-toolbar-help-page-link" : "Links",
 125+ "wikieditor-toolbar-help-page-heading" : "Headings",
 126+ "wikieditor-toolbar-help-page-list" : "Lists",
 127+ "wikieditor-toolbar-help-page-file" : "Files",
 128+ "wikieditor-toolbar-help-page-reference" : "References",
 129+ "wikieditor-toolbar-help-page-discussion" : "Discussion",
 130+ "wikieditor-toolbar-help-content-italic-description" : "Italic",
 131+ "wikieditor-toolbar-help-content-italic-syntax" : "''Italic text''",
 132+ "wikieditor-toolbar-help-content-italic-result" : "<em>Italic text</em>",
 133+ "wikieditor-toolbar-help-content-bold-description" : "Bold",
 134+ "wikieditor-toolbar-help-content-bold-syntax" : "'''Bold text'''",
 135+ "wikieditor-toolbar-help-content-bold-result" : "<strong>Bold text</strong>",
 136+ "wikieditor-toolbar-help-content-bolditalic-description" : "Bold &amp; italic",
 137+ "wikieditor-toolbar-help-content-bolditalic-syntax" : "'''''Bold &amp; italic text'''''",
 138+ "wikieditor-toolbar-help-content-bolditalic-result" : "<strong><em>Bold &amp; italic text</em></strong>",
 139+ "wikieditor-toolbar-help-content-ilink-description" : "Internal link",
 140+ "wikieditor-toolbar-help-content-ilink-syntax" : "[[Page title|Link label]]<br />[[Page title]]",
 141+ "wikieditor-toolbar-help-content-ilink-result" : "<a href='#'>Link label</a><br /><a href='#'>Page title</a>",
 142+ "wikieditor-toolbar-help-content-xlink-description" : "External link",
 143+ "wikieditor-toolbar-help-content-xlink-syntax" : "[http://www.example.org Link label]<br />[http://www.example.org]<br />http://www.example.org",
 144+ "wikieditor-toolbar-help-content-xlink-result" : "<a href='#' class='external'>Link label</a><br /><a href='#' class='external autonumber'>[1]</a><br /><a href='#' class='external'>http://www.example.org</a>",
 145+ "wikieditor-toolbar-help-content-heading1-description" : "1st level heading",
 146+ "wikieditor-toolbar-help-content-heading1-syntax" : "= Heading text =",
 147+ "wikieditor-toolbar-help-content-heading1-result" : "<h1>Heading text</h1>",
 148+ "wikieditor-toolbar-help-content-heading2-description" : "2nd level heading",
 149+ "wikieditor-toolbar-help-content-heading2-syntax" : "== Heading text ==",
 150+ "wikieditor-toolbar-help-content-heading2-result" : "<h2>Heading text</h2>",
 151+ "wikieditor-toolbar-help-content-heading3-description" : "3rd level heading",
 152+ "wikieditor-toolbar-help-content-heading3-syntax" : "=== Heading text ===",
 153+ "wikieditor-toolbar-help-content-heading3-result" : "<h3>Heading text</h3>",
 154+ "wikieditor-toolbar-help-content-heading4-description" : "4th level heading",
 155+ "wikieditor-toolbar-help-content-heading4-syntax" : "==== Heading text ====",
 156+ "wikieditor-toolbar-help-content-heading4-result" : "<h4>Heading text</h4>",
 157+ "wikieditor-toolbar-help-content-heading5-description" : "5th level heading",
 158+ "wikieditor-toolbar-help-content-heading5-syntax" : "===== Heading text =====",
 159+ "wikieditor-toolbar-help-content-heading5-result" : "<h5>Heading text</h5>",
 160+ "wikieditor-toolbar-help-content-ulist-description" : "Bulleted list",
 161+ "wikieditor-toolbar-help-content-ulist-syntax" : "* List item<br />* List item",
 162+ "wikieditor-toolbar-help-content-ulist-result" : "<ul><li>List item</li><li>List item</li></ul>",
 163+ "wikieditor-toolbar-help-content-olist-description" : "Numbered list",
 164+ "wikieditor-toolbar-help-content-olist-syntax" : "# List item<br /># List item",
 165+ "wikieditor-toolbar-help-content-olist-result" : "<ol><li>List item</li><li>List item</li></ol>",
 166+ "wikieditor-toolbar-help-content-file-description" : "Embedded file",
 167+ "wikieditor-toolbar-help-content-file-syntax" : "[[{{ns:file}}:Example.png|thumb|Caption text]]",
 168+ "wikieditor-toolbar-help-content-file-result" : "<div style='width:104px;' class='thumbinner'><a title='Caption text' class='image' href='#'><img height='50' width='100' border='0' class='thumbimage' src='extensions/UsabilityInitiative/images/wikiEditor/toolbar/example-image.png' alt=''/></a><div class='thumbcaption'><div class='magnify'><a title='Enlarge' class='internal' href='#'><img height='11' width='15' alt='' src='$1/common/images/magnify-clip.png'/></a></div>Caption text</div></div>",
 169+ "wikieditor-toolbar-help-content-reference-description" : "Reference",
 170+ "wikieditor-toolbar-help-content-reference-syntax" : "Page text.&lt;ref name=\"test\"&gt;[http://www.example.org Link text], additional text.&lt;/ref&gt;",
 171+ "wikieditor-toolbar-help-content-reference-result" : "Page text.<sup><a href='#'>[1]</a></sup>",
 172+ "wikieditor-toolbar-help-content-rereference-description" : "Additional use of same reference",
 173+ "wikieditor-toolbar-help-content-rereference-syntax" : "&lt;ref name=\"test\" /&gt;",
 174+ "wikieditor-toolbar-help-content-rereference-result" : "Page text.<sup><a href='#'>[1]</a></sup>",
 175+ "wikieditor-toolbar-help-content-showreferences-description" : "Display references",
 176+ "wikieditor-toolbar-help-content-showreferences-syntax" : "&lt;references /&gt;",
 177+ "wikieditor-toolbar-help-content-showreferences-result" : "<ol class='references'><li id='cite_note-test-0'><b><a title='' href='#'>^</a></b> <a rel='nofollow' title='http://www.example.org' class='external text' href='#'>Link text</a>, additional text.</li></ol>",
 178+ "wikieditor-toolbar-help-content-signaturetimestamp-description" : "Signature with timestamp",
 179+ "wikieditor-toolbar-help-content-signaturetimestamp-syntax" : "~~~~",
 180+ "wikieditor-toolbar-help-content-signaturetimestamp-result" : "<a href='#' title='{{#special:mypage}}'>Username</a> (<a href='#' title='{{#special:mytalk}}'>talk</a>) 15:54, 10 June 2009 (UTC)",
 181+ "wikieditor-toolbar-help-content-signature-description" : "Signature",
 182+ "wikieditor-toolbar-help-content-signature-syntax" : "~~~",
 183+ "wikieditor-toolbar-help-content-signature-result" : "<a href='#' title='{{#special:mypage}}'>Username</a> (<a href='#' title='{{#special:mytalk}}'>talk</a>)",
 184+ "wikieditor-toolbar-help-content-indent-description" : "Indent",
 185+ "wikieditor-toolbar-help-content-indent-syntax" : "Normal text<br />:Indented text<br />::Indented text",
 186+ "wikieditor-toolbar-help-content-indent-result" : "Normal text<dl><dd>Indented text<dl><dd>Indented text</dd></dl></dd></dl>"
 187+});
 188+
4189 mw.ready( function() {
5190 // Check preferences for toolbar
6191 if ( !wgWikiEditorEnabledModules.toolbar ) {
@@ -1652,3 +1837,4 @@
16531838
16541839 } } );
16551840
 1841+mw.loadDone( 'wikiEditor.config.toolbar' );
\ No newline at end of file
Index: trunk/extensions/UsabilityInitiative/WikiEditor/Modules/Toc/Toc.js
@@ -1,5 +1,11 @@
22 /* JavaScript for WikiEditor Toc module */
33
 4+mw.addMessages({
 5+ "wikieditor-toc-preference" : "Enable navigable table of contents",
 6+ "wikieditor-toc-show" : "Show contents",
 7+ "wikieditor-toc-hide" : "Hide contents"
 8+});
 9+
410 mw.ready( function() {
511 // Check preferences for toolbar
612 if ( !wgWikiEditorPreferences || !( wgWikiEditorPreferences.toc && wgWikiEditorPreferences.toc.enable ) ) {
@@ -11,3 +17,5 @@
1218 { 'toc' : { 'rtl' : ( $j( 'body' ).is( '.rtl' ) ) } } );
1319 }
1420 });
 21+
 22+mw.loadDone( 'wikiEditor.config.toc' );
\ No newline at end of file
Index: trunk/extensions/UsabilityInitiative/WikiEditor/Modules/Publish/Publish.js
@@ -1,5 +1,16 @@
22 /* JavaScript for WikiEditor Publish module */
33
 4+mw.addMessages({
 5+ "wikieditor-publish-preference" : "Enable step-by-step publishing",
 6+ "wikieditor-publish-button-publish" : "Publish",
 7+ "wikieditor-publish-button-cancel" : "Cancel",
 8+ "wikieditor-publish-dialog-title" : "Publish to {{SITENAME}}",
 9+ "wikieditor-publish-dialog-summary" : "Edit summary (briefly describe the changes you have made):",
 10+ "wikieditor-publish-dialog-minor" : "Minor edit",
 11+ "wikieditor-publish-dialog-watch" : "Watch this page",
 12+ "wikieditor-publish-dialog-publish" : "Publish",
 13+ "wikieditor-publish-dialog-goback" : "Go back"
 14+});
415 mw.ready( function() {
516 // Check preferences for publish
617 if ( !wgWikiEditorEnabledModules.preview ) {
@@ -10,3 +21,5 @@
1122 $j( 'textarea#wpTextbox1' ).wikiEditor( 'addModule', 'publish' );
1223 }
1324 });
 25+
 26+mw.loadDone( 'wikiEditor.config.publish' );
Index: trunk/extensions/UsabilityInitiative/WikiEditor/Modules/Highlight/Highlight.js
@@ -1,5 +1,9 @@
22 /* JavaScript for WikiEditor Highlight module */
33
 4+mw.addMessages({
 5+ "wikieditor-highlight-preference" : "Enable syntax highlighting when editing"
 6+});
 7+
48 mw.ready( function() {
59 // Check preferences for highlight
610 if ( !wgWikiEditorEnabledModules.highlight ) {
@@ -10,3 +14,5 @@
1115 $j( 'textarea#wpTextbox1' ).wikiEditor( 'addModule', 'highlight' );
1216 }
1317 });
 18+
 19+mw.loadDone( 'wikiEditor.config.highlight' );
\ No newline at end of file
Index: trunk/extensions/UsabilityInitiative/js/js2stopgap/jquery.cookie.js
@@ -0,0 +1,97 @@
 2+/**
 3+ * Cookie plugin
 4+ *
 5+ * Copyright (c) 2006 Klaus Hartl (stilbuero.de)
 6+ * Dual licensed under the MIT and GPL licenses:
 7+ * http://www.opensource.org/licenses/mit-license.php
 8+ * http://www.gnu.org/licenses/gpl.html
 9+ *
 10+ */
 11+
 12+/**
 13+ * Create a cookie with the given name and value and other optional parameters.
 14+ *
 15+ * @example $.cookie('the_cookie', 'the_value');
 16+ * @desc Set the value of a cookie.
 17+ * @example $.cookie('the_cookie', 'the_value', { expires: 7, path: '/', domain: 'jquery.com', secure: true });
 18+ * @desc Create a cookie with all available options.
 19+ * @example $.cookie('the_cookie', 'the_value');
 20+ * @desc Create a session cookie.
 21+ * @example $.cookie('the_cookie', null);
 22+ * @desc Delete a cookie by passing null as value. Keep in mind that you have to use the same path and domain
 23+ * used when the cookie was set.
 24+ *
 25+ * @param String name The name of the cookie.
 26+ * @param String value The value of the cookie.
 27+ * @param Object options An object literal containing key/value pairs to provide optional cookie attributes.
 28+ * @option Number|Date expires Either an integer specifying the expiration date from now on in days or a Date object.
 29+ * If a negative value is specified (e.g. a date in the past), the cookie will be deleted.
 30+ * If set to null or omitted, the cookie will be a session cookie and will not be retained
 31+ * when the the browser exits.
 32+ * @option String path The value of the path atribute of the cookie (default: path of page that created the cookie).
 33+ * @option String domain The value of the domain attribute of the cookie (default: domain of page that created the cookie).
 34+ * @option Boolean secure If true, the secure attribute of the cookie will be set and the cookie transmission will
 35+ * require a secure protocol (like HTTPS).
 36+ * @type undefined
 37+ *
 38+ * @name $.cookie
 39+ * @cat Plugins/Cookie
 40+ * @author Klaus Hartl/klaus.hartl@stilbuero.de
 41+ */
 42+
 43+/**
 44+ * Get the value of a cookie with the given name.
 45+ *
 46+ * @example $.cookie('the_cookie');
 47+ * @desc Get the value of a cookie.
 48+ *
 49+ * @param String name The name of the cookie.
 50+ * @return The value of the cookie.
 51+ * @type String
 52+ *
 53+ * @name $.cookie
 54+ * @cat Plugins/Cookie
 55+ * @author Klaus Hartl/klaus.hartl@stilbuero.de
 56+ */
 57+jQuery.cookie = function(name, value, options) {
 58+ if (typeof value != 'undefined') { // name and value given, set cookie
 59+ options = options || {};
 60+ if (value === null) {
 61+ value = '';
 62+ options.expires = -1;
 63+ }
 64+ var expires = '';
 65+ if (options.expires && (typeof options.expires == 'number' || options.expires.toUTCString)) {
 66+ var date;
 67+ if (typeof options.expires == 'number') {
 68+ date = new Date();
 69+ date.setTime(date.getTime() + (options.expires * 24 * 60 * 60 * 1000));
 70+ } else {
 71+ date = options.expires;
 72+ }
 73+ expires = '; expires=' + date.toUTCString(); // use expires attribute, max-age is not supported by IE
 74+ }
 75+ // CAUTION: Needed to parenthesize options.path and options.domain
 76+ // in the following expressions, otherwise they evaluate to undefined
 77+ // in the packed version for some reason...
 78+ var path = options.path ? '; path=' + (options.path) : '';
 79+ var domain = options.domain ? '; domain=' + (options.domain) : '';
 80+ var secure = options.secure ? '; secure' : '';
 81+ document.cookie = [name, '=', encodeURIComponent(value), expires, path, domain, secure].join('');
 82+ } else { // only name given, get cookie
 83+ var cookieValue = null;
 84+ if (document.cookie && document.cookie != '') {
 85+ var cookies = document.cookie.split(';');
 86+ for (var i = 0; i < cookies.length; i++) {
 87+ var cookie = jQuery.trim(cookies[i]);
 88+ // Does this cookie string begin with the name we want?
 89+ if (cookie.substring(0, name.length + 1) == (name + '=')) {
 90+ cookieValue = decodeURIComponent(cookie.substring(name.length + 1));
 91+ break;
 92+ }
 93+ }
 94+ }
 95+ return cookieValue;
 96+ }
 97+};
 98+
Property changes on: trunk/extensions/UsabilityInitiative/js/js2stopgap/jquery.cookie.js
___________________________________________________________________
Added: svn:mergeinfo
Added: svn:eol-style
199 + native
Index: trunk/extensions/UsabilityInitiative/js/js2stopgap/jquery.textSelection.js
@@ -0,0 +1,376 @@
 2+/**
 3+ * These plugins provide extra functionality for interaction with textareas.
 4+ */
 5+( function( $ ) {
 6+$.fn.textSelection = function( command, options ) {
 7+var fn = {
 8+/**
 9+ * Get the contents of the textarea
 10+ */
 11+getContents: function() {
 12+ return this.val();
 13+},
 14+/**
 15+ * Get the currently selected text in this textarea. Will focus the textarea
 16+ * in some browsers (IE/Opera)
 17+ */
 18+getSelection: function() {
 19+ var e = this.get( 0 );
 20+ var retval = '';
 21+ if ( $(e).is( ':hidden' ) ) {
 22+ // Do nothing
 23+ } else if ( document.selection && document.selection.createRange ) {
 24+ e.focus();
 25+ var range = document.selection.createRange();
 26+ retval = range.text;
 27+ } else if ( e.selectionStart || e.selectionStart == '0' ) {
 28+ retval = e.value.substring( e.selectionStart, e.selectionEnd );
 29+ }
 30+ return retval;
 31+},
 32+/**
 33+ * Ported from skins/common/edit.js by Trevor Parscal
 34+ * (c) 2009 Wikimedia Foundation (GPLv2) - http://www.wikimedia.org
 35+ *
 36+ * Inserts text at the begining and end of a text selection, optionally
 37+ * inserting text at the caret when selection is empty.
 38+ */
 39+encapsulateSelection: function( options ) {
 40+ return this.each( function() {
 41+ /**
 42+ * Check if the selected text is the same as the insert text
 43+ */
 44+ function checkSelectedText() {
 45+ if ( !selText ) {
 46+ selText = options.peri;
 47+ isSample = true;
 48+ } else if ( options.replace ) {
 49+ selText = options.peri;
 50+ } else if ( selText.charAt( selText.length - 1 ) == ' ' ) {
 51+ // Exclude ending space char
 52+ selText = selText.substring(0, selText.length - 1);
 53+ options.post += ' ';
 54+ }
 55+ }
 56+ var selText = $(this).textSelection( 'getSelection' );
 57+ var isSample = false;
 58+ if ( this.style.display == 'none' ) {
 59+ // Do nothing
 60+ } else if ( this.selectionStart || this.selectionStart == '0' ) {
 61+ // Mozilla/Opera
 62+ $(this).focus();
 63+ var startPos = this.selectionStart;
 64+ var endPos = this.selectionEnd;
 65+ checkSelectedText();
 66+ if ( options.ownline ) {
 67+ if ( startPos != 0 && this.value.charAt( startPos - 1 ) != "\n" ) {
 68+ options.pre = "\n" + options.pre;
 69+ }
 70+ if ( this.value.charAt( endPos ) != "\n" ) {
 71+ options.post += "\n";
 72+ }
 73+ }
 74+ this.value = this.value.substring( 0, startPos ) + options.pre + selText + options.post +
 75+ this.value.substring( endPos, this.value.length );
 76+ if ( window.opera ) {
 77+ options.pre = options.pre.replace( /\r?\n/g, "\r\n" );
 78+ selText = selText.replace( /\r?\n/g, "\r\n" );
 79+ options.post = options.post.replace( /\r?\n/g, "\r\n" );
 80+ }
 81+ if ( isSample ) {
 82+ this.selectionStart = startPos + options.pre.length;
 83+ this.selectionEnd = startPos + options.pre.length + selText.length;
 84+ } else {
 85+ this.selectionStart = startPos + options.pre.length + selText.length +
 86+ options.post.length;
 87+ this.selectionEnd = this.selectionStart;
 88+ }
 89+ } else if ( document.selection && document.selection.createRange ) {
 90+ // IE
 91+ $(this).focus();
 92+ var range = document.selection.createRange();
 93+ if ( options.ownline && range.moveStart ) {
 94+ var range2 = document.selection.createRange();
 95+ range2.collapse();
 96+ range2.moveStart( 'character', -1 );
 97+ // FIXME: Which check is correct?
 98+ if ( range2.text != "\r" && range2.text != "\n" && range2.text != "" ) {
 99+ options.pre = "\n" + options.pre;
 100+ }
 101+ var range3 = document.selection.createRange();
 102+ range3.collapse( false );
 103+ range3.moveEnd( 'character', 1 );
 104+ if ( range3.text != "\r" && range3.text != "\n" && range3.text != "" ) {
 105+ options.post += "\n";
 106+ }
 107+ }
 108+ checkSelectedText();
 109+ range.text = options.pre + selText + options.post;
 110+ if ( isSample && range.moveStart ) {
 111+ range.moveStart( 'character', - options.post.length - selText.length );
 112+ range.moveEnd( 'character', - options.post.length );
 113+ }
 114+ range.select();
 115+ }
 116+ // Scroll the textarea to the inserted text
 117+ $(this).textSelection( 'scrollToCaretPosition' );
 118+ $(this).trigger( 'encapsulateSelection', [ options.pre, options.peri, options.post, options.ownline,
 119+ options.replace ] );
 120+ });
 121+},
 122+/**
 123+ * Ported from Wikia's LinkSuggest extension
 124+ * https://svn.wikia-code.com/wikia/trunk/extensions/wikia/LinkSuggest
 125+ * Some code copied from
 126+ * http://www.dedestruct.com/2008/03/22/howto-cross-browser-cursor-position-in-textareas/
 127+ *
 128+ * Get the position (in resolution of bytes not nessecarily characters)
 129+ * in a textarea
 130+ */
 131+ getCaretPosition: function( options ) {
 132+ function getCaret( e ) {
 133+ var caretPos = 0, endPos = 0;
 134+ if ( $.browser.msie ) {
 135+ // IE Support
 136+ var postFinished = false;
 137+ var periFinished = false;
 138+ var postFinished = false;
 139+ var preText, rawPreText, periText;
 140+ var rawPeriText, postText, rawPostText;
 141+ // Create range containing text in the selection
 142+ var periRange = document.selection.createRange().duplicate();
 143+ // Create range containing text before the selection
 144+ var preRange = document.body.createTextRange();
 145+ // Select all the text
 146+ preRange.moveToElementText(e);
 147+ // Move the end where we need it
 148+ preRange.setEndPoint("EndToStart", periRange);
 149+ // Create range containing text after the selection
 150+ var postRange = document.body.createTextRange();
 151+ // Select all the text
 152+ postRange.moveToElementText(e);
 153+ // Move the start where we need it
 154+ postRange.setEndPoint("StartToEnd", periRange);
 155+ // Load the text values we need to compare
 156+ preText = rawPreText = preRange.text;
 157+ periText = rawPeriText = periRange.text;
 158+ postText = rawPostText = postRange.text;
 159+ /*
 160+ * Check each range for trimmed newlines by shrinking the range by 1
 161+ * character and seeing if the text property has changed. If it has
 162+ * not changed then we know that IE has trimmed a \r\n from the end.
 163+ */
 164+ do {
 165+ if ( !postFinished ) {
 166+ if ( preRange.compareEndPoints( "StartToEnd", preRange ) == 0 ) {
 167+ postFinished = true;
 168+ } else {
 169+ preRange.moveEnd( "character", -1 )
 170+ if ( preRange.text == preText ) {
 171+ rawPreText += "\r\n";
 172+ } else {
 173+ postFinished = true;
 174+ }
 175+ }
 176+ }
 177+ if ( !periFinished ) {
 178+ if ( periRange.compareEndPoints( "StartToEnd", periRange ) == 0 ) {
 179+ periFinished = true;
 180+ } else {
 181+ periRange.moveEnd( "character", -1 )
 182+ if ( periRange.text == periText ) {
 183+ rawPeriText += "\r\n";
 184+ } else {
 185+ periFinished = true;
 186+ }
 187+ }
 188+ }
 189+ if ( !postFinished ) {
 190+ if ( postRange.compareEndPoints("StartToEnd", postRange) == 0 ) {
 191+ postFinished = true;
 192+ } else {
 193+ postRange.moveEnd( "character", -1 )
 194+ if ( postRange.text == postText ) {
 195+ rawPostText += "\r\n";
 196+ } else {
 197+ postFinished = true;
 198+ }
 199+ }
 200+ }
 201+ } while ( ( !postFinished || !periFinished || !postFinished ) );
 202+ caretPos = rawPreText.replace( /\r\n/g, "\n" ).length;
 203+ endPos = caretPos + rawPeriText.replace( /\r\n/g, "\n" ).length;
 204+ } else if ( e.selectionStart || e.selectionStart == '0' ) {
 205+ // Firefox support
 206+ caretPos = e.selectionStart;
 207+ endPos = e.selectionEnd;
 208+ }
 209+ return options.startAndEnd ? [ caretPos, endPos ] : caretPos;
 210+ }
 211+ return getCaret( this.get( 0 ) );
 212+},
 213+setSelection: function( options ) {
 214+ return this.each( function() {
 215+ if ( $(this).is( ':hidden' ) ) {
 216+ // Do nothing
 217+ } else if ( this.selectionStart || this.selectionStart == '0' ) {
 218+ // Opera 9.0 doesn't allow setting selectionStart past
 219+ // selectionEnd; any attempts to do that will be ignored
 220+ // Make sure to set them in the right order
 221+ if ( options.start > this.selectionEnd ) {
 222+ this.selectionEnd = options.end;
 223+ this.selectionStart = options.start;
 224+ } else {
 225+ this.selectionStart = options.start;
 226+ this.selectionEnd = options.end;
 227+ }
 228+ } else if ( document.body.createTextRange ) {
 229+ var selection = document.body.createTextRange();
 230+ selection.moveToElementText( this );
 231+ var length = selection.text.length;
 232+ selection.moveStart( 'character', options.start );
 233+ selection.moveEnd( 'character', -length + options.end );
 234+ selection.select();
 235+ }
 236+ });
 237+},
 238+/**
 239+ * Ported from Wikia's LinkSuggest extension
 240+ * https://svn.wikia-code.com/wikia/trunk/extensions/wikia/LinkSuggest
 241+ *
 242+ * Scroll a textarea to the current cursor position. You can set the cursor
 243+ * position with setSelection()
 244+ * @param force boolean Whether to force a scroll even if the caret position
 245+ * is already visible. Defaults to false
 246+ */
 247+scrollToCaretPosition: function( options ) {
 248+ function getLineLength( e ) {
 249+ return Math.floor( e.scrollWidth / ( $.os.name == 'linux' ? 7 : 8 ) );
 250+ }
 251+ function getCaretScrollPosition( e ) {
 252+ // FIXME: This functions sucks and is off by a few lines most
 253+ // of the time. It should be replaced by something decent.
 254+ var text = e.value.replace( /\r/g, "" );
 255+ var caret = $( e ).textSelection( 'getCaretPosition' );
 256+ var lineLength = getLineLength( e );
 257+ var row = 0;
 258+ var charInLine = 0;
 259+ var lastSpaceInLine = 0;
 260+ for ( i = 0; i < caret; i++ ) {
 261+ charInLine++;
 262+ if ( text.charAt( i ) == " " ) {
 263+ lastSpaceInLine = charInLine;
 264+ } else if ( text.charAt( i ) == "\n" ) {
 265+ lastSpaceInLine = 0;
 266+ charInLine = 0;
 267+ row++;
 268+ }
 269+ if ( charInLine > lineLength ) {
 270+ if ( lastSpaceInLine > 0 ) {
 271+ charInLine = charInLine - lastSpaceInLine;
 272+ lastSpaceInLine = 0;
 273+ row++;
 274+ }
 275+ }
 276+ }
 277+ var nextSpace = 0;
 278+ for ( j = caret; j < caret + lineLength; j++ ) {
 279+ if (
 280+ text.charAt( j ) == " " ||
 281+ text.charAt( j ) == "\n" ||
 282+ caret == text.length
 283+ ) {
 284+ nextSpace = j;
 285+ break;
 286+ }
 287+ }
 288+ if ( nextSpace > lineLength && caret <= lineLength ) {
 289+ charInLine = caret - lastSpaceInLine;
 290+ row++;
 291+ }
 292+ return ( $.os.name == 'mac' ? 13 : ( $.os.name == 'linux' ? 15 : 16 ) ) * row;
 293+ }
 294+ return this.each(function() {
 295+ if ( $(this).is( ':hidden' ) ) {
 296+ // Do nothing
 297+ } else if ( this.selectionStart || this.selectionStart == '0' ) {
 298+ // Mozilla
 299+ var scroll = getCaretScrollPosition( this );
 300+ if ( options.force || scroll < $(this).scrollTop() ||
 301+ scroll > $(this).scrollTop() + $(this).height() )
 302+ $(this).scrollTop( scroll );
 303+ } else if ( document.selection && document.selection.createRange ) {
 304+ // IE / Opera
 305+ /*
 306+ * IE automatically scrolls the selected text to the
 307+ * bottom of the textarea at range.select() time, except
 308+ * if it was already in view and the cursor position
 309+ * wasn't changed, in which case it does nothing. To
 310+ * cover that case, we'll force it to act by moving one
 311+ * character back and forth.
 312+ */
 313+ var range = document.selection.createRange();
 314+ var pos = $(this).textSelection( 'getCaretPosition' );
 315+ var oldScrollTop = this.scrollTop;
 316+ range.moveToElementText( this );
 317+ range.collapse();
 318+ range.move( 'character', pos + 1);
 319+ range.select();
 320+ if ( this.scrollTop != oldScrollTop )
 321+ this.scrollTop += range.offsetTop;
 322+ else if ( options.force ) {
 323+ range.move( 'character', -1 );
 324+ range.select();
 325+ }
 326+ }
 327+ $(this).trigger( 'scrollToPosition' );
 328+ } );
 329+}
 330+};
 331+ // Apply defaults
 332+ switch ( command ) {
 333+ //case 'getContents': // no params
 334+ //case 'setContents': // no params with defaults
 335+ //case 'getSelection': // no params
 336+ case 'encapsulateSelection':
 337+ options = $.extend( {
 338+ 'pre': '', // Text to insert before the cursor/selection
 339+ 'peri': '', // Text to insert between pre and post and select afterwards
 340+ 'post': '', // Text to insert after the cursor/selection
 341+ 'ownline': false, // Put the inserted text on a line of its own
 342+ 'replace': false // If there is a selection, replace it with peri instead of leaving it alone
 343+ }, options );
 344+ break;
 345+ case 'getCaretPosition':
 346+ options = $.extend( {
 347+ 'startAndEnd': false // Return [start, end] instead of just start
 348+ }, options );
 349+ // FIXME: We may not need character position-based functions if we insert markers in the right places
 350+ break;
 351+ case 'setSelection':
 352+ options = $.extend( {
 353+ 'start': undefined, // Position to start selection at
 354+ 'end': undefined, // Position to end selection at. Defaults to start
 355+ 'startContainer': undefined, // Element to start selection in (iframe only)
 356+ 'endContainer': undefined // Element to end selection in (iframe only). Defaults to startContainer
 357+ }, options );
 358+ if ( options.end === undefined )
 359+ options.end = options.start;
 360+ if ( options.endContainer == undefined )
 361+ options.endContainer = options.startContainer;
 362+ // FIXME: We may not need character position-based functions if we insert markers in the right places
 363+ break;
 364+ case 'scrollToCaretPosition':
 365+ options = $.extend( {
 366+ 'force': false // Force a scroll even if the caret position is already visible
 367+ }, options );
 368+ break;
 369+ }
 370+ var context = $(this).data( 'wikiEditor-context' );
 371+ var hasIframe = context !== undefined && context.$iframe !== undefined;
 372+ // iframe functions have not been implemented yet, this is a temp hack
 373+ //var hasIframe = false;
 374+ return ( hasIframe ? context.fn : fn )[command].call( this, options );
 375+};
 376+
 377+} )( jQuery );
\ No newline at end of file
Property changes on: trunk/extensions/UsabilityInitiative/js/js2stopgap/jquery.textSelection.js
___________________________________________________________________
Added: svn:mergeinfo
Added: svn:eol-style
1378 + native
Index: trunk/extensions/UsabilityInitiative/js/loader.js
@@ -0,0 +1,35 @@
 2+/**
 3+* mwEmbed module type loader for usability initiative
 4+* This file is included as a "core" script on every page so should be kept small.
 5+*
 6+* loader.js defines:
 7+* * all classes names and their paths
 8+* * module loader functions
 9+*
 10+* loader.js files not in the core mwEmbed module folder must be defined in the global
 11+* $wgJsModuleLoaderPaths[] = ",
 12+*/
 13+// For non-script loader javascript path debuging
 14+mw.setConfig('loaderContext', wgScriptPath + '/extensions/UsabilityInitiative/js/');
 15+
 16+mw.addClassFilePaths({
 17+ "$j.whileAsync" : "plugins/jquery.async.js",
 18+ "$j.fn.autoEllipsis" : "plugins/jquery.autoEllipsis.js",
 19+ "$j.browserTest" : "plugins/jquery.browser.js",
 20+ "$j.fn.collapsibleTabs" : "plugins/jquery.collapsibleTabs.js",
 21+ "$j.fn.delayedBind" : "plugins/jquery.delayedBind.js",
 22+ "inherit" : "plugins/jquery.inherit.js",
 23+ "$j.fn.namespaceSelector" : "plugins/jquery.namespaceSelect.js",
 24+ "$j.suggestions" : "plugins/jquery.suggestions.js",
 25+ "$j.wikiEditor" : "plugins/jquery.wikiEditor.js",
 26+
 27+ "$j.wikiEditor.modules.highlight" : "plugins/jquery.wikiEditor.highlight.js",
 28+ "$j.wikiEditor.modules.toolbar" : "plugins/jquery.wikiEditor.toolbar.js",
 29+ "$j.wikiEditor.modules.dialogs" : "plugins/jquery.wikiEditor.dialogs.js",
 30+ "$j.wikiEditor.modules.toc" : "plugins/jquery.wikiEditor.toc.js",
 31+ "$j.wikiEditor.modules.preview" : "plugins/jquery.wikiEditor.preview.js",
 32+ "$j.wikiEditor.modules.templateEditor" : "plugins/jquery.wikiEditor.templateEditor.js",
 33+ "$j.wikiEditor.modules.publish" : "plugins/jquery.wikiEditor.publish.js"
 34+} );
 35+
 36+
Index: trunk/extensions/UsabilityInitiative/js/plugins/jquery.textSelection.js
@@ -1,376 +0,0 @@
2 -/**
3 - * These plugins provide extra functionality for interaction with textareas.
4 - */
5 -( function( $ ) {
6 -$.fn.textSelection = function( command, options ) {
7 -var fn = {
8 -/**
9 - * Get the contents of the textarea
10 - */
11 -getContents: function() {
12 - return this.val();
13 -},
14 -/**
15 - * Get the currently selected text in this textarea. Will focus the textarea
16 - * in some browsers (IE/Opera)
17 - */
18 -getSelection: function() {
19 - var e = this.get( 0 );
20 - var retval = '';
21 - if ( $(e).is( ':hidden' ) ) {
22 - // Do nothing
23 - } else if ( document.selection && document.selection.createRange ) {
24 - e.focus();
25 - var range = document.selection.createRange();
26 - retval = range.text;
27 - } else if ( e.selectionStart || e.selectionStart == '0' ) {
28 - retval = e.value.substring( e.selectionStart, e.selectionEnd );
29 - }
30 - return retval;
31 -},
32 -/**
33 - * Ported from skins/common/edit.js by Trevor Parscal
34 - * (c) 2009 Wikimedia Foundation (GPLv2) - http://www.wikimedia.org
35 - *
36 - * Inserts text at the begining and end of a text selection, optionally
37 - * inserting text at the caret when selection is empty.
38 - */
39 -encapsulateSelection: function( options ) {
40 - return this.each( function() {
41 - /**
42 - * Check if the selected text is the same as the insert text
43 - */
44 - function checkSelectedText() {
45 - if ( !selText ) {
46 - selText = options.peri;
47 - isSample = true;
48 - } else if ( options.replace ) {
49 - selText = options.peri;
50 - } else if ( selText.charAt( selText.length - 1 ) == ' ' ) {
51 - // Exclude ending space char
52 - selText = selText.substring(0, selText.length - 1);
53 - options.post += ' ';
54 - }
55 - }
56 - var selText = $(this).textSelection( 'getSelection' );
57 - var isSample = false;
58 - if ( this.style.display == 'none' ) {
59 - // Do nothing
60 - } else if ( this.selectionStart || this.selectionStart == '0' ) {
61 - // Mozilla/Opera
62 - $(this).focus();
63 - var startPos = this.selectionStart;
64 - var endPos = this.selectionEnd;
65 - checkSelectedText();
66 - if ( options.ownline ) {
67 - if ( startPos != 0 && this.value.charAt( startPos - 1 ) != "\n" ) {
68 - options.pre = "\n" + options.pre;
69 - }
70 - if ( this.value.charAt( endPos ) != "\n" ) {
71 - options.post += "\n";
72 - }
73 - }
74 - this.value = this.value.substring( 0, startPos ) + options.pre + selText + options.post +
75 - this.value.substring( endPos, this.value.length );
76 - if ( window.opera ) {
77 - options.pre = options.pre.replace( /\r?\n/g, "\r\n" );
78 - selText = selText.replace( /\r?\n/g, "\r\n" );
79 - options.post = options.post.replace( /\r?\n/g, "\r\n" );
80 - }
81 - if ( isSample ) {
82 - this.selectionStart = startPos + options.pre.length;
83 - this.selectionEnd = startPos + options.pre.length + selText.length;
84 - } else {
85 - this.selectionStart = startPos + options.pre.length + selText.length +
86 - options.post.length;
87 - this.selectionEnd = this.selectionStart;
88 - }
89 - } else if ( document.selection && document.selection.createRange ) {
90 - // IE
91 - $(this).focus();
92 - var range = document.selection.createRange();
93 - if ( options.ownline && range.moveStart ) {
94 - var range2 = document.selection.createRange();
95 - range2.collapse();
96 - range2.moveStart( 'character', -1 );
97 - // FIXME: Which check is correct?
98 - if ( range2.text != "\r" && range2.text != "\n" && range2.text != "" ) {
99 - options.pre = "\n" + options.pre;
100 - }
101 - var range3 = document.selection.createRange();
102 - range3.collapse( false );
103 - range3.moveEnd( 'character', 1 );
104 - if ( range3.text != "\r" && range3.text != "\n" && range3.text != "" ) {
105 - options.post += "\n";
106 - }
107 - }
108 - checkSelectedText();
109 - range.text = options.pre + selText + options.post;
110 - if ( isSample && range.moveStart ) {
111 - range.moveStart( 'character', - options.post.length - selText.length );
112 - range.moveEnd( 'character', - options.post.length );
113 - }
114 - range.select();
115 - }
116 - // Scroll the textarea to the inserted text
117 - $(this).textSelection( 'scrollToCaretPosition' );
118 - $(this).trigger( 'encapsulateSelection', [ options.pre, options.peri, options.post, options.ownline,
119 - options.replace ] );
120 - });
121 -},
122 -/**
123 - * Ported from Wikia's LinkSuggest extension
124 - * https://svn.wikia-code.com/wikia/trunk/extensions/wikia/LinkSuggest
125 - * Some code copied from
126 - * http://www.dedestruct.com/2008/03/22/howto-cross-browser-cursor-position-in-textareas/
127 - *
128 - * Get the position (in resolution of bytes not nessecarily characters)
129 - * in a textarea
130 - */
131 - getCaretPosition: function( options ) {
132 - function getCaret( e ) {
133 - var caretPos = 0, endPos = 0;
134 - if ( $.browser.msie ) {
135 - // IE Support
136 - var postFinished = false;
137 - var periFinished = false;
138 - var postFinished = false;
139 - var preText, rawPreText, periText;
140 - var rawPeriText, postText, rawPostText;
141 - // Create range containing text in the selection
142 - var periRange = document.selection.createRange().duplicate();
143 - // Create range containing text before the selection
144 - var preRange = document.body.createTextRange();
145 - // Select all the text
146 - preRange.moveToElementText(e);
147 - // Move the end where we need it
148 - preRange.setEndPoint("EndToStart", periRange);
149 - // Create range containing text after the selection
150 - var postRange = document.body.createTextRange();
151 - // Select all the text
152 - postRange.moveToElementText(e);
153 - // Move the start where we need it
154 - postRange.setEndPoint("StartToEnd", periRange);
155 - // Load the text values we need to compare
156 - preText = rawPreText = preRange.text;
157 - periText = rawPeriText = periRange.text;
158 - postText = rawPostText = postRange.text;
159 - /*
160 - * Check each range for trimmed newlines by shrinking the range by 1
161 - * character and seeing if the text property has changed. If it has
162 - * not changed then we know that IE has trimmed a \r\n from the end.
163 - */
164 - do {
165 - if ( !postFinished ) {
166 - if ( preRange.compareEndPoints( "StartToEnd", preRange ) == 0 ) {
167 - postFinished = true;
168 - } else {
169 - preRange.moveEnd( "character", -1 )
170 - if ( preRange.text == preText ) {
171 - rawPreText += "\r\n";
172 - } else {
173 - postFinished = true;
174 - }
175 - }
176 - }
177 - if ( !periFinished ) {
178 - if ( periRange.compareEndPoints( "StartToEnd", periRange ) == 0 ) {
179 - periFinished = true;
180 - } else {
181 - periRange.moveEnd( "character", -1 )
182 - if ( periRange.text == periText ) {
183 - rawPeriText += "\r\n";
184 - } else {
185 - periFinished = true;
186 - }
187 - }
188 - }
189 - if ( !postFinished ) {
190 - if ( postRange.compareEndPoints("StartToEnd", postRange) == 0 ) {
191 - postFinished = true;
192 - } else {
193 - postRange.moveEnd( "character", -1 )
194 - if ( postRange.text == postText ) {
195 - rawPostText += "\r\n";
196 - } else {
197 - postFinished = true;
198 - }
199 - }
200 - }
201 - } while ( ( !postFinished || !periFinished || !postFinished ) );
202 - caretPos = rawPreText.replace( /\r\n/g, "\n" ).length;
203 - endPos = caretPos + rawPeriText.replace( /\r\n/g, "\n" ).length;
204 - } else if ( e.selectionStart || e.selectionStart == '0' ) {
205 - // Firefox support
206 - caretPos = e.selectionStart;
207 - endPos = e.selectionEnd;
208 - }
209 - return options.startAndEnd ? [ caretPos, endPos ] : caretPos;
210 - }
211 - return getCaret( this.get( 0 ) );
212 -},
213 -setSelection: function( options ) {
214 - return this.each( function() {
215 - if ( $(this).is( ':hidden' ) ) {
216 - // Do nothing
217 - } else if ( this.selectionStart || this.selectionStart == '0' ) {
218 - // Opera 9.0 doesn't allow setting selectionStart past
219 - // selectionEnd; any attempts to do that will be ignored
220 - // Make sure to set them in the right order
221 - if ( options.start > this.selectionEnd ) {
222 - this.selectionEnd = options.end;
223 - this.selectionStart = options.start;
224 - } else {
225 - this.selectionStart = options.start;
226 - this.selectionEnd = options.end;
227 - }
228 - } else if ( document.body.createTextRange ) {
229 - var selection = document.body.createTextRange();
230 - selection.moveToElementText( this );
231 - var length = selection.text.length;
232 - selection.moveStart( 'character', options.start );
233 - selection.moveEnd( 'character', -length + options.end );
234 - selection.select();
235 - }
236 - });
237 -},
238 -/**
239 - * Ported from Wikia's LinkSuggest extension
240 - * https://svn.wikia-code.com/wikia/trunk/extensions/wikia/LinkSuggest
241 - *
242 - * Scroll a textarea to the current cursor position. You can set the cursor
243 - * position with setSelection()
244 - * @param force boolean Whether to force a scroll even if the caret position
245 - * is already visible. Defaults to false
246 - */
247 -scrollToCaretPosition: function( options ) {
248 - function getLineLength( e ) {
249 - return Math.floor( e.scrollWidth / ( $.os.name == 'linux' ? 7 : 8 ) );
250 - }
251 - function getCaretScrollPosition( e ) {
252 - // FIXME: This functions sucks and is off by a few lines most
253 - // of the time. It should be replaced by something decent.
254 - var text = e.value.replace( /\r/g, "" );
255 - var caret = $( e ).textSelection( 'getCaretPosition' );
256 - var lineLength = getLineLength( e );
257 - var row = 0;
258 - var charInLine = 0;
259 - var lastSpaceInLine = 0;
260 - for ( i = 0; i < caret; i++ ) {
261 - charInLine++;
262 - if ( text.charAt( i ) == " " ) {
263 - lastSpaceInLine = charInLine;
264 - } else if ( text.charAt( i ) == "\n" ) {
265 - lastSpaceInLine = 0;
266 - charInLine = 0;
267 - row++;
268 - }
269 - if ( charInLine > lineLength ) {
270 - if ( lastSpaceInLine > 0 ) {
271 - charInLine = charInLine - lastSpaceInLine;
272 - lastSpaceInLine = 0;
273 - row++;
274 - }
275 - }
276 - }
277 - var nextSpace = 0;
278 - for ( j = caret; j < caret + lineLength; j++ ) {
279 - if (
280 - text.charAt( j ) == " " ||
281 - text.charAt( j ) == "\n" ||
282 - caret == text.length
283 - ) {
284 - nextSpace = j;
285 - break;
286 - }
287 - }
288 - if ( nextSpace > lineLength && caret <= lineLength ) {
289 - charInLine = caret - lastSpaceInLine;
290 - row++;
291 - }
292 - return ( $.os.name == 'mac' ? 13 : ( $.os.name == 'linux' ? 15 : 16 ) ) * row;
293 - }
294 - return this.each(function() {
295 - if ( $(this).is( ':hidden' ) ) {
296 - // Do nothing
297 - } else if ( this.selectionStart || this.selectionStart == '0' ) {
298 - // Mozilla
299 - var scroll = getCaretScrollPosition( this );
300 - if ( options.force || scroll < $(this).scrollTop() ||
301 - scroll > $(this).scrollTop() + $(this).height() )
302 - $(this).scrollTop( scroll );
303 - } else if ( document.selection && document.selection.createRange ) {
304 - // IE / Opera
305 - /*
306 - * IE automatically scrolls the selected text to the
307 - * bottom of the textarea at range.select() time, except
308 - * if it was already in view and the cursor position
309 - * wasn't changed, in which case it does nothing. To
310 - * cover that case, we'll force it to act by moving one
311 - * character back and forth.
312 - */
313 - var range = document.selection.createRange();
314 - var pos = $(this).textSelection( 'getCaretPosition' );
315 - var oldScrollTop = this.scrollTop;
316 - range.moveToElementText( this );
317 - range.collapse();
318 - range.move( 'character', pos + 1);
319 - range.select();
320 - if ( this.scrollTop != oldScrollTop )
321 - this.scrollTop += range.offsetTop;
322 - else if ( options.force ) {
323 - range.move( 'character', -1 );
324 - range.select();
325 - }
326 - }
327 - $(this).trigger( 'scrollToPosition' );
328 - } );
329 -}
330 -};
331 - // Apply defaults
332 - switch ( command ) {
333 - //case 'getContents': // no params
334 - //case 'setContents': // no params with defaults
335 - //case 'getSelection': // no params
336 - case 'encapsulateSelection':
337 - options = $.extend( {
338 - 'pre': '', // Text to insert before the cursor/selection
339 - 'peri': '', // Text to insert between pre and post and select afterwards
340 - 'post': '', // Text to insert after the cursor/selection
341 - 'ownline': false, // Put the inserted text on a line of its own
342 - 'replace': false // If there is a selection, replace it with peri instead of leaving it alone
343 - }, options );
344 - break;
345 - case 'getCaretPosition':
346 - options = $.extend( {
347 - 'startAndEnd': false // Return [start, end] instead of just start
348 - }, options );
349 - // FIXME: We may not need character position-based functions if we insert markers in the right places
350 - break;
351 - case 'setSelection':
352 - options = $.extend( {
353 - 'start': undefined, // Position to start selection at
354 - 'end': undefined, // Position to end selection at. Defaults to start
355 - 'startContainer': undefined, // Element to start selection in (iframe only)
356 - 'endContainer': undefined // Element to end selection in (iframe only). Defaults to startContainer
357 - }, options );
358 - if ( options.end === undefined )
359 - options.end = options.start;
360 - if ( options.endContainer == undefined )
361 - options.endContainer = options.startContainer;
362 - // FIXME: We may not need character position-based functions if we insert markers in the right places
363 - break;
364 - case 'scrollToCaretPosition':
365 - options = $.extend( {
366 - 'force': false // Force a scroll even if the caret position is already visible
367 - }, options );
368 - break;
369 - }
370 - var context = $(this).data( 'wikiEditor-context' );
371 - var hasIframe = context !== undefined && context.$iframe !== undefined;
372 - // iframe functions have not been implemented yet, this is a temp hack
373 - //var hasIframe = false;
374 - return ( hasIframe ? context.fn : fn )[command].call( this, options );
375 -};
376 -
377 -} )( jQuery );
\ No newline at end of file
Index: trunk/extensions/UsabilityInitiative/js/plugins/jquery.cookie.js
@@ -1,97 +0,0 @@
2 -/**
3 - * Cookie plugin
4 - *
5 - * Copyright (c) 2006 Klaus Hartl (stilbuero.de)
6 - * Dual licensed under the MIT and GPL licenses:
7 - * http://www.opensource.org/licenses/mit-license.php
8 - * http://www.gnu.org/licenses/gpl.html
9 - *
10 - */
11 -
12 -/**
13 - * Create a cookie with the given name and value and other optional parameters.
14 - *
15 - * @example $.cookie('the_cookie', 'the_value');
16 - * @desc Set the value of a cookie.
17 - * @example $.cookie('the_cookie', 'the_value', { expires: 7, path: '/', domain: 'jquery.com', secure: true });
18 - * @desc Create a cookie with all available options.
19 - * @example $.cookie('the_cookie', 'the_value');
20 - * @desc Create a session cookie.
21 - * @example $.cookie('the_cookie', null);
22 - * @desc Delete a cookie by passing null as value. Keep in mind that you have to use the same path and domain
23 - * used when the cookie was set.
24 - *
25 - * @param String name The name of the cookie.
26 - * @param String value The value of the cookie.
27 - * @param Object options An object literal containing key/value pairs to provide optional cookie attributes.
28 - * @option Number|Date expires Either an integer specifying the expiration date from now on in days or a Date object.
29 - * If a negative value is specified (e.g. a date in the past), the cookie will be deleted.
30 - * If set to null or omitted, the cookie will be a session cookie and will not be retained
31 - * when the the browser exits.
32 - * @option String path The value of the path atribute of the cookie (default: path of page that created the cookie).
33 - * @option String domain The value of the domain attribute of the cookie (default: domain of page that created the cookie).
34 - * @option Boolean secure If true, the secure attribute of the cookie will be set and the cookie transmission will
35 - * require a secure protocol (like HTTPS).
36 - * @type undefined
37 - *
38 - * @name $.cookie
39 - * @cat Plugins/Cookie
40 - * @author Klaus Hartl/klaus.hartl@stilbuero.de
41 - */
42 -
43 -/**
44 - * Get the value of a cookie with the given name.
45 - *
46 - * @example $.cookie('the_cookie');
47 - * @desc Get the value of a cookie.
48 - *
49 - * @param String name The name of the cookie.
50 - * @return The value of the cookie.
51 - * @type String
52 - *
53 - * @name $.cookie
54 - * @cat Plugins/Cookie
55 - * @author Klaus Hartl/klaus.hartl@stilbuero.de
56 - */
57 -jQuery.cookie = function(name, value, options) {
58 - if (typeof value != 'undefined') { // name and value given, set cookie
59 - options = options || {};
60 - if (value === null) {
61 - value = '';
62 - options.expires = -1;
63 - }
64 - var expires = '';
65 - if (options.expires && (typeof options.expires == 'number' || options.expires.toUTCString)) {
66 - var date;
67 - if (typeof options.expires == 'number') {
68 - date = new Date();
69 - date.setTime(date.getTime() + (options.expires * 24 * 60 * 60 * 1000));
70 - } else {
71 - date = options.expires;
72 - }
73 - expires = '; expires=' + date.toUTCString(); // use expires attribute, max-age is not supported by IE
74 - }
75 - // CAUTION: Needed to parenthesize options.path and options.domain
76 - // in the following expressions, otherwise they evaluate to undefined
77 - // in the packed version for some reason...
78 - var path = options.path ? '; path=' + (options.path) : '';
79 - var domain = options.domain ? '; domain=' + (options.domain) : '';
80 - var secure = options.secure ? '; secure' : '';
81 - document.cookie = [name, '=', encodeURIComponent(value), expires, path, domain, secure].join('');
82 - } else { // only name given, get cookie
83 - var cookieValue = null;
84 - if (document.cookie && document.cookie != '') {
85 - var cookies = document.cookie.split(';');
86 - for (var i = 0; i < cookies.length; i++) {
87 - var cookie = jQuery.trim(cookies[i]);
88 - // Does this cookie string begin with the name we want?
89 - if (cookie.substring(0, name.length + 1) == (name + '=')) {
90 - cookieValue = decodeURIComponent(cookie.substring(name.length + 1));
91 - break;
92 - }
93 - }
94 - }
95 - return cookieValue;
96 - }
97 -};
98 -
Index: trunk/extensions/UsabilityInitiative/js/plugins/jquery.wikiEditor.dialogs.js
@@ -137,7 +137,7 @@
138138 },
139139 // This stuff is just hanging here, perhaps we could come up with a better home for this stuff
140140 modules: {},
141 -quickDialog: function( body, settings ) {
 141+quickDialog: function( body, settings ) {
142142 $( '<div />' )
143143 .text( body )
144144 .appendTo( $( 'body' ) )
Index: trunk/extensions/UsabilityInitiative/js/plugins/jquery.wikiEditor.js
@@ -8,6 +8,13 @@
99 * $j( 'textarea#wpTextbox1' ).wikiEditor( 'addModule', 'toolbar', { ... config ... } );
1010 *
1111 */
 12+
 13+mw.addMessages({
 14+ "wikieditor" : "Advanced wikitext editing interface",
 15+ "wikieditor-desc" : "Provides an extendable wikitext editing interface and many feature-providing modules",
 16+ "wikieditor-wikitext-tab" : "Wikitext"
 17+});
 18+
1219 ( function( $ ) {
1320
1421 /**
Index: trunk/extensions/UsabilityInitiative/UsabilityInitiative.php
@@ -43,6 +43,9 @@
4444 $wgExtensionMessagesFiles['UsabilityInitiative'] =
4545 dirname( __FILE__ ) . "/UsabilityInitiative.i18n.php";
4646
 47+// Adds the loader.js:
 48+$wgExtensionJavascriptLoader[] = "UsabilityInitiative/js/loader.js";
 49+
4750 // Registers Hooks
4851 $wgHooks['BeforePageDisplay'][] = 'UsabilityInitiativeHooks::addResources';
4952 $wgHooks['MakeGlobalVariablesScript'][] = 'UsabilityInitiativeHooks::addJSVars';
\ No newline at end of file
Index: trunk/extensions/UsabilityInitiative/UsabilityInitiative.hooks.php
@@ -66,32 +66,129 @@
6767 'raw' => array(
6868
6969 // These scripts can be pulled from core once the js2 is merged
70 - array( 'src' => 'js/js2stopgap/ui.core.js', 'version' => 1 ),
71 - array( 'src' => 'js/js2stopgap/ui.datepicker.js', 'version' => 1 ),
72 - array( 'src' => 'js/js2stopgap/ui.dialog.js', 'version' => 1 ),
73 - array( 'src' => 'js/js2stopgap/ui.draggable.js', 'version' => 1 ),
74 - array( 'src' => 'js/js2stopgap/ui.resizable.js', 'version' => 1 ),
75 - array( 'src' => 'js/js2stopgap/ui.tabs.js', 'version' => 1 ),
 70+ // NOTE:: a lot of the logic of hooks.php could be
 71+ // simplified into loader.js
 72+ array(
 73+ 'src' => 'js/js2stopgap/ui.core.js',
 74+ 'class' => 'j.ui',
 75+ 'version' => 1,
 76+ ),
 77+ array(
 78+ 'src' => 'js/js2stopgap/ui.datepicker.js',
 79+ 'class' => 'j.fn.datePicker',
 80+ 'version' => 1
 81+ ),
 82+ array(
 83+ 'src' => 'js/js2stopgap/ui.dialog.js',
 84+ 'class' => 'j.ui.dialog',
 85+ 'version' => 1
 86+ ),
 87+ array(
 88+ 'src' => 'js/js2stopgap/ui.draggable.js',
 89+ 'class' => 'j.ui.draggable',
 90+ 'version' => 1
 91+ ),
 92+ array(
 93+ 'src' => 'js/js2stopgap/ui.resizable.js',
 94+ 'class' => 'j.ui.resizable',
 95+ 'version' => 1
 96+ ),
 97+ array(
 98+ 'src' => 'js/js2stopgap/ui.tabs.js',
 99+ 'class' => 'j.ui.tabs',
 100+ 'version' => 1
 101+ ),
 102+ array(
 103+ 'src' => 'js/js2stopgap/jquery.cookie.js',
 104+ 'class' => 'j.cookie',
 105+ 'version' => 3
 106+ ),
 107+ array(
 108+ 'src' => 'js/js2stopgap/jquery.textSelection.js',
 109+ 'class' => 'j.fn.textSelection',
 110+ 'version' => 23
 111+ ),
76112
77113 // Core functionality of extension scripts
78 - array( 'src' => 'js/plugins/jquery.async.js', 'version' => 3 ),
79 - array( 'src' => 'js/plugins/jquery.autoEllipsis.js', 'version' => 6 ),
80 - array( 'src' => 'js/plugins/jquery.browser.js', 'version' => 3 ),
81 - array( 'src' => 'js/plugins/jquery.collapsibleTabs.js', 'version' => 5 ),
82 - array( 'src' => 'js/plugins/jquery.cookie.js', 'version' => 3 ),
83 - array( 'src' => 'js/plugins/jquery.delayedBind.js', 'version' => 1 ),
84 - array( 'src' => 'js/plugins/jquery.inherit.js', 'version' => 3 ),
85 - array( 'src' => 'js/plugins/jquery.namespaceSelect.js', 'version' => 1 ),
86 - array( 'src' => 'js/plugins/jquery.suggestions.js', 'version' => 7 ),
87 - array( 'src' => 'js/plugins/jquery.textSelection.js', 'version' => 23 ),
88 - array( 'src' => 'js/plugins/jquery.wikiEditor.js', 'version' => 47 ),
89 - array( 'src' => 'js/plugins/jquery.wikiEditor.highlight.js', 'version' => 12 ),
90 - array( 'src' => 'js/plugins/jquery.wikiEditor.toolbar.js', 'version' => 41 ),
91 - array( 'src' => 'js/plugins/jquery.wikiEditor.dialogs.js', 'version' => 10 ),
92 - array( 'src' => 'js/plugins/jquery.wikiEditor.toc.js', 'version' => 62 ),
93 - array( 'src' => 'js/plugins/jquery.wikiEditor.preview.js', 'version' => 9 ),
94 - array( 'src' => 'js/plugins/jquery.wikiEditor.templateEditor.js', 'version' => 14 ),
95 - array( 'src' => 'js/plugins/jquery.wikiEditor.publish.js', 'version' => 1 ),
 114+ array(
 115+ 'src' => 'js/plugins/jquery.async.js',
 116+ 'class' => 'j.whileAsync',
 117+ 'version' => 3
 118+ ),
 119+ array(
 120+ 'src' => 'js/plugins/jquery.autoEllipsis.js',
 121+ 'class' => 'j.fn.autoEllipsis',
 122+ 'version' => 6
 123+ ),
 124+ array(
 125+ 'src' => 'js/plugins/jquery.browser.js',
 126+ 'class' => 'j.browserTest',
 127+ 'version' => 3
 128+ ),
 129+ array(
 130+ 'src' => 'js/plugins/jquery.collapsibleTabs.js',
 131+ 'class' => 'j.fn.collapsibleTabs',
 132+ 'version' => 5
 133+ ),
 134+ array(
 135+ 'src' => 'js/plugins/jquery.delayedBind.js',
 136+ 'class' => 'j.fn.delayedBind',
 137+ 'version' => 1
 138+ ),
 139+ array(
 140+ 'src' => 'js/plugins/jquery.inherit.js',
 141+ 'class' => 'inherit',
 142+ 'version' => 3
 143+ ),
 144+ array(
 145+ 'src' => 'js/plugins/jquery.namespaceSelect.js',
 146+ 'class' => 'j.fn.namespaceSelector',
 147+ 'version' => 1
 148+ ),
 149+ array(
 150+ 'src' => 'js/plugins/jquery.suggestions.js',
 151+ 'class' => 'j.suggestions',
 152+ 'version' => 7
 153+ ),
 154+ array(
 155+ 'src' => 'js/plugins/jquery.wikiEditor.js',
 156+ 'class' => 'j.wikiEditor',
 157+ 'version' => 47
 158+ ),
 159+ array(
 160+ 'src' => 'js/plugins/jquery.wikiEditor.highlight.js',
 161+ 'class' => 'j.wikiEditor.modules.highlight',
 162+ 'version' => 12
 163+ ),
 164+ array(
 165+ 'src' => 'js/plugins/jquery.wikiEditor.toolbar.js',
 166+ 'class' => 'j.wikiEditor.modules.toolbar',
 167+ 'version' => 41
 168+ ),
 169+ array(
 170+ 'src' => 'js/plugins/jquery.wikiEditor.dialogs.js',
 171+ 'class' => 'j.wikiEditor.modules.dialogs',
 172+ 'version' => 10
 173+ ),
 174+ array(
 175+ 'src' => 'js/plugins/jquery.wikiEditor.toc.js',
 176+ 'class' => 'j.wikiEditor.modules.toc',
 177+ 'version' => 62
 178+ ),
 179+ array(
 180+ 'src' => 'js/plugins/jquery.wikiEditor.preview.js',
 181+ 'class' => 'j.wikiEditor.modules.preview',
 182+ 'version' => 9
 183+ ),
 184+ array(
 185+ 'src' => 'js/plugins/jquery.wikiEditor.templateEditor.js',
 186+ 'class' => 'j.wikiEditor.modules.templateEditor',
 187+ 'version' => 14
 188+ ),
 189+ array(
 190+ 'src' => 'js/plugins/jquery.wikiEditor.publish.js',
 191+ 'class' => 'j.wikiEditor.modules.publish',
 192+ 'version' => 1 ),
96193 ),
97194 'combined' => array(
98195 array( 'src' => 'js/plugins.combined.js', 'version' => 146 ),
@@ -103,7 +200,6 @@
104201 );
105202
106203 /* Static Functions */
107 -
108204 public static function initialize() {
109205 self::$doOutput = true;
110206 }
@@ -115,8 +211,8 @@
116212 public static function addResources( $out ) {
117213 global $wgExtensionAssetsPath, $wgJsMimeType;
118214 global $wgUsabilityInitiativeResourceMode;
119 - global $wgEnableJS2system, $wgEditToolbarRunTests;
120 - global $wgStyleVersion;
 215+ global $wgEditToolbarRunTests, $wgVersion;
 216+ global $wgStyleVersion, $wgEnableScriptLoader;
121217
122218 wfRunHooks( 'UsabilityInitiativeLoadModules' );
123219
@@ -134,9 +230,9 @@
135231 self::$scriptFiles['modules'][$mode],
136232 self::$scripts
137233 );
138 - // Provide enough support to make things work, even when js2 is not
139 - // in use (eventually it will be standard, but right now it's not)
140 - if ( !$wgEnableJS2system ) {
 234+ // Provide backward support for mediaWiki less than 1.17
 235+ // by including "no_js2" js.
 236+ if ( !version_compare( floatval( $wgVersion ), '1.17', '>=') ) {
141237 self::$scripts = array_merge(
142238 self::$scriptFiles['no_js2'][$mode], self::$scripts
143239 );
@@ -153,38 +249,39 @@
154250 }
155251 // Loops over each script
156252 foreach ( self::$scripts as $script ) {
157 - // Add javascript to document
158 - $src = "$wgExtensionAssetsPath/UsabilityInitiative/{$script['src']}";
159 - $version = isset( $script['version'] ) ? $script['version'] : $wgStyleVersion;
160 - $out->addScript(
161 - Xml::element(
162 - 'script',
163 - array(
164 - 'type' => $wgJsMimeType,
165 - 'src' => "$src?$version",
166 - ),
167 - '',
168 - false
169 - )
170 - );
 253+ if ( !version_compare( floatval( $wgVersion ), '1.17', '>=') ) {
 254+ // Add javascript to document
 255+ $src = "$wgExtensionAssetsPath/UsabilityInitiative/{$script['src']}";
 256+ $version = isset( $script['version'] ) ? $script['version'] : $wgStyleVersion;
 257+ $out->addScriptFile( $src, $version );
 258+ continue ;
 259+ }
 260+ // else add by class:
 261+ if( isset( $script['class'] ) ){
 262+ $out->addScriptClass( $script['class'] );
 263+ }
171264 }
 265+
172266 // Transforms messages into javascript object members
173 - foreach ( self::$messages as $i => $message ) {
174 - $escapedMessageValue = Xml::escapeJsString( wfMsg( $message ) );
175 - $escapedMessageKey = Xml::escapeJsString( $message );
176 - self::$messages[$i] =
177 - "'{$escapedMessageKey}':'{$escapedMessageValue}'";
 267+ // ( only not handled automatically )
 268+ if ( version_compare( $wgVersion, '1.17', '>') ) {
 269+ foreach ( self::$messages as $i => $message ) {
 270+ $escapedMessageValue = Xml::escapeJsString( wfMsg( $message ) );
 271+ $escapedMessageKey = Xml::escapeJsString( $message );
 272+ self::$messages[$i] =
 273+ "'{$escapedMessageKey}':'{$escapedMessageValue}'";
 274+ }
 275+ // Add javascript to document
 276+ if ( count( self::$messages ) > 0 ) {
 277+ $out->addScript(
 278+ Xml::tags(
 279+ 'script',
 280+ array( 'type' => $wgJsMimeType ),
 281+ 'mw.addMessages({' . implode( ',', self::$messages ) . '});'
 282+ )
 283+ );
 284+ }
178285 }
179 - // Add javascript to document
180 - if ( count( self::$messages ) > 0 ) {
181 - $out->addScript(
182 - Xml::tags(
183 - 'script',
184 - array( 'type' => $wgJsMimeType ),
185 - 'mw.addMessages({' . implode( ',', self::$messages ) . '});'
186 - )
187 - );
188 - }
189286 // Loops over each style
190287 foreach ( self::$styles as $style ) {
191288 // Add css for various styles
Index: branches/js2-work/phase3/includes/specials/SpecialUpload.php
@@ -56,8 +56,8 @@
5757 $this->mRequest = $request;
5858 $this->mSourceType = $request->getVal( 'wpSourceType', 'file' );
5959 $this->mUpload = UploadBase::createFromRequest( $request );
60 - $this->mUploadClicked = $request->wasPosted()
61 - && ( $request->getCheck( 'wpUpload' )
 60+ $this->mUploadClicked = $request->wasPosted()
 61+ && ( $request->getCheck( 'wpUpload' )
6262 || $request->getCheck( 'wpUploadIgnoreWarning' ) );
6363
6464 // Guess the desired name from the filename if not provided
@@ -187,11 +187,11 @@
188188 */
189189 protected function getUploadForm( $message = '', $sessionKey = '', $hideIgnoreWarning = false ) {
190190 global $wgOut;
191 -
 191+
192192 # Initialize form
193193 $form = new UploadForm( array(
194 - 'watch' => $this->watchCheck(),
195 - 'forreupload' => $this->mForReUpload,
 194+ 'watch' => $this->watchCheck(),
 195+ 'forreupload' => $this->mForReUpload,
196196 'sessionkey' => $sessionKey,
197197 'hideignorewarning' => $hideIgnoreWarning,
198198 ) );
@@ -206,16 +206,16 @@
207207 $form->addPreText( '<div id="uploadtext">' . wfMsgExt( 'uploadtext', 'parse' ) . '</div>');
208208 # Add upload error message
209209 $form->addPreText( $message );
210 -
 210+
211211 # Add footer to form
212212 $uploadFooter = wfMsgNoTrans( 'uploadfooter' );
213213 if ( $uploadFooter != '-' && !wfEmptyMsg( 'uploadfooter', $uploadFooter ) ) {
214214 $form->addPostText( '<div id="mw-upload-footer-message">'
215215 . $wgOut->parse( $uploadFooter ) . "</div>\n" );
216216 }
217 -
218 - return $form;
219217
 218+ return $form;
 219+
220220 }
221221
222222 /**
@@ -259,7 +259,7 @@
260260 $sessionKey = $this->mUpload->stashSession();
261261 $message = '<h2>' . wfMsgHtml( 'uploadwarning' ) . "</h2>\n" .
262262 '<div class="error">' . $message . "</div>\n";
263 -
 263+
264264 $form = $this->getUploadForm( $message, $sessionKey );
265265 $form->setSubmitText( wfMsg( 'upload-tryagain' ) );
266266 $this->showUploadForm( $form );
@@ -642,7 +642,7 @@
643643 protected $mForReUpload;
644644 protected $mSessionKey;
645645 protected $mHideIgnoreWarning;
646 -
 646+
647647 protected $mSourceIds;
648648
649649 public function __construct( $options = array() ) {
@@ -650,7 +650,7 @@
651651
652652 $this->mWatch = !empty( $options['watch'] );
653653 $this->mForReUpload = !empty( $options['forreupload'] );
654 - $this->mSessionKey = isset( $options['sessionkey'] )
 654+ $this->mSessionKey = isset( $options['sessionkey'] )
655655 ? $options['sessionkey'] : '';
656656 $this->mHideIgnoreWarning = !empty( $options['hideignorewarning'] );
657657
@@ -678,9 +678,9 @@
679679 }
680680
681681 /**
682 - * Get the descriptor of the fieldset that contains the file source
 682+ * Get the descriptor of the fieldset that contains the file source
683683 * selection. The section is 'source'
684 - *
 684+ *
685685 * @return array Descriptor array
686686 */
687687 protected function getSourceSection() {
@@ -750,7 +750,7 @@
751751
752752 /**
753753 * Get the messages indicating which extensions are preferred and prohibitted.
754 - *
 754+ *
755755 * @return string HTML string containing the message
756756 */
757757 protected function getExtensionsMessage() {
@@ -787,7 +787,7 @@
788788 /**
789789 * Get the descriptor of the fieldset that contains the file description
790790 * input. The section is 'description'
791 - *
 791+ *
792792 * @return array Descriptor array
793793 */
794794 protected function getDescriptionSection() {
@@ -851,9 +851,9 @@
852852 }
853853
854854 /**
855 - * Get the descriptor of the fieldset that contains the upload options,
 855+ * Get the descriptor of the fieldset that contains the upload options,
856856 * such as "watch this file". The section is 'options'
857 - *
 857+ *
858858 * @return array Descriptor array
859859 */
860860 protected function getOptionsSection() {
@@ -892,13 +892,13 @@
893893
894894 /**
895895 * Add upload JS to $wgOut
896 - *
 896+ *
897897 * @param bool $autofill Whether or not to autofill the destination
898898 * filename text box
899899 */
900900 protected function addUploadJS( ) {
901901 global $wgUseAjax, $wgAjaxUploadDestCheck, $wgAjaxLicensePreview;
902 - global $wgEnableFirefogg, $wgEnableJS2system;
 902+ global $wgEnableFirefogg;
903903 global $wgOut;
904904
905905 $useAjaxDestCheck = $wgUseAjax && $wgAjaxUploadDestCheck;
@@ -913,11 +913,11 @@
914914 );
915915
916916 $wgOut->addScript( Skin::makeVariablesScript( $scriptVars ) );
917 -
 917+
918918 // For <charinsert> support; not provided by js2 yet
919919 $wgOut->addScriptFile( 'edit.js' );
920 -
921 - if ( $wgEnableJS2system ) {
 920+
 921+ if ( $wgEnableFirefogg ) {
922922 // JS2 upload scripts
923923 $wgOut->addScriptClass( 'uploadPage' );
924924 } else {
@@ -928,7 +928,7 @@
929929
930930 /**
931931 * Empty function; submission is handled elsewhere.
932 - *
 932+ *
933933 * @return bool false
934934 */
935935 function trySubmit() {
Index: branches/js2-work/phase3/includes/Skin.php
@@ -363,7 +363,7 @@
364364 global $wgVersion, $wgEnableAPI, $wgEnableWriteAPI;
365365 global $wgRestrictionTypes, $wgLivePreview;
366366 global $wgMWSuggestTemplate, $wgDBname, $wgEnableMWSuggest;
367 - global $wgSitename, $wgEnableIframeApiProxy, $wgEnableJS2system;
 367+ global $wgSitename, $wgEnableIframeApiProxy;
368368
369369 $ns = $wgTitle->getNamespace();
370370 $nsname = MWNamespace::exists( $ns ) ? MWNamespace::getCanonicalName( $ns ) : $wgTitle->getNsText();
@@ -446,15 +446,13 @@
447447 $vars['wgLivepreviewMessageError'] = wfMsg( 'livepreview-error' );
448448 }
449449
450 - //add api proxy var and script link if on the special proxy page:
451 - if( $wgEnableJS2system &&
 450+ // Add api proxy var and script link if on the special proxy page:
 451+ if( $wgEnableIframeApiProxy &&
452452 $wgTitle->getNamespace() == NS_MEDIAWIKI &&
453453 $wgTitle->getDBKey() == 'ApiProxy' )
454454 {
455 - $vars['wgEnableIframeApiProxy'] = $wgEnableIframeApiProxy;
456 - //also add the apiProxy Page script if we are on that page
457 - if( $wgEnableIframeApiProxy )
458 - $wgOut->addScriptClass( 'apiProxyPage' );
 455+ $vars['wgEnableIframeApiProxy'] = $wgEnableIframeApiProxy;
 456+ $wgOut->addScriptClass( 'apiProxyPage' );
459457 }
460458
461459 if ( $wgOut->isArticleRelated() && $wgUseAjax && $wgAjaxWatch && $wgUser->isLoggedIn() ) {
@@ -2055,7 +2053,7 @@
20562054 /**
20572055 * Add content from a sidebar system message
20582056 * Currently only used for MediaWiki:Sidebar (but may be used by Extensions)
2059 - *
 2057+ *
20602058 * @param &$bar array
20612059 * @param $message String
20622060 */
Index: branches/js2-work/phase3/includes/EditPage.php
@@ -368,7 +368,7 @@
369369 * the newly-edited page.
370370 */
371371 function edit() {
372 - global $wgOut, $wgRequest, $wgEnableJS2system;
 372+ global $wgOut, $wgRequest, $wgEnableAddMediaWizard;
373373 // Allow extensions to modify/prevent this form or submission
374374 if ( !wfRunHooks( 'AlternateEdit', array( $this ) ) ) {
375375 return;
@@ -397,8 +397,10 @@
398398
399399 $wgOut->addScriptFile( 'edit.js' );
400400
401 - if( $wgEnableJS2system )
 401+ // Add the "edit" mwEmbed page for add media wizard support
 402+ if( $wgEnableAddMediaWizard ){
402403 $wgOut->addScriptClass( 'editPage' );
 404+ }
403405
404406 $permErrors = $this->getEditPermissionErrors();
405407 if ( $permErrors ) {
Index: branches/js2-work/phase3/includes/DefaultSettings.php
@@ -33,7 +33,7 @@
3434 }
3535
3636 /** MediaWiki version number */
37 -$wgVersion = '1.16alpha';
 37+$wgVersion = '1.17alpha';
3838
3939 /** Name of the site. It must be changed in LocalSettings.php */
4040 $wgSitename = 'MediaWiki';
@@ -473,11 +473,16 @@
474474 * Enable Firefogg support. Adds support for in-browser transcoding to Ogg
475475 * Theora, chunked uploads for large image files and client side hash checks.
476476 *
477 - * Ignored unless $wgEnableJS2system is true.
478477 */
479478 $wgEnableFirefogg = true;
480479
481480 /**
 481+ * Enable add-media-wizard. Adds support for add-media-wizard for the edit page
 482+ */
 483+$wgEnableAddMediaWizard = true;
 484+
 485+
 486+/**
482487 * Point the upload navigation link to an external URL
483488 * Useful if you want to use a shared repository by default
484489 * without disabling local uploads (use $wgEnableUploads = false for that)
@@ -2864,16 +2869,14 @@
28652870
28662871 /**
28672872 * For defining the location of loader.js files of
2868 - * external mwEmbed modules. ( ie modules hosted inside of extensions )
 2873+ * Extension mwEmbed modules. ( ie modules hosted inside of extensions )
28692874 */
2870 -$wgJSModuleLoaderPaths = array();
 2875+$wgExtensionJavascriptLoader = array();
28712876
28722877 /*
2873 - * boolean; if the script loader should be used to group all javascript requests.
 2878+ * $wgEnableScriptLoader; If the script loader should be used to group all javascript requests.
28742879 * more about the script loader: http://www.mediawiki.org/wiki/ScriptLoader
28752880 *
2876 - * (its recommended you DO NOT enable the script loader without also enabling $wgUseFileCache
2877 - * (or have mediaWiki behind a proxy) otherwise all new js requests will result in script server js processing.
28782881 */
28792882 $wgEnableScriptLoader = false;
28802883
@@ -2897,12 +2900,6 @@
28982901 $wgScriptModifiedMsgCheck = false;
28992902
29002903 /*
2901 - * enable js2 Script System
2902 - * if enabled we include jquery, mwEmbed and js2 versions of editPage.js
2903 - */
2904 -$wgEnableJS2system = false;
2905 -
2906 -/*
29072904 * enable api iframe proxy
29082905 */
29092906 $wgEnableIframeApiProxy = false;
Index: branches/js2-work/phase3/includes/OutputPage.php
@@ -133,9 +133,9 @@
134134
135135 // If script-loader enabled check if we can add the script via script-loader
136136 if( $wgEnableScriptLoader ) {
137 - $js_class = $this->getJsClassFromPath( $path );
138 - if( $js_class ) {
139 - $this->addScriptClass( $js_class );
 137+ $jsClass = $this->getJsClassFromPath( $path );
 138+ if( $jsClass ) {
 139+ $this->addScriptClass( $jsClass );
140140 return true;
141141 }
142142 }
@@ -178,15 +178,12 @@
179179 * this includes the conditional sitejs
180180 */
181181 function addCoreScripts2Top(){
182 - global $wgEnableScriptLoader, $wgJSAutoloadLocalClasses, $wgScriptPath, $wgEnableJS2system;
183 - global $wgUser, $wgJsMimeType;
 182+ global $wgEnableScriptLoader, $wgJSAutoloadClasses, $wgScriptPath;
 183+ global $wgUser, $wgJsMimeType, $wgExtensionJavascriptLoader;
 184+
184185 // @todo We should deprecate wikibits in favor of some mwEmbed pieces and jQuery
 186+ $coreClasses = array( 'window.jQuery', 'mwEmbed', 'wikibits' );
185187
186 - if( $wgEnableJS2system ){
187 - $core_classes = array( 'window.jQuery', 'mwEmbed', 'wikibits' );
188 - } else {
189 - $core_classes = array( 'wikibits' );
190 - }
191188
192189 //make sure scripts are on top:
193190 $postScripts = $this->mScripts;
@@ -194,31 +191,38 @@
195192
196193 if( $wgEnableScriptLoader ){
197194 //directly add script_loader call for addCoreScripts2Top
198 - $this->mScripts = $this->getScriptLoaderJs( $core_classes );
 195+ $this->mScripts = $this->getScriptLoaderJs( $coreClasses );
199196 } else {
200197 $so = '';
201 - foreach( $core_classes as $js_class ){
202 - $this->addScriptClass( $js_class );
 198+ foreach( $coreClasses as $jsClass ){
 199+ $this->addScriptClass( $jsClass );
203200 }
 201+ // Also add the "loader" classes ( script-loader won't run them )
 202+ foreach( $wgExtensionJavascriptLoader as $loaderPath){
 203+ $this->addScriptFile(
 204+ "$wgScriptPath/extensions/$loaderPath"
 205+ );
 206+ }
204207 }
205208 //Now re-append any scripts that got added prior to the addCoreScripts2Top call
206209 $this->mScripts = $this->mScripts . $postScripts;
207210 }
208211
209212 /**
210 - * @param string $js_class Name of the JavaScript class
 213+ * @param string $jsClass Name of the JavaScript class
211214 * @return boolean False if the class wasn't found, true on success
212215 */
213 - function addScriptClass( $js_class ){
214 - global $wgDebugJavaScript, $wgJSAutoloadLocalClasses, $wgJSAutoloadClasses, $IP,
215 - $wgEnableScriptLoader, $wgStyleVersion, $wgScriptPath, $wgStylePath, $wgEnableJS2system;
 216+ function addScriptClass( $jsClass ){
 217+ global $wgDebugJavaScript, $wgJSAutoloadClasses, $IP,
 218+ $wgEnableScriptLoader, $wgStyleVersion, $wgScriptPath, $wgStylePath;
216219
217 - $path = jsScriptLoader::getJsPathFromClass( $js_class );
 220+ $path = jsScriptLoader::getJsPathFromClass( $jsClass );
 221+
218222 if( $path !== false ){
219223 if( $wgEnableScriptLoader ) {
220224 // Register it with the script loader
221 - if( !in_array( $js_class, $this->mScriptLoaderClassList ) ) {
222 - $this->mScriptLoaderClassList[] = $js_class;
 225+ if( !in_array( $jsClass, $this->mScriptLoaderClassList ) ) {
 226+ $this->mScriptLoaderClassList[] = $jsClass;
223227 }
224228 } else {
225229 // Source the script directly
@@ -231,22 +235,21 @@
232236 } else {
233237 $path = $wgScriptPath . '/' . $path;
234238 }
235 - $this->addScript( Html::linkedScript( $path . "?" . $this->getURIDparam( $js_class ) ) );
 239+ $this->addScript( Html::linkedScript( $path . "?" . $this->getURIDparam( $jsClass ) ) );
236240
237 - // Merge in language text (if js2 is on and we have mw.addMessages function & scriptLoader is "off")
238 - if( $wgEnableJS2system ){
239 - if( !$this->mScriptLoader )
240 - $this->mScriptLoader = new jsScriptLoader();
241 -
242 - $inlineMsg = $this->mScriptLoader->getInlineMsgFromClass( $js_class );
243 - if( $inlineMsg != '' )
244 - $this->addScript( Html::inlineScript( $inlineMsg ));
 241+ // Merge in language text for non-script loader scripts
 242+ if( !$this->mScriptLoader ){
 243+ $this->mScriptLoader = new jsScriptLoader();
245244 }
 245+ $inlineMsg = $this->mScriptLoader->getInlineMsgFromClass( $jsClass );
 246+ if( $inlineMsg != '' ){
 247+ $this->addScript( Html::inlineScript( $inlineMsg ));
 248+ }
246249 }
247250 return true;
248251 }
249 - //print "could not find: $js_class\n";
250 - wfDebug( __METHOD__ . ' could not find js_class: ' . $js_class );
 252+ //print "could not find: $jsClass\n";
 253+ wfDebug( __METHOD__ . ' could not find js_class: ' . $jsClass );
251254 return false; // could not find the class
252255 }
253256
@@ -301,9 +304,9 @@
302305 }else{
303306 //check for file modified time:
304307 if( $wgScriptModifiedFileCheck ) {
305 - $js_path = jsScriptLoader::getJsPathFromClass( $class );
306 - if( $js_path ) {
307 - $cur_ftime = filemtime ( $IP ."/". $js_path );
 308+ $jsPath = jsScriptLoader::getJsPathFromClass( $class );
 309+ if( $jsPath ) {
 310+ $cur_ftime = filemtime ( $IP ."/". $jsPath );
308311 if( $cur_ftime > $ftime )
309312 $ftime = $cur_ftime;
310313 }
@@ -349,15 +352,14 @@
350353 * @param $path string
351354 */
352355 function getJsClassFromPath( $path ) {
353 - global $wgJSAutoloadClasses, $wgJSAutoloadLocalClasses, $wgScriptPath;
 356+ global $wgJSAutoloadClasses, $wgScriptPath;
354357 //Make sure we have the scriptClasses loaded:
355358 $this->loadJsClassPaths();
356359
357 - $scriptLoaderPaths = array_merge( $wgJSAutoloadClasses, $wgJSAutoloadLocalClasses );
358 - foreach( $scriptLoaderPaths as $js_class => $js_path ) {
359 - $js_path = "{$wgScriptPath}/{$js_path}";
360 - if( $path == $js_path )
361 - return $js_class;
 360+ foreach( $wgJSAutoloadClasses as $jsClass => $jsPath ) {
 361+ $jsPath = "{$wgScriptPath}/{$jsPath}";
 362+ if( $path == $jsPath )
 363+ return $jsClass;
362364 }
363365 return false;
364366 }
@@ -1244,8 +1246,8 @@
12451247 $this->addScriptFile( 'rightclickedit.js' );
12461248 }
12471249
1248 - global $wgUseAJAXCategories, $wgEnableJS2system;
1249 - if ($wgUseAJAXCategories && $wgEnableJS2system) {
 1250+ global $wgUseAJAXCategories;
 1251+ if ( $wgUseAJAXCategories ) {
12501252 global $wgAJAXCategoriesNamespaces;
12511253
12521254 $title = $this->getTitle();
Index: branches/js2-work/phase3/includes/AutoLoader.php
@@ -609,8 +609,7 @@
610610
611611 );
612612
613 -// Autoloader for JavaScript files (path is from the MediaWiki folder)
614 -global $wgJSAutoloadLocalClasses;
 613+// Autoloader for core mediaWiki JavaScript files (path is from the MediaWiki folder)
615614 $wgJSAutoloadLocalClasses = array(
616615 'ajax' => 'skins/common/ajax.js',
617616 'ajaxwatch' => 'skins/common/ajaxwatch.js',
Index: branches/js2-work/phase3/js/mwEmbed/includes/noMediaWikiConfig.php
@@ -11,8 +11,6 @@
1212
1313 // Setup the globals: (for documentation see: DefaultSettings.php )
1414
15 -$wgJSAutoloadLocalClasses = array();
16 -
1715 $IP = realpath( dirname( __FILE__ ) . '/../' );
1816
1917 // $wgMwEmbedDirectory becomes the root $IP
@@ -21,8 +19,8 @@
2220 $wgUseFileCache = true;
2321
2422 // Init our wg Globals
25 -$wgJSAutoloadClasses = array();
2623 $wgJSAutoloadLocalClasses = array();
 24+$wgJSAutoloadClasses = array();
2725
2826 $wgJSModuleLoaderPaths = array();
2927
@@ -30,9 +28,8 @@
3129 $wgEnableScriptLocalization = true;
3230
3331 $mwLanguageCode = 'en';
 32+$wgLang = false;
3433
35 -$wgContLanguageCode = '';
36 -
3734 $wgStyleVersion = '218';
3835
3936 $wgEnableScriptMinify = true;
Index: branches/js2-work/phase3/js/mwEmbed/includes/jsClassLoader.php
@@ -2,66 +2,86 @@
33
44 if ( !defined( 'MEDIAWIKI' ) ) die( 1 );
55
6 -global $wgJSAutoloadLocalClasses, $wgMwEmbedDirectory;
7 -// NOTE this is growing in complexity and globals sloppiness
8 -
9 -
106 class jsClassLoader {
117 private static $moduleList = array();
128 private static $combinedLoadersJs = '';
139 private static $classReplaceExp = '/mw\.addClassFilePaths\s*\(\s*{(.*)}\s*\)\s*\;/siU';
1410
1511 private static $loadClassFlag = false;
 12+ private static $directoryContext = '';
1613 /**
17 - * Get the javascript class paths
 14+ * Get the javascript class paths from javascript files
 15+ *
 16+ * Note:: if it is ~too costly~ to parse js we could cache in DB per file modified time
1817 */
1918 public static function loadClassPaths(){
20 - global $wgMwEmbedDirectory, $wgJSModuleLoaderPaths;
 19+ global $wgMwEmbedDirectory, $wgExtensionJavascriptLoader,
 20+ $wgJSAutoloadClasses, $wgJSAutoloadLocalClasses, $IP;
2121
2222 // Only run "once"
2323 if( self::$loadClassFlag )
2424 return false;
2525 self::$loadClassFlag = true;
2626
 27+ // Load classes from mediaWiki $wgJSAutoloadLocalClasses var:
 28+ $wgJSAutoloadClasses = array_merge( $wgJSAutoloadClasses, $wgJSAutoloadLocalClasses );
 29+
2730 // Load classes from mwEmbed.js
2831 if ( !is_file( $wgMwEmbedDirectory . 'mwEmbed.js' ) ) {
2932 // throw error no mwEmbed found
3033 throw new MWException( "mwEmbed.js missing check \$wgMwEmbedDirectory path\n" );
3134 return false;
3235 }
 36+
3337 // Read the file:
34 - $file_content = file_get_contents( $wgMwEmbedDirectory . 'mwEmbed.js' );
 38+ $fileContent = file_get_contents( $wgMwEmbedDirectory . 'mwEmbed.js' );
3539 // Get class paths from mwEmbed.js
36 - $replace_test = preg_replace_callback(
 40+ self::$directoryContext = $wgMwEmbedDirectory;
 41+ preg_replace_callback(
3742 self::$classReplaceExp,
3843 'jsClassLoader::preg_classPathLoader',
39 - $file_content
 44+ $fileContent
4045 );
4146
4247 // Get the list of enabled modules into $wgJSModuleList
43 - $replace_test = preg_replace_callback(
 48+ preg_replace_callback(
4449 '/mwEnabledModuleList\s*\=\s*\[(.*)\]/siU',
4550 'jsClassLoader::preg_buildModuleList',
46 - $file_content
 51+ $fileContent
4752 );
4853
4954 // Get all the classes from the loader files:
5055 foreach( self::$moduleList as $na => $moduleName){
51 - $file_content = file_get_contents(
52 - $wgMwEmbedDirectory . 'modules/' . $moduleName . '/loader.js'
53 - );
54 - // Add the mwEmbed loader js to its global collector:
55 - self::$combinedLoadersJs .= $file_content;
 56+ // Setup the directory context:
 57+ self::$directoryContext = $wgMwEmbedDirectory;
 58+ self::proccessLoaderPath( $wgMwEmbedDirectory .
 59+ 'modules/' . $moduleName . '/loader.js' );
5660
57 - $replace_test.= preg_replace_callback(
58 - self::$classReplaceExp,
59 - 'jsClassLoader::preg_classPathLoader',
60 - $file_content
61 - );
6261 }
6362
64 - // Get all the classes from extensions registered mwEmbed modules
 63+ // Get all the extension loader paths registered mwEmbed modules
 64+ foreach( $wgExtensionJavascriptLoader as $na => $loaderPath){
 65+ // Setup the directory context:
 66+ self::$directoryContext = 'extensions/' .str_replace('loader.js', '' , $loaderPath);
 67+ self::proccessLoaderPath( $IP . '/extensions/' . $loaderPath );
 68+ }
 69+ }
 70+ /**
 71+ * Process a loader path
 72+ *
 73+ * @param String $path
 74+ */
 75+ private static function proccessLoaderPath( $path ){
 76+ $fileContent = file_get_contents( $path );
6577
 78+ // Add the mwEmbed loader js to its global collector:
 79+ self::$combinedLoadersJs .= $fileContent;
 80+
 81+ preg_replace_callback(
 82+ self::$classReplaceExp,
 83+ 'jsClassLoader::preg_classPathLoader',
 84+ $fileContent
 85+ );
6686 }
6787 /**
6888 * Get the combined loader javascript
@@ -90,22 +110,20 @@
91111 }
92112 /**
93113 * Adds javascript autoloader class names and paths
94 - * to $wgJSAutoloadLocalClasses global
 114+ * to $wgJSAutoloadClasses global
95115 *
96 - * Use $wgJSAutoloadLocalClasses to support manual adding of class name / paths
97 - *
98116 * @param string $jvar Json string with class name list
99117 */
100118 private static function preg_classPathLoader( $jsvar ) {
101 - global $wgJSAutoloadLocalClasses, $wgMwEmbedDirectory;
 119+ global $wgJSAutoloadClasses;
102120 if ( !isset( $jsvar[1] ) )
103121 return false;
104122
105123 $jClassSet = FormatJson::decode( '{' . $jsvar[1] . '}', true );
106124 foreach ( $jClassSet as $jClass => $jPath ) {
107 - // Strip $ from jClass (as they are stripped on URL request parameter input)
 125+ // Strip $ from class (as they are stripped on URL request parameter input)
108126 $jClass = str_replace( '$', '', $jClass );
109 - $wgJSAutoloadLocalClasses[ $jClass ] = $wgMwEmbedDirectory . $jPath;
 127+ $wgJSAutoloadClasses[ $jClass ] = self::$directoryContext . $jPath;
110128 }
111129 }
112130 }
Index: branches/js2-work/phase3/js/mwEmbed/modules/AddMedia/searchLibs/mediaWikiSearch.js
@@ -47,7 +47,7 @@
4848 'iiurlwidth': parseInt( this.rsd.thumb_width ),
4949 'rvprop':'content'
5050 }
51 - mw.getJSON(this.provider.api_url, request, function( data ) {
 51+ mw.getJSON(this.provider.api_url, request, function( data ) {
5252 // check for redirect
5353 for ( var i in data.query.pages ) {
5454 var page = data.query.pages[i];
Index: branches/js2-work/phase3/js/mwEmbed/mwEmbed.js
@@ -1024,7 +1024,7 @@
10251025 loadDone = false;
10261026 }
10271027 // Run the parent scope callback for "loadMany"
1028 - if( loadDone ){
 1028+ if( loadDone && callback ){
10291029 callback( loadName );
10301030 }
10311031 } );
@@ -1171,18 +1171,26 @@
11721172 // Include class defined check for older browsers
11731173 var classDone = false;
11741174
 1175+ //Add a class callback hook ( for script-loader onDone callback )
 1176+ mwLoadDoneCB[ className ] = function(){
 1177+ mw.log('run callback for: ' + className );
 1178+ if( callback ){
 1179+ callback( className );
 1180+ }
 1181+ callback = null;
 1182+ mwLoadDoneCB[ className ] = 'done';
 1183+ };
11751184
11761185 // Issue the request to load the class (include class name in result callback:
11771186 mw.getScript( scriptRequest, function( scriptRequest ) {
1178 - if(! mw.isset( className )){
 1187+ if(! mw.isset( className ) && callback){
11791188 mw.log( 'Possible Error: ' + className +' not set in time, or not defined in:' + "\n" + _this.classPaths[ className ] );
1180 - }else{
1181 - if( callback )
1182 - callback( className );
1183 - callback = null;
11841189 }
 1190+ if( callback )
 1191+ callback( className );
 1192+ callback = null;
11851193 } );
1186 - //mw.log( 'done with running getScript request ' );
 1194+ //mw.log( 'done with running getScript request ' );
11871195
11881196 /*
11891197 * If scriptLoader is not enabled
@@ -1224,8 +1232,11 @@
12251233 * php scriptLoader to parse the file paths.
12261234 */
12271235 addClassFilePaths: function( classSet ){
 1236+ var prefix = ( mw.getConfig( 'loaderContext' ) )?
 1237+ mw.getConfig( 'loaderContext' ): '';
 1238+
12281239 for( var i in classSet ){
1229 - this.classPaths[ i ] = classSet[ i ];
 1240+ this.classPaths[ i ] = prefix + classSet[ i ];
12301241 }
12311242 },
12321243
@@ -1569,7 +1580,7 @@
15701581 return ;
15711582 }
15721583
1573 - if ( mw.isset( objectName ) ){
 1584+ if ( mw.isset( objectName ) || mwLoadDoneCB[ objectName ] == 'done' ){
15741585 callback( objectName )
15751586 }else{
15761587 setTimeout( function( ){
@@ -1719,9 +1730,7 @@
17201731 // Check if its a relative path name, ( ie does not start with "/" and does not include ://
17211732 var isRelativePath = ( scriptRequest.indexOf('://') == -1 && scriptRequest.indexOf('/') !== 0 )? true : false;
17221733 if( slpath && isRelativePath ) {
1723 - url = slpath + '?class=' + scriptRequest;
1724 - //Add a class callback hook ( for script-loader onDone callback )
1725 - mwLoadDoneCB[ scriptRequest ] = callback;
 1734+ url = slpath + '?class=' + scriptRequest;
17261735 }else{
17271736 // Add the mwEmbed path if a relative path request
17281737 url = ( isRelativePath )? mw.getMwEmbedPath() : '';
@@ -1753,9 +1762,9 @@
17541763 var script = document.createElement("script");
17551764 script.setAttribute( 'src', url );
17561765
1757 - // Attach handlers ( if not using script loader that issues onDone callback )
 1766+ // Attach handlers ( if not using script loader that issues onDone callback )
17581767 if( !mw.getScriptLoaderPath() ){
1759 - script.onload = script.onreadystatechange = function(){
 1768+ script.onload = script.onreadystatechange = function(){
17601769 if (!this.readyState || this.readyState == "loaded" || this.readyState == "complete") {
17611770 if( callback )
17621771 callback( scriptRequest );
@@ -2292,6 +2301,7 @@
22932302 $j.each( enabledModules, function( na, module_name ){
22942303 loaderRequest.push( 'modules/' + module_name + '/loader.js' );
22952304 })
 2305+ mw.setConfig('loaderContext', '' );
22962306 mw.load( loaderRequest, function(){
22972307 callback();
22982308 } );
@@ -2390,7 +2400,8 @@
23912401 * class paths
23922402 *
23932403 */
2394 -
 2404+mw.setConfig('loaderContext', '' );
 2405+
23952406 mw.addClassFilePaths( {
23962407 "mwEmbed" : "mwEmbed.js",
23972408 "window.jQuery" : "jquery/jquery-1.3.2.js",
Index: branches/js2-work/phase3/js/mwEmbed/jsScriptLoader.php
@@ -24,7 +24,7 @@
2525 var $jsFileList = array();
2626 var $langCode = '';
2727 var $jsout = '';
28 - var $rKey = ''; // the request key
 28+ var $requestKey = ''; // the request key
2929 var $error_msg = '';
3030 var $debug = false;
3131
@@ -63,19 +63,20 @@
6464 * outputs js
6565 */
6666 function doScriptLoader() {
67 - global $wgJSAutoloadClasses, $wgJSAutoloadLocalClasses, $IP,
 67+ global $wgJSAutoloadClasses, $IP,
6868 $wgEnableScriptMinify, $wgUseFileCache, $wgExtensionMessagesFiles;
6969
7070 // Load the ExtensionMessagesFiles
71 - $wgExtensionMessagesFiles[ 'mwEmbed' ] = realpath( dirname( __FILE__ ) ) . '/includes/languages/mwEmbed.i18n.php';
 71+ $wgExtensionMessagesFiles[ 'mwEmbed' ] = realpath( dirname( __FILE__ ) ) .
 72+ '/includes/languages/mwEmbed.i18n.php';
7273
73 - //Load the javascript class paths:
 74+ // Load the javascript class paths:
7475 require_once( realpath( dirname( __FILE__ ) ) . "/includes/jsClassLoader.php");
7576 jsClassLoader::loadClassPaths();
7677
7778 // Reset the requestKey:
7879 $this->requestKey = '';
79 - //do the post proc request with configuration vars:
 80+ // Do the post proc request with configuration vars:
8081 $this->postProcRequestVars();
8182 //update the filename (if gzip is on)
8283 $this->sFileCache->getCacheFileName();
@@ -338,7 +339,7 @@
339340 */
340341 function postProcRequestVars(){
341342 global $wgContLanguageCode, $wgEnableScriptMinify, $wgJSAutoloadClasses,
342 - $wgJSAutoloadLocalClasses, $wgStyleVersion;
 343+ $wgStyleVersion;
343344
344345 // Set debug flag
345346 if ( ( isset( $_GET['debug'] ) && $_GET['debug'] == 'true' ) || ( isset( $wgEnableScriptDebug ) && $wgEnableScriptDebug == true ) ) {
@@ -428,10 +429,10 @@
429430 * This is to quickly get a requestKey that we can check against the cache
430431 */
431432 function preProcRequestVars() {
432 - $rKey = '';
 433+ $requestKey = '';
433434 // Check for debug (won't use the cache)
434435 if ( ( isset( $_GET['debug'] ) && $_GET['debug'] == 'true' ) ) {
435 - //we are going to have to run postProcRequest
 436+ // We are going to have to run postProcRequest
436437 return false;
437438 }
438439
@@ -462,31 +463,31 @@
463464 }
464465
465466 // Check for the requested classes
466 - if ( count( $reqClassList ) > 0 ) {
 467+ if ( $reqClassList && count( $reqClassList ) > 0 ) {
467468 // Clean the class list and populate jsFileList
468469 foreach ( $reqClassList as $reqClass ) {
469470 //do some simple checks:
470471 if ( trim( $reqClass ) != '' ){
471472 if( substr( $reqClass, 0, 3 ) == 'WT:' && strtolower( substr( $reqClass, -3) ) == '.js' ){
472 - //wiki page requests (must end with .js):
473 - $rKey .= $reqClass;
 473+ // Wiki page requests (must end with .js):
 474+ $requestKey .= $reqClass;
474475 }else if( substr( $reqClass, 0, 3 ) != 'WT:' ){
475 - //normal class requests:
 476+ // Normal class requests:
476477 $reqClass = preg_replace( "/[^A-Za-z0-9_\-\.]/", '', $reqClass );
477 - $rKey .= $reqClass;
 478+ $requestKey .= $reqClass;
478479 }else{
479 - //not a valid class don't add it
 480+ // Not a valid class
480481 }
481482 }
482483 }
483484 }
484 - // Add the language code to the rKey:
485 - $rKey .= '_' . $langCode;
 485+ // Add the language code to the requestKey:
 486+ $requestKey .= '_' . $langCode;
486487
487488 // Add the unique rid
488 - $rKey .= $urid;
 489+ $requestKey .= $urid;
489490
490 - return $rKey;
 491+ return $requestKey;
491492 }
492493 /**
493494 * Check for the commons language hack.
@@ -517,10 +518,10 @@
518519 * @return path of the class or "false"
519520 */
520521 public static function getJsPathFromClass( $reqClass ){
521 - global $wgJSAutoloadLocalClasses, $wgJSAutoloadClasses;
522 - if ( isset( $wgJSAutoloadLocalClasses[$reqClass] ) ) {
523 - return $wgJSAutoloadLocalClasses[$reqClass];
524 - } else if ( isset( $wgJSAutoloadClasses[$reqClass] ) ) {
 522+ global $wgJSAutoloadClasses;
 523+ // Make sure the class is loaded:
 524+ jsClassLoader::loadClassPaths();
 525+ if ( isset( $wgJSAutoloadClasses[$reqClass] ) ) {
525526 return $wgJSAutoloadClasses[$reqClass];
526527 } else {
527528 return false;
@@ -530,18 +531,20 @@
531532 /**
532533 * Retrieve the js file into a string, updates error_msg if not retrivable.
533534 *
534 - * @param {String} $file_path File to get
 535+ * @param {String} $filePath File to get
535536 * @return {String} of the file contents
536537 */
537 - function doGetJsFile( $file_path ) {
 538+ function doGetJsFile( $filePath ) {
538539 global $IP;
539540
540541 // Load the file
541 - $str = @file_get_contents( "{$IP}/{$file_path}" );
 542+ wfSuppressWarnings();
 543+ $str = file_get_contents( "{$IP}/{$filePath}" );
 544+ wfRestoreWarnings();
542545
543546 if ( $str === false ) {
544547 // @@todo check PHP error level. Don't want to expose paths if errors are hidden.
545 - $this->error_msg .= 'Requested File: ' . htmlspecialchars( $file_path ) . ' could not be read' . "\n";
 548+ $this->error_msg .= 'Requested File: ' . htmlspecialchars( $IP.'/'.$filePath ) . ' could not be read' . "\n";
546549 return false;
547550 }
548551 return $str;
@@ -643,8 +646,8 @@
644647 * @return {Array} decoded json array of message key value pairs
645648 */
646649 function getMsgKeysFromClass( $class ){
647 - $file_path = self::getJsPathFromClass( $class );
648 - $str = $this->getScriptText($class, $file_path);
 650+ $filePath = self::getJsPathFromClass( $class );
 651+ $str = $this->getScriptText($class, $filePath);
649652
650653 $inx = self::getAddMessagesIndex( $str );
651654 if(!$inx)
@@ -660,13 +663,13 @@
661664 * @param {String} $langCode Language code override
662665 */
663666 static public function updateMsgKeys(& $jmsg, $langCode = false){
664 - global $wgContLanguageCode;
 667+ global $wgLang;
665668 // Check the langCode
666 - if(!$langCode)
667 - $langCode = $wgContLanguageCode;
 669+ if(!$langCode && $wgLang)
 670+ $langCode = $wgLang->getCode();
668671
669672 // Get the msg keys for the a json array
670 - foreach ( $jmsg as $msgKey => $default_en_value ) {
 673+ foreach ( $jmsg as $msgKey => $na ) {
671674 $jmsg[ $msgKey ] = wfMsgGetKey( $msgKey, true, $langCode, false );
672675 }
673676 }
Index: branches/js2-work/phase3/js/mwEmbed/jquery/plugins/jquery.cookie.js
@@ -53,7 +53,8 @@
5454 * @cat Plugins/Cookie
5555 * @author Klaus Hartl/klaus.hartl@stilbuero.de
5656 */
57 -jQuery.cookie = function(name, value, options) {
 57+(function($){
 58+$.cookie = function(name, value, options) {
5859 if (typeof value != 'undefined') { // name and value given, set cookie
5960 options = options || {};
6061 if (value === null) {
@@ -94,4 +95,5 @@
9596 }
9697 return cookieValue;
9798 }
98 -};
\ No newline at end of file
 99+};
 100+})(jQuery);
\ No newline at end of file

Follow-up revisions

RevisionCommit summaryAuthorDate
r61182UsabilityInitiative: (bug 2124) Fix for r61137: use <1.17 instead of >1.17 in...catrope23:36, 17 January 2010
r61184UsabilityInitiative: Fix for r61137: remove trailing tabcatrope23:48, 17 January 2010
r61195UsabilityInitiative: A few more whitespace changes, recombine for the last fe...catrope02:19, 18 January 2010
r61228Update js2stopgap.min.js for at least r61137 and r61075catrope00:58, 19 January 2010
r61557* Moved js2stopgap.js to skins/common/jquery.js, like I said I was going to d...tstarling04:17, 27 January 2010
r61566Reverted the UsabilityInitiative part of r61137 and associated changes in r61......tstarling07:56, 27 January 2010

Comments

#Comment by Catrope (talk | contribs)   00:06, 18 January 2010

This revision adds English localizations to a bunch of .js files, but

  • this obviously duplicates a crapload of text
  • missed Vector/*/*.js , nor did it add a Vector/loader.js or make any of the other changes to the Vector directory
  • broke our existing message loading by checking for version > 1.17 (fixed in r61182)
  • doesn't add localizations for other languages. Not sure how that's supposed to be handled but AFAICT just adding en is a hack
  • is compatible with the existing system only by accident: our message loading happens after the .js files are loaded so it overwrites any English messages in case the interface language is not English.

Also, I'd appreciate it if you didn't commit such large changes (moving files, breaking all usability localization completely, etc.) on a Saturday morning without consulting us or (seemingly) testing them in a non-JS2 environment.

#Comment by Catrope (talk | contribs)   00:19, 18 January 2010

I just realized you did send an e-mail to the usability alias, so you did contact us. Sorry for suggesting you didn't.

#Comment by Mdale (talk | contribs)   01:39, 18 January 2010

The idea with js2" localization is that it packages the localizations into the javascript output rather than inline. This enables interfaces to be dynamically loaded in a single request with their localized text. In development you have your English language fall-back near the the class / interfaces that are using the text, this makes it easy for developers to update the interface messages as the interface is developed. It also enables localization of "user-scripts" without some of the multiple request loading hackery we presently see on commons.

( obliviously it does support localizations for other languages as shown in the demo in the email sent to the list. )

php Localization scripts already manage text msg maintenance. This lets us keep developer written files separate from script maintained files. Scripts already exist to manage this js-> php localization file maintenance as done with mwEmbed.

If script-loader is "off" and your using > 1.17 then it packages the text into the page output after the script and "accidentally works" by in-line page output of msg text. If using < 1.17 then its up to the application to handle javascript msg localization.

( We could strip the addMessages calls to avoid the duplicate English fall-backs when using a different language with the script-loader "off" )

I tested with non-js2 branch and it was working, but missed that version check fixed in 61182 ( thanks)

I did not add a loader.js for vector since I don't think you would want to dynamically load "vector" All its scripts are outputted "all the time" when its enabled. Its message output system could be updated but did not get around to doing that in this commit and the idea is that it does not break things to have a hybrid environment. But it would be good to update that one too will give it a shot shortly.

Are there any remaining issues?

#Comment by Catrope (talk | contribs)   01:52, 18 January 2010

OK so basically the script loader's PHP code takes the JS and modifies its messages object for the requested language? Does that sound about right? Yes, it does work on sandbox2, which has JS2 enabled, but it needs to degrade gracefully in non-JS2 environments (including MW 1.16) and currently does so only by accident, as I mentioned, because of loading order. I guess this was indeed your intention and it did work after reversing said version check.

The argument about not loading Vector dynamically makes sense in the current situation, but we may want to add optional Vector modules in the future or attach preferences to existing ones (effectively making them optional). The latter is already the case for EditWarning.

In terms of remaining issues: I'm not too thrilled about the message duplication, but if it's part of a greater plan that's probably OK. Let's talk about this when you get back into the office (when?), as well as about the inline editing thing; that feature has some fundamental issues.

#Comment by Mdale (talk | contribs)   02:53, 18 January 2010

We could "turn off" the script-loader on sandbox2 and it would work with inline inserts that override the English fallback. That is unfortunate "duplication" but would only be used in debug mode, otherwise you would use the script-loader for production ... or in mw 1.16 you could strip the addMessage calls when you combine.

In terms of code maintenance duplication the idea is developers will only touch the js files with the msg being copied to the php via scripts.

Yes the inline edit was just put together as a demo of dynamic loading ( its not yet fully functional... but would take a short time to make it so ) There are other issues like do we want to include the full editor interface in inline mode? should it include the section outline?.. etc. Which is why I am not putting effort into finishing it up until there is clarity on what we want.

I will be back the 28th or so.

#Comment by Tim Starling (talk | contribs)   03:38, 27 January 2010

Please use separate commits for js2-work and trunk.

Status & tagging log