Introduce a general buttongroup menu
Change-Id: I2d84af1c9d43ce3e57b10321bd7d414a64cf68a8
diff --git a/dev/demo/buttongroup.html b/dev/demo/buttongroup.html
new file mode 100644
index 0000000..9a26ed1
--- /dev/null
+++ b/dev/demo/buttongroup.html
@@ -0,0 +1,36 @@
+<!DOCTYPE html>
+<html>
+ <head>
+ <title>Hint demo</title>
+ <meta charset="utf-8" />
+ <script src="../js/lib/require.js" async="async"></script>
+ <link type="text/css" rel="stylesheet" href="../css/kalamar.css" />
+ </head>
+ <body>
+ <nav id="mainButton" style="position: absolute; top: 300px"></nav>
+ </body>
+ <script>
+requirejs.config({
+ baseUrl: '../js/src',
+ paths : {
+ 'lib': '../lib'
+ }
+});
+
+
+require(['buttongroup'], function (btnClass) {
+ btns = btnClass.create();
+ btns.add('Meta',['meta'], function () {
+ console.log(this.button.classList.contains('meta'));
+ });
+ var list = btns.addList('More', ['list']);
+ list.readItems([
+ ['cool', 'cool', function (e, action) { console.log('really' + this.action()) }],
+ ['very cool', 'veryCool', function (e, action) { console.log('very cool') }]
+ ]);
+ document.getElementById('mainButton').appendChild(btns.element());
+});
+
+
+ </script>
+</html>
diff --git a/dev/js/runner/match.html b/dev/js/runner/match.html
index 564acab..cd4f93a 100644
--- a/dev/js/runner/match.html
+++ b/dev/js/runner/match.html
@@ -2,7 +2,7 @@
<html>
<head>
<meta charset="utf-8">
- <title>Spec Runner for Morph Table View</title>
+ <title>Spec Runner for Matches</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>
diff --git a/dev/js/spec/buttongroupSpec.js b/dev/js/spec/buttongroupSpec.js
index 1e27d96..67baaef 100644
--- a/dev/js/spec/buttongroupSpec.js
+++ b/dev/js/spec/buttongroupSpec.js
@@ -103,5 +103,9 @@
group.element().firstChild.click();
expect(fun.count).toEqual(1);
});
+
+ it('should open lists', function () {
+
+ });
});
});
diff --git a/dev/js/spec/matchSpec.js b/dev/js/spec/matchSpec.js
index b09a7cb..5463835 100644
--- a/dev/js/spec/matchSpec.js
+++ b/dev/js/spec/matchSpec.js
@@ -368,18 +368,18 @@
m.open();
var relation = e.querySelector("p.ref > div.action.bottom > span:nth-of-type(3)");
expect(relation.getAttribute("class")).toEqual("tree");
- expect(document.getElementById("treeMenu")).toBeNull();
+ expect(document.getElementsByClassName("button-group-list").length).toEqual(0);
expect(document.activeElement.tagName).toEqual("BODY");
// Show menu
relation.click();
- expect(document.getElementById("treeMenu")).toBeTruthy();
+ expect(document.getElementsByClassName("button-group-list").length).toEqual(1);
expect(document.activeElement.tagName).toEqual("UL");
// Choose first tree
- document.getElementById("treeMenu").getElementsByTagName("li")[1].click();
+ document.getElementsByClassName("button-group-list")[0].getElementsByTagName("li")[1].click();
expect(e.querySelector("div.matchinfo div.matchtree h6 span").innerText).toEqual("corenlp");
// This should blur the focus
@@ -701,14 +701,14 @@
describe('KorAP.MatchTreeMenu', function () {
- var matchTreeMenu = require('match/treemenu');
+ var matchTreeMenu = require('buttongroup/menu');
var matchTreeItem = require('match/treeitem');
it('should be initializable', function () {
var menu = matchTreeMenu.create([
['cnx/c', 'cnx', 'c'],
['xip/c', 'xip', 'c']
- ]);
+ ], matchTreeItem);
expect(menu.itemClass()).toEqual(matchTreeItem);
expect(menu.element().nodeName).toEqual('UL');
diff --git a/dev/js/src/buttongroup.js b/dev/js/src/buttongroup.js
index 12870b5..443d650 100644
--- a/dev/js/src/buttongroup.js
+++ b/dev/js/src/buttongroup.js
@@ -1,4 +1,6 @@
-define(['util'], function () {
+define(['buttongroup/menu','menu/item','util'], function (treeMenuClass, defaultItemClass) {
+ "use strict";
+
return {
/**
* Create button group
@@ -44,6 +46,8 @@
/**
* Add button in order
+ *
+ * Returns the button element
*/
add : function (title, classes, cb) {
var b = this._element.addE('span');
@@ -60,13 +64,36 @@
e.halt();
// Call callback
- cb.apply(that._bind || this, e)
+ var obj = that._bind || this;
+ obj.button = b;
+ cb.apply(obj, e)
});
+
+ return b;
},
/**
- * Bind an object to all callbacks of the button group
+ * Add button that spawns a list in order.
+ *
+ * Returns the list object.
+ */
+ addList : function (title, classes, itemClass) {
+ var list = treeMenuClass.create([], itemClass || defaultItemClass);
+ this.add(title, classes, function (e) {
+ list.show();
+ list.button(this.button);
+ list.focus();
+ });
+
+ return list;
+ },
+
+
+ /**
+ * Bind an object to all callbacks of the button group.
+ * To get the button element inside the callback,
+ * use this.button
*/
bind : function (obj) {
if (obj !== undefined) {
diff --git a/dev/js/src/match/treemenu.js b/dev/js/src/buttongroup/menu.js
similarity index 86%
rename from dev/js/src/match/treemenu.js
rename to dev/js/src/buttongroup/menu.js
index 0010271..7ab149d 100644
--- a/dev/js/src/match/treemenu.js
+++ b/dev/js/src/buttongroup/menu.js
@@ -1,7 +1,7 @@
/**
- * Menu to choose from for tree views.
+ * Menu to choose from in a button group.
*/
-define(['menu', 'match/treeitem'], function (menuClass, itemClass) {
+define(['menu'], function (menuClass) {
"use strict";
return {
@@ -15,7 +15,7 @@
* @param params The match menu items
* as an array of arrays.
*/
- create : function (list) {
+ create : function (list, itemClass) {
var obj = Object.create(menuClass)
.upgradeTo(this)
._init(list, {itemClass : itemClass});
@@ -28,7 +28,7 @@
this.menu.hide();
});
- e.setAttribute('id', 'treeMenu');
+ e.classList.add('button-group-list');
// Add menu to body
document.getElementsByTagName('body')[0].appendChild(e);
@@ -38,6 +38,8 @@
/**
* The match information object of the menu.
+ * TODO:
+ * Rename to 'Panel'
*/
info :function (infoVar) {
if (infoVar !== undefined)
@@ -47,10 +49,10 @@
},
// Attach menu to button
- attachTo : function (e) {
+ button : function (btn) {
// this._attached = e;
- this._repos(e);
+ this._repos(btn);
this.slider().reInit();
/*
@@ -62,7 +64,7 @@
};
this._onscroll = function () {
- this._repos(e);
+ this._repos(btn);
}.bind(this);
window.addEventListener('scroll', this._onscroll);
diff --git a/dev/js/src/hint/item.js b/dev/js/src/hint/item.js
index 47d332b..80ac78b 100644
--- a/dev/js/src/hint/item.js
+++ b/dev/js/src/hint/item.js
@@ -40,19 +40,20 @@
};
return this._content;
},
-
+
/**
* Override the click action
* of the menu item.
*/
onclick : function (e) {
var m = this.menu();
- var h = m.hint();
// m.hide();
// Reset prefix
m.prefix("");
+ var h = m.hint();
+
// Update input field
var input = h.inputField();
input.insert(this._action).update();
diff --git a/dev/js/src/match.js b/dev/js/src/match.js
index 4e7bd1a..59d2e83 100644
--- a/dev/js/src/match.js
+++ b/dev/js/src/match.js
@@ -11,10 +11,11 @@
*/
define([
'match/info', // rename to anno
- 'match/treemenu',
+ 'match/treeitem',
'buttongroup',
+ 'buttongroup/menu',
'util'
-], function (infoClass,matchTreeMenuClass,buttonGroupClass) { //, refClass) {
+], function (infoClass,treeItemClass,buttonGroupClass,buttonGroupMenuClass) { //, refClass) {
// Localization values
const loc = KorAP.Locale;
@@ -210,7 +211,7 @@
btns.add(
loc.ADDTREE, ['tree'], function (e) {
if (KorAP.TreeMenu === undefined) {
- KorAP.TreeMenu = matchTreeMenuClass.create([]);
+ KorAP.TreeMenu = buttonGroupMenuClass.create([], treeItemClass);
};
var tm = KorAP.TreeMenu;
@@ -221,7 +222,7 @@
// Reposition and show menu
tm.show();
- tm.attachTo(this);
+ tm.button(this);
tm.focus();
}
);
diff --git a/dev/js/src/menu/item.js b/dev/js/src/menu/item.js
index 812a398..e06de1e 100644
--- a/dev/js/src/menu/item.js
+++ b/dev/js/src/menu/item.js
@@ -47,15 +47,6 @@
},
/**
- * Get the lower cased field of the item
- * (used for analyses).
- */
- lcField : function () {
- return this._lcField;
- },
-
-
- /**
* Get or set the information for action of this item.
*/
action : function (action) {
@@ -63,6 +54,16 @@
this._action = action;
return this._action;
},
+
+
+ /**
+ * Get the lower cased field of the item
+ * (used for analyses).
+ */
+ lcField : function () {
+ return this._lcField;
+ },
+
/**
* Check or set if the item is active
@@ -170,6 +171,7 @@
this._prefix = null;
},
+
// Highlight a certain substring of the menu item
_highlight : function (elem, prefixString) {
if (elem.nodeType === 3) {
@@ -260,15 +262,36 @@
this.content(params[0]);
- if (params.length === 2)
+ if (params.length > 1) {
this._action = params[1];
+ if (params.length > 2)
+ this._onclick = params[2];
+ };
+
this._lcField = ' ' + this.content().textContent.toLowerCase();
this._prefix = null;
return this;
},
+
+ /**
+ * The click action of the menu item.
+ */
+ onclick : function (e) {
+ var m = this.menu();
+
+ // Reset prefix
+ m.prefix("");
+
+ if (this._onclick)
+ this._onclick.apply(this, e);
+
+ m.hide();
+ },
+
+
/**
* Return menu list.
*/
diff --git a/dev/scss/main/buttongroup.scss b/dev/scss/main/buttongroup.scss
index 607f9e3..dea337d 100644
--- a/dev/scss/main/buttongroup.scss
+++ b/dev/scss/main/buttongroup.scss
@@ -40,3 +40,17 @@
}
}
}
+
+ul.button-group-list {
+ border-top-right-radius: 8px;
+ z-index: 150;
+ font-size: 10pt;
+ position: fixed;
+ left: 0;
+ text-align: left;
+ margin: -1 * $border-size;
+ margin-top: 0;
+ > li:first-of-type {
+ border-top-right-radius: 5px;
+ }
+}
diff --git a/dev/scss/main/matchinfo.scss b/dev/scss/main/matchinfo.scss
index bf25ff1..f2ed006 100644
--- a/dev/scss/main/matchinfo.scss
+++ b/dev/scss/main/matchinfo.scss
@@ -79,23 +79,6 @@
}
}
}
-
-ul#treeMenu {
- border-top-right-radius: 8px;
- z-index: 150;
- font-size: 10pt;
- position: fixed;
- // width: $left-width;
- left: 0;
- // bottom: 0;
- text-align: left;
- margin: -1* $border-size;
- margin-top: 0;
- > li:first-of-type {
- border-top-right-radius: 5px;
- }
-}
-
div.matchtable > div {
z-index: 20;