mediawiki-extensions-Visual.../modules/ve/init/ve.init.Target.js
Trevor Parscal 5012ed101b Floating toolbar cleanup
Objective:

Move toolbar floating functionality to ve.init and clean it up

As a bonus:

demo.css
* Fix CSS path to set width of inputs properly

Changes:

demos/ve/index.php
* Allow ve.init.sa.Target to construct it's own surface object

ve.ce.Surface.js
* Move object resizing and table editing disabling commands from ve.Surface
* Add method for getting the currently focused node

ve.init.mw.ViewPageTarget.js
* Remove initializing surface property (now done in parent class)
* Normalize all uses of "setup" to "setUp"
* Replace uses of getDocumentModel with getModel().getDocument()
* Add calls to set up and tear down for toolbar floating

ve.init.mw.Target.js
* Replace uses of getDocumentModel with getModel().getDocument()

ve.init.sa.Target.js
* Move example from ve.Surface
* Change constructor to accept document model
* Create ve.Surface object in constructor
* Add set up for toolbar floating

ve.ui.init.Target.js
* Initialize surface property
* Move and cleanup toolbar floating functionality from ve.Surface

ve.ui.Surface.js
* Remove example now that init.sa creates it's own surface (moved)
* Document options
* Simplify toolbar options and remove the concept of multiple toolbars
* No longer cache the options object
* Move toolbar initialization to constructor
* Change setupCommands to addCommands, making it useful after construction
* Inline selection initialization
* Move and cleanup toolbar floating functionality to ve.ce.Surface
* Reorganize a few methods
* Move toolbar floating to ve.init.Target.js

Change-Id: I393a426e35567d57c048122bf64a83c1ef45e6e8
2013-05-14 12:43:30 -07:00

160 lines
4.2 KiB
JavaScript

/*!
* VisualEditor Initialization Target class.
*
* @copyright 2011-2013 VisualEditor Team and others; see AUTHORS.txt
* @license The MIT License (MIT); see LICENSE.txt
*/
/**
* Generic Initialization target.
*
* @class
* @abstract
* @mixins ve.EventEmitter
*
* @constructor
* @param {jQuery} $container Conainter to render target into
*/
ve.init.Target = function VeInitTarget( $container ) {
// Mixin constructors
ve.EventEmitter.call( this );
// Properties
this.$ = $container;
this.surface = null;
};
/* Inheritance */
ve.mixinClass( ve.init.Target, ve.EventEmitter );
/* Methods */
/**
* Handle window resize events while toolbar floating is enabled.
*
* @param {jQuery.Event} e Window resize event
*/
ve.init.Target.prototype.onToolbarFloatingWindowResize = function () {
if ( !this.surface ) {
return;
}
var $toolbarWrapper = this.surface.$toolbarWrapper,
$toolbar = this.surface.$toolbar,
toolbarOffset = $toolbarWrapper.offset();
if ( $toolbarWrapper.hasClass( 've-ui-toolbar-wrapper-floating' ) ) {
$toolbar.css( {
'left': toolbarOffset.left,
'right': $( window ).width() - $toolbarWrapper.outerWidth() - toolbarOffset.left
} );
}
};
/**
* Handle window scroll events while toolbar floating is enabled.
*
* Toolbar will stick to the top of the screen unless it would be over or under the last visible
* branch node in the root of the document being edited, at which point it will stop just above it.
*
* @param {jQuery.Event} e Window scroll event
*/
ve.init.Target.prototype.onToolbarFloatingWindowScroll = function () {
if ( !this.surface ) {
return;
}
var $window = $( window ),
scrollTop = $window.scrollTop(),
$toolbarWrapper = this.surface.$toolbarWrapper,
$toolbar = this.surface.$toolbar,
toolbarOffset = $toolbarWrapper.offset(),
$lastBranch = this.surface.$.find( '.ve-ce-documentNode > .ve-ce-branchNode:visible:last' ),
lastBranchOffset = $lastBranch.offset(),
belowLastBranch = $lastBranch.length &&
scrollTop + $toolbar.height() >= lastBranchOffset.top;
if ( scrollTop > toolbarOffset.top ) {
this.floatToolbar(
belowLastBranch ? lastBranchOffset.top - $toolbarWrapper.outerHeight() : 0,
toolbarOffset.left,
$window.width() - $toolbarWrapper.outerWidth() - toolbarOffset.left
);
} else {
this.resetToolbarPosition();
}
};
/**
* Float the toolbar.
*
* @method
* @param {number} top Top position, in pixels
* @param {number} left Left position, in pixels
* @param {number} right Right position, in pixels
*/
ve.init.Target.prototype.floatToolbar = function ( top, left, right ) {
if ( !this.surface ) {
return;
}
var $toolbarWrapper = this.surface.$toolbarWrapper,
$toolbar = this.surface.$toolbar;
// When switching from default position, manually set the height of the wrapper
if ( !$toolbarWrapper.hasClass( 've-ui-toolbar-wrapper-floating' ) ) {
$toolbarWrapper
.css( 'height', $toolbarWrapper.height() )
.addClass( 've-ui-toolbar-wrapper-floating' );
}
$toolbar.css( { 'top': top, 'left': left, 'right': right } );
if ( top > 0 ) {
$toolbarWrapper.addClass( 've-ui-toolbar-wrapper-bottom' );
} else {
$toolbarWrapper.removeClass( 've-ui-toolbar-wrapper-bottom' );
}
};
/**
* Reset the toolbar to its default position.
*
* @method
*/
ve.init.Target.prototype.resetToolbarPosition = function () {
if ( !this.surface ) {
return;
}
this.surface.$toolbarWrapper
.css( 'height', 'auto' )
.removeClass( 've-ui-toolbar-wrapper-floating ve-ui-toolbar-wrapper-bottom' );
this.surface.$toolbar.css( { 'top': 0, 'left': 0, 'right': 0 } );
};
/**
* Add automatic floating behavior to the toolbar.
*
* Toolbar floating is not enabled by default, call this on setup to enable it.
*
* @method
*/
ve.init.Target.prototype.setupToolbarFloating = function () {
$( window ).on( {
'resize.ve-init-target': ve.bind( this.onToolbarFloatingWindowResize, this ),
'scroll.ve-init-target': ve.bind( this.onToolbarFloatingWindowScroll, this )
} );
};
/**
* Remove automatic floating behavior to the toolbar.
*
* If toolbar floating was enabled, make sure to disable it on tear down.
*
* @method
*/
ve.init.Target.prototype.teardownToolbarFloating = function () {
$( window ).off( '.ve-init-target' );
this.resetToolbarPosition();
};