Move to using HTML templates when filling out the workspace history.

This is a pre-step to having a history list that you can click on
and having the code moved back into the textarea, which will come
as a follow-up CL.

BUG=skia:
R=mtklein@google.com

Author: jcgregorio@google.com

Review URL: https://codereview.chromium.org/244313007

git-svn-id: http://skia.googlecode.com/svn/trunk@14283 2bbb7eff-a529-9590-31e7-b0007b416f81
diff --git a/experimental/webtry/css/webtry.css b/experimental/webtry/css/webtry.css
index 58dc68b..dcc2540 100644
--- a/experimental/webtry/css/webtry.css
+++ b/experimental/webtry/css/webtry.css
@@ -31,6 +31,10 @@
   resize: none;
 }
 
+template {
+  display: none;
+}
+
 pre, code {
     padding: 0;
     color: green;
diff --git a/experimental/webtry/js/run.js b/experimental/webtry/js/run.js
index 2048ca4..5cd43ac 100644
--- a/experimental/webtry/js/run.js
+++ b/experimental/webtry/js/run.js
@@ -4,11 +4,37 @@
  */
 
 /**
+ * A polyfill for HTML Templates.
+ *
+ * This just adds in the content attribute, it doesn't stop scripts
+ * from running nor does it stop other side-effects.
+ */
+(function polyfillTemplates() {
+  if('content' in document.createElement('template')) {
+    return false;
+  }
+
+  var templates = document.getElementsByTagName('template');
+  for (var i=0; i<templates.length; i++) {
+    var content = document.createDocumentFragment();
+    while (templates[i].firstChild) {
+     content.appendChild(templates[i].firstChild);
+    }
+    templates[i].content = content;
+  }
+})();
+
+/**
  * All the functionality is wrapped up in this anonymous closure, but we need
  * to be told if we are on the workspace page or a normal try page, so the
  * workspaceName is passed into the closure, it must be set in the global
  * namespace. If workspaceName is the empty string then we know we aren't
  * running on a workspace page.
+ *
+ * If we are on a workspace page we also look for a 'history'
+ * variable in the global namespace which contains the list of tries
+ * that are included in this workspace. That variable is used to
+ * populate the history list.
  */
 (function(workspaceName) {
     var run = document.getElementById('run');
@@ -20,6 +46,15 @@
     var img = document.getElementById('img');
     var tryHistory = document.getElementById('tryHistory');
     var parser = new DOMParser();
+    var tryTemplate = document.getElementById('tryTemplate');
+
+
+    function addToHistory(hash, imgUrl) {
+      var clone = tryTemplate.content.cloneNode(true);
+      clone.querySelector('a').href = '/c/' + hash;
+      clone.querySelector('img').src = imgUrl;
+      tryHistory.insertBefore(clone, tryHistory.firstChild);
+    }
 
 
     function beginWait() {
@@ -58,13 +93,7 @@
       }
       // Add the image to the history if we are on a workspace page.
       if (tryHistory) {
-        var newHistoryStr = '<div class=tries>' +
-          '<a href="/c/' + body.hash + '">' +
-          '  <img width=64 height=64 src="' + img.src +  '">' +
-          '</a></div>';
-
-        var newHistory = parser.parseFromString(newHistoryStr, "text/html");
-        tryHistory.insertBefore(newHistory.body.firstChild, tryHistory.firstChild);
+        addToHistory(body.hash, 'data:image/png;base64,' + body.img);
       } else {
         window.history.pushState(null, null, "./" + body.hash);
       }
@@ -113,4 +142,12 @@
       embedButton.addEventListener('click', onEmbedClick);
     }
 
+
+    // Add the images to the history if we are on a workspace page.
+    if (tryHistory && history) {
+      for (var i=0; i<history.length; i++) {
+        addToHistory(history[i].hash, '/i/'+history[i].hash+'.png');
+      }
+    }
+
 })(workspaceName);
diff --git a/experimental/webtry/templates/workspace.html b/experimental/webtry/templates/workspace.html
index 4dab65b..3a461d6 100644
--- a/experimental/webtry/templates/workspace.html
+++ b/experimental/webtry/templates/workspace.html
@@ -6,6 +6,14 @@
     <link rel="stylesheet" href="/css/" type="text/css" media="screen">
 </head>
 <body>
+
+  <template id=tryTemplate>
+      <div class=tries>
+        <a href="">
+          <img width=64 height=64 src="">
+        </a>
+      </div>
+  </template>
   {{template "titlebar.html"}}
   <section id=content>
 {{if .Name}}
@@ -23,14 +31,10 @@
 
   <pre><code id='output'></code></pre>
   </section>
+  <script type="text/javascript" charset="utf-8">
+    var history = {{.Tries}};
+  </script>
   <section id=tryHistory>
-    {{range .Tries}}
-      <div class=tries>
-        <a href="/c/{{.Hash}}">
-          <img width=64 height=64 src="/i/{{.Hash}}.png">
-        </a>
-      </div>
-    {{end}}
   </section>
 
   <script type='text/javascript' charset='utf-8'>
diff --git a/experimental/webtry/webtry.go b/experimental/webtry/webtry.go
index 73b1ae5..a895b01 100644
--- a/experimental/webtry/webtry.go
+++ b/experimental/webtry/webtry.go
@@ -346,8 +346,8 @@
 }
 
 type Try struct {
-	Hash     string
-	CreateTS string
+	Hash     string `json:"hash"`
+	CreateTS string `json:"create_ts"`
 }
 
 type Recent struct {
@@ -418,7 +418,7 @@
 		name := ""
 		if len(match) == 2 {
 			name = match[1]
-			rows, err := db.Query("SELECT create_ts, hash FROM workspacetry WHERE name=? ORDER BY create_ts DESC ", name)
+			rows, err := db.Query("SELECT create_ts, hash FROM workspacetry WHERE name=? ORDER BY create_ts", name)
 			if err != nil {
 				reportError(w, r, err, "Failed to select.")
 				return
@@ -437,7 +437,7 @@
 		if len(tries) == 0 {
 			code = DEFAULT_SAMPLE
 		} else {
-			code = getCode(tries[0].Hash)
+			code = getCode(tries[len(tries)-1].Hash)
 		}
 		if err := workspaceTemplate.Execute(w, Workspace{Tries: tries, Code: code, Name: name}); err != nil {
 			log.Printf("ERROR: Failed to expand template: %q\n", err)