From 6de9a5368c3e0523f91f08e7b1516549ce006f98 Mon Sep 17 00:00:00 2001 From: Ben Hollis Date: Sun, 6 Jun 2010 15:00:49 -0700 Subject: [PATCH] Dialog: allow setting position with ui.position arguments. Fixes #5459 - Dialog: expose .position() API --- tests/unit/dialog/dialog_options.js | 103 +++++++++++++++++++++++++++- ui/jquery.ui.dialog.js | 86 +++++++++++------------ 2 files changed, 141 insertions(+), 48 deletions(-) diff --git a/tests/unit/dialog/dialog_options.js b/tests/unit/dialog/dialog_options.js index 28b3812b5..b5eda1fcf 100644 --- a/tests/unit/dialog/dialog_options.js +++ b/tests/unit/dialog/dialog_options.js @@ -244,11 +244,110 @@ test("position, default center on window", function() { var el = $('
').dialog(); var offset = el.parent().offset(); // use .position() instead to avoid replicating center-logic? - same(offset.left, Math.floor($(window).width() / 2 - el.parent().width() / 2)); - same(offset.top, Math.floor($(window).height() / 2 - el.parent().height() / 2)); + same(offset.left, Math.floor($(window).width() / 2 - dialog.outerWidth() / 2) + $(window).scrollLeft()); + same(offset.top, Math.floor($(window).height() / 2 - dialog.outerHeight() / 2) + $(window).scrollTop()); el.remove(); }); +test("position, top on window", function() { + var el = $('
').dialog({ position: "top" }); + var dialog = el.closest('.ui-dialog'); + var offset = dialog.offset(); + same(offset.left, Math.floor($(window).width() / 2 - dialog.outerWidth() / 2)); + same(offset.top, $(window).scrollTop()); + el.remove(); +}); + +test("position, left on window", function() { + var el = $('
').dialog({ position: "left" }); + var dialog = el.closest('.ui-dialog'); + var offset = dialog.offset(); + same(offset.left, 0); + same(offset.top, Math.floor($(window).height() / 2 - dialog.outerHeight() / 2) + $(window).scrollTop()); + el.remove(); +}); + +test("position, right bottom on window", function() { + var el = $('
').dialog({ position: "right bottom" }); + var dialog = el.closest('.ui-dialog'); + var offset = dialog.offset(); + same(offset.left, $(window).width() - dialog.outerWidth()); + same(offset.top, $(window).height() - dialog.outerHeight() + $(window).scrollTop()); + el.remove(); +}); + +test("position, right bottom on window w/array", function() { + var el = $('
').dialog({ position: ["right", "bottom"] }); + var dialog = el.closest('.ui-dialog'); + var offset = dialog.offset(); + same(offset.left, $(window).width() - dialog.outerWidth()); + same(offset.top, $(window).height() - dialog.outerHeight() + $(window).scrollTop()); + el.remove(); +}); + +test("position, offset from top left w/array", function() { + var el = $('
').dialog({ position: [10, 10] }); + var dialog = el.closest('.ui-dialog'); + var offset = dialog.offset(); + same(offset.left, 10); + same(offset.top, 10 + $(window).scrollTop()); + el.remove(); +}); + +test("position, right bottom at right bottom via ui.position args", function() { + var el = $('
').dialog({ + position: { + my: "right bottom", + at: "right bottom" + } + }); + + var dialog = el.closest('.ui-dialog'); + var offset = dialog.offset(); + + same(offset.left, $(window).width() - dialog.outerWidth()); + same(offset.top, $(window).height() - dialog.outerHeight() + $(window).scrollTop()); + el.remove(); +}); + +test("position, at another element", function() { + var parent = $('
').css({ + position: 'absolute', + top: 400, + left: 600, + height: 10, + width: 10 + }); + + var el = $('
').dialog({ + position: { + my: "left top", + at: "top left", + of: parent + } + }); + + var dialog = el.closest('.ui-dialog'); + var offset = dialog.offset(); + var parentOffset = parent.offset(); + + same(offset.left, parentOffset.left); + same(offset.top, parentOffset.top); + + el.dialog('option', 'position', { + my: "left top", + at: "right bottom", + of: parent + }); + + same(offset.left, parentOffset.left + parent.outerWidth()); + same(offset.top, parentOffset.top + parent.outerHeight()); + + el.remove(); + parent.remove(); +}); + + test("position, others", function() { ok(false, 'missing test - untested code is broken code'); }); diff --git a/ui/jquery.ui.dialog.js b/ui/jquery.ui.dialog.js index 71dda2c7d..dc2559e9d 100644 --- a/ui/jquery.ui.dialog.js +++ b/ui/jquery.ui.dialog.js @@ -39,7 +39,19 @@ $.widget("ui.dialog", { minHeight: 150, minWidth: 150, modal: false, - position: 'center', + position: { + my: 'center', + at: 'center', + of: window, + collision: 'fit', + // ensure that the titlebar is never outside the document + using: function(pos) { + var topOffset = $(this).css(pos).offset().top; + if (topOffset < 0) { + $(this).css('top', pos.top - topOffset); + } + } + }, resizable: true, show: null, stack: true, @@ -449,45 +461,40 @@ $.widget("ui.dialog", { } }, + _position: function(position) { var myAt = [], offset = [0, 0], isVisible; - position = position || $.ui.dialog.prototype.options.position; + if (position) { + // deep extending converts arrays to objects in jQuery <= 1.3.2 :-( + // if (typeof position == 'string' || $.isArray(position)) { + // myAt = $.isArray(position) ? position : position.split(' '); - // deep extending converts arrays to objects in jQuery <= 1.3.2 :-( -// if (typeof position == 'string' || $.isArray(position)) { -// myAt = $.isArray(position) ? position : position.split(' '); - - if (typeof position === 'string' || (typeof position === 'object' && '0' in position)) { - myAt = position.split ? position.split(' ') : [position[0], position[1]]; - if (myAt.length === 1) { - myAt[1] = myAt[0]; - } - - $.each(['left', 'top'], function(i, offsetPosition) { - if (+myAt[i] === myAt[i]) { - offset[i] = myAt[i]; - myAt[i] = offsetPosition; + if (typeof position === 'string' || (typeof position === 'object' && '0' in position)) { + myAt = position.split ? position.split(' ') : [position[0], position[1]]; + if (myAt.length === 1) { + myAt[1] = myAt[0]; } - }); - } else if (typeof position === 'object') { - if ('left' in position) { - myAt[0] = 'left'; - offset[0] = position.left; - } else if ('right' in position) { - myAt[0] = 'right'; - offset[0] = -position.right; - } - if ('top' in position) { - myAt[1] = 'top'; - offset[1] = position.top; - } else if ('bottom' in position) { - myAt[1] = 'bottom'; - offset[1] = -position.bottom; - } + $.each(['left', 'top'], function(i, offsetPosition) { + if (+myAt[i] === myAt[i]) { + offset[i] = myAt[i]; + myAt[i] = offsetPosition; + } + }); + + position = { + my: myAt.join(" "), + at: myAt.join(" "), + offset: offset.join(" ") + }; + } + + position = $.extend({}, $.ui.dialog.prototype.options.position, position); + } else { + position = $.ui.dialog.prototype.options.position; } // need to show the dialog to get the actual offset in the position plugin @@ -498,20 +505,7 @@ $.widget("ui.dialog", { this.uiDialog // workaround for jQuery bug #5781 http://dev.jquery.com/ticket/5781 .css({ top: 0, left: 0 }) - .position({ - my: myAt.join(' '), - at: myAt.join(' '), - offset: offset.join(' '), - of: window, - collision: 'fit', - // ensure that the titlebar is never outside the document - using: function(pos) { - var topOffset = $(this).css(pos).offset().top; - if (topOffset < 0) { - $(this).css('top', pos.top - topOffset); - } - } - }); + .position(position); if (!isVisible) { this.uiDialog.hide(); }