Skip to content

Instantly share code, notes, and snippets.

@OliverJAsh
Created July 25, 2014 12:16
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save OliverJAsh/cedbd215a8bdf162cf4b to your computer and use it in GitHub Desktop.
Save OliverJAsh/cedbd215a8bdf162cf4b to your computer and use it in GitHub Desktop.
Virtual DOM experiment for Scribe
./node_modules/.bin/browserify index.js -o bundle.js
System.config({
"paths": {
"*": "*.js",
"npm:*": "jspm_packages/npm/*.js",
"github:*": "jspm_packages/github/*.js"
}
});
System.config({
"map": {
"npm:virtual-dom": "npm:virtual-dom@^0.0.19",
"npm:vdom-virtualize": "npm:vdom-virtualize@^0.0.3",
"npm:vtree": "npm:vtree@^0.0.19",
"npm:vdom-virtualize@0.0.3": {
"vtree": "npm:vtree@0.0.14"
},
"npm:virtual-dom@0.0.19": {
"vtree": "npm:vtree@0.0.19",
"x-is-array": "npm:x-is-array@0.1.0",
"vdom": "npm:vdom@0.0.19",
"is-object": "npm:is-object@0.1.2",
"x-is-string": "npm:x-is-string@0.1.0",
"browser-split": "npm:browser-split@0.0.1"
},
"npm:vtree@0.0.19": {
"x-is-array": "npm:x-is-array@0.1",
"is-object": "npm:is-object@^0.1.2"
},
"npm:vtree@0.0.14": {
"x-is-array": "npm:x-is-array@0.1",
"is-object": "npm:is-object@^0.1.2"
},
"npm:x-is-array@0.1.0": {},
"npm:vdom@0.0.19": {
"is-object": "npm:is-object@0.1.2",
"x-is-array": "npm:x-is-array@0.1.0",
"vtree": "npm:vtree@0.0.19",
"global": "npm:global@4.2.1"
},
"npm:is-object@0.1.2": {},
"npm:min-document": "npm:min-document@^2.10.0",
"npm:min-document@2.10.0": {
"dom-walk": "npm:dom-walk@0.1"
},
"npm:dom-walk@0.1.1": {},
// https://github.com/Matt-Esch/global/blob/master/package.json#L23
"npm:global@4.2.1": {
"min-document": "npm:min-document@2.10.0"
}
}
});
System.config({
"versions": {
"npm:virtual-dom": "0.0.19",
"npm:vdom-virtualize": "0.0.3",
"npm:vtree": [
"0.0.14",
"0.0.19"
],
"github:jspm/nodelibs": "0.0.2",
"npm:x-is-array": "0.1.0",
"npm:vdom": "0.0.19",
"npm:is-object": "0.1.2",
"npm:x-is-string": "0.1.0",
"npm:browser-split": "0.0.1",
"npm:min-document": "2.10.0",
"npm:dom-walk": "0.1.1"
}
});
<!DOCTYPE html>
<head>
<meta charset="utf-8">
</head>
<body>
<div class="scribe">
<p>This is 'a' test<br>This is "another" test</p>
</div>
<!-- <script src="bundle.js"></script> -->
<script src="./jspm_packages/system@0.6.js"></script>
<script src="config.js"></script>
<script>
System.import('index').then(function () {
console.log(1, arguments);
}).catch(function (error) {
console.log(error);
})
</script>
</body>
/* global window, require */
var diff = require('npm:virtual-dom/diff');
var patch = require('npm:virtual-dom/patch');
var virtualize = require('npm:vdom-virtualize');
var isVNode = require('npm:vtree/is-vnode');
var isVText = require('npm:vtree/is-vtext');
var openDoubleCurly = '“';
var closeDoubleCurly = '”';
var openSingleCurly = '‘';
var closeSingleCurly = '’';
var scribeElement = window.document.querySelector('.scribe');
var tree = virtualize(scribeElement);
var p1 = window.document.querySelector('p');
console.log(1, p1);
var t1 = window.document.querySelector('p').childNodes[0];
console.log(2, t1);
function traverse(tree, fn) {
// Do not traverse text nodes
if (isVNode(tree)) {
var child = tree.children[0];
while (child) {
traverse(child, fn);
fn(child);
child = tree.children[tree.children.indexOf(child) + 1];
}
}
return tree;
}
// Mutate the tree, transforming curly quotes in text nodes
function curlyQuotesFormatter(parentTree) {
return traverse(parentTree, function (tree) {
if (isVText(tree)) {
tree.text = convertQuotes(tree.text);
}
});
}
function boldFormatter(parentTree) {
parentTree.properties.style.fontWeight = 'bold';
return parentTree;
}
var formatters = [curlyQuotesFormatter, boldFormatter];
function format(tree) {
formatters.forEach(function (formatter) {
formatter(tree);
});
return tree;
}
var tree = virtualize(scribeElement);
// Mutate the new tree
var newTree = format(virtualize(scribeElement));
var patches = diff(tree, newTree);
scribeElement = patch(scribeElement, patches);
// Are the node references the same? Yes. Even text nodes!
var p2 = window.document.querySelector('p');
console.log(3, p1 === p2);
var t2 = window.document.querySelector('p').childNodes[0];
console.log(4, t1 === t2);
// Standard curly quote functions, nothing interesting below here…
function convertQuotes(str) {
// Tokenise HTML elements vs text between them
// Note: this is escaped HTML in the text node!
var tokens = str.split(/(<[^>]+?>)/);
return tokens.map(function(token) {
// Only replace quotes in text between (potential) HTML elements
if (token[0] === '<') {
return token;
} else {
return token.
// Use [\s\S] instead of . to match any characters _including newlines_
replace(/([\s\S])?'([\s\S])?/g,
replaceQuotesFromContext(openSingleCurly, closeSingleCurly)).
replace(/([\s\S])?"([\s\S])?/g,
replaceQuotesFromContext(openDoubleCurly, closeDoubleCurly));
}
}).join('');
}
function isWordCharacter(character) {
return /[^\s()]/.test(character);
}
function replaceQuotesFromContext(openCurly, closeCurly) {
return function(m, prev, next) {
prev = prev || '';
next = next || '';
var isStart = ! prev;
var isEnd = ! next;
var hasCharsBefore = isWordCharacter(prev);
var hasCharsAfter = isWordCharacter(next);
// Optimistic heuristic, would need to look at DOM structure
// (esp block vs inline elements) for more robust inference
if (hasCharsBefore || (isStart && ! hasCharsAfter && ! isEnd)) {
return prev + closeCurly + next;
} else {
return prev + openCurly + next;
}
};
}
{
"name": "virtual-dom-scribe",
"version": "0.0.0",
"description": "",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"author": "",
"license": "ISC",
"dependencies": {
"browserify": "^5.0.7",
"vdom-virtualize": "0.0.3",
"virtual-dom": "0.0.16",
"vtree": "0.0.19"
},
"jspm": {
"registry": "jspm",
"name": "virtual-dom-scribe",
"main": "index.js",
"dependencies": {
"npm:virtual-dom": "^0.0.19",
"npm:vdom-virtualize": "^0.0.3",
"npm:vtree": "^0.0.19",
"npm:min-document": "^2.10.0"
}
}
}
Broken deps:
* vdom => global
* global => min-document
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment