mirror of
https://gerrit.wikimedia.org/r/mediawiki/extensions/VisualEditor
synced 2024-11-29 08:34:54 +00:00
8cea089f3b
See also http://stackoverflow.com/a/13139830/319266: > Some are unstable and cause CSS glitches. [If] you have an > <img> and you use the tiniest transparent GIF possible, it > works fine[. if] you then want your transparent GIF to have a > background-image, then this is impossible. For some reason, > some GIFs such as the following prevent CSS backgrounds (in > some browsers). > > == Shortest (but unstable) == > data:image/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw== > > == Stable (but slightly longer) *use this one* == > > data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7 > > Also: don't ommit image/gif. This will break in several browsers. For the record, this is not limited to rare browsers. It also affects latest Chrome in some cases as confirmed by Christian (it'd be white instead of transparent in some cases when uses as a css background-image without border). Change-Id: If9ff8a0820c217b6c23e3335944907939a37bef7
140 lines
3.3 KiB
JavaScript
140 lines
3.3 KiB
JavaScript
/*!
|
|
* VisualEditor ContentEditable RelocatableNode class.
|
|
*
|
|
* @copyright 2011-2013 VisualEditor Team and others; see AUTHORS.txt
|
|
* @license The MIT License (MIT); see LICENSE.txt
|
|
*/
|
|
|
|
/**
|
|
* ContentEditable relocatable node.
|
|
*
|
|
* Requires that the node also is Focusable
|
|
*
|
|
* @class
|
|
* @abstract
|
|
*
|
|
* @constructor
|
|
* @param {jQuery} [$relocatable=this.$] Element which can be relocated
|
|
*/
|
|
ve.ce.RelocatableNode = function VeCeRelocatableNode( $relocatable ) {
|
|
// Properties
|
|
this.relocatingSurface = null;
|
|
this.$relocatable = $relocatable || this.$;
|
|
this.$relocatableMarker = this.$$( '<img>' );
|
|
|
|
// Events
|
|
this.connect( this, {
|
|
'focus': 'onRelocatableFocus',
|
|
'blur': 'onRelocatableBlur',
|
|
'resize': 'onRelocatableResize',
|
|
'live': 'onRelocatableLive'
|
|
} );
|
|
|
|
// Initialization
|
|
this.$relocatableMarker
|
|
.addClass( 've-ce-relocatableNode-marker' )
|
|
.attr( 'src', 'data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7' )
|
|
.on( {
|
|
'dragstart': ve.bind( this.onRelocatableDragStart, this ),
|
|
'dragend': ve.bind( this.onRelocatableDragEnd, this )
|
|
} );
|
|
};
|
|
|
|
/* Static Properties */
|
|
|
|
/* Methods */
|
|
|
|
/**
|
|
* Handle node live.
|
|
*
|
|
* @method
|
|
*/
|
|
ve.ce.RelocatableNode.prototype.onRelocatableLive = function () {
|
|
var surfaceModel = this.root.getSurface().getModel();
|
|
|
|
if ( this.live ) {
|
|
surfaceModel.connect( this, { 'history': 'setRelocatableMarkerSizeAndPosition' } );
|
|
} else {
|
|
surfaceModel.disconnect( this, { 'history': 'setRelocatableMarkerSizeAndPosition' } );
|
|
}
|
|
};
|
|
|
|
/**
|
|
* Handle node focus.
|
|
*
|
|
* @method
|
|
*/
|
|
ve.ce.RelocatableNode.prototype.onRelocatableFocus = function () {
|
|
this.setRelocatableMarkerSizeAndPosition();
|
|
this.$relocatableMarker.appendTo( this.root.getSurface().getSurface().$localOverlayControls );
|
|
};
|
|
|
|
/**
|
|
* Handle node blur.
|
|
*
|
|
* @method
|
|
*/
|
|
ve.ce.RelocatableNode.prototype.onRelocatableBlur = function () {
|
|
this.$relocatableMarker.detach();
|
|
};
|
|
|
|
/**
|
|
* Handle node resize.
|
|
*
|
|
* @method
|
|
*/
|
|
ve.ce.RelocatableNode.prototype.onRelocatableResize = function () {
|
|
this.setRelocatableMarkerSizeAndPosition();
|
|
};
|
|
|
|
/**
|
|
* Handle element drag start.
|
|
*
|
|
* @method
|
|
*/
|
|
ve.ce.RelocatableNode.prototype.onRelocatableDragStart = function () {
|
|
// Store a copy of the surface, when dragend occurs the node will be detached
|
|
this.relocatingSurface = this.root.getSurface();
|
|
|
|
if ( this.relocatingSurface ) {
|
|
// Allow dragging this node in the surface
|
|
this.relocatingSurface.startRelocation( this );
|
|
}
|
|
this.$relocatableMarker.addClass( 'relocating' );
|
|
|
|
setTimeout( ve.bind( function () {
|
|
this.$relocatableMarker.css( { 'top': -10000, 'left': -10000 } );
|
|
}, this ), 0 );
|
|
};
|
|
|
|
/**
|
|
* Handle element drag end.
|
|
*
|
|
* @method
|
|
*/
|
|
ve.ce.RelocatableNode.prototype.onRelocatableDragEnd = function () {
|
|
if ( this.relocatingSurface ) {
|
|
this.relocatingSurface.endRelocation();
|
|
this.relocatingSurface = null;
|
|
}
|
|
this.$relocatableMarker.removeClass( 'relocating' );
|
|
};
|
|
|
|
/**
|
|
* Set the correct size and position of the relocatable marker.
|
|
*
|
|
* @method
|
|
*/
|
|
ve.ce.RelocatableNode.prototype.setRelocatableMarkerSizeAndPosition = function () {
|
|
var offset = ve.Element.getRelativePosition(
|
|
this.$relocatable, this.getRoot().getSurface().getSurface().$
|
|
);
|
|
|
|
this.$relocatableMarker.css( {
|
|
'height': this.$relocatable.height(),
|
|
'width': this.$relocatable.width(),
|
|
'top': offset.top,
|
|
'left': offset.left
|
|
} );
|
|
};
|