Showing with 54 additions and 35 deletions.
  1. +17 −1 docs/api/data-attributes.html
  2. +8 −7 docs/pages/popup/index.html
  3. +0 −12 docs/pages/popup/options.html
  4. +29 −15 js/widgets/popup.js
@@ -333,12 +333,28 @@ <h2><a href="../pages/page-links.html">Link</a></h2>
<th>data-rel</th>
<td>back (to move one step back in history)<br />
dialog (to open link styled as dialog, not tracked in history)<br />
external (for linking to another domain)</td>
external (for linking to another domain)<br />
popup (for opening a popup)</td>
</tr>
<tr>
<th>data-transition</th>
<td><strong>fade</strong> | flip | flow | pop | slide | slidedown | slidefade | slideup | turn | none</td>
</tr>
<tr>
<th>data-position-to</th>
<td>Used only with popups:<br />
<table>
<tr>
<td><strong>origin</strong></td><td>Center the popup over the link that opens it</td>
</tr>
<tr>
<td style="white-space: nowrap;">jQuery selector</td><td>Center the popup over the selected element. The element must be visible when the link is clicked.</td>
</tr>
<tr>
<td>window</td><td>Center the popup inside the window. This behaviour is also used if a jQuery selector is specified but turns out to be invalid, or if it does not evaluate to a visible element.</td>
</tr>
</table>
</tr>
</table>

<h2><a href="../lists/docs-lists.html">Listview</a></h2>
@@ -135,25 +135,26 @@ <h2>Adding padding</h2>


<h2>Positioning options</h2>
<p>By default, popups open centered vertically and horizontally over the thing you clicked (origin) which is good for popups used as tooltips or menus. The framework also applies some basic collision detection rules to ensure that the popup will appear on-screen so the ultimate position may not always be centered over the origin.</p>
<p>For situations like a dialog or lightbox where the popup should appear centered within the window instead of over the origin, add the <code>data-position-to</code> attribute to the popup container and specify a value of <code>window</code>. </p>
<p>By default, popups open centered vertically and horizontally over the thing you clicked (the origin) which is good for popups used as tooltips or menus. The framework also applies some basic collision detection rules to ensure that the popup will appear on-screen so the ultimate position may not always be centered over the origin.</p>
<p>For situations like a dialog or lightbox where the popup should appear centered within the window instead of over the origin, add the <code>data-position-to</code> attribute to the link and specify a value of <code>window</code>. </p>

<pre><code>
&lt;div data-role=&quot;popup&quot; id=&quot;positionWindow&quot; <strong>data-position-to=&quot;window&quot;</strong> &gt;
&lt;div data-role=&quot;popup&quot; id=&quot;positionWindow&quot;&gt;
&lt;p&gt;I am positioned to the window.&lt;/p&gt;
&lt;/div&gt;
&lt;a href=&quot;#positionWindow&quot; data-rel=&quot;popup&quot; <strong>data-position-to=&quot;window&quot;</strong>&gt;
</code></pre>

<p>A few examples:</p>

<a href="#positionWindow" data-role="button" data-inline="true" data-rel="popup">Position to window</a>
<a href="#positionOrigin" data-role="button" data-inline="true" data-rel="popup">Position to origin</a>
<a href="#positionWindow" data-role="button" data-inline="true" data-rel="popup" data-position-to="window">Position to window</a>
<a href="#positionOrigin" data-role="button" data-inline="true" data-rel="popup" data-position-to="origin">Position to origin</a>

<div data-role="popup" id="positionWindow" data-position-to="window" class="ui-content" data-theme="d">
<div data-role="popup" id="positionWindow" class="ui-content" data-theme="d">
<p>I am positioned to the window.</p>
</div>

<div data-role="popup" id="positionOrigin" data-position-to="origin" class="ui-content" data-theme="d">
<div data-role="popup" id="positionOrigin" class="ui-content" data-theme="d">
<p>I am positioned over the origin.</p>
</div>

@@ -65,18 +65,6 @@ <h2>Popup</h2>
<p>This option is also exposed as a data attribute: <code>data-overlay-theme=&quot;a&quot;</code></p>
</dd>

