123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357 |
- blocklyApp.TreeService = ng.core
- .Class({
- constructor: function() {
-
- this.activeDescendantIds_ = {};
- },
- getToolboxTreeNode_: function() {
- return document.getElementById('blockly-toolbox-tree');
- },
- getWorkspaceToolbarButtonNodes_: function() {
- return Array.from(document.querySelectorAll(
- 'button.blocklyWorkspaceToolbarButton'));
- },
-
- getWorkspaceTreeNodes_: function() {
- return Array.from(document.querySelectorAll('ol.blocklyWorkspaceTree'));
- },
-
- getAllTreeNodes_: function() {
- var treeNodes = [this.getToolboxTreeNode_()];
- treeNodes = treeNodes.concat(this.getWorkspaceToolbarButtonNodes_());
- treeNodes = treeNodes.concat(this.getWorkspaceTreeNodes_());
- return treeNodes;
- },
- isTopLevelWorkspaceTree: function(treeId) {
- return this.getWorkspaceTreeNodes_().some(function(tree) {
- return tree.id == treeId;
- });
- },
- getNodeToFocusOnWhenTreeIsDeleted: function(deletedTreeId) {
-
-
-
- var trees = this.getAllTreeNodes_();
- for (var i = 0; i < trees.length; i++) {
- if (trees[i].id == deletedTreeId) {
- if (i + 1 < trees.length) {
- return trees[i + 1];
- } else if (i > 0) {
- return trees[i - 1];
- }
- }
- }
- return this.getToolboxTreeNode_();
- },
- focusOnCurrentTree_: function(treeId) {
- var trees = this.getAllTreeNodes_();
- for (var i = 0; i < trees.length; i++) {
- if (trees[i].id == treeId) {
- trees[i].focus();
- return true;
- }
- }
- return false;
- },
- focusOnNextTree_: function(treeId) {
- var trees = this.getAllTreeNodes_();
- for (var i = 0; i < trees.length - 1; i++) {
- if (trees[i].id == treeId) {
- trees[i + 1].focus();
- return true;
- }
- }
- return false;
- },
- focusOnPreviousTree_: function(treeId) {
- var trees = this.getAllTreeNodes_();
- for (var i = trees.length - 1; i > 0; i--) {
- if (trees[i].id == treeId) {
- trees[i - 1].focus();
- return true;
- }
- }
- return false;
- },
- getActiveDescId: function(treeId) {
- return this.activeDescendantIds_[treeId] || '';
- },
- unmarkActiveDesc_: function(activeDescId) {
- var activeDesc = document.getElementById(activeDescId);
- if (activeDesc) {
- activeDesc.classList.remove('blocklyActiveDescendant');
- activeDesc.setAttribute('aria-selected', 'false');
- }
- },
- markActiveDesc_: function(activeDescId) {
- var newActiveDesc = document.getElementById(activeDescId);
- newActiveDesc.classList.add('blocklyActiveDescendant');
- newActiveDesc.setAttribute('aria-selected', 'true');
- },
-
-
- runWhilePreservingFocus: function(func, treeId, optionalNewActiveDescId) {
- var oldDescId = this.getActiveDescId(treeId);
- var newDescId = optionalNewActiveDescId || oldDescId;
- this.unmarkActiveDesc_(oldDescId);
- func();
-
-
-
- var that = this;
- setTimeout(function() {
- that.markActiveDesc_(newDescId);
- that.activeDescendantIds_[treeId] = newDescId;
- document.getElementById(treeId).focus();
- }, 0);
- },
-
- setActiveDesc: function(newActiveDescId, treeId) {
- this.unmarkActiveDesc_(this.getActiveDescId(treeId));
- this.markActiveDesc_(newActiveDescId);
- this.activeDescendantIds_[treeId] = newActiveDescId;
- },
- onWorkspaceToolbarKeypress: function(e, treeId) {
- if (e.keyCode == 9) {
-
- if (e.shiftKey) {
- this.focusOnPreviousTree_(treeId);
- } else {
- this.focusOnNextTree_(treeId);
- }
- e.preventDefault();
- e.stopPropagation();
- }
- },
- isButtonOrFieldNode_: function(node) {
- return ['BUTTON', 'INPUT'].indexOf(node.tagName) != -1;
- },
- getNextActiveDescWhenBlockIsDeleted: function(blockRootNode) {
-
- var nextNode = blockRootNode.parentNode;
- while (nextNode && nextNode.tagName != 'LI') {
- nextNode = nextNode.parentNode;
- }
- if (nextNode) {
- return nextNode;
- }
-
- var nextSibling = this.getNextSibling(blockRootNode);
- if (nextSibling) {
- return nextSibling;
- }
-
- var previousSibling = this.getPreviousSibling(blockRootNode);
- if (previousSibling) {
- return previousSibling;
- }
-
-
-
- console.error('Could not handle deletion of block.' + blockRootNode);
- },
- onKeypress: function(e, tree) {
- var treeId = tree.id;
- var activeDesc = document.getElementById(this.getActiveDescId(treeId));
- if (!activeDesc) {
- console.error('ERROR: no active descendant for current tree.');
-
- var workspaceTreeNodes = this.getWorkspaceTreeNodes_();
- for (var i = 0; i < workspaceTreeNodes.length; i++) {
- if (workspaceTreeNodes[i].id == treeId) {
-
- this.setActiveDesc(
- this.getFirstChild(workspaceTreeNodes[i]).id, treeId);
- break;
- }
- }
- return;
- }
- var isFocusingIntoField = false;
- if (e.keyCode == 13) {
-
- if (activeDesc.children.length == 1) {
- var child = activeDesc.children[0];
- if (child.tagName == 'BUTTON') {
- child.click();
- this.isFocusingIntoField = true;
- } else if (child.tagName == 'INPUT') {
- child.focus();
- }
- }
- } else if (e.keyCode == 9) {
-
- if (e.shiftKey) {
- this.focusOnPreviousTree_(treeId);
- } else {
- this.focusOnNextTree_(treeId);
- }
- e.preventDefault();
- e.stopPropagation();
- } else if (e.keyCode >= 37 && e.keyCode <= 40) {
-
- if (e.keyCode == 37) {
-
- var nextNode = activeDesc.parentNode;
- if (this.isButtonOrFieldNode_(activeDesc)) {
- nextNode = nextNode.parentNode;
- }
- while (nextNode && nextNode.tagName != 'LI') {
- nextNode = nextNode.parentNode;
- }
- if (nextNode) {
- this.setActiveDesc(nextNode.id, treeId);
- }
- } else if (e.keyCode == 38) {
-
- var prevSibling = this.getPreviousSibling(activeDesc);
- if (prevSibling) {
- this.setActiveDesc(prevSibling.id, treeId);
- }
- } else if (e.keyCode == 39) {
-
- var firstChild = this.getFirstChild(activeDesc);
- if (firstChild) {
- this.setActiveDesc(firstChild.id, treeId);
- }
- } else if (e.keyCode == 40) {
-
- var nextSibling = this.getNextSibling(activeDesc);
- if (nextSibling) {
- this.setActiveDesc(nextSibling.id, treeId);
- }
- }
- e.preventDefault();
- e.stopPropagation();
- }
- },
- getFirstChild: function(element) {
- if (!element) {
- return element;
- } else {
- var childList = element.children;
- for (var i = 0; i < childList.length; i++) {
- if (childList[i].tagName == 'LI') {
- return childList[i];
- } else {
- var potentialElement = this.getFirstChild(childList[i]);
- if (potentialElement) {
- return potentialElement;
- }
- }
- }
- return null;
- }
- },
- getNextSibling: function(element) {
- if (element.nextElementSibling) {
-
- var node = element.nextElementSibling;
- if (node.tagName == 'LI') {
- return node;
- } else {
-
-
- return node.getElementsByTagName('li')[0];
- }
- } else {
- var parent = element.parentNode;
- while (parent && parent.tagName != 'OL') {
- if (parent.nextElementSibling) {
- var node = parent.nextElementSibling;
- if (node.tagName == 'LI') {
- return node;
- } else {
- return this.getFirstChild(node);
- }
- } else {
- parent = parent.parentNode;
- }
- }
- return null;
- }
- },
- getPreviousSibling: function(element) {
- if (element.previousElementSibling) {
- var sibling = element.previousElementSibling;
- if (sibling.tagName == 'LI') {
- return sibling;
- } else {
- return this.getLastChild(sibling);
- }
- } else {
- var parent = element.parentNode;
- while (parent) {
- if (parent.tagName == 'OL') {
- break;
- }
- if (parent.previousElementSibling) {
- var node = parent.previousElementSibling;
- if (node.tagName == 'LI') {
- return node;
- } else {
-
- return this.getLastChild(node);
- }
- } else {
- parent = parent.parentNode;
- }
- }
- return null;
- }
- },
- getLastChild: function(element) {
- if (!element) {
- return element;
- } else {
- var childList = element.children;
- for (var i = childList.length - 1; i >= 0; i--) {
-
- if (childList[i].tagName == 'LI') {
- return childList[i];
- } else {
- var potentialElement = this.getLastChild(childList[i]);
- if (potentialElement) {
- return potentialElement;
- }
- }
- }
- return null;
- }
- }
- });
|