Merge "Document usage of verbatim expressions"
diff --git a/dev/js/runner/panel.html b/dev/js/runner/panel.html
new file mode 100644
index 0000000..d0cf2d2
--- /dev/null
+++ b/dev/js/runner/panel.html
@@ -0,0 +1,32 @@
+<!DOCTYPE html>
+<html>
+  <head>
+    <meta charset="utf-8">
+    <title>Spec Runner for Panels</title>
+    <link rel="shortcut icon" type="image/png" href="../lib/jasmine-2.1.1/jasmine_favicon.png">
+    <link rel="stylesheet" href="../lib/jasmine-2.1.1/jasmine.css">
+    <script src="../lib/require.js"></script>
+    <script src="../lib/jasmine-2.1.1/jasmine.js"></script>
+    <script src="../lib/jasmine-2.1.1/jasmine-html.js"></script>
+    <script src="../lib/jasmine-2.1.1/boot.js"></script>
+    <script>
+    require.config({
+      baseUrl: "../src",
+      paths: {
+        "lib" : "../lib",
+        "spec" : "../spec"
+      }
+    });
+    require([
+      'lib/domReady!',
+      'spec/panelSpec'
+    ],
+    function () {
+      if (jsApiReporter.finished === true)
+        jasmine.getEnv().execute();
+    });
+    </script>
+  </head>
+  <body>
+  </body>
+</html>
diff --git a/dev/js/spec/panelSpec.js b/dev/js/spec/panelSpec.js
new file mode 100644
index 0000000..4881c0c
--- /dev/null
+++ b/dev/js/spec/panelSpec.js
@@ -0,0 +1,130 @@
+define(['panel','view','util'], function (panelClass,viewClass) {
+
+  var controlStr = "";
+
+  var helloViewClass = {
+    create : function () {
+      return Object.create(viewClass)._init(['myview']).upgradeTo(this);
+    },
+
+    show : function () {
+      if (this._show)
+        return this._show;
+
+      var e = document.createElement('span');
+      e.addT("Hello World!");
+      
+      this._show = e;
+      return e;
+    }
+  };
+
+  describe('KorAP.View', function () {
+    it('should be initializable', function () {
+      var view = viewClass.create();
+
+      expect(view.shown()).toBeFalsy();
+
+      var e = view.element();
+      expect(view.shown()).toBeTruthy();
+
+      expect(e.tagName).toEqual("DIV");
+      expect(e.classList.contains("view")).toBeTruthy();
+
+      var btn = e.firstChild;
+      expect(btn.tagName).toEqual("DIV");
+      expect(btn.classList.contains("button-view")).toBeTruthy();
+      expect(btn.classList.contains("button-group")).toBeTruthy();
+
+      expect(btn.firstChild.tagName).toEqual("SPAN");
+      expect(btn.firstChild.getAttribute("title")).toEqual("Close");
+      expect(btn.firstChild.classList.contains("button-icon")).toBeTruthy();
+      expect(btn.firstChild.classList.contains("close")).toBeTruthy();
+      expect(btn.firstChild.firstChild.tagName).toEqual("SPAN");
+      expect(btn.firstChild.firstChild.firstChild.data).toEqual("Close");
+    });
+
+    it('should be classable', function () {
+      var view = viewClass.create(['versuch']);
+      var e = view.element();
+      expect(e.tagName).toEqual("DIV");
+      expect(e.classList.contains("view")).toBeTruthy();
+      expect(e.classList.contains("versuch")).toBeTruthy();
+
+      var btn = e.firstChild;
+      expect(btn.tagName).toEqual("DIV");
+      expect(btn.classList.contains("button-view")).toBeTruthy();
+      expect(btn.classList.contains("button-group")).toBeTruthy();
+      expect(btn.classList.contains("versuch")).toBeTruthy();
+    });
+  });
+  
+  describe('KorAP.Panel', function () {
+
+    it('should be initializable', function () {
+      var panel = panelClass.create();
+      var e = panel.element();
+      expect(e.tagName).toEqual("DIV");
+      expect(e.classList.contains("panel")).toBeTruthy();
+      expect(e.firstChild.tagName).toEqual("DIV");
+
+      // No children in the empty view element
+      expect(e.firstChild.firstChild).toBeFalsy();
+      expect(e.lastChild.tagName).toEqual("DIV");
+      expect(e.lastChild.classList.contains("button-panel")).toBeTruthy();
+      expect(e.lastChild.classList.contains("button-group")).toBeTruthy();
+      expect(e.lastChild.firstChild).toBeFalsy();
+
+      expect(panel.actions).toBeTruthy();
+    });
+
+    
+    it('should be extensible', function () {
+      var panel = panelClass.create();
+
+      controlStr = "";
+      panel.actions.add("New", ["new"], function () {
+        controlStr = 'New!!!';
+      });
+
+      var e = panel.element();
+
+      expect(e.tagName).toEqual("DIV");
+      expect(e.firstChild.firstChild).toBeFalsy();
+
+      expect(e.lastChild.firstChild.tagName).toEqual("SPAN");
+      expect(e.lastChild.firstChild.getAttribute("title")).toEqual("New");
+      expect(e.lastChild.firstChild.classList.contains("new")).toBeTruthy();
+      expect(e.lastChild.firstChild.firstChild.tagName).toEqual("SPAN");
+      expect(e.lastChild.firstChild.firstChild.firstChild.data).toEqual("New");
+
+      expect(controlStr).toEqual("");
+      e.lastChild.firstChild.click();
+      expect(controlStr).toEqual("New!!!");
+    });
+
+    it('should be classable', function () {
+      var panel = panelClass.create(["versuch"]);
+      var e = panel.element();
+      expect(e.tagName).toEqual("DIV");
+      expect(e.classList.contains("panel")).toBeTruthy();
+      expect(e.classList.contains("versuch")).toBeTruthy();
+      expect(e.lastChild.classList.contains("button-panel")).toBeTruthy();
+      expect(e.lastChild.classList.contains("versuch")).toBeTruthy();
+    });
+
+    it('should be extensible by a view', function () {
+      var panel = panelClass.create();
+      var view = helloViewClass.create();
+      var e = panel.element();
+
+      panel.add(view);
+
+      var viewE = e.firstChild.firstChild;
+      expect(viewE.classList.contains('view')).toBeTruthy();
+      expect(viewE.classList.contains('myview')).toBeTruthy();
+      expect(viewE.firstChild.tagName).toEqual("SPAN");
+      expect(viewE.firstChild.firstChild.data).toEqual("Hello World!");
+    });
+  });
+});
diff --git a/dev/js/src/view.js b/dev/js/src/view.js
index 0a47f0b..aabad29 100644
--- a/dev/js/src/view.js
+++ b/dev/js/src/view.js
@@ -5,8 +5,8 @@
 
 define(['buttongroup', 'util'], function (buttonGroupClass) {
 
-  const loc   = KorAP.Locale;
-  loc.CLOSE     = loc.CLOSE     || 'Close';
+  const loc = KorAP.Locale;
+  loc.CLOSE = loc.CLOSE     || 'Close';
   
 
   return {
@@ -53,6 +53,7 @@
       if (this._classes)
         cl.add.apply(cl, this._classes);
 
+      // TODO: The show may need to be wrapped in another DIV!
       if (this.show !== undefined)
         e.appendChild(this.show());
 
@@ -86,7 +87,6 @@
         this.onClose();
     },
 
-
     /**
      * Upgrade this object to another object,
      * while private data stays intact.