2013-02-20 19:44:44 +00:00
|
|
|
/*!
|
|
|
|
* 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
|
2013-05-01 22:21:32 +00:00
|
|
|
* @mixins ve.EventEmitter
|
2013-02-20 19:44:44 +00:00
|
|
|
*
|
|
|
|
* @constructor
|
|
|
|
* @param {jQuery} $container Conainter to render target into
|
|
|
|
*/
|
|
|
|
ve.init.Target = function VeInitTarget( $container ) {
|
2013-05-01 22:21:32 +00:00
|
|
|
// Mixin constructors
|
2013-02-20 19:44:44 +00:00
|
|
|
ve.EventEmitter.call( this );
|
|
|
|
|
|
|
|
// Properties
|
|
|
|
this.$ = $container;
|
2013-05-10 00:17:51 +00:00
|
|
|
this.surface = null;
|
2013-02-20 19:44:44 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
/* Inheritance */
|
|
|
|
|
2013-05-01 22:21:32 +00:00
|
|
|
ve.mixinClass( ve.init.Target, ve.EventEmitter );
|
2013-05-10 00:17:51 +00:00
|
|
|
|
|
|
|
/* 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();
|
|
|
|
};
|