update components
This commit is contained in:
parent
1f41a29864
commit
ba749de15d
18 changed files with 482 additions and 369 deletions
|
@ -16,12 +16,12 @@
|
||||||
},
|
},
|
||||||
"devDependencies": {},
|
"devDependencies": {},
|
||||||
"ignore": [],
|
"ignore": [],
|
||||||
"version": "1.1.33",
|
"version": "1.1.37",
|
||||||
"_release": "1.1.33",
|
"_release": "1.1.37",
|
||||||
"_resolution": {
|
"_resolution": {
|
||||||
"type": "version",
|
"type": "version",
|
||||||
"tag": "1.1.33",
|
"tag": "1.1.37",
|
||||||
"commit": "9933aefe464ffcf5a3a29851ec0f34ff088d0ff5"
|
"commit": "7235838b8cff53a9bb2aea7d6c6418160728cd3a"
|
||||||
},
|
},
|
||||||
"_source": "git://github.com/MediaBrowser/emby-webcomponents.git",
|
"_source": "git://github.com/MediaBrowser/emby-webcomponents.git",
|
||||||
"_target": "~1.1.5",
|
"_target": "~1.1.5",
|
||||||
|
|
|
@ -99,6 +99,7 @@
|
||||||
browser.web0s = userAgent.toLowerCase().indexOf('Web0S'.toLowerCase()) != -1;
|
browser.web0s = userAgent.toLowerCase().indexOf('Web0S'.toLowerCase()) != -1;
|
||||||
|
|
||||||
browser.tv = isTv();
|
browser.tv = isTv();
|
||||||
|
browser.operaTv = browser.tv && userAgent.toLowerCase().indexOf('opr/') != -1;
|
||||||
|
|
||||||
return browser;
|
return browser;
|
||||||
});
|
});
|
|
@ -88,6 +88,12 @@ define(['browser'], function (browser) {
|
||||||
|
|
||||||
// Unfortunately there's no real way to detect mkv support
|
// Unfortunately there's no real way to detect mkv support
|
||||||
if (browser.chrome) {
|
if (browser.chrome) {
|
||||||
|
|
||||||
|
// Not supported on opera tv
|
||||||
|
if (browser.operaTv) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -125,6 +131,15 @@ define(['browser'], function (browser) {
|
||||||
case 'wmv':
|
case 'wmv':
|
||||||
supported = browser.tizen || browser.web0s;
|
supported = browser.tizen || browser.web0s;
|
||||||
break;
|
break;
|
||||||
|
case 'ts':
|
||||||
|
supported = browser.tizen || browser.web0s;
|
||||||
|
if (supported) {
|
||||||
|
return {
|
||||||
|
Container: 'ts,mpegts',
|
||||||
|
Type: 'Video'
|
||||||
|
};
|
||||||
|
}
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -231,17 +246,8 @@ define(['browser'], function (browser) {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
if (canPlayTs) {
|
|
||||||
profile.DirectPlayProfiles.push({
|
|
||||||
Container: 'ts,mpegts',
|
|
||||||
Type: 'Video',
|
|
||||||
VideoCodec: 'h264',
|
|
||||||
AudioCodec: videoAudioCodecs.join(',')
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
// These are formats we can't test for but some devices will support
|
// These are formats we can't test for but some devices will support
|
||||||
['m2ts', 'wmv'].map(getDirectPlayProfileForVideoContainer).filter(function (i) {
|
['m2ts', 'wmv', 'ts'].map(getDirectPlayProfileForVideoContainer).filter(function (i) {
|
||||||
return i != null;
|
return i != null;
|
||||||
|
|
||||||
}).forEach(function (i) {
|
}).forEach(function (i) {
|
||||||
|
|
|
@ -5,8 +5,8 @@ define(['visibleinviewport', 'imageFetcher'], function (visibleinviewport, image
|
||||||
|
|
||||||
var wheelEvent = (document.implementation.hasFeature('Event.wheel', '3.0') ? 'wheel' : 'mousewheel');
|
var wheelEvent = (document.implementation.hasFeature('Event.wheel', '3.0') ? 'wheel' : 'mousewheel');
|
||||||
|
|
||||||
function isVisible(elem) {
|
function isVisible(elem, windowSize) {
|
||||||
return visibleinviewport(elem, true, thresholdX, thresholdY);
|
return visibleinviewport(elem, true, thresholdX, thresholdY, windowSize);
|
||||||
}
|
}
|
||||||
|
|
||||||
var self = {};
|
var self = {};
|
||||||
|
@ -56,6 +56,11 @@ define(['visibleinviewport', 'imageFetcher'], function (visibleinviewport, image
|
||||||
var anyFound = false;
|
var anyFound = false;
|
||||||
var out = false;
|
var out = false;
|
||||||
|
|
||||||
|
var windowSize = {
|
||||||
|
innerHeight: window.innerHeight,
|
||||||
|
innerWidth: window.innerWidth
|
||||||
|
};
|
||||||
|
|
||||||
// TODO: This out construct assumes left to right, top to bottom
|
// TODO: This out construct assumes left to right, top to bottom
|
||||||
|
|
||||||
for (var i = 0, length = images.length; i < length; i++) {
|
for (var i = 0, length = images.length; i < length; i++) {
|
||||||
|
@ -64,7 +69,7 @@ define(['visibleinviewport', 'imageFetcher'], function (visibleinviewport, image
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
var img = images[i];
|
var img = images[i];
|
||||||
if (!out && isVisible(img)) {
|
if (!out && isVisible(img, windowSize)) {
|
||||||
anyFound = true;
|
anyFound = true;
|
||||||
fillImage(img);
|
fillImage(img);
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -1,31 +1,54 @@
|
||||||
define(['focusManager'], function (focusManager) {
|
define(['focusManager'], function (focusManager) {
|
||||||
|
|
||||||
function getOffset(elem) {
|
function getOffsets(elems) {
|
||||||
|
|
||||||
var doc = document;
|
var doc = document;
|
||||||
var box = { top: 0, left: 0 };
|
var results = [];
|
||||||
|
|
||||||
if (!doc) {
|
if (!doc) {
|
||||||
return box;
|
return results;
|
||||||
}
|
}
|
||||||
|
|
||||||
var docElem = doc.documentElement;
|
var docElem = doc.documentElement;
|
||||||
|
var docElemValues = {
|
||||||
// Support: BlackBerry 5, iOS 3 (original iPhone)
|
clientTop: docElem.clientTop,
|
||||||
// If we don't have gBCR, just use 0,0 rather than error
|
clientLeft: docElem.clientLeft
|
||||||
if (elem.getBoundingClientRect) {
|
|
||||||
box = elem.getBoundingClientRect();
|
|
||||||
}
|
|
||||||
var win = doc.defaultView;
|
|
||||||
return {
|
|
||||||
top: box.top + win.pageYOffset - docElem.clientTop,
|
|
||||||
left: box.left + win.pageXOffset - docElem.clientLeft
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
var win = doc.defaultView;
|
||||||
|
var winValues = {
|
||||||
|
pageXOffset: win.pageXOffset,
|
||||||
|
pageYOffset: win.pageYOffset
|
||||||
|
};
|
||||||
|
|
||||||
|
var box;
|
||||||
|
var elem;
|
||||||
|
|
||||||
|
for (var i = 0, length = elems.length; i < length; i++) {
|
||||||
|
|
||||||
|
elem = elems[i];
|
||||||
|
// Support: BlackBerry 5, iOS 3 (original iPhone)
|
||||||
|
// If we don't have gBCR, just use 0,0 rather than error
|
||||||
|
if (elem.getBoundingClientRect) {
|
||||||
|
box = elem.getBoundingClientRect();
|
||||||
|
} else {
|
||||||
|
box = { top: 0, left: 0 };
|
||||||
|
}
|
||||||
|
|
||||||
|
results[i] = {
|
||||||
|
top: box.top + winValues.pageYOffset - docElemValues.clientTop,
|
||||||
|
left: box.left + winValues.pageXOffset - docElemValues.clientLeft
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
return results;
|
||||||
}
|
}
|
||||||
|
|
||||||
function getPosition(scrollContainer, item, horizontal) {
|
function getPosition(scrollContainer, item, horizontal) {
|
||||||
var slideeOffset = getOffset(scrollContainer);
|
|
||||||
var itemOffset = getOffset(item);
|
var offsets = getOffsets([scrollContainer, item]);
|
||||||
|
var slideeOffset = offsets[0];
|
||||||
|
var itemOffset = offsets[1];
|
||||||
|
|
||||||
var offset = horizontal ? itemOffset.left - slideeOffset.left : itemOffset.top - slideeOffset.top;
|
var offset = horizontal ? itemOffset.left - slideeOffset.left : itemOffset.top - slideeOffset.top;
|
||||||
var size = item[horizontal ? 'offsetWidth' : 'offsetHeight'];
|
var size = item[horizontal ? 'offsetWidth' : 'offsetHeight'];
|
||||||
|
|
|
@ -10,17 +10,22 @@
|
||||||
* the user visible viewport of a web browser.
|
* the user visible viewport of a web browser.
|
||||||
* only accounts for vertical position, not horizontal.
|
* only accounts for vertical position, not horizontal.
|
||||||
*/
|
*/
|
||||||
function visibleInViewport(elem, partial, thresholdX, thresholdY) {
|
function visibleInViewport(elem, partial, thresholdX, thresholdY, windowSize) {
|
||||||
|
|
||||||
thresholdX = thresholdX || 0;
|
thresholdX = thresholdX || 0;
|
||||||
thresholdY = thresholdY || 0;
|
thresholdY = thresholdY || 0;
|
||||||
|
|
||||||
var vpWidth = window.innerWidth,
|
if (!elem.getBoundingClientRect) {
|
||||||
vpHeight = window.innerHeight;
|
return true;
|
||||||
|
}
|
||||||
if (!elem.getBoundingClientRect){
|
|
||||||
return true;
|
windowSize = windowSize || {
|
||||||
}
|
innerHeight: window.innerHeight,
|
||||||
|
innerWidth: window.innerWidth
|
||||||
|
};
|
||||||
|
|
||||||
|
var vpWidth = windowSize.innerWidth,
|
||||||
|
vpHeight = windowSize.innerHeight;
|
||||||
|
|
||||||
// Use this native browser method, if available.
|
// Use this native browser method, if available.
|
||||||
var rec = elem.getBoundingClientRect(),
|
var rec = elem.getBoundingClientRect(),
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
{
|
{
|
||||||
"name": "iron-dropdown",
|
"name": "iron-dropdown",
|
||||||
"version": "1.2.0",
|
"version": "1.3.0",
|
||||||
"description": "An unstyled element that works similarly to a native browser select",
|
"description": "An unstyled element that works similarly to a native browser select",
|
||||||
"authors": [
|
"authors": [
|
||||||
"The Polymer Authors"
|
"The Polymer Authors"
|
||||||
|
@ -36,11 +36,11 @@
|
||||||
"iron-image": "polymerelements/iron-image#^1.0.0"
|
"iron-image": "polymerelements/iron-image#^1.0.0"
|
||||||
},
|
},
|
||||||
"ignore": [],
|
"ignore": [],
|
||||||
"_release": "1.2.0",
|
"_release": "1.3.0",
|
||||||
"_resolution": {
|
"_resolution": {
|
||||||
"type": "version",
|
"type": "version",
|
||||||
"tag": "v1.2.0",
|
"tag": "v1.3.0",
|
||||||
"commit": "f864191c6ffbd3aaddea8102102ab40137046327"
|
"commit": "9d6bb9e7a8150430e61559f5a0827526d2eefaa4"
|
||||||
},
|
},
|
||||||
"_source": "git://github.com/polymerelements/iron-dropdown.git",
|
"_source": "git://github.com/polymerelements/iron-dropdown.git",
|
||||||
"_target": "^1.0.0",
|
"_target": "^1.0.0",
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
{
|
{
|
||||||
"name": "iron-dropdown",
|
"name": "iron-dropdown",
|
||||||
"version": "1.2.0",
|
"version": "1.3.0",
|
||||||
"description": "An unstyled element that works similarly to a native browser select",
|
"description": "An unstyled element that works similarly to a native browser select",
|
||||||
"authors": [
|
"authors": [
|
||||||
"The Polymer Authors"
|
"The Polymer Authors"
|
||||||
|
|
|
@ -175,9 +175,11 @@ subject to an additional IP rights grant found at http://polymer.github.io/PATEN
|
||||||
},
|
},
|
||||||
|
|
||||||
_scrollInteractionHandler: function(event) {
|
_scrollInteractionHandler: function(event) {
|
||||||
|
var scrolledElement =
|
||||||
|
/** @type {HTMLElement} */(Polymer.dom(event).rootTarget);
|
||||||
if (Polymer
|
if (Polymer
|
||||||
.IronDropdownScrollManager
|
.IronDropdownScrollManager
|
||||||
.elementIsScrollLocked(Polymer.dom(event).rootTarget)) {
|
.elementIsScrollLocked(scrolledElement)) {
|
||||||
if (event.type === 'keydown' &&
|
if (event.type === 'keydown' &&
|
||||||
!Polymer.IronDropdownScrollManager._isScrollingKeypress(event)) {
|
!Polymer.IronDropdownScrollManager._isScrollingKeypress(event)) {
|
||||||
return;
|
return;
|
||||||
|
|
|
@ -143,8 +143,7 @@ method is called on the element.
|
||||||
* it is opened.
|
* it is opened.
|
||||||
*/
|
*/
|
||||||
positionTarget: {
|
positionTarget: {
|
||||||
type: Object,
|
type: Object
|
||||||
observer: '_positionTargetChanged'
|
|
||||||
},
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -189,15 +188,6 @@ method is called on the element.
|
||||||
allowOutsideScroll: {
|
allowOutsideScroll: {
|
||||||
type: Boolean,
|
type: Boolean,
|
||||||
value: false
|
value: false
|
||||||
},
|
|
||||||
|
|
||||||
/**
|
|
||||||
* We memoize the positionTarget bounding rectangle so that we can
|
|
||||||
* limit the number of times it is queried per resize / relayout.
|
|
||||||
* @type {?Object}
|
|
||||||
*/
|
|
||||||
_positionRectMemo: {
|
|
||||||
type: Object
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
|
@ -206,13 +196,13 @@ method is called on the element.
|
||||||
},
|
},
|
||||||
|
|
||||||
observers: [
|
observers: [
|
||||||
'_updateOverlayPosition(verticalAlign, horizontalAlign, verticalOffset, horizontalOffset)'
|
'_updateOverlayPosition(positionTarget, verticalAlign, horizontalAlign, verticalOffset, horizontalOffset)'
|
||||||
],
|
],
|
||||||
|
|
||||||
attached: function() {
|
attached: function() {
|
||||||
if (this.positionTarget === undefined) {
|
this.positionTarget = this.positionTarget || this._defaultPositionTarget;
|
||||||
this.positionTarget = this._defaultPositionTarget;
|
// Memoize this to avoid expensive calculations & relayouts.
|
||||||
}
|
this._isRTL = window.getComputedStyle(this).direction == 'rtl';
|
||||||
},
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -230,13 +220,6 @@ method is called on the element.
|
||||||
return this.focusTarget || this.containedElement;
|
return this.focusTarget || this.containedElement;
|
||||||
},
|
},
|
||||||
|
|
||||||
/**
|
|
||||||
* Whether the text direction is RTL
|
|
||||||
*/
|
|
||||||
_isRTL: function() {
|
|
||||||
return window.getComputedStyle(this).direction == 'rtl';
|
|
||||||
},
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The element that should be used to position the dropdown when
|
* The element that should be used to position the dropdown when
|
||||||
* it opens, if no position target is configured.
|
* it opens, if no position target is configured.
|
||||||
|
@ -252,31 +235,32 @@ method is called on the element.
|
||||||
},
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The bounding rect of the position target.
|
* The horizontal align value, accounting for the RTL/LTR text direction.
|
||||||
*/
|
*/
|
||||||
get _positionRect() {
|
get _localeHorizontalAlign() {
|
||||||
if (!this._positionRectMemo && this.positionTarget) {
|
// In RTL, "left" becomes "right".
|
||||||
this._positionRectMemo = this.positionTarget.getBoundingClientRect();
|
if (this._isRTL) {
|
||||||
|
return this.horizontalAlign === 'right' ? 'left' : 'right';
|
||||||
|
} else {
|
||||||
|
return this.horizontalAlign;
|
||||||
}
|
}
|
||||||
|
|
||||||
return this._positionRectMemo;
|
|
||||||
},
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The horizontal offset value used to position the dropdown.
|
* The horizontal offset value used to position the dropdown.
|
||||||
|
* @param {ClientRect} dropdownRect
|
||||||
|
* @param {ClientRect} positionRect
|
||||||
|
* @param {boolean=false} fromRight
|
||||||
|
* @return {number} pixels
|
||||||
|
* @private
|
||||||
*/
|
*/
|
||||||
get _horizontalAlignTargetValue() {
|
_horizontalAlignTargetValue: function(dropdownRect, positionRect, fromRight) {
|
||||||
var target;
|
var target;
|
||||||
|
if (fromRight) {
|
||||||
// In RTL, the direction flips, so what is "right" in LTR becomes "left".
|
target = document.documentElement.clientWidth - positionRect.right - (this._fitWidth - dropdownRect.right);
|
||||||
var isRTL = this._isRTL();
|
|
||||||
if ((!isRTL && this.horizontalAlign === 'right') ||
|
|
||||||
(isRTL && this.horizontalAlign === 'left')) {
|
|
||||||
target = document.documentElement.clientWidth - this._positionRect.right;
|
|
||||||
} else {
|
} else {
|
||||||
target = this._positionRect.left;
|
target = positionRect.left - dropdownRect.left;
|
||||||
}
|
}
|
||||||
|
|
||||||
target += this.horizontalOffset;
|
target += this.horizontalOffset;
|
||||||
|
|
||||||
return Math.max(target, 0);
|
return Math.max(target, 0);
|
||||||
|
@ -284,33 +268,24 @@ method is called on the element.
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The vertical offset value used to position the dropdown.
|
* The vertical offset value used to position the dropdown.
|
||||||
|
* @param {ClientRect} dropdownRect
|
||||||
|
* @param {ClientRect} positionRect
|
||||||
|
* @param {boolean=false} fromBottom
|
||||||
|
* @return {number} pixels
|
||||||
|
* @private
|
||||||
*/
|
*/
|
||||||
get _verticalAlignTargetValue() {
|
_verticalAlignTargetValue: function(dropdownRect, positionRect, fromBottom) {
|
||||||
var target;
|
var target;
|
||||||
|
if (fromBottom) {
|
||||||
if (this.verticalAlign === 'bottom') {
|
target = document.documentElement.clientHeight - positionRect.bottom - (this._fitHeight - dropdownRect.bottom);
|
||||||
target = document.documentElement.clientHeight - this._positionRect.bottom;
|
|
||||||
} else {
|
} else {
|
||||||
target = this._positionRect.top;
|
target = positionRect.top - dropdownRect.top;
|
||||||
}
|
}
|
||||||
|
|
||||||
target += this.verticalOffset;
|
target += this.verticalOffset;
|
||||||
|
|
||||||
return Math.max(target, 0);
|
return Math.max(target, 0);
|
||||||
},
|
},
|
||||||
|
|
||||||
/**
|
|
||||||
* The horizontal align value, accounting for the RTL/LTR text direction.
|
|
||||||
*/
|
|
||||||
get _localeHorizontalAlign() {
|
|
||||||
// In RTL, "left" becomes "right".
|
|
||||||
if (this._isRTL()) {
|
|
||||||
return this.horizontalAlign === 'right' ? 'left' : 'right';
|
|
||||||
} else {
|
|
||||||
return this.horizontalAlign;
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Called when the value of `opened` changes.
|
* Called when the value of `opened` changes.
|
||||||
*
|
*
|
||||||
|
@ -321,7 +296,8 @@ method is called on the element.
|
||||||
this.cancel();
|
this.cancel();
|
||||||
} else {
|
} else {
|
||||||
this.cancelAnimation();
|
this.cancelAnimation();
|
||||||
this._prepareDropdown();
|
this.sizingTarget = this.containedElement || this.sizingTarget;
|
||||||
|
this._updateAnimationConfig();
|
||||||
Polymer.IronOverlayBehaviorImpl._openedChanged.apply(this, arguments);
|
Polymer.IronOverlayBehaviorImpl._openedChanged.apply(this, arguments);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
@ -335,6 +311,9 @@ method is called on the element.
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!this.noAnimations && this.animationConfig && this.animationConfig.open) {
|
if (!this.noAnimations && this.animationConfig && this.animationConfig.open) {
|
||||||
|
if (this.withBackdrop) {
|
||||||
|
this.backdropElement.open();
|
||||||
|
}
|
||||||
this.$.contentWrapper.classList.add('animating');
|
this.$.contentWrapper.classList.add('animating');
|
||||||
this.playAnimation('open');
|
this.playAnimation('open');
|
||||||
} else {
|
} else {
|
||||||
|
@ -348,6 +327,9 @@ method is called on the element.
|
||||||
_renderClosed: function() {
|
_renderClosed: function() {
|
||||||
Polymer.IronDropdownScrollManager.removeScrollLock(this);
|
Polymer.IronDropdownScrollManager.removeScrollLock(this);
|
||||||
if (!this.noAnimations && this.animationConfig && this.animationConfig.close) {
|
if (!this.noAnimations && this.animationConfig && this.animationConfig.close) {
|
||||||
|
if (this.withBackdrop) {
|
||||||
|
this.backdropElement.close();
|
||||||
|
}
|
||||||
this.$.contentWrapper.classList.add('animating');
|
this.$.contentWrapper.classList.add('animating');
|
||||||
this.playAnimation('close');
|
this.playAnimation('close');
|
||||||
} else {
|
} else {
|
||||||
|
@ -364,44 +346,12 @@ method is called on the element.
|
||||||
_onNeonAnimationFinish: function() {
|
_onNeonAnimationFinish: function() {
|
||||||
this.$.contentWrapper.classList.remove('animating');
|
this.$.contentWrapper.classList.remove('animating');
|
||||||
if (this.opened) {
|
if (this.opened) {
|
||||||
Polymer.IronOverlayBehaviorImpl._renderOpened.apply(this);
|
Polymer.IronOverlayBehaviorImpl._finishRenderOpened.apply(this);
|
||||||
} else {
|
} else {
|
||||||
Polymer.IronOverlayBehaviorImpl._renderClosed.apply(this);
|
Polymer.IronOverlayBehaviorImpl._finishRenderClosed.apply(this);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
/**
|
|
||||||
* Called when an `iron-resize` event fires.
|
|
||||||
*/
|
|
||||||
_onIronResize: function() {
|
|
||||||
var containedElement = this.containedElement;
|
|
||||||
var scrollTop;
|
|
||||||
var scrollLeft;
|
|
||||||
|
|
||||||
if (this.opened && containedElement) {
|
|
||||||
scrollTop = containedElement.scrollTop;
|
|
||||||
scrollLeft = containedElement.scrollLeft;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (this.opened) {
|
|
||||||
this._updateOverlayPosition();
|
|
||||||
}
|
|
||||||
|
|
||||||
Polymer.IronOverlayBehaviorImpl._onIronResize.apply(this, arguments);
|
|
||||||
|
|
||||||
if (this.opened && containedElement) {
|
|
||||||
containedElement.scrollTop = scrollTop;
|
|
||||||
containedElement.scrollLeft = scrollLeft;
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Called when the `positionTarget` property changes.
|
|
||||||
*/
|
|
||||||
_positionTargetChanged: function() {
|
|
||||||
this._updateOverlayPosition();
|
|
||||||
},
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Constructs the final animation config from different properties used
|
* Constructs the final animation config from different properties used
|
||||||
* to configure specific parts of the opening and closing animations.
|
* to configure specific parts of the opening and closing animations.
|
||||||
|
@ -434,43 +384,73 @@ method is called on the element.
|
||||||
},
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Prepares the dropdown for opening by updating measured layout
|
* Updates the overlay position based on configured horizontal
|
||||||
* values.
|
* and vertical alignment.
|
||||||
*/
|
*/
|
||||||
_prepareDropdown: function() {
|
_updateOverlayPosition: function() {
|
||||||
this.sizingTarget = this.containedElement || this.sizingTarget;
|
if (this.isAttached) {
|
||||||
this._updateAnimationConfig();
|
// This triggers iron-resize, and iron-overlay-behavior will call refit if needed.
|
||||||
this._updateOverlayPosition();
|
this.notifyResize();
|
||||||
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Updates the overlay position based on configured horizontal
|
* Useful to call this after the element, the window, or the `fitInfo`
|
||||||
* and vertical alignment, and re-memoizes these values for the sake
|
* element has been resized. Will maintain the scroll position.
|
||||||
* of behavior in `IronFitBehavior`.
|
|
||||||
*/
|
*/
|
||||||
_updateOverlayPosition: function() {
|
refit: function () {
|
||||||
this._positionRectMemo = null;
|
if (!this.opened) {
|
||||||
|
return
|
||||||
if (!this.positionTarget) {
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
var containedElement = this.containedElement;
|
||||||
|
var scrollTop;
|
||||||
|
var scrollLeft;
|
||||||
|
|
||||||
this.style[this._localeHorizontalAlign] =
|
if (containedElement) {
|
||||||
this._horizontalAlignTargetValue + 'px';
|
scrollTop = containedElement.scrollTop;
|
||||||
|
scrollLeft = containedElement.scrollLeft;
|
||||||
this.style[this.verticalAlign] =
|
|
||||||
this._verticalAlignTargetValue + 'px';
|
|
||||||
|
|
||||||
// NOTE(cdata): We re-memoize inline styles here, otherwise
|
|
||||||
// calling `refit` from `IronFitBehavior` will reset inline styles
|
|
||||||
// to whatever they were when the dropdown first opened.
|
|
||||||
if (this._fitInfo) {
|
|
||||||
this._fitInfo.inlineStyle[this.horizontalAlign] =
|
|
||||||
this.style[this.horizontalAlign];
|
|
||||||
|
|
||||||
this._fitInfo.inlineStyle[this.verticalAlign] =
|
|
||||||
this.style[this.verticalAlign];
|
|
||||||
}
|
}
|
||||||
|
Polymer.IronFitBehavior.refit.apply(this, arguments);
|
||||||
|
|
||||||
|
if (containedElement) {
|
||||||
|
containedElement.scrollTop = scrollTop;
|
||||||
|
containedElement.scrollLeft = scrollLeft;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Resets the target element's position and size constraints, and clear
|
||||||
|
* the memoized data.
|
||||||
|
*/
|
||||||
|
resetFit: function() {
|
||||||
|
Polymer.IronFitBehavior.resetFit.apply(this, arguments);
|
||||||
|
|
||||||
|
var hAlign = this._localeHorizontalAlign;
|
||||||
|
var vAlign = this.verticalAlign;
|
||||||
|
// Set to 0, 0 in order to discover any offset caused by parent stacking contexts.
|
||||||
|
this.style[hAlign] = this.style[vAlign] = '0px';
|
||||||
|
|
||||||
|
var dropdownRect = this.getBoundingClientRect();
|
||||||
|
var positionRect = this.positionTarget.getBoundingClientRect();
|
||||||
|
var horizontalValue = this._horizontalAlignTargetValue(dropdownRect, positionRect, hAlign === 'right');
|
||||||
|
var verticalValue = this._verticalAlignTargetValue(dropdownRect, positionRect, vAlign === 'bottom');
|
||||||
|
|
||||||
|
this.style[hAlign] = horizontalValue + 'px';
|
||||||
|
this.style[vAlign] = verticalValue + 'px';
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Overridden from `IronFitBehavior`.
|
||||||
|
* Ensure positionedBy has correct values for horizontally & vertically.
|
||||||
|
*/
|
||||||
|
_discoverInfo: function() {
|
||||||
|
Polymer.IronFitBehavior._discoverInfo.apply(this, arguments);
|
||||||
|
// Note(valdrin): in Firefox, an element with style `position: fixed; bottom: 90vh; height: 20vh`
|
||||||
|
// would have `getComputedStyle(element).top < 0` (instead of being `auto`) http://jsbin.com/cofired/3/edit?html,output
|
||||||
|
// This would cause IronFitBehavior's `constrain` to wrongly calculate sizes
|
||||||
|
// (it would use `top` instead of `bottom`), so we ensure we give the correct values.
|
||||||
|
this._fitInfo.positionedBy.horizontally = this._localeHorizontalAlign;
|
||||||
|
this._fitInfo.positionedBy.vertically = this.verticalAlign;
|
||||||
},
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -28,13 +28,38 @@ subject to an additional IP rights grant found at http://polymer.github.io/PATEN
|
||||||
margin: 0;
|
margin: 0;
|
||||||
padding: 0;
|
padding: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.container {
|
||||||
|
display: block;
|
||||||
|
position: relative;
|
||||||
|
width: 100px;
|
||||||
|
height: 100px;
|
||||||
|
background-color: yellow;
|
||||||
|
}
|
||||||
|
|
||||||
|
.positioned {
|
||||||
|
position: absolute;
|
||||||
|
top: 40px;
|
||||||
|
left: 40px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.dropdown-content {
|
||||||
|
width: 50px;
|
||||||
|
height: 50px;
|
||||||
|
background-color: orange;
|
||||||
|
}
|
||||||
|
|
||||||
|
.full-screen {
|
||||||
|
width: 100vw;
|
||||||
|
height: 100vh;
|
||||||
|
}
|
||||||
</style>
|
</style>
|
||||||
<body>
|
<body>
|
||||||
|
|
||||||
<test-fixture id="TrivialDropdown">
|
<test-fixture id="TrivialDropdown">
|
||||||
<template>
|
<template>
|
||||||
<iron-dropdown>
|
<iron-dropdown>
|
||||||
<div class="dropdown-content">Hello!</div>
|
<div class="dropdown-content"></div>
|
||||||
</iron-dropdown>
|
</iron-dropdown>
|
||||||
</template>
|
</template>
|
||||||
</test-fixture>
|
</test-fixture>
|
||||||
|
@ -49,9 +74,9 @@ subject to an additional IP rights grant found at http://polymer.github.io/PATEN
|
||||||
|
|
||||||
<test-fixture id="AlignedDropdown">
|
<test-fixture id="AlignedDropdown">
|
||||||
<template>
|
<template>
|
||||||
<div style="display: block; position: relative; width: 100px; height: 100px;">
|
<div class="container">
|
||||||
<iron-dropdown horizontal-align="right" vertical-align="top">
|
<iron-dropdown horizontal-align="right" vertical-align="top">
|
||||||
<div class="dropdown-content">Hello!</div>
|
<div class="dropdown-content full-screen"></div>
|
||||||
</iron-dropdown>
|
</iron-dropdown>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
@ -60,9 +85,9 @@ subject to an additional IP rights grant found at http://polymer.github.io/PATEN
|
||||||
<!-- Absolutely position the dropdown so that it has enough space to move around -->
|
<!-- Absolutely position the dropdown so that it has enough space to move around -->
|
||||||
<test-fixture id="OffsetDropdownTopLeft">
|
<test-fixture id="OffsetDropdownTopLeft">
|
||||||
<template>
|
<template>
|
||||||
<div style="display: block; position: absolute; top: 40px; left: 40px; width: 100px; height: 100px;">
|
<div class="container positioned">
|
||||||
<iron-dropdown>
|
<iron-dropdown>
|
||||||
<div class="dropdown-content">Hello!</div>
|
<div class="dropdown-content"></div>
|
||||||
</iron-dropdown>
|
</iron-dropdown>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
@ -70,9 +95,9 @@ subject to an additional IP rights grant found at http://polymer.github.io/PATEN
|
||||||
|
|
||||||
<test-fixture id="OffsetDropdownBottomRight">
|
<test-fixture id="OffsetDropdownBottomRight">
|
||||||
<template>
|
<template>
|
||||||
<div style="display: block; position: absolute; top: 40px; left: 40px; width: 100px; height: 100px;">
|
<div class="container positioned">
|
||||||
<iron-dropdown horizontal-align="right" vertical-align="bottom">
|
<iron-dropdown horizontal-align="right" vertical-align="bottom">
|
||||||
<div class="dropdown-content">Hello!</div>
|
<div class="dropdown-content"></div>
|
||||||
</iron-dropdown>
|
</iron-dropdown>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
@ -90,9 +115,9 @@ subject to an additional IP rights grant found at http://polymer.github.io/PATEN
|
||||||
|
|
||||||
<test-fixture id="RTLDropdownLeft">
|
<test-fixture id="RTLDropdownLeft">
|
||||||
<template>
|
<template>
|
||||||
<div dir="rtl" style="display: block; position: relative; width: 100px; height: 100px;">
|
<div dir="rtl" class="container">
|
||||||
<iron-dropdown>
|
<iron-dropdown>
|
||||||
<div class="dropdown-content">Hello!</div>
|
<div class="dropdown-content"></div>
|
||||||
</iron-dropdown>
|
</iron-dropdown>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
@ -100,9 +125,9 @@ subject to an additional IP rights grant found at http://polymer.github.io/PATEN
|
||||||
|
|
||||||
<test-fixture id="RTLDropdownRight">
|
<test-fixture id="RTLDropdownRight">
|
||||||
<template>
|
<template>
|
||||||
<div dir="rtl" style="display: block; position: relative; width: 100px; height: 100px;">
|
<div dir="rtl" class="container">
|
||||||
<iron-dropdown horizontal-align="right">
|
<iron-dropdown horizontal-align="right">
|
||||||
<div class="dropdown-content">Hello!</div>
|
<div class="dropdown-content"></div>
|
||||||
</iron-dropdown>
|
</iron-dropdown>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
@ -196,7 +221,7 @@ subject to an additional IP rights grant found at http://polymer.github.io/PATEN
|
||||||
.to.be.equal(1);
|
.to.be.equal(1);
|
||||||
expect(Polymer.IronDropdownScrollManager.elementIsScrollLocked(document.body))
|
expect(Polymer.IronDropdownScrollManager.elementIsScrollLocked(document.body))
|
||||||
.to.be.equal(true);
|
.to.be.equal(true);
|
||||||
|
|
||||||
if(openCount === 0) {
|
if(openCount === 0) {
|
||||||
// This triggers a second `pushScrollLock` with the same element, however
|
// This triggers a second `pushScrollLock` with the same element, however
|
||||||
// that should not add the element to the `_lockingElements` stack twice
|
// that should not add the element to the `_lockingElements` stack twice
|
||||||
|
@ -240,11 +265,10 @@ subject to an additional IP rights grant found at http://polymer.github.io/PATEN
|
||||||
runAfterOpen(dropdown, function () {
|
runAfterOpen(dropdown, function () {
|
||||||
dropdownRect = dropdown.getBoundingClientRect();
|
dropdownRect = dropdown.getBoundingClientRect();
|
||||||
parentRect = parent.getBoundingClientRect();
|
parentRect = parent.getBoundingClientRect();
|
||||||
|
assert.equal(dropdownRect.top, parentRect.top, 'top ok');
|
||||||
// NOTE(cdata): IE10 / 11 have minor rounding errors in this case,
|
assert.equal(dropdownRect.left, 0, 'left ok');
|
||||||
// so we assert with `closeTo` and a tight threshold:
|
assert.equal(dropdownRect.bottom, document.documentElement.clientHeight, 'bottom ok');
|
||||||
expect(dropdownRect.top).to.be.closeTo(parentRect.top, 0.1);
|
assert.equal(dropdownRect.right, parentRect.right, 'right ok');
|
||||||
expect(dropdownRect.right).to.be.closeTo(parentRect.right, 0.1);
|
|
||||||
done();
|
done();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
@ -257,11 +281,26 @@ subject to an additional IP rights grant found at http://polymer.github.io/PATEN
|
||||||
runAfterOpen(dropdown, function () {
|
runAfterOpen(dropdown, function () {
|
||||||
parentRect = parent.getBoundingClientRect();
|
parentRect = parent.getBoundingClientRect();
|
||||||
dropdownRect = dropdown.getBoundingClientRect();
|
dropdownRect = dropdown.getBoundingClientRect();
|
||||||
|
assert.equal(dropdownRect.top, 0, 'top ok');
|
||||||
|
assert.equal(dropdownRect.left, 0, 'left ok');
|
||||||
|
assert.equal(dropdownRect.bottom, parentRect.bottom, 'bottom ok');
|
||||||
|
assert.equal(dropdownRect.right, parentRect.right, 'right ok');
|
||||||
|
done();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
// NOTE(cdata): IE10 / 11 have minor rounding errors in this case,
|
test('handles parent\'s stacking context', function(done) {
|
||||||
// so we assert with `closeTo` and a tight threshold:
|
var parentRect;
|
||||||
expect(dropdownRect.bottom).to.be.closeTo(parentRect.bottom, 0.1);
|
var dropdownRect;
|
||||||
expect(dropdownRect.right).to.be.closeTo(parentRect.right, 0.1);
|
// This will create a new stacking context.
|
||||||
|
parent.style.transform = 'translateZ(0)';
|
||||||
|
runAfterOpen(dropdown, function () {
|
||||||
|
dropdownRect = dropdown.getBoundingClientRect();
|
||||||
|
parentRect = parent.getBoundingClientRect();
|
||||||
|
assert.equal(dropdownRect.top, parentRect.top, 'top ok');
|
||||||
|
assert.equal(dropdownRect.left, 0, 'left ok');
|
||||||
|
assert.equal(dropdownRect.bottom, document.documentElement.clientHeight, 'bottom ok');
|
||||||
|
assert.equal(dropdownRect.right, parentRect.right, 'right ok');
|
||||||
done();
|
done();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
@ -285,9 +324,9 @@ subject to an additional IP rights grant found at http://polymer.github.io/PATEN
|
||||||
offsetDropdownRect = dropdown.getBoundingClientRect();
|
offsetDropdownRect = dropdown.getBoundingClientRect();
|
||||||
|
|
||||||
// verticalAlign is top, so a positive offset moves down.
|
// verticalAlign is top, so a positive offset moves down.
|
||||||
expect(dropdownRect.top + 10).to.be.closeTo(offsetDropdownRect.top, 0.1);
|
assert.equal(dropdownRect.top + 10, offsetDropdownRect.top, 'top ok');
|
||||||
// horizontalAlign is left, so a positive offset moves to the right.
|
// horizontalAlign is left, so a positive offset moves to the right.
|
||||||
expect(dropdownRect.left + 10).to.be.closeTo(offsetDropdownRect.left, 0.1);
|
assert.equal(dropdownRect.left + 10, offsetDropdownRect.left, 'left ok');
|
||||||
done();
|
done();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
@ -301,9 +340,9 @@ subject to an additional IP rights grant found at http://polymer.github.io/PATEN
|
||||||
offsetDropdownRect = dropdown.getBoundingClientRect();
|
offsetDropdownRect = dropdown.getBoundingClientRect();
|
||||||
|
|
||||||
// verticalAlign is top, so a negative offset moves up.
|
// verticalAlign is top, so a negative offset moves up.
|
||||||
expect(dropdownRect.top - 10).to.be.closeTo(offsetDropdownRect.top, 0.1);
|
assert.equal(dropdownRect.top - 10, offsetDropdownRect.top, 'top ok');
|
||||||
// horizontalAlign is left, so a negative offset moves to the left.
|
// horizontalAlign is left, so a negative offset moves to the left.
|
||||||
expect(dropdownRect.left - 10).to.be.closeTo(offsetDropdownRect.left, 0.1);
|
assert.equal(dropdownRect.left - 10, offsetDropdownRect.left, 'left ok');
|
||||||
done();
|
done();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
@ -327,9 +366,9 @@ subject to an additional IP rights grant found at http://polymer.github.io/PATEN
|
||||||
offsetDropdownRect = dropdown.getBoundingClientRect();
|
offsetDropdownRect = dropdown.getBoundingClientRect();
|
||||||
|
|
||||||
// verticalAlign is bottom, so a positive offset moves up.
|
// verticalAlign is bottom, so a positive offset moves up.
|
||||||
expect(dropdownRect.bottom - 10).to.be.closeTo(offsetDropdownRect.bottom, 0.1);
|
assert.equal(dropdownRect.bottom - 10, offsetDropdownRect.bottom, 'bottom ok');
|
||||||
// horizontalAlign is right, so a positive offset moves to the left.
|
// horizontalAlign is right, so a positive offset moves to the left.
|
||||||
expect(dropdownRect.right - 10).to.be.closeTo(offsetDropdownRect.right, 0.1);
|
assert.equal(dropdownRect.right - 10, offsetDropdownRect.right, 'right ok');
|
||||||
done();
|
done();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
@ -343,9 +382,9 @@ subject to an additional IP rights grant found at http://polymer.github.io/PATEN
|
||||||
offsetDropdownRect = dropdown.getBoundingClientRect();
|
offsetDropdownRect = dropdown.getBoundingClientRect();
|
||||||
|
|
||||||
// verticalAlign is bottom, so a negative offset moves down.
|
// verticalAlign is bottom, so a negative offset moves down.
|
||||||
expect(dropdownRect.bottom + 10).to.be.closeTo(offsetDropdownRect.bottom, 0.1);
|
assert.equal(dropdownRect.bottom + 10, offsetDropdownRect.bottom, 'bottom ok');
|
||||||
// horizontalAlign is right, so a positive offset moves to the right.
|
// horizontalAlign is right, so a positive offset moves to the right.
|
||||||
expect(dropdownRect.right + 10).to.be.closeTo(offsetDropdownRect.right, 0.1);
|
assert.equal(dropdownRect.right + 10, offsetDropdownRect.right, 'right ok');
|
||||||
done();
|
done();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
|
@ -32,14 +32,14 @@
|
||||||
"web-component-tester": "^4.0.0",
|
"web-component-tester": "^4.0.0",
|
||||||
"webcomponentsjs": "webcomponents/webcomponentsjs#^0.7.0"
|
"webcomponentsjs": "webcomponents/webcomponentsjs#^0.7.0"
|
||||||
},
|
},
|
||||||
"homepage": "https://github.com/PolymerElements/iron-icon",
|
"homepage": "https://github.com/polymerelements/iron-icon",
|
||||||
"_release": "1.0.8",
|
"_release": "1.0.8",
|
||||||
"_resolution": {
|
"_resolution": {
|
||||||
"type": "version",
|
"type": "version",
|
||||||
"tag": "v1.0.8",
|
"tag": "v1.0.8",
|
||||||
"commit": "f36b38928849ef3853db727faa8c9ef104d611eb"
|
"commit": "f36b38928849ef3853db727faa8c9ef104d611eb"
|
||||||
},
|
},
|
||||||
"_source": "git://github.com/PolymerElements/iron-icon.git",
|
"_source": "git://github.com/polymerelements/iron-icon.git",
|
||||||
"_target": "^1.0.0",
|
"_target": "^1.0.0",
|
||||||
"_originalSource": "PolymerElements/iron-icon"
|
"_originalSource": "polymerelements/iron-icon"
|
||||||
}
|
}
|
|
@ -1,6 +1,6 @@
|
||||||
{
|
{
|
||||||
"name": "iron-overlay-behavior",
|
"name": "iron-overlay-behavior",
|
||||||
"version": "1.4.2",
|
"version": "1.4.3",
|
||||||
"license": "http://polymer.github.io/LICENSE.txt",
|
"license": "http://polymer.github.io/LICENSE.txt",
|
||||||
"description": "Provides a behavior for making an element an overlay",
|
"description": "Provides a behavior for making an element an overlay",
|
||||||
"private": true,
|
"private": true,
|
||||||
|
@ -35,11 +35,11 @@
|
||||||
},
|
},
|
||||||
"ignore": [],
|
"ignore": [],
|
||||||
"homepage": "https://github.com/polymerelements/iron-overlay-behavior",
|
"homepage": "https://github.com/polymerelements/iron-overlay-behavior",
|
||||||
"_release": "1.4.2",
|
"_release": "1.4.3",
|
||||||
"_resolution": {
|
"_resolution": {
|
||||||
"type": "version",
|
"type": "version",
|
||||||
"tag": "v1.4.2",
|
"tag": "v1.4.3",
|
||||||
"commit": "565869d04433fb1065210ca30d81e7b7c4af73f8"
|
"commit": "6b8662619fbd4e82c2cebce6a846425ff9fc610d"
|
||||||
},
|
},
|
||||||
"_source": "git://github.com/polymerelements/iron-overlay-behavior.git",
|
"_source": "git://github.com/polymerelements/iron-overlay-behavior.git",
|
||||||
"_target": "^1.0.0",
|
"_target": "^1.0.0",
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
{
|
{
|
||||||
"name": "iron-overlay-behavior",
|
"name": "iron-overlay-behavior",
|
||||||
"version": "1.4.2",
|
"version": "1.4.3",
|
||||||
"license": "http://polymer.github.io/LICENSE.txt",
|
"license": "http://polymer.github.io/LICENSE.txt",
|
||||||
"description": "Provides a behavior for making an element an overlay",
|
"description": "Provides a behavior for making an element an overlay",
|
||||||
"private": true,
|
"private": true,
|
||||||
|
|
|
@ -136,6 +136,11 @@ context. You should place this element as a child of `<body>` whenever possible.
|
||||||
value: false
|
value: false
|
||||||
},
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Shortcut to access to the overlay manager.
|
||||||
|
* @private
|
||||||
|
* @type {Polymer.IronOverlayManagerClass}
|
||||||
|
*/
|
||||||
_manager: {
|
_manager: {
|
||||||
type: Object,
|
type: Object,
|
||||||
value: Polymer.IronOverlayManager
|
value: Polymer.IronOverlayManager
|
||||||
|
@ -176,7 +181,7 @@ context. You should place this element as a child of `<body>` whenever possible.
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The backdrop element.
|
* The backdrop element.
|
||||||
* @type {Node}
|
* @type {Element}
|
||||||
*/
|
*/
|
||||||
get backdropElement() {
|
get backdropElement() {
|
||||||
return this._manager.backdropElement;
|
return this._manager.backdropElement;
|
||||||
|
@ -197,7 +202,7 @@ context. You should place this element as a child of `<body>` whenever possible.
|
||||||
*
|
*
|
||||||
* If you know what is your content (specifically the first and last focusable children),
|
* If you know what is your content (specifically the first and last focusable children),
|
||||||
* you can override this method to return only `[firstFocusable, lastFocusable];`
|
* you can override this method to return only `[firstFocusable, lastFocusable];`
|
||||||
* @type {[Node]}
|
* @type {Array<Node>}
|
||||||
* @protected
|
* @protected
|
||||||
*/
|
*/
|
||||||
get _focusableNodes() {
|
get _focusableNodes() {
|
||||||
|
@ -295,7 +300,7 @@ context. You should place this element as a child of `<body>` whenever possible.
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Cancels the overlay.
|
* Cancels the overlay.
|
||||||
* @param {?Event} event The original event
|
* @param {Event=} event The original event
|
||||||
*/
|
*/
|
||||||
cancel: function(event) {
|
cancel: function(event) {
|
||||||
var cancelEvent = this.fire('iron-overlay-canceled', event, {cancelable: true});
|
var cancelEvent = this.fire('iron-overlay-canceled', event, {cancelable: true});
|
||||||
|
|
|
@ -15,197 +15,244 @@ subject to an additional IP rights grant found at http://polymer.github.io/PATEN
|
||||||
/**
|
/**
|
||||||
* @struct
|
* @struct
|
||||||
* @constructor
|
* @constructor
|
||||||
|
* @private
|
||||||
*/
|
*/
|
||||||
Polymer.IronOverlayManagerClass = function() {
|
Polymer.IronOverlayManagerClass = function() {
|
||||||
|
/**
|
||||||
|
* Used to keep track of the opened overlays.
|
||||||
|
* @private {Array<Element>}
|
||||||
|
*/
|
||||||
this._overlays = [];
|
this._overlays = [];
|
||||||
// Used to keep track of the last focused node before an overlay gets opened.
|
|
||||||
|
/**
|
||||||
|
* Used to keep track of the last focused node before an overlay gets opened.
|
||||||
|
* @private {Array<Element>}
|
||||||
|
*/
|
||||||
this._lastFocusedNodes = [];
|
this._lastFocusedNodes = [];
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* iframes have a default z-index of 100, so this default should be at least
|
* iframes have a default z-index of 100,
|
||||||
* that.
|
* so this default should be at least that.
|
||||||
* @private {number}
|
* @private {number}
|
||||||
*/
|
*/
|
||||||
this._minimumZ = 101;
|
this._minimumZ = 101;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Used to keep track of the opened overlays with backdrop.
|
||||||
|
* @private {Array<Element>}
|
||||||
|
*/
|
||||||
this._backdrops = [];
|
this._backdrops = [];
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Memoized backdrop element.
|
||||||
|
* @private {Element|null}
|
||||||
|
*/
|
||||||
this._backdropElement = null;
|
this._backdropElement = null;
|
||||||
Object.defineProperty(this, 'backdropElement', {
|
};
|
||||||
get: function() {
|
|
||||||
if (!this._backdropElement) {
|
Polymer.IronOverlayManagerClass.prototype = {
|
||||||
this._backdropElement = document.createElement('iron-overlay-backdrop');
|
|
||||||
}
|
constructor: Polymer.IronOverlayManagerClass,
|
||||||
return this._backdropElement;
|
|
||||||
}.bind(this)
|
/**
|
||||||
});
|
* The shared backdrop element.
|
||||||
|
* @type {Element} backdropElement
|
||||||
|
*/
|
||||||
|
get backdropElement() {
|
||||||
|
if (!this._backdropElement) {
|
||||||
|
this._backdropElement = document.createElement('iron-overlay-backdrop');
|
||||||
|
}
|
||||||
|
return this._backdropElement;
|
||||||
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The deepest active element.
|
* The deepest active element.
|
||||||
* returns {?Node} element the active element
|
* @type {Element|undefined} activeElement the active element
|
||||||
*/
|
*/
|
||||||
this.deepActiveElement = null;
|
get deepActiveElement() {
|
||||||
Object.defineProperty(this, 'deepActiveElement', {
|
var active = document.activeElement;
|
||||||
get: function() {
|
// document.activeElement can be null
|
||||||
var active = document.activeElement;
|
// https://developer.mozilla.org/en-US/docs/Web/API/Document/activeElement
|
||||||
// document.activeElement can be null
|
while (active && active.root && Polymer.dom(active.root).activeElement) {
|
||||||
// https://developer.mozilla.org/en-US/docs/Web/API/Document/activeElement
|
active = Polymer.dom(active.root).activeElement;
|
||||||
while (active && active.root && Polymer.dom(active.root).activeElement) {
|
}
|
||||||
active = Polymer.dom(active.root).activeElement;
|
return active;
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* If a node is contained in an overlay.
|
||||||
|
* @param {Element=} node
|
||||||
|
* @return {boolean}
|
||||||
|
* @private
|
||||||
|
*/
|
||||||
|
_isChildOfOverlay: function(node) {
|
||||||
|
while (node && node !== document.body) {
|
||||||
|
// Use logical parentNode, or native ShadowRoot host.
|
||||||
|
node = Polymer.dom(node).parentNode || node.host;
|
||||||
|
// Check if it is an overlay.
|
||||||
|
if (node && node.behaviors && node.behaviors.indexOf(Polymer.IronOverlayBehaviorImpl) !== -1) {
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
return active;
|
|
||||||
}.bind(this)
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* If a node is contained in an overlay.
|
|
||||||
* @private
|
|
||||||
* @param {Node} node
|
|
||||||
* @returns {Boolean}
|
|
||||||
*/
|
|
||||||
Polymer.IronOverlayManagerClass.prototype._isChildOfOverlay = function(node) {
|
|
||||||
while (node && node !== document.body) {
|
|
||||||
// Use logical parentNode, or native ShadowRoot host.
|
|
||||||
node = Polymer.dom(node).parentNode || node.host;
|
|
||||||
// Check if it is an overlay.
|
|
||||||
if (node && node.behaviors && node.behaviors.indexOf(Polymer.IronOverlayBehaviorImpl) !== -1) {
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
}
|
return false;
|
||||||
return false;
|
},
|
||||||
};
|
|
||||||
|
|
||||||
Polymer.IronOverlayManagerClass.prototype._applyOverlayZ = function(overlay, aboveZ) {
|
/**
|
||||||
this._setZ(overlay, aboveZ + 2);
|
* @param {Element} overlay
|
||||||
};
|
* @param {number} aboveZ
|
||||||
|
* @private
|
||||||
|
*/
|
||||||
|
_applyOverlayZ: function(overlay, aboveZ) {
|
||||||
|
this._setZ(overlay, aboveZ + 2);
|
||||||
|
},
|
||||||
|
|
||||||
Polymer.IronOverlayManagerClass.prototype._setZ = function(element, z) {
|
/**
|
||||||
element.style.zIndex = z;
|
* @param {Element} element
|
||||||
};
|
* @param {number|string} z
|
||||||
|
* @private
|
||||||
|
*/
|
||||||
|
_setZ: function(element, z) {
|
||||||
|
element.style.zIndex = z;
|
||||||
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* track overlays for z-index and focus managemant
|
* Tracks overlays for z-index and focus management.
|
||||||
*/
|
* @param {Element} overlay
|
||||||
Polymer.IronOverlayManagerClass.prototype.addOverlay = function(overlay) {
|
*/
|
||||||
var minimumZ = Math.max(this.currentOverlayZ(), this._minimumZ);
|
addOverlay: function(overlay) {
|
||||||
this._overlays.push(overlay);
|
var minimumZ = Math.max(this.currentOverlayZ(), this._minimumZ);
|
||||||
var newZ = this.currentOverlayZ();
|
this._overlays.push(overlay);
|
||||||
if (newZ <= minimumZ) {
|
var newZ = this.currentOverlayZ();
|
||||||
this._applyOverlayZ(overlay, minimumZ);
|
if (newZ <= minimumZ) {
|
||||||
}
|
this._applyOverlayZ(overlay, minimumZ);
|
||||||
var element = this.deepActiveElement;
|
|
||||||
// If already in other overlay, don't reset focus there.
|
|
||||||
if (this._isChildOfOverlay(element)) {
|
|
||||||
element = null;
|
|
||||||
}
|
|
||||||
this._lastFocusedNodes.push(element);
|
|
||||||
};
|
|
||||||
|
|
||||||
Polymer.IronOverlayManagerClass.prototype.removeOverlay = function(overlay) {
|
|
||||||
var i = this._overlays.indexOf(overlay);
|
|
||||||
if (i >= 0) {
|
|
||||||
this._overlays.splice(i, 1);
|
|
||||||
this._setZ(overlay, '');
|
|
||||||
|
|
||||||
var node = this._lastFocusedNodes[i];
|
|
||||||
// Focus only if still contained in document.body
|
|
||||||
if (overlay.restoreFocusOnClose && node && Polymer.dom(document.body).deepContains(node)) {
|
|
||||||
node.focus();
|
|
||||||
}
|
}
|
||||||
this._lastFocusedNodes.splice(i, 1);
|
var element = this.deepActiveElement;
|
||||||
}
|
// If already in other overlay, don't reset focus there.
|
||||||
};
|
if (this._isChildOfOverlay(element)) {
|
||||||
|
element = null;
|
||||||
Polymer.IronOverlayManagerClass.prototype.currentOverlay = function() {
|
|
||||||
var i = this._overlays.length - 1;
|
|
||||||
while (this._overlays[i] && !this._overlays[i].opened) {
|
|
||||||
--i;
|
|
||||||
}
|
|
||||||
return this._overlays[i];
|
|
||||||
};
|
|
||||||
|
|
||||||
Polymer.IronOverlayManagerClass.prototype.currentOverlayZ = function() {
|
|
||||||
return this._getOverlayZ(this.currentOverlay());
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Ensures that the minimum z-index of new overlays is at least `minimumZ`.
|
|
||||||
* This does not effect the z-index of any existing overlays.
|
|
||||||
*
|
|
||||||
* @param {number} minimumZ
|
|
||||||
*/
|
|
||||||
Polymer.IronOverlayManagerClass.prototype.ensureMinimumZ = function(minimumZ) {
|
|
||||||
this._minimumZ = Math.max(this._minimumZ, minimumZ);
|
|
||||||
};
|
|
||||||
|
|
||||||
Polymer.IronOverlayManagerClass.prototype.focusOverlay = function() {
|
|
||||||
var current = this.currentOverlay();
|
|
||||||
// We have to be careful to focus the next overlay _after_ any current
|
|
||||||
// transitions are complete (due to the state being toggled prior to the
|
|
||||||
// transition). Otherwise, we risk infinite recursion when a transitioning
|
|
||||||
// (closed) overlay becomes the current overlay.
|
|
||||||
//
|
|
||||||
// NOTE: We make the assumption that any overlay that completes a transition
|
|
||||||
// will call into focusOverlay to kick the process back off. Currently:
|
|
||||||
// transitionend -> _applyFocus -> focusOverlay.
|
|
||||||
if (current && !current.transitioning) {
|
|
||||||
current._applyFocus();
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
Polymer.IronOverlayManagerClass.prototype.trackBackdrop = function(element) {
|
|
||||||
// backdrops contains the overlays with a backdrop that are currently
|
|
||||||
// visible
|
|
||||||
var index = this._backdrops.indexOf(element);
|
|
||||||
if (element.opened && element.withBackdrop) {
|
|
||||||
// no duplicates
|
|
||||||
if (index === -1) {
|
|
||||||
this._backdrops.push(element);
|
|
||||||
}
|
}
|
||||||
} else if (index >= 0) {
|
this._lastFocusedNodes.push(element);
|
||||||
this._backdrops.splice(index, 1);
|
},
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
Polymer.IronOverlayManagerClass.prototype.getBackdrops = function() {
|
/**
|
||||||
return this._backdrops;
|
* @param {Element} overlay
|
||||||
};
|
*/
|
||||||
|
removeOverlay: function(overlay) {
|
||||||
|
var i = this._overlays.indexOf(overlay);
|
||||||
|
if (i >= 0) {
|
||||||
|
this._overlays.splice(i, 1);
|
||||||
|
this._setZ(overlay, '');
|
||||||
|
|
||||||
/**
|
var node = this._lastFocusedNodes[i];
|
||||||
* Returns the z-index for the backdrop.
|
// Focus only if still contained in document.body
|
||||||
*/
|
if (overlay.restoreFocusOnClose && node && Polymer.dom(document.body).deepContains(node)) {
|
||||||
Polymer.IronOverlayManagerClass.prototype.backdropZ = function() {
|
node.focus();
|
||||||
return this._getOverlayZ(this._overlayWithBackdrop()) - 1;
|
}
|
||||||
};
|
this._lastFocusedNodes.splice(i, 1);
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns the first opened overlay that has a backdrop.
|
|
||||||
*/
|
|
||||||
Polymer.IronOverlayManagerClass.prototype._overlayWithBackdrop = function() {
|
|
||||||
for (var i = 0; i < this._overlays.length; i++) {
|
|
||||||
if (this._overlays[i].opened && this._overlays[i].withBackdrop) {
|
|
||||||
return this._overlays[i];
|
|
||||||
}
|
}
|
||||||
}
|
},
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Calculates the minimum z-index for the overlay.
|
* @return {Element|undefined} overlay The current overlay.
|
||||||
*/
|
*/
|
||||||
Polymer.IronOverlayManagerClass.prototype._getOverlayZ = function(overlay) {
|
currentOverlay: function() {
|
||||||
var z = this._minimumZ;
|
var i = this._overlays.length - 1;
|
||||||
if (overlay) {
|
while (this._overlays[i] && !this._overlays[i].opened) {
|
||||||
var z1 = Number(window.getComputedStyle(overlay).zIndex);
|
--i;
|
||||||
// Check if is a number
|
|
||||||
// Number.isNaN not supported in IE 10+
|
|
||||||
if (z1 === z1) {
|
|
||||||
z = z1;
|
|
||||||
}
|
}
|
||||||
|
return this._overlays[i];
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return {number} zIndex the current overlay z-index.
|
||||||
|
*/
|
||||||
|
currentOverlayZ: function() {
|
||||||
|
return this._getOverlayZ(this.currentOverlay());
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Ensures that the minimum z-index of new overlays is at least `minimumZ`.
|
||||||
|
* This does not effect the z-index of any existing overlays.
|
||||||
|
* @param {number} minimumZ
|
||||||
|
*/
|
||||||
|
ensureMinimumZ: function(minimumZ) {
|
||||||
|
this._minimumZ = Math.max(this._minimumZ, minimumZ);
|
||||||
|
},
|
||||||
|
|
||||||
|
focusOverlay: function() {
|
||||||
|
var current = /** @type {?} */ (this.currentOverlay());
|
||||||
|
// We have to be careful to focus the next overlay _after_ any current
|
||||||
|
// transitions are complete (due to the state being toggled prior to the
|
||||||
|
// transition). Otherwise, we risk infinite recursion when a transitioning
|
||||||
|
// (closed) overlay becomes the current overlay.
|
||||||
|
//
|
||||||
|
// NOTE: We make the assumption that any overlay that completes a transition
|
||||||
|
// will call into focusOverlay to kick the process back off. Currently:
|
||||||
|
// transitionend -> _applyFocus -> focusOverlay.
|
||||||
|
if (current && !current.transitioning) {
|
||||||
|
current._applyFocus();
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {Element} overlay The overlay that updated its withBackdrop.
|
||||||
|
*/
|
||||||
|
trackBackdrop: function(overlay) {
|
||||||
|
var index = this._backdrops.indexOf(overlay);
|
||||||
|
if (overlay.opened && overlay.withBackdrop) {
|
||||||
|
// no duplicates
|
||||||
|
if (index === -1) {
|
||||||
|
this._backdrops.push(overlay);
|
||||||
|
}
|
||||||
|
} else if (index >= 0) {
|
||||||
|
this._backdrops.splice(index, 1);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return {Array<Element>} backdrops
|
||||||
|
*/
|
||||||
|
getBackdrops: function() {
|
||||||
|
return this._backdrops;
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return {number} index The z-index for the backdrop.
|
||||||
|
*/
|
||||||
|
backdropZ: function() {
|
||||||
|
return this._getOverlayZ(this._overlayWithBackdrop()) - 1;
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return {Element|undefined} overlay The first opened overlay that has a backdrop.
|
||||||
|
* @private
|
||||||
|
*/
|
||||||
|
_overlayWithBackdrop: function() {
|
||||||
|
for (var i = 0; i < this._overlays.length; i++) {
|
||||||
|
if (this._overlays[i].opened && this._overlays[i].withBackdrop) {
|
||||||
|
return this._overlays[i];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Calculates the minimum z-index for the overlay.
|
||||||
|
* @param {Element=} overlay
|
||||||
|
* @private
|
||||||
|
*/
|
||||||
|
_getOverlayZ: function(overlay) {
|
||||||
|
var z = this._minimumZ;
|
||||||
|
if (overlay) {
|
||||||
|
var z1 = Number(window.getComputedStyle(overlay).zIndex);
|
||||||
|
// Check if is a number
|
||||||
|
// Number.isNaN not supported in IE 10+
|
||||||
|
if (z1 === z1) {
|
||||||
|
z = z1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return z;
|
||||||
}
|
}
|
||||||
return z;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
Polymer.IronOverlayManager = new Polymer.IronOverlayManagerClass();
|
Polymer.IronOverlayManager = new Polymer.IronOverlayManagerClass();
|
||||||
|
|
||||||
</script>
|
</script>
|
||||||
|
|
|
@ -45,7 +45,7 @@
|
||||||
"tag": "v1.0.11",
|
"tag": "v1.0.11",
|
||||||
"commit": "e3c1ab0c72905b58fb4d9adc2921ea73b5c085a5"
|
"commit": "e3c1ab0c72905b58fb4d9adc2921ea73b5c085a5"
|
||||||
},
|
},
|
||||||
"_source": "git://github.com/polymerelements/paper-behaviors.git",
|
"_source": "git://github.com/PolymerElements/paper-behaviors.git",
|
||||||
"_target": "^1.0.0",
|
"_target": "^1.0.0",
|
||||||
"_originalSource": "polymerelements/paper-behaviors"
|
"_originalSource": "PolymerElements/paper-behaviors"
|
||||||
}
|
}
|
|
@ -32,14 +32,14 @@
|
||||||
"iron-test-helpers": "PolymerElements/iron-test-helpers#^1.0.0"
|
"iron-test-helpers": "PolymerElements/iron-test-helpers#^1.0.0"
|
||||||
},
|
},
|
||||||
"ignore": [],
|
"ignore": [],
|
||||||
"homepage": "https://github.com/polymerelements/paper-ripple",
|
"homepage": "https://github.com/PolymerElements/paper-ripple",
|
||||||
"_release": "1.0.5",
|
"_release": "1.0.5",
|
||||||
"_resolution": {
|
"_resolution": {
|
||||||
"type": "version",
|
"type": "version",
|
||||||
"tag": "v1.0.5",
|
"tag": "v1.0.5",
|
||||||
"commit": "d72e7a9a8ab518b901ed18dde492df3b87a93be5"
|
"commit": "d72e7a9a8ab518b901ed18dde492df3b87a93be5"
|
||||||
},
|
},
|
||||||
"_source": "git://github.com/polymerelements/paper-ripple.git",
|
"_source": "git://github.com/PolymerElements/paper-ripple.git",
|
||||||
"_target": "^1.0.0",
|
"_target": "^1.0.0",
|
||||||
"_originalSource": "polymerelements/paper-ripple"
|
"_originalSource": "PolymerElements/paper-ripple"
|
||||||
}
|
}
|
Loading…
Add table
Add a link
Reference in a new issue