Monday, December 24, 2007

Lohika Best People

12/21/2007 we had New Year party at Lohika.

I've seen people that i really appreciate to know them.

Nazar and Yuriy Hrynyshyn (our PM)

Oleh Tomashevskyy (our QA Lead) and Andry Zrobok (our DBA)

All them are Personalities from big letters.
People that do not lie, that are sincere, that you can trust to.
People that solve the problems. People that are reliable.

Thank you all for being part of my life :).

Monday, December 3, 2007

Mozilla/Firefox Range - Part 2: setStart and collapse Methods

As the continuation of Range setEnd investigation (see first article from Range cycle) let's go on and start from the beginning: setStart method.

Range startOffset Property and setStart Method
Range collapse Method (Solves Contradiction)
Range startOffset not Existing Target
Conclusions

Range startOffset Property and setStart Method
  • range.startContainer - points to the node where the range starts
  • range.startOffset - is shift inside the startContainer to point exactly to the place where range starts
  • range.setStart(newStartContainer, newStartOffset) – sets new start boundary of the range
As opposed to range.endOffset method range.startOffset means exactly what you've thought about - is index of child node or character of range.startContainer that is the first node that belongs to the range.







In terms of
previous example here we see range.startContainer is equal to text node 'day' and dayRange.startOffset is 0 (which points to 'd' letter - the first character that belongs to dayRange).

It looks like we shouldn't have any surprises with unexpected behavior or misunderstanding of startOffset property.

But here is also same warning as in case of endOffset property:
As it turns out node or character that startOffset points at may not exist.

We will see an illustration of this situation in the
below section of the article.

Range collapse Method (Solves Contradiction)
  • range.collapse(toStart) - furls range to a point. Depending on toStart value (boolean) range is collapsed to startNode and startOffset or endNode and endOffset.
Let's continue considering our example with dayRange.

So dayRange has next properties set:
  • commonAncestorContainer - Text node ‘day’
  • startContainer - Text node ‘day’
  • startOffset - 0
  • endContainer - Text node ‘day’
  • endOffset - 3

Now, let's collapse dayRange to start:

dayRange.collase(true);

After this call dayRange gonna hold no text information and its properties will be set to:

  • commonAncestorContainer - Text node ‘day’
  • startContainer - Text node ‘day’
  • startOffset - 0
  • endContainer - Text node ‘day’
  • endOffset - 0






Note that endOffset is set to 0 now. What does it mean? Remembering what we've investigated about endOffset we know, that it points right before the node or character that belongs to the range. As a consequence from this we conclude that 'd' does not belongs to the dayRange and that dayRange is ended right before it.

From the other side startOffset is also 0. This means that 'd' is the first letter of
dayRange and 'd' does belong to dayRange.

A little contradictious, yeah?

* * *
Here i have a question to mathematicians:
what is resulting range for [0,0)?

Is it point 0? Or is it empty range? Or this this is simply wrong question? ;)
* * *

In Mozilla's interpretation we have next explanation:
method collapse makes dayRange do not contain any text data. That means that 'd' does not belong to it.

Conclusion: endOffset exclusion has more strength than startOffset inclusion.


Range startOffset not Existing Target

Again, suppose we have initial dayRange (text node 'day' is selected):

  • commonAncestorContainer - Text node ‘day’
  • startContainer - Text node ‘day’
  • startOffset - 0
  • endContainer - Text node ‘day’
  • endOffset - 3







Now let's execute (collapse
dayRange to end)

dayRange.collase(false);

After execution dayRange properties will be set to:
  • commonAncestorContainer - Text node ‘day’
  • startContainer - Text node ‘day’
  • startOffset - 3
  • endContainer - Text node ‘day’
  • endOffset - 3







Now we have another situation: both
startOffset and endOffset point to fourth letter of the 'day' node. This is the case when startOffset points to nonexisting element.



Conclusions

We've determined two cases when we should be careful with startOffset.

  1. Node or character pointed by startOffset is not included in range when endOffset of the same range points to same node or character.

  2. Node or character pointed by startOffset may not exist in the case when it is not inclused into the range (because of 1. for example)

Thursday, November 29, 2007

Disapointment... Moving to WordPress