<dt><code>positionTo</code> <em>string</em></dt>
<dd>
<p class="default">default: "origin"</p>
<p>Determines the element over which the popup will be centered. This parameter can have one of three values:</p>
<ol>
<li><code>"origin"</code>: The coordinates passed to the <code>open</code> method will be used for positioning the popup. In the case where a popup is opened from a link, this means the popup will be centered over the link.</li>
<li><code>"window"</code>: The popup will be displayed in the center of the window.</li>
<li>A jQuery selector: The selector will be used to select an element over which to center the popup. The resulting selection will be filtered for those elements that are visible. If the selection turns up empty, the default value will be used for placing the popup.</li>
</ol>
<pre><code>$('.selector').popup(<strong>{ positionTo: "window" }</strong>);</code></pre>
</dd>

<dt><code>shadow</code> <em>boolean</em></dt>
<dd>
<p class="default">default: true</p>
@@ -32,7 +32,6 @@ define( [ "jquery",
shadow: true,
corners: true,
transition: "none",
positionTo: "origin",
initSelector: ":jqmData(role='popup')"
},

@@ -292,21 +291,25 @@ define( [ "jquery",
},

// The desired coordinates passed in will be returned untouched if no reference element can be identified via
// this.options.positionTo. Nevertheless, this function ensures that its return value always contains valid
// desiredPosition.positionTo. Nevertheless, this function ensures that its return value always contains valid
// x and y coordinates by specifying the center middle of the window if the coordinates are absent.
_desiredCoords: function( desired ) {
var dst = null, offset, $win = $( window );
_desiredCoords: function( desiredPosition ) {
var dst = null, offset, $win = $( window ),
desired = {
x: desiredPosition.x,
y: desiredPosition.y
};

// Establish which element will serve as the reference
if ( this.options.positionTo && this.options.positionTo !== "origin" ) {
if ( this.options.positionTo === "window" ) {
if ( desiredPosition.positionTo && desiredPosition.positionTo !== "origin" ) {
if ( desiredPosition.positionTo === "window" ) {
desired = {
x: $win.width() / 2 + $win.scrollLeft(),
y: $win.height() / 2 + $win.scrollTop()
};
} else {
try {
dst = $( this.options.positionTo );
dst = $( desiredPosition.positionTo );
} catch( e ) {
dst = null;
}
@@ -319,6 +322,7 @@ define( [ "jquery",
}
}

// If an element was found, center over it
if ( dst ) {
offset = dst.offset();
desired = {
@@ -327,26 +331,36 @@ define( [ "jquery",
};
}

if ( $.type( desired.x ) !== "number" ) {
// Make sure x and y are valid numbers
if ( $.type( desired.x ) !== "number" || isNaN( desired.x ) ) {
desired.x = $win.width() / 2 + $win.scrollLeft();
}

if ( $.type( desired.y ) !== "number" ) {
if ( $.type( desired.y ) !== "number" || isNaN( desired.y ) ) {
desired.y = $win.height() / 2 + $win.scrollTop();
}

return desired;

},

_open: function( x, y, transition ) {
_open: function( x, y, $link ) {
var self = this,
transition = "",
desiredPlacement = {
x: x,
y: y,
positionTo: "origin"
},
coords;

if ( $link ) {
transition = $link.jqmData( "transition" );
desiredPlacement.positionTo = $link.jqmData( "position-to" );
}

// Give applications a chance to modify the contents of the container before it appears
this.element.trigger( "popupbeforeopen" );

coords = self._placementCoords( self._desiredCoords( { x: x, y: y } ) );
coords = self._placementCoords( self._desiredCoords( desiredPlacement ) );

// Count down to triggering "popupafteropen" - we have two prerequisites:
// 1. The popup window animation completes (container())
@@ -449,7 +463,7 @@ define( [ "jquery",
});
},

open: function( x, y, transition ) {
open: function( x, y, $link ) {
$.mobile.popup.popupManager.push( this, arguments );
},

@@ -605,7 +619,7 @@ define( [ "jquery",
popup.popup( "open",
offset.left + $link.outerWidth() / 2,
offset.top + $link.outerHeight() / 2,
$link.jqmData( "transition" ) );
$link );

// If this link is not inside a popup, re-focus onto it after the popup(s) complete
// For some reason, a $.proxy( $link, "focus" ) doesn't work as the handler