ONLYOFFICE. The naked truth about the source code of the cloud office


In early July Teamlab renamed in ONLYOFFICE and fully opened the source code of your application, including online document editors, co-authoring, Gantt chart and invoicing functionality.
In two weeks we received a lot of questions on this subject, therefore, the rights of the employee will undertake to explain what was happening. If you don't have time to read a post, download installation of ONLYOFFICE distributed Sourceforge. Expand on your server. Ready! You have your cloud office. You are gorgeous.

Why Teamlab has become a ONLYOFFICE

the Idea of rebranding has existed for quite some time. In his blog, we wrote a post about why we have chosen ONLY the quality of the new consoles to your office, however, was quite specific reasons. First, the name of Teamlab has ceased to reflect the idea of the product, because "team" is associated with a small team, while among our clients are increasingly of the company's 300 and 400 people. Second, besides us, unfortunately, this word was chosen by the designers of interactive hangers in Japan.

Why we released the source code (Honesty is the best policy because)

the Main reason is, of course, trust. Not only from customers but also from our partners. In the current situation, we get quite a lot of questions about the security of corporate data, especially from overseas customers. Posting code ONLYOFFICE on Sourceforge and GitHub, we are taking another step towards them.

license

Publishing the source code of your product, we pursued several goals:
the
    the
  • to Attract the attention of the opensource community.
  • the
  • to Fix the authorship of the product.
  • the
  • to Strengthen the confidence of foreign customers and partners.

After weighing all the pros and cons, we chose AGPL v3. In a nutshell it means the following: you can use ONLYOFFICE in the company free and without restrictions, but if you want to embed our code in your own application, you will have to open source their product under the same license. Read more here.

What our programmers

Proceed to the most interesting part of our post. Open Source version of ONLYOFFICE is preparing to release quite a long time — one of only a text editor contains more than 500 000 lines of code! Of course, we have much to tell:

Special attention to Internet Explorer
the Basis of the algorithm of rasterization is taken from freetype, as it is a quality, time tested outdoor type: engine. The algorithms slightly changed to speed of execution was higher than it is in the browser, since we write in javascript.

Here, for example, a cache of letters we had to write in two flavors: Internet Explorer and everyone else. Due to the nature of the browser in IE first implementation was slow.
Oleg, lead programmer

What do you know about the width of columns in Excel?
There are two main scenarios for using Excel:
the
    the
  • financial calculations
  • the
  • creation of forms (invoices) for further filling and printing.

A large number of forms were created before the advent of our table editor, so our task was not only to learn how to open them, but to correctly calculate the width of columns and height of rows. Otherwise, when you print the form could not get the sheet.
For example, a standard column width in Microsoft Excel is 8.43 characters (characters). It is calculated from a default width of 8 characters, which translates to pixels depending on the Normal style. Then, as it turned out, the resulting number is rounded to the nearest multiple of 8.
Another feature is the height of the row. In Excel you cannot specify the line spacing, such as in Word, so the calculation of the row height in Excel is different from the calculation of the row height in Word. For example, the comparison in the font Cambria Math 11:
In the end, we implemented the calculation so that no one character was not circumcised.
Alexander, lead programmer

How we connected dependency tree and a topological sorting
a Large part of the spreadsheet one way or another contains the formula. For solving problems of parsing and counting formulas was implemented the parser and the calculator. Also in the working with formulas, special attention deserves the dependencies between cells. For this purpose, was used by the algorithm topological sort, allowing to build the traversal order of the dependency tree.
Dmitry, programmer

Fifteen thousand tests, and 80 machines
to test the installation of ONLYOFFICE, we launched it and started the usual process. The amount has run about 15,000 tests that run on 80 machines. By the way, hostim we have them now at Digital Ocean in the near future will tell how moved the entire test structure.
Stas, head of testing Department

Hopes&Fears
I'm Afraid if we determine that our code someone borrow personal gain? No. Use code ONLYOFFICE clearly spelled out in the license, and here we are, protected by international law.
Do we think that someone "watch" and make a similar product? Of course, I think. But the guys will take at least 3 years, so we don't here too much worry. However, we have long been accustomed to reside and survive in a highly competitive environment.
Alexander, head of promotion Department

What you should your editor on the canvas to build?
Any text editor starts with breaking text lines and rendering. The first working version consisted of 150 lines of code was implemented as follows:

the
// Class ParaText
ParaText function(value)
{
this.Value = value;
this.Type = para_Text;

this.Width = 0;
this.Height = 0;
}

ParaText.prototype.Draw = function(X, Y, Context);
ParaText.prototype.Measure = function(Context);

