|
|
|
!(function () {
|
|
|
|
var scale = 1, transformY = 0, selected = true;
|
|
|
|
var html = document.getElementsByTagName('html')[0];
|
|
|
|
var wrapper = document.getElementById("wrapper");
|
|
|
|
var fixedContainer = document.createElement('div');
|
|
|
|
fixedContainer.style.position = "absolute";
|
|
|
|
fixedContainer.style.top = "0";
|
|
|
|
fixedContainer.style.left = "0";
|
|
|
|
fixedContainer.style.width = "100%";
|
|
|
|
|
|
|
|
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 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() {
|
|
|
|
var bounds = getScaleBounds();
|
|
|
|
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 = "hidden";
|
|
|
|
document.body.style.overflowX = "hidden";
|
|
|
|
document.body.style.overflowY = "auto";
|
|
|
|
html.style.backgroundColor = "#ffffff";
|
|
|
|
|
|
|
|
window.scale = window.devicePixelRatio * scale;
|
|
|
|
}
|
|
|
|
|
|
|
|
// 取消缩放
|
|
|
|
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";
|
|
|
|
document.body.style.overflowX = "hidden";
|
|
|
|
document.body.style.overflowY = "hidden";
|
|
|
|
html.style.backgroundColor = "#ffffff";
|
|
|
|
|
|
|
|
scale = 1;
|
|
|
|
window.scale = window.devicePixelRatio / scale;
|
|
|
|
}
|
|
|
|
|
|
|
|
// 获取缩放倍数,原模板宽高
|
|
|
|
function getScaleBounds() {
|
|
|
|
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 bHeight = html.clientHeight / scaleRatio;
|
|
|
|
|
|
|
|
return {
|
|
|
|
scale: scaleRatio,
|
|
|
|
width: html.clientWidth / scaleRatio,
|
|
|
|
height: Math.max(bHeight, scaleRatio === 1 ? html.clientHeight : templateHeight)
|
|
|
|
};
|
|
|
|
}
|
|
|
|
|
|
|
|
// 准备环境,主要是纠正事件偏移
|
|
|
|
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 += el.offsetLeft;
|
|
|
|
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.parentNode;
|
|
|
|
} 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));
|
|
|
|
};
|
|
|
|
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 + "px";
|
|
|
|
this.popupView.element[0].style.top = parseInt(this.popupView.element[0].style.top) * scale + transformY + "px";
|
|
|
|
} else {
|
|
|
|
|
|
|
|
}
|
|
|
|
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 + "px";
|
|
|
|
tooltip.element[0].style.top = parseInt(tooltip.element[0].style.top) * scale + transformY + "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 + "px";
|
|
|
|
tooltip.element[0].style.top = parseInt(tooltip.element[0].style.top) * scale + transformY + "px";
|
|
|
|
tooltip.element[0].style.transform = "scale(" + scale+ ")";
|
|
|
|
tooltip.element[0].style.transformOrigin = "top left";
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
BI.createWidget = function () {
|
|
|
|
if (arguments[0] && arguments[0].element === "body") {
|
|
|
|
arguments[0].element = fixedContainer;
|
|
|
|
}
|
|
|
|
return injectCreate.apply(this, arguments);
|
|
|
|
};
|
|
|
|
|
|
|
|
// Popovers
|
|
|
|
BI.Popovers = new BI.PopoverController({render: fixedContainer});
|
|
|
|
|
|
|
|
//
|
|
|
|
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);
|
|
|
|
|
|
|
|
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() : 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();
|
|
|
|
}
|
|
|
|
}]
|
|
|
|
}])
|
|
|
|
});
|
|
|
|
}());
|