X-Git-Url: https://git.mdrn.pl/redakcja.git/blobdiff_plain/5c5ef4d21bc0b4862b31b0b96aab9373357140e1..de93104a2513acc5a378496c6bf6ab7ed0d45d60:/project/static/js/views/split.js diff --git a/project/static/js/views/split.js b/project/static/js/views/split.js index 84f48ead..48f0de73 100644 --- a/project/static/js/views/split.js +++ b/project/static/js/views/split.js @@ -1,86 +1,117 @@ -/*globals Class*/ +/*globals View*/ -var SplitView = Class.extend({ - leftPanelClass: 'splitview-left-panel', - rightPanelClass: 'splitview-right-panel', - splitterClass: 'splitview-splitter', +// Split view inspired by jQuery Splitter Plugin http://methvin.com/splitter/ +var SplitView = View.extend({ + _className: 'SplitView', + splitbarClass: 'splitview-splitbar', + activeClass: 'splitview-active', overlayClass: 'splitview-overlay', element: null, + model: null, + zombie: null, + leftViewOffset: 0, - init: function(element) { - this.element = $(element); - this.leftPanel = $(this.leftPanelClass, element); - this.rightPanel = $(this.rightPanelClass, element); - this.splitter = $(this.splitterClass, element); - this.overlay = this._createOverlay(this.overlayClass); - - this.splitter.bind('mousedown.splitview', this.beginResize.bind(this)); - }, + // Cache + _splitbarWidth: 0, - _createOverlay: function(cssClass) { - var pos = this.root.position(); - return $('
') - .addClass(cssClass) + init: function(element, model) { + this._super(element, model, null); + this.element.css('position', 'relative'); + this._resizingSubviews = false; + + this.views = $(">*", this.element[0]).css({ + position: 'absolute', // positioned inside splitter container + 'z-index': 1, // splitbar is positioned above + '-moz-outline-style': 'none', // don't show dotted outline + overflow: 'auto' + }); + + this.leftView = $(this.views[0]); + this.rightView = $(this.views[1]); + this.splitbar = $(this.views[2] || '') + .insertAfter(this.leftView) .css({ position: 'absolute', - left: pos.left, - top: pos.top, - width: this.root.width(), - height: this.root.height() + 'user-select': 'none', + '-webkit-user-select': 'none', + '-khtml-user-select': 'none', + '-moz-user-select': 'none', + 'z-index': 100 }) - .hide() - .appendTo(this.element); + .attr('unselectable', 'on') + .addClass(this.splitbarClass) + .bind('mousedown.splitview', this.beginResize.bind(this)); + + this._splitbarWidth = this.splitbar.outerWidth(); + + // Solomon's algorithm ;-) + this.resplit(this.element.width() / 2); }, - + beginResize: function(event) { - this.hotspotX = event.pageX - this.splitter.position().left; + this.zombie = this.zombie || this.splitbar.clone(false).insertAfter(this.leftView); + this.overlay = this.overlay || $('').addClass(this.overlayClass).css({ + position: 'absolute', + width: this.element.width(), + height: this.element.height(), + top: this.element.position().top, + left: this.element.position().left + }).appendTo(this.element); + this.views.css("-webkit-user-select", "none"); // Safari selects A/B text on a move + this.splitbar.addClass(this.activeClass); + this.leftViewOffset = this.leftView[0].offsetWidth - event.pageX; $(document) .bind('mousemove.splitview', this.resizeChanged.bind(this)) .bind('mouseup.splitview', this.endResize.bind(this)); - - this.overlay.show(); - return false; }, resizeChanged: function(event) { - var old_width = this.overlay.width(); - var delta = event.pageX + this.hotspotX - old_width; - - if(old_width + delta < 12) delta = 12 - old_width; - if(old_width + delta > $(window).width()) { - delta = $(window).width() - old_width; - } - - this.overlay.css({'width': old_width + delta}); - - if(this.overlay.next) { - var left = parseInt(this.overlay.next.css('left'), 10); - this.overlay.next.css('left', left+delta); - } - return false; + var newPosition = event.pageX + this.leftViewOffset; + newPosition = Math.max(0, Math.min(newPosition, this.element.width() - this._splitbarWidth)); + this.splitbar.css('left', newPosition); }, endResize: function(event) { + var newPosition = event.pageX + this.leftViewOffset; + this.zombie.remove(); + this.zombie = null; + this.overlay.remove(); + this.overlay = null; + this.resplit(newPosition); + $(document) .unbind('mousemove.splitview') .unbind('mouseup.splitview'); - - this.leftPanel.css({ + }, + + resized: function(event) { + if (!this._resizingSubviews) { + this.resplit(Math.min(this.leftView.width(), this.element.width() - this._splitbarWidth)); + } + }, + + resplit: function(newPosition) { + newPosition = Math.max(0, Math.min(newPosition, this.element.width() - this._splitbarWidth)); + this.splitbar.css('left', newPosition); + this.leftView.css({ left: 0, - right: this.hotspotX + width: newPosition }); - - this.rightPanel.css({ - left: this.hotspotX, - right: 0 + this.rightView.css({ + left: newPosition + this._splitbarWidth, + width: this.element.width() - newPosition - this._splitbarWidth }); - - this.overlay.hide(); + if (!$.browser.msie) { + this._resizingSubviews = true; + $(window).trigger('resize'); + this._resizingSubviews = false; + } }, dispose: function() { this.splitter.unbind('mousedown.splitview'); + this._super(); } });