App-SocialCalc-Multiplayer
view release on metacpan or search on metacpan
socialcalc/socialcalctableeditor.js view on Meta::CPAN
switch (charname) {
case "[ctrl-c]":
case "[ctrl-x]":
ta = editor.pasteTextarea;
ta.value = "";
cell=SocialCalc.GetEditorCellElement(editor, editor.ecell.row, editor.ecell.col);
if (cell) {
position = SocialCalc.GetElementPosition(cell.element);
ta.style.left = (position.left-1)+"px";
ta.style.top = (position.top-1)+"px";
}
if (editor.range.hasrange) {
sel = SocialCalc.crToCoord(editor.range.left, editor.range.top)+
":"+SocialCalc.crToCoord(editor.range.right, editor.range.bottom);
}
else {
sel = editor.ecell.coord;
}
// get what to copy to clipboard
cliptext = SocialCalc.ConvertSaveToOtherFormat(SocialCalc.CreateSheetSave(editor.context.sheetobj, sel), "tab");
if (charname == "[ctrl-c]" || editor.noEdit) { // if copy or cut but in no edit
cmd = "copy "+sel+" formulas";
}
else { // [ctrl-x]
cmd = "cut "+sel+" formulas";
}
editor.EditorScheduleSheetCommands(cmd, true, false); // queue up command to put on SocialCalc clipboard
/* Copy as HTML: This fails rather badly as it won't paste into Notepad as tab-delimited text. Oh well.
ha = editor.pasteHTMLarea;
if (editor.range.hasrange) {
cell = SocialCalc.GetEditorCellElement(editor, editor.range.top, editor.range.left);
}
else {
cell = SocialCalc.GetEditorCellElement(editor, editor.ecell.row, editor.ecell.col);
}
if (cell) position = SocialCalc.GetElementPosition(cell.element);
if (ha) {
if (position) {
ha.style.left = (position.left-1)+"px";
ha.style.top = (position.top-1)+"px";
}
ha.style.visibility="visible";
cliptext = SocialCalc.ConvertSaveToOtherFormat(SocialCalc.CreateSheetSave(editor.context.sheetobj, sel), "html");
ha.innerHTML = cliptext.replace(/<tr\b[^>]*>[\d\D]*?<\/tr\b[^>]*>/i, '');
ha.focus();
var range = document.body.createControlRange();
range.addElement(ha.childNodes[0]);
range.select();
}
*/
ta.style.display = "block";
ta.value = cliptext; // must follow "block" setting for Webkit
ta.focus();
ta.select();
window.setTimeout(function() {
if (!SocialCalc.GetSpreadsheetControlObject) return; // in case not loaded
var s = SocialCalc.GetSpreadsheetControlObject();
if (!s) return;
var editor = s.editor;
/*
var ha = editor.pasteHTMLarea;
if (ha) {
ha.blur();
ha.innerHTML = '';
ha.style.visibility = 'hidden';
}
*/
var ta = editor.pasteTextarea;
ta.blur();
ta.style.display = "none";
SocialCalc.KeyboardFocus();
}, 200);
return true;
case "[ctrl-v]":
if (editor.noEdit) return true; // not if no edit
var showPasteTextArea = function() {
ta = editor.pasteTextarea;
ta.value = "";
cell=SocialCalc.GetEditorCellElement(editor, editor.ecell.row, editor.ecell.col);
if (cell) {
position = SocialCalc.GetElementPosition(cell.element);
ta.style.left = (position.left-1)+"px";
ta.style.top = (position.top-1)+"px";
}
ta.style.display = "block";
ta.value = ""; // must follow "block" setting for Webkit
ta.focus();
};
ha = editor.pasteHTMLarea;
if (ha) {
/* Pasting via HTML - Currently IE only */
ha.style.visibility = "visible";
ha.focus();
}
else {
showPasteTextArea();
}
window.setTimeout(function() {
if (!SocialCalc.GetSpreadsheetControlObject) return;
var s = SocialCalc.GetSpreadsheetControlObject();
if (!s) return;
var editor = s.editor;
var value = null;
var isPasteSameAsClipboard = false;
ha = editor.pasteHTMLarea;
if (ha) {
/* IE: We append a U+FFFC to every TD that's not the last of its row,
* then we obtain innerText, then turn U+FFFC back to \t,
* thereby preserving the cell separations (which gets discarded
* if we simply paste via textarea.
*/
var _ObjectReplacementCharacter_ = String.fromCharCode(0xFFFC);
var html = ha.innerHTML;
if (html.search(/<(?![Bb][Rr])[A-Za-z]/) >= 0) {
/* HTML Paste: Mark TDs with U+FFFC accordingly.. */
ha.innerHTML = html.replace(
/(?:<\/[Tt][Dd]>)/g,
_ObjectReplacementCharacter_
);
}
else {
/* Text Paste: In IE, \t is transformed into , so replace them with U+FFFC. */
ha.innerHTML = html.replace(
/&[Nn][Bb][Ss][Pp];/g,
_ObjectReplacementCharacter_
);
}
value = ha.innerText.replace(new RegExp(_ObjectReplacementCharacter_, 'g'), '\t');
ha.innerHTML = '';
ha.blur();
ha.style.visibility = "hidden";
}
else {
var ta = editor.pasteTextarea;
value = ta.value;
ta.blur();
ta.style.display = "none";
}
value = value.replace(/\r\n/g, "\n").replace(/\n?$/, '\n');
var clipstr = SocialCalc.ConvertSaveToOtherFormat(SocialCalc.Clipboard.clipboard, "tab");
if (value == clipstr || (value.length-clipstr.length==1 && value.substring(0,value.length-1)==clipstr)) {
isPasteSameAsClipboard = true;
}
var cmd = "";
// pastes SocialCalc clipboard if did a Ctrl-C and contents still the same
// Webkit adds an extra blank line, so need to allow for that
if (!isPasteSameAsClipboard) {
cmd = "loadclipboard "+
SocialCalc.encodeForSave(SocialCalc.ConvertOtherFormatToSave(value, "tab")) + "\n";
}
var cr;
if (editor.range.hasrange) {
cr = SocialCalc.crToCoord(editor.range.left, editor.range.top);
}
else {
cr = editor.ecell.coord;
}
cmd += "paste "+cr+" formulas";
editor.EditorScheduleSheetCommands(cmd, true, false);
SocialCalc.KeyboardFocus();
}, 200);
return true;
case "[ctrl-z]":
editor.EditorScheduleSheetCommands("undo", true, false);
return false;
case "[ctrl-s]": // !!!! temporary hack
window.setTimeout(
function() {
if (!SocialCalc.GetSpreadsheetControlObject) return;
var s = SocialCalc.GetSpreadsheetControlObject();
if (!s) return;
var editor = s.editor;
var sheet = editor.context.sheetobj;
var cell = sheet.GetAssuredCell(editor.ecell.coord);
var ntvf = cell.nontextvalueformat ? sheet.valueformats[cell.nontextvalueformat-0] || "" : "";
var newntvf = window.prompt("Advanced Feature:\n\nCustom Numeric Format or Command", ntvf);
if (newntvf != null) { // not cancelled
if (newntvf.match(/^cmd:/)) {
cmd = newntvf.substring(4); // execute as command
}
else if (newntvf.match(/^edit:/)) {
cmd = newntvf.substring(5); // execute as command
if (SocialCalc.CtrlSEditor) {
SocialCalc.CtrlSEditor(cmd);
}
return;
}
else {
if (editor.range.hasrange) {
sel = SocialCalc.crToCoord(editor.range.left, editor.range.top)+
":"+SocialCalc.crToCoord(editor.range.right, editor.range.bottom);
}
else {
sel = editor.ecell.coord;
}
cmd = "set "+sel+" nontextvalueformat "+newntvf;
}
editor.EditorScheduleSheetCommands(cmd, true, false);
}
},
200);
return false;
default:
break;
}
return true;
};
// Set sheet's status callback:
context.sheetobj.statuscallback = SocialCalc.EditorSheetStatusCallback;
context.sheetobj.statuscallbackparams = this; // this object: the table editor object
// StatusCallback: all values are called at appropriate times, add with unique name, delete when done
//
// Each value must be an object in the form of:
//
// func: function(editor, status, arg, params) {...},
// params: params value to call func with
//
// The values for status and arg are:
//
// all the SocialCalc RecalcSheet statuscallbacks, including:
//
// calccheckdone, calclist length
socialcalc/socialcalctableeditor.js view on Meta::CPAN
case "calcfinished":
signalstatus(status);
editor.ScheduleRender();
return;
case "schedrender":
editor.busy = true; // in case got here without cmd or recalc
break;
case "renderdone":
break;
case "schedposcalc":
editor.busy = true; // in case got here without cmd or recalc
break;
case "doneposcalc":
if (editor.deferredCommands.length) {
signalstatus(status);
dcmd = editor.deferredCommands.shift();
editor.EditorScheduleSheetCommands(dcmd.cmdstr, dcmd.saveundo, true);
}
else {
editor.busy = false;
signalstatus(status);
if (editor.state=="start") editor.DisplayCellContents(); // make sure up to date
}
return;
default:
addmsg("Unknown status: "+status);
break;
}
signalstatus(status);
return;
}
// Timer-driven steps for use with SocialCalc.EditorSheetStatusCallback
SocialCalc.EditorStepInfo = {
// status: "", // saved value to pass to callback
editor: null // for callback
// arg: null, // for callback
// timerobj: null
};
/*
SocialCalc.EditorStepSet = function(editor, status, arg) {
var esi = SocialCalc.EditorStepInfo;
addmsg("step: "+status);
if (esi.timerobj) {
alert("Already waiting. Old/new: "+esi.status+"/"+status);
}
esi.editor = editor;
esi.status = status;
esi.timerobj = window.setTimeout(SocialCalc.EditorStepDone, 1);
}
SocialCalc.EditorStepDone = function() {
var esi = SocialCalc.EditorStepInfo;
esi.timerobj = null;
SocialCalc.EditorSheetStatusCallback(null, esi.status, null, esi.editor);
}
*/
//
// str = SocialCalc.EditorGetStatuslineString(editor, status, arg, params)
//
// Assumes params is an object where it can use "calculating" and "command"
// to keep track of state.
// Returns string for status line.
//
SocialCalc.EditorGetStatuslineString = function(editor, status, arg, params) {
var scc = SocialCalc.Constants;
var sstr, progress, coord, circ, r, c, cell, sum, ele;
progress = "";
switch (status) {
case "moveecell":
case "rangechange":
case "startup":
break;
case "cmdstart":
params.command = true;
document.body.style.cursor = "progress";
editor.griddiv.style.cursor = "progress";
progress = scc.s_statusline_executing;
break;
case "cmdextension":
progress = "Command Extension: "+arg;
break;
case "cmdend":
params.command = false;
break;
case "schedrender":
progress = scc.s_statusline_displaying;
break;
case "renderdone":
progress = " ";
break;
case "schedposcalc":
progress = scc.s_statusline_displaying;
break;
case "cmdendnorender":
case "doneposcalc":
document.body.style.cursor = "default";
editor.griddiv.style.cursor = "default";
break;
case "calcorder":
progress = scc.s_statusline_ordering+Math.floor(100*arg.count/(arg.total||1))+"%";
break;
case "calcstep":
socialcalc/socialcalctableeditor.js view on Meta::CPAN
var event = e || window.event;
var mouseinfo = SocialCalc.EditorMouseInfo;
var editor = mouseinfo.editor;
if (!editor) return; // not us, ignore
var viewport = SocialCalc.GetViewportInfo();
var clientX = event.clientX + viewport.horizontalScroll;
var newsize = (editor.context.colwidth[mouseinfo.mouseresizecolnum]-0) + (clientX - mouseinfo.mousedownclientx);
if (newsize < SocialCalc.Constants.defaultMinimumColWidth) newsize = SocialCalc.Constants.defaultMinimumColWidth;
var sizedisplay = mouseinfo.mouseresizedisplay;
// sizedisplay.firstChild.lastChild.firstChild.childNodes[1].firstChild.innerHTML = newsize+"";
// sizedisplay.firstChild.lastChild.firstChild.childNodes[0].firstChild.style.width = (newsize-2)+"px";
sizedisplay.innerHTML = '<table cellpadding="0" cellspacing="0"><tr><td style="height:100px;'+
'border:1px dashed black;background-color:white;width:' + (newsize-2) + 'px;"> </td>'+
'<td><div style="font-size:small;color:white;background-color:gray;padding:4px;">'+
newsize + '</div></td></tr></table>';
SocialCalc.setStyles(sizedisplay.firstChild.lastChild.firstChild.childNodes[0], "filter:alpha(opacity=85);opacity:.85;"); // so no warning msg with Firefox about filter
if (event.stopPropagation) event.stopPropagation(); // DOM Level 2
else event.cancelBubble = true; // IE 5+
if (event.preventDefault) event.preventDefault(); // DOM Level 2
else event.returnValue = false; // IE 5+
return;
}
SocialCalc.ProcessEditorColsizeMouseUp = function(e) {
var event = e || window.event;
var mouseinfo = SocialCalc.EditorMouseInfo;
var editor = mouseinfo.editor;
if (!editor) return; // not us, ignore
element = mouseinfo.element;
var viewport = SocialCalc.GetViewportInfo();
var clientX = event.clientX + viewport.horizontalScroll;
if (event.stopPropagation) event.stopPropagation(); // DOM Level 2
else event.cancelBubble = true; // IE 5+
if (event.preventDefault) event.preventDefault(); // DOM Level 2
else event.returnValue = false; // IE 5+
if (document.removeEventListener) { // DOM Level 2
document.removeEventListener("mousemove", SocialCalc.ProcessEditorColsizeMouseMove, true);
document.removeEventListener("mouseup", SocialCalc.ProcessEditorColsizeMouseUp, true);
}
else if (editor.toplevel.detachEvent) { // IE
editor.toplevel.detachEvent("onlosecapture", SocialCalc.ProcessEditorColsizeMouseUp);
editor.toplevel.detachEvent("onmouseup", SocialCalc.ProcessEditorColsizeMouseUp);
editor.toplevel.detachEvent("onmousemove", SocialCalc.ProcessEditorColsizeMouseMove);
editor.toplevel.releaseCapture();
}
var newsize = (editor.context.colwidth[mouseinfo.mouseresizecolnum]-0) + (clientX - mouseinfo.mousedownclientx);
if (newsize < SocialCalc.Constants.defaultMinimumColWidth) newsize = SocialCalc.Constants.defaultMinimumColWidth;
editor.EditorScheduleSheetCommands("set "+mouseinfo.mouseresizecol+" width "+newsize, true, false);
if (editor.timeout) window.clearTimeout(editor.timeout);
editor.timeout = window.setTimeout(SocialCalc.FinishColsize, 1); // wait - Firefox 2 has a bug otherwise with next mousedown
return false;
}
SocialCalc.FinishColsize = function() {
var mouseinfo = SocialCalc.EditorMouseInfo;
var editor = mouseinfo.editor;
if (!editor) return;
editor.toplevel.removeChild(mouseinfo.mouseresizedisplay);
mouseinfo.mouseresizedisplay = null;
// editor.FitToEditTable();
// editor.EditorRenderSheet();
// editor.SchedulePositionCalculations();
mouseinfo.editor = null;
return;
}
//
// Handle auto-repeat of dragging the cursor into the borders of the sheet
//
SocialCalc.AutoRepeatInfo = {
timer: null, // timer object for repeating
mouseinfo: null, // result from SocialCalc.GridMousePosition
repeatinterval: 1000, // milliseconds to wait between repeats
editor: null, // editor object to use when it repeats
repeatcallback: null // used instead of default when repeating (e.g., for cellhandles)
// called as: repeatcallback(newcoord, direction)
};
// Control auto-repeat. If mouseinfo==null, cancel.
SocialCalc.SetDragAutoRepeat = function(editor, mouseinfo, callback) {
var repeatinfo = SocialCalc.AutoRepeatInfo;
var coord, direction;
repeatinfo.repeatcallback = callback; // null in regular case
if (!mouseinfo) { // cancel
if (repeatinfo.timer) { // If was repeating, stop
window.clearTimeout(repeatinfo.timer); // cancel timer
repeatinfo.timer = null;
}
repeatinfo.mouseinfo = null;
return; // done
}
repeatinfo.editor = editor;
if (repeatinfo.mouseinfo) { // check for change while repeating
if (mouseinfo.rowheader || mouseinfo.rowfooter) {
if (mouseinfo.row != repeatinfo.mouseinfo.row) { // changed row while dragging sidewards
coord = SocialCalc.crToCoord(editor.ecell.col, mouseinfo.row); // change to it
if (repeatinfo.repeatcallback) {
if (mouseinfo.row < repeatinfo.mouseinfo.row) {
direction = "left";
}
else if (mouseinfo.row > repeatinfo.mouseinfo.row) {
direction = "right";
}
else {
direction = "";
}
repeatinfo.repeatcallback(coord, direction);
}
else {
editor.MoveECell(coord);
editor.MoveECell(coord);
editor.RangeExtend();
editor.EditorMouseRange(coord);
}
}
}
else if (mouseinfo.colheader || mouseinfo.colfooter) {
if (mouseinfo.col != repeatinfo.mouseinfo.col) { // changed col while dragging vertically
coord = SocialCalc.crToCoord(mouseinfo.col, editor.ecell.row); // change to it
if (repeatinfo.repeatcallback) {
if (mouseinfo.row < repeatinfo.mouseinfo.row) {
direction = "left";
}
else if (mouseinfo.row > repeatinfo.mouseinfo.row) {
direction = "right";
}
else {
direction = "";
}
repeatinfo.repeatcallback(coord, direction);
}
else {
editor.MoveECell(coord);
editor.RangeExtend();
editor.EditorMouseRange(coord);
}
}
}
}
repeatinfo.mouseinfo = mouseinfo;
if (mouseinfo.distance < 5) repeatinfo.repeatinterval = 333;
else if (mouseinfo.distance < 10) repeatinfo.repeatinterval = 250;
else if (mouseinfo.distance < 25) repeatinfo.repeatinterval = 100;
else if (mouseinfo.distance < 35) repeatinfo.repeatinterval = 75;
else { // too far - stop repeating
if (repeatinfo.timer) { // if repeating, cancel it
window.clearTimeout(repeatinfo.timer); // cancel timer
repeatinfo.timer = null;
}
return;
}
if (!repeatinfo.timer) { // start if not already running
repeatinfo.timer = window.setTimeout(SocialCalc.DragAutoRepeat, repeatinfo.repeatinterval);
}
return;
}
//
// DragAutoRepeat()
//
SocialCalc.DragAutoRepeat = function() {
var repeatinfo = SocialCalc.AutoRepeatInfo;
var mouseinfo = repeatinfo.mouseinfo;
var direction, coord, cr;
if (mouseinfo.rowheader) direction = "left";
else if (mouseinfo.rowfooter) direction = "right";
else if (mouseinfo.colheader) direction = "up";
else if (mouseinfo.colfooter) direction = "down";
if (repeatinfo.repeatcallback) {
cr = SocialCalc.coordToCr(repeatinfo.editor.ecell.coord);
if (direction == "left" && cr.col > 1) cr.col--;
else if (direction == "right") cr.col++;
else if (direction == "up" && cr.row > 1) cr.row--;
else if (direction == "down") cr.row++;
coord = SocialCalc.crToCoord(cr.col, cr.row);
repeatinfo.repeatcallback(coord, direction);
}
else {
coord = repeatinfo.editor.MoveECellWithKey("[a"+direction+"]shifted");
if (coord) repeatinfo.editor.EditorMouseRange(coord);
}
repeatinfo.timer = window.setTimeout(SocialCalc.DragAutoRepeat, repeatinfo.repeatinterval);
}
//
// Handling Clicking
//
SocialCalc.ProcessEditorDblClick = function(e) {
var editor, result, coord, textarea, wval, range;
var event = e || window.event;
var viewport = SocialCalc.GetViewportInfo();
var clientX = event.clientX + viewport.horizontalScroll;
var clientY = event.clientY + viewport.verticalScroll;
var mouseinfo = SocialCalc.EditorMouseInfo;
var ele = event.target || event.srcElement; // source object is often within what we want
var mobj;
if (mouseinfo.ignore) return; // ignore this
for (mobj=null; !mobj && ele; ele=ele.parentNode) { // go up tree looking for one of our elements
mobj = SocialCalc.LookupElement(ele, mouseinfo.registeredElements);
}
if (!mobj) {
mouseinfo.editor = null;
return; // not one of our elements
}
editor = mobj.editor;
result = SocialCalc.GridMousePosition(editor, clientX, clientY);
if (!result || !result.coord) return; // not within cell area - ignore
mouseinfo.editor = editor; // remember for later
mouseinfo.element = ele;
range = editor.range;
sheetobj = editor.context.sheetobj;
switch (editor.state) {
case "start":
SocialCalc.EditorOpenCellEdit(editor);
break;
case "input":
break;
default:
break;
}
if (event.stopPropagation) event.stopPropagation(); // DOM Level 2
else event.cancelBubble = true; // IE 5+
if (event.preventDefault) event.preventDefault(); // DOM Level 2
else event.returnValue = false; // IE 5+
return;
socialcalc/socialcalctableeditor.js view on Meta::CPAN
//
// CalculateEditorPositions(editor)
//
// Calculate the screen positions and other values of various editing elements
// These values change and need to be recomputed when the pane first/last or cell contents change,
// as well as new column widths, etc.
//
// Note: Only call this after the grid has been rendered! You may have to wait for a timeout...
//
SocialCalc.CalculateEditorPositions = function(editor) {
var rowpane, colpane, i;
editor.gridposition = SocialCalc.GetElementPosition(editor.griddiv);
editor.headposition =
SocialCalc.GetElementPosition(editor.griddiv.firstChild.lastChild.childNodes[2].childNodes[1]); // 3rd tr 2nd td
editor.rowpositions = [];
for (rowpane=0; rowpane<editor.context.rowpanes.length; rowpane++) {
editor.CalculateRowPositions(rowpane, editor.rowpositions, editor.rowheight);
}
for (i=0; i<editor.rowpositions.length; i++) {
if (editor.rowpositions[i]>editor.gridposition.top+editor.tableheight) break;
}
editor.lastvisiblerow = i-1;
editor.colpositions = [];
for (colpane=0; colpane<editor.context.colpanes.length; colpane++) {
editor.CalculateColPositions(colpane, editor.colpositions, editor.colwidth);
}
for (i=0; i<editor.colpositions.length; i++) {
if (editor.colpositions[i]>editor.gridposition.left+editor.tablewidth) break;
}
editor.lastvisiblecol = i-1;
editor.firstscrollingrow = editor.context.rowpanes[editor.context.rowpanes.length-1].first;
editor.firstscrollingrowtop = editor.rowpositions[editor.firstscrollingrow] || editor.headposition.top;
editor.lastnonscrollingrow = editor.context.rowpanes.length-1 > 0 ?
editor.context.rowpanes[editor.context.rowpanes.length-2].last : 0;
editor.firstscrollingcol = editor.context.colpanes[editor.context.colpanes.length-1].first;
editor.firstscrollingcolleft = editor.colpositions[editor.firstscrollingcol] || editor.headposition.left;
editor.lastnonscrollingcol = editor.context.colpanes.length-1 > 0 ?
editor.context.colpanes[editor.context.colpanes.length-2].last : 0;
// Now do the table controls
editor.verticaltablecontrol.ComputeTableControlPositions();
editor.horizontaltablecontrol.ComputeTableControlPositions();
}
//
// ScheduleRender(editor)
//
// Do a series of timeouts to render the sheet, wait for background layout and
// rendering by the browser, and then update editor visuals, sliders, etc.
//
SocialCalc.ScheduleRender = function(editor) {
if (editor.timeout) window.clearTimeout(editor.timeout); // in case called more than once, just use latest
SocialCalc.EditorSheetStatusCallback(null, "schedrender", null, editor);
SocialCalc.EditorStepInfo.editor = editor;
editor.timeout = window.setTimeout(SocialCalc.DoRenderStep, 1);
}
// DoRenderStep()
//
SocialCalc.DoRenderStep = function() {
var editor = SocialCalc.EditorStepInfo.editor;
editor.timeout = null;
editor.EditorRenderSheet();
SocialCalc.EditorSheetStatusCallback(null, "renderdone", null, editor);
SocialCalc.EditorSheetStatusCallback(null, "schedposcalc", null, editor);
editor.timeout = window.setTimeout(SocialCalc.DoPositionCalculations, 1);
}
//
// SocialCalc.SchedulePositionCalculations(editor)
//
SocialCalc.SchedulePositionCalculations = function(editor) {
SocialCalc.EditorStepInfo.editor = editor;
SocialCalc.EditorSheetStatusCallback(null, "schedposcalc", null, editor);
editor.timeout = window.setTimeout(SocialCalc.DoPositionCalculations, 1);
}
// DoPositionCalculations(editor)
//
// Update editor visuals, sliders, etc.
//
// Note: Only call this after the DOM objects have been modified and rendered!
//
SocialCalc.DoPositionCalculations = function() {
var editor = SocialCalc.EditorStepInfo.editor;
editor.timeout = null;
var ok = false;
try {
editor.CalculateEditorPositions();
ok = true;
} catch (e) {}
if (!ok) {
if (typeof $ != 'undefined') {
$(window).trigger('resize');
setTimeout( SocialCalc.DoPositionCalculations, 400);
}
return; /* Workaround IE6 partial-initialized-DOM bug */
}
editor.verticaltablecontrol.PositionTableControlElements();
editor.horizontaltablecontrol.PositionTableControlElements();
SocialCalc.EditorSheetStatusCallback(null, "doneposcalc", null, editor);
if (editor.ensureecell && editor.ecell && !editor.deferredCommands.length) { // don't do if deferred cmd to execute
editor.ensureecell = false;
editor.EnsureECellVisible(); // this could cause another redisplay
}
editor.cellhandles.ShowCellHandles(true);
//!!! Need to now check to see if this positioned controls out of the editing area
//!!! (such as when there is a large wrapped cell and it pushes the pane boundary too far down).
if (SocialCalc.Callbacks.broadcast) SocialCalc.Callbacks.broadcast('ask.ecell');
}
SocialCalc.CalculateRowPositions = function(editor, panenum, positions, sizes) {
var toprow, rowpane, rownum, offset, trowobj, cellposition;
var context=editor.context;
var sheetobj=context.sheetobj;
var tbodyobj;
if (!context.showRCHeaders) throw("Needs showRCHeaders=true");
tbodyobj=editor.fullgrid.lastChild;
// Calculate start of this pane as row in this table:
toprow = 2;
for (rowpane=0; rowpane<panenum; rowpane++) {
toprow += context.rowpanes[rowpane].last - context.rowpanes[rowpane].first + 2; // skip pane and spacing row
}
offset = 0;
for (rownum=context.rowpanes[rowpane].first; rownum<=context.rowpanes[rowpane].last; rownum++) {
trowobj = tbodyobj.childNodes[toprow+offset];
offset++;
cellposition = SocialCalc.GetElementPosition(trowobj.firstChild);
// Safari has problem: If a cell in the row is high, cell 1 is centered and it returns top of centered part
// but if you get position of row element, it always returns the same value (not the row's)
// So we require row number to be vertical aligned to top
if (!positions[rownum]) {
positions[rownum] = cellposition.top; // first one takes precedence
sizes[rownum] = trowobj.firstChild.offsetHeight;
}
}
return;
socialcalc/socialcalctableeditor.js view on Meta::CPAN
break;
}
if (editor.colpositions[col+1]+20>editor.verticaltablecontrol.controlborder) {
break;
}
if (editor.colpositions[col+1]-30<editor.headposition.left) {
break;
}
cellhandles.draghandle.style.left = (editor.colpositions[col+1]-1)+"px";
cellhandles.draghandle.style.top = (editor.rowpositions[row+1]-1)+"px";
cellhandles.draghandle.style.display = "block";
if (moveshow) {
cellhandles.draghandle.style.display = "none";
cellhandles.dragpalette.style.left = (editor.colpositions[col+1]-45)+"px";
cellhandles.dragpalette.style.top = (editor.rowpositions[row+1]-45)+"px";
cellhandles.dragpalette.style.display = "block";
viewport = SocialCalc.GetViewportInfo();
cellhandles.dragtooltip.style.right = (viewport.width-(editor.colpositions[col+1]-1))+"px";
cellhandles.dragtooltip.style.bottom = (viewport.height-(editor.rowpositions[row+1]-1))+"px";
cellhandles.dragtooltip.style.display = "none";
}
doshow = true;
}
while (false); // only do once
if (!doshow) {
cellhandles.draghandle.style.display = "none";
}
if (!moveshow) {
cellhandles.dragpalette.style.display = "none";
cellhandles.dragtooltip.style.display = "none";
}
}
SocialCalc.CellHandlesMouseMoveOnHandle = function(e) {
var scc = SocialCalc.Constants;
var event = e || window.event;
var target = event.target || event.srcElement
var viewport = SocialCalc.GetViewportInfo();
var clientX = event.clientX + viewport.horizontalScroll;
var clientY = event.clientY + viewport.verticalScroll;
editor = SocialCalc.Keyboard.focusTable; // get TableEditor doing keyboard stuff
if (!editor) return true; // we're not handling it -- let browser do default
var cellhandles = editor.cellhandles;
if (!cellhandles.editor) return true; // no handles
if (!editor.cellhandles.mouseDown) {
editor.cellhandles.ShowCellHandles(true, true); // show move handles, too
if (target == cellhandles.dragpalette) {
var whichhandle = SocialCalc.SegmentDivHit([scc.CH_radius1, scc.CH_radius2], editor.cellhandles.dragpalette, clientX, clientY);
if (whichhandle==0) { // off of active part of palette
SocialCalc.CellHandlesHoverTimeout();
return;
}
if (cellhandles.tooltipstimer) {
window.clearTimeout(cellhandles.tooltipstimer);
cellhandles.tooltipstimer = null;
}
cellhandles.tooltipswhichhandle = whichhandle;
cellhandles.tooltipstimer = window.setTimeout(SocialCalc.CellHandlesTooltipsTimeout, 700);
}
if (cellhandles.timer) {
window.clearTimeout(cellhandles.timer);
cellhandles.timer = null;
}
cellhandles.timer = window.setTimeout(SocialCalc.CellHandlesHoverTimeout, 3000);
}
return;
}
//
// whichsegment = SocialCalc.SegmentDivHit(segtable, divWithMouseHit, x, y)
//
// Takes segtable = [upperleft quadrant, upperright, bottomright, bottomleft]
// where each quadrant is either:
// 0 = ignore hits here
// number = return this value
// array = a new segtable for this subquadrant
//
// Alternatively, segtable can be:
// [radius 1, radius 2] and it returns 0 if no hit,
// -1, -2, -3, -4 for inner quadrants, and +1...+4 for outer quadrants
//
SocialCalc.SegmentDivHit = function(segtable, divWithMouseHit, x, y) {
var width = divWithMouseHit.offsetWidth;
var height = divWithMouseHit.offsetHeight;
var left = divWithMouseHit.offsetLeft;
var top = divWithMouseHit.offsetTop;
var v = 0;
var table = segtable;
var len = Math.sqrt(Math.pow(x-left-(width/2.0-.5), 2)+Math.pow(y-top-(height/2.0-.5), 2));
if (table.length==2) { // type 2 segtable
if (x >= left && x < left+width/2 && y >= top && y < top+height/2) { // upper left
if (len <= segtable[0]) v = -1;
else if (len <= segtable[1]) v = 1;
}
if (x >= left+width/2 && x < left+width && y >= top && y < top+height/2) { // upper right
if (len <= segtable[0]) v = -2;
else if (len <= segtable[1]) v = 2;
}
if (x >= left+width/2 && x < left+width && y >= top+height/2 && y < top+height) { // bottom right
if (len <= segtable[0]) v = -3;
else if (len <= segtable[1]) v = 3;
}
if (x >= left && x < left+width/2 && y >= top+height/2 && y < top+height) { // bottom right
if (len <= segtable[0]) v = -4;
else if (len <= segtable[1]) v = 4;
}
return v;
}
while (true) {
if (x >= left && x < left+width/2 && y >= top && y < top+height/2) { // upper left
quadrant += "1";
v = table[0];
if (typeof v == "number") {
break;
}
table = v;
width = width/2;
height = height/2;
continue;
}
if (x >= left+width/2 && x < left+width && y >= top && y < top+height/2) { // upper right
quadrant += "2";
v = table[1];
if (typeof v == "number") {
break;
}
table = v;
width = width/2;
left = left+width;
height = height/2;
continue;
}
if (x >= left+width/2 && x < left+width && y >= top+height/2 && y < top+height) { // bottom right
quadrant += "3";
v = table[2];
if (typeof v == "number") {
break;
}
table = v;
width = width/2;
left = left + width;
height = height/2;
top = top + height;
continue;
}
if (x >= left && x < left+width/2 && y >= top+height/2 && y < top+height) { // bottom right
quadrant += "4";
v = table[3];
if (typeof v == "number") {
break;
}
table = v;
width = width/2;
height = height/2;
top = top + height;
continue;
}
return 0; // didn't match
}
//addmsg((x-divWithMouseHit.offsetLeft)+","+(y-divWithMouseHit.offsetTop)+"="+quadrant+" "+v);
return v;
}
SocialCalc.CellHandlesHoverTimeout = function() {
editor = SocialCalc.Keyboard.focusTable; // get TableEditor doing keyboard stuff
if (!editor) return true; // we're not handling it -- let browser do default
var cellhandles = editor.cellhandles;
if (cellhandles.timer) {
window.clearTimeout(cellhandles.timer);
cellhandles.timer = null;
}
if (cellhandles.tooltipstimer) {
window.clearTimeout(cellhandles.tooltipstimer);
cellhandles.tooltipstimer = null;
}
editor.cellhandles.ShowCellHandles(true, false); // hide move handles
}
SocialCalc.CellHandlesTooltipsTimeout = function() {
editor = SocialCalc.Keyboard.focusTable; // get TableEditor doing keyboard stuff
if (!editor) return true; // we're not handling it -- let browser do default
var cellhandles = editor.cellhandles;
if (cellhandles.tooltipstimer) {
window.clearTimeout(cellhandles.tooltipstimer);
cellhandles.tooltipstimer = null;
}
var whichhandle = cellhandles.tooltipswhichhandle;
if (whichhandle==0) { // off of active part of palette
SocialCalc.CellHandlesHoverTimeout();
return;
}
if (whichhandle==-3) {
cellhandles.dragtooltip.innerHTML = scc.s_CHfillAllTooltip;
}
else if (whichhandle==3) {
cellhandles.dragtooltip.innerHTML = scc.s_CHfillContentsTooltip;
}
else if (whichhandle==-2) {
cellhandles.dragtooltip.innerHTML = scc.s_CHmovePasteAllTooltip;
}
else if (whichhandle==-4) {
cellhandles.dragtooltip.innerHTML = scc.s_CHmoveInsertAllTooltip;
}
else if (whichhandle==2) {
cellhandles.dragtooltip.innerHTML = scc.s_CHmovePasteContentsTooltip;
}
else if (whichhandle==4) {
cellhandles.dragtooltip.innerHTML = scc.s_CHmoveInsertContentsTooltip;
}
else {
cellhandles.dragtooltip.innerHTML = " ";
cellhandles.dragtooltip.style.display = "none";
return;
}
cellhandles.dragtooltip.style.display = "block";
}
SocialCalc.CellHandlesMouseDown = function(e) {
var scc = SocialCalc.Constants;
var editor, result, coord, textarea, wval, range;
var event = e || window.event;
var viewport = SocialCalc.GetViewportInfo();
var clientX = event.clientX + viewport.horizontalScroll;
var clientY = event.clientY + viewport.verticalScroll;
var mouseinfo = SocialCalc.EditorMouseInfo;
editor = SocialCalc.Keyboard.focusTable; // get TableEditor doing keyboard stuff
if (!editor) return true; // we're not handling it -- let browser do default
if (editor.busy) return; // don't do anything when busy (is this correct?)
var cellhandles = editor.cellhandles;
cellhandles.movedmouse = false; // detect no-op
if (cellhandles.timer) { // cancel timer
window.clearTimeout(cellhandles.timer);
cellhandles.timer = null;
}
if (cellhandles.tooltipstimer) {
window.clearTimeout(cellhandles.tooltipstimer);
cellhandles.tooltipstimer = null;
}
cellhandles.dragtooltip.innerHTML = " ";
cellhandles.dragtooltip.style.display = "none";
range = editor.range;
var whichhandle = SocialCalc.SegmentDivHit([scc.CH_radius1, scc.CH_radius2], editor.cellhandles.dragpalette, clientX, clientY);
if (whichhandle==1 || whichhandle==-1 || whichhandle==0) {
cellhandles.ShowCellHandles(true, false); // hide move handles
return;
}
mouseinfo.ignore = true; // stop other code from looking at the mouse
if (whichhandle==-3) {
cellhandles.dragtype = "Fill";
// mouseinfo.element = editor.cellhandles.fillhandle;
cellhandles.noCursorSuffix = false;
}
else if (whichhandle==3) {
cellhandles.dragtype = "FillC";
// mouseinfo.element = editor.cellhandles.fillhandle;
cellhandles.noCursorSuffix = false;
}
else if (whichhandle==-2) {
cellhandles.dragtype = "Move";
// mouseinfo.element = editor.cellhandles.movehandle1;
cellhandles.noCursorSuffix = true;
}
else if (whichhandle==-4) {
cellhandles.dragtype = "MoveI";
// mouseinfo.element = editor.cellhandles.movehandle2;
cellhandles.noCursorSuffix = false;
}
else if (whichhandle==2) {
cellhandles.dragtype = "MoveC";
// mouseinfo.element = editor.cellhandles.movehandle1;
cellhandles.noCursorSuffix = true;
}
else if (whichhandle==4) {
cellhandles.dragtype = "MoveIC";
// mouseinfo.element = editor.cellhandles.movehandle2;
cellhandles.noCursorSuffix = false;
}
cellhandles.filltype = null;
switch (cellhandles.dragtype) {
case "Fill":
case "FillC":
if (!range.hasrange) {
editor.RangeAnchor();
}
break;
case "Move":
case "MoveI":
case "MoveC":
case "MoveIC":
socialcalc/socialcalctableeditor.js view on Meta::CPAN
registered: false, // if true, an event handler has been registered for this functionality
// Items used during hover over an element
tooltipElement: null, // item being processed (.element is the actual element)
timer: null, // timer object waiting to see if holding over element
popupElement: null, // tooltip element being displayed
clientX: 0, // modifyable version to restrict movement
clientY: 0,
offsetX: SocialCalc.Constants.TooltipOffsetX, // modifyable version to allow positioning
offsetY: SocialCalc.Constants.TooltipOffsetY
}
//
// TooltipRegister(element, tiptext, functionobj) - make element have a tooltip
//
SocialCalc.TooltipRegister = function(element, tiptext, functionobj) {
var tooltipinfo = SocialCalc.TooltipInfo;
tooltipinfo.registeredElements.push(
{element: element, tiptext: tiptext, functionobj: functionobj}
);
if (tooltipinfo.registered) return; // only need to add event listener once
if (document.addEventListener) { // DOM Level 2 -- Firefox, et al
document.addEventListener("mousemove", SocialCalc.TooltipMouseMove, false);
}
else if (document.attachEvent) { // IE 5+
document.attachEvent("onmousemove", SocialCalc.TooltipMouseMove);
}
else { // don't handle this
throw SocialCalc.Constants.s_BrowserNotSupported;
}
tooltipinfo.registered = true; // remember
return;
}
//
// TooltipMouseMove(event)
//
SocialCalc.TooltipMouseMove = function(event) {
var e = event || window.event;
var tooltipinfo = SocialCalc.TooltipInfo;
tooltipinfo.viewport = SocialCalc.GetViewportInfo();
tooltipinfo.clientX = e.clientX + tooltipinfo.viewport.horizontalScroll;
tooltipinfo.clientY = e.clientY + tooltipinfo.viewport.verticalScroll;
var tobj = SocialCalc.LookupElement(e.target || e.srcElement, tooltipinfo.registeredElements);
if (tooltipinfo.timer) { // waiting to see if holding still: didn't hold still
window.clearTimeout(tooltipinfo.timer); // cancel timer
tooltipinfo.timer = null;
}
if (tooltipinfo.popupElement) { // currently displaying a tip: hide it
SocialCalc.TooltipHide();
}
tooltipinfo.tooltipElement = tobj || null;
if (!tobj || SocialCalc.ButtonInfo.buttonDown) return; // if not an object with a tip or a "button" is down, ignore
tooltipinfo.timer = window.setTimeout(SocialCalc.TooltipWaitDone, 700);
if (tooltipinfo.tooltipElement.element.addEventListener) { // Register event for mouse down which cancels tooltip stuff
tooltipinfo.tooltipElement.element.addEventListener("mousedown", SocialCalc.TooltipMouseDown, false);
}
else if (tooltipinfo.tooltipElement.element.attachEvent) { // IE
tooltipinfo.tooltipElement.element.attachEvent("onmousedown", SocialCalc.TooltipMouseDown);
}
return;
}
//
// TooltipMouseDown(event)
//
SocialCalc.TooltipMouseDown = function(event) {
var e = event || window.event;
var tooltipinfo = SocialCalc.TooltipInfo;
if (tooltipinfo.timer) {
window.clearTimeout(tooltipinfo.timer); // cancel timer
tooltipinfo.timer = null;
}
if (tooltipinfo.popupElement) { // currently displaying a tip: hide it
SocialCalc.TooltipHide();
}
if (tooltipinfo.tooltipElement) {
if (tooltipinfo.tooltipElement.element.removeEventListener) { // DOM Level 2 -- Firefox, et al
tooltipinfo.tooltipElement.element.removeEventListener("mousedown", SocialCalc.TooltipMouseDown, false);
}
else if (tooltipinfo.tooltipElement.element.attachEvent) { // IE 5+
tooltipinfo.tooltipElement.element.detachEvent("onmousedown", SocialCalc.TooltipMouseDown);
}
tooltipinfo.tooltipElement = null;
}
return;
}
//
// TooltipDisplay(tobj)
//
SocialCalc.TooltipDisplay = function(tobj) {
var tooltipinfo = SocialCalc.TooltipInfo;
var scc = SocialCalc.Constants;
var offsetX = (tobj.functionobj && ((typeof tobj.functionobj.offsetx) == "number")) ? tobj.functionobj.offsetx : tooltipinfo.offsetX;
var offsetY = (tobj.functionobj && ((typeof tobj.functionobj.offsety) == "number")) ? tobj.functionobj.offsety : tooltipinfo.offsetY;
tooltipinfo.popupElement = document.createElement("div");
if (scc.TDpopupElementClass) tooltipinfo.popupElement.className = scc.TDpopupElementClass;
SocialCalc.setStyles(tooltipinfo.popupElement, scc.TDpopupElementStyle);
tooltipinfo.popupElement.innerHTML = tobj.tiptext;
if (tooltipinfo.clientX > tooltipinfo.viewport.width/2) { // on right side of screen
tooltipinfo.popupElement.style.bottom = (tooltipinfo.viewport.height - tooltipinfo.clientY + offsetY)+"px";
tooltipinfo.popupElement.style.right = (tooltipinfo.viewport.width - tooltipinfo.clientX + offsetX)+"px";
}
else { // on left side of screen
tooltipinfo.popupElement.style.bottom = (tooltipinfo.viewport.height - tooltipinfo.clientY + offsetY)+"px";
tooltipinfo.popupElement.style.left = (tooltipinfo.clientX + offsetX)+"px";
}
if (tooltipinfo.clientY < 50) { // make sure fits on screen if nothing above grid
tooltipinfo.popupElement.style.bottom = (tooltipinfo.viewport.height - tooltipinfo.clientY + offsetY - 50)+"px";
}
document.body.appendChild(tooltipinfo.popupElement);
}
//
// TooltipHide()
//
SocialCalc.TooltipHide = function() {
socialcalc/socialcalctableeditor.js view on Meta::CPAN
buttoninfo.doingHover = false;
}
if (bobj && bobj.functionobj && bobj.functionobj.MouseOut) bobj.functionobj.MouseOut(e, buttoninfo, bobj);
return;
}
//
// ButtonMouseDown(event)
//
SocialCalc.ButtonMouseDown = function(event) {
var e = event || window.event;
var buttoninfo = SocialCalc.ButtonInfo;
var viewportinfo = SocialCalc.GetViewportInfo();
var bobj = SocialCalc.LookupElement(e.target || e.srcElement, buttoninfo.registeredElements);
if (!bobj) return; // not one of our elements
if (bobj && bobj.functionobj && bobj.functionobj.Disabled) {
if (bobj.functionobj.Disabled(e, buttoninfo, bobj)) {
return;
}
}
buttoninfo.buttonElement = bobj;
buttoninfo.buttonDown = true;
SocialCalc.setStyles(bobj.element, buttoninfo.buttonElement.downstyle);
// Register event handler for mouse up
// Event code from JavaScript, Flanagan, 5th Edition, pg. 422
if (document.addEventListener) { // DOM Level 2 -- Firefox, et al
document.addEventListener("mouseup", SocialCalc.ButtonMouseUp, true); // capture everywhere
}
else if (bobj.element.attachEvent) { // IE 5+
bobj.element.setCapture();
bobj.element.attachEvent("onmouseup", SocialCalc.ButtonMouseUp);
bobj.element.attachEvent("onlosecapture", SocialCalc.ButtonMouseUp);
}
if (e.stopPropagation) e.stopPropagation(); // DOM Level 2
else e.cancelBubble = true; // IE 5+
if (e.preventDefault) e.preventDefault(); // DOM Level 2
else e.returnValue = false; // IE 5+
buttoninfo.horizontalScroll = viewportinfo.horizontalScroll;
buttoninfo.verticalScroll = viewportinfo.verticalScroll;
buttoninfo.clientX = e.clientX + buttoninfo.horizontalScroll; // get document-relative coordinates
buttoninfo.clientY = e.clientY + buttoninfo.verticalScroll;
if (bobj && bobj.functionobj && bobj.functionobj.MouseDown) bobj.functionobj.MouseDown(e, buttoninfo, bobj);
if (bobj.repeatwait) { // if a repeat wait is set, then starting waiting for first repetition
buttoninfo.timer = window.setTimeout(SocialCalc.ButtonRepeat, bobj.repeatwait);
}
return;
}
//
// ButtonMouseUp(event)
//
SocialCalc.ButtonMouseUp = function(event) {
var e = event || window.event;
var buttoninfo = SocialCalc.ButtonInfo;
var bobj = buttoninfo.buttonElement;
if (buttoninfo.timer) { // if repeating, cancel it
window.clearTimeout(buttoninfo.timer); // cancel timer
buttoninfo.timer = null;
}
if (!buttoninfo.buttonDown) return; // already did this (e.g., in IE, releaseCapture fires losecapture)
if (e.stopPropagation) e.stopPropagation(); // DOM Level 2
else e.cancelBubble = true; // IE 5+
if (e.preventDefault) e.preventDefault(); // DOM Level 2
else e.returnValue = false; // IE 5+
if (document.removeEventListener) { // DOM Level 2
document.removeEventListener("mouseup", SocialCalc.ButtonMouseUp, true);
}
else if (document.detachEvent) { // IE
bobj.element.detachEvent("onlosecapture", SocialCalc.ButtonMouseUp);
bobj.element.detachEvent("onmouseup", SocialCalc.ButtonMouseUp);
bobj.element.releaseCapture();
}
if (buttoninfo.buttonElement.downstyle) {
if (buttoninfo.doingHover)
SocialCalc.setStyles(bobj.element, buttoninfo.buttonElement.hoverstyle);
else
SocialCalc.setStyles(bobj.element, buttoninfo.buttonElement.normalstyle);
}
buttoninfo.buttonDown = false;
if (bobj && bobj.functionobj && bobj.functionobj.MouseUp) bobj.functionobj.MouseUp(e, buttoninfo, bobj);
}
//
// ButtonRepeat()
//
SocialCalc.ButtonRepeat = function() {
var buttoninfo = SocialCalc.ButtonInfo;
var bobj = buttoninfo.buttonElement;
if (!bobj) return;
if (bobj && bobj.functionobj && bobj.functionobj.Repeat) bobj.functionobj.Repeat(null, buttoninfo, bobj);
buttoninfo.timer = window.setTimeout(SocialCalc.ButtonRepeat, bobj.repeatinterval || 100);
}
// *************************************
//
// MouseWheel functions:
//
// *************************************
SocialCalc.MouseWheelInfo = {
// There is only one of these -- no "new" is done.
// The mousewheel only affects the one area the mouse pointer is over
// The registeredElements array is used to identify items.
// One item for each element to respond to the mousewheel, each an object with:
// .element, .functionobj
registeredElements: []
}
//
// MouseWheelRegister(element, functionobj) - make element respond to mousewheel
//
SocialCalc.MouseWheelRegister = function(element, functionobj) {
var mousewheelinfo = SocialCalc.MouseWheelInfo;
mousewheelinfo.registeredElements.push(
{element: element, functionobj: functionobj}
);
if (element.addEventListener) { // DOM Level 2 -- Firefox, et al
element.addEventListener("DOMMouseScroll", SocialCalc.ProcessMouseWheel, false);
element.addEventListener("mousewheel", SocialCalc.ProcessMouseWheel, false); // Opera needs this
}
else if (element.attachEvent) { // IE 5+
element.attachEvent("onmousewheel", SocialCalc.ProcessMouseWheel);
}
else { // don't handle this
throw SocialCalc.Constants.s_BrowserNotSupported;
}
return;
}
SocialCalc.ProcessMouseWheel = function(e) {
var event = e || window.event;
var delta;
if (SocialCalc.Keyboard.passThru) return; // ignore
var mousewheelinfo = SocialCalc.MouseWheelInfo;
var ele = event.target || event.srcElement; // source object is often within what we want
var wobj;
( run in 1.898 second using v1.01-cache-2.11-cpan-39bf76dae61 )