140 lines of code
// Class ParaSpace
ParaSpace function()
{
this.Type = para_Space;

this.Width = 0;
this.Height = 0;
}

ParaSpace.prototype.Draw = function(X,Y, Context);
ParaSpace.prototype.Measure = function(Context);


// Class ParaNewLineRendered
ParaNewLineRendered function()
{
this.Type = para_NewLineRendered;
this.Width = 0;
this.Height = 0;
}

ParaNewLineRendered.prototype.Draw = function();
ParaNewLineRendered.prototype.Measure = function();

// Class Paragraph
function CParagraph()
{
//...................

// The initial shift
this.X = 0;
this.Y = 0;

// Width of the row 
this.XLimit = 0;

// Contents of the paragraph, consisting of objects of  type  ParaText, ParaSpace and ParaNewLineRendered
this.Content = new Array();

// Row height. Let us have it be the same for all rows
this.dLineHeight = 0;
//................... 
}

CParagraph.prototype.Recalculate = function()
{ 
// Preparing for the new translation. Here we delete old items ParaNewLineRendered
//..............................

// Shift to beginning of paragraph
var X = this.X, Y = this.Y;

// Calculate the paragraph 
var CurLine = 0;

var bNewLine = false;
var bFirstItemOnLine = true;
var bWord = false;
var nWordStartPos = 0;
var dWordLen = 0;

for ( var nPos = 0; nPos < this.Content.length; nPos++ )
{
var Item = this.Content[nPos];

switch( Item.Type )
{
case para_Text:
{
var dLetterLen = Item.Measure( Context ).Width;

if ( !bWord )
{
// If the word has just begun and it is on the line nothing happened, then it is not necessary to check whether it retracts on the line. 
if ( !bFirstItemOnLine )
{
if ( X + dLetterLen > this.XLimit )
{
// The first letter in the word is not out on the line, put a newline
this.Content.splice( nPos, 0, new ParaNewLineRendered() );
bNewLine = true;
}
}

if ( !bNewLine )
{
nWordStartPos = nPos;
dWordLen = dLetterLen;
bWord = true;
}
}
else
{
if ( X + dWordLen + dLetterLen > this.XLimit )
{
if ( bFirstItemOnLine )
{
// The word was the only line item and still

X += dWordLen;
this.Content.splice( nPos, 0, new ParaNewLineRendered() );

bNewLine = true;
}
else
{
// Shifted to the beginning of a word and before it put a line break
this.Content.splice( nWordStartPos, 0, new ParaNewLineRendered() );
nPos = nWordStartPos;

bNewLine = true;
}
}

if ( !bNewLine )
{
dWordLen += dLetterLen;
}
}
break;
}
case para_Space:
{
bFirstItemOnLine = false;

var dSpaceLen = Item.Measure( Canvas ).Width;
if ( bWord )
{
// No need to check whether the word is removed we check when adding letters
X += dWordLen;

bWord = false;
dWordLen = 0;
}

if ( X + dSpaceLen > this.XLimit )
{
bNewLine = true;
}
else
X += dSpaceLen;

break;
}
}

// Go to new line
if ( bNewLine )
{
bNewLine = false;
bFirstItemOnLine = true;
bWord = false;
dWordLen = 0;

// Horizontally shifted to the beginning of the paragraph, and vertically moves down by the height of the row
X = this.X;
Y += this.dLineHeight;

CurLine++;
}
}
}

CParagraph.prototype.Draw = function(Context)
{
var Y = this.Y;
var X = this.X;

var nCount = this.Content.length;
for ( var nPos = 0; nPos < nCount; nPos++ )
{
var Item = this.Content[nPos];

Item.Draw( X, Y, Context );

X += Item.Width;

if ( para_NewLineRendered == Item.Type )
{
Y += this.dLineHeight;
X = this.X;
}
}
}


Ilya, lead programmer

Two weeks after the beginning of the development was ready the first sample:


Download and test the sample here.
There is nothing nicer than to compare it with what we have achieved over several years. And at what stage are now the editors of competitors.


Test all editors without registering on the website personal.teamlab.com. They, by the way, do you actively use — it's free.

Our goal? Users of ONLYOFFICE worldwide

Plans we do have a lot. Now we are actively working on mobile and desktop applications, in addition to autumn will be released the version 3.0 of office editors, and we want to committing the design to GitHub in real time.

It seems that all. The roaming discussion in the comments)
Article based on information from habrahabr.ru

Комментарии

Популярные сообщения из этого блога

Integration of PostgreSQL with MS SQL Server for those who want faster and deeper

Custom database queries in MODx Revolution

Parse URL in Zend Framework 2