' + data.result.FilePath + ''); + if (testContent.length) { + src = testContent.text(); + } + else + src = data.result; + + if (src && $.trim(src)) { + var profileImagePath = dnn.getVar("sf_siteRoot", "/") + 'DnnImageHandler.ashx?mode=securefile&fileId=' + data.result.FileId + '&MaxWidth=180&MaxHeight=150'; + img.src = profileImagePath; + + var fileName = data.result.FilePath.replace('\\', '/'); + if (fileName.indexOf('/') > -1) { + fileName = fileName.split('/')[fileName.split('/').length - 1]; + } + if (fileName.indexOf('?') > -1) { + fileName = fileName.split('?')[0]; + } + + dnn[settings.filesComboId].refresh(dnn[settings.foldersComboId].selectedItem().key); + dnn[settings.filesComboId].selectedItem({ key: data.result.FileId, value: fileName}); + } + }, + fail: function (e, data) { + $('#' + settings.progressBarId).parent().hide(); + var resp = JSON.parse(data.jqXHR.responseText); + alert(resp.Message); + } + }); + + $('#' + scope + ' input[name=uploadFileButton]').click(function() { + var instance = dnn[settings.fileUploadId]; + + var options = instance.options; + if (dnn[settings.foldersComboId].selectedItem() != null) { + instance.options.folderPicker.initialState.selectedItem = dnn[settings.foldersComboId].selectedItem(); + instance.options.folderPath = window.dnn.dnnFileUpload.getSelectedPath(dnn[settings.foldersComboId]); + } + + instance.show(options); + + window.dnn.dnnFileUpload.updateExpandPath(dnn[settings.foldersComboId], instance._panel._folderPicker.id()); + + instance._panel.$element.on("onfileuploadcomplete", function (event, data) { + if (typeof data == "string") { + // for modern browsers + data = JSON.parse(data); + }else{ + // for IE8-9 + var b = data[0]; + data = JSON.parse(b.body.innerText); + } + if (data && data.fileId) { + var folderPicker = instance._panel._folderPicker; + dnn[settings.foldersComboId].selectedItem(folderPicker.selectedItem()); + window.dnn.dnnFileUpload.Folders_Changed(dnn[settings.foldersComboId].selectedItem(), dnn[settings.foldersComboId].$element); + window.dnn.dnnFileUpload.updateExpandPath(folderPicker, settings.foldersComboId); + + dnn[settings.filesComboId].refresh(dnn[settings.foldersComboId].selectedItem().key); + dnn[settings.filesComboId].selectedItem({ key: data.fileId.toString(), value: data.fileName }); + window.dnn.dnnFileUpload.Files_Changed(dnn[settings.filesComboId].selectedItem(), dnn[settings.filesComboId].$element); + } + }); + }); + + // set initial thumb image + setTimeout(function () { + dnn[settings.filesComboId].options.services.parameters.parentId = settings.selectedFolderId; + var filesCombo = dnn[settings.filesComboId]; + var selectedFileId = filesCombo.selectedItem() ? filesCombo.selectedItem().key : null; + var fileId = selectedFileId ? parseInt(selectedFileId) : 0; + if (fileId > 0) { + var maxWidth = 180, maxHeight = 150; + var profileImagePath = dnn.getVar("sf_siteRoot", "/") + 'DnnImageHandler.ashx?mode=securefile&fileId=' + fileId + '&MaxWidth=' + maxWidth + '&MaxHeight=' + maxHeight; + var img = new Image(); + + $(img).on('load', function () { + $('#' + settings.dropZoneId + ' img').remove(); + $(img).css({ 'max-width': maxWidth, 'max-height': maxHeight }).insertBefore($('#' + settings.dropZoneId + ' span')); + }); + img.src = profileImagePath; + } + }, 500); + }); + }; + + if (typeof window.dnn === 'undefined') window.dnn = {}; + window.dnn.dnnFileUpload = window.dnn.dnnFileUpload || {}; + window.dnn.dnnFileUpload.settings = {}; + window.dnn.dnnFileUpload.setSettings = function (scope, settings) { + window.dnn.dnnFileUpload.settings[scope] = settings; + }; + window.dnn.dnnFileUpload.getSettings = function (sender) { + var scope = sender.closest('.dnnFileUploadScope').attr('id'); + return window.dnn.dnnFileUpload.settings[scope]; + }; + window.dnn.dnnFileUpload.Folders_Changed = function (node, sender) { + var settings = window.dnn.dnnFileUpload.getSettings(sender); + if (!settings) return false; + + if (node) { + //get the selected folder path + var selectedPathArray = dnn[settings.foldersComboId].selectedPath(); + if (selectedPathArray.length === 0 && settings.folder) { + return settings.folder; + } + var selectedPath = ""; + if (selectedPathArray.length > 1) { + for (var i = 1, size = selectedPathArray.length; i < size; i++) { + selectedPath += selectedPathArray[i].name + "/"; + } + } + settings.folder = selectedPath; + + dnn[settings.filesComboId].refresh(node.key); + dnn[settings.filesComboId].selectedItem(null); + window.dnn.dnnFileUpload.Files_Changed({ key: null }, $('#' + settings.filesComboId)); + } + }; + window.dnn.dnnFileUpload.Files_Changed = function (node, sender) { + var settings = window.dnn.dnnFileUpload.getSettings(sender); + if (!settings) return; + + if (node) { + var fileId = node.key; + if (fileId) { + var maxWidth = 180, maxHeight = 150; + var profileImagePath = dnn.getVar("sf_siteRoot", "/") + 'DnnImageHandler.ashx?mode=securefile&fileId=' + fileId + '&MaxWidth=' + maxWidth + '&MaxHeight=' + maxHeight; + var img = new Image(); + + $(img).on('load', function () { + $('#' + settings.dropZoneId + ' img').remove(); + $(img).css({ 'max-width': maxWidth, 'max-height': maxHeight }).insertBefore($('#' + settings.dropZoneId + ' span')); + }); + img.src = profileImagePath; + } + else + $('#' + settings.dropZoneId + ' img').remove(); + } + }; + window.dnn.dnnFileUpload.updateExpandPath = function(dropDownList, targetId) { + //set expand path + var selectedPaths = dropDownList.selectedPath(); + var expandPath = ""; + if (selectedPaths.length == 0) { //which means the tree view hasn't opened. + expandPath = dnn.getVar(dropDownList.id() + '_expandPath'); + } + else if (selectedPaths.length > 1) { + for (var i = 0; i < selectedPaths.length - 1; i++) { + if (expandPath == "") { + expandPath = selectedPaths[i].id; + } else { + expandPath = expandPath + "," + selectedPaths[i].id; + } + } + } + + if (expandPath != "") { + dnn.setVar(targetId + '_expandPath', expandPath); + } + }; + window.dnn.dnnFileUpload.getSelectedPath = function(dropDownList) { + var selectedPathArray = dropDownList.selectedPath(); + var settings = window.dnn.dnnFileUpload.getSettings(dropDownList.$element); + if (selectedPathArray.length === 0 && settings.folder) { + return settings.folder; + } + var selectedPath = ""; + if (selectedPathArray.length > 1) { + for (var i = 1, size = selectedPathArray.length; i < size; i++) { + selectedPath += selectedPathArray[i].name + "/"; + } + } + return selectedPath; + }; +})(jQuery); + +(function ($) { + /* BELOW jscrollPane code */ + $.fn.jScrollPane = function (settings) { + // JScrollPane "class" - public methods are available through $('selector').data('jsp') + function JScrollPane(elem, s) { + var settings, jsp = this, pane, paneWidth, paneHeight, container, contentWidth, contentHeight, + percentInViewH, percentInViewV, isScrollableV, isScrollableH, verticalDrag, dragMaxY, + verticalDragPosition, horizontalDrag, dragMaxX, horizontalDragPosition, + verticalBar, verticalTrack, scrollbarWidth, verticalTrackHeight, verticalDragHeight, arrowUp, arrowDown, + horizontalBar, horizontalTrack, horizontalTrackWidth, horizontalDragWidth, arrowLeft, arrowRight, + reinitialiseInterval, originalPadding, originalPaddingTotalWidth, previousContentWidth, + wasAtTop = true, wasAtLeft = true, wasAtBottom = false, wasAtRight = false, + originalElement = elem.clone(false, false).empty(), + mwEvent = $.fn.mwheelIntent ? 'mwheelIntent.jsp' : 'mousewheel.jsp'; + + originalPadding = elem.css('paddingTop') + ' ' + + elem.css('paddingRight') + ' ' + + elem.css('paddingBottom') + ' ' + + elem.css('paddingLeft'); + originalPaddingTotalWidth = (parseInt(elem.css('paddingLeft'), 10) || 0) + + (parseInt(elem.css('paddingRight'), 10) || 0); + + function initialise(s) { + + var /*firstChild, lastChild, */isMaintainingPositon, lastContentX, lastContentY, + hasContainingSpaceChanged, originalScrollTop, originalScrollLeft, + maintainAtBottom = false, maintainAtRight = false; + + settings = s; + + if (pane === undefined) { + originalScrollTop = elem.scrollTop(); + originalScrollLeft = elem.scrollLeft(); + + elem.css( + { + overflow: 'hidden', + padding: 0 + } + ); + // TODO: Deal with where width/ height is 0 as it probably means the element is hidden and we should + // come back to it later and check once it is unhidden... + paneWidth = elem.innerWidth() + originalPaddingTotalWidth; + paneHeight = elem.innerHeight(); + + elem.width(paneWidth); + + pane = $('').css('padding', originalPadding).append(elem.children()); + container = $('') + .css({ + 'width': paneWidth + 'px', + 'height': paneHeight + 'px' + } + ).append(pane).appendTo(elem); + + /* + // Move any margins from the first and last children up to the container so they can still + // collapse with neighbouring elements as they would before jScrollPane + firstChild = pane.find(':first-child'); + lastChild = pane.find(':last-child'); + elem.css( + { + 'margin-top': firstChild.css('margin-top'), + 'margin-bottom': lastChild.css('margin-bottom') + } + ); + firstChild.css('margin-top', 0); + lastChild.css('margin-bottom', 0); + */ + } else { + elem.css('width', ''); + + maintainAtBottom = settings.stickToBottom && isCloseToBottom(); + maintainAtRight = settings.stickToRight && isCloseToRight(); + + hasContainingSpaceChanged = elem.innerWidth() + originalPaddingTotalWidth != paneWidth || elem.outerHeight() != paneHeight; + + if (hasContainingSpaceChanged) { + paneWidth = elem.innerWidth() + originalPaddingTotalWidth; + paneHeight = elem.innerHeight(); + container.css({ + width: paneWidth + 'px', + height: paneHeight + 'px' + }); + } + + // If nothing changed since last check... + if (!hasContainingSpaceChanged && previousContentWidth == contentWidth && pane.outerHeight() == contentHeight) { + elem.width(paneWidth); + return; + } + previousContentWidth = contentWidth; + + pane.css('width', ''); + elem.width(paneWidth); + + container.find('>.jspVerticalBar,>.jspHorizontalBar').remove().end(); + } + + pane.css('overflow', 'auto'); + if (s.contentWidth) { + contentWidth = s.contentWidth; + } else { + contentWidth = pane[0].scrollWidth; + } + contentHeight = pane[0].scrollHeight; + pane.css('overflow', ''); + + percentInViewH = contentWidth / paneWidth; + percentInViewV = contentHeight / paneHeight; + isScrollableV = percentInViewV > 1; + + isScrollableH = percentInViewH > 1; + + if (!(isScrollableH || isScrollableV)) { + elem.removeClass('jspScrollable'); + pane.css({ + top: 0, + width: container.width() - originalPaddingTotalWidth + }); + removeMousewheel(); + removeFocusHandler(); + removeKeyboardNav(); + removeClickOnTrack(); + } else { + elem.addClass('jspScrollable'); + + isMaintainingPositon = settings.maintainPosition && (verticalDragPosition || horizontalDragPosition); + if (isMaintainingPositon) { + lastContentX = contentPositionX(); + lastContentY = contentPositionY(); + } + + initialiseVerticalScroll(); + initialiseHorizontalScroll(); + resizeScrollbars(); + + if (isMaintainingPositon) { + scrollToX(maintainAtRight ? (contentWidth - paneWidth) : lastContentX, false); + scrollToY(maintainAtBottom ? (contentHeight - paneHeight) : lastContentY, false); + } + + initFocusHandler(); + initMousewheel(); + initTouch(); + + if (settings.enableKeyboardNavigation) { + initKeyboardNav(); + } + if (settings.clickOnTrack) { + initClickOnTrack(); + } + + observeHash(); + if (settings.hijackInternalLinks) { + hijackInternalLinks(); + } + } + + if (settings.autoReinitialise && !reinitialiseInterval) { + reinitialiseInterval = setInterval( + function () { + initialise(settings); + }, + settings.autoReinitialiseDelay + ); + } else if (!settings.autoReinitialise && reinitialiseInterval) { + clearInterval(reinitialiseInterval); + } + + originalScrollTop && elem.scrollTop(0) && scrollToY(originalScrollTop, false); + originalScrollLeft && elem.scrollLeft(0) && scrollToX(originalScrollLeft, false); + + elem.trigger('jsp-initialised', [isScrollableH || isScrollableV]); + } + + function initialiseVerticalScroll() { + if (isScrollableV) { + + container.append( + $('').append( + $(''), + $('').append( + $('').append( + $(''), + $('') + ) + ), + $('') + ) + ); + + verticalBar = container.find('>.jspVerticalBar'); + verticalTrack = verticalBar.find('>.jspTrack'); + verticalDrag = verticalTrack.find('>.jspDrag'); + + if (settings.showArrows) { + arrowUp = $('').on( + 'mousedown.jsp', getArrowScroll(0, -1) + ).on('click.jsp', nil); + arrowDown = $('').on( + 'mousedown.jsp', getArrowScroll(0, 1) + ).on('click.jsp', nil); + if (settings.arrowScrollOnHover) { + arrowUp.on('mouseover.jsp', getArrowScroll(0, -1, arrowUp)); + arrowDown.on('mouseover.jsp', getArrowScroll(0, 1, arrowDown)); + } + + appendArrows(verticalTrack, settings.verticalArrowPositions, arrowUp, arrowDown); + } + + verticalTrackHeight = paneHeight; + container.find('>.jspVerticalBar>.jspCap:visible,>.jspVerticalBar>.jspArrow').each( + function () { + verticalTrackHeight -= $(this).outerHeight(); + } + ); + + + verticalDrag.hover( + function () { + verticalDrag.addClass('jspHover'); + }, + function () { + verticalDrag.removeClass('jspHover'); + } + ).on( + 'mousedown.jsp', + function (e) { + // Stop IE from allowing text selection + $('html').on('dragstart.jsp selectstart.jsp', nil); + + verticalDrag.addClass('jspActive'); + + var startY = e.pageY - verticalDrag.position().top; + + $('html').on( + 'mousemove.jsp', + function (e) { + positionDragY(e.pageY - startY, false); + } + ).on('mouseup.jsp mouseleave.jsp', cancelDrag); + return false; + } + ); + sizeVerticalScrollbar(); + } + } + + function sizeVerticalScrollbar() { + verticalTrack.height(verticalTrackHeight + 'px'); + verticalDragPosition = 0; + scrollbarWidth = settings.verticalGutter + verticalTrack.outerWidth(); + + // Make the pane thinner to allow for the vertical scrollbar + pane.width(paneWidth - scrollbarWidth - originalPaddingTotalWidth); + + // Add margin to the left of the pane if scrollbars are on that side (to position + // the scrollbar on the left or right set it's left or right property in CSS) + try { + if (verticalBar.position().left === 0) { + pane.css('margin-left', scrollbarWidth + 'px'); + } + } catch (err) { + } + } + + function initialiseHorizontalScroll() { + if (isScrollableH) { + + container.append( + $('').append( + $(''), + $('').append( + $('').append( + $(''), + $('') + ) + ), + $('') + ) + ); + + horizontalBar = container.find('>.jspHorizontalBar'); + horizontalTrack = horizontalBar.find('>.jspTrack'); + horizontalDrag = horizontalTrack.find('>.jspDrag'); + + if (settings.showArrows) { + arrowLeft = $('').on( + 'mousedown.jsp', getArrowScroll(-1, 0) + ).on('click.jsp', nil); + arrowRight = $('').on( + 'mousedown.jsp', getArrowScroll(1, 0) + ).on('click.jsp', nil); + if (settings.arrowScrollOnHover) { + arrowLeft.on('mouseover.jsp', getArrowScroll(-1, 0, arrowLeft)); + arrowRight.on('mouseover.jsp', getArrowScroll(1, 0, arrowRight)); + } + appendArrows(horizontalTrack, settings.horizontalArrowPositions, arrowLeft, arrowRight); + } + + horizontalDrag.hover( + function () { + horizontalDrag.addClass('jspHover'); + }, + function () { + horizontalDrag.removeClass('jspHover'); + } + ).on( + 'mousedown.jsp', + function (e) { + // Stop IE from allowing text selection + $('html').on('dragstart.jsp selectstart.jsp', nil); + + horizontalDrag.addClass('jspActive'); + + var startX = e.pageX - horizontalDrag.position().left; + + $('html').on( + 'mousemove.jsp', + function (e) { + positionDragX(e.pageX - startX, false); + } + ).on('mouseup.jsp mouseleave.jsp', cancelDrag); + return false; + } + ); + horizontalTrackWidth = container.innerWidth(); + sizeHorizontalScrollbar(); + } + } + + function sizeHorizontalScrollbar() { + container.find('>.jspHorizontalBar>.jspCap:visible,>.jspHorizontalBar>.jspArrow').each( + function () { + horizontalTrackWidth -= $(this).outerWidth(); + } + ); + + horizontalTrack.width(horizontalTrackWidth + 'px'); + horizontalDragPosition = 0; + } + + function resizeScrollbars() { + if (isScrollableH && isScrollableV) { + var horizontalTrackHeight = horizontalTrack.outerHeight(), + verticalTrackWidth = verticalTrack.outerWidth(); + verticalTrackHeight -= horizontalTrackHeight; + $(horizontalBar).find('>.jspCap:visible,>.jspArrow').each( + function () { + horizontalTrackWidth += $(this).outerWidth(); + } + ); + horizontalTrackWidth -= verticalTrackWidth; + paneHeight -= verticalTrackWidth; + paneWidth -= horizontalTrackHeight; + horizontalTrack.parent().append( + $('').css('width', horizontalTrackHeight + 'px') + ); + sizeVerticalScrollbar(); + sizeHorizontalScrollbar(); + } + // reflow content + if (isScrollableH) { + pane.width((container.outerWidth() - originalPaddingTotalWidth) + 'px'); + } + contentHeight = pane.outerHeight(); + percentInViewV = contentHeight / paneHeight; + + if (isScrollableH) { + horizontalDragWidth = Math.ceil(1 / percentInViewH * horizontalTrackWidth); + if (horizontalDragWidth > settings.horizontalDragMaxWidth) { + horizontalDragWidth = settings.horizontalDragMaxWidth; + } else if (horizontalDragWidth < settings.horizontalDragMinWidth) { + horizontalDragWidth = settings.horizontalDragMinWidth; + } + horizontalDrag.width(horizontalDragWidth + 'px'); + dragMaxX = horizontalTrackWidth - horizontalDragWidth; + _positionDragX(horizontalDragPosition); // To update the state for the arrow buttons + } + if (isScrollableV) { + verticalDragHeight = Math.ceil(1 / percentInViewV * verticalTrackHeight); + if (verticalDragHeight > settings.verticalDragMaxHeight) { + verticalDragHeight = settings.verticalDragMaxHeight; + } else if (verticalDragHeight < settings.verticalDragMinHeight) { + verticalDragHeight = settings.verticalDragMinHeight; + } + verticalDrag.height(verticalDragHeight + 'px'); + dragMaxY = verticalTrackHeight - verticalDragHeight; + _positionDragY(verticalDragPosition); // To update the state for the arrow buttons + } + } + + function appendArrows(ele, p, a1, a2) { + var p1 = "before", p2 = "after", aTemp; + + // Sniff for mac... Is there a better way to determine whether the arrows would naturally appear + // at the top or the bottom of the bar? + if (p == "os") { + p = /Mac/.test(navigator.platform) ? "after" : "split"; + } + if (p == p1) { + p2 = p; + } else if (p == p2) { + p1 = p; + aTemp = a1; + a1 = a2; + a2 = aTemp; + } + + ele[p1](a1)[p2](a2); + } + + function getArrowScroll(dirX, dirY, ele) { + return function () { + arrowScroll(dirX, dirY, this, ele); + this.blur(); + return false; + }; + } + + function arrowScroll(dirX, dirY, arrow, ele) { + arrow = $(arrow).addClass('jspActive'); + + var eve, + scrollTimeout, + isFirst = true, + doScroll = function () { + if (dirX !== 0) { + jsp.scrollByX(dirX * settings.arrowButtonSpeed); + } + if (dirY !== 0) { + jsp.scrollByY(dirY * settings.arrowButtonSpeed); + } + scrollTimeout = setTimeout(doScroll, isFirst ? settings.initialDelay : settings.arrowRepeatFreq); + isFirst = false; + }; + + doScroll(); + + eve = ele ? 'mouseout.jsp' : 'mouseup.jsp'; + ele = ele || $('html'); + ele.on( + eve, + function () { + arrow.removeClass('jspActive'); + scrollTimeout && clearTimeout(scrollTimeout); + scrollTimeout = null; + ele.off(eve); + } + ); + } + + function initClickOnTrack() { + removeClickOnTrack(); + if (isScrollableV) { + verticalTrack.on( + 'mousedown.jsp', + function (e) { + if (e.originalTarget === undefined || e.originalTarget == e.currentTarget) { + var clickedTrack = $(this), + offset = clickedTrack.offset(), + direction = e.pageY - offset.top - verticalDragPosition, + scrollTimeout, + isFirst = true, + doScroll = function () { + var offset = clickedTrack.offset(), + pos = e.pageY - offset.top - verticalDragHeight / 2, + contentDragY = paneHeight * settings.scrollPagePercent, + dragY = dragMaxY * contentDragY / (contentHeight - paneHeight); + if (direction < 0) { + if (verticalDragPosition - dragY > pos) { + jsp.scrollByY(-contentDragY); + } else { + positionDragY(pos); + } + } else if (direction > 0) { + if (verticalDragPosition + dragY < pos) { + jsp.scrollByY(contentDragY); + } else { + positionDragY(pos); + } + } else { + cancelClick(); + return; + } + scrollTimeout = setTimeout(doScroll, isFirst ? settings.initialDelay : settings.trackClickRepeatFreq); + isFirst = false; + }, + cancelClick = function () { + scrollTimeout && clearTimeout(scrollTimeout); + scrollTimeout = null; + $(document).off('mouseup.jsp', cancelClick); + }; + doScroll(); + $(document).on('mouseup.jsp', cancelClick); + return false; + } + } + ); + } + + if (isScrollableH) { + horizontalTrack.on( + 'mousedown.jsp', + function (e) { + if (e.originalTarget === undefined || e.originalTarget == e.currentTarget) { + var clickedTrack = $(this), + offset = clickedTrack.offset(), + direction = e.pageX - offset.left - horizontalDragPosition, + scrollTimeout, + isFirst = true, + doScroll = function () { + var offset = clickedTrack.offset(), + pos = e.pageX - offset.left - horizontalDragWidth / 2, + contentDragX = paneWidth * settings.scrollPagePercent, + dragX = dragMaxX * contentDragX / (contentWidth - paneWidth); + if (direction < 0) { + if (horizontalDragPosition - dragX > pos) { + jsp.scrollByX(-contentDragX); + } else { + positionDragX(pos); + } + } else if (direction > 0) { + if (horizontalDragPosition + dragX < pos) { + jsp.scrollByX(contentDragX); + } else { + positionDragX(pos); + } + } else { + cancelClick(); + return; + } + scrollTimeout = setTimeout(doScroll, isFirst ? settings.initialDelay : settings.trackClickRepeatFreq); + isFirst = false; + }, + cancelClick = function () { + scrollTimeout && clearTimeout(scrollTimeout); + scrollTimeout = null; + $(document).off('mouseup.jsp', cancelClick); + }; + doScroll(); + $(document).on('mouseup.jsp', cancelClick); + return false; + } + } + ); + } + } + + function removeClickOnTrack() { + if (horizontalTrack) { + horizontalTrack.off('mousedown.jsp'); + } + if (verticalTrack) { + verticalTrack.off('mousedown.jsp'); + } + } + + function cancelDrag() { + $('html').off('dragstart.jsp selectstart.jsp mousemove.jsp mouseup.jsp mouseleave.jsp'); + + if (verticalDrag) { + verticalDrag.removeClass('jspActive'); + } + if (horizontalDrag) { + horizontalDrag.removeClass('jspActive'); + } + } + + function positionDragY(destY, animate) { + if (!isScrollableV) { + return; + } + if (destY < 0) { + destY = 0; + } else if (destY > dragMaxY) { + destY = dragMaxY; + } + + // can't just check if(animate) because false is a valid value that could be passed in... + if (animate === undefined) { + animate = settings.animateScroll; + } + if (animate) { + jsp.animate(verticalDrag, 'top', destY, _positionDragY); + } else { + verticalDrag.css('top', destY); + _positionDragY(destY); + } + + } + + function _positionDragY(destY) { + if (destY === undefined) { + destY = verticalDrag.position().top; + } + + container.scrollTop(0); + verticalDragPosition = destY; + + var isAtTop = verticalDragPosition === 0, + isAtBottom = verticalDragPosition == dragMaxY, + percentScrolled = destY / dragMaxY, + destTop = -percentScrolled * (contentHeight - paneHeight); + + if (wasAtTop != isAtTop || wasAtBottom != isAtBottom) { + wasAtTop = isAtTop; + wasAtBottom = isAtBottom; + elem.trigger('jsp-arrow-change', [wasAtTop, wasAtBottom, wasAtLeft, wasAtRight]); + } + + updateVerticalArrows(isAtTop, isAtBottom); + pane.css('top', destTop); + elem.trigger('jsp-scroll-y', [-destTop, isAtTop, isAtBottom]).trigger('scroll'); + } + + function positionDragX(destX, animate) { + if (!isScrollableH) { + return; + } + if (destX < 0) { + destX = 0; + } else if (destX > dragMaxX) { + destX = dragMaxX; + } + + if (animate === undefined) { + animate = settings.animateScroll; + } + if (animate) { + jsp.animate(horizontalDrag, 'left', destX, _positionDragX); + } else { + horizontalDrag.css('left', destX); + _positionDragX(destX); + } + } + + function _positionDragX(destX) { + if (destX === undefined) { + destX = horizontalDrag.position().left; + } + + container.scrollTop(0); + horizontalDragPosition = destX; + + var isAtLeft = horizontalDragPosition === 0, + isAtRight = horizontalDragPosition == dragMaxX, + percentScrolled = destX / dragMaxX, + destLeft = -percentScrolled * (contentWidth - paneWidth); + + if (wasAtLeft != isAtLeft || wasAtRight != isAtRight) { + wasAtLeft = isAtLeft; + wasAtRight = isAtRight; + elem.trigger('jsp-arrow-change', [wasAtTop, wasAtBottom, wasAtLeft, wasAtRight]); + } + + updateHorizontalArrows(isAtLeft, isAtRight); + pane.css('left', destLeft); + elem.trigger('jsp-scroll-x', [-destLeft, isAtLeft, isAtRight]).trigger('scroll'); + } + + function updateVerticalArrows(isAtTop, isAtBottom) { + if (settings.showArrows) { + arrowUp[isAtTop ? 'addClass' : 'removeClass']('jspDisabled'); + arrowDown[isAtBottom ? 'addClass' : 'removeClass']('jspDisabled'); + } + } + + function updateHorizontalArrows(isAtLeft, isAtRight) { + if (settings.showArrows) { + arrowLeft[isAtLeft ? 'addClass' : 'removeClass']('jspDisabled'); + arrowRight[isAtRight ? 'addClass' : 'removeClass']('jspDisabled'); + } + } + + function scrollToY(destY, animate) { + var percentScrolled = destY / (contentHeight - paneHeight); + positionDragY(percentScrolled * dragMaxY, animate); + } + + function scrollToX(destX, animate) { + var percentScrolled = destX / (contentWidth - paneWidth); + positionDragX(percentScrolled * dragMaxX, animate); + } + + function scrollToElement(ele, stickToTop, animate) { + var e, eleHeight, eleWidth, eleTop = 0, eleLeft = 0, viewportTop, viewportLeft, maxVisibleEleTop, maxVisibleEleLeft, destY, destX; + + // Legal hash values aren't necessarily legal jQuery selectors so we need to catch any + // errors from the lookup... + try { + e = $(ele); + } catch (err) { + return; + } + eleHeight = e.outerHeight(); + eleWidth = e.outerWidth(); + + container.scrollTop(0); + container.scrollLeft(0); + + // loop through parents adding the offset top of any elements that are relatively positioned between + // the focused element and the jspPane so we can get the true distance from the top + // of the focused element to the top of the scrollpane... + while (!e.is('.jspPane')) { + eleTop += e.position().top; + eleLeft += e.position().left; + e = e.offsetParent(); + if (/^body|html$/i.test(e[0].nodeName)) { + // we ended up too high in the document structure. Quit! + return; + } + } + + viewportTop = contentPositionY(); + maxVisibleEleTop = viewportTop + paneHeight; + if (eleTop < viewportTop || stickToTop) { // element is above viewport + destY = eleTop - settings.verticalGutter; + } else if (eleTop + eleHeight > maxVisibleEleTop) { // element is below viewport + destY = eleTop - paneHeight + eleHeight + settings.verticalGutter; + } + if (destY) { + scrollToY(destY, animate); + } + + viewportLeft = contentPositionX(); + maxVisibleEleLeft = viewportLeft + paneWidth; + if (eleLeft < viewportLeft || stickToTop) { // element is to the left of viewport + destX = eleLeft - settings.horizontalGutter; + } else if (eleLeft + eleWidth > maxVisibleEleLeft) { // element is to the right viewport + destX = eleLeft - paneWidth + eleWidth + settings.horizontalGutter; + } + if (destX) { + scrollToX(destX, animate); + } + + } + + function contentPositionX() { + return -pane.position().left; + } + + function contentPositionY() { + return -pane.position().top; + } + + function isCloseToBottom() { + var scrollableHeight = contentHeight - paneHeight; + return (scrollableHeight > 20) && (scrollableHeight - contentPositionY() < 10); + } + + function isCloseToRight() { + var scrollableWidth = contentWidth - paneWidth; + return (scrollableWidth > 20) && (scrollableWidth - contentPositionX() < 10); + } + + function initMousewheel() { + container.off(mwEvent).on( + mwEvent, + function (event, delta, deltaX, deltaY) { + var dX = horizontalDragPosition, dY = verticalDragPosition; + jsp.scrollBy(deltaX * settings.mouseWheelSpeed, -deltaY * settings.mouseWheelSpeed, false); + // return true if there was no movement so rest of screen can scroll + return dX == horizontalDragPosition && dY == verticalDragPosition; + } + ); + } + + function removeMousewheel() { + container.off(mwEvent); + } + + function nil() { + return false; + } + + function initFocusHandler() { + pane.find(':input,a').off('focus.jsp').on( + 'focus.jsp', + function (e) { + scrollToElement(e.target, false); + } + ); + } + + function removeFocusHandler() { + pane.find(':input,a').off('focus.jsp'); + } + + function initKeyboardNav() { + var keyDown, elementHasScrolled, validParents = []; + isScrollableH && validParents.push(horizontalBar[0]); + isScrollableV && validParents.push(verticalBar[0]); + + // IE also focuses elements that don't have tabindex set. + pane.focus( + function () { + elem.focus(); + } + ); + + elem.attr('tabindex', 0) + .off('keydown.jsp keypress.jsp') + .on( + 'keydown.jsp', + function (e) { + if (e.target !== this && !(validParents.length && $(e.target).closest(validParents).length)) { + return; + } + var dX = horizontalDragPosition, dY = verticalDragPosition; + switch (e.keyCode) { + case 40: // down + case 38: // up + case 34: // page down + case 32: // space + case 33: // page up + case 39: // right + case 37: // left + keyDown = e.keyCode; + keyDownHandler(); + break; + case 35: // end + scrollToY(contentHeight - paneHeight); + keyDown = null; + break; + case 36: // home + scrollToY(0); + keyDown = null; + break; + } + + elementHasScrolled = e.keyCode == keyDown && dX != horizontalDragPosition || dY != verticalDragPosition; + return !elementHasScrolled; + } + ).off( + 'keypress.jsp', // For FF/ OSX so that we can cancel the repeat key presses if the JSP scrolls... + function (e) { + if (e.keyCode == keyDown) { + keyDownHandler(); + } + return !elementHasScrolled; + } + ); + + if (settings.hideFocus) { + elem.css('outline', 'none'); + if ('hideFocus' in container[0]) { + elem.attr('hideFocus', true); + } + } else { + elem.css('outline', ''); + if ('hideFocus' in container[0]) { + elem.attr('hideFocus', false); + } + } + + function keyDownHandler() { + var dX = horizontalDragPosition, dY = verticalDragPosition; + switch (keyDown) { + case 40: // down + jsp.scrollByY(settings.keyboardSpeed, false); + break; + case 38: // up + jsp.scrollByY(-settings.keyboardSpeed, false); + break; + case 34: // page down + case 32: // space + jsp.scrollByY(paneHeight * settings.scrollPagePercent, false); + break; + case 33: // page up + jsp.scrollByY(-paneHeight * settings.scrollPagePercent, false); + break; + case 39: // right + jsp.scrollByX(settings.keyboardSpeed, false); + break; + case 37: // left + jsp.scrollByX(-settings.keyboardSpeed, false); + break; + } + + elementHasScrolled = dX != horizontalDragPosition || dY != verticalDragPosition; + return elementHasScrolled; + } + } + + function removeKeyboardNav() { + elem.attr('tabindex', '-1') + .removeAttr('tabindex') + .off('keydown.jsp keypress.jsp'); + } + + function observeHash() { + if (location.hash && location.hash.length > 1) { + var e, + retryInt, + hash = escape(location.hash.substr(1)) // hash must be escaped to prevent XSS + ; + try { + e = $('#' + hash + ', a[name="' + hash + '"]'); + } catch (err) { + return; + } + + if (e.length && pane.find(hash)) { + // nasty workaround but it appears to take a little while before the hash has done its thing + // to the rendered page so we just wait until the container's scrollTop has been messed up. + if (container.scrollTop() === 0) { + retryInt = setInterval( + function () { + if (container.scrollTop() > 0) { + scrollToElement(e, true); + $(document).scrollTop(container.position().top); + clearInterval(retryInt); + } + }, + 50 + ); + } else { + scrollToElement(e, true); + $(document).scrollTop(container.position().top); + } + } + } + } + + function hijackInternalLinks() { + // only register the link handler once + if ($(document.body).data('jspHijack')) { + return; + } + + // remember that the handler was bound + $(document.body).data('jspHijack', true); + + // use live handler to also capture newly created links + $(document.body).delegate('a[href*=#]', 'click', function (event) { + // does the link point to the same page? + // this also takes care of cases with a
@@ -20,117 +21,99 @@ namespace DotNetNuke.Entities.Controllers
///
///