App-SocialCalc-Multiplayer
view release on metacpan or search on metacpan
socialcalc/socialcalc-3.js view on Meta::CPAN
SocialCalc.Callbacks = {
// The next two are used by SocialCalc.format_text_for_display
// The function to expand wiki text - should be set if you want wikitext expansion
// The form is: expand_wiki(displayvalue, sheetobj, linkstyle, valueformat)
// valueformat is text-wiki followed by optional sub-formats, e.g., text-wikipagelink
expand_wiki: null,
expand_markup: function(displayvalue, sheetobj, linkstyle) // the old function to expand wiki text - may be replaced
{return SocialCalc.default_expand_markup(displayvalue, sheetobj, linkstyle);},
// MakePageLink is used to create the href for a link to another "page"
// The form is: MakePageLink(pagename, workspacename, linktyle, valueformat), returns string
MakePageLink: null,
// NormalizeSheetName is used to make different variations of sheetnames use the same cache slot
NormalizeSheetName: null // use default - lowercase
};
// Shared flags
// none at present
// *************************************
//
// Cell class:
//
// *************************************
//
// Class SocialCalc.Cell
//
// Usage: var s = new SocialCalc.Cell(coord);
//
// Cell attributes include:
//
// coord: the column/row as a string, e.g., "A1"
// datavalue: the value to be used for computation and formatting for display,
// string or numeric (tolerant of numbers stored as strings)
// datatype: if present, v=numeric value, t=text value, f=formula,
// or c=constant that is not a simple number (like "$1.20")
// formula: if present, the formula (without leading "=") for computation or the constant
// valuetype: first char is main type, the following are sub-types.
// Main types are b=blank cell, n=numeric, t=text, e=error
// Examples of using sub-types would be "nt" for a numeric time value, "n$" for currency, "nl" for logical
// displayvalue: if present, rendered version of datavalue with formatting attributes applied
// parseinfo: if present, cached parsed version of formula
//
// The following optional values, if present, are mainly used in rendering, overriding defaults:
//
// bt, br, bb, bl: number of border's definition
// layout: layout (vertical alignment, padding) definition number
// font: font definition number
// color: text color definition number
// bgcolor: background color definition number
// cellformat: cell format (horizontal alignment) definition number
// nontextvalueformat: custom format definition number for non-text values, e.g., numbers
// textvalueformat: custom format definition number for text values
// colspan, rowspan: number of cells to span for merged cells (only on main cell)
// cssc: custom css classname for cell, as text (no special chars)
// csss: custom css style definition
// mod: modification allowed flag "y" if present
// comment: cell comment string
//
SocialCalc.Cell = function(coord) {
this.coord = coord;
this.datavalue = "";
this.datatype = null;
this.formula = "";
this.valuetype = "b";
}
// The types of cell properties
//
// Type 1: Base, Type 2: Attribute, Type 3: Special (e.g., displaystring, parseinfo)
SocialCalc.CellProperties = {
coord: 1, datavalue: 1, datatype: 1, formula: 1, valuetype: 1, errors: 1, comment: 1,
bt: 2, br: 2, bb: 2, bl: 2, layout: 2, font: 2, color: 2, bgcolor: 2,
cellformat: 2, nontextvalueformat: 2, textvalueformat: 2, colspan: 2, rowspan: 2,
cssc: 2, csss: 2, mod: 2,
displaystring: 3, // used to cache rendered HTML of cell contents
parseinfo: 3, // used to cache parsed formulas
hcolspan: 3, hrowspan: 3 // spans taking hidden cols/rows into account (!!! NOT YET !!!)
};
SocialCalc.CellPropertiesTable = {
bt: "borderstyle", br: "borderstyle", bb: "borderstyle", bl: "borderstyle",
layout: "layout", font: "font", color: "color", bgcolor: "color",
cellformat: "cellformat", nontextvalueformat: "valueformat", textvalueformat: "valueformat"
};
// *************************************
//
// Sheet class:
//
// *************************************
//
// Class SocialCalc.Sheet
//
// Usage: var s = new SocialCalc.Sheet();
//
SocialCalc.Sheet = function() {
SocialCalc.ResetSheet(this);
// Set other values:
//
// sheet.statuscallback(data, status, arg, this.statuscallbackparams) is called
// during recalc and commands.
socialcalc/socialcalc-3.js view on Meta::CPAN
sheet.copiedfrom = ""; // if a range, then this was loaded from a saved range as clipboard content
sheet.changes = new SocialCalc.UndoStack();
sheet.renderneeded = false;
sheet.changedrendervalues = true; // if true, spans and/or fonts have changed (set by ExecuteSheetCommand & GetStyle)
sheet.recalcchangedavalue = false; // true if a recalc resulted in a change to a cell's calculated value
}
// Methods:
SocialCalc.Sheet.prototype.ResetSheet = function() {SocialCalc.ResetSheet(this);};
SocialCalc.Sheet.prototype.AddCell = function(newcell) {return this.cells[newcell.coord]=newcell;};
SocialCalc.Sheet.prototype.GetAssuredCell = function(coord) {
return this.cells[coord] || this.AddCell(new SocialCalc.Cell(coord));
};
SocialCalc.Sheet.prototype.ParseSheetSave = function(savedsheet) {SocialCalc.ParseSheetSave(savedsheet,this);};
SocialCalc.Sheet.prototype.CellFromStringParts = function(cell, parts, j) {return SocialCalc.CellFromStringParts(this, cell, parts, j);};
SocialCalc.Sheet.prototype.CreateSheetSave = function(range, canonicalize) {return SocialCalc.CreateSheetSave(this, range, canonicalize);};
SocialCalc.Sheet.prototype.CellToString = function(cell) {return SocialCalc.CellToString(this, cell);};
SocialCalc.Sheet.prototype.CanonicalizeSheet = function(full) {return SocialCalc.CanonicalizeSheet(this, full);};
SocialCalc.Sheet.prototype.EncodeCellAttributes = function(coord) {return SocialCalc.EncodeCellAttributes(this, coord);};
SocialCalc.Sheet.prototype.EncodeSheetAttributes = function() {return SocialCalc.EncodeSheetAttributes(this);};
SocialCalc.Sheet.prototype.DecodeCellAttributes = function(coord, attribs, range) {return SocialCalc.DecodeCellAttributes(this, coord, attribs, range);};
SocialCalc.Sheet.prototype.DecodeSheetAttributes = function(attribs) {return SocialCalc.DecodeSheetAttributes(this, attribs);};
SocialCalc.Sheet.prototype.ScheduleSheetCommands = function(cmd, saveundo, isRemote) {return SocialCalc.ScheduleSheetCommands(this, cmd, saveundo, isRemote);};
SocialCalc.Sheet.prototype.SheetUndo = function() {return SocialCalc.SheetUndo(this);};
SocialCalc.Sheet.prototype.SheetRedo = function() {return SocialCalc.SheetRedo(this);};
SocialCalc.Sheet.prototype.CreateAuditString = function() {return SocialCalc.CreateAuditString(this);};
SocialCalc.Sheet.prototype.GetStyleNum = function(atype, style) {return SocialCalc.GetStyleNum(this, atype, style);};
SocialCalc.Sheet.prototype.GetStyleString = function(atype, num) {return SocialCalc.GetStyleString(this, atype, num);};
SocialCalc.Sheet.prototype.RecalcSheet = function() {return SocialCalc.RecalcSheet(this);};
//
// Sheet save format:
//
// linetype:param1:param2:...
//
// Linetypes are:
//
// version:versionname - version of this format. Currently 1.4.
//
// cell:coord:type:value...:type:value... - Types are as follows:
//
// v:value - straight numeric value
// t:value - straight text/wiki-text in cell, encoded to handle \, :, newlines
// vt:fulltype:value - value with value type/subtype
// vtf:fulltype:value:formulatext - formula resulting in value with value type/subtype, value and text encoded
// vtc:fulltype:value:valuetext - formatted text constant resulting in value with value type/subtype, value and text encoded
// vf:fvalue:formulatext - formula resulting in value, value and text encoded (obsolete: only pre format version 1.1)
// fvalue - first char is "N" for numeric value, "T" for text value, "H" for HTML value, rest is the value
// e:errortext - Error text. Non-blank means formula parsing/calculation results in error.
// b:topborder#:rightborder#:bottomborder#:leftborder# - border# in sheet border list or blank if none
// l:layout# - number in cell layout list
// f:font# - number in sheet fonts list
// c:color# - sheet color list index for text
// bg:color# - sheet color list index for background color
// cf:format# - sheet cell format number for explicit format (align:left, etc.)
// cvf:valueformat# - sheet cell value format number (obsolete: only pre format v1.2)
// tvf:valueformat# - sheet cell text value format number
// ntvf:valueformat# - sheet cell non-text value format number
// colspan:numcols - number of columns spanned in merged cell
// rowspan:numrows - number of rows spanned in merged cell
// cssc:classname - name of CSS class to be used for cell when published instead of one calculated here
// csss:styletext - explicit CSS style information, encoded to handle :, etc.
// mod:allow - if "y" allow modification of cell for live "view" recalc
// comment:value - encoded text of comment for this cell (added in v1.5)
//
// col:
// w:widthval - number, "auto" (no width in <col> tag), number%, or blank (use default)
// hide: - yes/no, no is assumed if missing
// row:
// hide - yes/no, no is assumed if missing
//
// sheet:
// c:lastcol - number
// r:lastrow - number
// w:defaultcolwidth - number, "auto", number%, or blank (default->80)
// h:defaultrowheight - not used
// tf:format# - cell format number for sheet default for text values
// ntf:format# - cell format number for sheet default for non-text values (i.e., numbers)
// layout:layout# - default cell layout number in cell layout list
// font:font# - default font number in sheet font list
// vf:valueformat# - default number value format number in sheet valueformat list (obsolete: only pre format version 1.2)
// ntvf:valueformat# - default non-text (number) value format number in sheet valueformat list
// tvf:valueformat# - default text value format number in sheet valueformat list
// color:color# - default number for text color in sheet color list
// bgcolor:color# - default number for background color in sheet color list
// circularreferencecell:coord - cell coord with a circular reference
// recalc:value - on/off (on is default). If not "off", appropriate changes to the sheet cause a recalc
// needsrecalc:value - yes/no (no is default). If "yes", formula values are not up to date
//
// name:name:description:value - name definition, name in uppercase, with value being "B5", "A1:B7", or "=formula";
// description and value are encoded.
// font:fontnum:value - text of font definition (style weight size family) for font fontnum
// "*" for "style weight", size, or family, means use default (first look to sheet, then builtin)
// color:colornum:rgbvalue - text of color definition (e.g., rgb(255,255,255)) for color colornum
// border:bordernum:value - text of border definition (thickness style color) for border bordernum
// layout:layoutnum:value - text of vertical alignment and padding style for cell layout layoutnum (* for default):
// vertical-alignment:vavalue;padding:topval rightval bottomval leftval;
// cellformat:cformatnum:value - text of cell alignment (left/center/right) for cellformat cformatnum
// valueformat:vformatnum:value - text of number format (see FormatValueForDisplay) for valueformat vformatnum (changed in v1.2)
// clipboardrange:upperleftcoord:bottomrightcoord - ignored -- from wikiCalc
// clipboard:coord:type:value:... - ignored -- from wikiCalc
//
// If this is clipboard contents, then there is also information to facilitate pasting:
//
// copiedfrom:upperleftcoord:bottomrightcoord - range from which this was copied
//
// Functions:
SocialCalc.ParseSheetSave = function(savedsheet,sheetobj) {
var lines=savedsheet.split(/\r\n|\n/);
var parts=[];
var line;
var i, j, t, v, coord, cell, attribs, name;
var scc = SocialCalc.Constants;
for (i=0;i<lines.length;i++) {
line=lines[i];
parts = line.split(":");
switch (parts[0]) {
case "cell":
cell=sheetobj.GetAssuredCell(parts[1]);
j=2;
sheetobj.CellFromStringParts(cell, parts, j);
break;
case "col":
coord=parts[1];
j=2;
while (t=parts[j++]) {
switch (t) {
case "w":
sheetobj.colattribs.width[coord]=parts[j++]; // must be text - could be auto or %, etc.
break;
case "hide":
sheetobj.colattribs.hide[coord]=parts[j++];
break;
default:
throw scc.s_pssUnknownColType+" '"+t+"'";
break;
}
}
break;
socialcalc/socialcalc-3.js view on Meta::CPAN
}
else ttext = '"' + ttext + '"';
}
updatedformula += ttext;
}
return updatedformula;
}
// ************************
//
// Recalc Loop Code
//
// ************************
//
// How recalc works:
//
// !!!!!!!!!!!!!!
//
// SocialCalc.RecalcInfo - object with global recalc info
SocialCalc.RecalcInfo = {
sheet: null, // which sheet is being recalced
currentState: 0, // current state
state: {start_calc: 1, order: 2, calc: 3, start_wait: 4, done_wait: 5}, // allowed state values
recalctimer: null, // value to cancel timer
maxtimeslice: 100, // maximum milliseconds per slice of recalc time before a wait
timeslicedelay: 1, // milliseconds to wait between recalc time slices
starttime: 0, // when recalc started
// LoadSheet: a function that returns true if started a load or false if not.
//
LoadSheet: function(sheetname) {return false;} // default returns not found
}
// SocialCalc.RecalcData - object with recalc info while determining recalc order and afterward
SocialCalc.RecalcData = function() { // initialize a RecalcData object
this.inrecalc = true; // if true, doing a recalc
this.celllist = []; // list with all potential cells to calculate
this.celllistitem = 0; // cell to check next when ordering
this.calclist = null; // object which is the chained list of cells to calculate
// each in the form of "coord: nextcoord"
// e.g., if B8 is calculated right after A8, then calclist.A8=="B8"
// if null, need to create the list
this.calclistlength = 0; // number of items in calclist
this.firstcalc = null; // start of the calc list - a string or null
this.lastcalc = null; // last one on chain (used to add more to the end)
this.nextcalc = null; // used to keep track during background recalc to make it restartable
this.count = 0; // number calculated
// checkinfo is used when determining calc order:
this.checkinfo = {}; // attributes are coords; if no attrib for a coord, it wasn't checked or doesn't need it
// values are RecalcCheckInfo objects while checking or TRUE when complete
}
// SocialCalc.RecalcCheckInfo - object that stores checking info while determining recalc order
SocialCalc.RecalcCheckInfo = function() { // initialize a RecalcCheckInfo object
this.oldcoord = null; // chain back up of cells referring to cells
this.parsepos = 0; // which token we are up to
// range info
this.inrange = false; // if true, in the process of checking a range of coords
this.inrangestart = false; // if true, have not yet filled in range loop values
this.cr1 = null; // range first coord as a cr object
this.cr2 = null; // range second coord as a cr object
this.c1 = null; // range extents
this.c2 = null;
this.r1 = null;
this.r2 = null;
this.c = null; // looping values
this.r = null;
}
// Recalc the entire sheet
SocialCalc.RecalcSheet = function(sheet) {
var coord, err, recalcdata;
var scri = SocialCalc.RecalcInfo;
delete sheet.attribs.circularreferencecell; // reset recalc-wide things
SocialCalc.Formula.FreshnessInfoReset();
SocialCalc.RecalcClearTimeout();
scri.sheet = sheet; // set values needed by background recalc
scri.currentState = scri.state.start_calc;
scri.starttime = new Date();
if (sheet.statuscallback) {
sheet.statuscallback(scri, "calcstart", null, sheet.statuscallbackparams);
}
SocialCalc.RecalcSetTimeout();
}
//
// SocialCalc.RecalcSetTimeout - set a timer for next recalc step
//
SocialCalc.RecalcSetTimeout = function() {
var scri = SocialCalc.RecalcInfo;
scri.recalctimer = window.setTimeout(SocialCalc.RecalcTimerRoutine, scri.timeslicedelay);
}
//
// SocialCalc.RecalcClearTimeout - cancel any timeouts
//
SocialCalc.RecalcClearTimeout = function() {
var scri = SocialCalc.RecalcInfo;
if (scri.recalctimer) {
window.clearTimeout(scri.recalctimer);
scri.recalctimer = null;
}
}
//
// SocialCalc.RecalcLoadedSheet(sheetname, str, recalcneeded)
//
// Called when a sheet finishes loading with name, string, and t/f whether it should be recalced.
// If loaded sheet has sheet.attribs.recalc=="off", then no recalc done.
// If sheetname is null, then the sheetname waiting for will be used.
//
SocialCalc.RecalcLoadedSheet = function(sheetname, str, recalcneeded) {
var sheet;
var scri = SocialCalc.RecalcInfo;
var scf = SocialCalc.Formula;
sheet = SocialCalc.Formula.AddSheetToCache(sheetname || scf.SheetCache.waitingForLoading, str);
if (recalcneeded && sheet && sheet.attribs.recalc!="off") { // if recalcneeded, and not manual sheet, chain in this new sheet to recalc loop
sheet.previousrecalcsheet = scri.sheet;
scri.sheet = sheet;
scri.currentState = scri.state.start_calc;
}
scf.SheetCache.waitingForLoading = null;
SocialCalc.RecalcSetTimeout();
}
//
// SocialCalc.RecalcTimerRoutine - handles the actual order determination and cell-by-cell recalculation in the background
//
SocialCalc.RecalcTimerRoutine = function() {
var eresult, cell, coord, err, status;
var starttime = new Date();
var count = 0;
var scf = SocialCalc.Formula;
if (!scf) {
return "Need SocialCalc.Formula";
}
var scri = SocialCalc.RecalcInfo;
var sheet = scri.sheet;
if (!sheet) {
return;
}
var recalcdata = sheet.recalcdata;
var do_statuscallback = function(status, arg) { // routine to do callback if required
if (sheet.statuscallback) {
sheet.statuscallback(recalcdata, status, arg, sheet.statuscallbackparams);
}
}
SocialCalc.RecalcClearTimeout();
if (scri.currentState == scri.state.start_calc) {
recalcdata = new SocialCalc.RecalcData();
sheet.recalcdata = recalcdata;
for (coord in sheet.cells) { // get list of cells to check for order
if (!coord) continue;
recalcdata.celllist.push(coord);
}
recalcdata.calclist = {}; // start with empty list
scri.currentState = scri.state.order; // drop through to determining recalc order
}
if (scri.currentState == scri.state.order) {
while (recalcdata.celllistitem < recalcdata.celllist.length) { // check all the cells to see if they should be on the list
coord = recalcdata.celllist[recalcdata.celllistitem++];
err = SocialCalc.RecalcCheckCell(sheet, coord);
if (((new Date()) - starttime) >= scri.maxtimeslice) { // if taking too long, give up CPU for a while
do_statuscallback("calcorder", {coord: coord, total: recalcdata.celllist.length, count: recalcdata.celllistitem});
SocialCalc.RecalcSetTimeout();
return;
}
}
do_statuscallback("calccheckdone", recalcdata.calclistlength);
recalcdata.nextcalc = recalcdata.firstcalc; // start at the beginning of the recalc chain
scri.currentState = scri.state.calc; // loop through cells on next timer call
SocialCalc.RecalcSetTimeout();
return;
}
if (scri.currentState == scri.state.start_wait) { // starting to wait for something
socialcalc/socialcalc-3.js view on Meta::CPAN
}
// *************************************
//
// Clipboard Object:
//
// This is a single object.
// Stores the clipboard, which is shared by all active sheets.
// Like the undo stack, it does not persist from one editing session to another.
//
// *************************************
SocialCalc.Clipboard = {
// properties:
clipboard: "" // empty or string in save format with "copiedfrom:" set to a range
}
// *************************************
//
// RenderContext class:
//
// *************************************
SocialCalc.RenderContext = function(sheetobj) {
var parts, num, s;
var attribs = sheetobj.attribs;
var scc = SocialCalc.Constants;
// properties:
this.sheetobj = sheetobj;
this.hideRowsCols = false; // Rendering with panes only works with "false"
// !!!! Note: not implemented yet in rendering, just saved as an attribute
this.showGrid = false;
this.showRCHeaders = false;
this.rownamewidth = scc.defaultRowNameWidth;
this.pixelsPerRow = scc.defaultAssumedRowHeight;
this.cellskip = {}; // if present, coord of cell covering this cell
this.coordToCR = {}; // for cells starting spans, coordToCR[coord]={row:row, col:col}
this.colwidth = []; // precomputed column widths, taking into account defaults
this.totalwidth = 0; // precomputed total table width
this.rowpanes = []; // for each pane, {first: firstrow, last: lastrow}
this.colpanes = []; // for each pane, {first: firstrow, last: lastrow}
this.maxcol=0; // max col and row to display, adding long spans, etc.
this.maxrow=0;
this.highlights = {}; // for each cell with special display: coord:highlightType (see this.highlightTypes)
this.cursorsuffix = ""; // added to highlights[cr]=="cursor" to get type to lookup
this.highlightTypes = // attributes to change when highlit
{
cursor: {style: scc.defaultHighlightTypeCursorStyle, className: scc.defaultHighlightTypeCursorClass},
range: {style: scc.defaultHighlightTypeRangeStyle, className: scc.defaultHighlightTypeRangeClass},
cursorinsertup: {style: "color:#FFF;backgroundColor:#A6A6A6;backgroundRepeat:repeat-x;backgroundPosition:top left;backgroundImage:url("+scc.defaultImagePrefix+"cursorinsertup.gif);", className: scc.defaultHighlightTypeCursorClass},
cursorinsertleft: {style: "color:#FFF;backgroundColor:#A6A6A6;backgroundRepeat:repeat-y;backgroundPosition:top left;backgroundImage:url("+scc.defaultImagePrefix+"cursorinsertleft.gif);", className: scc.defaultHighlightTypeCursorClass},
range2: {style: "color:#000;backgroundColor:#FFF;backgroundImage:url("+scc.defaultImagePrefix+"range2.gif);", className: ""}
}
this.cellIDprefix = scc.defaultCellIDPrefix; // if non-null, each cell will render with an ID
this.defaultlinkstyle = null; // default linkstyle object (allows you to pass values to link renderer)
this.defaultHTMLlinkstyle = {type: "html"}; // default linkstyle for standalone HTML
// constants:
this.defaultfontstyle = scc.defaultCellFontStyle;
this.defaultfontsize = scc.defaultCellFontSize;
this.defaultfontfamily = scc.defaultCellFontFamily;
this.defaultlayout = scc.defaultCellLayout;
this.defaultpanedividerwidth = scc.defaultPaneDividerWidth;
this.defaultpanedividerheight = scc.defaultPaneDividerHeight;
this.gridCSS = scc.defaultGridCSS;
this.commentClassName = scc.defaultCommentClass; // for cells with non-blank comments when this.showGrid is true
this.commentCSS = scc.defaultCommentStyle; // any combination of classnames and styles may be used
this.commentNoGridClassName = scc.defaultCommentNoGridClass; // for cells when this.showGrid is false
this.commentNoGridCSS = scc.defaultCommentNoGridStyle; // any combination of classnames and styles may be used
this.classnames = // any combination of classnames and explicitStyles can be used
{
colname: scc.defaultColnameClass,
rowname: scc.defaultRownameClass,
selectedcolname: scc.defaultSelectedColnameClass,
selectedrowname: scc.defaultSelectedRownameClass,
upperleft: scc.defaultUpperLeftClass,
skippedcell: scc.defaultSkippedCellClass,
panedivider: scc.defaultPaneDividerClass
};
this.explicitStyles = // these may be used so you won't need a stylesheet with the classnames
{
colname: scc.defaultColnameStyle,
rowname: scc.defaultRownameStyle,
selectedcolname: scc.defaultSelectedColnameStyle,
selectedrowname: scc.defaultSelectedRownameStyle,
upperleft: scc.defaultUpperLeftStyle,
skippedcell: scc.defaultSkippedCellStyle,
panedivider: scc.defaultPaneDividerStyle
};
// processed info about cell skipping
this.cellskip = null;
this.needcellskip = true;
// precomputed values, filling in defaults indicated by "*"
this.fonts=[]; // for each fontnum, {style: fs, weight: fw, size: fs, family: ff}
this.layouts=[]; // for each layout, "padding:Tpx Rpx Bpx Lpx;vertical-align:va;"
this.needprecompute = true; // need to call PrecomputeSheetFontsAndLayouts
// if have a sheet object, initialize constants and precomputed values
socialcalc/socialcalc-3.js view on Meta::CPAN
if (!cell) {
cell=new SocialCalc.Cell(coord);
}
sheetattribs=sheetobj.attribs;
scc=SocialCalc.Constants;
if (cell.colspan>1) {
span=1;
for (num=1; num<cell.colspan; num++) {
if (sheetobj.colattribs.hide[SocialCalc.rcColname(colnum+num)]!="yes" &&
context.CellInPane(rownum, colnum+num, rowpane, colpane)) {
span++;
}
}
result.colSpan=span;
}
if (cell.rowspan>1) {
span=1;
for (num=1; num<cell.rowspan; num++) {
if (sheetobj.rowattribs.hide[(rownum+num)+""]!="yes" &&
context.CellInPane(rownum+num, colnum, rowpane, colpane))
span++;
}
result.rowSpan=span;
}
if (cell.displaystring==undefined) { // cache the display value
cell.displaystring = SocialCalc.FormatValueForDisplay(sheetobj, cell.datavalue, coord, (linkstyle || context.defaultlinkstyle));
}
result.innerHTML = cell.displaystring;
num=cell.layout || sheetattribs.defaultlayout;
if (num) {
stylestr+=context.layouts[num]; // use precomputed layout with "*"'s filled in
}
else {
stylestr+=scc.defaultCellLayout;
}
num=cell.font || sheetattribs.defaultfont;
if (num) { // get expanded font strings in context
t = context.fonts[num]; // do each - plain "font:" style sets all sorts of other values, too (Safari font-stretch problem on cssText)
stylestr+="font-style:"+t.style+";font-weight:"+t.weight+";font-size:"+t.size+";font-family:"+t.family+";";
}
else {
if (scc.defaultCellFontSize) {
stylestr+="font-size:"+scc.defaultCellFontSize+";";
}
if (scc.defaultCellFontFamily) {
stylestr+="font-family:"+scc.defaultCellFontFamily+";";
}
}
num=cell.color || sheetattribs.defaultcolor;
if (num) stylestr+="color:"+sheetobj.colors[num]+";";
num=cell.bgcolor || sheetattribs.defaultbgcolor;
if (num) stylestr+="background-color:"+sheetobj.colors[num]+";";
num=cell.cellformat;
if (num) {
stylestr+="text-align:"+sheetobj.cellformats[num]+";";
}
else {
t=cell.valuetype.charAt(0);
if (t=="t") {
num=sheetattribs.defaulttextformat;
if (num) stylestr+="text-align:"+sheetobj.cellformats[num]+";";
}
else if (t="n") {
num=sheetattribs.defaultnontextformat;
if (num) {
stylestr+="text-align:"+sheetobj.cellformats[num]+";";
}
else {
stylestr+="text-align:right;";
}
}
else stylestr+="text-align:left;";
}
num=cell.bt;
if (num) stylestr+="border-top:"+sheetobj.borderstyles[num]+";";
num=cell.br;
if (num) stylestr+="border-right:"+sheetobj.borderstyles[num]+";";
else if (context.showGrid) {
if (context.CellInPane(rownum, colnum+(cell.colspan || 1), rowpane, colpane))
t=SocialCalc.crToCoord(colnum+(cell.colspan || 1), rownum);
else t="nomatch";
if (context.cellskip[t]) t=context.cellskip[t];
if (!sheetobj.cells[t] || !sheetobj.cells[t].bl)
stylestr+="border-right:"+context.gridCSS;
}
num=cell.bb;
if (num) stylestr+="border-bottom:"+sheetobj.borderstyles[num]+";";
else if (context.showGrid) {
if (context.CellInPane(rownum+(cell.rowspan || 1), colnum, rowpane, colpane))
t=SocialCalc.crToCoord(colnum, rownum+(cell.rowspan || 1));
else t="nomatch";
if (context.cellskip[t]) t=context.cellskip[t];
if (!sheetobj.cells[t] || !sheetobj.cells[t].bt)
stylestr+="border-bottom:"+context.gridCSS;
}
num=cell.bl;
if (num) stylestr+="border-left:"+sheetobj.borderstyles[num]+";";
if (cell.comment) {
if (context.showGrid) {
if (context.commentClassName) {
result.className = (result.className ? result.className+" " : "") + context.commentClassName;
}
stylestr+=context.commentCSS;
}
else {
if (context.commentNoGridClassName) {
( run in 1.981 second using v1.01-cache-2.11-cpan-97f6503c9c8 )