nscomponentsreact
Version:
React Wrapper Components for NSComponents
1,563 lines (1,457 loc) • 55.3 kB
JavaScript
var nsModuleExport = function(root,name,prototype)
{
if(typeof exports === 'object' && typeof module === 'object')
{
module.exports[name] = prototype;
}
else if (typeof define === "function" && define.amd)
{
define(name,[], function () {return prototype;});
}
else if(typeof exports === 'object')
{
exports[name] = prototype;
}
else
{
root[name] = prototype;
}
};var nsIsWeb = function(root)
{
if(typeof exports === 'object' && typeof module === 'object')
{
return false;
}
else if (typeof define === "function" && define.amd)
{
return false;
}
else if(typeof exports === 'object')
{
return false;
}
else
{
return true;
}
};if(!nsIsWeb())
{
var nsutilRef = require('./nsUtil.min.js');
var NSUtil = nsutilRef.NSUtil;
var nscontainerbaseRef = require('./nsContainerBase.min.js');
var nsExtendPrototype = nscontainerbaseRef.nsExtendPrototype;
var NSContainerBase = nscontainerbaseRef.NSContainerBase;
}
"use strict";
var NSScrollAnimator = (function()
{
function NSScrollAnimator(config)
{
var self = this;
var setting = {};
var util = null;
var stopScroll = false;
var start = 0;
var startTime = 0;
var destinationOffsetToScroll = 0;
var animationFunction = {};
var props = {};
var propItem = {};
var interval = null;
var initialize = function()
{
if(!config)
{
config = {};
}
util = new NSUtil();
initAnimationFunc();
setting = {
element: config["element"] || window,
direction: config["direction"] || "vertical",
duration: !util.isUndefinedOrNull(config["duration"]) ? parseInt(config["duration"]) : 500,
easing: config["easing"] || "easeInOutQuad",
callback: config["callback"] || null,
};
if(setting.element === window)
{
setting.refElement = document.documentElement;
}
else
{
setting.refElement = setting.element;
}
props = { vertical:{scroll: "scrollTop", scrollSize: "scrollHeight",client: "clientHeight",offset: "offsetHeight",inner: "innerHeight",offsetPos: "offsetTop",},
horizontal:{scroll: "scrollLeft", scrollSize: "scrollWidth",client: "clientWidth",offset: "offsetWidth",inner: "innerWidth",offsetPos: "offsetLeft",}
};
propItem = props[setting.direction];
};
var scrollTo = function(newPos)
{
if(!util.isUndefinedOrNull(newPos))
{
start = setting.refElement[propItem.scroll];
startTime = 'now' in window.performance ? performance.now() : new Date().getTime();
var outerSize = Math.max(setting.refElement[propItem.scrollSize], setting.refElement[propItem.offset], setting.refElement[propItem.offset]);
var innerSize = setting.refElement[propItem.inner] || setting.refElement[propItem.offset];
var destinationOffset = typeof newPos === 'number' ? newPos : newPos[propItem.offsetPos];
destinationOffsetToScroll = Math.round(outerSize - destinationOffset < innerSize ? outerSize - innerSize : destinationOffset);
animateScroll();
}
};
var getMaxScrollPos = function()
{
return setting.refElement[propItem.scrollSize] - setting.refElement[propItem.client];
};
var getScrollPos = function()
{
return setting.refElement[propItem.scroll];
};
var stop = function()
{
stopScroll = true;
};
var animateScroll = function()
{
if (!stopScroll)
{
var now = 'now' in window.performance ? performance.now() : new Date().getTime();
var time = Math.min(1, ((now - startTime) / setting.duration));
var timeFunction = animationFunction[setting.easing](time);
var val = Math.ceil((timeFunction * (destinationOffsetToScroll - start)) + start);
setting.refElement[propItem.scroll] = val;
if (setting.refElement[propItem.scroll] === destinationOffsetToScroll)
{
if(setting.callback)
{
setting.callback();
}
return;
}
interval = util.getRequestAnimationFrame.bind(window)(animateScroll);
}
else
{
util.getCancelAnimationFrame.bind(window)(interval);
setting.refElement[propItem.scroll] = destinationOffsetToScroll;
if(setting.callback)
{
setting.callback();
}
}
};
var initAnimationFunc = function()
{
animationFunction = {
linear: function(t) {
return t;
},
easeInQuad: function(t) {
return t * t;
},
easeOutQuad: function(t) {
return t * (2 - t);
},
easeInOutQuad: function(t) {
return t < 0.5 ? 2 * t * t : -1 + (4 - 2 * t) * t;
},
easeInCubic: function(t) {
return t * t * t;
},
easeOutCubic: function(t) {
return (--t) * t * t + 1;
},
easeInOutCubic: function(t) {
return t < 0.5 ? 4 * t * t * t : (t - 1) * (2 * t - 2) * (2 * t - 2) + 1;
},
easeInQuart: function(t) {
return t * t * t * t;
},
easeOutQuart: function(t) {
return 1 - (--t) * t * t * t;
},
easeInOutQuart: function(t) {
return t < 0.5 ? 8 * t * t * t * t : 1 - 8 * (--t) * t * t * t;
},
easeInQuint: function(t) {
return t * t * t * t * t;
},
easeOutQuint: function(t) {
return 1 + (--t) * t * t * t * t;
},
easeInOutQuint: function(t) {
return t < 0.5 ? 16 * t * t * t * t * t : 1 + 16 * (--t) * t * t * t * t;
}
};
};
self.scrollTo = scrollTo;
self.getScrollPos = getScrollPos;
self.getMaxScrollPos = getMaxScrollPos;
self.stop = stop;
initialize();
};
return NSScrollAnimator;
})();
nsModuleExport(this,"NSScrollAnimator",NSScrollAnimator);var NSScroller = (function()
{
function NSScroller(setting)
{
var self = this;
var util = null;
var config = {};
//var parentNode = null;
var divScrollBarCorner = null;
var props = {};
var operaMaxScrollBarSize = 17;
var macScrollBarSize = 15;
var macFFRegex = /[\s\S]*Macintosh[\s\S]*\) Gecko[\s\S]*/;
var isMacFF = macFFRegex.test(window.navigator && window.navigator.userAgent);
var selectedItem = null;
var interval = null;
var delayInterval = null;
var mouseWheelEndInterval = null;
var mutationObserver = null;
var lastScrollPos = -1;
var setIsInternalWithOutDelay = true;
var isInternalScroll = false;
var itemElementScrollInterval = -1;
var isSameElement = false;
var setScrollWidth = function(width)
{
config.scrollWidth = width;
var item = props.horizontal;
item.inputSize = width;
setScrollElementSize(item);
};
var setScrollHeight = function(height)
{
config.scrollHeight = height;
var item = props.vertical;
item.inputSize = height;
setScrollElementSize(item);
};
var setScrollTop = function(scrollTop)
{
var item = props.vertical;
setScrollPos(item,scrollTop);
};
var getScrollTop = function()
{
var item = props.vertical;
return item.element[item.scroll];
};
var setScrollLeft = function(scrollLeft)
{
var item = props.horizontal;
setScrollPos(item,scrollLeft);
};
var getScrollLeft = function()
{
var item = props.horizontal;
return item.element[item.scroll];
};
var getVerticalScrollHeight = function()
{
var item = props.vertical;
return item.element[item.scrollSize];
};
var getHorizontalScrollWidth = function()
{
var item = props.horizontal;
return item.element[item.scrollSize];
};
var hasHorizontalScroller = function()
{
return hasScroll(props.horizontal);
};
var hasVerticalScroller = function()
{
return hasScroll(props.vertical);
};
var getHorizontalScroller = function()
{
var item = props.horizontal;
return item.container;
};
var getVerticalScroller = function()
{
var item = props.vertical;
return item.container;
};
var getHorizontalBar = function()
{
var item = props.horizontal;
return item.scroller;
};
var getVertcialBar = function()
{
var item = props.vertical;
return item.scroller;
};
var initialize = function()
{
util = new NSUtil();
setConfig();
setProps();
createComponent();
if(isSameElement)
{
var element = props[Object.keys(props)[0]].target;
util.addStyleClass(element,"nsScrollerScrollable");
util.addStyleClass(element,"nsScrollerElement");
//DOMMouseScroll for Firefox
util.addEvent(element,"mousewheel DOMMouseScroll",mouseWheelHandler);
util.addEvent(element,"scroll",bodyScrollHandler);
}
if(config.otherScrollableElement && config.otherScrollableElement.length > 0)
{
for(var count = 0;count < config.otherScrollableElement.length;count++)
{
var element = config.otherScrollableElement[count];
//DOMMouseScroll for Firefox
util.addEvent(element,"mousewheel DOMMouseScroll",mouseWheelHandler);
}
}
updateScrollBars();
util.addEvent(window,"resize",updateWithDelay);
addObserver();
};
var setConfig = function()
{
if(!setting)
{
setting = {};
}
config = {
parentElement : setting["parentElement"],
element : setting["element"],
verticalElement : setting["verticalElement"] || setting["element"],
verticalParentElement : setting["verticalParentElement"] || setting["parentElement"],
horizontalElement : setting["horizontalElement"] || setting["element"],
horizontalParentElement : setting["horizontalParentElement"] || setting["parentElement"],
otherScrollableElement : setting["otherScrollableElement"],//for Grid if we have left,center and right body
horizontalScrollButtons: setting["horizontalScrollButtons"] || {enable:false,leftHTML:null,rightHTML:null},
verticalScrollButtons: setting["verticalScrollButtons"] || {enable:false,topHTML:null,bottomHTML:null},
elementPosition: setting["elementPosition"] || "relative" ,// if content has fixable headers then use static (values: static,relative,absolute)
enableCustomHandler: Boolean.parse(setting["enableCustomHandler"]),
scrollWidth: setting["scrollWidth"],
scrollHeight: setting["scrollHeight"],
enableMoveOnClick: Boolean.parse(setting["enableMoveOnClick"]),
enableAnimation: Boolean.parse(setting["enableAnimation"]),
};
if(!config.verticalElement && !config.horizontalElement)
{
util.throwNSError("NSScroller","Element in setting is missing");
}
if(!config.verticalParentElement)
{
config.verticalParentElement = config.verticalElement.parentNode;
}
if(!config.horizontalParentElement)
{
config.horizontalParentElement = config.horizontalElement.parentNode;
}
if(config.verticalElement && config.horizontalElement && config.verticalElement == config.horizontalElement)
{
isSameElement = true;
}
//parentNode = config.element.parentNode;
if(config.horizontalScrollButtons.enable)
{
if(!config.horizontalScrollButtons.leftHTML)
{
config.horizontalScrollButtons.leftHTML = '<span class="nsScrollerControlBtnLeft"></span>';
}
if(!config.horizontalScrollButtons.rightHTML)
{
config.horizontalScrollButtons.rightHTML = '<span class="nsScrollerControlBtnRight"></span>';
}
}
if(config.verticalScrollButtons.enable)
{
if(!config.verticalScrollButtons.topHTML)
{
config.verticalScrollButtons.topHTML = '<span class="nsScrollerControlBtnUp"></span>';
}
if(!config.verticalScrollButtons.bottomHTML)
{
config.verticalScrollButtons.bottomHTML = '<span class="nsScrollerControlBtnDown"></span>';
}
}
};
var setProps = function()
{
props = {
vertical: {
x: "Y",direction:"v", displayDirection:"vertical", pos: "top",
size: "height",crossSize: "width", crossMinSize: "min-width", crossMaxSize: "max-width",
client: "clientHeight", crossClient: "clientWidth",
scrollEdge: "scrollLeft",offset: "offsetHeight", crossOffset: "offsetWidth", offsetPos: "offsetTop",
scroll: "scrollTop", scrollSize: "scrollHeight",barTopLimit:0,containerCSS:"nsScrollerVerticalContainer",
scrollerCSS:"nsScrollerVerticalBar",buttonProp:"verticalScrollButtons",beforeButtonProp:"topHTML",
afterButtonProp:"bottomHTML",beforeButtonCSS:"nsScrollerButtonUp",afterButtonCSS:"nsScrollerButtonDown",
elementPosition:config.elementPosition,inputSize:config.scrollHeight,decreaseScrollSize:false,
targetProp:"verticalElement",targetParentProp:"verticalParentElement",isMouseWheelReq:true,
eventProp:"clientY",paddingStart:"paddingTop",paddingEnd:"paddingBottom"
},
horizontal: {
x: "X",direction:"h",displayDirection:"horizontal", pos: "left",
size: "width",crossSize: "height", crossMinSize: "min-height", crossMaxSize: "max-height",
client: "clientWidth", crossClient: "clientHeight",
scrollEdge: "scrollTop",offset: "offsetWidth", crossOffset: "offsetHeight", offsetPos: "offsetLeft",
scroll: "scrollLeft", scrollSize: "scrollWidth",barTopLimit:0,containerCSS:"nsScrollerHorizontalContainer",
scrollerCSS:"nsScrollerHorizontalBar",buttonProp:"horizontalScrollButtons",beforeButtonProp:"leftHTML",
afterButtonProp:"rightHTML",beforeButtonCSS:"nsScrollerButtonLeft",afterButtonCSS:"nsScrollerButtonRight",
elementPosition:config.elementPosition,inputSize:config.scrollWidth,decreaseScrollSize:false,
targetProp:"horizontalElement",targetParentProp:"horizontalParentElement",isMouseWheelReq:false,
eventProp:"clientX",paddingStart:"paddingLeft",paddingEnd:"paddingRight"
}
};
};
var setScrollPos = function(item,scrollPos)
{
selectedItem = item;
if(selectedItem)
{
util.addEvent(selectedItem.element,"scroll",scrollableElementScrollHandler);
setScrollableItems(selectedItem,scrollPos);
}
};
var applyStyle = function(item,on)
{
var overflow = on ? 'hidden' : null;
var msOverflowStyle = on ? 'none' : null;
util.css(item.target.parentNode, {
overflow: overflow,
msOverflowStyle: msOverflowStyle,
position: (item.elementPosition == 'static') ? '' : 'relative'
});
var scroll = on ? 'scroll' : null;
var axis = item.direction == 'v' ? 'y' : 'x';
var css = {};
css['overflow-' + axis] = scroll;
css['box-sizing'] = 'border-box';
css.margin = '0';
css.border = '0';
if(item.elementPosition == 'absolute')
{
css.position = 'absolute';
css.top = '0';
if (item.direction == 'h')
{
css.left = '0';
}
else
{
css.bottom = '0';
css.right = item.rtl ? '0' : '';
css.left = item.rtl ? '' : '0';
}
}
util.css(item.target,css);
};
var onScrollerMouseDown = function(event,scroller)
{
setSelectedItem(event,null,true);
if(selectedItem)
{
event.preventDefault();
event.stopPropagation();
if(selectedItem.activeCSS)
{
util.addStyleClass(selectedItem.scroller,selectedItem.activeCSS);
}
dispatchScrollStartEvent(selectedItem,event);
}
};
var setSelectedItem = function(event,target,setScrollPos)
{
target = target ? target : event.target;
selectedItem = getItemByScroller(target);
if(selectedItem)
{
selectedItem.dragging = true;
if(setScrollPos)
{
selectedItem.scrollerPos = getCursorPosition(selectedItem,event) - selectedItem.barPos;
}
}
};
var getItemByScroller = function(scroller)
{
for(var key in props)
{
var item = props[key];
if(item.scroller == scroller)
{
return item;
}
}
return null;
};
var createComponent = function()
{
for(var key in props)
{
var item = props[key];
item.target = config[item.targetProp];
item.targetParent = config[item.targetParentProp];
if(!isSameElement)
{
util.addStyleClass(item.target,"nsScrollerScrollable");
util.addStyleClass(item.target,"nsScrollerElement");
if(item.isMouseWheelReq)
{
util.addEvent(item.target,"mousewheel",mouseWheelHandler);
}
//util.addEvent(item.target,"scroll",bodyScrollHandler);
}
var container = createScroller(null,item.containerCSS,item.scrollerCSS);
var scroller = container.children[0];
var eleBefore = null;
var eleAfter = null;
var scrollerParent = container;
if(config[item.buttonProp]["enable"])
{
var eleBefore = createButton(item,item.beforeButtonCSS,config[item.buttonProp][item.beforeButtonProp]);
container.appendChild(eleBefore);
scrollerParent = util.createDiv(null,"nsScrollerBarParent-" + item.direction);
scrollerParent.appendChild(scroller);
container.appendChild(scrollerParent);
var eleAfter = createButton(item,item.afterButtonCSS,config[item.buttonProp][item.afterButtonProp]);
container.appendChild(eleAfter);
item.buttonBefore = eleBefore;
item.buttonAfter = eleAfter;
}
util.addStyleClass(scrollerParent,"nsScrollerBarParent");
item.targetParent.appendChild(container);
//container.style[item.crossSize] = scroller[item.crossOffset] + "px";
var setting = {element:scroller,restriction:"parent",enableXAxis:(item.direction != "v"),enableYAxis:(item.direction == "v"),
dragStartingCallback:onScrollerMouseDown,draggingCallback:docMouseMoveHandler,dragEndCallback:docMouseUpHandler,
enableMoveOnClick:config.enableMoveOnClick,moveOnClickCallback:scrollerClickHandler};
var objDrag = new nsScrollerDraggable(setting);
var divScrollCause = util.createDiv(null);
divScrollCause.innerHTML = " ";
var divScroll = util.createDiv("divTest" + item.x);
var css = {};
css["position"] = "absolute";
css["overflow-" + item.x.toLowerCase()] = "scroll";
css["left"] = "-9999px";
css["top"] = "-9999px";
util.css(divScroll,css);
divScroll.appendChild(divScrollCause);
document.body.appendChild(divScroll);
item.scrollContainer = container;
item.container = scrollerParent;
item.scroller = scroller;
item.element = divScroll;
item.scrollableElementCause = divScrollCause;
item.objDrag = objDrag;
setScrollElementSize(item);
}
if(isSameElement)
{
divScrollBarCorner = util.createDiv(null,"nsScrollBarCorner");
props[Object.keys(props)[0]].targetParent.appendChild(divScrollBarCorner);
}
};
var createScroller = function(id,cssContainer,cssScroller)
{
cssContainer = cssContainer ? cssContainer : "";
cssScroller = cssScroller ? cssScroller : "";
var scrollContainer = util.createDiv(null,"nsScrollerContainer " + cssContainer);
var scroller = util.createDiv(null,"nsScrollerBar " + cssScroller);
scrollContainer.appendChild(scroller);
return scrollContainer;
};
var createButton = function(item,css,html)
{
var div = util.createDiv(null,"nsScrollerControl nsScrollerControl-" + item.direction);
div.innerHTML = html;
util.addStyleClass(div,css);
//util.addEvent(div,"click",btnControlClickHandler);
util.addEvent(div,"mousedown",btnMouseDownHandler);
util.addEvent(div,"dblclick",btnMouseDownHandler);
util.addEvent(div,"mouseup",clearScroll);
util.addEvent(div,"mouseout",clearScroll);
return div;
};
var btnMouseDownHandler = function(event)
{
//console.log("btnMouseDownHandler " + event.type);
btnControlClickHandler(event);
clearTimeout(interval);
interval = setTimeout(function(){btnMouseDownHandler(event);}, 200);
};
var clearScroll = function(event)
{
//console.log("clearScroll " + event.type);
clearTimeout(interval);
interval = null;
lastScrollPos = -1;
};
var btnControlClickHandler = function(event)
{
event = util.getEvent(event);
var target = event.target;
var parent = util.findParent(target,null,".nsScrollerContainer");
var scroller = parent.querySelector(".nsScrollerBar");
setSelectedItem(event,scroller,true);
if(selectedItem)
{
var btnParent = util.findParent(target,null,".nsScrollerControl");
var isAdd = true;
if(util.hasStyleClass(btnParent,selectedItem.beforeButtonCSS))
{
isAdd = false;
}
var oldPos = scrollableElementPosition(selectedItem);
var newPos = isAdd ? (oldPos + 30) : (oldPos - 30);
util.addEvent(selectedItem.element,"scroll",scrollableElementScrollHandler);
scrollableElementPosition(selectedItem,newPos);
//selectedItem = null;
event.preventDefault();
event.stopPropagation();
}
};
var mouseWheelHandler = function(event)
{
event = util.getEvent(event);
var element = props.vertical.targetParent;
var verticalScroller = element.querySelector(".nsScrollerVerticalBar");
setSelectedItem(event,verticalScroller,true);
if(selectedItem)
{
util.addEvent(selectedItem.element,"scroll",scrollableElementScrollHandler);//selectedItem.objDrag.setElementPos(null,100);
var oldPos = selectedItem.element[selectedItem.scroll];
var newPos = oldPos + event["delta" + selectedItem.x];
selectedItem.element[selectedItem.scroll] = newPos;
if(config.enableCustomHandler)
{
event.preventDefault();
event.stopPropagation();
}
dispatchScrollingEvent(selectedItem,newPos,oldPos,event);
mouseWheelEndEvent(selectedItem,event);
}
};
var mouseWheelEndEvent = function(item,event)
{
if(mouseWheelEndInterval)
{
clearInterval(mouseWheelEndInterval);
mouseWheelEndInterval = null;
mouseWheelEndInterval = setInterval(function() {
dispatchScrollEndEvent(item,event);
}, 300);
}
};
var scrollableElementScrollHandler = function(event)
{
event = util.getEvent(event);
if(selectedItem)
{
elementScrollHandler(selectedItem.element,selectedItem,event);
setIsInternalWithOutDelay = false;
isInternalScroll = true;
util.removeEvent(selectedItem.element,"scroll",scrollableElementScrollHandler);
}
};
var bodyScrollHandler = function(event)
{
if(!isInternalScroll)
{
console.log("In Element Scroll");
event = util.getEvent(event);
for(var key in props)
{
var item = props[key];
var scroller = item.scroller;
setSelectedItem(event,scroller,true);
if(selectedItem)
{
selectedItem.element[selectedItem.scroll] = selectedItem.target[selectedItem.scroll];
elementScrollHandler(selectedItem.target,selectedItem,event);
isInternalScroll = true;
}
}
}
if(setIsInternalWithOutDelay)
{
isInternalScroll = false;
}
else
{
if (itemElementScrollInterval != -1)
{
clearTimeout(itemElementScrollInterval);
itemElementScrollInterval = -1;
setIsInternalWithOutDelay = false;
isInternalScroll = true;
}
itemElementScrollInterval = setTimeout(
function()
{
setIsInternalWithOutDelay = true;
isInternalScroll = false;
},1000);
}
};
var docMouseMoveHandler = function(event,scroller)
{
event = util.getEvent(event);
if(!selectedItem)
{
setSelectedItem(event,scroller,true);
}
if(selectedItem)
{
dragHandler(selectedItem,event);
scrollBody(selectedItem,event);
}
};
var docMouseUpHandler = function(event)
{
event = util.getEvent(event);
if(selectedItem.activeCSS)
{
util.removeStyleClass(selectedItem.scroller,selectedItem.activeCSS);
}
updateScrollBars();
var item = selectedItem;
selectedItem = null;
clearScroll();
dispatchScrollEndEvent(item,event);
};
var scrollerClickHandler = function(event,target,oldBarBound,newBarBound,oldTrackBound,newTrackBound)
{
event = util.getEvent(event);
//if(!selectedItem)
//{
setSelectedItem(event,target,false);
//}
if(selectedItem)
{
var item = selectedItem;
var perc = (event[item.eventProp] - oldTrackBound[item.pos]) / (oldTrackBound[item.size] - oldTrackBound[item.paddingStart] - oldTrackBound[item.paddingEnd]);
var scrollSize = item.scrollableElementCause[item.scrollSize];
var clientSize = item.targetParent[item.client];
var newScrollPos = perc * (scrollSize - clientSize);
if(config.enableAnimation)
{
var isSmoothScrollSupported = 'scrollBehavior' in document.documentElement.style;
if(isSmoothScrollSupported)
{
item.target.style.scrollBehavior = 'smooth';
setTimeout(function(){item.target.style.scrollBehavior = null;}, 500);
setScrollPos(item,newScrollPos);
}
else
{
var scrollAnimateSetting = {element: item.target,direction:item.displayDirection,callback:function(){
setScrollPos(item,newScrollPos);
}};
var scrollerAnimate = new NSScrollAnimator(scrollAnimateSetting);
scrollerAnimate.scrollTo(newScrollPos);
}
}
else
{
setScrollPos(item,newScrollPos);
}
}
};
var scrollBody = function(item,event)
{
updateScrollPositions(item,false);
};
var dragHandler = function(item,event)
{
if(!item.scrollerPos)
{
item.scrollerPos = 0;
}
var relPos = barPositionToRelative(item,getCursorPosition(item,event) - item.scrollerPos);
var subPos = item.element[item.scrollSize] - item.element[item.client];
var scrollPos = relPos * subPos;
//console.log(relPos + " * " + subPos + " = " + scrollPos);
setScrollableItems(item,scrollPos);
};
var setScrollableItems = function(item,scrollPos)
{
scrollPos = Math.round(scrollPos);
var maxValue = item.element[item.scrollSize] - item.element[item.client];
//console.log(scrollPos);
if(scrollPos < 0)
{
scrollPos = 0;
}
if(scrollPos > maxValue)
{
scrollPos = maxValue;
}
var lastScrollPos = item.element[item.scroll];
if(lastScrollPos != scrollPos)
{
//console.log(scrollPos + " == " + item.element[item.scrollSize]);
setIsInternalWithOutDelay = true;
isInternalScroll = true;
item.element[item.scroll] = scrollPos;
if(!config.enableCustomHandler)
{
item.target[item.scroll] = scrollPos;
if(config.otherScrollableElement && config.otherScrollableElement.length > 0)
{
for(var count = 0;count < config.otherScrollableElement.length;count++)
{
var element = config.otherScrollableElement[count];
element[item.scroll] = scrollPos;
}
}
}
dispatchScrollingEvent(item,scrollPos,lastScrollPos);
}
lastScrollPos = scrollPos;
};
var getCursorPosition = function(item,event)
{
return event["client" + item.x] || ((event.touches || {})[0] || {})["page" + item.x];
};
var updateScrollBars = function()
{
for(var key in props)
{
var item = props[key];
applyStyle(item,true);
setScrollElementSize(item);
resizeHandler(item);
updateScrollPositions(item,true);
}
updateScrollControls();
};
var resizeHandler = function(item)
{
var updatePos = function()
{
var offset = item.element[item.crossOffset];
var client = item.element[item.crossClient];
var padding = 0;
var oldPos, newPos;
if (isMacFF)
{
padding = macScrollBarSize;
}
else if (client > 0 && offset === 0)
{
offset = client + operaMaxScrollBarSize;
}
if (offset)
{
var delta = offset - client + padding;
if (item.elementPosition == 'static')
{
oldPos = util.css(item.element,item.crossSize);
newPos = item.target.parentNode[item.crossClient] + delta + "px";
if (oldPos != newPos)
{
setCrossSizes(item,item.element, newPos);
}
}
else
{
var styles = {};
var key = item.rtl ? 'Left' : 'Right';
if (item.direction == 'h')
{
key = 'Bottom';
}
util.css(item.element, styles);
}
}
item.resizeLastFire = getCurrentTime();
};
var container = item["container"];
var scroller = item["scroller"];
var scrollerSize = item["scrollerSize"];
var barPos = item["barPos"];
var minPeriod = (item.resizeDebounce === undefined) ? 300 : item.resizeDebounce;
var delay = 0;
if (getCurrentTime() - item.resizeLastFire < minPeriod)
{
clearTimeout(item.resizePauseTimer);
delay = minPeriod;
}
if (delay)
{
item.resizePauseTimer = setTimeout(updatePos, delay);
}
else
{
updatePos();
}
};
var elementScrollHandler = function(element,item,event)
{
if(element && item)
{
var elementOffset = element[item.offset];
if(item.buttonBefore)
{
elementOffset = elementOffset - item.buttonBefore[item.offset];
}
if(item.buttonAfter)
{
elementOffset = elementOffset - item.buttonAfter[item.offset];
}
item["barPos"] = Math.round((elementOffset/element[item.scrollSize]) * element[item.scroll]);
setBarPosition(item, item["barPos"]);
}
};
var setElementScrollPos = function(element,item,newScrollPos)
{
if(config.enableAnimation)
{
/*var isSmoothScrollSupported = 'scrollBehavior' in document.documentElement.style;
if(isSmoothScrollSupported)
{
element.style.scrollBehavior = 'smooth';
setTimeout(function(){element.style.scrollBehavior = null;}, 500);
}
else
{*/
var scrollAnimateSetting = {element: element,direction:item.displayDirection,callback:function(){
}};
var scrollerAnimate = new NSScrollAnimator(scrollAnimateSetting);
scrollerAnimate.scrollTo(newScrollPos);
//}
}
};
var addObserver = function()
{
var mutationProp = { attributes: false, childList: true, subtree: true};
var callback = function(mutationsList, observer)
{
for(var count = 0;count < mutationsList.length;count++)
{
var mutation = mutationsList[count];
if (mutation.type == 'childList')
{
updateWithDelay();
}
}
};
var mutationObserver = new MutationObserver(callback);
if(isSameElement)
{
var element = props[Object.keys(props)[0]].target;
mutationObserver.observe(element,mutationProp);
}
else
{
for(key in props)
{
var item = props[key];
mutationObserver.observe(item.target,mutationProp);
}
}
};
var updateWithDelay = function()
{
stopDelayInterval();
delayInterval = setInterval(function() {
updateScrollBars();
stopDelayInterval();
}, 300);
};
var stopDelayInterval = function()
{
if(delayInterval)
{
clearInterval(delayInterval);
delayInterval = null;
}
};
var setCrossSizes = function(item,element,size)
{
var styles = {};
styles[item.crossSize] = size;
styles[item.crossMinSize] = size;
styles[item.crossMaxSize] = size;
util.css(element, styles);
};
var getCurrentTime = function()
{
return new Date().getTime();
};
var updateScrollPositions = function(item,isReset,isSetBarPos)
{
checkScroll(item);
var container = item["container"];
var scroller = item["scroller"];
var scrollerSize = item["scrollerSize"];
var barPos = item["barPos"];
var extraOffset = isBothScrollPresent() ? 16 : 0;
var newBarSize = (container[item.client] - item.barTopLimit) * (item.element[item.client] / item.element[item.scrollSize]);
/*if(config[item.buttonProp]["enable"])
{
}*/
if((newBarSize - extraOffset) > 0)
{
newBarSize = newBarSize - extraOffset;
}
//console.log(item.displayDirection + " , " + container[item.client] + " , " + item.barTopLimit + " , " + item.element[item.client] + " , " + item.element[item.scrollSize]);
// Positioning bar
if (isReset || parseInt(scrollerSize, 10) != parseInt(newBarSize, 10))
{
setScrollerSize(item,newBarSize);
item["scrollerSize"] = newBarSize;
}
item["barPos"] = relativeToBarPosition(item,relativePosition(item));
if(isSetBarPos)
{
setBarPosition(item, item["barPos"]);
}
};
var setBarPosition = function(item,position)
{
var scroller = item["scroller"];
var sendItem = {deltaX:null,deltaY:null};
sendItem["delta" + item.x] = position - parseInt(scroller.style[item.pos]);
item.objDrag.setPosition(sendItem.deltaX,sendItem.deltaY);
var oldPos = scroller.style[item.pos];
var newPos = position + "px";
if (newPos && newPos != oldPos)
{
scroller.style[item.pos] = newPos;
}
};
var setScrollerSize = function(item,size)
{
var scroller = item["scroller"];
var barMinSize = item.barMinSize || 20;
var newSize = size;
if (newSize > 0 && newSize < barMinSize)
{
newSize = barMinSize;
}
if(scroller)
{
scroller.style[item.size] = parseInt(newSize, 10) + "px";
}
};
var setScrollElementSize = function(item)
{
var scrollCss = {};
//console.log(item.displayDirection + " , " + config.element[item.offset] + " , " + config.element[item.scrollSize]);
var offset = 0;
var scrollBarSize = item.decreaseScrollSize ? getScrollBarSize(item) : 0;
scrollCss[item.size] = item.target[item.client] - scrollBarSize + "px";
util.css(item.element,scrollCss);
var causeCss = {};
if(util.isUndefinedOrNull(item.inputSize) || parseInt(item.inputSize) <= 0)
{
causeCss[item.size] = (item.target[item.scrollSize]) + "px";
}
else
{
causeCss[item.size] = parseInt(item.inputSize) + "px";
}
util.css(item.scrollableElementCause,causeCss);
};
var relativePosition = function(item,position)
{
var size = item.element[item.scrollSize] - item.element[item.client];
var newPos;
if(position)
{
newPos = scrollableElementPosition(item,position * size);
}
else
{
newPos = scrollableElementPosition(item);
}
return newPos / (size || 1);
};
var scrollableElementPosition = function(item,x)
{
var ie = "page" + item.x + "Offset";
var key = (item.element[ie]) ? ie : item.scroll;
if (!util.isUndefined(x))
{
if(key === item.scroll)
{
setScrollableItems(item,x);
}
else
{
item.element[key] = x;
}
}
return item.element[key];
};
var relativeToBarPosition = function(item,pos)
{
return pos * getPos(item) + item.barTopLimit;
};
var barPositionToRelative = function(item,pos)
{
return (pos - item.barTopLimit) / getPos(item);
};
var getPos = function(item)
{
return item.container[item.client] - item.barTopLimit - item.scroller[item.offset];
};
var checkScroll = function(item)
{
var scrollContainer = item["scrollContainer"];
var scroller = item["scroller"];
var isOverflowing = hasScroll(item);
if(isOverflowing)
{
util.addStyleClass(item.target,"nsScrollerScrollable-" + item.direction);
util.removeStyleClass(scrollContainer,"nsScrollerHidden");
}
else
{
util.removeStyleClass(item.target,"nsScrollerScrollable-" + item.direction);
util.addStyleClass(scrollContainer,"nsScrollerHidden");
}
};
var hasScroll = function(item)
{
var isOverflowing = item.element[item.client] < item.element[item.scrollSize];
return isOverflowing;
};
var updateScrollControls = function()
{
var scrollPresent = isBothScrollPresent();
for(var key in props)
{
var item = props[key];
var scrollContainer = item["scrollContainer"];
var container = item["container"];
var scroller = item["scroller"];
if(scrollPresent && isSameElement)
{
util.addStyleClass(scrollContainer,item.containerCSS + "-both");
util.addStyleClass(scrollContainer,"nsScrollerBarParent" + "-" + item.direction + "-both");
if(item.buttonAfter)
{
util.addStyleClass(item.buttonAfter,item.afterButtonCSS + "-both");
}
}
else
{
util.removeStyleClass(scrollContainer,item.containerCSS + "-both");
util.removeStyleClass(scrollContainer,"nsScrollerBarParent" + "-" + item.direction + "-both");
if(item.buttonAfter)
{
util.removeStyleClass(item.buttonAfter,item.afterButtonCSS + "-both");
}
}
}
if(scrollPresent)
{
util.removeStyleClass(divScrollBarCorner,"nsScrollerHidden");
}
else
{
util.addStyleClass(divScrollBarCorner,"nsScrollerHidden");
}
};
var isBothScrollPresent = function()
{
var arrScrollContainer = [];
for(key in props)
{
var item = props[key];
if(item && item.targetParent && item.targetParent.querySelectorAll(".nsScrollerContainer"))
{
var arrCon = item.targetParent.querySelectorAll(".nsScrollerContainer");
for(var index in arrCon)
{
arrScrollContainer.push(arrCon[index]);
}
}
}
var retValue = true;
for(var count = 0;count < arrScrollContainer.length;count++)
{
var scrollContainer = arrScrollContainer[count];
if(util.hasStyleClass(scrollContainer,"nsScrollerHidden"))
{
retValue = false;
}
}
return retValue;
};
var getScrollBarSize = function(item,element)
{
if(!element)
{
element = item.target;
}
var scrollContainer = item["scrollContainer"];
if(util.hasStyleClass(scrollContainer,"nsScrollerHidden"))
{
return 0;
}
//if Chrome then scrollbar size is 0 so the below condition is 0 but we should return the scrollbar size
if((element[item.offset] - element[item.client]) == 0)
{
return util.getScrollBarWidth();
}
return 0;
};
var remove = function()
{
for(var key in props)
{
var item = props[key];
if(item.objDrag)
{
item.objDrag.remove();
}
}
util.removeEvent(window,"resize",updateWithDelay);
clearScroll();
if(mutationObserver)
{
mutationObserver.disconnect();
}
};
var dispatchScrollStartEvent = function(item,event)
{
var eventItem = getEventItem(item,event);
dispatchEvent(NSScroller.SCROLL_START,eventItem,eventItem,item);
};
var dispatchScrollingEvent = function(item,newScrollPos,oldScrollPos,event)
{
var eventItem = getEventItem(item,event || window.event,{oldScrollPos:oldScrollPos,scrollPos:newScrollPos});
dispatchEvent(NSScroller.SCROLLING,eventItem,eventItem,item);
};
var dispatchScrollEndEvent = function(item,event)
{
var eventItem = getEventItem(item,event);
dispatchEvent(NSScroller.SCROLL_END,eventItem,eventItem,item);
};
var getEventItem = function(item,event,objExtraProp)
{
var position = getAbsoluteElementPosition(item.scroller);
var eventItem = {scroller:item.container,scrollBar:item.scroller,direction:item.displayDirection,scrollPos:item.element[item.scroll],orignalEvent: event,absoluteScrollBarPos: position};
if(objExtraProp)
{
for(var key in objExtraProp)
{
eventItem[key] = objExtraProp[key];
}
}
return eventItem;
};
var dispatchEvent = function(eventType,data,param,item,bubbles,cancelable)
{
util.dispatchEvent(item.target,eventType,data,param,bubbles,cancelable);
};
var getAbsoluteElementPosition = function(element)
{
var position = {x:0,y:0};
var rec = element.getBoundingClientRect();
position = {y: rec.top + window.scrollY, x: rec.left + window.scrollX};
return position;
};
var nsScrollerDraggable = function(setting)
{
var self = this;
var util = null;
var config = {};
var objVar = {};
var fromMouseUpHandler = false;
var documentMouseMoveRef = null;
var documentMouseUpRef = null;
var documentTouchMoveRef = null;
var documentTouchEndRef = null;
var initialize = function()
{
util = new NSUtil();
if(!setting)
{
setting = {};
}
config = {
element: setting["element"],
restriction: setting["restriction"],
enableXAxis: util.isUndefinedOrNull(setting["enableXAxis"]) ? true : Boolean.parse(setting["enableXAxis"]),
enableYAxis: util.isUndefinedOrNull(setting["enableYAxis"]) ? true : Boolean.parse(setting["enableYAxis"]),
xBoundaryElement: setting["xBoundaryElement"],
yBoundaryElement: setting["yBoundaryElement"],
enableMoveOnClick: Boolean.parse(setting["enableMoveOnClick"]),
context: setting["context"] || window,
document: setting["document"] || document,
body: setting["body"] || document.body,
};
if(!config.element)
{
util.throwNSError("NSScrollerDraggable","Element in setting is missing");
}
util.addStyleClass(config.element,"nsScrollerDraggableElement");
config.dragStartingCallback = util.getFunction(setting["dragStartingCallback"],config.context);
config.draggingCallback = util.getFunction(setting["draggingCallback"],config.context);
config.dragEndCallback = util.getFunction(setting["dragEndCallback"],config.context);
if(config.restriction == "parent")
{
config.xBoundaryElement = config.element.parentNode;
config.yBoundaryElement = config.element.parentNode;
}
var position = util.getStyleValue(config.element,"position",true);
if(position != "relative" && position != "absolute")
{
config.element.style.position = "relative";
}
config.element.style.top = "0px";
config.element.style.left = "0px";
util.addEvent(config.element,"mousedown",elementMouseDownHandler);
if(config.enableMoveOnClick)
{
util.addEvent(config.xBoundaryElement,"click",boundaryElementClickHandler);
util.addEvent(config.yBoundaryElement,"click",boundaryElementClickHandler);
config.moveOnClickCallback = util.getFunction(setting["moveOnClickCallback"],config.context);
}
};
var elementMouseDownHandler = function(event)
{
event = util.getEvent(event);
objVar.dragging = true;
var rect = config.element.getBoundingClientRect();
objVar.initX = event.clientX - rect.left;
objVar.initY = event.clientY - rect.top;
objVar.initLeft = config.element.style.left;
objVar.initTop = config.element.style.top;
selection(false);
addDocumentHandler();
if(config.dragStartingCallback)
{
config.dragStartingCallback(event,config.element);
}
};
var windowMouseMoveHandler = function(event)
{
if(objVar.dragging)
{
event = util.getEvent(event);
var rect = config.element.getBoundingClientRect();
var deltaX = event.clientX - (objVar.initX + rect.left);
var deltaY = event.clientY - (objVar.initY + rect.top);
setElementPos(deltaX,deltaY);
if(config.draggingCallback)
{
config.draggingCallback(event,config.element);
}
}
};
var windowMouseUpHandler = function(event)
{
if (objVar.dragging)
{
event = util.getEvent(event);
complete(event);
release();
}
removeDocumentHandler();
event.stopPropagation();
event.preventDefault();
fromMouseUpHandler = true;
setTimeout(function(){fromMouseUpHandler = false;},1000);
};
var windowKeyDownHandler = function(event)
{
event = util.getEvent(event);
if (event.key === "Escape" && objVar.dragging)
{
cancel();
release();
}
};
var boundaryElementClickHandler = function(event)
{
if(!fromMouseUpHandler)
{
var shiftTo = function(x, y)
{
if (bar && !isNaN(x) && !isNaN(y))
{
bar.style.left = Math.round(x) + "px";
bar.style.top = Math.round(y) + "px";
}
};
event = util.getEvent(event);
var target = event.currentTarget;
var currentParentBound = getElementDimensions(target);
var currentElementBound = getElementDimensions(config.element);
var xPosition = event.clientX - currentParentBound.x - (config.element.clientWidth);
var yPosition = event.clientY - currentParentBound.y - (config.element.clientHeight);
setElementPos(xPosition - currentElementBound.styleLeft,yPosition - currentElementBound.styleTop);
var newParentBound = getElementDimensions(target);
var newElementBound = getElementDimensions(config.element);
if(config.moveOnClickCallback)
{
config.moveOnClickCallback(event,config.element,currentElementBound,newElementBound,currentParentBound,newParentBound);
}
release();
}
fromMouseUpHandler = false;
};
var getElementDimensions = function(element)
{
if(element)
{
var bounds = element.getBoundingClientRect();
var styles = window.getComputedStyle(element, null);
bounds.paddingTop = parseInt(styles.paddingTop, 10);
bounds.paddingBottom = parseInt(styles.paddingBottom, 10);
bounds.paddingLeft = parseInt(styles.paddingLeft, 10);
bounds.paddingRight = parseInt(styles.paddingRight, 10);
bounds.styleTop = parseInt(styles.top, 10);
bounds.styleBottom = parseInt(styles.bottom, 10);
bounds.styleLeft = parseInt(styles.left, 10);
bounds.styleRight = parseInt(styles.right, 10);
return bounds;
}
return null;
};
var setElementPos = function(deltaX,deltaY)
{
var rect = config.element.getBoundingClientRect();
if (config.enableXAxis)
{
var newLeft = parseInt(config.element.style.left) + deltaX;
if (config.xBoundaryElement)
{
var boundaryRect = config.xBoundaryElement.getBoundingClientRect();
var dragDestination = rect.left + deltaX;
var notPastLeft = dragDestination >= boundaryRect.left;
var notPastRight = dragDestination <= (boundaryRect.right - rect.width);
if (notPastLeft && notPastRight)
{
config.element.style.left = newLeft + "px";
}
else if (!notPastLeft)
{
config.element.style.left = newLeft - (dragDestination - boundaryRect.left) + "px";
}
else if (!notPastRight)
{
config.element.style.left = newLeft - (dragDestination - boundaryRect.right + rect.width) + "px";
}
}
else
{
config.element.style.left = newLeft + "px";
}
}
if (config.enableYAxis)
{
var newTop = parseInt(config.element.style.top) + deltaY;
if (config.yBoundaryElement)
{
var boundaryRect = config.yBoundaryElement.getBoundingClientRect();
var dragDestination = rect.top + d