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>



No vertical align with display:table-cell

I got everything to work in most browsers, but not always in IE11. Apparently, IE 11 ignores width/height inside display:table-cell.

The solution that almost worked, see CodePen. It works in Chrome (left), IE10(middle), but NOT in IE11(right)

Screen Shot 2014-05-12 at 4.56.22 PM

<div class="container">
 <div class="cell">
 <img src="http://i.imgur.com/kpRaL9K.jpg"/>

.container {
display: table;
table-layout: fixed; /*crucial for IE*/
border: 1px solid black;
.cell {
display: table-cell;
vertical-align: middle;

img {
max-width: 100%;
max-height: 100%;
margin: auto;


How to speed up page load?

A very common interview question and a really good video is here:

An interesting way to look at the question:

To understand how absurd this question is – for fast pages, what is the right number of requests and optimal page size, Paul posed another similar question – for good health, what is the right number of meals and optimal pounds per meal to eat?

The answer is – not all requests are equal, not all bytes are equal.



Docker on Mac

Trying to set up Docker on Mac, and it seems like Vagrant is a good option.

Some Docker-friendly Vagrant base boxes are listed here: https://github.com/phusion/open-vagrant-boxes#readme

Step zero:
install Vagrant and Virtualbox

Step one:

vagrant init phusion/ubuntu-12.04-amd64

Step two:
Modify the vagrant file. Pay attention to the network settings:

# Vagrantfile API/syntax version. Don't touch unless you know what you're doing!

Vagrant.configure(VAGRANTFILE_API_VERSION) do |config|
 # Every Vagrant virtual environment requires a box to build off of.
 config.vm.box = "phusion/ubuntu-12.04-amd64"

 # Create a private network, which allows host-only access to the machine
 # using a specific IP.
 config.vm.network "private_network", ip: ""

 # Share an additional folder to the guest VM. The first argument is
 # the path on the host to the actual folder. The second argument is
 # the path on the guest to mount the folder. And the optional third
 # argument is a set of non-required options.
 config.vm.synced_folder "../srv", "/vagrant_srv"


Step three, run this to install docker:

wget -q -O - https://get.docker.io/gpg | apt-key add -;
echo deb http://get.docker.io/ubuntu docker main > /etc/apt/sources.list.d/docker.list;
apt-get update -qq; apt-get install -q -y --force-yes lxc-docker; 

I am using private network from vagrant so that all ports are automatically forwarded so that you can visit however you want

View at Medium.com