|
| 1 | +( function( $, undefined ) { |
| 2 | + |
| 3 | +// Eventually, the real handleLink function should pass the coordinates and |
| 4 | +// size of the rectangle representing the origin into popup's "open" method, or |
| 5 | +// maybe the origin itself, instead of merely the midpoint of it. Here, the |
| 6 | +// origin (link) is saved in lastLink, and appended to the options in the |
| 7 | +// overridden version of open. Thankfully, JS is not multithreaded. Hooray! |
| 8 | +var lastLink, |
| 9 | + origHandleLink = $.mobile.popup.handleLink, |
| 10 | + handleLink = function( link ) { |
| 11 | + lastLink = link; |
| 12 | + return origHandleLink.apply( this, arguments ); |
| 13 | + }; |
| 14 | + |
| 15 | +$.mobile.popup.handleLink = handleLink; |
| 16 | + |
| 17 | +$.widget( "mobile.popup", $.mobile.popup, { |
| 18 | + options: { |
| 19 | + align: "0.5,0.5" |
| 20 | + }, |
| 21 | + |
| 22 | + open: function( options ) { |
| 23 | + this._ui.link = lastLink; |
| 24 | + return this._super( options ); |
| 25 | + }, |
| 26 | + |
| 27 | + _closePrereqsDone: function() { |
| 28 | + this._ui.link = null; |
| 29 | + this._superApply( arguments ); |
| 30 | + }, |
| 31 | + |
| 32 | + _alignmentToCoeffs: function( alignment ) { |
| 33 | + return { |
| 34 | + originCoeff: |
| 35 | + alignment < 0 ? 0 : |
| 36 | + alignment <= 1 ? alignment : |
| 37 | + 1, |
| 38 | + popupCoeff: |
| 39 | + alignment < 0 ? alignment : |
| 40 | + alignment <= 1 ? -alignment : |
| 41 | + alignment - 2 |
| 42 | + }; |
| 43 | + }, |
| 44 | + |
| 45 | + _getAlignment: function() { |
| 46 | + var ar, align; |
| 47 | + |
| 48 | + if ( this.options.align ) { |
| 49 | + ar = this.options.align.split( "," ); |
| 50 | + } |
| 51 | + |
| 52 | + if ( ar && ar.length > 0 ) { |
| 53 | + align = { |
| 54 | + x: parseFloat( ar[ 0 ] ), |
| 55 | + y: ar.length > 1 ? parseFloat( ar[ 1 ] ) : align.x |
| 56 | + }; |
| 57 | + } |
| 58 | + |
| 59 | + if ( align && !( isNaN( align.x ) || isNaN( align.y ) ) ) { |
| 60 | + return { |
| 61 | + x: this._alignmentToCoeffs( align.x ), |
| 62 | + y: this._alignmentToCoeffs( align.y ) |
| 63 | + }; |
| 64 | + } |
| 65 | + }, |
| 66 | + |
| 67 | + _setOptions: function( options ) { |
| 68 | + var linkOffset, linkSize; |
| 69 | + |
| 70 | + this._super( options ); |
| 71 | + |
| 72 | + if ( this._isOpen && |
| 73 | + options.align !== undefined && |
| 74 | + this._ui.link !== null && |
| 75 | + ( this._ui.link.jqmData( "position-to" ) === "origin" || |
| 76 | + this.options.positionTo === "origin" ) ) { |
| 77 | + linkOffset = this._ui.link.offset(); |
| 78 | + linkSize = { |
| 79 | + cx: this._ui.link.outerWidth(), |
| 80 | + cy: this._ui.link.outerHeight() |
| 81 | + }; |
| 82 | + |
| 83 | + this._reposition({ |
| 84 | + x: linkOffset.left + linkSize.cx / 2, |
| 85 | + y: linkOffset.top + linkSize.cy / 2, |
| 86 | + positionTo: "origin" |
| 87 | + }); |
| 88 | + } |
| 89 | + }, |
| 90 | + |
| 91 | + _alignedCoord: function( start, coeffs, originSize, popupSize ) { |
| 92 | + return ( |
| 93 | + |
| 94 | + // Start at the origin |
| 95 | + start + |
| 96 | + |
| 97 | + // Apply lignment |
| 98 | + coeffs.originCoeff * originSize + coeffs.popupCoeff * popupSize + |
| 99 | + |
| 100 | + // Resulting coordinate needs to be that of the middle of the popup, so |
| 101 | + // add half a popup width |
| 102 | + popupSize / 2 ); |
| 103 | + }, |
| 104 | + |
| 105 | + _desiredCoords: function( options ) { |
| 106 | + var linkBox, offset, clampInfo, |
| 107 | + alignment = this._getAlignment(); |
| 108 | + |
| 109 | + if ( alignment && options.positionTo === "origin" && this._ui.link ) { |
| 110 | + |
| 111 | + // Grab the size of the popup and the offset and size of the link |
| 112 | + clampInfo = this._clampPopupWidth( true ); |
| 113 | + clampInfo.menuSize.cx = Math.min( clampInfo.menuSize.cx, clampInfo.rc.cx ); |
| 114 | + offset = this._ui.link.offset(); |
| 115 | + linkBox = { |
| 116 | + x: offset.left, |
| 117 | + y: offset.top, |
| 118 | + cx: this._ui.link.outerWidth(), |
| 119 | + cy: this._ui.link.outerHeight() |
| 120 | + }; |
| 121 | + |
| 122 | + // Determine the desired coordinates of the middle of the popup |
| 123 | + options.x = this._alignedCoord( linkBox.x, alignment.x, linkBox.cx, clampInfo.menuSize.cx ); |
| 124 | + options.y = this._alignedCoord( linkBox.y, alignment.y, linkBox.cy, clampInfo.menuSize.cy ); |
| 125 | + } |
| 126 | + |
| 127 | + return this._super( options ); |
| 128 | + } |
| 129 | + |
| 130 | +}); |
| 131 | + |
| 132 | +})( jQuery ); |
0 commit comments