SlidingView.js
Summary
No overview generated for 'SlidingView.js'
const TKSlidingViewNumberOfElements = 'slidingViewNumberOfElements';
const TKSlidingViewElementAtIndex = 'slidingViewElementAtIndex';
const TKSlidingViewStyleForItemAtIndex = 'slidingViewStyleForItemAtIndex';
const TKSlidingViewDidSelectActiveElement = 'slidingViewDidSelectActiveElement';
const TKSlidingViewDidFocusElementAtIndex = 'slidingViewDidFocusElementAtIndex';
const TKSlidingViewDidBlurElementAtIndex = 'slidingViewDidBlurElementAtIndex';
const TKSlidingViewDidHideElementAtIndex = 'slidingViewDidHideElementAtIndex';
const TKSlidingViewWillUnhideElementAtIndex = 'slidingViewWillUnhideElementAtIndex';
const TKSlidingViewDidHoverElementAtIndex = 'slidingViewDidHoverElementAtIndex';
const TKSlidingViewDidUnhoverElementAtIndex = 'slidingViewDidUnhoverElementAtIndex';
const TKSlidingViewCSSContainerClass = 'sliding-view';
const TKSlidingViewCSSElementClass = 'sliding-view-element';
const TKSlidingViewCSSFocusedClass = 'sliding-view-element-focused';
const TKSlidingViewCSSSideBeforeClass = 'sliding-view-element-before';
const TKSlidingViewCSSSideAfterClass = 'sliding-view-element-after';
const TKSlidingViewCSSStagedBeforeClass = 'sliding-view-element-staged-before';
const TKSlidingViewCSSStagedAfterClass = 'sliding-view-element-staged-after';
const TKSlidingViewCSSHiddenClass = 'sliding-view-element-hidden';
const TKSlidingViewOrientationHorizontal = 'horizontal';
const TKSlidingViewOrientationVertical = 'vertical';
TKSlidingView.synthetizes = ['dataSource',
'delegate',
'activeElementIndex',
'orientation',
'interactive',
'sideOffsetBefore',
'sideOffsetAfter',
'distanceBetweenElements',
'sideElementsVisible',
'pageControl',
'incrementalLoading',
'loops',
'raiseHoverEvents',
'numberOfElements'];
function TKSlidingView (element) {
this.callSuper();
this._activeElementIndex = 0;
this._orientation = TKSlidingViewOrientationHorizontal;
this._interactive = true;
this._sideOffsetBefore = 160;
this._sideOffsetAfter = 160;
this._distanceBetweenElements = 25;
this._sideElementsVisible = 4;
this._pageControl = null;
this._incrementalLoading = false;
this._loops = false;
this._raiseHoverEvents = false;
this._elements = [];
if (element) {
this.element = element;
} else {
this.element = document.createElement("div");
}
this.element.addClassName(TKSlidingViewCSSContainerClass);
}
TKSlidingView.prototype.init = function () {
if (!this.dataSource ||
!TKUtils.objectHasMethod(this.dataSource, TKSlidingViewNumberOfElements) ||
!TKUtils.objectHasMethod(this.dataSource, TKSlidingViewElementAtIndex)) {
return;
}
var numElements = this.numberOfElements;
if (this._incrementalLoading) {
this.bufferElements();
} else {
for (var i=0; i < numElements; i++) {
var el = this.dataSource[TKSlidingViewElementAtIndex](this, i);
el.addClassName(TKSlidingViewCSSElementClass);
el._needsAppending = true;
this._elements[i] = el;
el._slidingViewIndex = i;
if (this._interactive) {
el.addEventListener("click", this, false);
}
if (this._raiseHoverEvents) {
el.addEventListener("mouseover", this, false);
el.addEventListener("mouseout", this, false);
}
}
}
this.layout(true);
};
TKSlidingView.prototype.setPageControl = function (newPageControl) {
this._pageControl = newPageControl;
this._pageControl.deferCurrentPageDisplay = true;
this._pageControl.delegate = this;
this._pageControl.currentPage = this._activeElementIndex;
};
TKSlidingView.prototype.setActiveElementIndex = function (newActiveElementIndex) {
if ((this._loops || (newActiveElementIndex >= 0 && newActiveElementIndex < this.numberOfElements)) &&
newActiveElementIndex != this._activeElementIndex) {
var needsForcedLayout = (this._activeElementIndex === undefined);
if (!needsForcedLayout && TKUtils.objectHasMethod(this.delegate, TKSlidingViewDidBlurElementAtIndex)) {
this.delegate[TKSlidingViewDidBlurElementAtIndex](this, this._activeElementIndex);
}
if (newActiveElementIndex < 0) {
this._activeElementIndex = (this.numberOfElements + newActiveElementIndex) % this.numberOfElements;
} else {
this._activeElementIndex = newActiveElementIndex % this.numberOfElements;
}
if (TKUtils.objectHasMethod(this.delegate, TKSlidingViewDidFocusElementAtIndex)) {
this.delegate[TKSlidingViewDidFocusElementAtIndex](this, this._activeElementIndex);
}
if (this._pageControl) {
this._pageControl.currentPage = newActiveElementIndex;
}
this.bufferElements();
this.layout(needsForcedLayout);
}
};
TKSlidingView.prototype.getNumberOfElements = function () {
if (this.dataSource) {
return this.dataSource[TKSlidingViewNumberOfElements](this);
} else {
return 0;
}
};
TKSlidingView.prototype.getElementAtIndex = function (index) {
return this._elements[index];
};
TKSlidingView.prototype.bufferElements = function () {
if (this._incrementalLoading) {
var numElements = this.numberOfElements;
for (var i=0; i < numElements; i++) {
var offset = this._activeElementIndex - i;
var absOffset = Math.abs(offset);
if (this._loops) {
var offset2 = offset + ((offset < 0) ? numElements : -numElements);
var absOffset2 = Math.abs(offset2);
if (absOffset2 <= this._sideElementsVisible) {
offset = offset2;
absOffset = absOffset2;
}
}
if (absOffset <= this._sideElementsVisible) {
if (!this._elements[i]) {
var el = this.dataSource[TKSlidingViewElementAtIndex](this, i);
el.addClassName(TKSlidingViewCSSElementClass);
el._needsAppending = true;
this._elements[i] = el;
el._slidingViewIndex = i;
if (this._interactive) {
el.addEventListener("click", this, false);
}
if (this._raiseHoverEvents) {
el.addEventListener("mouseover", this, false);
el.addEventListener("mouseout", this, false);
}
}
} else {
if (this._elements[i]) {
this.element.removeChild(this._elements[i]);
this._elements[i] = null;
}
}
}
}
};
TKSlidingView.prototype.layout = function (forceLayout) {
var numElements = this.numberOfElements;
for (var i=0; i < numElements; i++) {
var offset = this._activeElementIndex - i;
var absOffset = Math.abs(offset);
if (this._loops) {
var offset2 = offset + ((offset < 0) ? numElements : -numElements);
var absOffset2 = Math.abs(offset2);
if (absOffset2 <= this._sideElementsVisible) {
offset = offset2;
absOffset = absOffset2;
}
}
var element = this._elements[i];
if (!element) {
continue;
}
if (element._needsAppending) {
this.element.appendChild(element);
element._needsAppending = false;
}
var transform = null;
if (absOffset <= this._sideElementsVisible) {
if (offset > 0) {
if (this._orientation == TKSlidingViewOrientationHorizontal) {
transform = "translate3d(" + (-1 * (absOffset * this._distanceBetweenElements + this._sideOffsetBefore)) + "px, 0, 0)";
} else {
transform = "translate3d(0, " + (-1 * (absOffset * this._distanceBetweenElements + this._sideOffsetBefore)) + "px, 0)";
}
this.applySlidingClass(element, TKSlidingViewCSSSideBeforeClass);
} else if (offset < 0) {
if (this._orientation == TKSlidingViewOrientationHorizontal) {
transform = "translate3d(" + (absOffset * this._distanceBetweenElements + this._sideOffsetAfter) + "px, 0, 0)";
} else {
transform = "translate3d(0, " + (absOffset * this._distanceBetweenElements + this._sideOffsetAfter) + "px, 0)";
}
this.applySlidingClass(element, TKSlidingViewCSSSideAfterClass);
} else {
transform = "translate3d(0, 0, 0)";
this.applySlidingClass(element, TKSlidingViewCSSFocusedClass);
}
element.style.webkitTransform = transform;
element.style.opacity = 1;
} else if (absOffset == (this._sideElementsVisible + 1)) {
if (offset > 0) {
if (this._orientation == TKSlidingViewOrientationHorizontal) {
transform = "translate3d(" + (-1 * (absOffset * this._distanceBetweenElements + this._sideOffsetBefore)) + "px, 0, 0)";
} else {
transform = "translate3d(0, " + (-1 * (absOffset * this._distanceBetweenElements + this._sideOffsetBefore)) + "px, 0)";
}
this.applySlidingClass(element, TKSlidingViewCSSSideBeforeClass);
} else {
if (this._orientation == TKSlidingViewOrientationHorizontal) {
transform = "translate3d(" + (absOffset * this._distanceBetweenElements + this._sideOffsetAfter) + "px, 0, 0)";
} else {
transform = "translate3d(0, " + (absOffset * this._distanceBetweenElements + this._sideOffsetAfter) + "px, 0)";
}
this.applySlidingClass(element, TKSlidingViewCSSSideAfterClass);
}
element.style.webkitTransform = transform;
element.style.opacity = 0;
} else if (absOffset > this._sideElementsVisible || forceLayout) {
if (offset > 0) {
if (this._orientation == TKSlidingViewOrientationHorizontal) {
transform = "translate3d(" + (-1 * (absOffset * this._distanceBetweenElements + this._sideOffsetBefore)) + "px, 0, 0)";
} else {
transform = "translate3d(0, " + (-1 * (absOffset * this._distanceBetweenElements + this._sideOffsetBefore)) + "px, 0)";
}
} else {
if (this._orientation == TKSlidingViewOrientationHorizontal) {
transform = "translate3d(" + (absOffset * this._distanceBetweenElements + this._sideOffsetAfter) + "px, 0, 0)";
} else {
transform = "translate3d(0, " + (absOffset * this._distanceBetweenElements + this._sideOffsetAfter) + "px, 0)";
}
}
this.applySlidingClass(element, TKSlidingViewCSSHiddenClass);
element.style.webkitTransform = transform;
element.style.opacity = 0;
}
if (TKUtils.objectHasMethod(this.delegate, TKSlidingViewStyleForItemAtIndex)) {
override_styles = this.delegate[TKSlidingViewStyleForItemAtIndex](this, i);
for (var j = 0; j < override_styles.length; j++) {
var override_style = override_styles[j];
element.style.setProperty(override_style[0], override_style[1], '');
}
}
}
};
TKSlidingView.prototype.applySlidingClass = function (element, className) {
element.removeClassName(TKSlidingViewCSSFocusedClass);
element.removeClassName(TKSlidingViewCSSSideBeforeClass);
element.removeClassName(TKSlidingViewCSSSideAfterClass);
element.removeClassName(TKSlidingViewCSSStagedBeforeClass);
element.removeClassName(TKSlidingViewCSSStagedAfterClass);
element.removeClassName(TKSlidingViewCSSHiddenClass);
element.addClassName(className);
};
TKSlidingView.prototype.handleEvent = function (event) {
switch (event.type) {
case "click":
this.handleClick(event);
break;
case "mouseover":
this.handleMouseover(event);
break;
case "mouseout":
this.handleMouseout(event);
break;
default:
debug("unhandled event type in TKSlidingView: " + event.type);
}
};
TKSlidingView.prototype.handleClick = function (event) {
var target = event.target;
while (target && TKUtils.objectIsUndefined(target._slidingViewIndex)) {
target = target.parentNode;
}
if (!target) {
return;
}
if (target._slidingViewIndex == this.activeElementIndex) {
if (TKUtils.objectHasMethod(this.delegate, TKSlidingViewDidSelectActiveElement)) {
this.delegate[TKSlidingViewDidSelectActiveElement](this, this._activeElementIndex);
}
} else {
if (target._slidingViewIndex < this.activeElementIndex) {
if (this._loops && target._slidingViewIndex == 0) {
this.activeElementIndex = 0;
} else {
this.activeElementIndex--;
}
} else {
if (this._loops && target._slidingViewIndex == this.numberOfElements - 1) {
this.activeElementIndex = this.numberOfElements - 1;
} else {
this.activeElementIndex++;
}
}
}
};
TKSlidingView.prototype.handleMouseover = function (event) {
var target = event.target;
while (target && TKUtils.objectIsUndefined(target._slidingViewIndex)) {
target = target.parentNode;
}
if (!target) {
return;
}
if (TKUtils.objectHasMethod(this.delegate, TKSlidingViewDidHoverElementAtIndex)) {
this.delegate[TKSlidingViewDidHoverElementAtIndex](this, target._slidingViewIndex);
}
};
TKSlidingView.prototype.handleMouseout = function (event) {
var target = event.target;
while (target && TKUtils.objectIsUndefined(target._slidingViewIndex)) {
target = target.parentNode;
}
if (!target) {
return;
}
if (TKUtils.objectHasMethod(this.delegate, TKSlidingViewDidUnhoverElementAtIndex)) {
this.delegate[TKSlidingViewDidUnhoverElementAtIndex](this, target._slidingViewIndex);
}
};
TKSlidingView.prototype.pageControlDidUpdateCurrentPage = function (control, newPageIndex) {
if (control === this._pageControl) {
this.activeElementIndex = newPageIndex;
this._pageControl.updateCurrentPageDisplay();
}
};
TKClass(TKSlidingView);
function TKSlidingViewDataSourceHelper(data, incrementalLoading) {
this.data = data;
this.incrementalLoading = incrementalLoading;
this.elements = [];
};
TKSlidingViewDataSourceHelper.prototype.slidingViewNumberOfElements = function(view) {
if (this.data) {
return this.data.length;
} else {
return 0;
}
};
TKSlidingViewDataSourceHelper.prototype.slidingViewElementAtIndex = function(view, index) {
if (!this.data || index >= this.data.length) {
return null;
}
var element = this.elements[index];
if (!element) {
var source = this.data[index];
element = TKUtils.buildElement(source);
}
if (!this.incrementalLoading) {
this.elements[index] = element;
}
return element;
};
TKSlidingView.buildSlidingView = function(element, data) {
if (TKUtils.objectIsUndefined(data) || !data || data.type != "TKSlidingView") {
return null;
}
var slidingView = new TKSlidingView(element);
if (!TKUtils.objectIsUndefined(data.elements)) {
slidingView.dataSource = new TKSlidingViewDataSourceHelper(data.elements, data.incrementalLoading);
}
TKSlidingView.synthetizes.forEach(function(prop) {
if (prop != "dataSource" && prop != "delegate") {
if (!TKUtils.objectIsUndefined(data[prop])) {
slidingView[prop] = data[prop];
}
}
});
return slidingView;
};
Documentation generated by
JSDoc on Tue Sep 15 21:24:36 2009