Oh no! It looks like blogspot is too buggy to use...
  • Editing entry reformats the text multiplying nine breaks on image upload... So i have manually go line by line and delete it...
  • Added image always appears on entry begin... So it is necessary take it and drag down down and down until the place where i need it.
  • No possibility to add a table... Editing source manually and writing <table&gh; there results in huge gap before the table (a screen or two)... Later i discovered that it is possible to insert a table copying it from Word and pasting to Firefox. But after saving it looks just awful in Internet Explorer!
  • Also applying different font does not always work (when begin and end of selection have same font as you've chosen to format - the inside is not formatted).
  • Sometimes you font drop down disappears at all and sometimes it shows no options to choose from.
So I'm moving to WordPress.

Tuesday, November 27, 2007

Mozilla/Firefox Range - Part 1: setEndAfter Mythic

This article is one of the cycle about Range behavior in Mozilla Firefox. There are lots of nuances in Range manipulation (especially when you need to write some custom behavior that is tightly bounded to page DOM). This entry describes nonobvious behavior of setEnd Range method

Range endOffset Property and setEnd Method
Range setEndAfter Method
The setEndAfter Mythics


Range endOffset Property and setEnd Method

Let's consider next Range properties:
  • range.endContainer – points to the node where the range ends.
  • range.endOffset – is shift inside the endContainer to point exactly to the place where range ends
  • range.setEnd(newEndContainer, newEndOffset) – sets new end boundary of the range.

The prevalent errors are made here when misunderstanding endOffset property.

EndOffset is the index of node or character right before which is the end of the range and this node or character does not belong to the range itself (not the index of last range node or character!!)

The second important point here is that this node or character before the end may not even exist.

Example:





Suppose some range contains some text node (dayNode.nodeType = “#text”).
For example dayRange contains text node with textContent ‘day’.

dayRange has next properties set:

  • commonAncestorContainer - Text node ‘day’
  • startContainer - Text node ‘day’
  • startOffset - 0
  • endContainer - Text node ‘day’
  • endOffset - 3

Note that endOffset is 3, but dayNode.textContent.charAt(3) doesn’t exist.

Range setEndAfter Method

setEndAfter method, moves range’s right boundary after the node passed in parameter.

Lets suppose dayNode is a child of a dayWrapperNode (the only one child).

After calling

dayRange.setEndAfter(dayNode);

dayRange.endContainer will point to second (nonexisting in our case) child of
dayWrapperNode: dayWrapperNode.childNodes[1].

The dayRange is now:
  • commonAncestorContainer - dayWrapperNode
  • startContainer - Text node 'day'
  • startOffset - 0
  • endContainer - dayWrapperNode
  • endOffset - 1

Note that commonAncestorContainer has also changed to dayWrapperNode.

It might seem strange that range whose text content ex facte is completely in text node, (dayRange) is reached out from the dayNode to next sibling of the parent node. Cool yeah? But it is the way how it is implemented.

The setEndAfter Mythic

It is hard to understand, but something mythical happens with setEndAfter method.

Suppose dayWrapperNode a child of some dayWrapperWrapperNode and
dayRange.startContainer == dayRange.endContainer == dayNode.

Question 1: what is expected result of calling:

dayRange.setEndAfter(dayRange.startContainer);?

Question 2: what is expected result of calling:

dayRange.setEndAfter(dayRange.endContainer);?

As dayRange.endContainer and dayRange.startContainer point to same node, it is natural to expect that results of execution any of those operations will be the same.

But… no – they, are not the same.

In the former case dayRange.startContainer will point to dayWpapperNode.childNodes[1]:

In the latter case dayRange.endContainer will point to dayWrapperWrapperNode.childNodes[1]:

Question 3: what is expected result of executing this:

var endNode = dayRange.endContainer;
dayRange.setEndAfter(endNode);


?

The answer is awesome!
The result is same as calling

dayRange.setEndAfter(dayRange.startContainer);

i.e. it will point to dayWpapperNode.childNodes[1].

And now... will somebody tell me that Javascript programming isn't great? There are so many unknown and hidden features to take over in order to be a master....

Saturday, November 24, 2007

Forgotten to Think!

There are so much events happening in technology world these days and so many information we are trying to keep in our heads.... that sometimes we forget to think... simply stop and think about all this stuff around... rearrange and put everything in order... generate own ideas and own direction to move on... Do not loose self identity in this world of mass thoughts, mass fashion, mass living...