From 1f4182d20db6de0e13e09d068b341e2ab51f624f Mon Sep 17 00:00:00 2001 From: "James D. Forrester" Date: Mon, 28 Apr 2014 12:57:53 -0700 Subject: [PATCH] Update OOjs UI to v0.1.0-pre (b91660e612) New changes: db345e1 Add text config option to OO.ui.Element 47e272a Add aggregate method beaa3be Localisation updates from https://translatewiki.net. 32fef8b Follow-up I0eddaaed91: Fix mistake in class name 62df7aa Followup 32fef8b5ee247: actually fix event aggregation, unbreak toolgroup disabling e3a09eb Element: Make onDOMEvent fix focusout in addition to focusin cc33eb6 InputWidget: DOM property is 'readOnly', not 'readonly' 59e9a07 Localisation updates from https://translatewiki.net. c7109be build: Update jscs config and phase out deprecated jshint config 58c2862 Localisation updates from https://translatewiki.net. Change-Id: I3f0049f03eb443113246761c81a0175ecfd9a94e --- resources/lib/oojs-ui/i18n/sco.json | 2 +- resources/lib/oojs-ui/i18n/yi.json | 1 + resources/lib/oojs-ui/i18n/zh-hant.json | 9 +- resources/lib/oojs-ui/oojs-ui.js | 202 +++++++++++++++++------- resources/lib/oojs-ui/oojs-ui.svg.css | 4 +- 5 files changed, 151 insertions(+), 67 deletions(-) diff --git a/resources/lib/oojs-ui/i18n/sco.json b/resources/lib/oojs-ui/i18n/sco.json index 2dcb19827c..085f908a4e 100644 --- a/resources/lib/oojs-ui/i18n/sco.json +++ b/resources/lib/oojs-ui/i18n/sco.json @@ -7,6 +7,6 @@ "ooui-dialog-action-close": "Claise", "ooui-outline-control-move-down": "Muiv eetem doon", "ooui-outline-control-move-up": "Muiv eetem up", - "ooui-outline-control-remove": "Remuiv eitem", + "ooui-outline-control-remove": "Remuiv eetem", "ooui-toolbar-more": "Mair" } diff --git a/resources/lib/oojs-ui/i18n/yi.json b/resources/lib/oojs-ui/i18n/yi.json index 0eec396269..091dbaf298 100644 --- a/resources/lib/oojs-ui/i18n/yi.json +++ b/resources/lib/oojs-ui/i18n/yi.json @@ -9,5 +9,6 @@ "ooui-dialog-action-close": "שליסן", "ooui-outline-control-move-down": "רוקן עלעמענט אראפ", "ooui-outline-control-move-up": "רוקן עלעמענט ארויף", + "ooui-outline-control-remove": "אַראָפנעמען איינס", "ooui-toolbar-more": "נאך" } diff --git a/resources/lib/oojs-ui/i18n/zh-hant.json b/resources/lib/oojs-ui/i18n/zh-hant.json index da9bacc96c..56f5e6dead 100644 --- a/resources/lib/oojs-ui/i18n/zh-hant.json +++ b/resources/lib/oojs-ui/i18n/zh-hant.json @@ -12,12 +12,13 @@ "Shirayuki", "Simon Shek", "Spring Roll Conan", - "Waihorace" + "Waihorace", + "Cwlin0416" ] }, "ooui-dialog-action-close": "關閉", - "ooui-outline-control-move-down": "向下移項", - "ooui-outline-control-move-up": "向上移項", - "ooui-outline-control-remove": "移除項", + "ooui-outline-control-move-down": "項目下移", + "ooui-outline-control-move-up": "項目上移", + "ooui-outline-control-remove": "移除項目", "ooui-toolbar-more": "更多" } diff --git a/resources/lib/oojs-ui/oojs-ui.js b/resources/lib/oojs-ui/oojs-ui.js index ff11631179..60476d51a0 100644 --- a/resources/lib/oojs-ui/oojs-ui.js +++ b/resources/lib/oojs-ui/oojs-ui.js @@ -1,12 +1,12 @@ /*! - * OOjs UI v0.1.0-pre (0a7180f468) + * OOjs UI v0.1.0-pre (b91660e612) * https://www.mediawiki.org/wiki/OOjs_UI * * Copyright 2011–2014 OOjs Team and other contributors. * Released under the MIT license * http://oojs.mit-license.org * - * Date: Wed Apr 23 2014 18:05:30 GMT-0700 (PDT) + * Date: Mon Apr 28 2014 12:57:47 GMT-0700 (PDT) */ ( function ( OO ) { @@ -173,7 +173,8 @@ OO.ui.resolveMsg = function ( msg ) { * @param {Object} [config] Configuration options * @cfg {Function} [$] jQuery for the frame the widget is in * @cfg {string[]} [classes] CSS class names - * @cfg {jQuery} [$content] Content elements to append + * @cfg {string} [text] Text to insert + * @cfg {jQuery} [$content] Content elements to append (after text) */ OO.ui.Element = function OoUiElement( config ) { // Configuration initialization @@ -188,6 +189,9 @@ OO.ui.Element = function OoUiElement( config ) { if ( $.isArray( config.classes ) ) { this.$element.addClass( config.classes.join( ' ' ) ); } + if ( config.text ) { + this.$element.text( config.text ); + } if ( config.$content ) { this.$element.append( config.$content ); } @@ -612,32 +616,52 @@ OO.ui.Element.prototype.offDOMEvent = function ( event, callback ) { ( function () { // Static - var specialFocusin; - function handler( e ) { - jQuery.event.simulate( 'focusin', e.target, jQuery.event.fix( e ), /* bubble = */ true ); - } + // jQuery 1.8.3 has a bug with handling focusin/focusout events inside iframes. + // Firefox doesn't support focusin/focusout at all, so we listen for 'focus'/'blur' on the + // document, and simulate a 'focusin'/'focusout' event on the target element and make + // it bubble from there. + // + // - http://jsfiddle.net/sw3hr/ + // - http://bugs.jquery.com/ticket/14180 + // - https://github.com/jquery/jquery/commit/1cecf64e5aa4153 + function specialEvent( simulatedName, realName ) { + function handler( e ) { + jQuery.event.simulate( + simulatedName, + e.target, + jQuery.event.fix( e ), + /* bubble = */ true + ); + } - specialFocusin = { - setup: function () { - var doc = this.ownerDocument || this, - attaches = $.data( doc, 'ooui-focusin-attaches' ); - if ( !attaches ) { - doc.addEventListener( 'focus', handler, true ); - } - $.data( doc, 'ooui-focusin-attaches', ( attaches || 0 ) + 1 ); - }, - teardown: function () { - var doc = this.ownerDocument || this, - attaches = $.data( doc, 'ooui-focusin-attaches' ) - 1; - if ( !attaches ) { - doc.removeEventListener( 'focus', handler, true ); - $.removeData( doc, 'ooui-focusin-attaches' ); - } else { - $.data( doc, 'ooui-focusin-attaches', attaches ); + return { + setup: function () { + var doc = this.ownerDocument || this, + attaches = $.data( doc, 'ooui-' + simulatedName + '-attaches' ); + if ( !attaches ) { + doc.addEventListener( realName, handler, true ); + } + $.data( doc, 'ooui-' + simulatedName + '-attaches', ( attaches || 0 ) + 1 ); + }, + teardown: function () { + var doc = this.ownerDocument || this, + attaches = $.data( doc, 'ooui-' + simulatedName + '-attaches' ) - 1; + if ( !attaches ) { + doc.removeEventListener( realName, handler, true ); + $.removeData( doc, 'ooui-' + simulatedName + '-attaches' ); + } else { + $.data( doc, 'ooui-' + simulatedName + '-attaches', attaches ); + } } - } - }; + }; + } + + var hasOwn = Object.prototype.hasOwnProperty, + specialEvents = { + focusin: specialEvent( 'focusin', 'focus' ), + focusout: specialEvent( 'focusout', 'blur' ) + }; /** * Bind a handler for an event on a DOM element. @@ -654,25 +678,15 @@ OO.ui.Element.prototype.offDOMEvent = function ( event, callback ) { OO.ui.Element.onDOMEvent = function ( el, event, callback ) { var orig; - if ( event === 'focusin' ) { - // jQuery 1.8.3 has a bug with handling focusin events inside iframes. - // Firefox doesn't support focusin at all, so we listen for 'focus' on the - // document, and simulate a 'focusin' event on the target element and make - // it bubble from there. - // - // - http://jsfiddle.net/sw3hr/ - // - http://bugs.jquery.com/ticket/14180 - // - https://github.com/jquery/jquery/commit/1cecf64e5aa4153 - + if ( hasOwn.call( specialEvents, event ) ) { // Replace jQuery's override with our own - orig = $.event.special.focusin; - $.event.special.focusin = specialFocusin; + orig = $.event.special[event]; + $.event.special[event] = specialEvents[event]; $( el ).on( event, callback ); // Restore - $.event.special.focusin = orig; - + $.event.special[event] = orig; } else { $( el ).on( event, callback ); } @@ -688,11 +702,15 @@ OO.ui.Element.prototype.offDOMEvent = function ( event, callback ) { */ OO.ui.Element.offDOMEvent = function ( el, event, callback ) { var orig; - if ( event === 'focusin' ) { - orig = $.event.special.focusin; - $.event.special.focusin = specialFocusin; + if ( hasOwn.call( specialEvents, event ) ) { + // Replace jQuery's override with our own + orig = $.event.special[event]; + $.event.special[event] = specialEvents[event]; + $( el ).off( event, callback ); - $.event.special.focusin = orig; + + // Restore + $.event.special[event] = orig; } else { $( el ).off( event, callback ); } @@ -2206,7 +2224,6 @@ OO.ui.FlaggableElement.prototype.setFlags = function ( flags ) { * @constructor * @param {jQuery} $group Container node, assigned to #$group * @param {Object} [config] Configuration options - * @cfg {Object.} [aggregations] Events to aggregate, keyed by item event name */ OO.ui.GroupElement = function OoUiGroupElement( $group, config ) { // Configuration @@ -2216,8 +2233,7 @@ OO.ui.GroupElement = function OoUiGroupElement( $group, config ) { this.$group = $group; this.items = []; this.$items = this.$( [] ); - this.aggregate = !$.isEmptyObject( config.aggregations ); - this.aggregations = config.aggregations || {}; + this.aggregateItemEvents = {}; }; /* Methods */ @@ -2231,6 +2247,59 @@ OO.ui.GroupElement.prototype.getItems = function () { return this.items.slice( 0 ); }; +/** + * Add an aggregate item event. + * + * Aggregated events are listened to on each item and then emitted by the group under a new name, + * and with an additional leading parameter containing the item that emitted the original event. + * Other arguments that were emitted from the original event are passed through. + * + * @param {Object.} events Aggregate events emitted by group, keyed by item + * event, use null value to remove aggregation + * @throws {Error} If aggregation already exists + */ +OO.ui.GroupElement.prototype.aggregate = function ( events ) { + var i, len, item, add, remove, itemEvent, groupEvent; + + for ( itemEvent in events ) { + groupEvent = events[itemEvent]; + + // Remove existing aggregated event + if ( itemEvent in this.aggregateItemEvents ) { + // Don't allow duplicate aggregations + if ( groupEvent ) { + throw new Error( 'Duplicate item event aggregation for ' + itemEvent ); + } + // Remove event aggregation from existing items + for ( i = 0, len = this.items.length; i < len; i++ ) { + item = this.items[i]; + if ( item.connect && item.disconnect ) { + remove = {}; + remove[itemEvent] = [ 'emit', groupEvent, item ]; + item.disconnect( this, remove ); + } + } + // Prevent future items from aggregating event + delete this.aggregateItemEvents[itemEvent]; + } + + // Add new aggregate event + if ( groupEvent ) { + // Make future items aggregate event + this.aggregateItemEvents[itemEvent] = groupEvent; + // Add event aggregation to existing items + for ( i = 0, len = this.items.length; i < len; i++ ) { + item = this.items[i]; + if ( item.connect && item.disconnect ) { + add = {}; + add[itemEvent] = [ 'emit', groupEvent, item ]; + item.connect( this, add ); + } + } + } + } +}; + /** * Add items. * @@ -2255,10 +2324,10 @@ OO.ui.GroupElement.prototype.addItems = function ( items, index ) { } } // Add the item - if ( this.aggregate ) { + if ( item.connect && item.disconnect && !$.isEmptyObject( this.aggregateItemEvents ) ) { events = {}; - for ( event in this.aggregations ) { - events[event] = [ 'emit', this.aggregations[event], item ]; + for ( event in this.aggregateItemEvents ) { + events[event] = [ 'emit', this.aggregateItemEvents[event], item ]; } item.connect( this, events ); } @@ -2291,15 +2360,22 @@ OO.ui.GroupElement.prototype.addItems = function ( items, index ) { * @chainable */ OO.ui.GroupElement.prototype.removeItems = function ( items ) { - var i, len, item, index; + var i, len, item, index, remove, itemEvent; // Remove specific items for ( i = 0, len = items.length; i < len; i++ ) { item = items[i]; index = $.inArray( item, this.items ); if ( index !== -1 ) { - if ( this.aggregate ) { - item.disconnect( this ); + if ( + item.connect && item.disconnect && + !$.isEmptyObject( this.aggregateItemEvents ) + ) { + remove = {}; + if ( itemEvent in this.aggregateItemEvents ) { + remove[itemEvent] = [ 'emit', this.aggregateItemEvents[itemEvent], item ]; + } + item.disconnect( this, remove ); } item.setElementGroup( null ); this.items.splice( index, 1 ); @@ -2319,13 +2395,20 @@ OO.ui.GroupElement.prototype.removeItems = function ( items ) { * @chainable */ OO.ui.GroupElement.prototype.clearItems = function () { - var i, len, item; + var i, len, item, remove, itemEvent; // Remove all items for ( i = 0, len = this.items.length; i < len; i++ ) { item = this.items[i]; - if ( this.aggregate ) { - item.disconnect( this ); + if ( + item.connect && item.disconnect && + !$.isEmptyObject( this.aggregateItemEvents ) + ) { + remove = {}; + if ( itemEvent in this.aggregateItemEvents ) { + remove[itemEvent] = [ 'emit', this.aggregateItemEvents[itemEvent], item ]; + } + item.disconnect( this, remove ); } item.setElementGroup( null ); } @@ -3344,9 +3427,7 @@ OO.ui.ToolFactory.prototype.extract = function ( collection, used ) { */ OO.ui.ToolGroup = function OoUiToolGroup( toolbar, config ) { // Configuration initialization - config = $.extend( true, { - 'aggregations': { 'disable': 'itemDisable' } - }, config ); + config = config || {}; // Parent constructor OO.ui.ToolGroup.super.call( this, config ); @@ -3373,6 +3454,7 @@ OO.ui.ToolGroup = function OoUiToolGroup( toolbar, config ) { 'mouseout': OO.ui.bind( this.onMouseOut, this ) } ); this.toolbar.getToolFactory().connect( this, { 'register': 'onToolFactoryRegister' } ); + this.aggregate( { 'disable': 'itemDisable' } ); this.connect( this, { 'itemDisable': 'updateDisabled' } ); // Initialization @@ -5464,7 +5546,7 @@ OO.ui.InputWidget.prototype.isReadOnly = function () { */ OO.ui.InputWidget.prototype.setReadOnly = function ( state ) { this.readOnly = !!state; - this.$input.prop( 'readonly', this.readOnly ); + this.$input.prop( 'readOnly', this.readOnly ); return this; }; diff --git a/resources/lib/oojs-ui/oojs-ui.svg.css b/resources/lib/oojs-ui/oojs-ui.svg.css index 1dbb09813c..321f3f8374 100644 --- a/resources/lib/oojs-ui/oojs-ui.svg.css +++ b/resources/lib/oojs-ui/oojs-ui.svg.css @@ -1,12 +1,12 @@ /*! - * OOjs UI v0.1.0-pre (0a7180f468) + * OOjs UI v0.1.0-pre (b91660e612) * https://www.mediawiki.org/wiki/OOjs_UI * * Copyright 2011–2014 OOjs Team and other contributors. * Released under the MIT license * http://oojs.mit-license.org * - * Date: Wed Apr 23 2014 18:05:30 GMT-0700 (PDT) + * Date: Mon Apr 28 2014 12:57:47 GMT-0700 (PDT) */ /* Textures */ -- 2.20.1