summaryrefslogtreecommitdiff
path: root/extensions/Vector/modules
diff options
context:
space:
mode:
Diffstat (limited to 'extensions/Vector/modules')
-rw-r--r--extensions/Vector/modules/ext.vector.collapsibleNav.css56
-rw-r--r--extensions/Vector/modules/ext.vector.collapsibleNav.js228
-rw-r--r--extensions/Vector/modules/ext.vector.collapsibleTabs.js123
-rw-r--r--extensions/Vector/modules/ext.vector.editWarning.js71
-rw-r--r--extensions/Vector/modules/ext.vector.expandableSearch.css9
-rw-r--r--extensions/Vector/modules/ext.vector.expandableSearch.js70
-rw-r--r--extensions/Vector/modules/ext.vector.footerCleanup.css87
-rw-r--r--extensions/Vector/modules/ext.vector.footerCleanup.js68
-rw-r--r--extensions/Vector/modules/ext.vector.sectionEditLinks.css15
-rw-r--r--extensions/Vector/modules/ext.vector.sectionEditLinks.js75
-rw-r--r--extensions/Vector/modules/ext.vector.simpleSearch.js130
-rw-r--r--extensions/Vector/modules/images/closed-ltr.pngbin0 -> 184 bytes
-rw-r--r--extensions/Vector/modules/images/closed-rtl.pngbin0 -> 942 bytes
-rw-r--r--extensions/Vector/modules/images/edit-faded.pngbin0 -> 546 bytes
-rw-r--r--extensions/Vector/modules/images/edit.pngbin0 -> 551 bytes
-rw-r--r--extensions/Vector/modules/images/open.pngbin0 -> 181 bytes
-rw-r--r--extensions/Vector/modules/images/portal-break.pngbin0 -> 242 bytes
17 files changed, 932 insertions, 0 deletions
diff --git a/extensions/Vector/modules/ext.vector.collapsibleNav.css b/extensions/Vector/modules/ext.vector.collapsibleNav.css
new file mode 100644
index 00000000..f11046c9
--- /dev/null
+++ b/extensions/Vector/modules/ext.vector.collapsibleNav.css
@@ -0,0 +1,56 @@
+/* Prototype code to show collapsing left nav options */
+#mw-panel.collapsible-nav div.portal {
+ /* @embed */
+ background-image:url(images/portal-break.png);
+ background-position:left top;
+ background-repeat:no-repeat;
+ padding: 0.25em 0 !important;
+ margin: -11px 9px 10px 11px;
+}
+#mw-panel.collapsible-nav div.portal h5 {
+ color: #4D4D4D;
+ font-weight: normal;
+ /* @embed */
+ background: url(images/open.png) left center no-repeat;
+ padding: 4px 0 3px 1.5em;
+ margin-bottom: 0px;
+}
+#mw-panel.collapsible-nav div.collapsed h5 {
+ color: #0645AD;
+ /* @embed */
+ background: url(images/closed-ltr.png) left center no-repeat;
+ margin-bottom: 0px;
+}
+#mw-panel.collapsible-nav div h5:hover {
+ cursor: pointer;
+ text-decoration: none;
+}
+#mw-panel.collapsible-nav div.collapsed h5:hover {
+ text-decoration: underline;
+}
+#mw-panel.collapsible-nav div.portal div.body {
+ background: none !important;
+ padding-top: 0px;
+ display: none;
+}
+#mw-panel.collapsible-nav div.persistent div.body {
+ display: block;
+}
+#mw-panel.collapsible-nav div.first h5 {
+ display: none;
+}
+#mw-panel.collapsible-nav div.persistent h5 {
+ background: none !important;
+ padding-left: 0.7em;
+ cursor: default;
+}
+#mw-panel.collapsible-nav div.portal div.body ul li {
+ padding: 0.25em 0;
+}
+#mw-panel.collapsible-nav div.first {
+ background-image: none;
+ margin-top: 0px;
+}
+#mw-panel.collapsible-nav div.persistent div.body {
+ margin-left: 0.5em;
+} \ No newline at end of file
diff --git a/extensions/Vector/modules/ext.vector.collapsibleNav.js b/extensions/Vector/modules/ext.vector.collapsibleNav.js
new file mode 100644
index 00000000..9a9b77f7
--- /dev/null
+++ b/extensions/Vector/modules/ext.vector.collapsibleNav.js
@@ -0,0 +1,228 @@
+/*
+ * Collapisble navigation for Vector
+ */
+( function( $ ) {
+
+ /* Browser Support */
+
+ var map = {
+ // Left-to-right languages
+ 'ltr': {
+ // Collapsible Nav is broken in Opera < 9.6 and Konqueror < 4
+ 'msie': [['>=', 7]],
+ 'opera': [['>=', 9.6]],
+ 'konqueror': [['>=', 4.0]],
+ 'blackberry': false,
+ 'ipod': false,
+ 'iphone': false,
+ 'ps3': false
+ },
+ // Right-to-left languages
+ 'rtl': {
+ 'msie': [['>=', 7]],
+ 'opera': [['>=', 9.6]],
+ 'konqueror': [['>=', 4.0]],
+ 'blackberry': false,
+ 'ipod': false,
+ 'iphone': false,
+ 'ps3': false
+ }
+ };
+ if ( !$.client.test( map ) ) {
+ return true;
+ }
+
+ /* Bucket Testing */
+
+ // Fallback to old version
+ var version = 1;
+ // Allow new version override
+ if ( mediaWiki.config.get( 'wgCollapsibleNavForceNewVersion' ) ) {
+ version = 2;
+ } else {
+ // Make bucket testing optional
+ if ( mediaWiki.config.get( 'wgCollapsibleNavBucketTest' ) ) {
+ // This is be determined randomly, and then stored in a cookie
+ version = $.cookie( 'vector-nav-pref-version' );
+ // If the cookie didn't exist, or the value is out of range, generate a new one and save it
+ if ( version == null ) {
+ // 50% of the people will get the new version
+ version = Math.round( Math.random() + 1 );
+ $.cookie( 'vector-nav-pref-version', version, { 'expires': 30, 'path': '/' } );
+ }
+ }
+ }
+
+ /* Special Language Portal Handling */
+
+ // Language portal splitting feature (if it's turned on)
+ if ( version == 2 ) {
+ // How many links to show in the primary languages portal
+ var limit = 5;
+ // How many links there must be in the secondary portal to justify having a secondary portal
+ var threshold = 3;
+ // Make the interwiki language links list a secondary list, and create a new list before it as primary list
+ $( '#p-lang ul' ).addClass( 'secondary' ).before( '<ul class="primary"></ul>' );
+ // This is a list of languages in order of Wikipedia project size. This is the lowest fallback for choosing
+ // which links to show in the primary list. Ideally the browser's accept-language headers should steer this
+ // list, and we should fallback on a site configured (MediaWiki:Common.js) list of prefered languages.
+ var languages = [
+ 'en', 'fr', 'de', 'es', 'pt', 'it', 'ru', 'ja', 'nl', 'pl', 'zh', 'sv', 'ar', 'tr', 'uk', 'fi', 'no', 'ca',
+ 'ro', 'hu', 'ksh', 'id', 'he', 'cs', 'vi', 'ko', 'sr', 'fa', 'da', 'eo', 'sk', 'th', 'lt', 'vo', 'bg',
+ 'sl', 'hr', 'hi', 'et', 'mk', 'simple', 'new', 'ms', 'nn', 'gl', 'el', 'eu', 'ka', 'tl', 'bn', 'lv', 'ml',
+ 'bs', 'te', 'la', 'az', 'sh', 'war', 'br', 'is', 'mr', 'be-x-old', 'sq', 'cy', 'lb', 'ta', 'zh-classical',
+ 'an', 'jv', 'ht', 'oc', 'bpy', 'ceb', 'ur', 'zh-yue', 'pms', 'scn', 'be', 'roa-rup', 'qu', 'af', 'sw',
+ 'nds', 'fy', 'lmo', 'wa', 'ku', 'hy', 'su', 'yi', 'io', 'os', 'ga', 'ast', 'nap', 'vec', 'gu', 'cv',
+ 'bat-smg', 'kn', 'uz', 'zh-min-nan', 'si', 'als', 'yo', 'li', 'gan', 'arz', 'sah', 'tt', 'bar', 'gd', 'tg',
+ 'kk', 'pam', 'hsb', 'roa-tara', 'nah', 'mn', 'vls', 'gv', 'mi', 'am', 'ia', 'co', 'ne', 'fo', 'nds-nl',
+ 'glk', 'mt', 'ang', 'wuu', 'dv', 'km', 'sco', 'bcl', 'mg', 'my', 'diq', 'tk', 'szl', 'ug', 'fiu-vro', 'sc',
+ 'rm', 'nrm', 'ps', 'nv', 'hif', 'bo', 'se', 'sa', 'pnb', 'map-bms', 'lad', 'lij', 'crh', 'fur', 'kw', 'to',
+ 'pa', 'jbo', 'ba', 'ilo', 'csb', 'wo', 'xal', 'krc', 'ckb', 'pag', 'ln', 'frp', 'mzn', 'ce', 'nov', 'kv',
+ 'eml', 'gn', 'ky', 'pdc', 'lo', 'haw', 'mhr', 'dsb', 'stq', 'tpi', 'arc', 'hak', 'ie', 'so', 'bh', 'ext',
+ 'mwl', 'sd', 'ig', 'myv', 'ay', 'iu', 'na', 'cu', 'pi', 'kl', 'ty', 'lbe', 'ab', 'got', 'sm', 'as', 'mo',
+ 'ee', 'zea', 'av', 'ace', 'kg', 'bm', 'cdo', 'cbk-zam', 'kab', 'om', 'chr', 'pap', 'udm', 'ks', 'zu', 'rmy',
+ 'cr', 'ch', 'st', 'ik', 'mdf', 'kaa', 'aa', 'fj', 'srn', 'tet', 'or', 'pnt', 'bug', 'ss', 'ts', 'pcd',
+ 'pih', 'za', 'sg', 'lg', 'bxr', 'xh', 'ak', 'ha', 'bi', 've', 'tn', 'ff', 'dz', 'ti', 'ki', 'ny', 'rw',
+ 'chy', 'tw', 'sn', 'tum', 'ng', 'rn', 'mh', 'ii', 'cho', 'hz', 'kr', 'ho', 'mus', 'kj'
+ ];
+ // If the user has an Accept-Language cookie, use it. Otherwise, set it asynchronously but keep the default
+ // behavior for this page view.
+ var acceptLangCookie = $.cookie( 'accept-language' );
+ if ( acceptLangCookie != null ) {
+ // Put the user's accepted languages before the list ordered by wiki size
+ if ( acceptLangCookie != '' ) {
+ languages = acceptLangCookie.split( ',' ).concat( languages );
+ }
+ } else {
+ $.getJSON(
+ wgScriptPath + '/api.php?action=query&meta=userinfo&uiprop=acceptlang&format=json',
+ function( data ) {
+ var langs = [];
+ if (
+ typeof data.query != 'undefined' &&
+ typeof data.query.userinfo != 'undefined' &&
+ typeof data.query.userinfo.acceptlang != 'undefined'
+ ) {
+ for ( var j = 0; j < data.query.userinfo.acceptlang.length; j++ ) {
+ if ( data.query.userinfo.acceptlang[j].q != 0 ) {
+ langs.push( data.query.userinfo.acceptlang[j]['*'] );
+ }
+ }
+ }
+ $.cookie( 'accept-language', langs.join( ',' ), { 'path': '/', 'expires': 30 } );
+ }
+ );
+ }
+ // Shortcuts to the two lists
+ var $primary = $( '#p-lang ul.primary' );
+ var $secondary = $( '#p-lang ul.secondary' );
+ // Adjust the limit based on the threshold
+ if ( $secondary.children().length < limit + threshold ) {
+ limit += threshold;
+ }
+ // Move up to 5 of the links into the primary list, based on the priorities set forth in the languages list
+ var count = 0;
+ for ( var i = 0; i < languages.length; i++ ) {
+ var $link = $secondary.find( '.interwiki-' + languages[i] );
+ if ( $link.length ) {
+ if ( count++ < limit ) {
+ $link.appendTo( $primary );
+ } else {
+ break;
+ }
+ }
+ }
+ // If there's still links in the secondary list and we havn't filled the primary list to it's limit yet, move
+ // links into the primary list in order of appearance
+ if ( count < limit ) {
+ $secondary.children().each( function() {
+ if ( count++ < limit ) {
+ $(this).appendTo( $primary );
+ } else {
+ return false;
+ }
+ } );
+ }
+ // Hide the more portal if it's now empty, otherwise make the list into it's very own portal
+ if ( $secondary.children().length == 0 ) {
+ $secondary.remove();
+ } else {
+ $( '#p-lang' ).after( '<div id="p-lang-more" class="portal"><h5></h5><div class="body"></div></div>' );
+ $( '#p-lang-more h5' ).text( mw.usability.getMsg( 'vector-collapsiblenav-more' ) );
+ $secondary.appendTo( $( '#p-lang-more div.body' ) );
+ }
+ // Always show the primary interwiki language portal
+ $( '#p-lang' ).addClass( 'persistent' );
+ }
+
+ /* General Portal Modification */
+
+ // Always show the first portal
+ $( '#mw-panel > div.portal:first' ).addClass( 'first persistent' );
+ // Apply a class to the entire panel to activate styles
+ $( '#mw-panel' ).addClass( 'collapsible-nav' );
+ // Use cookie data to restore preferences of what to show and hide
+ $( '#mw-panel > div.portal:not(.persistent)' )
+ .each( function( i ) {
+ var id = $(this).attr( 'id' );
+ var state = $.cookie( 'vector-nav-' + id );
+ // In the case that we are not showing the new version, let's show the languages by default
+ if (
+ state == 'true' ||
+ ( state == null && i < 1 ) ||
+ ( state == null && version == 1 && id == 'p-lang' )
+ ) {
+ $(this)
+ .addClass( 'expanded' )
+ .find( 'div.body' )
+ .show();
+ } else {
+ $(this).addClass( 'collapsed' );
+ }
+ // Re-save cookie
+ if ( state != null ) {
+ $.cookie( 'vector-nav-' + $(this).attr( 'id' ), state, { 'expires': 30, 'path': '/' } );
+ }
+ } );
+ // Use the same function for all navigation headings - don't repeat yourself
+ function toggle( $element ) {
+ $.cookie(
+ 'vector-nav-' + $element.parent().attr( 'id' ),
+ $element.parent().is( '.collapsed' ),
+ { 'expires': 30, 'path': '/' }
+ );
+ $element
+ .parent()
+ .toggleClass( 'expanded' )
+ .toggleClass( 'collapsed' )
+ .find( 'div.body' )
+ .slideToggle( 'fast' );
+ }
+
+ /* Tab Indexing */
+
+ var $headings = $( '#mw-panel > div.portal:not(.persistent) > h5' );
+ // Get the highest tab index
+ var tabIndex = $( document ).lastTabIndex() + 1;
+ // Fix the search not having a tabindex
+ $( '#searchInput' ).attr( 'tabindex', tabIndex++ );
+ // Make it keyboard accessible
+ $headings.each( function() {
+ $(this).attr( 'tabindex', tabIndex++ );
+ } );
+ // Toggle the selected menu's class and expand or collapse the menu
+ $( '#mw-panel' )
+ .delegate( 'div.portal:not(.persistent) > h5', 'keydown', function( event ) {
+ // Make the space and enter keys act as a click
+ if ( event.which == 13 /* Enter */ || event.which == 32 /* Space */ ) {
+ toggle( $(this) );
+ }
+ } )
+ .delegate( 'div.portal:not(.persistent) > h5', 'mousedown', function( event ) {
+ if ( event.which != 3 ) { // Right mouse click
+ toggle( $(this) );
+ $(this).blur();
+ }
+ return false;
+ } );
+} )( jQuery );
diff --git a/extensions/Vector/modules/ext.vector.collapsibleTabs.js b/extensions/Vector/modules/ext.vector.collapsibleTabs.js
new file mode 100644
index 00000000..fb0681e7
--- /dev/null
+++ b/extensions/Vector/modules/ext.vector.collapsibleTabs.js
@@ -0,0 +1,123 @@
+/*
+ * Collapsible tabs for Vector
+ */
+jQuery(function( $ ) {
+ var rtl = $( 'body' ).is( '.rtl' );
+
+ // Overloading the moveToCollapsed function to animate the transition
+ $.collapsibleTabs.moveToCollapsed = function( ele ) {
+ var $moving = $( ele );
+
+ //$.collapsibleTabs.getSettings( $( $.collapsibleTabs.getSettings( $moving ).expandedContainer ) ).shifting = true;
+ // Do the above, except with guards for JS errors
+ var data = $.collapsibleTabs.getSettings( $moving );
+ if ( !data ) {
+ return;
+ }
+ var expContainerSettings = $.collapsibleTabs.getSettings( $( data.expandedContainer ) );
+ if ( !expContainerSettings ) {
+ return;
+ }
+ expContainerSettings.shifting = true;
+
+ // Remove the element from where it's at and put it in the dropdown menu
+ var target = data.collapsedContainer;
+ $moving.css( "position", "relative" )
+ .css( ( rtl ? 'left' : 'right' ), 0 )
+ .animate( { width: '1px' }, "normal", function() {
+ $( this ).hide();
+ // add the placeholder
+ $( '<span class="placeholder" style="display:none;"></span>' ).insertAfter( this );
+ $( this ).detach().prependTo( target ).data( 'collapsibleTabsSettings', data );
+ $( this ).attr( 'style', 'display:list-item;' );
+ //$.collapsibleTabs.getSettings( $( $.collapsibleTabs.getSettings( $( ele ) ).expandedContainer ) )
+ // .shifting = false;
+ // Do the above, except with guards for JS errors
+ var data = $.collapsibleTabs.getSettings( $( ele ) );
+ if ( !data ) {
+ return;
+ }
+ var expContainerSettings = $.collapsibleTabs.getSettings( $( data.expandedContainer ) );
+ if ( !expContainerSettings ) {
+ return;
+ }
+ expContainerSettings.shifting = false;
+ $.collapsibleTabs.handleResize();
+ } );
+ };
+
+ // Overloading the moveToExpanded function to animate the transition
+ $.collapsibleTabs.moveToExpanded = function( ele ) {
+ var $moving = $( ele );
+ //$.collapsibleTabs.getSettings( $( $.collapsibleTabs.getSettings( $moving ).expandedContainer ) ).shifting = true;
+ // Do the above, except with guards for JS errors
+ var data = $.collapsibleTabs.getSettings( $moving );
+ if ( !data ) {
+ return;
+ }
+ var expContainerSettings = $.collapsibleTabs.getSettings( $( data.expandedContainer ) );
+ if ( !expContainerSettings ) {
+ return;
+ }
+ expContainerSettings.shifting = true;
+
+ // grab the next appearing placeholder so we can use it for replacing
+ var $target = $( data.expandedContainer ).find( 'span.placeholder:first' );
+ var expandedWidth = data.expandedWidth;
+ $moving.css( "position", "relative" ).css( ( rtl ? 'right' : 'left' ), 0 ).css( 'width', '1px' );
+ $target.replaceWith( $moving.detach().css( 'width', '1px' ).data( 'collapsibleTabsSettings', data )
+ .animate( { width: expandedWidth+"px" }, "normal", function( ) {
+ $( this ).attr( 'style', 'display:block;' );
+ //$.collapsibleTabs.getSettings( $( $.collapsibleTabs.getSettings( $( ele ) ).expandedContainer ) )
+ // .shifting = false;
+ // Do the above, except with guards for JS errors
+ var data = $.collapsibleTabs.getSettings( $( this ) );
+ if ( !data ) {
+ return;
+ }
+ var expContainerSettings = $.collapsibleTabs.getSettings( $( data.expandedContainer ) );
+ if ( !expContainerSettings ) {
+ return;
+ }
+ expContainerSettings.shifting = false;
+ $.collapsibleTabs.handleResize();
+ } ) );
+ };
+
+ // Bind callback functions to animate our drop down menu in and out
+ // and then call the collapsibleTabs function on the menu
+ $( '#p-views ul' ).bind( 'beforeTabCollapse', function() {
+ if ( $( '#p-cactions' ).css( 'display' ) == 'none' ) {
+ $( '#p-cactions' )
+ .addClass( 'filledPortlet' ).removeClass( 'emptyPortlet' )
+ .find( 'h5' )
+ .css( 'width','1px' ).animate( { 'width':'26px' }, 390 );
+ }
+ } ).bind( 'beforeTabExpand', function() {
+ if ( $( '#p-cactions li' ).length == 1 ) {
+ $( '#p-cactions h5' ).animate( { 'width':'1px' }, 370, function() {
+ $( this ).attr( 'style', '' )
+ .parent().addClass( 'emptyPortlet' ).removeClass( 'filledPortlet' );
+ });
+ }
+ } ).collapsibleTabs( {
+ expandCondition: function( eleWidth ) {
+ if( rtl ){
+ return ( $( '#right-navigation' ).position().left + $( '#right-navigation' ).width() + 1 )
+ < ( $( '#left-navigation' ).position().left - eleWidth );
+ } else {
+ return ( $( '#left-navigation' ).position().left + $( '#left-navigation' ).width() + 1 )
+ < ( $( '#right-navigation' ).position().left - eleWidth );
+ }
+ },
+ collapseCondition: function() {
+ if( rtl ) {
+ return ( $( '#right-navigation' ).position().left + $( '#right-navigation' ).width() )
+ > $( '#left-navigation' ).position().left;
+ } else {
+ return ( $( '#left-navigation' ).position().left + $( '#left-navigation' ).width() )
+ > $( '#right-navigation' ).position().left;
+ }
+ }
+ } );
+} );
diff --git a/extensions/Vector/modules/ext.vector.editWarning.js b/extensions/Vector/modules/ext.vector.editWarning.js
new file mode 100644
index 00000000..d7494c70
--- /dev/null
+++ b/extensions/Vector/modules/ext.vector.editWarning.js
@@ -0,0 +1,71 @@
+/*
+ * Edit warning for Vector
+ */
+(function( $ ) {
+ $(document).ready( function() {
+ // Check if EditWarning is enabled and if we need it
+ if ( $( '#wpTextbox1' ).size() == 0 ) {
+ return true;
+ }
+ // Get the original values of some form elements
+ $( '#wpTextbox1, #wpSummary' ).each( function() {
+ $(this).data( 'origtext', $(this).val() );
+ });
+ // Attach our own handler for onbeforeunload which respects the current one
+ var fallbackWindowOnBeforeUnload = window.onbeforeunload;
+ var ourWindowOnBeforeUnload = function() {
+ var fallbackResult = undefined;
+ var retval = undefined;
+ var thisFunc = arguments.callee;
+ // Check if someone already set on onbeforeunload hook
+ if ( fallbackWindowOnBeforeUnload ) {
+ // Get the result of their onbeforeunload hook
+ fallbackResult = fallbackWindowOnBeforeUnload();
+ }
+ // Check if their onbeforeunload hook returned something
+ if ( fallbackResult !== undefined ) {
+ // Exit here, returning their message
+ retval = fallbackResult;
+ } else {
+ // Check if the current values of some form elements are the same as
+ // the original values
+ if (
+ wgAction == 'submit' ||
+ $( '#wpTextbox1' ).data( 'origtext' ) != $( '#wpTextbox1' ).val() ||
+ $( '#wpSummary' ).data( 'origtext' ) != $( '#wpSummary' ).val()
+ ) {
+ // Return our message
+ retval = mediaWiki.msg( 'vector-editwarning-warning' );
+ }
+ }
+
+ // Unset the onbeforeunload handler so we don't break page caching in Firefox
+ window.onbeforeunload = null;
+ if ( retval !== undefined ) {
+ // ...but if the user chooses not to leave the page, we need to rebind it
+ setTimeout( function() {
+ window.onbeforeunload = thisFunc;
+ } );
+ return retval;
+ }
+ };
+ var pageShowHandler = function() {
+ // Re-add onbeforeunload handler
+ window.onbeforeunload = ourWindowOnBeforeUnload;
+ };
+ pageShowHandler();
+ if ( window.addEventListener ) {
+ window.addEventListener('pageshow', pageShowHandler, false);
+ } else if ( window.attachEvent ) {
+ window.attachEvent( 'pageshow', pageShowHandler );
+ }
+
+ // Add form submission handler
+ $( 'form' ).submit( function() {
+ // Restore whatever previous onbeforeload hook existed
+ window.onbeforeunload = fallbackWindowOnBeforeUnload;
+ });
+ });
+ //Global storage of fallback for onbeforeunload hook
+ var fallbackWindowOnBeforeUnload = null;
+})( jQuery );
diff --git a/extensions/Vector/modules/ext.vector.expandableSearch.css b/extensions/Vector/modules/ext.vector.expandableSearch.css
new file mode 100644
index 00000000..be679b4c
--- /dev/null
+++ b/extensions/Vector/modules/ext.vector.expandableSearch.css
@@ -0,0 +1,9 @@
+.expandableField {
+ display: block;
+}
+#simpleSearch {
+ overflow: auto;
+}
+#searchButton {
+ margin-top: 0.2em !important;
+} \ No newline at end of file
diff --git a/extensions/Vector/modules/ext.vector.expandableSearch.js b/extensions/Vector/modules/ext.vector.expandableSearch.js
new file mode 100644
index 00000000..850ff74f
--- /dev/null
+++ b/extensions/Vector/modules/ext.vector.expandableSearch.js
@@ -0,0 +1,70 @@
+/*
+ * Expandable search for Vector
+ */
+$( document ).ready( function() {
+
+ /* Browser Support */
+
+ var map = {
+ // Left-to-right languages
+ 'ltr': {
+ // Collapsible Nav is broken in Opera < 9.6 and Konqueror < 4
+ 'msie': [['>=', 8]],
+ 'blackberry': false,
+ 'ipod': false,
+ 'iphone': false,
+ 'ps3': false
+ },
+ // Right-to-left languages
+ 'rtl': {
+ 'msie': [['>=', 8]],
+ 'blackberry': false,
+ 'ipod': false,
+ 'iphone': false,
+ 'ps3': false
+ }
+ };
+ if ( !$.client.test( map ) ) {
+ return true;
+ }
+
+ $( '#searchInput' )
+ .expandableField( {
+ 'beforeExpand': function( context ) {
+ // animate the containers border
+ $( this )
+ .parent()
+ .animate( {
+ 'borderTopColor': '#a0d8ff',
+ 'borderLeftColor': '#a0d8ff',
+ 'borderRightColor': '#a0d8ff',
+ 'borderBottomColor': '#a0d8ff' }, 'fast' );
+ },
+ 'beforeCondense': function( context ) {
+ // animate the containers border
+ $( this )
+ .parent()
+ .animate( {
+ 'borderTopColor': '#aaaaaa',
+ 'borderLeftColor': '#aaaaaa',
+ 'borderRightColor': '#aaaaaa',
+ 'borderBottomColor': '#aaaaaa' }, 'fast' );
+ },
+ 'afterExpand': function( context ) {
+ //trigger the collapsible tabs resize handler
+ if ( typeof $.collapsibleTabs != 'undefined' ){
+ $.collapsibleTabs.handleResize();
+ }
+ },
+ 'afterCondense': function( context ) {
+ //trigger the collapsible tabs resize handler
+ if ( typeof $.collapsibleTabs != 'undefined' ){
+ $.collapsibleTabs.handleResize();
+ }
+ },
+ 'expandToLeft': ! $( 'body' ).is( '.rtl' )
+ } )
+ .css( 'float', $( 'body' ).is( '.rtl' ) ? 'right' : 'left' )
+ .siblings( 'button' )
+ .css( 'float', $( 'body' ).is( '.rtl' ) ? 'right' : 'left' );
+} );
diff --git a/extensions/Vector/modules/ext.vector.footerCleanup.css b/extensions/Vector/modules/ext.vector.footerCleanup.css
new file mode 100644
index 00000000..ab951df6
--- /dev/null
+++ b/extensions/Vector/modules/ext.vector.footerCleanup.css
@@ -0,0 +1,87 @@
+/* Prototype code to show collapsing left nav options */
+#editpage-bottom {
+ background-color: #F3F3F3;
+ border: 1px solid silver;
+ border-top: none;
+ padding: 20px 170px 20px 170px;
+ margin-right: -2px;
+}
+
+#editpage-bottom input.inline-hint {
+ color: #999999;
+ font-style: italic;
+}
+.collapsible-list {
+ border-top: 1px solid silver;
+ border-bottom: 1px solid silver;
+}
+.collapsible-list {
+ border-top: 1px solid silver;
+ border-bottom: 1px solid silver;
+ padding: 3px 2px;
+}
+.collapsible-list ul {
+ display: block;
+ padding: 0 0 0 14px;
+}
+.collapsible-list.collapsed label {
+ /* @embed */
+ background: url(../images/vector/collapsibleNav/arrow-down.png?1) 0 50% no-repeat;
+ padding: 4px 0 3px 1.5em;
+ margin-bottom: 0px;
+}
+.collapsible-list.expanded label {
+ /* @embed */
+ background: url(../images/vector/collapsibleNav/arrow-right.png?1) 0 50% no-repeat;
+ padding: 4px 0 3px 1.5em;
+ margin-bottom: 0px;
+}
+
+#editpage-bottom .editOptions {
+ width: 100%;
+}
+#editpage-bottom #wpSummaryLabel,
+#editpage-bottom #editpage-summary-fields,
+#editpage-bottom .editButtons {
+ float: left;
+}
+#editpage-bottom #wpSummaryLabel{
+ width: 150px;
+ margin-left: -150px;
+ position: relative;
+}
+#editpage-bottom #editpage-summary-fields {
+ width: 100%;
+ margin-right: -100%;
+}
+#editpage-bottom #editpage-summary-fields input.mw-summary {
+ width: 95%;
+}
+#editpage-bottom .editButtons {
+ width: 150px;
+ margin-right: -150px;
+ float: right;
+ position: relative;
+}
+#editpage-bottom #editpage-copywarn {
+ margin-left: -150px;
+ margin-right: 10px;
+}
+/* Why don't we use self clearing floats anywhere? */
+
+#editpage-bottom .editOptions:after {
+ content: ".";
+ display: block;
+ height: 0;
+ clear: both;
+ visibility: hidden;
+}
+#editpage-bottom .editOptions {
+ display: inline-block;
+}
+* html #editpage-bottom .editOptions {
+ height: 1%;
+}
+#editpage-bottom .editOptions {
+ display:block;
+} \ No newline at end of file
diff --git a/extensions/Vector/modules/ext.vector.footerCleanup.js b/extensions/Vector/modules/ext.vector.footerCleanup.js
new file mode 100644
index 00000000..eb9b3dd2
--- /dev/null
+++ b/extensions/Vector/modules/ext.vector.footerCleanup.js
@@ -0,0 +1,68 @@
+/*
+ * Footer cleanup for Vector
+ */
+$( document ).ready( function() {
+ $( '#editpage-copywarn' )
+ .add( '.editOptions' )
+ .wrapAll( '<div id="editpage-bottom"></div>' );
+ $( '#wpSummary' )
+ .data( 'hint',
+ $( '#wpSummaryLabel span small' )
+ .remove()
+ .text()
+ // FIXME - Not a long-term solution. This change should be done in the message itself
+ .replace( /\)|\(/g, '' )
+ )
+ .change( function() {
+ if ( $( this ).val().length == 0 ) {
+ $( this )
+ .addClass( 'inline-hint' )
+ .val( $( this ).data( 'hint' ) );
+ } else {
+ $( this ).removeClass( 'inline-hint' );
+ }
+ } )
+ .focus( function() {
+ if ( $( this ).val() == $( this ).data( 'hint' ) ) {
+ $( this )
+ .removeClass( 'inline-hint' )
+ .val( "" );
+ }
+ })
+ .blur( function() { $( this ).trigger( 'change' ); } )
+ .trigger( 'change' );
+ $( '#wpSummary' )
+ .add( '.editCheckboxes' )
+ .wrapAll( '<div id="editpage-summary-fields"></div>' );
+
+ $( '#editpage-specialchars' ).remove();
+
+ // transclusions
+ // FIXME - bad CSS styling here with double class selectors. Should address here.
+ var transclusionCount = $( '.templatesUsed ul li' ).size();
+ $( '.templatesUsed ul' )
+ .wrap( '<div id="transclusions-list" class="collapsible-list collapsed"></div>' )
+ .parent()
+ // FIXME: i18n, remove link from message and let community add link to transclusion page if it exists
+ .prepend( '<label>This page contains <a href="http://en.wikipedia.org/wiki/transclusion">transclusions</a> of <strong>'
+ + transclusionCount
+ + '</strong> other pages.</label>' );
+ $( '.mw-templatesUsedExplanation' ).remove();
+
+ $( '.collapsible-list label' )
+ .click( function() {
+ $( this )
+ .parent()
+ .toggleClass( 'expanded' )
+ .toggleClass( 'collapsed' )
+ .find( 'ul' )
+ .slideToggle( 'fast' );
+ return false;
+ })
+ .trigger( 'click' );
+ $( '#wpPreview, #wpDiff, .editHelp, #editpage-specialchars' )
+ .remove();
+ $( '#mw-editform-cancel' )
+ .remove()
+ .appendTo( '.editButtons' );
+} );
diff --git a/extensions/Vector/modules/ext.vector.sectionEditLinks.css b/extensions/Vector/modules/ext.vector.sectionEditLinks.css
new file mode 100644
index 00000000..6c864001
--- /dev/null
+++ b/extensions/Vector/modules/ext.vector.sectionEditLinks.css
@@ -0,0 +1,15 @@
+span.vector-editLink {
+ float: none;
+ display: inline-block;
+}
+span.vector-editLink a {
+ padding-left: 18px;
+ /* @embed */
+ background-image: url(images/edit-faded.png);
+ background-position: left top;
+ background-repeat: no-repeat;
+}
+span.vector-editLink a:hover {
+ /* @embed */
+ background-image: url(images/edit.png);
+}
diff --git a/extensions/Vector/modules/ext.vector.sectionEditLinks.js b/extensions/Vector/modules/ext.vector.sectionEditLinks.js
new file mode 100644
index 00000000..94a154e9
--- /dev/null
+++ b/extensions/Vector/modules/ext.vector.sectionEditLinks.js
@@ -0,0 +1,75 @@
+/*
+ * Section Edit Links for Vector
+ */
+( function( $, mw ) {
+
+var eventBase = 'ext.vector.sectionEditLinks-bucket:';
+var cookieBase = 'ext.vector.sectionEditLinks-';
+
+if ( mw.config.get( 'wgVectorSectionEditLinksBucketTest', false ) ) {
+ // If the version in the client's cookie doesn't match wgVectorSectionEditLinksExperiment, then
+ // we need to disregard the bucket they may already be in to ensure accurate redistribution
+ var currentExperiment = $.cookie( cookieBase + 'experiment' );
+ var experiment = Number( mw.config.get( 'wgVectorSectionEditLinksExperiment', 0 ) );
+ var bucket = null;
+ if ( currentExperiment === null || Number( currentExperiment ) != experiment ) {
+ $.cookie( cookieBase + 'experiment', experiment );
+ } else {
+ bucket = $.cookie( cookieBase + 'bucket' );
+ }
+ if ( bucket === null ) {
+ // Percentage chance of being tracked
+ var odds = Math.min( 100, Math.max( 0,
+ Number( mw.config.get( 'wgVectorSectionEditLinksLotteryOdds', 0 ) )
+ ) );
+ // 0 = not tracked, 1 = tracked with old version, 2 = tracked with new version
+ bucket = ( Math.random() * 100 ) < odds ? Number( Math.random() < 0.5 ) + 1 : 0;
+ $.cookie( cookieBase + 'bucket', bucket, { 'path': '/', 'expires': 30 } );
+ // If we are going to track this person from now on, let's also track which bucket we put
+ // them into and when
+ if ( bucket > 0 && 'trackAction' in $ ) {
+ $.trackAction( eventBase + bucket + '@' + experiment );
+ }
+ }
+}
+if ( bucket > 0 ) {
+ // Transform the targets of section edit links to route through the click tracking API
+ var session = $.cookie( 'clicktracking-session' );
+ $( 'span.editsection a, #ca-edit a' ).each( function() {
+ var event = eventBase + bucket + '@' + experiment;
+ if ( $(this).is( '#ca-edit a' ) ) {
+ event += '-tab';
+ }
+ var href = $( this ).attr( 'href' );
+ var editUrl = href + ( href.indexOf( '?' ) >= 0 ? '&' : '?' ) + $.param( {
+ 'clicktrackingsession': session,
+ 'clicktrackingevent': event + '-save'
+ } );
+ $(this).attr( 'href', $.trackActionURL( editUrl, event + '-click' ) );
+ } );
+ if ( bucket == 2 ) {
+ // Move the link over to be next to the heading text and style it with an icon
+ $( 'span.mw-headline' ).each( function() {
+ $(this)
+ .after(
+ $( '<span class="editsection vector-editLink"></span>' )
+ .append(
+ $(this)
+ .prev( 'span.editsection' )
+ .find( 'a' )
+ .each( function() {
+ var text = $(this).text();
+ $(this).text(
+ text.substr( 0, 1 ).toUpperCase() + text.substr( 1 )
+ );
+ } )
+ .detach()
+ )
+ )
+ .prev( 'span.editsection' )
+ .remove();
+ } );
+ }
+}
+
+} )( jQuery, mediaWiki );
diff --git a/extensions/Vector/modules/ext.vector.simpleSearch.js b/extensions/Vector/modules/ext.vector.simpleSearch.js
new file mode 100644
index 00000000..01ef14ea
--- /dev/null
+++ b/extensions/Vector/modules/ext.vector.simpleSearch.js
@@ -0,0 +1,130 @@
+/* JavaScript for SimpleSearch extension */
+
+jQuery( document ).ready( function( $ ) {
+
+ // Compatibility map
+ var map = {
+ 'browsers': {
+ // Left-to-right languages
+ 'ltr': {
+ // SimpleSearch is broken in Opera < 9.6
+ 'opera': [['>=', 9.6]],
+ 'docomo': false,
+ 'blackberry': false,
+ 'ipod': false,
+ 'iphone': false
+ },
+ // Right-to-left languages
+ 'rtl': {
+ 'opera': [['>=', 9.6]],
+ 'docomo': false,
+ 'blackberry': false,
+ 'ipod': false,
+ 'iphone': false
+ }
+ }
+ };
+ if ( !$.client.test( map ) ) {
+ return true;
+ }
+
+ // Disable MWSuggest if loaded
+ if ( window.os_MWSuggestDisable ) {
+ window.os_MWSuggestDisable();
+ }
+
+ // Placeholder text for SimpleSearch box
+ $( '#simpleSearch > input#searchInput' )
+ .attr( 'placeholder', mw.msg( 'vector-simplesearch-search' ) )
+ .placeholder();
+
+ // General suggestions functionality for all search boxes
+ $( '#searchInput, #searchInput2, #powerSearchText, #searchText' )
+ .suggestions( {
+ fetch: function( query ) {
+ var $this = $(this);
+ if ( query.length !== 0 ) {
+ var request = $.ajax( {
+ url: mw.util.wikiScript( 'api' ),
+ data: {
+ action: 'opensearch',
+ search: query,
+ namespace: 0,
+ suggest: ''
+ },
+ dataType: 'json',
+ success: function( data ) {
+ if ( $.isArray( data ) && 1 in data ) {
+ $this.suggestions( 'suggestions', data[1] );
+ }
+ }
+ });
+ $this.data( 'request', request );
+ }
+ },
+ cancel: function() {
+ var request = $(this).data( 'request' );
+ // If the delay setting has caused the fetch to have not even happend yet, the request object will
+ // have never been set
+ if ( request && $.isFunction( request.abort ) ) {
+ request.abort();
+ $(this).removeData( 'request' );
+ }
+ },
+ result: {
+ select: function( $input ) {
+ $input.closest( 'form' ).submit();
+ }
+ },
+ delay: 120,
+ positionFromLeft: $( 'body' ).hasClass( 'rtl' ),
+ highlightInput: true
+ } )
+ .bind( 'paste cut drop', function( e ) {
+ // make sure paste and cut events from the mouse and drag&drop events
+ // trigger the keypress handler and cause the suggestions to update
+ $( this ).trigger( 'keypress' );
+ } );
+ // Special suggestions functionality for skin-provided search box
+ $( '#searchInput' ).suggestions( {
+ result: {
+ select: function( $input ) {
+ $input.closest( 'form' ).submit();
+ }
+ },
+ special: {
+ render: function( query ) {
+ if ( $(this).children().length === 0 ) {
+ $(this).show();
+ var $label = $( '<div></div>', {
+ 'class': 'special-label',
+ text: mw.msg( 'vector-simplesearch-containing' )
+ })
+ .appendTo( $(this) );
+ var $query = $( '<div></div>', {
+ 'class': 'special-query',
+ text: query
+ })
+ .appendTo( $(this) );
+ $query.autoEllipsis();
+ } else {
+ $(this).find( '.special-query' )
+ .empty()
+ .text( query )
+ .autoEllipsis();
+ }
+ },
+ select: function( $input ) {
+ $input.closest( 'form' ).append(
+ $( '<input>', {
+ type: 'hidden',
+ name: 'fulltext',
+ val: '1'
+ })
+ );
+ $input.closest( 'form' ).submit();
+ }
+ },
+ $region: $( '#simpleSearch' )
+ } );
+}); \ No newline at end of file
diff --git a/extensions/Vector/modules/images/closed-ltr.png b/extensions/Vector/modules/images/closed-ltr.png
new file mode 100644
index 00000000..c27c9636
--- /dev/null
+++ b/extensions/Vector/modules/images/closed-ltr.png
Binary files differ
diff --git a/extensions/Vector/modules/images/closed-rtl.png b/extensions/Vector/modules/images/closed-rtl.png
new file mode 100644
index 00000000..be968a4a
--- /dev/null
+++ b/extensions/Vector/modules/images/closed-rtl.png
Binary files differ
diff --git a/extensions/Vector/modules/images/edit-faded.png b/extensions/Vector/modules/images/edit-faded.png
new file mode 100644
index 00000000..0f622e12
--- /dev/null
+++ b/extensions/Vector/modules/images/edit-faded.png
Binary files differ
diff --git a/extensions/Vector/modules/images/edit.png b/extensions/Vector/modules/images/edit.png
new file mode 100644
index 00000000..ec02a986
--- /dev/null
+++ b/extensions/Vector/modules/images/edit.png
Binary files differ
diff --git a/extensions/Vector/modules/images/open.png b/extensions/Vector/modules/images/open.png
new file mode 100644
index 00000000..bf2d4fb4
--- /dev/null
+++ b/extensions/Vector/modules/images/open.png
Binary files differ
diff --git a/extensions/Vector/modules/images/portal-break.png b/extensions/Vector/modules/images/portal-break.png
new file mode 100644
index 00000000..e81b5597
--- /dev/null
+++ b/extensions/Vector/modules/images/portal-break.png
Binary files differ