513 lines
20 KiB
513 lines
20 KiB
!(function () { |
|
var scale = 1, transformY = 0, selected = true, globalScaleRatio = parseFloat(BI.Cache.getItem('scaleRatio')) || null; |
|
var html = document.getElementsByTagName('html')[0]; |
|
var wrapper = document.getElementById("wrapper"); |
|
var fixedWrapper = document.createElement("div"); |
|
var fixedContainer = document.createElement('div'); |
|
fixedContainer.style.position = "absolute"; |
|
fixedContainer.style.top = "0"; |
|
fixedContainer.style.left = "0"; |
|
fixedContainer.style.width = "100%"; |
|
|
|
document.body.appendChild(fixedWrapper); |
|
fixedWrapper.appendChild(wrapper); |
|
wrapper.appendChild(fixedContainer); |
|
|
|
var jQuery = $ || window.jQuery; |
|
var injectOffset = jQuery.fn.offset; |
|
var injectEventFix = jQuery.event.fix; |
|
var injectMouseInBounds = jQuery.fn.__isMouseInBounds__; |
|
var injectToolTipShow = null; |
|
var injectBubblesShow = null; |
|
var adjustHeight = BI.Combo.prototype.adjustHeight; |
|
var originalRender = BI.Widget._renderEngine; |
|
var injectSearch = BI.Searcher.prototype._assertPopupView; |
|
|
|
var injectCreate = BI.createWidget; |
|
|
|
// 修正事件偏移 |
|
function correctEvent(e) { |
|
if (e && !e.corrected) { |
|
e.pageX = e.pageX / scale; |
|
e.pageY = (e.pageY - transformY) / scale; |
|
e.clientX = e.clientX / scale; |
|
e.clientY = (e.clientY - transformY) / scale; |
|
e.corrected = true; |
|
} |
|
return e; |
|
} |
|
|
|
function checkInPopupView(el) { |
|
var t = el.parentElement; |
|
var flag = false; |
|
do { |
|
if (t.className && t.className.indexOf("bi-popup-view") !== -1) { |
|
flag = true; |
|
break; |
|
} |
|
t = t.parentElement |
|
} while (t); |
|
|
|
return flag; |
|
} |
|
|
|
// 进行缩放 |
|
function transformScale(ratio) { |
|
var bounds = getScaleBounds(ratio); |
|
scale = bounds.scale; |
|
|
|
wrapper.style.width = bounds.width + "px"; |
|
wrapper.style.height = bounds.height + "px"; |
|
wrapper.style.transform = "scale(" + bounds.scale+ ")"; |
|
wrapper.style.transformOrigin = "top left"; |
|
wrapper.style["-ms-transform"] = "scale(" + bounds.scale+ ")"; |
|
wrapper.style["-ms-transform-origin"] = "top left"; |
|
fixedContainer.style.height = (document.body.clientHeight / scale) + "px"; |
|
wrapper.style.overflowY = "auto"; |
|
html.style.backgroundColor = "#ffffff"; |
|
|
|
document.body.style.overflowX = globalScaleRatio ? "auto" : "hidden"; |
|
document.body.style.overflowY = "auto"; |
|
fixedWrapper.style.overflow = "hidden"; |
|
fixedWrapper.style.width = bounds.width * scale + "px"; |
|
fixedWrapper.style.height = bounds.height * scale + "px"; |
|
|
|
window.scale = Math.max(window.devicePixelRatio * scale, 1); |
|
} |
|
|
|
// 取消缩放 |
|
function removeScale() { |
|
wrapper.style.width = "100%"; |
|
wrapper.style.height = "100%"; |
|
wrapper.style.transform = ""; |
|
wrapper.style.transformOrigin = ""; |
|
wrapper.style["-ms-transform"] = ""; |
|
wrapper.style["-ms-transform-origin"] = ""; |
|
wrapper.style.overflowY = "hidden"; |
|
wrapper.style.top = ""; |
|
fixedContainer.style.height = "0px"; |
|
html.style.backgroundColor = "#ffffff"; |
|
|
|
document.body.style.overflow = "hidden"; |
|
document.body.style.width = "100%"; |
|
document.body.style.height = "100%"; |
|
fixedWrapper.style.overflow = "hidden"; |
|
fixedWrapper.style.width = "100%"; |
|
fixedWrapper.style.height = "100%"; |
|
|
|
scale = 1; |
|
window.scale = window.devicePixelRatio; |
|
} |
|
|
|
// 获取缩放倍数,原模板宽高 |
|
function getScaleBounds(ratio) { |
|
var widgets = BI.designConfigure.widgets, |
|
layoutRatio = BI.designConfigure.layoutRatio, |
|
freeLayoutRatio = BI.designConfigure.freeLayoutRatio, |
|
freeWidgets = BI.designConfigure.freeWidgetIds; |
|
|
|
if (Object.keys(widgets).length === 0) { |
|
return { |
|
scale: 1, |
|
width: html.clientWidth, |
|
height: html.clientHeight |
|
} |
|
} |
|
var left = null, right = null, top = null, bottom = null, |
|
freeLeft = null, freeRight = null, freeTop = null, freeBottom = null; |
|
BI.each(widgets, function (wId, widget) { |
|
var bounds = widget.bounds || {}; |
|
if (BI.contains(freeWidgets, wId)) { |
|
freeLeft = BI.isNull(freeLeft) ? bounds.left : Math.min(freeLeft, bounds.left); |
|
freeRight = Math.max(freeRight, bounds.left + bounds.width); |
|
freeTop = BI.isNull(freeTop) ? bounds.top : Math.min(freeTop, bounds.top); |
|
freeBottom = Math.max(freeBottom, bounds.top + bounds.height); |
|
} else { |
|
left = BI.isNull(left) ? bounds.left : Math.min(left, bounds.left); |
|
right = Math.max(right, bounds.left + bounds.width); |
|
top = BI.isNull(top) ? bounds.top : Math.min(top, bounds.top); |
|
bottom = Math.max(bottom, bounds.top + bounds.height); |
|
} |
|
}); |
|
|
|
var templateWidth = (Math.round((right / (layoutRatio.x || 1)) || (freeRight / (freeLayoutRatio.x || 1)))) + 60; |
|
var templateHeight = (Math.round((bottom / (layoutRatio.y || 1)) || (freeBottom / (freeLayoutRatio.y || 1)))) + 30; |
|
var scaleRatio = parseFloat((html.clientWidth / templateWidth).toFixed(1)); |
|
|
|
var resultWidth = 0; |
|
var resultHeight = 0; |
|
var bHeight = 0; |
|
|
|
if (ratio) { |
|
scaleRatio = ratio; |
|
bHeight = html.clientHeight / scaleRatio; |
|
resultWidth = templateWidth; |
|
resultHeight = Math.max(bHeight, templateHeight); |
|
} else { |
|
bHeight = html.clientHeight / scaleRatio; |
|
resultWidth = html.clientWidth / scaleRatio; |
|
resultHeight = Math.max(bHeight, scaleRatio === 1 ? html.clientHeight : templateHeight); |
|
} |
|
|
|
|
|
return { |
|
scale: scaleRatio, |
|
width: resultWidth, |
|
height: resultHeight |
|
}; |
|
} |
|
|
|
// 准备环境,主要是纠正事件偏移 |
|
function prepareEnv() { |
|
// IE的fixed元素不受transform:scale影响 |
|
injectToolTipShow = injectToolTipShow || BI.Tooltips.show; |
|
injectBubblesShow = injectBubblesShow || BI.Bubbles.show; |
|
jQuery.fn.__isMouseInBounds__ = function (e) { |
|
var offset2Body = this.get(0).getBoundingClientRect ? this.get(0).getBoundingClientRect() : this.offset(); |
|
var width = offset2Body.width || this.outerWidth(); |
|
var height = offset2Body.height || this.outerHeight(); |
|
var pageX = e.clientX * scale, |
|
pageY = e.clientY * scale + transformY; |
|
return !(pageX < Math.floor(offset2Body.left) || pageX > offset2Body.left + width |
|
|| pageY < Math.floor(offset2Body.top) || pageY > offset2Body.top + height); |
|
}; |
|
jQuery.fn.offset = function( options ) { |
|
function getWindow( elem ) { |
|
return jQuery.isWindow( elem ) ? |
|
elem : |
|
elem.nodeType === 9 ? |
|
elem.defaultView || elem.parentWindow : |
|
false; |
|
} |
|
|
|
if ( arguments.length ) { |
|
return options === undefined ? |
|
this : |
|
this.each(function( i ) { |
|
jQuery.offset.setOffset( this, options, i ); |
|
}); |
|
} |
|
|
|
|
|
var docElem, win, |
|
box = { top: 0, left: 0 }, |
|
elem = this[ 0 ], |
|
doc = elem && elem.ownerDocument; |
|
|
|
if ( !doc ) { |
|
return; |
|
} |
|
|
|
docElem = doc.documentElement; |
|
|
|
// Make sure it's not a disconnected DOM node |
|
if ( !jQuery.contains( docElem, elem ) ) { |
|
return box; |
|
} |
|
|
|
var el = elem, |
|
offsetLeft = 0, |
|
offsetTop = 0; |
|
|
|
do{ |
|
offsetLeft += ( BI.isIE() ? window.getComputedStyle(el).position === "fixed" ? el.offsetLeft / scale : el.offsetLeft : el.offsetLeft ); |
|
offsetTop += ( BI.isIE() ? window.getComputedStyle(el).position === "fixed" ? el.offsetTop / scale : el.offsetTop : el.offsetTop ); |
|
el = el.offsetParent; |
|
} while( el ); |
|
|
|
var elm = elem; |
|
if (!checkInPopupView(elm)) { |
|
do{ |
|
if (elm === document.body) { |
|
break; |
|
} |
|
offsetLeft -= elm.scrollLeft || 0; |
|
offsetTop -= elm.scrollTop || 0; |
|
elm = elm.offsetParent; |
|
} while( elm ); |
|
} |
|
win = getWindow( doc ); |
|
return { |
|
top: offsetTop + ( win.pageYOffset || docElem.scrollTop ) - ( docElem.clientTop || 0 ), |
|
left: offsetLeft + ( win.pageXOffset || docElem.scrollLeft ) - ( docElem.clientLeft || 0 ) |
|
}; |
|
}; |
|
|
|
jQuery.event.fix = function ( e ) { |
|
return correctEvent(injectEventFix.call(this, e)); |
|
}; |
|
|
|
|
|
// Popovers |
|
BI.Popovers = new BI.PopoverController({render: fixedContainer}); |
|
if (BI.isIE()) { |
|
BI.Combo.prototype.adjustHeight = function (e) { |
|
adjustHeight.call(this, e); |
|
if (this.popupView) { |
|
if (!checkInPopupView(this.popupView.element[0])) { |
|
this.popupView.element[0].style.left = (parseInt(this.popupView.element[0].style.left) * scale - document.body.scrollLeft) + "px"; |
|
this.popupView.element[0].style.top = (parseInt(this.popupView.element[0].style.top) * scale + transformY - document.body.scrollTop) + "px"; |
|
} else { |
|
var cBounds = this.popupView.element[0].getBoundingClientRect(); |
|
var pBounds = this.popupView.element[0].parentElement.getBoundingClientRect(); |
|
if (cBounds.left + cBounds.width > body.clientWidth * scale) { |
|
this.popupView.element[0].style.top = (parseInt(pBounds.top) + transformY - document.body.scrollTop) + "px"; |
|
this.popupView.element[0].style.left = (parseInt(this.popupView.element[0].style.left) * scale) + "px"; |
|
} else if (this.options.direction === "right") { |
|
this.popupView.element[0].style.top = (parseInt(pBounds.top) + transformY - document.body.scrollTop) + "px"; |
|
this.popupView.element[0].style.left = (parseInt(pBounds.right) + transformY - document.body.scrollTop) + "px"; |
|
} else if (parseInt(cBounds.top) >= parseInt(pBounds.top) && parseInt(cBounds.left) >= parseInt(pBounds.left)) { |
|
this.popupView.element[0].style.top = (parseInt(pBounds.bottom) + transformY - document.body.scrollTop) + "px"; |
|
this.popupView.element[0].style.left = (parseInt(pBounds.left) + transformY - document.body.scrollTop) + "px"; |
|
}else if (parseInt(cBounds.top) >= parseInt(pBounds.top) && parseInt(cBounds.left) < parseInt(pBounds.left)) { |
|
this.popupView.element[0].style.top = (parseInt(pBounds.bottom) + transformY - document.body.scrollTop) + "px"; |
|
this.popupView.element[0].style.left = (parseInt(pBounds.left) + transformY - document.body.scrollTop) + "px"; |
|
} |
|
} |
|
this.popupView.element[0].style.transform = "scale(" + scale+ ")"; |
|
this.popupView.element[0].style.transformOrigin = "top left"; |
|
} |
|
}; |
|
BI.Tooltips.show = function (e, name, text, level, context, opt) { |
|
injectToolTipShow.call(this, e, name, text, level, context, opt); |
|
var tooltip = this.get(name); |
|
tooltip.element[0].style.left = parseInt(tooltip.element[0].style.left) * scale - document.body.scrollLeft + "px"; |
|
tooltip.element[0].style.top = parseInt(tooltip.element[0].style.top) * scale + transformY - document.body.scrollTop + "px"; |
|
tooltip.element[0].style.transform = "scale(" + scale+ ")"; |
|
tooltip.element[0].style.transformOrigin = "top left"; |
|
} |
|
BI.Bubbles.show = function (name, text, context, opt) { |
|
injectBubblesShow.call(this, name, text, context, opt); |
|
var tooltip = this.get(name); |
|
tooltip.element[0].style.left = parseInt(tooltip.element[0].style.left) * scale - document.body.scrollLeft + "px"; |
|
tooltip.element[0].style.top = parseInt(tooltip.element[0].style.top) * scale + transformY - document.body.scrollTop + "px"; |
|
tooltip.element[0].style.transform = "scale(" + scale+ ")"; |
|
tooltip.element[0].style.transformOrigin = "top left"; |
|
} |
|
|
|
var tempAdd = BI.Popovers.add; |
|
BI.Popovers.add = function (name, popover, options, context) { |
|
tempAdd.call(this, name, popover, options, context); |
|
if (this.floatContainer[name].options.cls && this.floatContainer[name].options.cls.includes("bi-popup-view")) { |
|
this.floatContainer[name].element[0].style.setProperty("position", "absolute", "important"); |
|
} |
|
} |
|
|
|
// Searcher |
|
BI.Searcher.prototype._assertPopupView = function () { |
|
injectSearch.call(this); |
|
var self = this; |
|
if (this.popupView) { |
|
BI.defer(function () { |
|
self.popupView.element[0].parentElement.style.left = parseInt(self.popupView.element[0].parentElement.style.left) * scale + "px"; |
|
self.popupView.element[0].parentElement.style.top = parseInt(self.popupView.element[0].parentElement.style.top) * scale + "px"; |
|
self.popupView.element[0].parentElement.style.transform = "scale(" + scale + ")"; |
|
self.popupView.element[0].parentElement.style.transformOrigin = "left top"; |
|
}) |
|
} |
|
} |
|
} |
|
|
|
BI.createWidget = function () { |
|
if (arguments[0] && arguments[0].element === "body") { |
|
arguments[0].element = fixedContainer; |
|
} |
|
return injectCreate.apply(this, arguments); |
|
}; |
|
|
|
BI.Widget.registerRenderEngine({ |
|
createElement: function (widget) { |
|
if (widget === "body") { |
|
return BI.$(wrapper); |
|
} |
|
return originalRender.createElement(widget); |
|
}, |
|
createFragment: function () { |
|
return originalRender.createFragment(); |
|
} |
|
}); |
|
|
|
window.addEventListener('resize', updateScale); |
|
window.matchMedia && window.matchMedia('screen and (min-resolution: 2dppx)'). |
|
addListener(selectHandler); |
|
} |
|
|
|
function restoreEnv() { |
|
jQuery.fn.__isMouseInBounds__ = injectMouseInBounds; |
|
jQuery.fn.offset = injectOffset; |
|
jQuery.event.fix = injectEventFix; |
|
if (BI.isIE()) { |
|
BI.Combo.prototype.adjustHeight = adjustHeight; |
|
BI.Tooltips.show = injectToolTipShow; |
|
BI.Bubbles.show = injectBubblesShow; |
|
} |
|
BI.createWidget = injectCreate; |
|
|
|
// Popovers |
|
BI.Popovers = new BI.PopoverController(); |
|
BI.Widget.registerRenderEngine(originalRender); |
|
|
|
BI.Searcher.prototype._assertPopupView = injectSearch; |
|
|
|
document.body.onmousedown = null; |
|
window.removeEventListener('resize', updateScale); |
|
window.matchMedia && window.matchMedia('screen and (min-resolution: 2dppx)'). |
|
removeListener(selectHandler); |
|
} |
|
|
|
var selectHandler = BI.debounce(function () { |
|
selected && prepareEnv(); |
|
selected ? transformScale(globalScaleRatio) : removeScale(); |
|
!selected && restoreEnv(); |
|
}, 30); |
|
|
|
function updateScale () { |
|
if (html.getBoundingClientRect().width !== wrapper.getBoundingClientRect().width) { |
|
selectHandler(); |
|
} |
|
} |
|
|
|
var injectCaptureMouseMoves = BI.MouseMoveTracker.prototype.captureMouseMoves; |
|
var injectOnMouseMove = BI.MouseMoveTracker.prototype._onMouseMove; |
|
// 用jQEvent代替MouseEvent |
|
function injectMouseMoveTracker() { |
|
BI.MouseMoveTracker.prototype.captureMouseMoves = function (e) { |
|
var jQEvent = e.originalEvent ? e : jQuery.event.fix(e); |
|
injectCaptureMouseMoves.call(this, correctEvent(jQEvent)); |
|
}; |
|
BI.MouseMoveTracker.prototype._onMouseMove = function (e) { |
|
var jQEvent = e.originalEvent ? e : jQuery.event.fix(e); |
|
injectOnMouseMove.call(this, correctEvent(jQEvent)); |
|
} |
|
} |
|
injectMouseMoveTracker(); |
|
|
|
selectHandler(); |
|
BI.config("bi.constant.dashboard.toolbar.left.items", function (config) { |
|
return BI.concat(config, [{ |
|
type: "bi.multi_select_item", |
|
text: BI.i18nText("BI-Plugin-Scale_Adaptive"), |
|
selected: true, |
|
listeners: [{ |
|
eventName: BI.MultiSelectItem.EVENT_CHANGE, |
|
action: function () { |
|
selected = this.isSelected(); |
|
selectHandler(); |
|
} |
|
}] |
|
}, { |
|
type: 'bi.text_value_combo', |
|
text: '自定义缩放比例', |
|
width: 120, |
|
value: globalScaleRatio, |
|
items: [ |
|
{ |
|
text: '自动', |
|
value: null, |
|
lgap: 10, |
|
}, |
|
{ |
|
text: '50%', |
|
value: 0.5, |
|
lgap: 10, |
|
}, |
|
{ |
|
text: '60%', |
|
value: 0.6, |
|
lgap: 10, |
|
}, |
|
{ |
|
text: '70%', |
|
value: 0.7, |
|
lgap: 10, |
|
}, |
|
{ |
|
lgap: 10, |
|
text: '80%', |
|
value: 0.8, |
|
lgap: 10, |
|
}, |
|
{ |
|
lgap: 10, |
|
text: '90%', |
|
value: 0.9, |
|
lgap: 10, |
|
}, |
|
{ |
|
lgap: 10, |
|
text: '100%', |
|
value: 1.0, |
|
lgap: 10, |
|
}, |
|
{ |
|
lgap: 10, |
|
text: '110%', |
|
value: 1.1, |
|
lgap: 10, |
|
}, |
|
{ |
|
lgap: 10, |
|
text: '120%', |
|
value: 1.2, |
|
lgap: 10, |
|
}, |
|
{ |
|
lgap: 10, |
|
text: '130%', |
|
value: 1.3, |
|
lgap: 10, |
|
}, |
|
{ |
|
lgap: 10, |
|
text: '140%', |
|
value: 1.4, |
|
lgap: 10, |
|
}, |
|
{ |
|
lgap: 10, |
|
text: '150%', |
|
value: 1.5, |
|
lgap: 10, |
|
}, |
|
{ |
|
lgap: 10, |
|
text: '160%', |
|
value: 1.6, |
|
lgap: 10, |
|
}, |
|
{ |
|
lgap: 10, |
|
text: '170%', |
|
value: 1.7, |
|
lgap: 10, |
|
}, |
|
{ |
|
lgap: 10, |
|
text: '180%', |
|
value: 1.8, |
|
lgap: 10, |
|
}, |
|
{ |
|
lgap: 10, |
|
text: '190%', |
|
value: 1.9, |
|
lgap: 10, |
|
}, |
|
{ |
|
lgap: 10, |
|
text: '200%', |
|
value: 2.0, |
|
lgap: 10, |
|
}, |
|
], |
|
listeners: [{ |
|
eventName: "EVENT_CHANGE", |
|
action: function (v) { |
|
BI.Cache.setItem('scaleRatio', v); |
|
globalScaleRatio = v; |
|
selectHandler(); |
|
} |
|
}], |
|
}]) |
|
}); |
|
}()); |