public
Created — forked from nzakas/es6proxy.htm

Example of ES6 Proxy

  • Download Gist
es6proxy.htm
HTML
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168
<!DOCTYPE html>
<!--
 
This is a simple experiment relying on ECMAScript 6 Proxies. To try this out,
use Aurora (http://www.mozilla.org/en-US/firefox/channel/).
 
The goal was to create a HTML writer where the method names were really just
the HTML tags names, but without manually creating each method. This uses
a Proxy to create a shell to an underlying writer object that checks each
method name to see if it's in a list of known tags.
 
-->
<html>
<body>
<script>
/*
* The constructor name I want is HTMLWriter.
*/
var HTMLWriter = (function(){
 
/*
* Lazily-incomplete list of HTML tags.
*/
var tags = [
"a", "abbr", "acronym", "address", "applet", "area",
"b", "base", "basefont", "bdo", "big", "blockquote",
"body", "br", "button",
"caption", "center", "cite", "code", "col", "colgroup",
"dd", "del", "dir", "div", "dfn", "dl", "dt",
"em",
"fieldset", "font", "form", "frame", "frameset",
"h1", "h2", "h3", "h4", "h5", "h6", "head", "hr", "html",
"i", "iframe", "img", "input", "ins", "isindex",
"kbd",
"label", "legend", "li", "link",
"map", "menu", "meta",
"noframes", "noscript",
"object", "ol", "optgroup", "option",
"p", "param", "pre",
"q",
"s", "samp", "script", "select", "small", "span", "strike",
"strong", "style", "sub", "sup",
"table", "tbody", "td", "textarea", "tfoot", "th", "thead",
"title", "tr", "tt",
"u", "ul",
"var"
];
 
/*
* Define an internal-only type. Code taken from:
* http://www.nczonline.net/blog/2009/02/17/mozilla-javascript-extension-nosuchmethod/
*/
function InternalHTMLWriter(){
this._work = [];
}
 
InternalHTMLWriter.prototype = {
 
escape: function (text){
return text.replace(/[><"&]/g, function(c){
switch(c){
case ">": return "&gt;";
case "<": return "&lt;";
case "\"": return "&quot;";
case "&": return "&amp;";
}
});
},
 
startTag: function(tagName, attributes){
this._work.push("<" + tagName);
 
if (attributes){
var name, value;
for (name in attributes){
if (attributes.hasOwnProperty(name)){
value = this.escape(attributes[name]);
this._work.push(" " + name + "=\"" + value + "\"");
}
}
}
 
this._work.push(">");
return this;
},
 
text: function(text){
this._work.push(this.escape(text));
return this;
},
 
endTag: function(tagName){
this._work.push("</" + tagName + ">");
return this;
},
 
toString: function(){
return this._work.join("");
}
 
};
/*
* Output a pseudo-constructor. It's not a real constructor,
* since it just returns the proxy object, but I like the
* "new" pattern vs. factory functions.
*/
return function(){
var writer = new InternalHTMLWriter(),
proxy = Proxy.create({
 
/*
* Only really need getter, don't want anything else going on.
*/
get: function(receiver, name){
var tagName,
closeTag = false;
if (name in writer){
return writer[name];
} else {
if (tags.indexOf(name) > -1){
tagName = name;
} else if (name.charAt(0) == "x" && tags.indexOf(name.substring(1)) > -1){
tagName = name.substring(1);
closeTag = true;
}
if (tagName){
return function(){
if (!closeTag){
writer.startTag(tagName, arguments[0]);
} else {
writer.endTag(tagName);
}
return receiver;
};
}
}
},
/*
* Don't allow fixing.
*/
fix: function(){
return undefined;
}
});
return proxy;
};
})();
 
//hmmm...doesn't look like magic way down here
var w = new HTMLWriter();
 
w.html()
.head().title().text("Example & Test").xtitle().xhead()
.body().text("Hello world!").xbody()
.xhtml();
 
console.log(w);
</script>
</body>
</html>

Please sign in to comment on this gist.

Something went wrong with that request. Please try again.