/** * @class Ext.dom.AbstractElement */ Ext.dom.AbstractElement.override({ /** * Gets the x,y coordinates specified by the anchor position on the element. * @param {String} [anchor] The specified anchor position (defaults to "c"). See {@link Ext.dom.Element#alignTo} * for details on supported anchor positions. * @param {Boolean} [local] True to get the local (element top/left-relative) anchor position instead * of page coordinates * @param {Object} [size] An object containing the size to use for calculating anchor position * {width: (target width), height: (target height)} (defaults to the element's current size) * @return {Array} [x, y] An array containing the element's x and y coordinates */ getAnchorXY: function(anchor, local, size) { //Passing a different size is useful for pre-calculating anchors, //especially for anchored animations that change the el size. anchor = (anchor || "tl").toLowerCase(); size = size || {}; var me = this, vp = me.dom == document.body || me.dom == document, width = size.width || vp ? window.innerWidth: me.getWidth(), height = size.height || vp ? window.innerHeight: me.getHeight(), xy, rnd = Math.round, myXY = me.getXY(), extraX = vp ? 0: !local ? myXY[0] : 0, extraY = vp ? 0: !local ? myXY[1] : 0, hash = { c: [rnd(width * 0.5), rnd(height * 0.5)], t: [rnd(width * 0.5), 0], l: [0, rnd(height * 0.5)], r: [width, rnd(height * 0.5)], b: [rnd(width * 0.5), height], tl: [0, 0], bl: [0, height], br: [width, height], tr: [width, 0] }; xy = hash[anchor]; return [xy[0] + extraX, xy[1] + extraY]; }, alignToRe: /^([a-z]+)-([a-z]+)(\?)?$/, /** * Gets the x,y coordinates to align this element with another element. See {@link Ext.dom.Element#alignTo} for more info on the * supported position values. * @param {Ext.Element/HTMLElement/String} element The element to align to. * @param {String} [position="tl-bl?"] The position to align to. * @param {Array} [offsets=[0,0]] Offset the positioning by [x, y] * @return {Array} [x, y] */ getAlignToXY: function(el, position, offsets, local) { local = !!local; el = Ext.get(el); // if (!el || !el.dom) { throw new Error("Element.alignToXY with an element that doesn't exist"); } // offsets = offsets || [0, 0]; if (!position || position == '?') { position = 'tl-bl?'; } else if (! (/-/).test(position) && position !== "") { position = 'tl-' + position; } position = position.toLowerCase(); var me = this, matches = position.match(this.alignToRe), dw = window.innerWidth, dh = window.innerHeight, p1 = "", p2 = "", a1, a2, x, y, swapX, swapY, p1x, p1y, p2x, p2y, width, height, region, constrain; if (!matches) { throw "Element.alignTo with an invalid alignment " + position; } p1 = matches[1]; p2 = matches[2]; constrain = !!matches[3]; //Subtract the aligned el's internal xy from the target's offset xy //plus custom offset to get the aligned el's new offset xy a1 = me.getAnchorXY(p1, true); a2 = el.getAnchorXY(p2, local); x = a2[0] - a1[0] + offsets[0]; y = a2[1] - a1[1] + offsets[1]; if (constrain) { width = me.getWidth(); height = me.getHeight(); region = el.getPageBox(); //If we are at a viewport boundary and the aligned el is anchored on a target border that is //perpendicular to the vp border, allow the aligned el to slide on that border, //otherwise swap the aligned el to the opposite border of the target. p1y = p1.charAt(0); p1x = p1.charAt(p1.length - 1); p2y = p2.charAt(0); p2x = p2.charAt(p2.length - 1); swapY = ((p1y == "t" && p2y == "b") || (p1y == "b" && p2y == "t")); swapX = ((p1x == "r" && p2x == "l") || (p1x == "l" && p2x == "r")); if (x + width > dw) { x = swapX ? region.left - width: dw - width; } if (x < 0) { x = swapX ? region.right: 0; } if (y + height > dh) { y = swapY ? region.top - height: dh - height; } if (y < 0) { y = swapY ? region.bottom: 0; } } return [x, y]; }, // private getAnchor: function(){ var data = (this.$cache || this.getCache()).data, anchor; if (!this.dom) { return; } anchor = data._anchor; if(!anchor){ anchor = data._anchor = {}; } return anchor; }, // private ==> used outside of core adjustForConstraints: function(xy, parent) { var vector = this.getConstrainVector(parent, xy); if (vector) { xy[0] += vector[0]; xy[1] += vector[1]; } return xy; } });