diff options
author | Luke Shumaker <lukeshu@sbcglobal.net> | 2016-05-01 15:12:12 -0400 |
---|---|---|
committer | Luke Shumaker <lukeshu@sbcglobal.net> | 2016-05-01 15:12:12 -0400 |
commit | c9aa36da061816dee256a979c2ff8d2ee41824d9 (patch) | |
tree | 29f7002b80ee984b488bd047dbbd80b36bf892e9 /extensions/WikiEditor/modules/jquery.wikiEditor.js | |
parent | b4274e0e33eafb5e9ead9d949ebf031a9fb8363b (diff) | |
parent | d1ba966140d7a60cd5ae4e8667ceb27c1a138592 (diff) |
Merge branch 'archwiki'
# Conflicts:
# skins/ArchLinux.php
# skins/ArchLinux/archlogo.gif
Diffstat (limited to 'extensions/WikiEditor/modules/jquery.wikiEditor.js')
-rw-r--r-- | extensions/WikiEditor/modules/jquery.wikiEditor.js | 127 |
1 files changed, 66 insertions, 61 deletions
diff --git a/extensions/WikiEditor/modules/jquery.wikiEditor.js b/extensions/WikiEditor/modules/jquery.wikiEditor.js index def8b69e..e5d34aa9 100644 --- a/extensions/WikiEditor/modules/jquery.wikiEditor.js +++ b/extensions/WikiEditor/modules/jquery.wikiEditor.js @@ -8,7 +8,8 @@ * $( 'textarea#wpTextbox1' ).wikiEditor( 'addModule', 'toolbar', { ... config ... } ); * */ -( function ( $ ) { +/*jshint onevar:false, boss:true */ +( function ( $, mw ) { /** * Global static object for wikiEditor that provides generally useful functionality to all modules and contexts. @@ -47,15 +48,15 @@ $.wikiEditor = { msie: [['>=', 7]], // Layout issues in FF < 2 firefox: [['>=', 2]], - // Text selection bugs galore - this may be a different situation with the new iframe-based solution + // Text selection bugs galore opera: [['>=', 9.6]], // jQuery minimums safari: [['>=', 3]], chrome: [['>=', 3]], netscape: [['>=', 9]], blackberry: false, - ipod: false, - iphone: false + ipod: [['>=', 6]], + iphone: [['>=', 6]] }, // Right-to-left languages rtl: { @@ -63,15 +64,15 @@ $.wikiEditor = { msie: [['>=', 8]], // Layout issues in FF < 2 firefox: [['>=', 2]], - // Text selection bugs galore - this may be a different situation with the new iframe-based solution + // Text selection bugs galore opera: [['>=', 9.6]], // jQuery minimums safari: [['>=', 3]], chrome: [['>=', 3]], netscape: [['>=', 9]], blackberry: false, - ipod: false, - iphone: false + ipod: [['>=', 6]], + iphone: [['>=', 6]] } }, @@ -113,7 +114,7 @@ $.wikiEditor = { isRequired: function ( module, requirement ) { if ( typeof module.req !== 'undefined' ) { for ( var req in module.req ) { - if ( module.req[req] == requirement ) { + if ( module.req[req] === requirement ) { return true; } } @@ -132,9 +133,10 @@ $.wikiEditor = { * with the key 'bar'. */ autoMsg: function ( object, property ) { + var i, p; // Accept array of possible properties, of which the first one found will be used - if ( typeof property == 'object' ) { - for ( var i in property ) { + if ( typeof property === 'object' ) { + for ( i in property ) { if ( property[i] in object || property[i] + 'Msg' in object ) { property = property[i]; break; @@ -144,11 +146,11 @@ $.wikiEditor = { if ( property in object ) { return object[property]; } else if ( property + 'Msg' in object ) { - var p = object[property + 'Msg']; + p = object[property + 'Msg']; if ( $.isArray( p ) && p.length >= 2 ) { - return mediaWiki.message.apply( mediaWiki.message, p ).plain(); + return mw.message.apply( mw.message, p ).plain(); } else { - return mediaWiki.message( p ).plain(); + return mw.message( p ).plain(); } } else { return ''; @@ -181,10 +183,10 @@ $.wikiEditor = { var src = $.wikiEditor.autoLang( icon, lang ); path = path || $.wikiEditor.imgPath; // Prepend path if src is not absolute - if ( src.substr( 0, 7 ) != 'http://' && src.substr( 0, 8 ) != 'https://' && src[0] != '/' ) { + if ( src.substr( 0, 7 ) !== 'http://' && src.substr( 0, 8 ) !== 'https://' && src[0] !== '/' ) { src = path + src; } - return src + '?' + mw.loader.version( 'jquery.wikiEditor' ); + return src + '?' + mw.loader.getVersion( 'jquery.wikiEditor' ); }, /** @@ -197,9 +199,9 @@ $.wikiEditor = { */ autoIconOrOffset: function ( icon, offset, path, lang ) { lang = lang || mw.config.get( 'wgUserLanguage' ); - if ( typeof offset == 'object' && lang in offset ) { + if ( typeof offset === 'object' && lang in offset ) { return offset[lang]; - } else if ( typeof icon == 'object' && lang in icon ) { + } else if ( typeof icon === 'object' && lang in icon ) { return $.wikiEditor.autoIcon( icon, undefined, lang ); } else { return $.wikiEditor.autoLang( offset, lang ); @@ -214,21 +216,21 @@ $.fn.wikiEditor = function () { // Skip any further work when running in browsers that are unsupported if ( !$.wikiEditor.isSupported() ) { - return $(this); + return $( this ); } /* Initialization */ // The wikiEditor context is stored in the element's data, so when this function gets called again we can pick up right // where we left off -var context = $(this).data( 'wikiEditor-context' ); +var context = $( this ).data( 'wikiEditor-context' ); // On first call, we need to set things up, but on all following calls we can skip right to the API handling -if ( !context || typeof context == 'undefined' ) { +if ( !context || typeof context === 'undefined' ) { // Star filling the context with useful data - any jQuery selections, as usual should be named with a preceding $ context = { // Reference to the textarea element which the wikiEditor is being built around - '$textarea': $(this), + '$textarea': $( this ), // Container for any number of mutually exclusive views that are accessible by tabs 'views': {}, // Container for any number of module-specific data - only including data for modules in use on this context @@ -236,25 +238,9 @@ if ( !context || typeof context == 'undefined' ) { // General place to shouve bits of data into 'data': {}, // Unique numeric ID of this instance used both for looking up and differentiating instances of wikiEditor - 'instance': $.wikiEditor.instances.push( $(this) ) - 1, - // Array mapping elements in the textarea to character offsets - 'offsets': null, - // Cache for context.fn.htmlToText() - 'htmlToTextMap': {}, - // The previous HTML of the iframe, stored to detect whether something really changed. - 'oldHTML': null, - // Same for delayedChange() - 'oldDelayedHTML': null, - // The previous selection of the iframe, stored to detect whether the selection has changed - 'oldDelayedSel': null, - // Saved selection state for IE + 'instance': $.wikiEditor.instances.push( $( this ) ) - 1, + // Saved selection state for old IE (<=10) 'savedSelection': null, - // Stack of states in { html: [string] } form - 'history': [], - // Current history state position - this is number of steps backwards, so it's always -1 or less - 'historyPosition': -1, - /// The previous historyPosition, stored to detect if change events were due to an undo or redo action - 'oldDelayedHistoryPosition': -1, // List of extensions active on this context 'extensions': [] }; @@ -262,7 +248,7 @@ if ( !context || typeof context == 'undefined' ) { /** * Externally Accessible API * - * These are available using calls to $(selection).wikiEditor( call, data ) where selection is a jQuery selection + * These are available using calls to $( selection ).wikiEditor( call, data ) where selection is a jQuery selection * of the textarea that the wikiEditor instance was built around. */ @@ -276,14 +262,14 @@ if ( !context || typeof context == 'undefined' ) { 'addModule': function ( context, data ) { var module, call, modules = {}; - if ( typeof data == 'string' ) { + if ( typeof data === 'string' ) { modules[data] = {}; - } else if ( typeof data == 'object' ) { + } else if ( typeof data === 'object' ) { modules = data; } for ( module in modules ) { // Check for the existance of an available / supported module with a matching name and a create function - if ( typeof module == 'string' && typeof $.wikiEditor.modules[module] !== 'undefined' && + if ( typeof module === 'string' && typeof $.wikiEditor.modules[module] !== 'undefined' && $.wikiEditor.isSupported( $.wikiEditor.modules[module] ) ) { // Extend the context's core API with this module's own API calls @@ -326,11 +312,11 @@ if ( !context || typeof context == 'undefined' ) { */ trigger: function ( name, event ) { // Event is an optional argument, but from here on out, at least the type field should be dependable - if ( typeof event == 'undefined' ) { + if ( typeof event === 'undefined' ) { event = { 'type': 'custom' }; } // Ensure there's a place for extra information to live - if ( typeof event.data == 'undefined' ) { + if ( typeof event.data === 'undefined' ) { event.data = {}; } @@ -350,9 +336,9 @@ if ( !context || typeof context == 'undefined' ) { name in $.wikiEditor.modules[module].evt ) { var ret = $.wikiEditor.modules[module].evt[name]( context, event ); - if (ret !== null) { + if ( ret !== null ) { //if 1 returns false, the end result is false - if( returnFromModules === null ) { + if ( returnFromModules === null ) { returnFromModules = ret; } else { returnFromModules = returnFromModules && ret; @@ -393,7 +379,7 @@ if ( !context || typeof context == 'undefined' ) { // Return the newly appended tab return $( '<div>' ) .attr( 'rel', 'wikiEditor-ui-view-' + options.name ) - .addClass( context.view == options.name ? 'current' : null ) + .addClass( context.view === options.name ? 'current' : null ) .append( $( '<a>' ) .attr( 'href', '#' ) .mousedown( function () { @@ -402,11 +388,11 @@ if ( !context || typeof context == 'undefined' ) { } ) .click( function ( event ) { context.$ui.find( '.wikiEditor-ui-view' ).hide(); - context.$ui.find( '.' + $(this).parent().attr( 'rel' ) ).show(); + context.$ui.find( '.' + $( this ).parent().attr( 'rel' ) ).show(); context.$tabs.find( 'div' ).removeClass( 'current' ); - $(this).parent().addClass( 'current' ); - $(this).blur(); - if ( 'init' in options && typeof options.init == 'function' ) { + $( this ).parent().addClass( 'current' ); + $( this ).blur(); + if ( 'init' in options && typeof options.init === 'function' ) { options.init( context ); } event.preventDefault(); @@ -457,17 +443,17 @@ if ( !context || typeof context == 'undefined' ) { }, /** - * Save text selection for IE + * Save text selection for old IE (<=10) */ saveSelection: function () { - if ( $.client.profile().name === 'msie' ) { + if ( $.client.profile().name === 'msie' && document.selection && document.selection.createRange ) { context.$textarea.focus(); context.savedSelection = document.selection.createRange(); } }, /** - * Restore text selection for IE + * Restore text selection for old IE (<=10) */ restoreSelection: function () { if ( $.client.profile().name === 'msie' && context.savedSelection !== null ) { @@ -479,6 +465,13 @@ if ( !context || typeof context == 'undefined' ) { }; /** + * Workaround for a scrolling bug in IE8 (bug 61908) + */ + if ( $.client.profile().name === 'msie' ) { + context.$textarea.css( 'height', context.$textarea.height() ); + } + + /** * Base UI Construction * * The UI is built from several containers, the outer-most being a div classed as "wikiEditor-ui". These containers @@ -493,6 +486,9 @@ if ( !context || typeof context == 'undefined' ) { .append( $( '<span>' + mediaWiki.msg( 'wikieditor-loading' ) + '</span>' ) .css( 'marginTop', context.$textarea.height() / 2 ) ); */ + /* Preserving cursor and focus state, which will get lost due to wrapAll */ + var hasFocus = context.$textarea.is( ':focus' ), + cursorPos = context.$textarea.textSelection( 'getCaretPosition', { startAndEnd: true } ); // Encapsulate the textarea with some containers for layout context.$textarea /* Disabling our loading div for now @@ -504,6 +500,14 @@ if ( !context || typeof context == 'undefined' ) { .wrapAll( $( '<div>' ).addClass( 'wikiEditor-ui-left' ) ) .wrapAll( $( '<div>' ).addClass( 'wikiEditor-ui-bottom' ) ) .wrapAll( $( '<div>' ).addClass( 'wikiEditor-ui-text' ) ); + // Restore scroll position after this wrapAll (tracked by mediawiki.action.edit) + context.$textarea.prop( 'scrollTop', $( '#wpScrolltop' ).val() ); + // Restore focus and cursor if needed + if ( hasFocus ) { + context.$textarea.focus(); + context.$textarea.textSelection( 'setSelection', { start: cursorPos[0], end: cursorPos[1] } ); + } + // Get references to some of the newly created containers context.$ui = context.$textarea.parent().parent().parent().parent().parent(); context.$wikitext = context.$textarea.parent().parent().parent().parent(); @@ -514,15 +518,16 @@ if ( !context || typeof context == 'undefined' ) { .append( $( '<div>' ).addClass( 'wikiEditor-ui-tabs' ).hide() ) .append( $( '<div>' ).addClass( 'wikiEditor-ui-buttons' ) ) ) - .before( $( '<div style="clear: both;"></div>' ) ); + .before( $( '<div>' ).addClass( 'wikiEditor-ui-clear' ) ); // Get references to some of the newly created containers context.$controls = context.$ui.find( '.wikiEditor-ui-buttons' ).hide(); context.$buttons = context.$ui.find( '.wikiEditor-ui-buttons' ); context.$tabs = context.$ui.find( '.wikiEditor-ui-tabs' ); // Clear all floating after the UI - context.$ui.after( $( '<div style="clear: both;"></div>' ) ); + context.$ui.after( $( '<div>' ).addClass( 'wikiEditor-ui-clear' ) ); // Attach a right container context.$wikitext.append( $( '<div>' ).addClass( 'wikiEditor-ui-right' ) ); + context.$wikitext.append( $( '<div>' ).addClass( 'wikiEditor-ui-clear' ) ); // Attach a top container to the left pane context.$wikitext.find( '.wikiEditor-ui-left' ).prepend( $( '<div>' ).addClass( 'wikiEditor-ui-top' ) ); // Setup the intial view @@ -539,9 +544,9 @@ if ( !context || typeof context == 'undefined' ) { var args = $.makeArray( arguments ); // Dynamically setup core extensions for modules that are required -if ( args[0] == 'addModule' && typeof args[1] !== 'undefined' ) { +if ( args[0] === 'addModule' && typeof args[1] !== 'undefined' ) { var modules = args[1]; - if ( typeof modules !== "object" ) { + if ( typeof modules !== 'object' ) { modules = {}; modules[args[1]] = ''; } @@ -573,8 +578,8 @@ if ( args.length > 0 ) { } // Store the context for next time, and support chaining -return $(this).data( 'wikiEditor-context', context ); +return $( this ).data( 'wikiEditor-context', context ); }; -}( jQuery ) ); +}( jQuery, mediaWiki ) ); |