A medium contenteditable editor written in React?

Facebook’s official implementation: 


After writing our in-house rich text editor (I know, it was a bad idea), I kept wondering whether there is a better way.

React.js opens some interesting possibilities, because now rending to DOM is so cheap. Additionally, the medium engineering team’s blog re-assured the difficulty of writing a contenteditable editor and shared similar visions with Polymer web components.

At a very high level, I think the approach could be similar to what Medium is doing right now:

  1. Apply a sequence of atomic operations on an in-memory text string to generate innerHTML, give the innerHTML to the virtual DOM, and let Reactjs update the actual DOM.
  2. Atomic operations could be bold / underline / h2 / h3 etc. They takes a text string and outputs HTML.
  3. In-memory text string is the raw text, typed by the author
  4. We also need a controller to coordinate atomic operations, meaning not only know how to apply one operation at a particular start-end position of the text string, but also knowing how to prioritize different operations.

This also reminds me of the fancy command logging, the idea of always starting with a base state, and generate current state by applying many many atomic operations.

Anyway, would love to write a rich text editor that doesn’t suck and generate consistent HTML markups in React.js, but it is a pretty big undertake… Maybe someday…


My .bash_profile

if [ -f ~/.bashrc ]; then
  source ~/.bashrc

if [ -f $(brew --prefix)/etc/bash_completion ]; then
  . $(brew --prefix)/etc/bash_completion
export PS1="\\w\$(__git_ps1 '(%s)') \$ "

export CLICOLOR=1
export LSCOLORS=GxFxCxDxBxegedabagaced

alias 'subl=/Applications/Sublime\ Text\ 2.app/Contents/SharedSupport/bin/subl'

[ -s "/Users/shao/.nvm/nvm.sh" ] && . "/Users/shao/.nvm/nvm.sh" # This loads nvm

Some prerequisites:
– brew
– nvm
– brew install git bash-completion


Firebase 101

It sounds like a great idea, but comes with interesting twists…

For one, the security rule is not easy…

“the basic gist is that the rules cascade, but they stop as soon as access is granted. So once you’ve granted access to one branch of your data model, that user has access to all child attributes. You can’t deny access farther down the tree.” From Chris

Second, still not sure how to ensure uniqueness, i.e., storing URL and wanting to ensure that URL hasn’t be saved before…


Polymer sequence of life cycle events

When you do this with a Polyer element

  created: function() {
  ready: function() {
  attached: function () {
  domReady: function() {
  detached: function() {

You get:


Requirejs inside web components


The data-main attribute doesn’t work. You have to require manually.


This does NOT work:

<element name="vs-text">
   <link rel="stylesheet" href="vs-text.css">

     <div class="main"></div>

   <script type="text/javascript" src="//cdnjs.cloudflare.com/ajax/libs/require.js/2.1.11/require.min.js</span>" data-main="main"></script>

   <script src="vs-text.min.js"></script>


This works:

<element name="vs-text">
<link rel="stylesheet" href="vs-text.css">

<div class="main"></div>

<script type="text/javascript" src="//cdnjs.cloudflare.com/ajax/libs/require.js/2.1.11/require.min.js</span>"></script>
<script type="text/javascript">
require([], function() {

<script src="vs-text.min.js"></script>