UNPKG

nscomponentsreact

Version:

React Wrapper Components for NSComponents

1,563 lines (1,457 loc) 55.3 kB
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 = "&nbsp;"; 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