define(
'tinymce.themes.mobile.ios.view.IosViewport',
[
'ephox.katamari.api.Adt',
'ephox.katamari.api.Arr',
'ephox.katamari.api.Fun',
'ephox.sugar.api.properties.Attr',
'ephox.sugar.api.properties.Css',
'ephox.sugar.api.search.SelectorFilter',
'ephox.sugar.api.search.Traverse',
'ephox.sugar.api.view.Height',
'tinymce.themes.mobile.ios.view.DeviceZones',
'tinymce.themes.mobile.style.Styles',
'tinymce.themes.mobile.touch.scroll.Scrollable',
'tinymce.themes.mobile.util.DataAttributes'
],
function (Adt, Arr, Fun, Attr, Css, SelectorFilter, Traverse, Height, DeviceZones, Styles, Scrollable, DataAttributes) {
var fixture = Adt.generate([
{ 'fixed': [ 'element', 'property', 'offsetY' ] },
// Not supporting property yet
{ 'scroller' :[ 'element', 'offsetY' ] }
]);
var yFixedData = 'data-' + Styles.resolve('position-y-fixed');
var yFixedProperty = 'data-' + Styles.resolve('y-property');
var yScrollingData = 'data-' + Styles.resolve('scrolling');
var windowSizeData = 'data-' + Styles.resolve('last-window-height');
var getYFixedData = function (element) {
return DataAttributes.safeParse(element, yFixedData);
};
var getYFixedProperty = function (element) {
return Attr.get(element, yFixedProperty);
};
var getLastWindowSize = function (element) {
return DataAttributes.safeParse(element, windowSizeData);
};
var classifyFixed = function (element, offsetY) {
var prop = getYFixedProperty(element);
return fixture.fixed(element, prop, offsetY);
};
var classifyScrolling = function (element, offsetY) {
return fixture.scroller(element, offsetY);
};
var classify = function (element) {
var offsetY = getYFixedData(element);
var classifier = Attr.get(element, yScrollingData) === 'true' ? classifyScrolling : classifyFixed;
return classifier(element, offsetY);
};
var findFixtures = function (container) {
var candidates = SelectorFilter.descendants(container, '[' + yFixedData + ']');
return Arr.map(candidates, classify);
};
var takeoverToolbar = function (toolbar) {
var oldToolbarStyle = Attr.get(toolbar, 'style');
Css.setAll(toolbar, {
position: 'absolute',
top: '0px'
});
Attr.set(toolbar, yFixedData, '0px');
Attr.set(toolbar, yFixedProperty, 'top');
var restore = function () {
Attr.set(toolbar, 'style', oldToolbarStyle || '');
Attr.remove(toolbar, yFixedData);
Attr.remove(toolbar, yFixedProperty);
};
return {
restore: restore
};
};
var takeoverViewport = function (toolbarHeight, height, viewport) {
var oldViewportStyle = Attr.get(viewport, 'style');
Scrollable.register(viewport);
Css.setAll(viewport, {
'position': 'absolute',
// I think there a class that does this overflow scrolling touch part
'height': height + 'px',
'width': '100%',
'top': toolbarHeight + 'px'
});
Attr.set(viewport, yFixedData, toolbarHeight + 'px');
Attr.set(viewport, yScrollingData, 'true');
Attr.set(viewport, yFixedProperty, 'top');
var restore = function () {
Scrollable.deregister(viewport);
Attr.set(viewport, 'style', oldViewportStyle || '');
Attr.remove(viewport, yFixedData);
Attr.remove(viewport, yScrollingData);
Attr.remove(viewport, yFixedProperty);
};
return {
restore: restore
};
};
var takeoverDropup = function (dropup, toolbarHeight, viewportHeight) {
var oldDropupStyle = Attr.get(dropup, 'style');
Css.setAll(dropup, {
position: 'absolute',
bottom: '0px'
});
Attr.set(dropup, yFixedData, '0px');
Attr.set(dropup, yFixedProperty, 'bottom');
var restore = function () {
Attr.set(dropup, 'style', oldDropupStyle || '');
Attr.remove(dropup, yFixedData);
Attr.remove(dropup, yFixedProperty);
};
return {
restore: restore
};
};
var deriveViewportHeight = function (viewport, toolbarHeight, dropupHeight) {
// Note, Mike thinks this value changes when the URL address bar grows and shrinks. If this value is too high
// the main problem is that scrolling into the greenzone may not scroll into an area that is viewable. Investigate.
var outerWindow = Traverse.owner(viewport).dom().defaultView;
var winH = outerWindow.innerHeight;
Attr.set(viewport, windowSizeData, winH + 'px');
return winH - toolbarHeight - dropupHeight;
};
var takeover = function (viewport, contentBody, toolbar, dropup) {
var outerWindow = Traverse.owner(viewport).dom().defaultView;
var toolbarSetup = takeoverToolbar(toolbar);
var toolbarHeight = Height.get(toolbar);
var dropupHeight = Height.get(dropup);
var viewportHeight = deriveViewportHeight(viewport, toolbarHeight, dropupHeight);
var viewportSetup = takeoverViewport(toolbarHeight, viewportHeight, viewport);
var dropupSetup = takeoverDropup(dropup, toolbarHeight, viewportHeight);
var isActive = true;
var restore = function () {
isActive = false;
toolbarSetup.restore();
viewportSetup.restore();
dropupSetup.restore();
};
var isExpanding = function () {
var currentWinHeight = outerWindow.innerHeight;
var lastWinHeight = getLastWindowSize(viewport);
return currentWinHeight > lastWinHeight;
};
var refresh = function () {
if (isActive) {
var newToolbarHeight = Height.get(toolbar);
var dropupHeight = Height.get(dropup);
var newHeight = deriveViewportHeight(viewport, newToolbarHeight, dropupHeight);
Attr.set(viewport, yFixedData, newToolbarHeight + 'px');
Css.set(viewport, 'height', newHeight + 'px');
Css.set(dropup, 'bottom', -(newToolbarHeight + newHeight + dropupHeight) + 'px');
DeviceZones.updatePadding(contentBody, viewport, dropup);
}
};
var setViewportOffset = function (newYOffset) {
var offsetPx = newYOffset + 'px';
Attr.set(viewport, yFixedData, offsetPx);
// The toolbar height has probably changed, so recalculate the viewport height.
refresh();
};
DeviceZones.updatePadding(contentBody, viewport, dropup);
return {
setViewportOffset: setViewportOffset,
isExpanding: isExpanding,
isShrinking: Fun.not(isExpanding),
refresh: refresh,
restore: restore
};
};
return {
findFixtures: findFixtures,
takeover: takeover,
getYFixedData: getYFixedData
};
}
);
|