📄 window-manager.js
字号:
/**
* @fileOverview UI layers and window-wide dragging
* @name SimileAjax.WindowManager
*/
/**
* This is a singleton that keeps track of UI layers (modal and
* modeless) and enables/disables UI elements based on which layers
* they belong to. It also provides window-wide dragging
* implementation.
*/
SimileAjax.WindowManager = {
_initialized: false,
_listeners: [],
_draggedElement: null,
_draggedElementCallback: null,
_dropTargetHighlightElement: null,
_lastCoords: null,
_ghostCoords: null,
_draggingMode: "",
_dragging: false,
_layers: []
};
SimileAjax.WindowManager.initialize = function() {
if (SimileAjax.WindowManager._initialized) {
return;
}
SimileAjax.DOM.registerEvent(document.body, "mousedown", SimileAjax.WindowManager._onBodyMouseDown);
SimileAjax.DOM.registerEvent(document.body, "mousemove", SimileAjax.WindowManager._onBodyMouseMove);
SimileAjax.DOM.registerEvent(document.body, "mouseup", SimileAjax.WindowManager._onBodyMouseUp);
SimileAjax.DOM.registerEvent(document, "keydown", SimileAjax.WindowManager._onBodyKeyDown);
SimileAjax.DOM.registerEvent(document, "keyup", SimileAjax.WindowManager._onBodyKeyUp);
SimileAjax.WindowManager._layers.push({index: 0});
SimileAjax.WindowManager._historyListener = {
onBeforeUndoSeveral: function() {},
onAfterUndoSeveral: function() {},
onBeforeUndo: function() {},
onAfterUndo: function() {},
onBeforeRedoSeveral: function() {},
onAfterRedoSeveral: function() {},
onBeforeRedo: function() {},
onAfterRedo: function() {}
};
SimileAjax.History.addListener(SimileAjax.WindowManager._historyListener);
SimileAjax.WindowManager._initialized = true;
};
SimileAjax.WindowManager.getBaseLayer = function() {
SimileAjax.WindowManager.initialize();
return SimileAjax.WindowManager._layers[0];
};
SimileAjax.WindowManager.getHighestLayer = function() {
SimileAjax.WindowManager.initialize();
return SimileAjax.WindowManager._layers[SimileAjax.WindowManager._layers.length - 1];
};
SimileAjax.WindowManager.registerEventWithObject = function(elmt, eventName, obj, handlerName, layer) {
SimileAjax.WindowManager.registerEvent(
elmt,
eventName,
function(elmt2, evt, target) {
return obj[handlerName].call(obj, elmt2, evt, target);
},
layer
);
};
SimileAjax.WindowManager.registerEvent = function(elmt, eventName, handler, layer) {
if (layer == null) {
layer = SimileAjax.WindowManager.getHighestLayer();
}
var handler2 = function(elmt, evt, target) {
if (SimileAjax.WindowManager._canProcessEventAtLayer(layer)) {
SimileAjax.WindowManager._popToLayer(layer.index);
try {
handler(elmt, evt, target);
} catch (e) {
SimileAjax.Debug.exception(e);
}
}
SimileAjax.DOM.cancelEvent(evt);
return false;
}
SimileAjax.DOM.registerEvent(elmt, eventName, handler2);
};
SimileAjax.WindowManager.pushLayer = function(f, ephemeral, elmt) {
var layer = { onPop: f, index: SimileAjax.WindowManager._layers.length, ephemeral: (ephemeral), elmt: elmt };
SimileAjax.WindowManager._layers.push(layer);
return layer;
};
SimileAjax.WindowManager.popLayer = function(layer) {
for (var i = 1; i < SimileAjax.WindowManager._layers.length; i++) {
if (SimileAjax.WindowManager._layers[i] == layer) {
SimileAjax.WindowManager._popToLayer(i - 1);
break;
}
}
};
SimileAjax.WindowManager.popAllLayers = function() {
SimileAjax.WindowManager._popToLayer(0);
};
SimileAjax.WindowManager.registerForDragging = function(elmt, callback, layer) {
SimileAjax.WindowManager.registerEvent(
elmt,
"mousedown",
function(elmt, evt, target) {
SimileAjax.WindowManager._handleMouseDown(elmt, evt, callback);
},
layer
);
};
SimileAjax.WindowManager._popToLayer = function(level) {
while (level+1 < SimileAjax.WindowManager._layers.length) {
try {
var layer = SimileAjax.WindowManager._layers.pop();
if (layer.onPop != null) {
layer.onPop();
}
} catch (e) {
}
}
};
SimileAjax.WindowManager._canProcessEventAtLayer = function(layer) {
if (layer.index == (SimileAjax.WindowManager._layers.length - 1)) {
return true;
}
for (var i = layer.index + 1; i < SimileAjax.WindowManager._layers.length; i++) {
if (!SimileAjax.WindowManager._layers[i].ephemeral) {
return false;
}
}
return true;
};
SimileAjax.WindowManager.cancelPopups = function(evt) {
var evtCoords = (evt) ? SimileAjax.DOM.getEventPageCoordinates(evt) : { x: -1, y: -1 };
var i = SimileAjax.WindowManager._layers.length - 1;
while (i > 0 && SimileAjax.WindowManager._layers[i].ephemeral) {
var layer = SimileAjax.WindowManager._layers[i];
if (layer.elmt != null) { // if event falls within main element of layer then don't cancel
var elmt = layer.elmt;
var elmtCoords = SimileAjax.DOM.getPageCoordinates(elmt);
if (evtCoords.x >= elmtCoords.left && evtCoords.x < (elmtCoords.left + elmt.offsetWidth) &&
evtCoords.y >= elmtCoords.top && evtCoords.y < (elmtCoords.top + elmt.offsetHeight)) {
break;
}
}
i--;
}
SimileAjax.WindowManager._popToLayer(i);
};
SimileAjax.WindowManager._onBodyMouseDown = function(elmt, evt, target) {
if (!("eventPhase" in evt) || evt.eventPhase == evt.BUBBLING_PHASE) {
SimileAjax.WindowManager.cancelPopups(evt);
}
};
SimileAjax.WindowManager._handleMouseDown = function(elmt, evt, callback) {
SimileAjax.WindowManager._draggedElement = elmt;
SimileAjax.WindowManager._draggedElementCallback = callback;
SimileAjax.WindowManager._lastCoords = { x: evt.clientX, y: evt.clientY };
SimileAjax.DOM.cancelEvent(evt);
return false;
};
SimileAjax.WindowManager._onBodyKeyDown = function(elmt, evt, target) {
if (SimileAjax.WindowManager._dragging) {
if (evt.keyCode == 27) { // esc
SimileAjax.WindowManager._cancelDragging();
} else if ((evt.keyCode == 17 || evt.keyCode == 16) && SimileAjax.WindowManager._draggingMode != "copy") {
SimileAjax.WindowManager._draggingMode = "copy";
var img = SimileAjax.Graphics.createTranslucentImage(SimileAjax.urlPrefix + "images/copy.png");
img.style.position = "absolute";
img.style.left = (SimileAjax.WindowManager._ghostCoords.left - 16) + "px";
img.style.top = (SimileAjax.WindowManager._ghostCoords.top) + "px";
document.body.appendChild(img);
SimileAjax.WindowManager._draggingModeIndicatorElmt = img;
}
}
};
SimileAjax.WindowManager._onBodyKeyUp = function(elmt, evt, target) {
if (SimileAjax.WindowManager._dragging) {
if (evt.keyCode == 17 || evt.keyCode == 16) {
SimileAjax.WindowManager._draggingMode = "";
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -