diff options
Diffstat (limited to 'vendor/oojs/oojs-ui/src/layouts/BookletLayout.js')
-rw-r--r-- | vendor/oojs/oojs-ui/src/layouts/BookletLayout.js | 542 |
1 files changed, 0 insertions, 542 deletions
diff --git a/vendor/oojs/oojs-ui/src/layouts/BookletLayout.js b/vendor/oojs/oojs-ui/src/layouts/BookletLayout.js deleted file mode 100644 index eebf57d6..00000000 --- a/vendor/oojs/oojs-ui/src/layouts/BookletLayout.js +++ /dev/null @@ -1,542 +0,0 @@ -/** - * BookletLayouts contain {@link OO.ui.PageLayout page layouts} as well as - * an {@link OO.ui.OutlineSelectWidget outline} that allows users to easily navigate - * through the pages and select which one to display. By default, only one page is - * displayed at a time and the outline is hidden. When a user navigates to a new page, - * the booklet layout automatically focuses on the first focusable element, unless the - * default setting is changed. Optionally, booklets can be configured to show - * {@link OO.ui.OutlineControlsWidget controls} for adding, moving, and removing items. - * - * @example - * // Example of a BookletLayout that contains two PageLayouts. - * - * function PageOneLayout( name, config ) { - * PageOneLayout.super.call( this, name, config ); - * this.$element.append( '<p>First page</p><p>(This booklet has an outline, displayed on the left)</p>' ); - * } - * OO.inheritClass( PageOneLayout, OO.ui.PageLayout ); - * PageOneLayout.prototype.setupOutlineItem = function () { - * this.outlineItem.setLabel( 'Page One' ); - * }; - * - * function PageTwoLayout( name, config ) { - * PageTwoLayout.super.call( this, name, config ); - * this.$element.append( '<p>Second page</p>' ); - * } - * OO.inheritClass( PageTwoLayout, OO.ui.PageLayout ); - * PageTwoLayout.prototype.setupOutlineItem = function () { - * this.outlineItem.setLabel( 'Page Two' ); - * }; - * - * var page1 = new PageOneLayout( 'one' ), - * page2 = new PageTwoLayout( 'two' ); - * - * var booklet = new OO.ui.BookletLayout( { - * outlined: true - * } ); - * - * booklet.addPages ( [ page1, page2 ] ); - * $( 'body' ).append( booklet.$element ); - * - * @class - * @extends OO.ui.MenuLayout - * - * @constructor - * @param {Object} [config] Configuration options - * @cfg {boolean} [continuous=false] Show all pages, one after another - * @cfg {boolean} [autoFocus=true] Focus on the first focusable element when a new page is displayed. - * @cfg {boolean} [outlined=false] Show the outline. The outline is used to navigate through the pages of the booklet. - * @cfg {boolean} [editable=false] Show controls for adding, removing and reordering pages - */ -OO.ui.BookletLayout = function OoUiBookletLayout( config ) { - // Configuration initialization - config = config || {}; - - // Parent constructor - OO.ui.BookletLayout.super.call( this, config ); - - // Properties - this.currentPageName = null; - this.pages = {}; - this.ignoreFocus = false; - this.stackLayout = new OO.ui.StackLayout( { continuous: !!config.continuous } ); - this.$content.append( this.stackLayout.$element ); - this.autoFocus = config.autoFocus === undefined || !!config.autoFocus; - this.outlineVisible = false; - this.outlined = !!config.outlined; - if ( this.outlined ) { - this.editable = !!config.editable; - this.outlineControlsWidget = null; - this.outlineSelectWidget = new OO.ui.OutlineSelectWidget(); - this.outlinePanel = new OO.ui.PanelLayout( { scrollable: true } ); - this.$menu.append( this.outlinePanel.$element ); - this.outlineVisible = true; - if ( this.editable ) { - this.outlineControlsWidget = new OO.ui.OutlineControlsWidget( - this.outlineSelectWidget - ); - } - } - this.toggleMenu( this.outlined ); - - // Events - this.stackLayout.connect( this, { set: 'onStackLayoutSet' } ); - if ( this.outlined ) { - this.outlineSelectWidget.connect( this, { select: 'onOutlineSelectWidgetSelect' } ); - } - if ( this.autoFocus ) { - // Event 'focus' does not bubble, but 'focusin' does - this.stackLayout.$element.on( 'focusin', this.onStackLayoutFocus.bind( this ) ); - } - - // Initialization - this.$element.addClass( 'oo-ui-bookletLayout' ); - this.stackLayout.$element.addClass( 'oo-ui-bookletLayout-stackLayout' ); - if ( this.outlined ) { - this.outlinePanel.$element - .addClass( 'oo-ui-bookletLayout-outlinePanel' ) - .append( this.outlineSelectWidget.$element ); - if ( this.editable ) { - this.outlinePanel.$element - .addClass( 'oo-ui-bookletLayout-outlinePanel-editable' ) - .append( this.outlineControlsWidget.$element ); - } - } -}; - -/* Setup */ - -OO.inheritClass( OO.ui.BookletLayout, OO.ui.MenuLayout ); - -/* Events */ - -/** - * A 'set' event is emitted when a page is {@link #setPage set} to be displayed by the booklet layout. - * @event set - * @param {OO.ui.PageLayout} page Current page - */ - -/** - * An 'add' event is emitted when pages are {@link #addPages added} to the booklet layout. - * - * @event add - * @param {OO.ui.PageLayout[]} page Added pages - * @param {number} index Index pages were added at - */ - -/** - * A 'remove' event is emitted when pages are {@link #clearPages cleared} or - * {@link #removePages removed} from the booklet. - * - * @event remove - * @param {OO.ui.PageLayout[]} pages Removed pages - */ - -/* Methods */ - -/** - * Handle stack layout focus. - * - * @private - * @param {jQuery.Event} e Focusin event - */ -OO.ui.BookletLayout.prototype.onStackLayoutFocus = function ( e ) { - var name, $target; - - // Find the page that an element was focused within - $target = $( e.target ).closest( '.oo-ui-pageLayout' ); - for ( name in this.pages ) { - // Check for page match, exclude current page to find only page changes - if ( this.pages[ name ].$element[ 0 ] === $target[ 0 ] && name !== this.currentPageName ) { - this.setPage( name ); - break; - } - } -}; - -/** - * Handle stack layout set events. - * - * @private - * @param {OO.ui.PanelLayout|null} page The page panel that is now the current panel - */ -OO.ui.BookletLayout.prototype.onStackLayoutSet = function ( page ) { - var layout = this; - if ( page ) { - page.scrollElementIntoView( { complete: function () { - if ( layout.autoFocus ) { - layout.focus(); - } - } } ); - } -}; - -/** - * Focus the first input in the current page. - * - * If no page is selected, the first selectable page will be selected. - * If the focus is already in an element on the current page, nothing will happen. - * @param {number} [itemIndex] A specific item to focus on - */ -OO.ui.BookletLayout.prototype.focus = function ( itemIndex ) { - var $input, page, - items = this.stackLayout.getItems(); - - if ( itemIndex !== undefined && items[ itemIndex ] ) { - page = items[ itemIndex ]; - } else { - page = this.stackLayout.getCurrentItem(); - } - - if ( !page && this.outlined ) { - this.selectFirstSelectablePage(); - page = this.stackLayout.getCurrentItem(); - } - if ( !page ) { - return; - } - // Only change the focus if is not already in the current page - if ( !page.$element.find( ':focus' ).length ) { - $input = page.$element.find( ':input:first' ); - if ( $input.length ) { - $input[ 0 ].focus(); - } - } -}; - -/** - * Find the first focusable input in the booklet layout and focus - * on it. - */ -OO.ui.BookletLayout.prototype.focusFirstFocusable = function () { - var i, len, - found = false, - items = this.stackLayout.getItems(), - checkAndFocus = function () { - if ( OO.ui.isFocusableElement( $( this ) ) ) { - $( this ).focus(); - found = true; - return false; - } - }; - - for ( i = 0, len = items.length; i < len; i++ ) { - if ( found ) { - break; - } - // Find all potentially focusable elements in the item - // and check if they are focusable - items[i].$element - .find( 'input, select, textarea, button, object' ) - /* jshint loopfunc:true */ - .each( checkAndFocus ); - } -}; - -/** - * Handle outline widget select events. - * - * @private - * @param {OO.ui.OptionWidget|null} item Selected item - */ -OO.ui.BookletLayout.prototype.onOutlineSelectWidgetSelect = function ( item ) { - if ( item ) { - this.setPage( item.getData() ); - } -}; - -/** - * Check if booklet has an outline. - * - * @return {boolean} Booklet has an outline - */ -OO.ui.BookletLayout.prototype.isOutlined = function () { - return this.outlined; -}; - -/** - * Check if booklet has editing controls. - * - * @return {boolean} Booklet is editable - */ -OO.ui.BookletLayout.prototype.isEditable = function () { - return this.editable; -}; - -/** - * Check if booklet has a visible outline. - * - * @return {boolean} Outline is visible - */ -OO.ui.BookletLayout.prototype.isOutlineVisible = function () { - return this.outlined && this.outlineVisible; -}; - -/** - * Hide or show the outline. - * - * @param {boolean} [show] Show outline, omit to invert current state - * @chainable - */ -OO.ui.BookletLayout.prototype.toggleOutline = function ( show ) { - if ( this.outlined ) { - show = show === undefined ? !this.outlineVisible : !!show; - this.outlineVisible = show; - this.toggleMenu( show ); - } - - return this; -}; - -/** - * Get the page closest to the specified page. - * - * @param {OO.ui.PageLayout} page Page to use as a reference point - * @return {OO.ui.PageLayout|null} Page closest to the specified page - */ -OO.ui.BookletLayout.prototype.getClosestPage = function ( page ) { - var next, prev, level, - pages = this.stackLayout.getItems(), - index = $.inArray( page, pages ); - - if ( index !== -1 ) { - next = pages[ index + 1 ]; - prev = pages[ index - 1 ]; - // Prefer adjacent pages at the same level - if ( this.outlined ) { - level = this.outlineSelectWidget.getItemFromData( page.getName() ).getLevel(); - if ( - prev && - level === this.outlineSelectWidget.getItemFromData( prev.getName() ).getLevel() - ) { - return prev; - } - if ( - next && - level === this.outlineSelectWidget.getItemFromData( next.getName() ).getLevel() - ) { - return next; - } - } - } - return prev || next || null; -}; - -/** - * Get the outline widget. - * - * If the booklet is not outlined, the method will return `null`. - * - * @return {OO.ui.OutlineSelectWidget|null} Outline widget, or null if the booklet is not outlined - */ -OO.ui.BookletLayout.prototype.getOutline = function () { - return this.outlineSelectWidget; -}; - -/** - * Get the outline controls widget. - * - * If the outline is not editable, the method will return `null`. - * - * @return {OO.ui.OutlineControlsWidget|null} The outline controls widget. - */ -OO.ui.BookletLayout.prototype.getOutlineControls = function () { - return this.outlineControlsWidget; -}; - -/** - * Get a page by its symbolic name. - * - * @param {string} name Symbolic name of page - * @return {OO.ui.PageLayout|undefined} Page, if found - */ -OO.ui.BookletLayout.prototype.getPage = function ( name ) { - return this.pages[ name ]; -}; - -/** - * Get the current page. - * - * @return {OO.ui.PageLayout|undefined} Current page, if found - */ -OO.ui.BookletLayout.prototype.getCurrentPage = function () { - var name = this.getCurrentPageName(); - return name ? this.getPage( name ) : undefined; -}; - -/** - * Get the symbolic name of the current page. - * - * @return {string|null} Symbolic name of the current page - */ -OO.ui.BookletLayout.prototype.getCurrentPageName = function () { - return this.currentPageName; -}; - -/** - * Add pages to the booklet layout - * - * When pages are added with the same names as existing pages, the existing pages will be - * automatically removed before the new pages are added. - * - * @param {OO.ui.PageLayout[]} pages Pages to add - * @param {number} index Index of the insertion point - * @fires add - * @chainable - */ -OO.ui.BookletLayout.prototype.addPages = function ( pages, index ) { - var i, len, name, page, item, currentIndex, - stackLayoutPages = this.stackLayout.getItems(), - remove = [], - items = []; - - // Remove pages with same names - for ( i = 0, len = pages.length; i < len; i++ ) { - page = pages[ i ]; - name = page.getName(); - - if ( Object.prototype.hasOwnProperty.call( this.pages, name ) ) { - // Correct the insertion index - currentIndex = $.inArray( this.pages[ name ], stackLayoutPages ); - if ( currentIndex !== -1 && currentIndex + 1 < index ) { - index--; - } - remove.push( this.pages[ name ] ); - } - } - if ( remove.length ) { - this.removePages( remove ); - } - - // Add new pages - for ( i = 0, len = pages.length; i < len; i++ ) { - page = pages[ i ]; - name = page.getName(); - this.pages[ page.getName() ] = page; - if ( this.outlined ) { - item = new OO.ui.OutlineOptionWidget( { data: name } ); - page.setOutlineItem( item ); - items.push( item ); - } - } - - if ( this.outlined && items.length ) { - this.outlineSelectWidget.addItems( items, index ); - this.selectFirstSelectablePage(); - } - this.stackLayout.addItems( pages, index ); - this.emit( 'add', pages, index ); - - return this; -}; - -/** - * Remove the specified pages from the booklet layout. - * - * To remove all pages from the booklet, you may wish to use the #clearPages method instead. - * - * @param {OO.ui.PageLayout[]} pages An array of pages to remove - * @fires remove - * @chainable - */ -OO.ui.BookletLayout.prototype.removePages = function ( pages ) { - var i, len, name, page, - items = []; - - for ( i = 0, len = pages.length; i < len; i++ ) { - page = pages[ i ]; - name = page.getName(); - delete this.pages[ name ]; - if ( this.outlined ) { - items.push( this.outlineSelectWidget.getItemFromData( name ) ); - page.setOutlineItem( null ); - } - } - if ( this.outlined && items.length ) { - this.outlineSelectWidget.removeItems( items ); - this.selectFirstSelectablePage(); - } - this.stackLayout.removeItems( pages ); - this.emit( 'remove', pages ); - - return this; -}; - -/** - * Clear all pages from the booklet layout. - * - * To remove only a subset of pages from the booklet, use the #removePages method. - * - * @fires remove - * @chainable - */ -OO.ui.BookletLayout.prototype.clearPages = function () { - var i, len, - pages = this.stackLayout.getItems(); - - this.pages = {}; - this.currentPageName = null; - if ( this.outlined ) { - this.outlineSelectWidget.clearItems(); - for ( i = 0, len = pages.length; i < len; i++ ) { - pages[ i ].setOutlineItem( null ); - } - } - this.stackLayout.clearItems(); - - this.emit( 'remove', pages ); - - return this; -}; - -/** - * Set the current page by symbolic name. - * - * @fires set - * @param {string} name Symbolic name of page - */ -OO.ui.BookletLayout.prototype.setPage = function ( name ) { - var selectedItem, - $focused, - page = this.pages[ name ]; - - if ( name !== this.currentPageName ) { - if ( this.outlined ) { - selectedItem = this.outlineSelectWidget.getSelectedItem(); - if ( selectedItem && selectedItem.getData() !== name ) { - this.outlineSelectWidget.selectItemByData( name ); - } - } - if ( page ) { - if ( this.currentPageName && this.pages[ this.currentPageName ] ) { - this.pages[ this.currentPageName ].setActive( false ); - // Blur anything focused if the next page doesn't have anything focusable - this - // is not needed if the next page has something focusable because once it is focused - // this blur happens automatically - if ( this.autoFocus && !page.$element.find( ':input' ).length ) { - $focused = this.pages[ this.currentPageName ].$element.find( ':focus' ); - if ( $focused.length ) { - $focused[ 0 ].blur(); - } - } - } - this.currentPageName = name; - this.stackLayout.setItem( page ); - page.setActive( true ); - this.emit( 'set', page ); - } - } -}; - -/** - * Select the first selectable page. - * - * @chainable - */ -OO.ui.BookletLayout.prototype.selectFirstSelectablePage = function () { - if ( !this.outlineSelectWidget.getSelectedItem() ) { - this.outlineSelectWidget.selectItem( this.outlineSelectWidget.getFirstSelectableItem() ); - } - - return this; -}; |