
Show HN: A DOM text-selection highlight renderer - bowlingx
http://bowlingx.github.io/marklib/
======
kevin
This is really great. I think we're going to use this for helping us highlight
parts of the YC application that sticks out to the partners. Very interesting
to see that what you actually store in local storage.

[{"startOffset":35,"endOffset":42,"startContainerPath":"html>body>div:nth-of-
type(1)>div>p:nth-of-type(1);0","endContainerPath":"html>body>div:nth-of-
type(1)>div>p:nth-of-
type(1);0"},{"startOffset":32,"endOffset":7,"startContainerPath":"html>body>div:nth-
of-type(1)>div>p:nth-of-type(1);10","endContainerPath":"html>body>div:nth-of-
type(1)>div>p:nth-of-type(1)>code:nth-of-type(3);0"}]

One thing I think we might tweak for ourselves is to also store a copy of the
string in there.

Thank you so much for sharing! I bet people would love an example showing how
to use this to sync highlighted examples across user accounts. Hopefully,
someone will do a Show HN of that!

~~~
callmevlad
It seems like using a tree-index based path, this serialization format would
only work with purely static content. If you have a change to the underlying
content (e.g. adding a new paragraph before a selection), there doesn't seem
to be enough information in the serialized path to select the right part of
the page.

~~~
bowlingx
That's correct. But it is possible to specify a context container where the
highlighting is executed so if you change parts of the document (like around
this container) it doesn't change the relative path.

Example:

<html>

<body>

<article id="myContextContainer">

    
    
      <p>...</p>
    

</article>

</body>

</html>

If you add or change words and paragraphs of course, that would make the
highlighting unstable. You could also restrict the marking to a specific
paragraph only (and set the context accordingly). It always depends on the
application this library is used for. But if anyone has a good idea how to
compensate that I'm open for suggestions :)

Thank you for your feedback.

------
bowlingx
I build a fast small text-selection renderer that creates serializable text-
renderings. Feedback appreciated. Right now it lacks some documentation how to
use it, but I hope the sample makes clear what the library does.

~~~
VeejayRampay
We were working on a Medium-style text editor for a while and text selection
is notoriously hard. Things like
[https://github.com/timdown/rangy](https://github.com/timdown/rangy) somehow
made it more palatable but seriously, what a pain when you want to select
something and apply DOM transformations to the underlying nodes.

Could a WYSIWYG text editor be based on your library or does it have a
completely different target?

~~~
bowlingx
Thank you for the Feedback. The library only focuses on render a selection,
either a serialized one (it's not yet shown in the demo) or a selection made
by the user.

But of course you may use it with any other library :)

~~~
VeejayRampay
To be more precise, the biggest pain with selections I feel is that if you
have a H1 (for example) containing some text and you select that text, the
range will never report the H1 even though the user actually selected it. That
makes it hard to go full WYSIWYG and you end up having to deal with parentNode
and the likes.

~~~
jammaloo
That was a huge problem to overcome when I was working on the new email
designer for ActiveCampaign. Rangy had issues, because it wouldn't select
["empty" elements]([https://developer.mozilla.org/en-
US/docs/Glossary/Empty_elem...](https://developer.mozilla.org/en-
US/docs/Glossary/Empty_element)).

I ended up rolling my own solution that worked for us, but one approach we
tried out was looking at each selected element's parent. If the first and last
element non-empty nodes in the parent were selected, then we also added the
parent to the selection.

------
dfar1
I noticed that you can mark an already marked section, which adds the marked
color on top again, and again and again until you can't tell anymore because
alpha = 100.

~~~
bowlingx
yes, thats correct, I just specified colors for 4 overlappings. This is just
made with css, you can specify the level how deep you want.

~~~
dfar1
Oops... I guessed wrong. It's a nice option to be able to define different
colors for each level. Great work.

------
pknight
Did you take inspiration from Rangy
([https://github.com/timdown/rangy](https://github.com/timdown/rangy)) and if
yes, what makes Marklib better? Would like to know if there are obvious
benefits to using Marklib over Rangy.

~~~
bowlingx
Hi :), marklib focuses on rendering and persisting (serializing) the
selection, not on actually providing a cross-browser functionality to get the
selection.

marklib is especially useful and build for rendering incremental persisted
selections and/or adding selections when other selections are already rendered
(and though have modified the DOM). This is something rangy does not provide
(at least that's my last information).

~~~
agrothberg
Might be worth adding this to adding these notes to the README.

------
lgas
Seems like a good candidate for a bookmarklet that injects it into any page.

~~~
christiangenco
My thoughts exactly. This should be a chrome plugin.

~~~
Flenser
[http://www.getpoint.co/](http://www.getpoint.co/)

~~~
christiangenco
Hmm... kind of. Point looks like its focus is primarily on sharing and
discussing articles and quotes with others - I just want something that will
let me save (and browse/search?) my personal highlights for the next time I
read an article or need information from it.

------
pimlottc
I get inconsistent results when I triple-click to create the selection. For
example, triple-clicking the word "Start" in the first paragraph highlights
the entire first line, extending to the right margin; hitting enter to "mark"
it results in the entire paragraph being marked. Triple-clicking the first
word "Marklib" in the next sentence highlights the remaining three sentences,
but only "Marklib" is marked.

Also, any marking in the "code block" or the page title omits the spaces,
which looks a little awkward.

Running Chrome 43.0.2357.124 on OS X

------
lepunk
Well done! I know it is not an easy task to do. I built something fairly
similar (and way less quick)
[http://jsfiddle.net/2XLBr/](http://jsfiddle.net/2XLBr/) and the git repo:
[https://github.com/skimhub/phone-highlight](https://github.com/skimhub/phone-
highlight)

------
baby
There is a weird behavior when you highlight something that has partially
already been highlighted. I think you should take a look at how `preview` on
osx does it. It cancels the already highlighted parts only if they are
included in the new highlighted area. If an already highlighted part cross
with the new highlighted area, then it will behave like it is behaving in your
script.

~~~
bowlingx
Thank you for your feedback. What do you mean with cancel? The script will
render all selections without doing any assumptions about previous renderings
and nests them. Can you give an example?

thank you :)

~~~
baby
do you have osx? that would be easier for you to open a pdf and see how that
highlight thing works.

I'll try to explain it again giving another example:

if you highlight a word, and then you highlight the entire sentence containing
that world, with your script it will highlight the word with a different
color, with osx it will display like you didn't highlight the word prior to
this

your behavior only happens when two highlighted segments cross over, but none
of them contain the other.

------
wdewind
This is really nice work! I think I've found a bug where the highlight doesn't
fully mark the part I've selected, though. To reproduce scroll down to the
section "A second paragraph with some latin like text" and select that header,
the entire paragraph, and up to the button below it. Then press enter. Only
the header is highlighted.

~~~
bowlingx
Hey, thank you for your feedback. Yeah, that are some problems with the
selection that comes back (no textnode comes back but properly the body or
something else). I have no solution for this so far but I will figure
something out ;). thanks!

------
mparramon
This is a case of Something.js if I've ever seen one:

[http://www.developingandstuff.com/2015/03/somethingjs.html](http://www.developingandstuff.com/2015/03/somethingjs.html)

~~~
Gigablah
One, it doesn't have ".js" in the title. Two, it's a Show HN post.

------
user3885
There is also
[https://github.com/SmartTeleMax/MaSha](https://github.com/SmartTeleMax/MaSha)
MaSha has ajax support. But no library supports multiple colors :(

------
thomasfoster96
Well done - works surprisingly well on my iPhone. Working with text selection
in the browser is notoriously difficult so I'm glad this works.

------
tauchunfall
Thanks a thousand for posting about marklib (and rangy, and phone-highlight).

------
sandaru1
Is there a good library that does the same inside a textarea?

------
notNow
At the risk of sounding a bit grumpy but I'm genuine here, I seriously don't
get this tool. Is not the same thing as getSelection() with a CSS background-
color cherry on the top or I'm missing something here?

~~~
bowlingx
marklib helps you persisting selections a user did by providing rendering and
serialization of selections.

~~~
WaltPurvis
I'll volunteer to display my total ignorance: I have no idea what you mean
when you say "rendering and serialization of selections" or why and how that
is useful. Could you elaborate and give some good scenarios in which it
(whatever it is) would be useful? I _think_ this could be cool, but I don't
understand.

~~~
bowlingx
Let's say you want to build a collaboration tool where you write articles. You
want to provide a functionality that people can comment on parts inside the
article (inline comments) and you need a way to visualize what they marked and
also persist the marking (on a server for instance). That what this library is
for :).

~~~
WaltPurvis
Thank you. So am I correct in thinking this would be useful if you wanted to
let people select a portion of an article and save just that portion to a
database? (If so, I'll be using it immediately.)

~~~
bowlingx
If you just want to select a portion of a text that would be working with
build-in browser APIs (see [https://developer.mozilla.org/en-
US/docs/Web/API/Window/getS...](https://developer.mozilla.org/en-
US/docs/Web/API/Window/getSelection)). Marklib can be used to make a selection
visible and persistent. Especially if you want to display a lot of inline
comments for instance and you need to paginate trough the result, this library
can be handy because it allows marking, even if the document has been altered
before with another rendering.

