Element Finder now returns the line numbers of matching elements

I just released an updated version of the Sublime Text package Element Finder. The results screen now includes the line number of each matching element. You can double click the line number or summary and Sublime will open the file and jump down to the correct line.

How it works

To add this feature I needed a way to map DOM elements to line/column numbers in HTML source-code. Once a DOM has been generated it has no direct relationship with the HTML. There is no function in the DOM, jQuery, etc like `$(“#header”).getLineNumber()`. To solve this problem I wrote a Node module called domtosource, and included this as a submodule in Element Finder. Domtosource has a couple of techniques for finding the line and column number of an element.

The first technique is fastest, but only works if the outerHTML of the element is a unique string in the HTML. If that is the case, we can just get the character index of the unique string, count the line breaks before that index to get the line number, and then count the characters between the last line break and the start of the string to get the column number.

If the outerHTML is not unique, domtosource uses a slower method, but one that works in all cases. This method is based on the fact that elements appear in the HTML and the DOM tree in the same order. We get the node type of the matched element, for example `div`, then walk through the DOM tree to find how many other div elements appear before the matched one. Now that we know this is the nth div, we search through the HTML for the nth occurance of the string `<div`, which gives us the character index of the element. Once we have that index we can re-use part of the first technique and count the line breaks and characters before the index.

You can install Element Finder through Package Control.

CSS Specificity Calculator

When you see two CSS selectors can you always say which one has a higher specificity? For example, which of the following selectors would overrule the other?

div.products li > *[data-name="test"] a
:first-child .selected:hover

I don’t always know with some of the more complicated selectors, so I made a little web app to figure it out for me: specificity.keegan.st

The app uses regular expressions to find the parts of the selector which contribute to specificity. It highlights each part with a background colour to help you learn the specificity rules. The core part of the app is a JavaScript module I wrote which is available through npm via:

npm install specificity

The JavaScript module source and the website source are on GitHub.